pax_global_header00006660000000000000000000000064141737637650014535gustar00rootroot0000000000000052 comment=b401d7cc3433f34de9f4c6cd518dfaf1bfac7484 arb-2.22.1/000077500000000000000000000000001417376376500123655ustar00rootroot00000000000000arb-2.22.1/.build_dependencies000077500000000000000000000012061417376376500161750ustar00rootroot00000000000000#! /bin/sh wget http://mpir.org/mpir-2.7.0.tar.bz2 tar -xf mpir-2.7.0.tar.bz2 cd mpir-2.7.0 ./configure --enable-gmpcompat --prefix=$HOME/deps --disable-static make -j4 > /dev/null 2>&1 make install cd .. wget http://www.mpfr.org/mpfr-3.1.4/mpfr-3.1.4.tar.bz2 tar -xf mpfr-3.1.4.tar.bz2 cd mpfr-3.1.4 ./configure --with-gmp=$HOME/deps --prefix=$HOME/deps --disable-static make -j4 > /dev/null 2>&1 make install cd .. wget http://flintlib.org/flint-2.5.2.tar.gz tar -xf flint-2.5.2.tar.gz cd flint-2.5.2 ./configure --with-gmp=$HOME/deps --with-mpfr=$HOME/deps --prefix=$HOME/deps --disable-static make -j4 > /dev/null 2>&1 make install cd .. arb-2.22.1/.github/000077500000000000000000000000001417376376500137255ustar00rootroot00000000000000arb-2.22.1/.github/workflows/000077500000000000000000000000001417376376500157625ustar00rootroot00000000000000arb-2.22.1/.github/workflows/ci-sage.yml000066400000000000000000000365601417376376500200270ustar00rootroot00000000000000name: Run Sage CI for Linux/Cygwin/macOS ## This GitHub Actions workflow provides: ## ## - portability testing, by building and testing this project on many platforms ## (Linux variants and Cygwin), each with two configurations (installed packages), ## ## - continuous integration, by building and testing other software ## that depends on this project. ## ## It runs on every pull request and push of a tag to the GitHub repository. ## ## The testing can be monitored in the "Actions" tab of the GitHub repository. ## ## After all jobs have finished (or are canceled) and a short delay, ## tar files of all logs are made available as "build artifacts". ## ## This GitHub Actions workflow uses the portability testing framework ## of SageMath (https://www.sagemath.org/). For more information, see ## https://doc.sagemath.org/html/en/developer/portability_testing.html ## The workflow consists of two jobs: ## ## - First, it builds a source distribution of the project ## and generates a script "update-pkgs.sh". It uploads them ## as a build artifact named upstream. ## ## - Second, it checks out a copy of the SageMath source tree. ## It downloads the upstream artifact and replaces the project's ## package in the SageMath distribution by the newly packaged one ## from the upstream artifact, by running the script "update-pkgs.sh". ## Then it builds a small portion of the Sage distribution. ## ## Many copies of the second step are run in parallel for each of the tested ## systems/configurations. #on: [push, pull_request] on: pull_request: types: [opened, synchronize] push: tags: - '*' env: # Ubuntu packages to install so that the project's "make dist" can succeed DIST_PREREQ: # Name of this project in the Sage distribution SPKG: arb # Sage distribution packages to build TARGETS_PRE: build/make/Makefile TARGETS: SAGE_CHECK=yes arb symengine TARGETS_OPTIONAL: SAGE_CHECK=warn e_antic # Standard setting: Test the current beta release of Sage: SAGE_REPO: sagemath/sage SAGE_REF: develop # Merge the branch from sage ticket adding symengine; no-op when merged already SAGE_TRAC_GIT: git://trac.sagemath.org/sage.git SAGE_TRAC_COMMAND: try SAGE_TICKET: 29497 REMOVE_PATCHES: "*" jobs: dist: runs-on: ubuntu-latest steps: - name: Check out ${{ env.SPKG }} uses: actions/checkout@v2 with: path: build/pkgs/${{ env.SPKG }}/src - name: Install prerequisites run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install $DIST_PREREQ if: env.DIST_PREREQ != '' - name: Run make dist, prepare upstream artifact run: | (cd build/pkgs/${{ env.SPKG }}/src && (cd .. && tar czf - src) > arb-git.tar.gz) \ && mkdir -p upstream && cp build/pkgs/${{ env.SPKG }}/src/*.tar.gz upstream/${{ env.SPKG }}-git.tar.gz \ && echo "sage-package create ${{ env.SPKG }} --version git --tarball ${{ env.SPKG }}-git.tar.gz --type=optional" > upstream/update-pkgs.sh \ && if [ -n "${{ env.REMOVE_PATCHES }}" ]; then echo "(cd ../build/pkgs/${{ env.SPKG }}/patches && rm -f ${{ env.REMOVE_PATCHES }}; :)" >> upstream/update-pkgs.sh; fi \ && ls -l upstream/ - uses: actions/upload-artifact@v2 with: path: upstream name: upstream cygwin: env: STAGE: i-a LOCAL_ARTIFACT_NAME: sage-local-commit-${{ github.sha }}-cygwin-${{ matrix.pkgs }} LOGS_ARTIFACT_NAME: logs-commit-${{ github.sha }}-cygwin-${{ matrix.pkgs }} MAKE: make -j8 SAGE_NUM_THREADS: 3 SAGE_CHECK: yes SAGE_CHECK_PACKAGES: "!cython,!r,!python3,!python2,!nose,!pathpy,!gap,!cysignals,!linbox,!git,!ppl" CYGWIN: winsymlinks:native CONFIGURE_ARGS: --enable-experimental-packages --enable-download-from-upstream-url SAGE_FAT_BINARY: yes runs-on: windows-latest needs: [dist] strategy: fail-fast: false matrix: pkgs: [minimal, standard] steps: - run: | git config --global core.autocrlf false git config --global core.symlinks true - name: install cygwin with choco shell: bash {0} run: | choco --version choco install git python3 --source cygwin - name: Check out SageMath uses: actions/checkout@v2 with: repository: ${{ env.SAGE_REPO }} ref: ${{ env.SAGE_REF }} if: env.SAGE_REPO != '' - name: Check out git-trac-command uses: actions/checkout@v2 with: repository: sagemath/git-trac-command path: git-trac-command if: env.SAGE_TRAC_GIT != '' - name: Check out SageMath from trac.sagemath.org shell: bash {0} # Random sleep and retry to limit the load on trac.sagemath.org run: | if [ ! -d .git ]; then git init; fi; git remote add trac ${{ env.SAGE_TRAC_GIT }} && x=1 && while [ $x -le 5 ]; do x=$(( $x + 1 )); sleep $(( $RANDOM % 60 + 1 )); if git-trac-command/git-trac ${{ env.SAGE_TRAC_COMMAND }} $SAGE_TICKET; then exit 0; fi; sleep 40; done; exit 1 if: env.SAGE_TRAC_GIT != '' - uses: actions/download-artifact@v2 with: path: upstream name: upstream - name: install minimal prerequisites with choco shell: bash {0} run: | choco --version PACKAGES=$(sed 's/#.*//;' ./build/pkgs/cygwin.txt ./build/pkgs/cygwin-bootstrap.txt) choco install $PACKAGES --source cygwin - name: Update Sage packages from upstream artifact run: | C:\\tools\\cygwin\\bin\\bash -l -c 'export PATH=/usr/local/bin:/usr/bin && cd $(cygpath -u "$GITHUB_WORKSPACE") && ls -l upstream/ && export PATH="$(pwd)/build/bin:$PATH:/usr/local/bin:/usr/bin" && (cd upstream && bash -x update-pkgs.sh) && git diff' - name: bootstrap run: | C:\\tools\\cygwin\\bin\\bash -l -c 'export PATH=/usr/local/bin:/usr/bin && cd $(cygpath -u "$GITHUB_WORKSPACE") && env && ./bootstrap' - name: install additional cygwin packages with choco if: contains(matrix.pkgs, 'standard') shell: bash {0} run: | PACKAGES=$(sed 's/#.*//;' ./build/pkgs/*/distros/cygwin.txt) choco install $PACKAGES --source cygwin - name: configure run: | C:\\tools\\cygwin\\bin\\bash -l -c 'export PATH=/usr/local/bin:/usr/bin && cd $(cygpath -u "$GITHUB_WORKSPACE") && ./configure $CONFIGURE_ARGS' - name: make run: | C:\\tools\\cygwin\\bin\\bash -l -x -c 'export PATH=/usr/local/bin:/usr/bin && cd $(cygpath -u "$GITHUB_WORKSPACE") && make -k -w V=0 base-toolchain && make -k -w V=1 $TARGETS' - name: make run: | C:\\tools\\cygwin\\bin\\bash -l -x -c 'export PATH=/usr/local/bin:/usr/bin && cd $(cygpath -u "$GITHUB_WORKSPACE") && make -k -w V=1 $TARGETS_OPTIONAL' - name: Prepare logs artifact shell: bash run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME"; for a in local/var/tmp/sage/build/*; do if [ -d $a ]; then tar -c --remove-files -f "artifacts/$LOGS_ARTIFACT_NAME/$(basename $a).tar" $a; fi; done; cp -r logs/* "artifacts/$LOGS_ARTIFACT_NAME" if: always() - uses: actions/upload-artifact@v2 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} if: always() - name: Print out logs for immediate inspection # The markup in the output is a GitHub Actions logging command # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions shell: bash run: | find "artifacts/$LOGS_ARTIFACT_NAME" -type f -name "*.log" -exec sh -c 'if tail -20 "{}" 2>/dev/null | grep "^Error" >/dev/null; then echo :":"error file={}:":" ==== LOG FILE {} CONTAINS AN ERROR ====; cat {} ; fi' \; if: always() - name: Prepare sage-local artifact # We specifically use the cygwin tar so that symlinks are saved/restored correctly on Windows. # We remove the local/lib64 link, which will be recreated by the next stage. run: | C:\\tools\\cygwin\\bin\\bash -l -c 'cd $(cygpath -u "$GITHUB_WORKSPACE") && rm -f local/lib64; tar -cf /tmp/sage-local-${{ env.STAGE }}.tar --remove-files local' if: always() - uses: actions/upload-artifact@v2 # upload-artifact@v2 does not support whitespace in file names. # so we tar up the directory ourselves with: path: C:\\tools\\cygwin\\tmp\\sage-local-${{ env.STAGE }}.tar name: ${{ env.LOCAL_ARTIFACT_NAME }} if: always() docker: runs-on: ubuntu-latest needs: [dist] strategy: fail-fast: false max-parallel: 32 matrix: tox_system_factor: [ubuntu-trusty, ubuntu-xenial, ubuntu-bionic, ubuntu-eoan, ubuntu-focal, debian-jessie, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-17, linuxmint-18, linuxmint-19, linuxmint-19.3, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, centos-7, centos-8, archlinux-latest, slackware-14.2, conda-forge, ubuntu-bionic-i386, ubuntu-eoan-i386, debian-buster-i386, centos-7-i386, raspbian-buster-armhf] tox_packages_factor: [minimal, standard] env: TOX_ENV: docker-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} LOGS_ARTIFACT_NAME: logs-commit-${{ github.sha }}-tox-docker-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} DOCKER_TARGETS: configured with-targets steps: - name: Check out SageMath uses: actions/checkout@v2 with: repository: ${{ env.SAGE_REPO }} ref: ${{ env.SAGE_REF }} if: env.SAGE_REPO != '' - name: Check out git-trac-command uses: actions/checkout@v2 with: repository: sagemath/git-trac-command path: git-trac-command if: env.SAGE_TRAC_GIT != '' - name: Check out SageMath from trac.sagemath.org shell: bash {0} run: | if [ ! -d .git ]; then git init; fi; git remote add trac ${{ env.SAGE_TRAC_GIT }} && x=1 && while [ $x -le 5 ]; do x=$(( $x + 1 )); sleep $(( $RANDOM % 60 + 1 )); if git-trac-command/git-trac ${{ env.SAGE_TRAC_COMMAND }} $SAGE_TICKET; then exit 0; fi; sleep 40; done; exit 1 if: env.SAGE_TRAC_GIT != '' - uses: actions/download-artifact@v2 with: path: upstream name: upstream - name: Install test prerequisites run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install python-tox python3-setuptools - name: Update Sage packages from upstream artifact run: | (export PATH=$(pwd)/build/bin:$PATH; (cd upstream && bash -x update-pkgs.sh) && sed -i.bak '/upstream/d' .dockerignore && echo "/:toolchain:/i ADD upstream upstream" | sed -i.bak -f - build/bin/write-dockerfile.sh && git diff) - run: | set -o pipefail; EXTRA_DOCKER_BUILD_ARGS="--build-arg USE_MAKEFLAGS=\"-k V=0 SAGE_NUM_THREADS=3\"" tox -e $TOX_ENV -- $TARGETS 2>&1 | sed "/^configure: notice:/s|^|::warning file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;/^configure: warning:/s|^|::warning file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;/^configure: error:/s|^|::error file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;" - name: Copy logs from the docker image or build container run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME" cp -r .tox/$TOX_ENV/Dockerfile .tox/$TOX_ENV/log "artifacts/$LOGS_ARTIFACT_NAME" if [ -f .tox/$TOX_ENV/Dockertags ]; then CONTAINERS=$(docker create $(tail -1 .tox/$TOX_ENV/Dockertags) /bin/bash || true); fi if [ -n "$CONTAINERS" ]; then for CONTAINER in $CONTAINERS; do for ARTIFACT in /sage/logs; do docker cp $CONTAINER:$ARTIFACT artifacts/$LOGS_ARTIFACT_NAME && HAVE_LOG=1; done; if [ -n "$HAVE_LOG" ]; then break; fi; done; fi if: always() - uses: actions/upload-artifact@v2 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} if: always() - name: Print out logs for immediate inspection # and markup the output with GitHub Actions logging commands run: | .github/workflows/scan-logs.sh "artifacts/$LOGS_ARTIFACT_NAME" if: always() - name: Push docker images run: | if [ -f .tox/$TOX_ENV/Dockertags ]; then TOKEN="${{ secrets.DOCKER_PKG_GITHUB_TOKEN }}" if [ -z "$TOKEN" ]; then TOKEN="${{ secrets.GITHUB_TOKEN }}" fi echo "$TOKEN" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin for a in $(cat .tox/$TOX_ENV/Dockertags); do FULL_TAG=docker.pkg.github.com/$(echo ${{ github.repository }}|tr 'A-Z' 'a-z')/$a docker tag $a $FULL_TAG echo Pushing $FULL_TAG docker push $FULL_TAG done || echo "(Ignoring errors)" fi if: always() macos: runs-on: macos-latest strategy: fail-fast: false max-parallel: 4 matrix: tox_system_factor: [homebrew-macos, homebrew-macos-python3_xcode, homebrew-macos-python3_xcode-nokegonly, conda-forge-macos] tox_packages_factor: [minimal, standard] needs: [dist] env: TOX_ENV: local-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} LOGS_ARTIFACT_NAME: logs-commit-${{ github.sha }}-tox-local-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} steps: - name: Check out SageMath uses: actions/checkout@v2 with: repository: ${{ env.SAGE_REPO }} ref: ${{ env.SAGE_REF }} if: env.SAGE_REPO != '' - name: Check out git-trac-command uses: actions/checkout@v2 with: repository: sagemath/git-trac-command path: git-trac-command if: env.SAGE_TRAC_GIT != '' - name: Check out SageMath from trac.sagemath.org shell: bash {0} run: | if [ ! -d .git ]; then git init; fi; git remote add trac ${{ env.SAGE_TRAC_GIT }} && x=1 && while [ $x -le 5 ]; do x=$(( $x + 1 )); sleep $(( $RANDOM % 60 + 1 )); if git-trac-command/git-trac ${{ env.SAGE_TRAC_COMMAND }} $SAGE_TICKET; then exit 0; fi; sleep 40; done; exit 1 if: env.SAGE_TRAC_GIT != '' - uses: actions/download-artifact@v2 with: path: upstream name: upstream - name: Update Sage packages from upstream artifact run: | (export PATH=$(pwd)/build/bin:$PATH; (cd upstream && bash -x update-pkgs.sh) && git diff) - name: Install test prerequisites run: | brew install tox - name: Build and test with tox # We use a high parallelization on purpose in order to catch possible parallelization bugs in the build scripts. # For doctesting, we use a lower parallelization to avoid timeouts. run: | MAKE="make -j12" tox -e $TOX_ENV -- SAGE_NUM_THREADS=4 $TARGETS - name: Prepare logs artifact run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME"; cp -r .tox/*/log "artifacts/$LOGS_ARTIFACT_NAME" if: always() - uses: actions/upload-artifact@v1 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} if: always() - name: Print out logs for immediate inspection # and markup the output with GitHub Actions logging commands run: | .github/workflows/scan-logs.sh "artifacts/$LOGS_ARTIFACT_NAME" if: always() arb-2.22.1/.gitignore000066400000000000000000000001271417376376500143550ustar00rootroot00000000000000Makefile build/* libarb.so* libarb.a doc/build/* *.ppm *.lo *.deps/ *.libs/ *.dirstamp arb-2.22.1/.travis.yml000066400000000000000000000012461417376376500145010ustar00rootroot00000000000000language: c sudo: false addons: apt: packages: - texinfo os: - osx - linux osx_image: xcode7 compiler: - gcc - clang script: - if [[ "${TRAVIS_OS_NAME}" == "osx" ]] && [[ "${CC}" == "gcc" ]]; then brew update; brew install gcc; brew link --overwrite gcc; export CC=gcc; export CXX=g++; gcc --version; g++ --version; fi - if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then export ARB_TEST_MULTIPLIER=0.1; fi - ./.build_dependencies - ./configure --with-mpir=$HOME/deps --with-mpfr=$HOME/deps --with-flint=$HOME/deps --prefix=$HOME/deps - make -j4 - make install - make check arb-2.22.1/CMakeLists.txt000066400000000000000000000121241417376376500151250ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.1) project(arb C) file(READ "${CMAKE_CURRENT_SOURCE_DIR}/configure" CONFIGURE_CONTENTS) string(REGEX MATCH "ARB_MAJOR=([0-9]*)" _ ${CONFIGURE_CONTENTS}) set(ARB_MAJOR ${CMAKE_MATCH_1}) string(REGEX MATCH "ARB_MINOR=([0-9]*)" _ ${CONFIGURE_CONTENTS}) set(ARB_MINOR ${CMAKE_MATCH_1}) string(REGEX MATCH "ARB_PATCH=([0-9]*)" _ ${CONFIGURE_CONTENTS}) set(ARB_PATCH ${CMAKE_MATCH_1}) set(ARB_VERSION "${ARB_MAJOR}.${ARB_MINOR}.${ARB_PATCH}") if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type (Debug, Release)" FORCE) endif () set (BUILD_SHARED_LIBS yes CACHE BOOL "Build shared library or not") set (BUILD_TESTING no CACHE BOOL "Build tests or not") if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Release")) message("${CMAKE_BUILD_TYPE}") message(FATAL_ERROR "CMAKE_BUILD_TYPE must be one of: Debug, Release (current value: '${CMAKE_BUILD_TYPE}')") endif () if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") set (PLATFORM "x64") else () set (PLATFORM "Win32") endif() if (BUILD_SHARED_LIBS) set (LIBRARY_TYPE dll) else () set (LIBRARY_TYPE lib) endif() set (MSVC_USE_MT yes CACHE BOOL "Use MT flags when compiling in MSVC") set (MSVC_WARNING_LEVEL 1 CACHE STRING "MSVC warning level") if (MSVC) if (MSVC_USE_MT) foreach(CompilerFlag CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE) string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") endforeach() endif() foreach(CompilerFlag CMAKE_C_FLAGS) set(${CompilerFlag} "${${CompilerFlag}} /W${MSVC_WARNING_LEVEL}") endforeach() foreach(CompilerFlag CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE) if (BUILD_SHARED_LIBS) set(${CompilerFlag} "${${CompilerFlag}} /DMSC_USE_DLL") else () set(${CompilerFlag} "${${CompilerFlag}} /DPTW32_STATIC_LIB") endif() endforeach() if ("${LIBRARY_TYPE}" STREQUAL "dll") set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS yes) endif() endif() set (DEPS flint2 mpfr mpir) set (mpir_lib gmp mpir) set (mpfr_lib mpfr) set (pthreads_lib pthreads pthread) set (flint2_lib ${LIBRARY_TYPE}_flint flint) set (mpir_header gmp.h) set (mpfr_header mpfr.h) set (pthreads_header pthread.h) set (flint2_header flint/flint.h) if(MSVC) set(DEPS ${DEPS} pthreads) else() option(CMAKE_THREAD_PREFER_PTHREAD "Prefer pthreads" yes) option(THREADS_PREFER_PTHREAD_FLAG "Prefer -pthread flag" yes) find_package(Threads REQUIRED) set(PTHREADS_LIBRARIES Threads::Threads) endif() foreach (LIB ${DEPS}) string (TOUPPER ${LIB} LIB_UPPER) find_library(${LIB_UPPER}_LIBRARY NAMES ${${LIB}_lib} HINTS ../${LIB} PATH_SUFFIXES ${LIBRARY_TYPE}/${PLATFORM}/${CMAKE_BUILD_TYPE}) if (NOT ${LIB_UPPER}_LIBRARY) message(FATAL_ERROR "${LIB} library not found.") endif() add_library(${LIB} UNKNOWN IMPORTED) set_property(TARGET ${LIB} PROPERTY IMPORTED_LOCATION ${${LIB_UPPER}_LIBRARY}) message("${LIB} found in ${${LIB_UPPER}_LIBRARY}") endforeach () foreach (LIB ${DEPS}) string(TOUPPER ${LIB} HEADER_PKG) set (HEADER ${${LIB}_header}) find_path(${HEADER_PKG}_INCLUDE_DIR NAMES ${HEADER} HINTS ../${LIB} PATH_SUFFIXES ${LIBRARY_TYPE}/${PLATFORM}/${CMAKE_BUILD_TYPE}) if (NOT ${HEADER_PKG}_INCLUDE_DIR) message(FATAL_ERROR "${HEADER} header not found.") endif() message("${HEADER} found in ${${HEADER_PKG}_INCLUDE_DIR}") set (DEP_INCLUDE_DIRS ${DEP_INCLUDE_DIRS} ${${HEADER_PKG}_INCLUDE_DIR}) endforeach () file(GLOB TEMP "*.h") foreach (TEMP_H ${TEMP}) get_filename_component(FOLDER ${TEMP_H} NAME_WE) set(FOLDERS ${FOLDERS} ${FOLDER}) endforeach() foreach (FOLDER ${FOLDERS}) file(GLOB TEMP "${FOLDER}/*.c") set(SRC ${SRC} ${TEMP}) endforeach () include_directories(BEFORE ${arb_SOURCE_DIR}) include_directories(BEFORE ${DEP_INCLUDE_DIRS}) add_library(arb ${SRC}) target_link_libraries(arb ${DEPS} ${PTHREADS_LIBRARIES}) target_compile_definitions(arb PRIVATE "ARB_BUILD_DLL") set_target_properties(arb PROPERTIES VERSION ${ARB_VERSION} SOVERSION ${ARB_MAJOR}) if(WIN32) set_target_properties(arb PROPERTIES RUNTIME_OUTPUT_NAME "arb-${ARB_MAJOR}") endif() if(NOT MSVC) target_link_libraries(arb m) endif() include(GNUInstallDirs) install(TARGETS arb RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" ) foreach (FOLDER ${FOLDERS}) set(HEADERS ${HEADERS} ${FOLDER}.h) endforeach () install(FILES ${HEADERS} DESTINATION include) if (BUILD_TESTING) enable_testing() foreach (FOLDER ${FOLDERS}) file(GLOB TEMP "${FOLDER}/test/*.c") foreach (TEST_SOURCE ${TEMP}) get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE) add_executable(${FOLDER}-${TEST_NAME} ${TEST_SOURCE}) target_link_libraries(${FOLDER}-${TEST_NAME} arb ${PTHREADS_LIBRARIES}) add_test(${FOLDER}-${TEST_NAME} ${FOLDER}-${TEST_NAME}) endforeach () endforeach () endif () arb-2.22.1/LICENSE000066400000000000000000000636421417376376500134050ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! arb-2.22.1/Makefile.in000066400000000000000000000231331417376376500144340ustar00rootroot00000000000000ifdef $(DLPATH) $(DLPATH):=$($(DLPATH)):$(DLPATH_ADD) else $(DLPATH):=$(DLPATH_ADD) endif LIBDIR=lib QUIET_CC = @echo ' ' CC ' ' $@; QUIET_CXX = @echo ' ' CXX ' ' $@; QUIET_AR = @echo ' ' AR ' ' $@; AT=@ BUILD_DIRS = fmpr arf mag arb arb_mat arb_poly arb_calc acb acb_mat acb_poly \ acb_dft acb_calc acb_hypgeom acb_elliptic acb_modular dirichlet acb_dirichlet \ arb_hypgeom bernoulli hypgeom fmpz_extras bool_mat partitions dlog \ double_interval arb_fmpz_poly arb_fpwrap \ $(EXTRA_BUILD_DIRS) TEMPLATE_DIRS = export SOURCES = LIB_SOURCES = $(wildcard $(patsubst %, %/*.c, $(BUILD_DIRS))) $(patsubst %, %/*.c, $(TEMPLATE_DIRS)) HEADERS = $(patsubst %, %.h, $(BUILD_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 -f $(OBJS) $(LOBJS) $(TESTS) $(PROFS) $(EXMPS) $(wildcard $(ARB_LIBNAME)*) libarb.a rm -rf build distclean: clean rm -f Makefile profile: library $(PROF_SOURCES) $(EXT_PROF_SOURCES) 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 $$?;) $(ARB_LIB): $(LOBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) $(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 $$?;) $(QUIET_CC) $(CC) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) -o $(ARB_LIB) $(LDFLAGS) $(LIBS2); -$(AT)if [ "$(ARB_SOLIB)" -eq "1" ]; then \ $(LDCONFIG) -n "$(CURDIR)"; \ fi ln -sf "$(ARB_LIB)" "$(ARB_LIBNAME)"; \ ln -sf "$(ARB_LIB)" "$(ARB_LIBNAME).$(ARB_MAJOR)"; \ libarb.a: $(OBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) $(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 [ "$(ARB_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)$(foreach mod, $(BUILD_DIRS), $(AR) rcs libarb.a build/$(mod)/*.o || exit $$?;) $(AT)$(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(AR) rcs libarb.a build/$(mod)/*.o || exit $$?;)) library: $(AT)if [ "$(ARB_SHARED)" -eq "1" ]; then \ $(MAKE) shared; \ fi $(AT)if [ "$(ARB_STATIC)" -eq "1" ]; then \ $(MAKE) static; \ fi shared: $(ARB_LIB) static: libarb.a tests: library $(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 $$?;)) check: library 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 $$?;) 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)/$(LIBDIR) mkdir -p $(DESTDIR)$(PREFIX)/include $(AT)if [ "$(ARB_SHARED)" -eq "1" ]; then \ cp $(ARB_LIB) "$(DESTDIR)$(PREFIX)/$(LIBDIR)"; \ cp -a $(shell ls $(ARB_LIBNAME)*) "$(DESTDIR)$(PREFIX)/$(LIBDIR)"; \ fi $(AT)if [ "$(ARB_STATIC)" -eq "1" ]; then \ cp libarb.a $(DESTDIR)$(PREFIX)/$(LIBDIR); \ fi cp $(HEADERS) $(DESTDIR)$(PREFIX)/include $(AT)if [ ! -z $(EXT_HEADERS) ]; then \ cp $(EXT_HEADERS) $(DESTDIR)$(PREFIX)/include; \ fi 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 print-%: @echo '$*=$($*)' .PHONY: profile library shared static clean examples tune check tests distclean dist install all valgrind arb-2.22.1/Makefile.subdirs000066400000000000000000000046611417376376500155060ustar00rootroot00000000000000QUIET_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 $(QUIET_CC) $(CC) $(ABI_FLAG) -O2 -std=c99 -g $(INCS) $< -o $@ $(LDLFAGS) $(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) $(LDLFAGS) $(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) -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 ($(ARB_SHARED), 0) $(BUILD_DIR)/test/%$(EXEEXT): $(BUILD_DIR)/../../libarb.a endif $(BUILD_DIR)/test/%$(EXEEXT): test/%.c $(QUIET_CC) $(CC) $(CFLAGS) $(INCS) $< -o $@ $(LDLFAGS) $(LIBS) -MMD -MP -MF $@.d -MT "$@" -MT "$@.d" $(BUILD_DIR)/test/%$(EXEEXT): test/%.cpp $(BUILD_DIR)/../../test_helpers.o $(QUIET_CC) $(CXX) $(CFLAGS) $(INCS) $< -o $@ $(LDLFAGS) $(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 arb-2.22.1/README.md000066400000000000000000000150431417376376500136470ustar00rootroot00000000000000# Arb Arb is a C library for arbitrary-precision interval arithmetic. It has full support for both real and complex numbers. The library is thread-safe, portable, and extensively tested. Arb is free software distributed under the GNU Lesser General Public License (LGPL), version 2.1 or later. ![arb logo](http://fredrikj.net/blog/2015/01/arb-2-5-0-released/arbtext.png) Documentation: http://arblib.org Development updates: http://fredrikj.net/blog/ Author: Fredrik Johansson Bug reports, feature requests and other comments are welcome in private communication, on the GitHub issue tracker, or on the FLINT mailing list . [![Build status](https://ci.appveyor.com/api/projects/status/r9bmee3ab3bb7xig?svg=true)](https://ci.appveyor.com/project/fredrik-johansson/arb) ## Code example The following program evaluates `sin(pi + exp(-10000))`. Since the input to the sine function matches a root to within 4343 digits, at least 4343-digit (14427-bit) precision is needed to get an accurate result. The program repeats the evaluation at 64-bit, 128-bit, ... precision, stopping only when the result is accurate to at least 53 bits. #include "arb.h" int main() { slong prec; arb_t x, y; arb_init(x); arb_init(y); for (prec = 64; ; prec *= 2) { arb_const_pi(x, prec); arb_set_si(y, -10000); arb_exp(y, y, prec); arb_add(x, x, y, prec); arb_sin(y, x, prec); arb_printn(y, 15, 0); printf("\n"); if (arb_rel_accuracy_bits(y) >= 53) break; } arb_clear(x); arb_clear(y); flint_cleanup(); } The output is: [+/- 6.01e-19] [+/- 2.55e-38] [+/- 8.01e-77] [+/- 8.64e-154] [+/- 5.37e-308] [+/- 3.63e-616] [+/- 1.07e-1232] [+/- 9.27e-2466] [-1.13548386531474e-4343 +/- 3.91e-4358] Each line shows a rigorous enclosure of the exact value of the expression. The program demonstrates how the user can rely on Arb's automatic error bound tracking to get an output that is guaranteed to be accurate -- no error analysis needs to be done by the user. For more example programs, see: http://arblib.org/examples.html ## Features Besides basic arithmetic, Arb allows working with univariate polynomials, truncated power series, and matrices over both real and complex numbers. Basic linear algebra is supported, including matrix multiplication, determinant, inverse, nonsingular solving, matrix exponential, and computation of eigenvalues and eigenvectors. Support for polynomials and power series is quite extensive, including methods for composition, reversion, product trees, multipoint evaluation and interpolation, complex root isolation, and transcendental functions of power series. Other features include root isolation for real functions, rigorous numerical integration of complex functions, and discrete Fourier transforms (DFTs). ## Special functions Arb can compute a wide range of transcendental and special functions, including the gamma function, polygamma functions, Riemann zeta and Hurwitz zeta function, Dirichlet L-functions, polylogarithm, error function, Gauss hypergeometric function 2F1, confluent hypergeometric functions, Bessel functions, Airy functions, Legendre functions and other orthogonal polynomials, exponential and trigonometric integrals, incomplete gamma and beta functions, Jacobi theta functions, modular functions, Weierstrass elliptic functions, complete and incomplete elliptic integrals, arithmetic-geometric mean, Bernoulli numbers, partition function, Barnes G-function, Lambert W function. ## Speed Arb uses a midpoint-radius (ball) representation of real numbers. At high precision, this allows doing interval arithmetic without significant overhead compared to plain floating-point arithmetic. Various low-level optimizations have also been implemented to reduce overhead at precisions of just a few machine words. Most operations on polynomials and power series use asymptotically fast FFT multiplication based on FLINT. Similarly, most operations on large matrices take advantage of the fast integer matrix multiplication in FLINT. For basic arithmetic, Arb should generally be around as fast as MPFR (http://mpfr.org), though it can be a bit slower at low precision, and around twice as fast as MPFI (https://perso.ens-lyon.fr/nathalie.revol/software.html). Transcendental functions in Arb are quite well optimized and should generally be faster than any other arbitrary-precision software currently available. The following table compares the time in seconds to evaluate the Gauss hypergeometric function `2F1(1/2, 1/4, 1, z)` at the complex number `z = 5^(1/2) + 7^(1/2)i`, to a given number of decimal digits (Arb 2.8-git and mpmath 0.19 on an 1.90 GHz Intel i5-4300U, Mathematica 9.0 on a 3.07 GHz Intel Xeon X5675). | Digits | Mathematica | mpmath | Arb | | -------:|:------------|:-----------|:-----------| | 10 | 0.00066 | 0.00065 | 0.000071 | | 100 | 0.0039 | 0.0012 | 0.00048 | | 1000 | 0.23 | 1.2 | 0.0093 | | 10000 | 42.6 | 84 | 0.56 | ## Dependencies, installation, and interfaces Arb depends on FLINT (http://flintlib.org/), either GMP (http://gmplib.org) or MPIR (http://mpir.org), and MPFR (http://mpfr.org). See http://arblib.org/setup.html for instructions on building and installing Arb directly from the source code. Arb might also be available (or coming soon) as a package for your Linux distribution. SageMath () includes Arb as a standard package and contains a high-level Python interface. See the SageMath documentation for RealBallField (http://doc.sagemath.org/html/en/reference/rings_numerical/sage/rings/real_arb.html) and ComplexBallField (http://doc.sagemath.org/html/en/reference/rings_numerical/sage/rings/complex_arb.html). Nemo () is a computer algebra package for the Julia programming language which includes a high-level Julia interface to Arb. The Nemo installation script will create a local installation of Arb along with other dependencies. A standalone Python interface to FLINT and Arb is also available (). A separate wrapper of transcendental functions for use with the C99 `complex double` type is available (). Other third-party wrappers include: * A Julia interface: https://github.com/JeffreySarnoff/ArbNumerics.jl * Java wrapper using JNA: https://github.com/crowlogic/arb/ arb-2.22.1/acb.h000066400000000000000000000726101417376376500132710ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_H #define ACB_H #ifdef ACB_INLINES_C #define ACB_INLINE #else #define ACB_INLINE static __inline__ #endif #include #include "arf.h" #include "arb.h" #ifdef __cplusplus extern "C" { #endif typedef struct { arb_struct real; arb_struct imag; } acb_struct; typedef acb_struct acb_t[1]; typedef acb_struct * acb_ptr; typedef const acb_struct * acb_srcptr; #define acb_realref(x) (&(x)->real) #define acb_imagref(x) (&(x)->imag) ACB_INLINE void acb_init(acb_t x) { arb_init(acb_realref(x)); arb_init(acb_imagref(x)); } void acb_clear(acb_t x); acb_ptr _acb_vec_init(slong n); void _acb_vec_clear(acb_ptr v, slong n); ACB_INLINE arb_ptr acb_real_ptr(acb_t z) { return acb_realref(z); } ACB_INLINE arb_ptr acb_imag_ptr(acb_t z) { return acb_imagref(z); } ACB_INLINE void acb_get_real(arb_t re, const acb_t z) { arb_set(re, acb_realref(z)); } ACB_INLINE void acb_get_imag(arb_t im, const acb_t z) { arb_set(im, acb_imagref(z)); } ACB_INLINE void acb_get_mid(acb_t res, const acb_t x) { arb_get_mid_arb(acb_realref(res), acb_realref(x)); arb_get_mid_arb(acb_imagref(res), acb_imagref(x)); } ACB_INLINE int acb_is_zero(const acb_t z) { return arb_is_zero(acb_realref(z)) && arb_is_zero(acb_imagref(z)); } ACB_INLINE int acb_is_one(const acb_t z) { return arb_is_one(acb_realref(z)) && arb_is_zero(acb_imagref(z)); } ACB_INLINE int acb_is_exact(const acb_t z) { return arb_is_exact(acb_realref(z)) && arb_is_exact(acb_imagref(z)); } ACB_INLINE int acb_is_int(const acb_t z) { return arb_is_zero(acb_imagref(z)) && arb_is_int(acb_realref(z)); } ACB_INLINE int acb_is_int_2exp_si(const acb_t z, slong e) { return arb_is_zero(acb_imagref(z)) && arb_is_int_2exp_si(acb_realref(z), e); } ACB_INLINE void acb_zero(acb_t z) { arb_zero(acb_realref(z)); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_one(acb_t z) { arb_one(acb_realref(z)); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_onei(acb_t z) { arb_zero(acb_realref(z)); arb_one(acb_imagref(z)); } ACB_INLINE void acb_set(acb_t z, const acb_t x) { arb_set(acb_realref(z), acb_realref(x)); arb_set(acb_imagref(z), acb_imagref(x)); } ACB_INLINE void acb_set_round(acb_t z, const acb_t x, slong prec) { arb_set_round(acb_realref(z), acb_realref(x), prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_neg_round(acb_t z, const acb_t x, slong prec) { arb_neg_round(acb_realref(z), acb_realref(x), prec); arb_neg_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_swap(acb_t z, acb_t x) { arb_swap(acb_realref(z), acb_realref(x)); arb_swap(acb_imagref(z), acb_imagref(x)); } ACB_INLINE int acb_equal(const acb_t x, const acb_t y) { return arb_equal(acb_realref(x), acb_realref(y)) && arb_equal(acb_imagref(x), acb_imagref(y)); } ACB_INLINE int acb_equal_si(const acb_t x, slong y) { return arb_equal_si(acb_realref(x), y) && arb_is_zero(acb_imagref(x)); } ACB_INLINE int acb_eq(const acb_t x, const acb_t y) { return arb_eq(acb_realref(x), acb_realref(y)) && arb_eq(acb_imagref(x), acb_imagref(y)); } ACB_INLINE int acb_ne(const acb_t x, const acb_t y) { return arb_ne(acb_realref(x), acb_realref(y)) || arb_ne(acb_imagref(x), acb_imagref(y)); } ACB_INLINE int acb_overlaps(const acb_t x, const acb_t y) { return arb_overlaps(acb_realref(x), acb_realref(y)) && arb_overlaps(acb_imagref(x), acb_imagref(y)); } ACB_INLINE int acb_contains_zero(const acb_t x) { return arb_contains_zero(acb_realref(x)) && arb_contains_zero(acb_imagref(x)); } ACB_INLINE int acb_contains_fmpq(const acb_t x, const fmpq_t y) { return arb_contains_fmpq(acb_realref(x), y) && arb_contains_zero(acb_imagref(x)); } ACB_INLINE int acb_contains_fmpz(const acb_t x, const fmpz_t y) { return arb_contains_fmpz(acb_realref(x), y) && arb_contains_zero(acb_imagref(x)); } ACB_INLINE int acb_contains(const acb_t x, const acb_t y) { return arb_contains(acb_realref(x), acb_realref(y)) && arb_contains(acb_imagref(x), acb_imagref(y)); } ACB_INLINE int acb_contains_interior(const acb_t x, const acb_t y) { return arb_contains_interior(acb_realref(x), acb_realref(y)) && arb_contains_interior(acb_imagref(x), acb_imagref(y)); } ACB_INLINE void acb_set_ui(acb_t z, ulong c) { arb_set_ui(acb_realref(z), c); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_set_d(acb_t z, double c) { arb_set_d(acb_realref(z), c); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_set_si(acb_t z, slong c) { arb_set_si(acb_realref(z), c); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_set_si_si(acb_t z, slong x, slong y) { arb_set_si(acb_realref(z), x); arb_set_si(acb_imagref(z), y); } ACB_INLINE void acb_set_d_d(acb_t z, double x, double y) { arb_set_d(acb_realref(z), x); arb_set_d(acb_imagref(z), y); } ACB_INLINE void acb_set_fmpz(acb_t z, const fmpz_t c) { arb_set_fmpz(acb_realref(z), c); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_set_fmpz_fmpz(acb_t z, const fmpz_t x, const fmpz_t y) { arb_set_fmpz(acb_realref(z), x); arb_set_fmpz(acb_imagref(z), y); } ACB_INLINE void acb_set_round_fmpz(acb_t z, const fmpz_t y, slong prec) { arb_set_round_fmpz(acb_realref(z), y, prec); arb_zero(acb_imagref(z)); } int acb_contains_int(const acb_t x); int acb_get_unique_fmpz(fmpz_t z, const acb_t x); ACB_INLINE void acb_set_fmpq(acb_t z, const fmpq_t c, slong prec) { arb_set_fmpq(acb_realref(z), c, prec); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_set_arb(acb_t z, const arb_t c) { arb_set(acb_realref(z), c); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_set_arb_arb(acb_t z, const arb_t x, const arb_t y) { arb_set(acb_realref(z), x); arb_set(acb_imagref(z), y); } ACB_INLINE void acb_set_round_arb(acb_t z, const arb_t x, slong prec) { arb_set_round(acb_realref(z), x, prec); arb_zero(acb_imagref(z)); } ACB_INLINE void acb_trim(acb_t z, const acb_t x) { arb_trim(acb_realref(z), acb_realref(x)); arb_trim(acb_imagref(z), acb_imagref(x)); } ACB_INLINE void acb_add_error_arf(acb_t x, const arf_t err) { arb_add_error_arf(acb_realref(x), err); arb_add_error_arf(acb_imagref(x), err); } ACB_INLINE void acb_add_error_mag(acb_t x, const mag_t err) { arb_add_error_mag(acb_realref(x), err); arb_add_error_mag(acb_imagref(x), err); } ACB_INLINE void acb_add_error_arb(acb_t x, const arb_t err) { arb_add_error(acb_realref(x), err); arb_add_error(acb_imagref(x), err); } void acb_get_mag(mag_t z, const acb_t x); void acb_get_mag_lower(mag_t z, const acb_t x); void acb_get_abs_ubound_arf(arf_t u, const acb_t z, slong prec); void acb_get_abs_lbound_arf(arf_t u, const acb_t z, slong prec); void acb_get_rad_ubound_arf(arf_t u, const acb_t z, slong prec); ACB_INLINE void acb_union(acb_t res, const acb_t x, const acb_t y, slong prec) { arb_union(acb_realref(res), acb_realref(x), acb_realref(y), prec); arb_union(acb_imagref(res), acb_imagref(x), acb_imagref(y), prec); } void acb_arg(arb_t r, const acb_t z, slong prec); void acb_sgn(acb_t res, const acb_t z, slong prec); void acb_csgn(arb_t res, const acb_t z); void acb_real_abs(acb_t res, const acb_t z, int analytic, slong prec); void acb_real_sgn(acb_t res, const acb_t z, int analytic, slong prec); void acb_real_heaviside(acb_t res, const acb_t z, int analytic, slong prec); void acb_real_floor(acb_t res, const acb_t z, int analytic, slong prec); void acb_real_ceil(acb_t res, const acb_t z, int analytic, slong prec); void acb_real_max(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec); void acb_real_min(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec); void acb_real_sqrtpos(acb_t res, const acb_t z, int analytic, slong prec); void acb_sqrt_analytic(acb_t res, const acb_t z, int analytic, slong prec); void acb_rsqrt_analytic(acb_t res, const acb_t z, int analytic, slong prec); void acb_log_analytic(acb_t res, const acb_t z, int analytic, slong prec); void acb_pow_analytic(acb_t res, const acb_t z, const acb_t w, int analytic, slong prec); ACB_INLINE void acb_add(acb_t z, const acb_t x, const acb_t y, slong prec) { arb_add(acb_realref(z), acb_realref(x), acb_realref(y), prec); arb_add(acb_imagref(z), acb_imagref(x), acb_imagref(y), prec); } ACB_INLINE void acb_sub(acb_t z, const acb_t x, const acb_t y, slong prec) { arb_sub(acb_realref(z), acb_realref(x), acb_realref(y), prec); arb_sub(acb_imagref(z), acb_imagref(x), acb_imagref(y), prec); } ACB_INLINE void acb_add_si(acb_t z, const acb_t x, ulong c, slong prec) { arb_add_si(acb_realref(z), acb_realref(x), c, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_add_ui(acb_t z, const acb_t x, ulong c, slong prec) { arb_add_ui(acb_realref(z), acb_realref(x), c, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_sub_si(acb_t z, const acb_t x, ulong c, slong prec) { arb_sub_si(acb_realref(z), acb_realref(x), c, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_sub_ui(acb_t z, const acb_t x, ulong c, slong prec) { arb_sub_ui(acb_realref(z), acb_realref(x), c, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_add_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) { arb_add_fmpz(acb_realref(z), acb_realref(x), y, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_add_arb(acb_t z, const acb_t x, const arb_t y, slong prec) { arb_add(acb_realref(z), acb_realref(x), y, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_sub_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) { arb_sub_fmpz(acb_realref(z), acb_realref(x), y, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_sub_arb(acb_t z, const acb_t x, const arb_t y, slong prec) { arb_sub(acb_realref(z), acb_realref(x), y, prec); arb_set_round(acb_imagref(z), acb_imagref(x), prec); } ACB_INLINE void acb_neg(acb_t z, const acb_t x) { arb_neg(acb_realref(z), acb_realref(x)); arb_neg(acb_imagref(z), acb_imagref(x)); } ACB_INLINE void acb_conj(acb_t z, const acb_t x) { arb_set(acb_realref(z), acb_realref(x)); arb_neg(acb_imagref(z), acb_imagref(x)); } ACB_INLINE void acb_abs(arb_t u, const acb_t z, slong prec) { arb_hypot(u, acb_realref(z), acb_imagref(z), prec); } ACB_INLINE void acb_mul_ui(acb_t z, const acb_t x, ulong y, slong prec) { arb_mul_ui(acb_realref(z), acb_realref(x), y, prec); arb_mul_ui(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_mul_si(acb_t z, const acb_t x, slong y, slong prec) { arb_mul_si(acb_realref(z), acb_realref(x), y, prec); arb_mul_si(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_mul_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) { arb_mul_fmpz(acb_realref(z), acb_realref(x), y, prec); arb_mul_fmpz(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_mul_arb(acb_t z, const acb_t x, const arb_t y, slong prec) { arb_mul(acb_realref(z), acb_realref(x), y, prec); arb_mul(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_mul_onei(acb_t z, const acb_t x) { if (z == x) { arb_swap(acb_realref(z), acb_imagref(z)); arb_neg(acb_realref(z), acb_realref(z)); } else { arb_neg(acb_realref(z), acb_imagref(x)); arb_set(acb_imagref(z), acb_realref(x)); } } ACB_INLINE void acb_div_onei(acb_t z, const acb_t x) { if (z == x) { arb_swap(acb_realref(z), acb_imagref(z)); arb_neg(acb_imagref(z), acb_imagref(z)); } else { arb_set(acb_realref(z), acb_imagref(x)); arb_neg(acb_imagref(z), acb_realref(x)); } } void acb_mul(acb_t z, const acb_t x, const acb_t y, slong prec); void acb_mul_naive(acb_t z, const acb_t x, const acb_t y, slong prec); ACB_INLINE void acb_mul_2exp_si(acb_t z, const acb_t x, slong e) { arb_mul_2exp_si(acb_realref(z), acb_realref(x), e); arb_mul_2exp_si(acb_imagref(z), acb_imagref(x), e); } ACB_INLINE void acb_mul_2exp_fmpz(acb_t z, const acb_t x, const fmpz_t c) { arb_mul_2exp_fmpz(acb_realref(z), acb_realref(x), c); arb_mul_2exp_fmpz(acb_imagref(z), acb_imagref(x), c); } void acb_addmul(acb_t z, const acb_t x, const acb_t y, slong prec); void acb_submul(acb_t z, const acb_t x, const acb_t y, slong prec); ACB_INLINE void acb_addmul_ui(acb_t z, const acb_t x, ulong y, slong prec) { arb_addmul_ui(acb_realref(z), acb_realref(x), y, prec); arb_addmul_ui(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_addmul_si(acb_t z, const acb_t x, slong y, slong prec) { arb_addmul_si(acb_realref(z), acb_realref(x), y, prec); arb_addmul_si(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_submul_ui(acb_t z, const acb_t x, ulong y, slong prec) { arb_submul_ui(acb_realref(z), acb_realref(x), y, prec); arb_submul_ui(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_submul_si(acb_t z, const acb_t x, slong y, slong prec) { arb_submul_si(acb_realref(z), acb_realref(x), y, prec); arb_submul_si(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_addmul_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) { arb_addmul_fmpz(acb_realref(z), acb_realref(x), y, prec); arb_addmul_fmpz(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_submul_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) { arb_submul_fmpz(acb_realref(z), acb_realref(x), y, prec); arb_submul_fmpz(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_addmul_arb(acb_t z, const acb_t x, const arb_t y, slong prec) { arb_addmul(acb_realref(z), acb_realref(x), y, prec); arb_addmul(acb_imagref(z), acb_imagref(x), y, prec); } ACB_INLINE void acb_submul_arb(acb_t z, const acb_t x, const arb_t y, slong prec) { arb_submul(acb_realref(z), acb_realref(x), y, prec); arb_submul(acb_imagref(z), acb_imagref(x), y, prec); } void acb_dot_simple(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec); void acb_dot_precise(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec); void acb_dot(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec); void acb_approx_dot(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec); void acb_dot_ui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec); void acb_dot_si(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const slong * y, slong ystep, slong len, slong prec); void acb_dot_uiui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec); void acb_dot_siui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec); void acb_dot_fmpz(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const fmpz * y, slong ystep, slong len, slong prec); void acb_inv(acb_t z, const acb_t x, slong prec); void acb_div(acb_t z, const acb_t x, const acb_t y, slong prec); ACB_INLINE void acb_div_ui(acb_t z, const acb_t x, ulong c, slong prec) { arb_div_ui(acb_realref(z), acb_realref(x), c, prec); arb_div_ui(acb_imagref(z), acb_imagref(x), c, prec); } ACB_INLINE void acb_div_si(acb_t z, const acb_t x, slong c, slong prec) { arb_div_si(acb_realref(z), acb_realref(x), c, prec); arb_div_si(acb_imagref(z), acb_imagref(x), c, prec); } ACB_INLINE void acb_div_arb(acb_t z, const acb_t x, const arb_t c, slong prec) { arb_div(acb_realref(z), acb_realref(x), c, prec); arb_div(acb_imagref(z), acb_imagref(x), c, prec); } ACB_INLINE void acb_div_fmpz(acb_t z, const acb_t x, const fmpz_t c, slong prec) { arb_div_fmpz(acb_realref(z), acb_realref(x), c, prec); arb_div_fmpz(acb_imagref(z), acb_imagref(x), c, prec); } void acb_cube(acb_t y, const acb_t x, slong prec); void acb_pow_fmpz(acb_t y, const acb_t b, const fmpz_t e, slong prec); void acb_pow_ui(acb_t y, const acb_t b, ulong e, slong prec); void acb_pow_si(acb_t y, const acb_t b, slong e, slong prec); ACB_INLINE void acb_const_pi(acb_t x, slong prec) { arb_const_pi(acb_realref(x), prec); arb_zero(acb_imagref(x)); } void acb_log(acb_t r, const acb_t z, slong prec); void acb_log1p(acb_t r, const acb_t z, slong prec); void acb_exp(acb_t r, const acb_t z, slong prec); void acb_exp_pi_i(acb_t r, const acb_t z, slong prec); void acb_exp_invexp(acb_t r, acb_t s, const acb_t z, slong prec); void acb_expm1(acb_t r, const acb_t z, slong prec); void acb_sin(acb_t r, const acb_t z, slong prec); void acb_cos(acb_t r, const acb_t z, slong prec); void acb_sin_cos(acb_t s, acb_t c, const acb_t z, slong prec); void acb_tan(acb_t r, const acb_t z, slong prec); void acb_cot(acb_t r, const acb_t z, slong prec); void acb_asin(acb_t r, const acb_t z, slong prec); void acb_acos(acb_t r, const acb_t z, slong prec); void acb_atan(acb_t r, const acb_t z, slong prec); void acb_asinh(acb_t r, const acb_t z, slong prec); void acb_acosh(acb_t r, const acb_t z, slong prec); void acb_atanh(acb_t r, const acb_t z, slong prec); ACB_INLINE void acb_sinh(acb_t y, const acb_t x, slong prec) { acb_mul_onei(y, x); acb_sin(y, y, prec); acb_div_onei(y, y); } ACB_INLINE void acb_cosh(acb_t y, const acb_t x, slong prec) { acb_mul_onei(y, x); acb_cos(y, y, prec); } ACB_INLINE void acb_sinh_cosh(acb_t y, acb_t z, const acb_t x, slong prec) { acb_mul_onei(y, x); acb_sin_cos(y, z, y, prec); acb_div_onei(y, y); } ACB_INLINE void acb_tanh(acb_t y, const acb_t x, slong prec) { acb_mul_onei(y, x); acb_tan(y, y, prec); acb_div_onei(y, y); } ACB_INLINE void acb_coth(acb_t y, const acb_t x, slong prec) { acb_mul_onei(y, x); acb_cot(y, y, prec); acb_mul_onei(y, y); } void acb_sech(acb_t r, const acb_t z, slong prec); void acb_csch(acb_t r, const acb_t z, slong prec); ACB_INLINE void acb_sec(acb_t y, const acb_t x, slong prec) { acb_mul_onei(y, x); acb_sech(y, y, prec); } ACB_INLINE void acb_csc(acb_t y, const acb_t x, slong prec) { acb_mul_onei(y, x); acb_csch(y, y, prec); acb_mul_onei(y, y); } void acb_sin_pi(acb_t r, const acb_t z, slong prec); void acb_cos_pi(acb_t r, const acb_t z, slong prec); void acb_sin_cos_pi(acb_t s, acb_t c, const acb_t z, slong prec); void acb_tan_pi(acb_t r, const acb_t z, slong prec); void acb_cot_pi(acb_t r, const acb_t z, slong prec); void acb_csc_pi(acb_t y, const acb_t x, slong prec); void acb_sinc(acb_t res, const acb_t z, slong prec); void acb_sinc_pi(acb_t res, const acb_t z, slong prec); void acb_pow_arb(acb_t z, const acb_t x, const arb_t y, slong prec); void acb_pow(acb_t r, const acb_t x, const acb_t y, slong prec); void acb_sqrt(acb_t y, const acb_t x, slong prec); void acb_rsqrt(acb_t y, const acb_t x, slong prec); void acb_root_ui(acb_t y, const acb_t x, ulong k, slong prec); void acb_quadratic_roots_fmpz(acb_t r1, acb_t r2, const fmpz_t a, const fmpz_t b, const fmpz_t c, slong prec); void acb_chebyshev_t_ui(acb_t a, ulong n, const acb_t x, slong prec); void acb_chebyshev_t2_ui(acb_t a, acb_t b, ulong n, const acb_t x, slong prec); void acb_chebyshev_u_ui(acb_t a, ulong n, const acb_t x, slong prec); void acb_chebyshev_u2_ui(acb_t a, acb_t b, ulong n, const acb_t x, slong prec); void acb_rising_ui(acb_t z, const acb_t x, ulong n, slong prec); void acb_rising(acb_t z, const acb_t x, const acb_t n, slong prec); void acb_rising2_ui(acb_t u, acb_t v, const acb_t x, ulong n, slong prec); void acb_rising_ui_get_mag(mag_t bound, const acb_t s, ulong n); void acb_gamma(acb_t y, const acb_t x, slong prec); void acb_rgamma(acb_t y, const acb_t x, slong prec); void acb_lgamma(acb_t y, const acb_t x, slong prec); void acb_log_sin_pi(acb_t res, const acb_t z, slong prec); void acb_digamma(acb_t y, const acb_t x, slong prec); void acb_zeta(acb_t z, const acb_t s, slong prec); void acb_hurwitz_zeta(acb_t z, const acb_t s, const acb_t a, slong prec); void acb_polygamma(acb_t res, const acb_t s, const acb_t z, slong prec); void acb_bernoulli_poly_ui(acb_t res, ulong n, const acb_t x, slong prec); void acb_log_barnes_g(acb_t res, const acb_t z, slong prec); void acb_barnes_g(acb_t res, const acb_t z, slong prec); void acb_polylog(acb_t w, const acb_t s, const acb_t z, slong prec); void acb_polylog_si(acb_t w, slong s, const acb_t z, slong prec); void acb_agm1(acb_t m, const acb_t z, slong prec); void acb_agm1_cpx(acb_ptr m, const acb_t z, slong len, slong prec); void acb_agm(acb_t res, const acb_t a, const acb_t b, slong prec); #define ACB_LAMBERTW_LEFT 2 #define ACB_LAMBERTW_MIDDLE 4 void acb_lambertw_asymp(acb_t res, const acb_t z, const fmpz_t k, slong L, slong M, slong prec); int acb_lambertw_check_branch(const acb_t w, const fmpz_t k, slong prec); void acb_lambertw_bound_deriv(mag_t res, const acb_t z, const acb_t ez1, const fmpz_t k); void acb_lambertw(acb_t res, const acb_t z, const fmpz_t k, int flags, slong prec); ACB_INLINE void acb_sqr(acb_t res, const acb_t val, slong prec) { acb_mul(res, val, val, prec); } ACB_INLINE int acb_is_finite(const acb_t x) { return arb_is_finite(acb_realref(x)) && arb_is_finite(acb_imagref(x)); } ACB_INLINE void acb_indeterminate(acb_t x) { arb_indeterminate(acb_realref(x)); arb_indeterminate(acb_imagref(x)); } ACB_INLINE acb_ptr _acb_vec_entry_ptr(acb_ptr vec, slong i) { return vec + i; } ACB_INLINE void _acb_vec_zero(acb_ptr A, slong n) { slong i; for (i = 0; i < n; i++) acb_zero(A + i); } ACB_INLINE int _acb_vec_is_zero(acb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) if (!acb_is_zero(vec + i)) return 0; return 1; } ACB_INLINE void _acb_vec_set(acb_ptr res, acb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) acb_set(res + i, vec + i); } ACB_INLINE void _acb_vec_set_round(acb_ptr res, acb_srcptr vec, slong len, slong prec) { slong i; for (i = 0; i < len; i++) acb_set_round(res + i, vec + i, prec); } ACB_INLINE void _acb_vec_swap(acb_ptr res, acb_ptr vec, slong len) { slong i; for (i = 0; i < len; i++) acb_swap(res + i, vec + i); } ACB_INLINE void _acb_vec_neg(acb_ptr res, acb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) acb_neg(res + i, vec + i); } ACB_INLINE void _acb_vec_add(acb_ptr res, acb_srcptr vec1, acb_srcptr vec2, slong len, slong prec) { slong i; for (i = 0; i < len; i++) acb_add(res + i, vec1 + i, vec2 + i, prec); } ACB_INLINE void _acb_vec_sub(acb_ptr res, acb_srcptr vec1, acb_srcptr vec2, slong len, slong prec) { slong i; for (i = 0; i < len; i++) acb_sub(res + i, vec1 + i, vec2 + i, prec); } ACB_INLINE void _acb_vec_scalar_submul(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) { slong i; for (i = 0; i < len; i++) acb_submul(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_addmul(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) { slong i; for (i = 0; i < len; i++) acb_addmul(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_mul(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) { slong i; for (i = 0; i < len; i++) acb_mul(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_mul_ui(acb_ptr res, acb_srcptr vec, slong len, ulong c, slong prec) { slong i; for (i = 0; i < len; i++) acb_mul_ui(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_mul_2exp_si(acb_ptr res, acb_srcptr vec, slong len, slong c) { slong i; for (i = 0; i < len; i++) acb_mul_2exp_si(res + i, vec + i, c); } ACB_INLINE void _acb_vec_scalar_mul_onei(acb_ptr res, acb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) acb_mul_onei(res + i, vec + i); } ACB_INLINE void _acb_vec_scalar_div_ui(acb_ptr res, acb_srcptr vec, slong len, ulong c, slong prec) { slong i; for (i = 0; i < len; i++) acb_div_ui(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_div(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) { slong i; for (i = 0; i < len; i++) acb_div(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_mul_arb(acb_ptr res, acb_srcptr vec, slong len, const arb_t c, slong prec) { slong i; for (i = 0; i < len; i++) acb_mul_arb(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_div_arb(acb_ptr res, acb_srcptr vec, slong len, const arb_t c, slong prec) { slong i; for (i = 0; i < len; i++) { arb_div(acb_realref(res + i), acb_realref(vec + i), c, prec); arb_div(acb_imagref(res + i), acb_imagref(vec + i), c, prec); } } ACB_INLINE void _acb_vec_scalar_mul_fmpz(acb_ptr res, acb_srcptr vec, slong len, const fmpz_t c, slong prec) { slong i; for (i = 0; i < len; i++) acb_mul_fmpz(res + i, vec + i, c, prec); } ACB_INLINE void _acb_vec_scalar_div_fmpz(acb_ptr res, acb_srcptr vec, slong len, const fmpz_t c, slong prec) { slong i; for (i = 0; i < len; i++) acb_div_fmpz(res + i, vec + i, c, prec); } ACB_INLINE void acb_fprint(FILE * file, const acb_t x) { flint_fprintf(file, "("); arb_fprint(file, acb_realref(x)); flint_fprintf(file, ", "); arb_fprint(file, acb_imagref(x)); flint_fprintf(file, ")"); } ACB_INLINE void acb_print(const acb_t x) { acb_fprint(stdout, x); } void acb_fprintd(FILE * file, const acb_t z, slong digits); ACB_INLINE void acb_printd(const acb_t z, slong digits) { acb_fprintd(stdout, z, digits); } void acb_fprintn(FILE * fp, const acb_t z, slong digits, ulong flags); ACB_INLINE void acb_printn(const acb_t x, slong digits, ulong flags) { acb_fprintn(stdout, x, digits, flags); } ACB_INLINE void _acb_vec_printn(acb_srcptr vec, slong len, slong ndigits, ulong flags) { slong i; for (i = 0; i < len; i++) { acb_printn(vec + i, ndigits, flags); if (i < len - 1) flint_printf(", "); } } void acb_randtest(acb_t z, flint_rand_t state, slong prec, slong mag_bits); void acb_randtest_special(acb_t z, flint_rand_t state, slong prec, slong mag_bits); void acb_randtest_precise(acb_t z, flint_rand_t state, slong prec, slong mag_bits); void acb_randtest_param(acb_t z, flint_rand_t state, slong prec, slong mag_bits); slong acb_rel_error_bits(const acb_t x); ACB_INLINE slong acb_rel_accuracy_bits(const acb_t x) { return -acb_rel_error_bits(x); } slong acb_rel_one_accuracy_bits(const acb_t x); ACB_INLINE slong acb_bits(const acb_t x) { slong b1, b2; b1 = arb_bits(acb_realref(x)); b2 = arb_bits(acb_imagref(x)); return FLINT_MAX(b1, b2); } ACB_INLINE int acb_is_real(const acb_t x) { return arb_is_zero(acb_imagref(x)); } ACB_INLINE int _acb_vec_is_real(acb_srcptr v, slong len) { slong i; for (i = 0; i < len; i++) { if (!acb_is_real(v + i)) return 0; } return 1; } ACB_INLINE slong _acb_vec_bits(acb_srcptr vec, slong len) { return _arb_vec_bits((arb_srcptr) vec, 2 * len); } void _acb_vec_set_powers(acb_ptr xs, const acb_t x, slong len, slong prec); ACB_INLINE void _acb_vec_add_error_arf_vec(acb_ptr res, arf_srcptr err, slong len) { slong i; for (i = 0; i < len; i++) acb_add_error_arf(res + i, err + i); } ACB_INLINE void _acb_vec_add_error_mag_vec(acb_ptr res, mag_srcptr err, slong len) { slong i; for (i = 0; i < len; i++) { mag_add(arb_radref(acb_realref(res + i)), arb_radref(acb_realref(res + i)), err + i); mag_add(arb_radref(acb_imagref(res + i)), arb_radref(acb_imagref(res + i)), err + i); } } ACB_INLINE void _acb_vec_indeterminate(acb_ptr vec, slong len) { _arb_vec_indeterminate((arb_ptr) vec, 2 * len); } ACB_INLINE void _acb_vec_trim(acb_ptr res, acb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) acb_trim(res + i, vec + i); } ACB_INLINE int _acb_vec_get_unique_fmpz_vec(fmpz * res, acb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) if (!acb_get_unique_fmpz(res + i, vec + i)) return 0; return 1; } /* sort complex numbers in a nice-to-display order */ void _acb_vec_sort_pretty(acb_ptr vec, slong len); /* roots of unity */ void acb_unit_root(acb_t res, ulong order, slong prec); void _acb_vec_unit_roots(acb_ptr z, slong order, slong len, slong prec); ACB_INLINE slong acb_allocated_bytes(const acb_t x) { return arb_allocated_bytes(acb_realref(x)) + arb_allocated_bytes(acb_imagref(x)); } ACB_INLINE slong _acb_vec_allocated_bytes(acb_srcptr vec, slong len) { return _arb_vec_allocated_bytes((arb_srcptr) vec, 2 * len); } ACB_INLINE double _acb_vec_estimate_allocated_bytes(slong len, slong prec) { return 2 * _arb_vec_estimate_allocated_bytes(len, prec); } #ifdef __cplusplus } #endif #endif arb-2.22.1/acb/000077500000000000000000000000001417376376500131125ustar00rootroot00000000000000arb-2.22.1/acb/acos.c000066400000000000000000000020531417376376500142030ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_acos(acb_t res, const acb_t z, slong prec) { if (acb_is_one(z)) { acb_zero(res); } else { acb_t t; acb_init(t); acb_one(t); if (arb_is_zero(acb_imagref(z)) && arb_gt(acb_realref(z), acb_realref(t))) { /* pure imaginary on (1,inf) */ acb_asin(res, z, prec); acb_neg(res, res); arb_zero(acb_realref(res)); } else { acb_asin(res, z, prec); acb_const_pi(t, prec); acb_mul_2exp_si(t, t, -1); acb_sub(res, t, res, prec); } acb_clear(t); } } arb-2.22.1/acb/acosh.c000066400000000000000000000023241417376376500143540ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_acosh(acb_t res, const acb_t z, slong prec) { if (acb_is_one(z)) { acb_zero(res); } else { acb_t t, u; acb_init(t); acb_init(u); acb_add_ui(t, z, 1, prec); acb_sub_ui(u, z, 1, prec); acb_sqrt(t, t, prec); acb_sqrt(u, u, prec); acb_mul(t, t, u, prec); acb_add(t, t, z, prec); if (!arb_is_zero(acb_imagref(z))) { acb_log(res, t, prec); } else { /* pure imaginary on (-1,1) */ arb_abs(acb_realref(u), acb_realref(z)); arb_one(acb_imagref(u)); acb_log(res, t, prec); if (arb_lt(acb_realref(u), acb_imagref(u))) arb_zero(acb_realref(res)); } acb_clear(t); acb_clear(u); } } arb-2.22.1/acb/addmul.c000066400000000000000000000017661417376376500145360ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_addmul(acb_t z, const acb_t x, const acb_t y, slong prec) { if (arb_is_zero(acb_imagref(y))) { arb_addmul(acb_imagref(z), acb_imagref(x), acb_realref(y), prec); arb_addmul(acb_realref(z), acb_realref(x), acb_realref(y), prec); } else if (arb_is_zero(acb_imagref(x))) { arb_addmul(acb_imagref(z), acb_imagref(y), acb_realref(x), prec); arb_addmul(acb_realref(z), acb_realref(y), acb_realref(x), prec); } else { acb_t t; acb_init(t); acb_mul(t, x, y, prec); acb_add(z, z, t, prec); acb_clear(t); } } arb-2.22.1/acb/agm.c000066400000000000000000000061731417376376500140310ustar00rootroot00000000000000/* Copyright (C) 2020 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void mag_agm(mag_t res, const mag_t x, const mag_t y); static void agm_helper(acb_t res, const acb_t a, const acb_t b, slong prec) { if (acb_rel_accuracy_bits(b) >= acb_rel_accuracy_bits(a)) { acb_div(res, a, b, prec); acb_agm1(res, res, prec); acb_mul(res, res, b, prec); } else { acb_div(res, b, a, prec); acb_agm1(res, res, prec); acb_mul(res, res, a, prec); } } void acb_agm(acb_t res, const acb_t a, const acb_t b, slong prec) { acb_t t, u, v; if (!acb_is_finite(a) || !acb_is_finite(b)) { acb_indeterminate(res); return; } if (acb_is_zero(a) || acb_is_zero(b)) { acb_zero(res); return; } if (arb_is_zero(acb_imagref(a)) && arb_is_zero(acb_imagref(b))) { if (arb_is_nonnegative(acb_realref(a)) && arb_is_nonnegative(acb_realref(b))) { arb_agm(acb_realref(res), acb_realref(a), acb_realref(b), prec); arb_zero(acb_imagref(res)); return; } } if (acb_contains_zero(a) || acb_contains_zero(b)) { mag_t ra, rb; mag_init(ra); mag_init(rb); acb_get_mag(ra, a); acb_get_mag(rb, b); mag_agm(ra, ra, rb); acb_zero(res); acb_add_error_mag(res, ra); mag_clear(ra); mag_clear(rb); return; } acb_init(t); acb_add(t, a, b, prec); acb_mul_2exp_si(t, t, -1); /* a ~= -b; bound magnitude */ if (acb_contains_zero(t)) { mag_t ra, rb; mag_init(ra); mag_init(rb); acb_get_mag(ra, a); acb_get_mag(rb, b); mag_mul(rb, ra, rb); mag_sqrt(rb, rb); acb_get_mag(ra, t); mag_agm(ra, ra, rb); acb_zero(res); acb_add_error_mag(res, ra); mag_clear(ra); mag_clear(rb); acb_clear(t); return; } /* Do the initial step with the optimal square root, reducing to agm1 */ acb_init(u); acb_init(v); acb_mul(u, a, b, prec); /* we can compute either square root here; avoid the branch cut */ if (arf_sgn(arb_midref(acb_realref(u))) >= 0) { acb_sqrt(u, u, prec); } else { acb_neg(u, u); acb_sqrt(u, u, prec); acb_mul_onei(u, u); } acb_div(v, t, u, prec); if (arb_is_nonnegative(acb_realref(v))) { agm_helper(res, t, u, prec); } else if (arb_is_negative(acb_realref(v))) { acb_neg(u, u); agm_helper(res, t, u, prec); } else { agm_helper(v, t, u, prec); acb_neg(u, u); agm_helper(res, t, u, prec); acb_union(res, res, v, prec); } acb_clear(t); acb_clear(u); acb_clear(v); } arb-2.22.1/acb/agm1.c000066400000000000000000000344351417376376500141140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #include "acb_poly.h" void mag_agm(mag_t res, const mag_t x, const mag_t y); /* Checks that |arg(z)| <= 3 pi / 4 */ static int acb_check_arg(const acb_t z) { mag_t re, im; int res; if (!arb_contains_negative(acb_realref(z))) return 1; mag_init(re); mag_init(im); arb_get_mag(re, acb_realref(z)); arb_get_mag_lower(im, acb_imagref(z)); res = mag_cmp(re, im) < 0; mag_clear(re); mag_clear(im); return res; } static void sqrtmul(acb_t c, const acb_t a, const acb_t b, slong prec) { if (arb_is_positive(acb_realref(a)) && arb_is_positive(acb_realref(b))) { acb_mul(c, a, b, prec); acb_sqrt(c, c, prec); } else if (arb_is_nonnegative(acb_imagref(a)) && arb_is_nonnegative(acb_imagref(b))) { acb_mul(c, a, b, prec); acb_neg(c, c); acb_sqrt(c, c, prec); acb_mul_onei(c, c); } else if (arb_is_nonpositive(acb_imagref(a)) && arb_is_nonpositive(acb_imagref(b))) { acb_mul(c, a, b, prec); acb_neg(c, c); acb_sqrt(c, c, prec); acb_mul_onei(c, c); acb_neg(c, c); } else { acb_t d; acb_init(d); acb_sqrt(c, a, prec); acb_sqrt(d, b, prec); acb_mul(c, c, d, prec); acb_clear(d); } } static void acb_agm_close_taylor(acb_t res, acb_t z, acb_t z2, const acb_t aplusb, const acb_t aminusb, const mag_t err, slong prec) { acb_div(z, aminusb, aplusb, prec); acb_sqr(z, z, prec); acb_sqr(z2, z, prec); acb_mul_si(res, z2, -469, prec); acb_addmul_si(res, z, -704, prec); acb_mul(res, res, z2, prec); acb_addmul_si(res, z2, -1280, prec); acb_mul_2exp_si(z, z, 12); acb_sub(res, res, z, prec); acb_add_ui(res, res, 16384, prec); acb_mul_2exp_si(res, res, -15); acb_add_error_mag(res, err); acb_mul(res, res, aplusb, prec); } static void acb_agm1_around_zero(acb_t res, const acb_t z, slong prec) { mag_t a, b; mag_init(a); mag_init(b); mag_one(a); acb_get_mag(b, z); mag_agm(a, a, b); acb_zero(res); acb_add_error_mag(res, a); mag_clear(a); mag_clear(b); } void acb_agm1_basecase(acb_t res, const acb_t z, slong prec) { acb_t a, b, t, u; mag_t err, err2; int isreal; isreal = acb_is_real(z) && arb_is_nonnegative(acb_realref(z)); if (isreal) { acb_init(a); acb_one(a); arb_agm(acb_realref(res), acb_realref(a), acb_realref(z), prec); arb_zero(acb_imagref(res)); acb_clear(a); return; } if (acb_is_zero(z)) { acb_zero(res); return; } if (acb_is_one(z)) { acb_one(res); return; } if (!acb_check_arg(z)) { acb_agm1_around_zero(res, z, prec); return; } acb_init(a); acb_init(b); acb_init(t); acb_init(u); mag_init(err); mag_init(err2); acb_one(a); acb_set_round(b, z, prec); while (1) { acb_sub(u, a, b, prec); if (acb_contains_zero(u)) { /* Dupont's thesis, p. 87: |M(z) - a_n| <= |a_n - b_n| */ acb_set(res, a); acb_get_mag(err, u); acb_add_error_mag(res, err); break; } acb_add(t, a, b, prec); acb_get_mag(err, u); acb_get_mag_lower(err2, t); mag_div(err, err, err2); mag_geom_series(err, err, 10); mag_mul_2exp_si(err, err, -6); if (mag_cmp_2exp_si(err, -prec) < 0) { acb_agm_close_taylor(res, a, b, t, u, err, prec); break; } acb_mul_2exp_si(t, t, -1); sqrtmul(u, a, b, prec); acb_swap(t, a); acb_swap(u, b); } acb_clear(a); acb_clear(b); acb_clear(t); acb_clear(u); mag_clear(err); mag_clear(err2); } /* Computes (M(z), M'(z)) using a finite difference. Assumes z exact, |arg(z)| <= 3 pi / 4. */ void acb_agm1_deriv_diff(acb_t Mz, acb_t Mzp, const acb_t z, slong prec) { mag_t err, t, C; fmpz_t rexp, hexp; acb_t u, v; slong wp, qexp; int isreal; if (!acb_is_exact(z) || !acb_is_finite(z) || acb_is_zero(z) || !acb_check_arg(z)) { acb_indeterminate(Mz); acb_indeterminate(Mzp); return; } isreal = acb_is_real(z) && arb_is_nonnegative(acb_realref(z)); /* |M^(k)(z) / k!| <= C * D^k where C = max(1, |z| + r), D = 1/r, and 0 < r < |z| M(z+h) - M(z-h) |--------------- - M'(z)| <= D^3 h^2 / (1 - D h) 2h M(z+h) + M(z-h) |--------------- - M(z)| <= D^2 h^2 / (1 - D h) 2 h D < 1. */ fmpz_init(hexp); fmpz_init(rexp); mag_init(err); mag_init(t); mag_init(C); acb_init(u); acb_init(v); /* choose r = 2^rexp such that r < |z| */ acb_get_mag_lower(t, z); fmpz_sub_ui(rexp, MAG_EXPREF(t), 2); /* Choose h = r/q = 2^hexp = 2^(rexp-qexp) with qexp = floor(prec/2) + 5 D = 1/r = 2^-rexp f(z) error <= C D^2 h^2 / (1-Dh) f'(z) error <= C D^3 h^2 / (1-Dh) 1/(1-Dh) < 2, hence: f(z) error < 2 C D^2 h^2 = C 2^(1-2*qexp) f'(z) error < 2 C D^3 h^2 = C 2^(1-rexp-2*qexp) */ /* C = max(1, |z| + r) */ acb_get_mag(C, z); mag_one(t); mag_mul_2exp_fmpz(t, t, rexp); mag_add(C, C, t); mag_one(t); mag_max(C, C, t); qexp = prec / 2 + 5; /* if (fmpz_sgn(rexp) < 0) qexp += fmpz_bits(rexp); */ /* compute h = 2^hexp */ fmpz_sub_ui(hexp, rexp, qexp); /* compute finite differences */ wp = prec + qexp + 5; acb_one(u); acb_mul_2exp_fmpz(u, u, hexp); acb_add(u, z, u, wp); acb_agm1_basecase(u, u, wp); acb_one(v); acb_mul_2exp_fmpz(v, v, hexp); acb_sub(v, z, v, wp); acb_agm1_basecase(v, v, wp); acb_add(Mz, u, v, prec); acb_sub(Mzp, u, v, prec); acb_mul_2exp_si(Mz, Mz, -1); acb_mul_2exp_si(Mzp, Mzp, -1); fmpz_neg(hexp, hexp); acb_mul_2exp_fmpz(Mzp, Mzp, hexp); /* add error */ mag_mul_2exp_si(err, C, 1 - 2 * qexp); if (isreal) arb_add_error_mag(acb_realref(Mz), err); else acb_add_error_mag(Mz, err); fmpz_neg(rexp, rexp); mag_mul_2exp_fmpz(err, err, rexp); if (isreal) arb_add_error_mag(acb_realref(Mzp), err); else acb_add_error_mag(Mzp, err); fmpz_clear(hexp); fmpz_clear(rexp); mag_clear(err); mag_clear(t); mag_clear(C); acb_clear(u); acb_clear(v); } /* For input z + eps First derivative bound: max(1, |z|+|eps|+r) / r Second derivative bound: 2 max(1, |z|+|eps|+r) / r^2 This is assuming that the circle at z with radius |eps| + r does not cross the negative half axis, which we check. */ void acb_agm1_deriv_right(acb_t Mz, acb_t Mzp, const acb_t z, slong prec) { if (acb_is_exact(z)) { acb_agm1_deriv_diff(Mz, Mzp, z, prec); } else { if (!acb_is_finite(z) || !acb_check_arg(z)) { acb_indeterminate(Mz); acb_indeterminate(Mzp); } else { acb_t t; mag_t r, eps, err, one; int isreal; acb_init(t); mag_init(r); mag_init(err); mag_init(one); mag_init(eps); isreal = acb_is_real(z) && arb_is_nonnegative(acb_realref(z)); mag_hypot(eps, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); /* choose r avoiding overlap with negative half axis */ if (arf_sgn(arb_midref(acb_realref(z))) < 0) arb_get_mag_lower(r, acb_imagref(z)); else acb_get_mag_lower(r, z); mag_mul_2exp_si(r, r, -1); if (mag_is_zero(r)) { acb_indeterminate(Mz); acb_indeterminate(Mzp); } else { acb_set(t, z); mag_zero(arb_radref(acb_realref(t))); mag_zero(arb_radref(acb_imagref(t))); acb_get_mag(err, z); mag_add(err, err, r); mag_add(err, err, eps); mag_one(one); mag_max(err, err, one); mag_mul(err, err, eps); acb_agm1_deriv_diff(Mz, Mzp, t, prec); mag_div(err, err, r); if (isreal) arb_add_error_mag(acb_realref(Mz), err); else acb_add_error_mag(Mz, err); mag_div(err, err, r); mag_mul_2exp_si(err, err, 1); if (isreal) arb_add_error_mag(acb_realref(Mzp), err); else acb_add_error_mag(Mzp, err); } acb_clear(t); mag_clear(r); mag_clear(err); mag_clear(one); mag_clear(eps); } } } void acb_agm1(acb_t res, const acb_t z, slong prec) { if (acb_is_zero(z)) { acb_zero(res); } else if (!acb_is_finite(z)) { acb_indeterminate(res); } else if (acb_contains_zero(z)) { acb_agm1_around_zero(res, z, prec); } else if (arf_sgn(arb_midref(acb_realref(z))) >= 0) { acb_agm1_basecase(res, z, prec); } else if (acb_equal_si(z, -1)) { acb_zero(res); } else { /* use M(1,z) = M((z+1)/2, sqrt(z)) = (z+1)/2 * M(1, 2 sqrt(z) / (z+1)) = sqrt(z) * M(1, (z+1) / (2 sqrt(z)) */ acb_t t; acb_init(t); acb_add_ui(t, z, 1, prec); acb_mul_2exp_si(t, t, -1); if (acb_contains_zero(t)) { mag_t ra, rb; mag_init(ra); mag_init(rb); acb_get_mag(ra, t); acb_get_mag(rb, z); mag_sqrt(rb, rb); mag_agm(ra, ra, rb); acb_zero(res); acb_add_error_mag(res, ra); mag_clear(ra); mag_clear(rb); } else if (acb_rel_accuracy_bits(t) > acb_rel_accuracy_bits(z)) { acb_sqrt(res, z, prec); acb_div(res, res, t, prec); acb_agm1_basecase(res, res, prec); acb_mul(res, res, t, prec); } else { acb_sqrt(res, z, prec); acb_div(t, t, res, prec); acb_agm1_basecase(t, t, prec); acb_mul(res, res, t, prec); } acb_clear(t); } } void acb_agm1_deriv(acb_t Mz, acb_t Mzp, const acb_t z, slong prec) { /* u = 2 sqrt(z) / (1+z) Mz = (1+z) M(u) / 2 Mzp = [M(u) - (z-1) M'(u) / ((1+z) sqrt(z))] / 2 */ if (arf_sgn(arb_midref(acb_realref(z))) >= 0) { if (acb_is_one(z)) { acb_one(Mz); acb_mul_2exp_si(Mzp, Mz, -1); } else acb_agm1_deriv_right(Mz, Mzp, z, prec); } else { acb_t t, u, zp1, zm1; acb_init(t); acb_init(u); acb_init(zp1); acb_init(zm1); acb_sqrt(t, z, prec); acb_add_ui(zp1, z, 1, prec); acb_sub_ui(zm1, z, 1, prec); acb_div(u, t, zp1, prec); acb_mul_2exp_si(u, u, 1); acb_agm1_deriv_right(Mz, Mzp, u, prec); acb_mul(Mzp, Mzp, zm1, prec); acb_mul(t, t, zp1, prec); acb_div(Mzp, Mzp, t, prec); acb_sub(Mzp, Mz, Mzp, prec); acb_mul_2exp_si(Mzp, Mzp, -1); acb_mul(Mz, Mz, zp1, prec); acb_mul_2exp_si(Mz, Mz, -1); acb_clear(t); acb_clear(u); acb_clear(zp1); acb_clear(zm1); } } void acb_agm1_cpx(acb_ptr m, const acb_t z, slong len, slong prec) { if (len < 1) return; if (len == 1) { acb_agm1(m, z, prec); return; } if (len == 2) { acb_agm1_deriv(m, m + 1, z, prec); return; } if (len >= 3) { acb_t t, u, v; acb_ptr w; slong k, n; acb_init(t); acb_init(u); acb_init(v); w = _acb_vec_init(len); acb_agm1_deriv(w, w + 1, z, prec); /* invert series */ acb_inv(w, w, prec); acb_mul(t, w, w, prec); acb_mul(w + 1, w + 1, t, prec); acb_neg(w + 1, w + 1); if (acb_is_one(z)) { for (k = 2; k < len; k++) { n = k - 2; acb_mul_ui(w + k, w + n + 0, (n+1)*(n+1), prec); acb_addmul_ui(w + k, w + n + 1, 7+3*n*(3+n), prec); acb_div_ui(w + k, w + k, 2*(n+2)*(n+2), prec); acb_neg(w + k, w + k); } } else { /* t = 3z^2 - 1 */ /* u = -1 / (z^3 - z) */ acb_mul(t, z, z, prec); acb_mul(u, t, z, prec); acb_mul_ui(t, t, 3, prec); acb_sub_ui(t, t, 1, prec); acb_sub(u, u, z, prec); acb_inv(u, u, prec); acb_neg(u, u); /* use differential equation for second derivative */ acb_mul(w + 2, z, w + 0, prec); acb_addmul(w + 2, t, w + 1, prec); acb_mul(w + 2, w + 2, u, prec); acb_mul_2exp_si(w + 2, w + 2, -1); /* recurrence */ for (k = 3; k < len; k++) { n = k - 3; acb_mul_ui(w + k, w + n + 0, (n+1)*(n+1), prec); acb_mul(v, w + n + 1, z, prec); acb_addmul_ui(w + k, v, 7+3*n*(3+n), prec); acb_mul(v, w + n + 2, t, prec); acb_addmul_ui(w + k, v, (n+2)*(n+2), prec); acb_mul(w + k, w + k, u, prec); acb_div_ui(w + k, w + k, (n+2)*(n+3), prec); } } /* invert series */ _acb_poly_inv_series(m, w, len, len, prec); acb_clear(t); acb_clear(u); acb_clear(v); _acb_vec_clear(w, len); } } arb-2.22.1/acb/approx_dot.c000066400000000000000000000610161417376376500154410ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" /* We need uint64_t instead of mp_limb_t on 32-bit systems for safe summation of 30-bit error bounds. */ #include /* The following macros are found in FLINT's longlong.h, but the release version is out of date. */ /* x86 : 64 bit */ #if (GMP_LIMB_BITS == 64 && defined (__amd64__)) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addq %8,%q2\n\tadcq %6,%q1\n\tadcq %4,%q0" \ : "=r" (sh), "=&r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "rme" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "rme" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "rme" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subq %8,%q2\n\tsbbq %6,%q1\n\tsbbq %4,%q0" \ : "=r" (dh), "=&r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "rme" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "rme" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "rme" ((mp_limb_t)(sl))) \ #endif /* x86_64 */ /* x86 : 32 bit */ #if (GMP_LIMB_BITS == 32 && (defined (__i386__) \ || defined (__i486__) || defined(__amd64__))) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addl %8,%k2\n\tadcl %6,%k1\n\tadcl %4,%k0" \ : "=r" (sh), "=r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "g" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "g" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "g" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subl %8,%k2\n\tsbbl %6,%k1\n\tsbbl %4,%k0" \ : "=r" (dh), "=r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "g" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "g" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "g" ((mp_limb_t)(sl))) \ #endif /* x86 */ #if !defined(add_sssaaaaaa2) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ do { \ mp_limb_t __t, __u; \ add_ssaaaa(__t, sl, (mp_limb_t) 0, al, (mp_limb_t) 0, bl); \ add_ssaaaa(__u, sm, (mp_limb_t) 0, am, (mp_limb_t) 0, bm); \ add_ssaaaa(sh, sm, ah + bh, sm, __u, __t); \ } while (0) #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ do { \ mp_limb_t __t, __u; \ sub_ddmmss(__t, dl, (mp_limb_t) 0, ml, (mp_limb_t) 0, sl); \ sub_ddmmss(__u, dm, (mp_limb_t) 0, mm, (mp_limb_t) 0, sm); \ sub_ddmmss(dh, dm, mh - sh, dm, -__u, -__t); \ } while (0) #endif void _arb_dot_addmul_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, mp_srcptr yptr, mp_size_t yn, int negative, flint_bitcnt_t shift); void _arb_dot_add_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, int negative, flint_bitcnt_t shift); static void _arb_dot_output(arb_t res, mp_ptr sum, mp_size_t sn, int negative, slong sum_exp, slong prec) { slong exp_fix; if (sum[sn - 1] >= LIMB_TOP) { mpn_neg(sum, sum, sn); negative ^= 1; } exp_fix = 0; if (sum[sn - 1] == 0) { slong sum_exp2; mp_size_t sn2; sn2 = sn; sum_exp2 = sum_exp; while (sn2 > 0 && sum[sn2 - 1] == 0) { sum_exp2 -= FLINT_BITS; sn2--; } if (sn2 == 0) { arf_zero(arb_midref(res)); } else { _arf_set_round_mpn(arb_midref(res), &exp_fix, sum, sn2, negative, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp_fix + sum_exp2); } } else { if (sn == 2) /* unnecessary? */ _arf_set_round_uiui(arb_midref(res), &exp_fix, sum[1], sum[0], negative, prec, ARF_RND_DOWN); else _arf_set_round_mpn(arb_midref(res), &exp_fix, sum, sn, negative, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp_fix + sum_exp); } } /* xxx: don't use surrounding variables */ #define ARB_DOT_ADD(s_sum, s_serr, s_sn, s_sum_exp, s_subtract, xm) \ if (!arf_is_special(xm)) \ { \ mp_srcptr xptr; \ xexp = ARF_EXP(xm); \ xn = ARF_SIZE(xm); \ xnegative = ARF_SGNBIT(xm); \ shift = s_sum_exp - xexp; \ if (shift >= s_sn * FLINT_BITS) \ { \ } \ else \ { \ xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); \ _arb_dot_add_generic(s_sum, &s_serr, tmp, s_sn, xptr, xn, xnegative ^ s_subtract, shift); \ } \ } \ static void _arf_complex_mul_gauss(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d) { mp_srcptr ap, bp, cp, dp; int asgn, bsgn, csgn, dsgn; mp_size_t an, bn, cn, dn; slong aexp, bexp, cexp, dexp; fmpz texp, uexp; fmpz_t za, zb, zc, zd, t, u, v; slong abot, bbot, cbot, dbot; ARF_GET_MPN_READONLY(ap, an, a); asgn = ARF_SGNBIT(a); aexp = ARF_EXP(a); ARF_GET_MPN_READONLY(bp, bn, b); bsgn = ARF_SGNBIT(b); bexp = ARF_EXP(b); ARF_GET_MPN_READONLY(cp, cn, c); csgn = ARF_SGNBIT(c); cexp = ARF_EXP(c); ARF_GET_MPN_READONLY(dp, dn, d); dsgn = ARF_SGNBIT(d); dexp = ARF_EXP(d); /* Gauss multiplication e = ac - bd f = (a+b)(c+d) - ac - bd */ abot = aexp - an * FLINT_BITS; bbot = bexp - bn * FLINT_BITS; cbot = cexp - cn * FLINT_BITS; dbot = dexp - dn * FLINT_BITS; texp = FLINT_MIN(abot, bbot); uexp = FLINT_MIN(cbot, dbot); fmpz_init(za); fmpz_init(zb); fmpz_init(zc); fmpz_init(zd); fmpz_init(t); fmpz_init(u); fmpz_init(v); fmpz_lshift_mpn(za, ap, an, asgn, abot - texp); fmpz_lshift_mpn(zb, bp, bn, bsgn, bbot - texp); fmpz_lshift_mpn(zc, cp, cn, csgn, cbot - uexp); fmpz_lshift_mpn(zd, dp, dn, dsgn, dbot - uexp); fmpz_add(t, za, zb); fmpz_add(v, zc, zd); fmpz_mul(u, t, v); fmpz_mul(t, za, zc); fmpz_mul(v, zb, zd); fmpz_sub(u, u, t); fmpz_sub(u, u, v); fmpz_sub(t, t, v); texp += uexp; arf_set_fmpz_2exp(e, t, &texp); arf_set_fmpz_2exp(f, u, &texp); fmpz_clear(za); fmpz_clear(zb); fmpz_clear(zc); fmpz_clear(zd); fmpz_clear(t); fmpz_clear(u); fmpz_clear(v); } ARB_DLL extern slong acb_dot_gauss_dot_cutoff; #define GAUSS_CUTOFF acb_dot_gauss_dot_cutoff void acb_approx_dot_simple(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) { slong i; if (len <= 0) { if (initial == NULL) { arf_zero(arb_midref(acb_realref(res))); arf_zero(arb_midref(acb_imagref(res))); } else { arf_set_round(arb_midref(acb_realref(res)), arb_midref(acb_realref(initial)), prec, ARB_RND); arf_set_round(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(initial)), prec, ARB_RND); } return; } if (initial == NULL && len == 1) { arf_complex_mul(arb_midref(acb_realref(res)), arb_midref(acb_imagref(res)), arb_midref(acb_realref(x)), arb_midref(acb_imagref(x)), arb_midref(acb_realref(y)), arb_midref(acb_imagref(y)), prec, ARB_RND); } else { arf_t e, f; arf_init(e); arf_init(f); if (initial != NULL) { if (subtract) { arf_neg(arb_midref(acb_realref(res)), arb_midref(acb_realref(initial))); arf_neg(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(initial))); } else { arf_set(arb_midref(acb_realref(res)), arb_midref(acb_realref(initial))); arf_set(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(initial))); } } for (i = 0; i < len; i++) { arf_complex_mul(e, f, arb_midref(acb_realref(x + i * xstep)), arb_midref(acb_imagref(x + i * xstep)), arb_midref(acb_realref(y + i * ystep)), arb_midref(acb_imagref(y + i * ystep)), prec, ARB_RND); if (i == 0 && initial == NULL) { arf_set(arb_midref(acb_realref(res)), e); arf_set(arb_midref(acb_imagref(res)), f); } else { arf_add(arb_midref(acb_realref(res)), arb_midref(acb_realref(res)), e, prec, ARB_RND); arf_add(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(res)), f, prec, ARB_RND); } } arf_clear(e); arf_clear(f); } if (subtract) { arf_neg(arb_midref(acb_realref(res)), arb_midref(acb_realref(res))); arf_neg(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(res))); } } void acb_approx_dot(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) { slong i, j, padding, extend; slong xexp, yexp, exp; slong re_nonzero, im_nonzero; slong re_max_exp, re_min_exp, re_sum_exp; slong im_max_exp, im_min_exp, im_sum_exp; slong re_prec, im_prec; int xnegative, ynegative; mp_size_t xn, yn, re_sn, im_sn, alloc; flint_bitcnt_t shift; arb_srcptr xi, yi; arf_srcptr xm, ym; mp_limb_t re_serr, im_serr; /* Sum over arithmetic errors */ mp_ptr tmp, re_sum, im_sum; /* Workspace */ slong xoff, yoff; char * use_gauss; ARF_ADD_TMP_DECL; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { acb_approx_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } /* Number of nonzero midpoint terms in sum. */ re_nonzero = 0; im_nonzero = 0; /* Terms are bounded by 2^max_exp (with WORD_MIN = -infty) */ re_max_exp = WORD_MIN; im_max_exp = WORD_MIN; /* Used to reduce the precision. */ re_min_exp = WORD_MAX; im_min_exp = WORD_MAX; /* Account for the initial term. */ if (initial != NULL) { if (!ARF_IS_LAGOM(arb_midref(acb_realref(initial))) || !ARF_IS_LAGOM(arb_midref(acb_imagref(initial)))) { acb_approx_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(acb_realref(initial)); if (!arf_is_special(xm)) { re_max_exp = ARF_EXP(xm); re_nonzero++; if (prec > 2 * FLINT_BITS) re_min_exp = ARF_EXP(xm) - ARF_SIZE(xm) * FLINT_BITS; } xm = arb_midref(acb_imagref(initial)); if (!arf_is_special(xm)) { im_max_exp = ARF_EXP(xm); im_nonzero++; if (prec > 2 * FLINT_BITS) im_min_exp = ARF_EXP(xm) - ARF_SIZE(xm) * FLINT_BITS; } } for (xoff = 0; xoff < 2; xoff++) { for (yoff = 0; yoff < 2; yoff++) { slong nonzero, max_exp, min_exp; if (xoff == yoff) { nonzero = re_nonzero; max_exp = re_max_exp; min_exp = re_min_exp; } else { nonzero = im_nonzero; max_exp = im_max_exp; min_exp = im_min_exp; } /* Determine maximum exponents for the main sum and the radius sum. */ for (i = 0; i < len; i++) { xi = ((arb_srcptr) x) + 2 * i * xstep + xoff; yi = ((arb_srcptr) y) + 2 * i * ystep + yoff; /* Fallback for huge exponents or non-finite values. */ if (!ARF_IS_LAGOM(arb_midref(xi)) || !ARF_IS_LAGOM(arb_midref(yi))) { acb_approx_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(xi); ym = arb_midref(yi); /* (xm+xr)(ym+yr) = xm ym + [xr ym + xm yr + xr yr] */ if (!arf_is_special(xm)) { xexp = ARF_EXP(xm); if (!arf_is_special(ym)) { yexp = ARF_EXP(ym); max_exp = FLINT_MAX(max_exp, xexp + yexp); nonzero++; if (prec > 2 * FLINT_BITS) { slong bot; bot = (xexp + yexp) - (ARF_SIZE(xm) + ARF_SIZE(ym)) * FLINT_BITS; min_exp = FLINT_MIN(min_exp, bot); } } } } if (xoff == yoff) { re_nonzero = nonzero; re_max_exp = max_exp; re_min_exp = min_exp; } else { im_nonzero = nonzero; im_max_exp = max_exp; im_min_exp = min_exp; } } } re_prec = prec; im_prec = prec; if (re_max_exp == WORD_MIN && im_max_exp == WORD_MIN) { arf_zero(arb_midref(acb_realref(res))); arf_zero(arb_midref(acb_imagref(res))); return; } /* The midpoint sum is zero. */ if (re_max_exp == WORD_MIN) { re_prec = 2; } else { if (re_min_exp != WORD_MAX) re_prec = FLINT_MIN(re_prec, re_max_exp - re_min_exp + MAG_BITS); re_prec = FLINT_MAX(re_prec, 2); } if (im_max_exp == WORD_MIN) { im_prec = 2; } else { if (re_min_exp != WORD_MAX) im_prec = FLINT_MIN(im_prec, im_max_exp - im_min_exp + MAG_BITS); im_prec = FLINT_MAX(im_prec, 2); } extend = FLINT_BIT_COUNT(re_nonzero) + 1; padding = 4 + FLINT_BIT_COUNT(len); re_sn = (re_prec + extend + padding + FLINT_BITS - 1) / FLINT_BITS; re_sn = FLINT_MAX(re_sn, 2); re_sum_exp = re_max_exp + extend; extend = FLINT_BIT_COUNT(im_nonzero) + 1; padding = 4 + FLINT_BIT_COUNT(len); im_sn = (im_prec + extend + padding + FLINT_BITS - 1) / FLINT_BITS; im_sn = FLINT_MAX(im_sn, 2); im_sum_exp = im_max_exp + extend; /* We need sn + 1 limb for the sum (sn limbs + 1 dummy limb for carry or borrow that avoids an extra branch). We need 2 * (sn + 2) limbs to store the product of two numbers with up to (sn + 2) limbs, plus 1 extra limb for shifting the product. */ alloc = (re_sn + 1) + (im_sn + 1) + 2 * (FLINT_MAX(re_sn, im_sn) + 2) + 1; ARF_ADD_TMP_ALLOC(re_sum, alloc) im_sum = re_sum + (re_sn + 1); tmp = im_sum + (im_sn + 1); /* Set sum to 0 */ re_serr = 0; for (j = 0; j < re_sn + 1; j++) re_sum[j] = 0; im_serr = 0; for (j = 0; j < im_sn + 1; j++) im_sum[j] = 0; if (initial != NULL) { xm = arb_midref(acb_realref(initial)); ARB_DOT_ADD(re_sum, re_serr, re_sn, re_sum_exp, subtract, xm); xm = arb_midref(acb_imagref(initial)); ARB_DOT_ADD(im_sum, im_serr, im_sn, im_sum_exp, subtract, xm); } use_gauss = NULL; if (re_prec >= GAUSS_CUTOFF * FLINT_BITS && im_prec >= GAUSS_CUTOFF * FLINT_BITS) { arf_t e, f; for (i = 0; i < len; i++) { arb_srcptr ai, bi, ci, di; mp_size_t an, bn, cn, dn; slong aexp, bexp, cexp, dexp; ai = ((arb_srcptr) x) + 2 * i * xstep; bi = ((arb_srcptr) x) + 2 * i * xstep + 1; ci = ((arb_srcptr) y) + 2 * i * ystep; di = ((arb_srcptr) y) + 2 * i * ystep + 1; an = ARF_SIZE(arb_midref(ai)); bn = ARF_SIZE(arb_midref(bi)); cn = ARF_SIZE(arb_midref(ci)); dn = ARF_SIZE(arb_midref(di)); aexp = ARF_EXP(arb_midref(ai)); bexp = ARF_EXP(arb_midref(bi)); cexp = ARF_EXP(arb_midref(ci)); dexp = ARF_EXP(arb_midref(di)); if (an >= GAUSS_CUTOFF && bn >= GAUSS_CUTOFF && bn >= GAUSS_CUTOFF && cn >= GAUSS_CUTOFF && FLINT_ABS(an - bn) <= 2 && FLINT_ABS(cn - dn) <= 2 && FLINT_ABS(aexp - bexp) <= 64 && FLINT_ABS(cexp - dexp) <= 64 && re_sum_exp - (aexp + cexp) < 0.1 * re_prec && im_sum_exp - (aexp + dexp) < 0.1 * im_prec && an + cn < 2.2 * re_sn && an + dn < 2.2 * im_sn) { if (use_gauss == NULL) { use_gauss = flint_calloc(len, sizeof(char)); arf_init(e); arf_init(f); } use_gauss[i] = 1; _arf_complex_mul_gauss(e, f, arb_midref(ai), arb_midref(bi), arb_midref(ci), arb_midref(di)); ARB_DOT_ADD(re_sum, re_serr, re_sn, re_sum_exp, 0, e); ARB_DOT_ADD(im_sum, im_serr, im_sn, im_sum_exp, 0, f); } } if (use_gauss != NULL) { arf_clear(e); arf_clear(f); } } for (xoff = 0; xoff < 2; xoff++) { for (yoff = 0; yoff < 2; yoff++) { slong sum_exp; mp_ptr sum; mp_size_t sn; mp_limb_t serr; int flipsign; if (xoff == yoff) { sum_exp = re_sum_exp; sum = re_sum; sn = re_sn; if (re_max_exp == WORD_MIN) continue; } else { sum_exp = im_sum_exp; sum = im_sum; sn = im_sn; if (im_max_exp == WORD_MIN) continue; } serr = 0; flipsign = (xoff + yoff == 2); for (i = 0; i < len; i++) { xi = ((arb_srcptr) x) + 2 * i * xstep + xoff; yi = ((arb_srcptr) y) + 2 * i * ystep + yoff; xm = arb_midref(xi); ym = arb_midref(yi); /* The midpoints of x[i] and y[i] are both nonzero. */ if (!arf_is_special(xm) && !arf_is_special(ym)) { xexp = ARF_EXP(xm); xn = ARF_SIZE(xm); xnegative = ARF_SGNBIT(xm); yexp = ARF_EXP(ym); yn = ARF_SIZE(ym); ynegative = ARF_SGNBIT(ym); exp = xexp + yexp; shift = sum_exp - exp; if (shift >= sn * FLINT_BITS) { } else if (xn <= 2 && yn <= 2 && sn <= 3) { mp_limb_t x1, x0, y1, y0; mp_limb_t u3, u2, u1, u0; if (xn == 1 && yn == 1) { x0 = ARF_NOPTR_D(xm)[0]; y0 = ARF_NOPTR_D(ym)[0]; umul_ppmm(u3, u2, x0, y0); u1 = u0 = 0; } else if (xn == 2 && yn == 2) { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; nn_mul_2x2(u3, u2, u1, u0, x1, x0, y1, y0); } else if (xn == 1) { x0 = ARF_NOPTR_D(xm)[0]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; nn_mul_2x1(u3, u2, u1, y1, y0, x0); u0 = 0; } else { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; nn_mul_2x1(u3, u2, u1, x1, x0, y0); u0 = 0; } if (sn == 2) { if (shift < FLINT_BITS) { u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { u2 = u3; u3 = 0; } else /* FLINT_BITS < shift < 2 * FLINT_BITS */ { u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } if (xnegative ^ ynegative ^ flipsign) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], u3, u2); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], u3, u2); } else if (sn == 3) { if (shift < FLINT_BITS) { u1 = (u1 >> shift) | (u2 << (FLINT_BITS - shift)); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { u1 = u2; u2 = u3; u3 = 0; } else if (shift < 2 * FLINT_BITS) { u1 = (u3 << (2 * FLINT_BITS - shift)) | (u2 >> (shift - FLINT_BITS)); u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } else if (shift == 2 * FLINT_BITS) { u1 = u3; u2 = 0; u3 = 0; } else /* 2 * FLINT_BITS < shift < 3 * FLINT_BITS */ { u1 = (u3 >> (shift - 2 * FLINT_BITS)); u2 = 0; u3 = 0; } if (xnegative ^ ynegative ^ flipsign) sub_dddmmmsss2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); else add_sssaaaaaa2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); } } else { mp_srcptr xptr, yptr; xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); yptr = (yn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(ym) : ARF_PTR_D(ym); if (use_gauss == NULL || use_gauss[i] == 0) _arb_dot_addmul_generic(sum, &serr, tmp, sn, xptr, xn, yptr, yn, xnegative ^ ynegative ^ flipsign, shift); } } } } } _arb_dot_output(acb_realref(res), re_sum, re_sn, subtract, re_sum_exp, re_prec); _arb_dot_output(acb_imagref(res), im_sum, im_sn, subtract, im_sum_exp, im_prec); ARF_ADD_TMP_FREE(re_sum, alloc); if (use_gauss != NULL) flint_free(use_gauss); } arb-2.22.1/acb/arg.c000066400000000000000000000007741417376376500140370ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_arg(arb_t r, const acb_t z, slong prec) { arb_atan2(r, acb_imagref(z), acb_realref(z), prec); } arb-2.22.1/acb/asin.c000066400000000000000000000022201417376376500142040ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_asin(acb_t res, const acb_t z, slong prec) { if (arb_is_zero(acb_realref(z))) { arb_asinh(acb_imagref(res), acb_imagref(z), prec); arb_zero(acb_realref(res)); } else { acb_t t; acb_init(t); acb_mul(t, z, z, prec); acb_sub_ui(t, t, 1, prec); acb_neg(t, t); acb_sqrt(t, t, prec); if (acb_is_real(z) && acb_is_real(t)) { arb_atan2(acb_realref(res), acb_realref(z), acb_realref(t), prec); arb_zero(acb_imagref(res)); } else { acb_mul_onei(res, z); acb_add(res, res, t, prec); acb_log(res, res, prec); acb_div_onei(res, res); } acb_clear(t); } } arb-2.22.1/acb/asinh.c000066400000000000000000000010341417376376500143560ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_asinh(acb_t res, const acb_t z, slong prec) { acb_mul_onei(res, z); acb_asin(res, res, prec); acb_div_onei(res, res); } arb-2.22.1/acb/atan.c000066400000000000000000000053401417376376500142030ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" /* branch cuts are on (+/-i)*[1,inf] */ int acb_atan_on_branch_cut(const acb_t z) { arb_t unit; int result; if (!acb_is_finite(z)) return 1; if (arb_is_nonzero(acb_realref(z))) return 0; if (arb_contains_si(acb_imagref(z), 1) || arb_contains_si(acb_imagref(z), -1)) return 1; arb_init(unit); mag_one(arb_radref(unit)); result = !arb_contains(unit, acb_imagref(z)); arb_clear(unit); return result; } void acb_atan(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_atan(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (!acb_is_finite(z)) { acb_indeterminate(r); } else { acb_t t, u; acb_init(t); acb_init(u); if (acb_atan_on_branch_cut(z)) { acb_mul_onei(u, z); acb_neg(t, u); acb_log1p(t, t, prec); acb_log1p(u, u, prec); acb_sub(t, t, u, prec); acb_mul_onei(t, t); acb_mul_2exp_si(r, t, -1); } else if (acb_is_exact(z)) { acb_onei(t); acb_sub(t, t, z, prec); acb_div(t, z, t, prec); acb_mul_2exp_si(t, t, 1); acb_log1p(t, t, prec); acb_mul_onei(t, t); acb_mul_2exp_si(r, t, -1); } else { mag_t err, err2; mag_init(err); mag_init(err2); /* atan'(z) = 1/(1+z^2) = 1/((z+i)(z-i)) */ acb_onei(t); acb_add(t, z, t, prec); acb_get_mag_lower(err, t); acb_onei(t); acb_sub(t, z, t, prec); acb_get_mag_lower(err2, t); mag_mul_lower(err, err, err2); mag_hypot(err2, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); mag_div(err, err2, err); arf_set(arb_midref(acb_realref(t)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(t)), arb_midref(acb_imagref(z))); mag_zero(arb_radref(acb_realref(t))); mag_zero(arb_radref(acb_imagref(t))); acb_atan(r, t, prec); acb_add_error_mag(r, err); mag_clear(err); mag_clear(err2); } acb_clear(t); acb_clear(u); } } arb-2.22.1/acb/atanh.c000066400000000000000000000010341417376376500143470ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_atanh(acb_t res, const acb_t z, slong prec) { acb_mul_onei(res, z); acb_atan(res, res, prec); acb_div_onei(res, res); } arb-2.22.1/acb/barnes_g.c000066400000000000000000000056221417376376500150430ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #include "acb_poly.h" void _arb_const_zeta_minus_one_eval(arb_t y, slong prec) { acb_struct z[2]; acb_t s, a; acb_init(z + 0); acb_init(z + 1); acb_init(s); acb_init(a); acb_set_si(s, -1); acb_one(a); _acb_poly_zeta_cpx_series(z, s, a, 0, 2, prec + 20); arb_set(y, acb_realref(z + 1)); acb_clear(z + 0); acb_clear(z + 1); acb_clear(s); acb_clear(a); } ARB_DEF_CACHED_CONSTANT(_arb_const_zeta_minus_one, _arb_const_zeta_minus_one_eval) /* LogG(z) = (z-1) LogGamma(z) - zeta'(-1,z) + zeta'(-1) LogG'(z) = (1/2)(-2z + 1 + log(2pi)) + (z-1) digamma(z) */ void _acb_log_barnes_g_zeta(acb_t res, const acb_t z, slong prec) { acb_struct t[3]; acb_init(t + 0); acb_init(t + 1); acb_init(t + 2); acb_set_si(t + 2, -1); _acb_poly_zeta_cpx_series(t, t + 2, z, 0, 2, prec); _arb_const_zeta_minus_one(acb_realref(t), prec); arb_zero(acb_imagref(t)); acb_sub(t, t, t + 1, prec); acb_lgamma(t + 1, z, prec); acb_sub_ui(t + 2, z, 1, prec); acb_addmul(t, t + 1, t + 2, prec); acb_set(res, t); acb_clear(t + 0); acb_clear(t + 1); acb_clear(t + 2); } void _acb_barnes_g_ui_rec(acb_t res, ulong n, slong prec) { acb_t t; ulong k; acb_init(t); acb_one(res); acb_one(t); for (k = 3; k < n; k++) { acb_mul_ui(t, t, k - 1, prec); acb_mul(res, res, t, prec); } acb_clear(t); } void acb_log_barnes_g(acb_t res, const acb_t z, slong prec) { if (acb_is_int(z)) { if (arb_is_nonpositive(acb_realref(z))) { acb_indeterminate(res); return; } if (arf_cmpabs_ui(arb_midref(acb_realref(z)), prec) < 0) { _acb_barnes_g_ui_rec(res, arf_get_si(arb_midref(acb_realref(z)), ARF_RND_DOWN), prec); acb_log(res, res, prec); return; } } _acb_log_barnes_g_zeta(res, z, prec); } void acb_barnes_g(acb_t res, const acb_t z, slong prec) { int real; real = acb_is_real(z); if (acb_is_int(z)) { if (arb_is_nonpositive(acb_realref(z))) { acb_zero(res); return; } if (arf_cmpabs_ui(arb_midref(acb_realref(z)), prec) < 0) { _acb_barnes_g_ui_rec(res, arf_get_si(arb_midref(acb_realref(z)), ARF_RND_DOWN), prec); return; } } _acb_log_barnes_g_zeta(res, z, prec); acb_exp(res, res, prec); if (real) arb_zero(acb_imagref(res)); } arb-2.22.1/acb/bernoulli_poly_ui.c000066400000000000000000000036761417376376500170250ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_bernoulli_poly_ui(acb_t res, ulong n, const acb_t x, slong prec) { acb_t s, x2; arb_t t, c; ulong k; if (n == 0) { acb_one(res); return; } if (n == 1) { acb_mul_2exp_si(res, x, 1); acb_sub_ui(res, res, 1, prec); acb_mul_2exp_si(res, res, -1); return; } if (acb_is_real(x)) { arb_bernoulli_poly_ui(acb_realref(res), n, acb_realref(x), prec); arb_zero(acb_imagref(res)); return; } /* assuming small n simplifies the code that follows */ if (n >> (FLINT_BITS / 2) || !acb_is_finite(x)) { acb_indeterminate(res); return; } acb_init(s); acb_init(x2); arb_init(t); arb_init(c); acb_mul(x2, x, x, prec); /* s = x^2 - x n / 2 */ acb_mul_ui(s, x, n, prec); acb_mul_2exp_si(s, s, -1); acb_sub(s, x2, s, prec); /* c = n (n-1) / 2; s = s + c / 6 */ arb_set_ui(c, n * (n - 1)); arb_mul_2exp_si(c, c, -1); arb_div_ui(t, c, 6, prec); acb_add_arb(s, s, t, prec); for (k = 4; k <= n; k += 2) { /* c = binomial(n,k) */ arb_mul_ui(c, c, (n + 1 - k) * (n + 2 - k), prec); arb_div_ui(c, c, k * (k - 1), prec); /* s = s x^2 + b_k c */ acb_mul(s, s, x2, prec); arb_bernoulli_ui(t, k, prec); arb_mul(t, t, c, prec); acb_add_arb(s, s, t, prec); } if (n >= 3 && n % 2) acb_mul(s, s, x, prec); acb_swap(res, s); acb_clear(s); acb_clear(x2); arb_clear(t); arb_clear(c); } arb-2.22.1/acb/chebyshev_t2_ui.c000066400000000000000000000023201417376376500163350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_chebyshev_t2_ui(acb_t a, acb_t b, ulong n, const acb_t x, slong prec) { int i; acb_set_round(a, x, prec); acb_one(b); if (n <= 1) { if (n == 0) acb_swap(a, b); return; } for (i = FLINT_BIT_COUNT(n - 1) - 1; i >= 0; i--) { if (((n - 1) >> i) & 1) { acb_mul(b, b, a, prec); acb_mul_2exp_si(b, b, 1); acb_sub(b, b, x, prec); acb_mul(a, a, a, prec); acb_mul_2exp_si(a, a, 1); acb_sub_ui(a, a, 1, prec); } else { acb_mul(a, a, b, prec); acb_mul_2exp_si(a, a, 1); acb_sub(a, a, x, prec); acb_mul(b, b, b, prec); acb_mul_2exp_si(b, b, 1); acb_sub_ui(b, b, 1, prec); } } } arb-2.22.1/acb/chebyshev_t_ui.c000066400000000000000000000024371417376376500162640ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_chebyshev_t_ui(acb_t y, ulong n, const acb_t x, slong prec) { int i, r; if (n <= 1) { if (n == 0) acb_one(y); else acb_set_round(y, x, prec); return; } count_trailing_zeros(r, n); if ((n >> r) == 1) { acb_mul(y, x, x, prec); acb_mul_2exp_si(y, y, 1); acb_sub_ui(y, y, 1, prec); r -= 1; } else { /* we only need one value, so break out final iteration */ acb_t t, u; acb_init(t); acb_init(u); acb_chebyshev_t2_ui(t, u, (n >> (r + 1)) + 1, x, prec); acb_mul(t, t, u, prec); acb_mul_2exp_si(t, t, 1); acb_sub(y, t, x, prec); acb_clear(t); acb_clear(u); } for (i = 0; i < r; i++) { acb_mul(y, y, y, prec); acb_mul_2exp_si(y, y, 1); acb_sub_ui(y, y, 1, prec); } } arb-2.22.1/acb/chebyshev_u2_ui.c000066400000000000000000000024361417376376500163460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_chebyshev_u2_ui(acb_t a, acb_t b, ulong n, const acb_t x, slong prec) { int i; acb_t t, u; if (n == 0) { acb_one(a); acb_zero(b); return; } acb_set_round(a, x, prec); acb_mul_2exp_si(a, a, 1); acb_one(b); if (n == 1) return; acb_init(t); acb_init(u); for (i = FLINT_BIT_COUNT(n) - 2; i >= 0; i--) { acb_add(t, a, b, prec); acb_sub(u, a, b, prec); if ((n >> i) & 1) { acb_submul(b, x, a, prec); acb_mul(a, a, b, prec); acb_neg(a, a); acb_mul_2exp_si(a, a, 1); acb_mul(b, t, u, prec); } else { acb_submul(a, x, b, prec); acb_mul(b, a, b, prec); acb_mul_2exp_si(b, b, 1); acb_mul(a, t, u, prec); } } acb_clear(t); acb_clear(u); } arb-2.22.1/acb/chebyshev_u_ui.c000066400000000000000000000021151417376376500162560ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_chebyshev_u_ui(acb_t y, ulong n, const acb_t x, slong prec) { acb_t a, b; if (n <= 1) { if (n == 0) { acb_one(y); } else { acb_set_round(y, x, prec); acb_mul_2exp_si(y, y, 1); } return; } acb_init(a); acb_init(b); acb_chebyshev_u2_ui(a, b, n / 2, x, prec); if (n % 2 == 0) { acb_add(y, a, b, prec); acb_sub(b, a, b, prec); acb_mul(y, y, b, prec); } else { acb_submul(b, a, x, prec); acb_mul(y, a, b, prec); acb_mul_2exp_si(y, y, 1); acb_neg(y, y); } acb_clear(a); acb_clear(b); } arb-2.22.1/acb/clear.c000066400000000000000000000023711417376376500143470ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" /* The clear methods are not defined as inlines since this inflates the code size. We inline the content manually here to avoid function call overhead. Question: would calling arb_clear twice here be worth the call overhead, by improving branch prediction? */ void acb_clear(acb_t x) { ARF_DEMOTE(arb_midref(acb_realref(x))); if (COEFF_IS_MPZ(ARF_EXP(arb_midref(acb_realref(x))))) _fmpz_clear_mpz(ARF_EXP(arb_midref(acb_realref(x)))); if (COEFF_IS_MPZ(MAG_EXP(arb_radref(acb_realref(x))))) _fmpz_clear_mpz(MAG_EXP(arb_radref(acb_realref(x)))); ARF_DEMOTE(arb_midref(acb_imagref(x))); if (COEFF_IS_MPZ(ARF_EXP(arb_midref(acb_imagref(x))))) _fmpz_clear_mpz(ARF_EXP(arb_midref(acb_imagref(x)))); if (COEFF_IS_MPZ(MAG_EXP(arb_radref(acb_imagref(x))))) _fmpz_clear_mpz(MAG_EXP(arb_radref(acb_imagref(x)))); } arb-2.22.1/acb/contains_int.c000066400000000000000000000010431417376376500157440ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int acb_contains_int(const acb_t x) { if (!arb_contains_zero(acb_imagref(x))) return 0; return arb_contains_int(acb_realref(x)); } arb-2.22.1/acb/cos.c000066400000000000000000000022661417376376500140500ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_cos(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_cos(acb_realref(r), a, prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(a)) { arb_cosh(acb_realref(r), b, prec); arb_zero(acb_imagref(r)); } else { arb_t sa, ca, sb, cb; arb_init(sa); arb_init(ca); arb_init(sb); arb_init(cb); arb_sin_cos(sa, ca, a, prec); arb_sinh_cosh(sb, cb, b, prec); arb_mul(acb_realref(r), ca, cb, prec); arb_mul(acb_imagref(r), sa, sb, prec); arb_neg(acb_imagref(r), acb_imagref(r)); arb_clear(sa); arb_clear(ca); arb_clear(sb); arb_clear(cb); } #undef a #undef b } arb-2.22.1/acb/cos_pi.c000066400000000000000000000025751417376376500145430ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_cos_pi(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_cos_pi(acb_realref(r), a, prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(a)) { arb_t t; arb_init(t); arb_const_pi(t, prec); arb_mul(t, t, b, prec); arb_cosh(acb_realref(r), t, prec); arb_zero(acb_imagref(r)); arb_clear(t); } else { arb_t sa, ca, sb, cb; arb_init(sa); arb_init(ca); arb_init(sb); arb_init(cb); arb_sin_cos_pi(sa, ca, a, prec); arb_const_pi(cb, prec); arb_mul(cb, cb, b, prec); arb_sinh_cosh(sb, cb, cb, prec); arb_mul(acb_realref(r), ca, cb, prec); arb_mul(acb_imagref(r), sa, sb, prec); arb_neg(acb_imagref(r), acb_imagref(r)); arb_clear(sa); arb_clear(ca); arb_clear(sb); arb_clear(cb); } #undef a #undef b } arb-2.22.1/acb/cot.c000066400000000000000000000034251417376376500140470ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_cot(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_cot(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_coth(acb_imagref(r), acb_imagref(z), prec); arb_neg(acb_imagref(r), acb_imagref(r)); arb_zero(acb_realref(r)); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos(r, t, z, prec + 4); acb_div(r, t, r, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_mul_onei(t, t); acb_exp(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_mul_onei(r, r); } else { acb_div_onei(t, t); acb_exp(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_div_onei(r, r); } } acb_clear(t); } } arb-2.22.1/acb/cot_pi.c000066400000000000000000000036021417376376500145340ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_cot_pi(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_cot_pi(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_t t; arb_init(t); arb_const_pi(t, prec + 4); arb_mul(t, acb_imagref(z), t, prec + 4); arb_coth(acb_imagref(r), t, prec); arb_neg(acb_imagref(r), acb_imagref(r)); arb_zero(acb_realref(r)); arb_clear(t); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos_pi(r, t, z, prec + 4); acb_div(r, t, r, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_exp_pi_i(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_mul_onei(r, r); } else { acb_neg(t, t); acb_exp_pi_i(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_div_onei(r, r); } } acb_clear(t); } } arb-2.22.1/acb/csc_pi.c000066400000000000000000000037271417376376500145270ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_csc_pi(acb_t res, const acb_t z, slong prec) { if (acb_contains_zero(z) || !acb_is_finite(z)) { acb_indeterminate(res); } else if (arb_is_zero(acb_imagref(z))) { arb_csc_pi(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } else if (arb_is_zero(acb_realref(z))) { arb_const_pi(acb_realref(res), prec); arb_mul(acb_imagref(res), acb_imagref(z), acb_realref(res), prec); arb_csch(acb_imagref(res), acb_imagref(res), prec); arb_neg(acb_imagref(res), acb_imagref(res)); arb_zero(acb_realref(res)); } else { if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) > 0) { acb_t t; acb_init(t); if (arf_sgn(arb_midref(acb_imagref(z))) < 0) { acb_neg(t, z); acb_exp_pi_i(t, t, prec + 4); acb_mul(res, t, t, prec + 4); acb_sub_ui(res, res, 1, prec + 4); acb_div(res, t, res, prec); acb_neg(res, res); } else { acb_exp_pi_i(t, z, prec + 4); acb_mul(res, t, t, prec + 4); acb_sub_ui(res, res, 1, prec + 4); acb_div(res, t, res, prec); } acb_mul_2exp_si(res, res, 1); acb_mul_onei(res, res); acb_clear(t); } else { acb_sin_pi(res, z, prec + 4); acb_inv(res, res, prec); } } } arb-2.22.1/acb/csch.c000066400000000000000000000034001417376376500141730ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_csch(acb_t res, const acb_t z, slong prec) { if (acb_contains_zero(z) || !acb_is_finite(z)) { acb_indeterminate(res); } else if (arb_is_zero(acb_imagref(z))) { arb_csch(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } else if (arb_is_zero(acb_realref(z))) { arb_csc(acb_imagref(res), acb_imagref(z), prec); arb_neg(acb_imagref(res), acb_imagref(res)); arb_zero(acb_realref(res)); } else { if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 0) > 0) { acb_t t; acb_init(t); if (arf_sgn(arb_midref(acb_realref(z))) > 0) { acb_neg(t, z); acb_exp(t, t, prec + 4); acb_mul(res, t, t, prec + 4); acb_sub_ui(res, res, 1, prec + 4); acb_div(res, t, res, prec); acb_neg(res, res); } else { acb_exp(t, z, prec + 4); acb_mul(res, t, t, prec + 4); acb_sub_ui(res, res, 1, prec + 4); acb_div(res, t, res, prec); } acb_mul_2exp_si(res, res, 1); acb_clear(t); } else { acb_sinh(res, z, prec + 4); acb_inv(res, res, prec); } } } arb-2.22.1/acb/csgn.c000066400000000000000000000011151417376376500142060ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_csgn(arb_t res, const acb_t z) { if (arb_is_zero(acb_realref(z))) { arb_sgn(res, acb_imagref(z)); } else { arb_sgn(res, acb_realref(z)); } } arb-2.22.1/acb/cube.c000066400000000000000000000024571417376376500142040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_cube(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_pow_ui(acb_realref(r), a, 3, prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(a)) { arb_pow_ui(acb_imagref(r), b, 3, prec); arb_neg(acb_imagref(r), acb_imagref(r)); arb_zero(acb_realref(r)); } else { arb_t t, u, v; arb_init(t); arb_init(u); arb_init(v); arb_mul(t, a, a, prec); arb_mul(u, b, b, prec); arb_set(v, t); /* t = a^2 - 3b^2 */ arb_submul_ui(t, u, 3, prec); /* u = -(b^2 - 3a^2) */ arb_submul_ui(u, v, 3, prec); arb_neg(u, u); arb_mul(acb_realref(r), t, a, prec); arb_mul(acb_imagref(r), u, b, prec); arb_clear(t); arb_clear(u); arb_clear(v); } #undef a #undef b } arb-2.22.1/acb/digamma.c000066400000000000000000000034111417376376500146540ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t x, int use_reflect, int digamma, slong prec); void acb_gamma_stirling_eval(acb_t s, const acb_t z, slong nterms, int digamma, slong prec); void acb_digamma(acb_t y, const acb_t x, slong prec) { int reflect; slong r, n, wp; acb_t t, u, v; if (acb_is_real(x)) { arb_digamma(acb_realref(y), acb_realref(x), prec); arb_zero(acb_imagref(y)); return; } wp = prec + FLINT_BIT_COUNT(prec); acb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 1, wp); acb_init(t); acb_init(u); acb_init(v); /* psi(x) = psi((1-x)+r) - h(1-x,r) - pi*cot(pi*x) */ if (reflect) { acb_sub_ui(t, x, 1, wp); acb_neg(t, t); acb_cot_pi(v, x, wp); arb_const_pi(acb_realref(u), wp); acb_mul_arb(v, v, acb_realref(u), wp); acb_rising2_ui(y, u, t, r, wp); acb_div(u, u, y, wp); acb_add(v, v, u, wp); acb_add_ui(t, t, r, wp); acb_gamma_stirling_eval(u, t, n, 1, wp); acb_sub(y, u, v, wp); } else { acb_add_ui(t, x, r, wp); acb_gamma_stirling_eval(u, t, n, 1, wp); acb_rising2_ui(y, t, x, r, wp); acb_div(t, t, y, wp); acb_sub(y, u, t, prec); } acb_clear(t); acb_clear(u); acb_clear(v); } arb-2.22.1/acb/div.c000066400000000000000000000057351417376376500140520ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_div(acb_t z, const acb_t x, const acb_t y, slong prec) { #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(y) #define d acb_imagref(y) if (arb_is_zero(d)) { if (arb_is_zero(b)) { arb_div(acb_realref(z), a, c, prec); arb_zero(acb_imagref(z)); } else if (arb_is_zero(a)) { arb_div(acb_imagref(z), b, c, prec); arb_zero(acb_realref(z)); } else if (z != y) { arb_div(acb_realref(z), a, c, prec); arb_div(acb_imagref(z), b, c, prec); } else { arb_t t; arb_init(t); arb_set(t, c); arb_div(acb_realref(z), a, t, prec); arb_div(acb_imagref(z), b, t, prec); arb_clear(t); } } else if (arb_is_zero(c)) { if (arb_is_zero(b)) { arb_div(acb_imagref(z), a, d, prec); arb_neg(acb_imagref(z), acb_imagref(z)); arb_zero(acb_realref(z)); } else if (arb_is_zero(a)) { arb_div(acb_realref(z), b, d, prec); arb_zero(acb_imagref(z)); } else if (z != y) { arb_div(acb_realref(z), a, d, prec); arb_div(acb_imagref(z), b, d, prec); arb_swap(acb_realref(z), acb_imagref(z)); arb_neg(acb_imagref(z), acb_imagref(z)); } else { arb_t t; arb_init(t); arb_set(t, d); arb_div(acb_realref(z), a, t, prec); arb_div(acb_imagref(z), b, t, prec); arb_swap(acb_realref(z), acb_imagref(z)); arb_neg(acb_imagref(z), acb_imagref(z)); arb_clear(t); } } else { if (prec > 256 && acb_bits(y) <= prec / 2 && acb_is_exact(y)) { arb_t t, u, v; arb_init(t); arb_init(u); arb_init(v); arb_mul(t, c, c, prec); arb_addmul(t, d, d, prec); arb_mul(u, a, c, prec); arb_addmul(u, b, d, prec); arb_mul(v, b, c, prec); arb_submul(v, a, d, prec); arb_div(acb_realref(z), u, t, prec); arb_div(acb_imagref(z), v, t, prec); arb_clear(t); arb_clear(u); arb_clear(v); } else { acb_t t; acb_init(t); acb_inv(t, y, prec); acb_mul(z, x, t, prec); acb_clear(t); } } #undef a #undef b #undef c #undef d } arb-2.22.1/acb/dot.c000066400000000000000000001016031417376376500140450ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" /* We need uint64_t instead of mp_limb_t on 32-bit systems for safe summation of 30-bit error bounds. */ #include /* The following macros are found in FLINT's longlong.h, but the release version is out of date. */ /* x86 : 64 bit */ #if (GMP_LIMB_BITS == 64 && defined (__amd64__)) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addq %8,%q2\n\tadcq %6,%q1\n\tadcq %4,%q0" \ : "=r" (sh), "=&r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "rme" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "rme" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "rme" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subq %8,%q2\n\tsbbq %6,%q1\n\tsbbq %4,%q0" \ : "=r" (dh), "=&r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "rme" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "rme" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "rme" ((mp_limb_t)(sl))) \ #endif /* x86_64 */ /* x86 : 32 bit */ #if (GMP_LIMB_BITS == 32 && (defined (__i386__) \ || defined (__i486__) || defined(__amd64__))) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addl %8,%k2\n\tadcl %6,%k1\n\tadcl %4,%k0" \ : "=r" (sh), "=r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "g" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "g" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "g" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subl %8,%k2\n\tsbbl %6,%k1\n\tsbbl %4,%k0" \ : "=r" (dh), "=r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "g" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "g" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "g" ((mp_limb_t)(sl))) \ #endif /* x86 */ #if !defined(add_sssaaaaaa2) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ do { \ mp_limb_t __t, __u; \ add_ssaaaa(__t, sl, (mp_limb_t) 0, al, (mp_limb_t) 0, bl); \ add_ssaaaa(__u, sm, (mp_limb_t) 0, am, (mp_limb_t) 0, bm); \ add_ssaaaa(sh, sm, ah + bh, sm, __u, __t); \ } while (0) #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ do { \ mp_limb_t __t, __u; \ sub_ddmmss(__t, dl, (mp_limb_t) 0, ml, (mp_limb_t) 0, sl); \ sub_ddmmss(__u, dm, (mp_limb_t) 0, mm, (mp_limb_t) 0, sm); \ sub_ddmmss(dh, dm, mh - sh, dm, -__u, -__t); \ } while (0) #endif /* Add ((a * b) / 2^MAG_BITS) * 2^exp into srad*2^srad_exp. Assumes that srad_exp >= exp and that overflow cannot occur. */ #define RAD_ADDMUL(srad, srad_exp, a, b, exp) \ do { \ uint64_t __a, __b; \ slong __shift; \ __a = (a); \ __b = (b); \ __shift = (srad_exp) - (exp); \ if (__shift < MAG_BITS) \ (srad) += (((__a) * (__b)) >> (MAG_BITS + __shift)) + 1; \ else \ (srad) += 1; \ } while (0) void mag_set_ui_2exp_small(mag_t z, ulong x, slong e); static void add_errors(mag_t rad, uint64_t Aerr, slong Aexp, uint64_t Berr, slong Bexp, uint64_t Cerr, slong Cexp) { slong shift; if (Aerr && Berr) { if (Aexp >= Bexp) { shift = Aexp - Bexp; if (shift < 64) Aerr = Aerr + (Berr >> shift) + 1; else Aerr = Aerr + 1; } else { shift = Bexp - Aexp; if (shift < 64) Aerr = Berr + (Aerr >> shift) + 1; else Aerr = Berr + 1; Aexp = Bexp; } } else if (Berr) { Aerr = Berr; Aexp = Bexp; } if (Aerr && Cerr) { if (Aexp >= Cexp) { shift = Aexp - Cexp; if (shift < 64) Aerr = Aerr + (Cerr >> shift) + 1; else Aerr = Aerr + 1; } else { shift = Cexp - Aexp; if (shift < 64) Aerr = Cerr + (Aerr >> shift) + 1; else Aerr = Cerr + 1; Aexp = Cexp; } } else if (Cerr) { Aerr = Cerr; Aexp = Cexp; } #if FLINT_BITS == 64 mag_set_ui_2exp_small(rad, Aerr, Aexp - MAG_BITS); #else mag_set_d(rad, Aerr * (1.0 + 1e-14)); mag_mul_2exp_si(rad, rad, Aexp - MAG_BITS); #endif } void _arb_dot_addmul_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, mp_srcptr yptr, mp_size_t yn, int negative, flint_bitcnt_t shift); void _arb_dot_add_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, int negative, flint_bitcnt_t shift); static void _arb_dot_output(arb_t res, mp_ptr sum, mp_size_t sn, int negative, uint64_t serr, slong sum_exp, uint64_t srad, slong srad_exp, slong prec) { slong exp_fix; int inexact; if (sum[sn - 1] >= LIMB_TOP) { mpn_neg(sum, sum, sn); negative ^= 1; } exp_fix = 0; if (sum[sn - 1] == 0) { slong sum_exp2; mp_size_t sn2; sn2 = sn; sum_exp2 = sum_exp; while (sn2 > 0 && sum[sn2 - 1] == 0) { sum_exp2 -= FLINT_BITS; sn2--; } if (sn2 == 0) { arf_zero(arb_midref(res)); inexact = 0; } else { inexact = _arf_set_round_mpn(arb_midref(res), &exp_fix, sum, sn2, negative, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp_fix + sum_exp2); } } else { if (sn == 2) /* unnecessary? */ inexact = _arf_set_round_uiui(arb_midref(res), &exp_fix, sum[1], sum[0], negative, prec, ARF_RND_DOWN); else inexact = _arf_set_round_mpn(arb_midref(res), &exp_fix, sum, sn, negative, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp_fix + sum_exp); } add_errors(arb_radref(res), inexact << MAG_BITS, exp_fix + sum_exp - prec, ((uint64_t) serr) << MAG_BITS, sum_exp - sn * FLINT_BITS, srad, srad_exp); } /* xxx: don't use surrounding variables */ #define ARB_DOT_ADD(s_sum, s_serr, s_sn, s_sum_exp, s_subtract, xm) \ if (!arf_is_special(xm)) \ { \ mp_srcptr xptr; \ xexp = ARF_EXP(xm); \ xn = ARF_SIZE(xm); \ xnegative = ARF_SGNBIT(xm); \ shift = s_sum_exp - xexp; \ if (shift >= s_sn * FLINT_BITS) \ { \ s_serr++; \ } \ else \ { \ xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); \ _arb_dot_add_generic(s_sum, &s_serr, tmp, s_sn, xptr, xn, xnegative ^ s_subtract, shift); \ } \ } \ /* xxx: don't use surrounding variables */ #define ARB_DOT_ADD_RAD(s_srad, s_srad_exp, xr) \ if (!mag_is_special(xr)) \ { \ xrad = MAG_MAN(xr); \ xrexp = MAG_EXP(xr); \ shift = s_srad_exp - xrexp; \ if (shift < 64) \ s_srad += (xrad >> shift) + 1; \ else \ s_srad++; \ } static void _arf_complex_mul_gauss(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d) { mp_srcptr ap, bp, cp, dp; int asgn, bsgn, csgn, dsgn; mp_size_t an, bn, cn, dn; slong aexp, bexp, cexp, dexp; fmpz texp, uexp; fmpz_t za, zb, zc, zd, t, u, v; slong abot, bbot, cbot, dbot; ARF_GET_MPN_READONLY(ap, an, a); asgn = ARF_SGNBIT(a); aexp = ARF_EXP(a); ARF_GET_MPN_READONLY(bp, bn, b); bsgn = ARF_SGNBIT(b); bexp = ARF_EXP(b); ARF_GET_MPN_READONLY(cp, cn, c); csgn = ARF_SGNBIT(c); cexp = ARF_EXP(c); ARF_GET_MPN_READONLY(dp, dn, d); dsgn = ARF_SGNBIT(d); dexp = ARF_EXP(d); /* Gauss multiplication e = ac - bd f = (a+b)(c+d) - ac - bd */ abot = aexp - an * FLINT_BITS; bbot = bexp - bn * FLINT_BITS; cbot = cexp - cn * FLINT_BITS; dbot = dexp - dn * FLINT_BITS; texp = FLINT_MIN(abot, bbot); uexp = FLINT_MIN(cbot, dbot); fmpz_init(za); fmpz_init(zb); fmpz_init(zc); fmpz_init(zd); fmpz_init(t); fmpz_init(u); fmpz_init(v); fmpz_lshift_mpn(za, ap, an, asgn, abot - texp); fmpz_lshift_mpn(zb, bp, bn, bsgn, bbot - texp); fmpz_lshift_mpn(zc, cp, cn, csgn, cbot - uexp); fmpz_lshift_mpn(zd, dp, dn, dsgn, dbot - uexp); fmpz_add(t, za, zb); fmpz_add(v, zc, zd); fmpz_mul(u, t, v); fmpz_mul(t, za, zc); fmpz_mul(v, zb, zd); fmpz_sub(u, u, t); fmpz_sub(u, u, v); fmpz_sub(t, t, v); texp += uexp; arf_set_fmpz_2exp(e, t, &texp); arf_set_fmpz_2exp(f, u, &texp); fmpz_clear(za); fmpz_clear(zb); fmpz_clear(zc); fmpz_clear(zd); fmpz_clear(t); fmpz_clear(u); fmpz_clear(v); } /* TODO: this could be much lower, but it's currently competing against mulhigh in the Karatsuba range. */ ARB_DLL slong acb_dot_gauss_dot_cutoff = 128; #define GAUSS_CUTOFF acb_dot_gauss_dot_cutoff void acb_dot(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) { slong i, j, padding, extend; slong xexp, yexp, exp; slong re_nonzero, im_nonzero; slong re_max_exp, re_min_exp, re_sum_exp; slong im_max_exp, im_min_exp, im_sum_exp; slong re_srad_exp, re_max_rad_exp; slong im_srad_exp, im_max_rad_exp; slong re_prec, im_prec; slong xrexp, yrexp; int xnegative, ynegative; mp_size_t xn, yn, re_sn, im_sn, alloc; flint_bitcnt_t shift; arb_srcptr xi, yi; arf_srcptr xm, ym; mag_srcptr xr, yr; mp_limb_t xtop, ytop; mp_limb_t xrad, yrad; mp_limb_t re_serr, im_serr; /* Sum over arithmetic errors */ uint64_t re_srad, im_srad; /* Sum over propagated errors */ mp_ptr tmp, re_sum, im_sum; /* Workspace */ slong xoff, yoff; char * use_gauss; ARF_ADD_TMP_DECL; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) acb_zero(res); else { acb_mul(res, x, y, prec); if (subtract) acb_neg(res, res); } return; } else if (len <= 0) { acb_set_round(res, initial, prec); return; } } /* Number of nonzero midpoint terms in sum. */ re_nonzero = 0; im_nonzero = 0; /* Terms are bounded by 2^max_exp (with WORD_MIN = -infty) */ re_max_exp = WORD_MIN; im_max_exp = WORD_MIN; /* Propagated error terms are bounded by 2^max_rad_exp */ re_max_rad_exp = WORD_MIN; im_max_rad_exp = WORD_MIN; /* Used to reduce the precision. */ re_min_exp = WORD_MAX; im_min_exp = WORD_MAX; /* Account for the initial term. */ if (initial != NULL) { if (!ARB_IS_LAGOM(acb_realref(initial)) || !ARB_IS_LAGOM(acb_imagref(initial))) { acb_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(acb_realref(initial)); xr = arb_radref(acb_realref(initial)); if (!arf_is_special(xm)) { re_max_exp = ARF_EXP(xm); re_nonzero++; if (prec > 2 * FLINT_BITS) re_min_exp = ARF_EXP(xm) - ARF_SIZE(xm) * FLINT_BITS; } if (!mag_is_special(xr)) re_max_rad_exp = MAG_EXP(xr); xm = arb_midref(acb_imagref(initial)); xr = arb_radref(acb_imagref(initial)); if (!arf_is_special(xm)) { im_max_exp = ARF_EXP(xm); im_nonzero++; if (prec > 2 * FLINT_BITS) im_min_exp = ARF_EXP(xm) - ARF_SIZE(xm) * FLINT_BITS; } if (!mag_is_special(xr)) im_max_rad_exp = MAG_EXP(xr); } for (xoff = 0; xoff < 2; xoff++) { for (yoff = 0; yoff < 2; yoff++) { slong nonzero, max_exp, min_exp, max_rad_exp; if (xoff == yoff) { nonzero = re_nonzero; max_exp = re_max_exp; min_exp = re_min_exp; max_rad_exp = re_max_rad_exp; } else { nonzero = im_nonzero; max_exp = im_max_exp; min_exp = im_min_exp; max_rad_exp = im_max_rad_exp; } /* Determine maximum exponents for the main sum and the radius sum. */ for (i = 0; i < len; i++) { xi = ((arb_srcptr) x) + 2 * i * xstep + xoff; yi = ((arb_srcptr) y) + 2 * i * ystep + yoff; /* Fallback for huge exponents or non-finite values. */ if (!ARB_IS_LAGOM(xi) || !ARB_IS_LAGOM(yi)) { acb_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(xi); ym = arb_midref(yi); xr = arb_radref(xi); yr = arb_radref(yi); /* (xm+xr)(ym+yr) = xm ym + [xr ym + xm yr + xr yr] */ if (!arf_is_special(xm)) { xexp = ARF_EXP(xm); if (!arf_is_special(ym)) { yexp = ARF_EXP(ym); max_exp = FLINT_MAX(max_exp, xexp + yexp); nonzero++; if (prec > 2 * FLINT_BITS) { slong bot; bot = (xexp + yexp) - (ARF_SIZE(xm) + ARF_SIZE(ym)) * FLINT_BITS; min_exp = FLINT_MIN(min_exp, bot); } if (!mag_is_special(xr)) { xrexp = MAG_EXP(xr); max_rad_exp = FLINT_MAX(max_rad_exp, yexp + xrexp); if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xexp + yrexp); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yrexp); } } else { if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xexp + yrexp); } } } else /* if y = 0, something can happen only if yr != 0 */ { if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xexp + yrexp); if (!mag_is_special(xr)) { xrexp = MAG_EXP(xr); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yrexp); } } } } else /* if x = 0, something can happen only if xr != 0 */ { if (!mag_is_special(xr)) { xrexp = MAG_EXP(xr); if (!arf_is_special(ym)) { yexp = ARF_EXP(ym); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yexp); } if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yrexp); } } } } if (xoff == yoff) { re_nonzero = nonzero; re_max_exp = max_exp; re_min_exp = min_exp; re_max_rad_exp = max_rad_exp; } else { im_nonzero = nonzero; im_max_exp = max_exp; im_min_exp = min_exp; im_max_rad_exp = max_rad_exp; } } } re_prec = prec; im_prec = prec; if (re_max_exp == WORD_MIN && re_max_rad_exp == WORD_MIN && im_max_exp == WORD_MIN && im_max_rad_exp == WORD_MIN) { acb_zero(res); return; } /* The midpoint sum is zero. */ if (re_max_exp == WORD_MIN) { re_prec = 2; } else { if (re_max_rad_exp != WORD_MIN) re_prec = FLINT_MIN(re_prec, re_max_exp - re_max_rad_exp + MAG_BITS); if (re_min_exp != WORD_MAX) re_prec = FLINT_MIN(re_prec, re_max_exp - re_min_exp + MAG_BITS); re_prec = FLINT_MAX(re_prec, 2); } if (im_max_exp == WORD_MIN) { im_prec = 2; } else { if (im_max_rad_exp != WORD_MIN) im_prec = FLINT_MIN(im_prec, im_max_exp - im_max_rad_exp + MAG_BITS); if (re_min_exp != WORD_MAX) im_prec = FLINT_MIN(im_prec, im_max_exp - im_min_exp + MAG_BITS); im_prec = FLINT_MAX(im_prec, 2); } extend = FLINT_BIT_COUNT(re_nonzero) + 1; padding = 4 + FLINT_BIT_COUNT(len); re_sn = (re_prec + extend + padding + FLINT_BITS - 1) / FLINT_BITS; re_sn = FLINT_MAX(re_sn, 2); re_sum_exp = re_max_exp + extend; extend = FLINT_BIT_COUNT(im_nonzero) + 1; padding = 4 + FLINT_BIT_COUNT(len); im_sn = (im_prec + extend + padding + FLINT_BITS - 1) / FLINT_BITS; im_sn = FLINT_MAX(im_sn, 2); im_sum_exp = im_max_exp + extend; /* We need sn + 1 limb for the sum (sn limbs + 1 dummy limb for carry or borrow that avoids an extra branch). We need 2 * (sn + 2) limbs to store the product of two numbers with up to (sn + 2) limbs, plus 1 extra limb for shifting the product. */ alloc = (re_sn + 1) + (im_sn + 1) + 2 * (FLINT_MAX(re_sn, im_sn) + 2) + 1; ARF_ADD_TMP_ALLOC(re_sum, alloc) im_sum = re_sum + (re_sn + 1); tmp = im_sum + (im_sn + 1); /* Sum of propagated errors. */ re_srad_exp = re_max_rad_exp; re_srad = 0; im_srad_exp = im_max_rad_exp; im_srad = 0; /* Set sum to 0 */ re_serr = 0; for (j = 0; j < re_sn + 1; j++) re_sum[j] = 0; im_serr = 0; for (j = 0; j < im_sn + 1; j++) im_sum[j] = 0; if (initial != NULL) { xm = arb_midref(acb_realref(initial)); xr = arb_radref(acb_realref(initial)); ARB_DOT_ADD(re_sum, re_serr, re_sn, re_sum_exp, subtract, xm); ARB_DOT_ADD_RAD(re_srad, re_srad_exp, xr); xm = arb_midref(acb_imagref(initial)); xr = arb_radref(acb_imagref(initial)); ARB_DOT_ADD(im_sum, im_serr, im_sn, im_sum_exp, subtract, xm); ARB_DOT_ADD_RAD(im_srad, im_srad_exp, xr); } /* Look for terms to process using the Gauss multiplication formula. If any such terms are found, we mask the ith entry in use_gauss so that they will be skipped in the main loop. Important: the cutoffs must be such that the fast case (xn <= 2, yn <= 2, sn <= 3) is not hit below and the mask check is done. The cutoffs below are not optimal in the generic case; also, it would be nicer to have both mulhigh and Gauss here. A more elegant solution would be to write a fallback version of acb_dot_simple where acb_addmul does the right thing. */ use_gauss = NULL; if (re_prec >= GAUSS_CUTOFF * FLINT_BITS && im_prec >= GAUSS_CUTOFF * FLINT_BITS) { arf_t e, f; for (i = 0; i < len; i++) { arb_srcptr ai, bi, ci, di; mp_size_t an, bn, cn, dn; slong aexp, bexp, cexp, dexp; ai = ((arb_srcptr) x) + 2 * i * xstep; bi = ((arb_srcptr) x) + 2 * i * xstep + 1; ci = ((arb_srcptr) y) + 2 * i * ystep; di = ((arb_srcptr) y) + 2 * i * ystep + 1; an = ARF_SIZE(arb_midref(ai)); bn = ARF_SIZE(arb_midref(bi)); cn = ARF_SIZE(arb_midref(ci)); dn = ARF_SIZE(arb_midref(di)); aexp = ARF_EXP(arb_midref(ai)); bexp = ARF_EXP(arb_midref(bi)); cexp = ARF_EXP(arb_midref(ci)); dexp = ARF_EXP(arb_midref(di)); if (an >= GAUSS_CUTOFF && bn >= GAUSS_CUTOFF && bn >= GAUSS_CUTOFF && cn >= GAUSS_CUTOFF && FLINT_ABS(an - bn) <= 2 && FLINT_ABS(cn - dn) <= 2 && FLINT_ABS(aexp - bexp) <= 64 && FLINT_ABS(cexp - dexp) <= 64 && re_sum_exp - (aexp + cexp) < 0.1 * re_prec && im_sum_exp - (aexp + dexp) < 0.1 * im_prec && an + cn < 2.2 * re_sn && an + dn < 2.2 * im_sn) { if (use_gauss == NULL) { use_gauss = flint_calloc(len, sizeof(char)); arf_init(e); arf_init(f); } use_gauss[i] = 1; _arf_complex_mul_gauss(e, f, arb_midref(ai), arb_midref(bi), arb_midref(ci), arb_midref(di)); ARB_DOT_ADD(re_sum, re_serr, re_sn, re_sum_exp, 0, e); ARB_DOT_ADD(im_sum, im_serr, im_sn, im_sum_exp, 0, f); } } if (use_gauss != NULL) { arf_clear(e); arf_clear(f); } } for (xoff = 0; xoff < 2; xoff++) { for (yoff = 0; yoff < 2; yoff++) { slong sum_exp, srad_exp; mp_ptr sum; mp_size_t sn; mp_limb_t serr; uint64_t srad; int flipsign; if (xoff == yoff) { sum_exp = re_sum_exp; srad_exp = re_srad_exp; sum = re_sum; sn = re_sn; if (re_max_exp == WORD_MIN && re_max_rad_exp == WORD_MIN) continue; } else { sum_exp = im_sum_exp; srad_exp = im_srad_exp; sum = im_sum; sn = im_sn; if (im_max_exp == WORD_MIN && im_max_rad_exp == WORD_MIN) continue; } serr = 0; srad = 0; flipsign = (xoff + yoff == 2); for (i = 0; i < len; i++) { xi = ((arb_srcptr) x) + 2 * i * xstep + xoff; yi = ((arb_srcptr) y) + 2 * i * ystep + yoff; xm = arb_midref(xi); ym = arb_midref(yi); xr = arb_radref(xi); yr = arb_radref(yi); /* The midpoints of x[i] and y[i] are both nonzero. */ if (!arf_is_special(xm) && !arf_is_special(ym)) { xexp = ARF_EXP(xm); xn = ARF_SIZE(xm); xnegative = ARF_SGNBIT(xm); yexp = ARF_EXP(ym); yn = ARF_SIZE(ym); ynegative = ARF_SGNBIT(ym); exp = xexp + yexp; shift = sum_exp - exp; if (shift >= sn * FLINT_BITS) { /* We may yet need the top limbs for bounds. */ ARF_GET_TOP_LIMB(xtop, xm); ARF_GET_TOP_LIMB(ytop, ym); serr++; } else if (xn <= 2 && yn <= 2 && sn <= 3) { mp_limb_t x1, x0, y1, y0; mp_limb_t u3, u2, u1, u0; if (xn == 1 && yn == 1) { xtop = ARF_NOPTR_D(xm)[0]; ytop = ARF_NOPTR_D(ym)[0]; umul_ppmm(u3, u2, xtop, ytop); u1 = u0 = 0; } else if (xn == 2 && yn == 2) { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; xtop = x1; ytop = y1; nn_mul_2x2(u3, u2, u1, u0, x1, x0, y1, y0); } else if (xn == 1) { x0 = ARF_NOPTR_D(xm)[0]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; xtop = x0; ytop = y1; nn_mul_2x1(u3, u2, u1, y1, y0, x0); u0 = 0; } else { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; xtop = x1; ytop = y0; nn_mul_2x1(u3, u2, u1, x1, x0, y0); u0 = 0; } if (sn == 2) { if (shift < FLINT_BITS) { serr += ((u2 << (FLINT_BITS - shift)) != 0) || (u1 != 0) || (u0 != 0); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { serr += (u2 != 0) || (u1 != 0) || (u0 != 0); u2 = u3; u3 = 0; } else /* FLINT_BITS < shift < 2 * FLINT_BITS */ { serr += ((u3 << (2 * FLINT_BITS - shift)) != 0) || (u2 != 0) || (u1 != 0) || (u0 != 0); u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } if (xnegative ^ ynegative ^ flipsign) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], u3, u2); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], u3, u2); } else if (sn == 3) { if (shift < FLINT_BITS) { serr += ((u1 << (FLINT_BITS - shift)) != 0) || (u0 != 0); u1 = (u1 >> shift) | (u2 << (FLINT_BITS - shift)); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { serr += (u1 != 0) || (u0 != 0); u1 = u2; u2 = u3; u3 = 0; } else if (shift < 2 * FLINT_BITS) { serr += ((u2 << (2 * FLINT_BITS - shift)) != 0) || (u1 != 0) || (u0 != 0); u1 = (u3 << (2 * FLINT_BITS - shift)) | (u2 >> (shift - FLINT_BITS)); u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } else if (shift == 2 * FLINT_BITS) { serr += (u2 != 0) || (u1 != 0) || (u0 != 0); u1 = u3; u2 = 0; u3 = 0; } else /* 2 * FLINT_BITS < shift < 3 * FLINT_BITS */ { serr += ((u3 << (3 * FLINT_BITS - shift)) != 0) || (u2 != 0) || (u1 != 0) || (u0 != 0); u1 = (u3 >> (shift - 2 * FLINT_BITS)); u2 = 0; u3 = 0; } if (xnegative ^ ynegative ^ flipsign) sub_dddmmmsss2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); else add_sssaaaaaa2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); } } else { mp_srcptr xptr, yptr; xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); yptr = (yn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(ym) : ARF_PTR_D(ym); xtop = xptr[xn - 1]; ytop = yptr[yn - 1]; if (use_gauss == NULL || use_gauss[i] == 0) _arb_dot_addmul_generic(sum, &serr, tmp, sn, xptr, xn, yptr, yn, xnegative ^ ynegative ^ flipsign, shift); } xrad = MAG_MAN(xr); yrad = MAG_MAN(yr); if (xrad != 0 && yrad != 0) { xrexp = MAG_EXP(xr); yrexp = MAG_EXP(yr); RAD_ADDMUL(srad, srad_exp, (xtop >> (FLINT_BITS - MAG_BITS)) + 1, yrad, xexp + yrexp); RAD_ADDMUL(srad, srad_exp, (ytop >> (FLINT_BITS - MAG_BITS)) + 1, xrad, yexp + xrexp); RAD_ADDMUL(srad, srad_exp, xrad, yrad, xrexp + yrexp); } else if (xrad != 0) { xrexp = MAG_EXP(xr); RAD_ADDMUL(srad, srad_exp, (ytop >> (FLINT_BITS - MAG_BITS)) + 1, xrad, yexp + xrexp); } else if (yrad != 0) { yrexp = MAG_EXP(yr); RAD_ADDMUL(srad, srad_exp, (xtop >> (FLINT_BITS - MAG_BITS)) + 1, yrad, xexp + yrexp); } } else { xrad = MAG_MAN(xr); yrad = MAG_MAN(yr); xexp = ARF_EXP(xm); yexp = ARF_EXP(ym); xrexp = MAG_EXP(xr); yrexp = MAG_EXP(yr); /* (xm+xr)(ym+yr) = xm ym + [xm yr + ym xr + xr yr] */ if (yrad && !arf_is_special(xm)) { ARF_GET_TOP_LIMB(xtop, xm); RAD_ADDMUL(srad, srad_exp, (xtop >> (FLINT_BITS - MAG_BITS)) + 1, yrad, xexp + yrexp); } if (xrad && !arf_is_special(ym)) { ARF_GET_TOP_LIMB(ytop, ym); RAD_ADDMUL(srad, srad_exp, (ytop >> (FLINT_BITS - MAG_BITS)) + 1, xrad, yexp + xrexp); } if (xrad && yrad) { RAD_ADDMUL(srad, srad_exp, xrad, yrad, xrexp + yrexp); } } } if (xoff == yoff) { re_serr += serr; re_srad += srad; } else { im_serr += serr; im_srad += srad; } } } _arb_dot_output(acb_realref(res), re_sum, re_sn, subtract, re_serr, re_sum_exp, re_srad, re_srad_exp, re_prec); _arb_dot_output(acb_imagref(res), im_sum, im_sn, subtract, im_serr, im_sum_exp, im_srad, im_srad_exp, im_prec); ARF_ADD_TMP_FREE(re_sum, alloc); if (use_gauss != NULL) flint_free(use_gauss); } arb-2.22.1/acb/dot_fmpz.c000066400000000000000000000100511417376376500150750ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_dot_fmpz(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const fmpz * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i, ssize, size, tmp_size; mp_ptr ztmp; fmpz v; ulong av, al; unsigned int bc; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) acb_zero(res); else { acb_mul_fmpz(res, x, y, prec); if (subtract) acb_neg(res, res); } return; } else if (len <= 0) { acb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); tmp_size = 0; for (i = 0; i < len; i++) { v = y[i * ystep]; MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; if (v == 0) { ARF_XSIZE(arb_midref(t + i)) = 0; ARF_EXP(arb_midref(t + i)) = ARF_EXP_ZERO; } else if (!COEFF_IS_MPZ(v)) { av = FLINT_ABS(v); count_leading_zeros(bc, av); ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = av << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, v < 0); } else { __mpz_struct * z = COEFF_TO_PTR(v); ssize = z->_mp_size; size = FLINT_ABS(ssize); av = z->_mp_d[size - 1]; count_leading_zeros(bc, av); if (size == 1) { ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = av << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, ssize < 0); } else if (size == 2) { al = z->_mp_d[0]; ARF_EXP(arb_midref(t + i)) = 2 * FLINT_BITS - bc; if (bc != 0) { av = (av << bc) | (al >> (FLINT_BITS - bc)); al = al << bc; } ARF_NOPTR_D(arb_midref(t + i))[0] = al; ARF_NOPTR_D(arb_midref(t + i))[1] = av; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(2, ssize < 0); } else { if (bc != 0) { tmp_size += size; /* use to flag tmp where we need tmp storage */ MAG_MAN(arb_radref(t + i)) = bc; } ARF_EXP(arb_midref(t + i)) = size * FLINT_BITS - bc; ARF_PTR_D(arb_midref(t + i)) = z->_mp_d; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(size, ssize < 0); } } } if (tmp_size != 0) { ztmp = TMP_ALLOC(sizeof(mp_limb_t) * tmp_size); for (i = 0; i < len; i++) { bc = MAG_MAN(arb_radref(t + i)); if (bc != 0) { size = ARF_SIZE(arb_midref(t + i)); mpn_lshift(ztmp, ARF_PTR_D(arb_midref(t + i)), size, bc); ARF_PTR_D(arb_midref(t + i)) = ztmp; ztmp += size; } MAG_MAN(arb_radref(t + i)) = 0; } } arb_dot(((arb_ptr) res) + 0, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 0, subtract, ((arb_srcptr) x) + 0, 2 * xstep, t, 1, len, prec); arb_dot(((arb_ptr) res) + 1, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 1, subtract, ((arb_srcptr) x) + 1, 2 * xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/acb/dot_precise.c000066400000000000000000000030771417376376500155650ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_dot_precise(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) { arb_ptr tmp; slong i; tmp = flint_malloc(sizeof(arb_struct) * (4 * len)); for (i = 0; i < len; i++) { tmp[0 * len + i] = *acb_realref(x + i * xstep); tmp[1 * len + i] = *acb_imagref(x + i * xstep); tmp[2 * len + i] = *acb_realref(y + i * ystep); arb_init(tmp + 3 * len + i); arb_neg(tmp + 3 * len + i, acb_imagref(y + i * ystep)); } arb_dot_precise(acb_realref(res), initial == NULL ? NULL : acb_realref(initial), subtract, tmp, 1, tmp + 2 * len, 1, 2 * len, prec); for (i = 0; i < len; i++) arb_clear(tmp + 3 * len + i); for (i = 0; i < len; i++) { tmp[0 * len + i] = *acb_realref(x + i * xstep); tmp[1 * len + i] = *acb_imagref(x + i * xstep); tmp[2 * len + i] = *acb_imagref(y + i * ystep); tmp[3 * len + i] = *acb_realref(y + i * ystep); } arb_dot_precise(acb_imagref(res), initial == NULL ? NULL : acb_imagref(initial), subtract, tmp, 1, tmp + 2 * len, 1, 2 * len, prec); flint_free(tmp); } arb-2.22.1/acb/dot_si.c000066400000000000000000000040301417376376500145340ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_dot_si(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const slong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; slong v; ulong av; unsigned int bc; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) acb_zero(res); else { acb_mul_si(res, x, y[0], prec); if (subtract) acb_neg(res, res); } return; } else if (len <= 0) { acb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { v = y[i * ystep]; if (v == 0) { ARF_XSIZE(arb_midref(t + i)) = 0; ARF_EXP(arb_midref(t + i)) = ARF_EXP_ZERO; } else { av = FLINT_ABS(v); count_leading_zeros(bc, av); ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = av << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, v < 0); } MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(((arb_ptr) res) + 0, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 0, subtract, ((arb_srcptr) x) + 0, 2 * xstep, t, 1, len, prec); arb_dot(((arb_ptr) res) + 1, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 1, subtract, ((arb_srcptr) x) + 1, 2 * xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/acb/dot_simple.c000066400000000000000000000021121417376376500154110ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_dot_simple(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) { slong i; if (len <= 0) { if (initial == NULL) acb_zero(res); else acb_set_round(res, initial, prec); return; } if (initial == NULL) { acb_mul(res, x, y, prec); } else { if (subtract) acb_neg(res, initial); else acb_set(res, initial); acb_addmul(res, x, y, prec); } for (i = 1; i < len; i++) acb_addmul(res, x + i * xstep, y + i * ystep, prec); if (subtract) acb_neg(res, res); } arb-2.22.1/acb/dot_siui.c000066400000000000000000000057451417376376500151100ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void arf_shallow_set_siui(arf_t res, ulong vhi, ulong vlo) { int negative; unsigned int bc; negative = ((slong) vhi) < 0; if (negative) { vhi = -vhi - (vlo != 0); vlo = -vlo; } if (vhi == 0) { if (vlo == 0) { ARF_XSIZE(res) = 0; ARF_EXP(res) = ARF_EXP_ZERO; } else { count_leading_zeros(bc, vlo); ARF_EXP(res) = FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, negative); } } else if (vlo == 0) { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vhi << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, negative); } else { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; if (bc == 0) ARF_NOPTR_D(res)[1] = vhi; else ARF_NOPTR_D(res)[1] = (vhi << bc) | (vlo >> (FLINT_BITS - bc)); ARF_XSIZE(res) = ARF_MAKE_XSIZE(2, negative); } } void acb_dot_siui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; ulong vhi, vlo; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) acb_zero(res); else { arf_t t; arf_shallow_set_siui(t, y[1], y[0]); arb_mul_arf(acb_realref(res), acb_realref(x), t, prec); arb_mul_arf(acb_imagref(res), acb_imagref(x), t, prec); if (subtract) acb_neg(res, res); } return; } else if (len <= 0) { acb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { vlo = y[2 * i * ystep]; vhi = y[2 * i * ystep + 1]; arf_shallow_set_siui(arb_midref(t + i), vhi, vlo); MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(((arb_ptr) res) + 0, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 0, subtract, ((arb_srcptr) x) + 0, 2 * xstep, t, 1, len, prec); arb_dot(((arb_ptr) res) + 1, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 1, subtract, ((arb_srcptr) x) + 1, 2 * xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/acb/dot_ui.c000066400000000000000000000037451417376376500145520ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_dot_ui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; ulong v; unsigned int bc; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) acb_zero(res); else { acb_mul_ui(res, x, y[0], prec); if (subtract) acb_neg(res, res); } return; } else if (len <= 0) { acb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { v = y[i * ystep]; if (v == 0) { ARF_XSIZE(arb_midref(t + i)) = 0; ARF_EXP(arb_midref(t + i)) = ARF_EXP_ZERO; } else { count_leading_zeros(bc, v); ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = v << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, 0); } MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(((arb_ptr) res) + 0, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 0, subtract, ((arb_srcptr) x) + 0, 2 * xstep, t, 1, len, prec); arb_dot(((arb_ptr) res) + 1, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 1, subtract, ((arb_srcptr) x) + 1, 2 * xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/acb/dot_uiui.c000066400000000000000000000055071417376376500151060ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void arf_shallow_set_uiui(arf_t res, ulong vhi, ulong vlo) { unsigned int bc; if (vhi == 0) { if (vlo == 0) { ARF_XSIZE(res) = 0; ARF_EXP(res) = ARF_EXP_ZERO; } else { count_leading_zeros(bc, vlo); ARF_EXP(res) = FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, 0); } } else if (vlo == 0) { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vhi << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, 0); } else { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; if (bc == 0) ARF_NOPTR_D(res)[1] = vhi; else ARF_NOPTR_D(res)[1] = (vhi << bc) | (vlo >> (FLINT_BITS - bc)); ARF_XSIZE(res) = ARF_MAKE_XSIZE(2, 0); } } void acb_dot_uiui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; ulong vhi, vlo; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) acb_zero(res); else { arf_t t; arf_shallow_set_uiui(t, y[1], y[0]); arb_mul_arf(acb_realref(res), acb_realref(x), t, prec); arb_mul_arf(acb_imagref(res), acb_imagref(x), t, prec); if (subtract) acb_neg(res, res); } return; } else if (len <= 0) { acb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { vlo = y[2 * i * ystep]; vhi = y[2 * i * ystep + 1]; arf_shallow_set_uiui(arb_midref(t + i), vhi, vlo); MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(((arb_ptr) res) + 0, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 0, subtract, ((arb_srcptr) x) + 0, 2 * xstep, t, 1, len, prec); arb_dot(((arb_ptr) res) + 1, (initial == NULL) ? NULL : ((arb_srcptr) initial) + 1, subtract, ((arb_srcptr) x) + 1, 2 * xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/acb/exp.c000066400000000000000000000020531417376376500140520ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_exp(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_exp(acb_realref(r), a, prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(a)) { arb_sin_cos(acb_imagref(r), acb_realref(r), b, prec); } else { arb_t t, u, v; arb_init(t); arb_init(u); arb_init(v); arb_exp(t, a, prec); arb_sin_cos(u, v, b, prec); arb_mul(acb_realref(r), t, v, prec); arb_mul(acb_imagref(r), t, u, prec); arb_clear(t); arb_clear(u); arb_clear(v); } #undef a #undef b } arb-2.22.1/acb/exp_invexp.c000066400000000000000000000025201417376376500154420ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_exp_invexp(acb_t r, acb_t s, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_exp_invexp(acb_realref(r), acb_realref(s), a, prec); arb_zero(acb_imagref(r)); arb_zero(acb_imagref(s)); } else if (arb_is_zero(a)) { arb_sin_cos(acb_imagref(r), acb_realref(r), b, prec); acb_conj(s, r); } else { arb_t t, u, v, w; arb_init(t); arb_init(u); arb_init(v); arb_init(w); arb_exp_invexp(t, u, a, prec); arb_sin_cos(v, w, b, prec); arb_mul(acb_realref(r), t, w, prec); arb_mul(acb_imagref(r), t, v, prec); arb_mul(acb_realref(s), u, w, prec); arb_mul(acb_imagref(s), u, v, prec); arb_neg(acb_imagref(s), acb_imagref(s)); arb_clear(t); arb_clear(u); arb_clear(v); arb_clear(w); } #undef a #undef b } arb-2.22.1/acb/exp_pi_i.c000066400000000000000000000024611417376376500150550ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_exp_pi_i(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_sin_cos_pi(acb_imagref(r), acb_realref(r), a, prec); } else if (arb_is_zero(a)) { arb_const_pi(acb_realref(r), prec); arb_mul(acb_realref(r), acb_realref(r), b, prec); arb_neg(acb_realref(r), acb_realref(r)); arb_exp(acb_realref(r), acb_realref(r), prec); arb_zero(acb_imagref(r)); } else { arb_t t, u, v; arb_init(t); arb_init(u); arb_init(v); arb_const_pi(t, prec); arb_mul(t, t, b, prec); arb_neg(t, t); arb_exp(t, t, prec); arb_sin_cos_pi(u, v, a, prec); arb_mul(acb_realref(r), t, v, prec); arb_mul(acb_imagref(r), t, u, prec); arb_clear(t); arb_clear(u); arb_clear(v); } #undef a #undef b } arb-2.22.1/acb/expm1.c000066400000000000000000000040431417376376500143110ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_expm1(acb_t res, const acb_t z, slong prec) { if (acb_is_real(z)) { arb_expm1(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } else if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -3) <= 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -3) <= 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -3) <= 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -3) <= 0) { arf_srcptr midmax; slong extra; if (arf_cmpabs(arb_midref(acb_realref(z)), arb_midref(acb_imagref(z))) >= 0) midmax = arb_midref(acb_realref(z)); else midmax = arb_midref(acb_imagref(z)); if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -prec - 100) > 0) { extra = -ARF_EXP(midmax); extra = FLINT_MIN(extra, prec + 100); extra = FLINT_MAX(extra, 0); acb_exp(res, z, prec + extra + 4); acb_sub_ui(res, res, 1, prec); } else { /* lazy solution: e^z-1 = 4 (sinh(z/4)+cosh(z/4))^2 sinh(z/4) cosh(z/4) */ acb_t t, u; acb_init(t); acb_init(u); acb_mul_2exp_si(t, z, -2); acb_sinh_cosh(t, u, t, prec + 4); acb_add(res, t, u, prec + 4); acb_mul(res, res, res, prec + 4); acb_mul(t, t, u, prec + 4); acb_mul(res, res, t, prec); acb_mul_2exp_si(res, res, 2); acb_clear(t); acb_clear(u); } } else { acb_exp(res, z, prec + 4); acb_sub_ui(res, res, 1, prec); } } arb-2.22.1/acb/fprintd.c000066400000000000000000000022441417376376500147260ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_fprintd(FILE * file, const acb_t z, slong digits) { flint_fprintf(file, "("); arf_fprintd(file, arb_midref(acb_realref(z)), digits); if (arf_sgn(arb_midref(acb_imagref(z))) < 0) { arf_t t; arf_init_neg_shallow(t, arb_midref(acb_imagref(z))); flint_fprintf(file, " - "); arf_fprintd(file, t, digits); } else { flint_fprintf(file, " + "); arf_fprintd(file, arb_midref(acb_imagref(z)), digits); } flint_fprintf(file, "j)"); flint_fprintf(file, " +/- "); flint_fprintf(file, "("); mag_fprintd(file, arb_radref(acb_realref(z)), 3); flint_fprintf(file, ", "); mag_fprintd(file, arb_radref(acb_imagref(z)), 3); flint_fprintf(file, "j)"); } arb-2.22.1/acb/fprintn.c000066400000000000000000000025321417376376500147400ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_fprintn(FILE * file, const acb_t z, slong digits, ulong flags) { if (arb_is_zero(acb_imagref(z))) { arb_fprintn(file, acb_realref(z), digits, flags); } else if (arb_is_zero(acb_realref(z))) { arb_fprintn(file, acb_imagref(z), digits, flags); flint_fprintf(file, "*I"); } else { arb_fprintn(file, acb_realref(z), digits, flags); if ((arb_is_exact(acb_imagref(z)) || (flags & ARB_STR_NO_RADIUS)) && arf_sgn(arb_midref(acb_imagref(z))) < 0) { arb_t t; arb_init(t); arb_neg(t, acb_imagref(z)); flint_fprintf(file, " - "); arb_fprintn(file, t, digits, flags); arb_clear(t); } else { flint_fprintf(file, " + "); arb_fprintn(file, acb_imagref(z), digits, flags); } flint_fprintf(file, "*I"); } } arb-2.22.1/acb/gamma.c000066400000000000000000000064311417376376500143440ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" #include "acb.h" #include "acb_hypgeom.h" void acb_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t z, int use_reflect, int digamma, slong prec); void acb_gamma_stirling_bound(mag_ptr err, const acb_t z, slong k0, slong knum, slong n); void arb_gamma_stirling_coeff(arb_t b, ulong k, int digamma, slong prec); void acb_gamma_stirling_eval(acb_t s, const acb_t z, slong nterms, int digamma, slong prec) { acb_t t, logz, zinv, zinv2; arb_t b; mag_t err; slong k, term_prec; double z_mag, term_mag; acb_init(t); acb_init(logz); acb_init(zinv); acb_init(zinv2); arb_init(b); acb_log(logz, z, prec); acb_inv(zinv, z, prec); nterms = FLINT_MAX(nterms, 1); acb_zero(s); if (nterms > 1) { acb_mul(zinv2, zinv, zinv, prec); z_mag = arf_get_d(arb_midref(acb_realref(logz)), ARF_RND_UP) * 1.44269504088896; for (k = nterms - 1; k >= 1; k--) { term_mag = bernoulli_bound_2exp_si(2 * k); term_mag -= (2 * k - 1) * z_mag; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); arb_gamma_stirling_coeff(b, k, digamma, term_prec); if (prec > 2000) { acb_set_round(t, zinv2, term_prec); acb_mul(s, s, t, term_prec); } else acb_mul(s, s, zinv2, term_prec); arb_add(acb_realref(s), acb_realref(s), b, term_prec); } if (digamma) acb_mul(s, s, zinv2, prec); else acb_mul(s, s, zinv, prec); } /* remainder bound */ mag_init(err); acb_gamma_stirling_bound(err, z, digamma ? 1 : 0, 1, nterms); mag_add(arb_radref(acb_realref(s)), arb_radref(acb_realref(s)), err); mag_add(arb_radref(acb_imagref(s)), arb_radref(acb_imagref(s)), err); mag_clear(err); if (digamma) { acb_neg(s, s); acb_mul_2exp_si(zinv, zinv, -1); acb_sub(s, s, zinv, prec); acb_add(s, s, logz, prec); } else { /* (z-0.5)*log(z) - z + log(2*pi)/2 */ arb_one(b); arb_mul_2exp_si(b, b, -1); arb_set(acb_imagref(t), acb_imagref(z)); arb_sub(acb_realref(t), acb_realref(z), b, prec); acb_mul(t, logz, t, prec); acb_add(s, s, t, prec); acb_sub(s, s, z, prec); arb_const_log_sqrt2pi(b, prec); arb_add(acb_realref(s), acb_realref(s), b, prec); } acb_clear(t); acb_clear(logz); acb_clear(zinv); acb_clear(zinv2); arb_clear(b); } void acb_gamma(acb_t y, const acb_t x, slong prec) { acb_hypgeom_gamma(y, x, prec); } void acb_rgamma(acb_t y, const acb_t x, slong prec) { acb_hypgeom_rgamma(y, x, prec); } void acb_lgamma(acb_t y, const acb_t x, slong prec) { acb_hypgeom_lgamma(y, x, prec); } arb-2.22.1/acb/get_abs_lbound_arf.c000066400000000000000000000020471417376376500170600ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_get_abs_lbound_arf(arf_t u, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_get_abs_lbound_arf(u, acb_realref(z), prec); } else if (arb_is_zero(acb_realref(z))) { arb_get_abs_lbound_arf(u, acb_imagref(z), prec); } else { arf_t v; arf_init(v); arb_get_abs_lbound_arf(u, acb_realref(z), prec); arb_get_abs_lbound_arf(v, acb_imagref(z), prec); arf_mul(u, u, u, prec, ARF_RND_DOWN); arf_mul(v, v, v, prec, ARF_RND_DOWN); arf_add(u, u, v, prec, ARF_RND_DOWN); arf_sqrt(u, u, prec, ARF_RND_DOWN); arf_clear(v); } } arb-2.22.1/acb/get_abs_ubound_arf.c000066400000000000000000000020371417376376500170700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_get_abs_ubound_arf(arf_t u, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_get_abs_ubound_arf(u, acb_realref(z), prec); } else if (arb_is_zero(acb_realref(z))) { arb_get_abs_ubound_arf(u, acb_imagref(z), prec); } else { arf_t v; arf_init(v); arb_get_abs_ubound_arf(u, acb_realref(z), prec); arb_get_abs_ubound_arf(v, acb_imagref(z), prec); arf_mul(u, u, u, prec, ARF_RND_UP); arf_mul(v, v, v, prec, ARF_RND_UP); arf_add(u, u, v, prec, ARF_RND_UP); arf_sqrt(u, u, prec, ARF_RND_UP); arf_clear(v); } } arb-2.22.1/acb/get_mag.c000066400000000000000000000015461417376376500146670ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_get_mag(mag_t u, const acb_t z) { if (arb_is_zero(acb_imagref(z))) { arb_get_mag(u, acb_realref(z)); } else if (arb_is_zero(acb_realref(z))) { arb_get_mag(u, acb_imagref(z)); } else { mag_t v; mag_init(v); arb_get_mag(u, acb_realref(z)); arb_get_mag(v, acb_imagref(z)); mag_mul(u, u, u); mag_addmul(u, v, v); mag_sqrt(u, u); mag_clear(v); } } arb-2.22.1/acb/get_mag_lower.c000066400000000000000000000016631417376376500160770ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_get_mag_lower(mag_t z, const acb_t x) { if (arb_is_zero(acb_imagref(x))) { arb_get_mag_lower(z, acb_realref(x)); } else if (arb_is_zero(acb_realref(x))) { arb_get_mag_lower(z, acb_imagref(x)); } else { mag_t t; mag_init(t); arb_get_mag_lower(t, acb_realref(x)); arb_get_mag_lower(z, acb_imagref(x)); mag_mul_lower(t, t, t); mag_mul_lower(z, z, z); mag_add_lower(z, z, t); mag_sqrt_lower(z, z); mag_clear(t); } } arb-2.22.1/acb/get_rad_ubound_arf.c000066400000000000000000000013341417376376500170700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_get_rad_ubound_arf(arf_t u, const acb_t z, slong prec) { /* fixme: this bound is very sloppy */ if (mag_cmp(arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))) >= 0) arf_set_mag(u, arb_radref(acb_realref(z))); else arf_set_mag(u, arb_radref(acb_imagref(z))); arf_mul_2exp_si(u, u, 1); } arb-2.22.1/acb/get_unique_fmpz.c000066400000000000000000000010661417376376500164620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int acb_get_unique_fmpz(fmpz_t z, const acb_t x) { if (!arb_contains_zero(acb_imagref(x))) return 0; return arb_get_unique_fmpz(z, acb_realref(x)); } arb-2.22.1/acb/inlines.c000066400000000000000000000006441417376376500147230ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ACB_INLINES_C #include "acb.h" arb-2.22.1/acb/inv.c000066400000000000000000000125021417376376500140520ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void _arb_arf_div_rounded_den(arb_t res, const arf_t x, const arf_t y, int yinexact, slong prec) { int inexact = arf_div(arb_midref(res), x, y, prec, ARB_RND); if (yinexact && !arf_is_special(arb_midref(res))) arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec - 1); else if (inexact) arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec); else mag_zero(arb_radref(res)); } static void _arb_arf_div_rounded_den_add_err(arb_t res, const arf_t x, const arf_t y, int yinexact, slong prec) { int inexact = arf_div(arb_midref(res), x, y, prec, ARB_RND); if (yinexact && !arf_is_special(arb_midref(res))) arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec - 1); else if (inexact) arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec); } void acb_inv(acb_t res, const acb_t z, slong prec) { mag_t am, bm; slong hprec; #define a arb_midref(acb_realref(z)) #define b arb_midref(acb_imagref(z)) #define x arb_radref(acb_realref(z)) #define y arb_radref(acb_imagref(z)) /* choose precision for the floating-point approximation of a^2+b^2 so that the double rounding result in less than 2 ulp error; also use at least MAG_BITS bits since the value will be recycled for error bounds */ hprec = FLINT_MAX(prec + 3, MAG_BITS); if (arb_is_zero(acb_imagref(z))) { arb_inv(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); return; } if (arb_is_zero(acb_realref(z))) { arb_inv(acb_imagref(res), acb_imagref(z), prec); arb_neg(acb_imagref(res), acb_imagref(res)); arb_zero(acb_realref(res)); return; } if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (mag_is_zero(x) && mag_is_zero(y)) { int inexact; arf_t a2b2; arf_init(a2b2); inexact = arf_sosq(a2b2, a, b, hprec, ARF_RND_DOWN); if (arf_is_special(a2b2)) { acb_indeterminate(res); } else { _arb_arf_div_rounded_den(acb_realref(res), a, a2b2, inexact, prec); _arb_arf_div_rounded_den(acb_imagref(res), b, a2b2, inexact, prec); arf_neg(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(res))); } arf_clear(a2b2); return; } mag_init(am); mag_init(bm); /* first bound |a|-x, |b|-y */ arb_get_mag_lower(am, acb_realref(z)); arb_get_mag_lower(bm, acb_imagref(z)); if ((mag_is_zero(am) && mag_is_zero(bm))) { acb_indeterminate(res); } else { /* The propagated error in the real part is given exactly by (a+x')/((a+x')^2+(b+y'))^2 - a/(a^2+b^2) = P / Q, P = [(b^2-a^2) x' - a (x'^2+y'^2 + 2y'b)] Q = [(a^2+b^2)((a+x')^2+(b+y')^2)] where |x'| <= x and |y'| <= y, and analogously for the imaginary part. */ mag_t t, u, v, w; arf_t a2b2; int inexact; mag_init(t); mag_init(u); mag_init(v); mag_init(w); arf_init(a2b2); inexact = arf_sosq(a2b2, a, b, hprec, ARF_RND_DOWN); /* compute denominator */ /* t = (|a|-x)^2 + (|b|-x)^2 (lower bound) */ mag_mul_lower(t, am, am); mag_mul_lower(u, bm, bm); mag_add_lower(t, t, u); /* u = a^2 + b^2 (lower bound) */ arf_get_mag_lower(u, a2b2); /* t = ((|a|-x)^2 + (|b|-x)^2)(a^2 + b^2) (lower bound) */ mag_mul_lower(t, t, u); /* compute numerator */ /* real: |a^2-b^2| x + |a| ((x^2 + y^2) + 2 |b| y)) */ /* imag: |a^2-b^2| y + |b| ((x^2 + y^2) + 2 |a| x)) */ /* am, bm = upper bounds for a, b */ arf_get_mag(am, a); arf_get_mag(bm, b); /* v = x^2 + y^2 */ mag_mul(v, x, x); mag_addmul(v, y, y); /* u = |a| ((x^2 + y^2) + 2 |b| y) */ mag_mul_2exp_si(u, bm, 1); mag_mul(u, u, y); mag_add(u, u, v); mag_mul(u, u, am); /* v = |b| ((x^2 + y^2) + 2 |a| x) */ mag_mul_2exp_si(w, am, 1); mag_addmul(v, w, x); mag_mul(v, v, bm); /* w = |b^2 - a^2| (upper bound) */ if (arf_cmpabs(a, b) >= 0) mag_mul(w, am, am); else mag_mul(w, bm, bm); mag_addmul(u, w, x); mag_addmul(v, w, y); mag_div(arb_radref(acb_realref(res)), u, t); mag_div(arb_radref(acb_imagref(res)), v, t); _arb_arf_div_rounded_den_add_err(acb_realref(res), a, a2b2, inexact, prec); _arb_arf_div_rounded_den_add_err(acb_imagref(res), b, a2b2, inexact, prec); arf_neg(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(res))); mag_clear(t); mag_clear(u); mag_clear(v); mag_clear(w); arf_clear(a2b2); } mag_clear(am); mag_clear(bm); #undef a #undef b #undef x #undef y } arb-2.22.1/acb/lambertw.c000066400000000000000000000531751417376376500151060ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" /* Check if z crosses a branch cut. */ int acb_lambertw_branch_crossing(const acb_t z, const acb_t ez1, const fmpz_t k) { if (arb_contains_zero(acb_imagref(z)) && !arb_is_nonnegative(acb_imagref(z))) { if (fmpz_is_zero(k)) { if (!arb_is_positive(acb_realref(ez1))) { return 1; } } else if (!arb_is_positive(acb_realref(z))) { return 1; } } return 0; } /* todo: remove radii */ void acb_lambertw_halley_step(acb_t res, acb_t ew, const acb_t z, const acb_t w, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); acb_exp(ew, w, prec); acb_add_ui(u, w, 2, prec); acb_add_ui(v, w, 1, prec); acb_mul_2exp_si(v, v, 1); acb_div(v, u, v, prec); acb_mul(t, ew, w, prec); acb_sub(u, t, z, prec); acb_mul(v, v, u, prec); acb_neg(v, v); acb_add(v, v, t, prec); acb_add(v, v, ew, prec); acb_div(t, u, v, prec); acb_sub(t, w, t, prec); acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(v); } /* assumes no aliasing of w and p */ void acb_lambertw_branchpoint_series(acb_t w, const acb_t t, int bound, slong prec) { slong i; static const int coeffs[] = {-130636800,130636800,-43545600,19958400, -10402560,5813640,-3394560,2042589,-1256320}; acb_zero(w); for (i = 8; i >= 0; i--) { acb_mul(w, w, t, prec); acb_add_si(w, w, coeffs[i], prec); } acb_div_si(w, w, -coeffs[0], prec); if (bound) { mag_t err; mag_init(err); acb_get_mag(err, t); mag_geom_series(err, err, 9); if (acb_is_real(t)) arb_add_error_mag(acb_realref(w), err); else acb_add_error_mag(w, err); mag_clear(err); } } void acb_lambertw_principal_d(acb_t res, const acb_t z) { double za, zb, wa, wb, ewa, ewb, t, u, q, r; int k, maxk = 15; za = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); zb = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); /* make sure we end up on the right branch */ if (za < -0.367 && zb > -1e-20 && zb <= 0.0 && arf_sgn(arb_midref(acb_imagref(z))) < 0) zb = -1e-20; wa = za; wb = zb; if (fabs(wa) > 2.0 || fabs(wb) > 2.0) { t = atan2(wb, wa); wa = 0.5 * log(wa * wa + wb * wb); wb = t; } else if (fabs(wa) > 0.25 || fabs(wb) > 0.25) { /* We have W(z) ~= -1 + (2(ez+1))^(1/2) near the branch point. Changing the exponent to 1/4 gives a much worse local guess which however does the job on a larger domain. */ wa *= 5.43656365691809; wb *= 5.43656365691809; wa += 2.0; t = atan2(wb, wa); r = pow(wa * wa + wb * wb, 0.125); wa = r * cos(0.25 * t); wb = r * sin(0.25 * t); wa -= 1.0; } for (k = 0; k < maxk; k++) { t = exp(wa); ewa = t * cos(wb); ewb = t * sin(wb); t = (ewa * wa - ewb * wb); q = t + ewa; t -= za; u = (ewb * wa + ewa * wb); r = u + ewb; u -= zb; ewa = q * t + r * u; ewb = q * u - r * t; r = 1.0 / (q * q + r * r); ewa *= r; ewb *= r; if ((ewa*ewa + ewb*ewb) < (wa*wa + wb*wb) * 1e-12) maxk = FLINT_MIN(maxk, k + 2); wa -= ewa; wb -= ewb; } acb_set_d_d(res, wa, wb); } void acb_lambertw_initial_asymp(acb_t w, const acb_t z, const fmpz_t k, slong prec) { acb_t L1, L2, t; acb_init(L1); acb_init(L2); acb_init(t); acb_const_pi(L2, prec); acb_mul_2exp_si(L2, L2, 1); acb_mul_fmpz(L2, L2, k, prec); acb_mul_onei(L2, L2); acb_log(L1, z, prec); acb_add(L1, L1, L2, prec); acb_log(L2, L1, prec); /* L1 - L2 + L2/L1 + L2(L2-2)/(2 L1^2) */ acb_inv(t, L1, prec); acb_mul_2exp_si(w, L2, 1); acb_submul(w, L2, L2, prec); acb_neg(w, w); acb_mul(w, w, t, prec); acb_mul_2exp_si(w, w, -1); acb_add(w, w, L2, prec); acb_mul(w, w, t, prec); acb_sub(w, w, L2, prec); acb_add(w, w, L1, prec); acb_clear(L1); acb_clear(L2); acb_clear(t); } /* assumes no aliasing */ slong acb_lambertw_initial(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, slong prec) { /* Handle z very close to 0 on the principal branch. */ if (fmpz_is_zero(k) && (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -20) <= 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -20) <= 0)) { acb_set(res, z); acb_submul(res, res, res, prec); return 40; /* could be tightened... */ } /* For moderate input not close to the branch point, compute a double approximation as the initial value. */ if (fmpz_is_zero(k) && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 400) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 400) < 0 && (arf_cmp_d(arb_midref(acb_realref(z)), -0.37) < 0 || arf_cmp_d(arb_midref(acb_realref(z)), -0.36) > 0 || arf_cmpabs_d(arb_midref(acb_imagref(z)), 0.01) > 0)) { acb_lambertw_principal_d(res, z); return 48; } /* Check if we are close to the branch point at -1/e. */ if ((fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z))) || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z)))) && ((arf_cmpabs_2exp_si(arb_midref(acb_realref(ez1)), -2) <= 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(ez1)), -2) <= 0))) { acb_t t; acb_init(t); acb_mul_2exp_si(t, ez1, 1); mag_zero(arb_radref(acb_realref(t))); mag_zero(arb_radref(acb_imagref(t))); acb_mul_ui(t, t, 3, prec); acb_sqrt(t, t, prec); if (!fmpz_is_zero(k)) acb_neg(t, t); acb_lambertw_branchpoint_series(res, t, 0, prec); acb_clear(t); return 1; /* todo: estimate */ } acb_lambertw_initial_asymp(res, z, k, prec); return 1; /* todo: estimate */ } /* note: z should be exact here */ void acb_lambertw_main(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { acb_t w, t, oldw, ew; mag_t err; slong i, wp, accuracy, ebits, kbits, mbits, wp_initial, extraprec; int have_ew; acb_init(t); acb_init(w); acb_init(oldw); acb_init(ew); mag_init(err); /* We need higher precision for large k, large exponents, or very close to the branch point at -1/e. todo: we should be recomputing ez1 to higher precision when close... */ acb_get_mag(err, z); if (fmpz_is_zero(k) && mag_cmp_2exp_si(err, 0) < 0) ebits = 0; else ebits = fmpz_bits(MAG_EXPREF(err)); if (fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z))) || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z)))) { acb_get_mag(err, ez1); mbits = -MAG_EXP(err); mbits = FLINT_MAX(mbits, 0); mbits = FLINT_MIN(mbits, prec); } else { mbits = 0; } kbits = fmpz_bits(k); extraprec = FLINT_MAX(ebits, kbits); extraprec = FLINT_MAX(extraprec, mbits); wp = wp_initial = 40 + extraprec; accuracy = acb_lambertw_initial(w, z, ez1, k, wp_initial); mag_zero(arb_radref(acb_realref(w))); mag_zero(arb_radref(acb_imagref(w))); /* We should be able to compute e^w for the final certification during the Halley iteration. */ have_ew = 0; for (i = 0; i < 5 + FLINT_BIT_COUNT(prec + extraprec); i++) { /* todo: should we restart? */ if (!acb_is_finite(w)) break; wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10); wp = FLINT_MAX(wp, 40); wp += extraprec; acb_set(oldw, w); acb_lambertw_halley_step(t, ew, z, w, wp); /* estimate the error (conservatively) */ acb_sub(w, w, t, wp); acb_get_mag(err, w); acb_set(w, t); acb_add_error_mag(t, err); accuracy = acb_rel_accuracy_bits(t); if (accuracy > 2 * extraprec) accuracy *= 2.9; /* less conservatively */ accuracy = FLINT_MIN(accuracy, wp); accuracy = FLINT_MAX(accuracy, 0); if (accuracy > prec + extraprec) { /* e^w = e^oldw * e^(w-oldw) */ acb_sub(t, w, oldw, wp); acb_exp(t, t, wp); acb_mul(ew, ew, t, wp); have_ew = 1; break; } mag_zero(arb_radref(acb_realref(w))); mag_zero(arb_radref(acb_imagref(w))); } wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10); wp = FLINT_MAX(wp, 40); wp += extraprec; if (acb_lambertw_check_branch(w, k, wp)) { acb_t u, r, eu1; mag_t err, rad; acb_init(u); acb_init(r); acb_init(eu1); mag_init(err); mag_init(rad); if (have_ew) acb_set(t, ew); else acb_exp(t, w, wp); /* t = w e^w */ acb_mul(t, t, w, wp); acb_sub(r, t, z, wp); /* Bound W' on the straight line path between t and z */ acb_union(u, t, z, wp); arb_const_e(acb_realref(eu1), wp); arb_zero(acb_imagref(eu1)); acb_mul(eu1, eu1, u, wp); acb_add_ui(eu1, eu1, 1, wp); if (acb_lambertw_branch_crossing(u, eu1, k)) { mag_inf(err); } else { acb_lambertw_bound_deriv(err, u, eu1, k); acb_get_mag(rad, r); mag_mul(err, err, rad); } acb_add_error_mag(w, err); acb_set(res, w); acb_clear(u); acb_clear(r); acb_clear(eu1); mag_clear(err); mag_clear(rad); } else { acb_indeterminate(res); } acb_clear(t); acb_clear(w); acb_clear(oldw); acb_clear(ew); mag_clear(err); } void acb_lambertw_cleared_cut(acb_t res, const acb_t z, const fmpz_t k, int flags, slong prec) { acb_t ez1; acb_init(ez1); /* compute e*z + 1 */ arb_const_e(acb_realref(ez1), prec); acb_mul(ez1, ez1, z, prec); acb_add_ui(ez1, ez1, 1, prec); if (acb_is_exact(z)) { acb_lambertw_main(res, z, ez1, k, flags, prec); } else { acb_t zz; mag_t err, rad; mag_init(err); mag_init(rad); acb_init(zz); acb_lambertw_bound_deriv(err, z, ez1, k); mag_hypot(rad, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); mag_mul(err, err, rad); acb_set(zz, z); mag_zero(arb_radref(acb_realref(zz))); mag_zero(arb_radref(acb_imagref(zz))); /* todo: recompute ez1? */ acb_lambertw_main(res, zz, ez1, k, flags, prec); acb_add_error_mag(res, err); mag_clear(err); mag_clear(rad); acb_clear(zz); } acb_clear(ez1); } /* Extremely close to the branch point at -1/e, use the series expansion directly. */ int acb_lambertw_try_near_branch_point(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { if (fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z))) || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z)))) { if (acb_contains_zero(ez1) || (arf_cmpabs_2exp_si(arb_midref(acb_realref(ez1)), -prec / 4.5 - 6) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(ez1)), -prec / 4.5 - 6) < 0)) { acb_t t; acb_init(t); acb_mul_2exp_si(t, ez1, 1); acb_sqrt(t, t, prec); if (!fmpz_is_zero(k)) acb_neg(t, t); acb_lambertw_branchpoint_series(res, t, 1, prec); acb_clear(t); return 1; } } return 0; } void acb_lambertw_cleared_cut_fix_small(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { acb_t zz, zmid, zmide1; arf_t eps; acb_init(zz); acb_init(zmid); acb_init(zmide1); arf_init(eps); arf_mul_2exp_si(eps, arb_midref(acb_realref(z)), -prec); acb_set(zz, z); if (arf_sgn(arb_midref(acb_realref(zz))) < 0 && (!fmpz_is_zero(k) || arf_sgn(arb_midref(acb_realref(ez1))) < 0) && arf_cmpabs(arb_midref(acb_imagref(zz)), eps) < 0) { /* now the value must be in [0,2eps] */ arf_get_mag(arb_radref(acb_imagref(zz)), eps); arf_set_mag(arb_midref(acb_imagref(zz)), arb_radref(acb_imagref(zz))); if (arf_sgn(arb_midref(acb_imagref(z))) >= 0) { acb_lambertw_cleared_cut(res, zz, k, flags, prec); } else { fmpz_t kk; fmpz_init(kk); fmpz_neg(kk, k); acb_lambertw_cleared_cut(res, zz, kk, flags, prec); acb_conj(res, res); fmpz_clear(kk); } } else { acb_lambertw_cleared_cut(res, zz, k, flags, prec); } acb_clear(zz); acb_clear(zmid); acb_clear(zmide1); arf_clear(eps); } void _acb_lambertw(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { slong goal, ebits, ebits2, ls, lt; const fmpz * expo; /* Estimated accuracy goal. */ /* todo: account for exponent bits and bits in k. */ goal = acb_rel_accuracy_bits(z); goal = FLINT_MAX(goal, 10); goal = FLINT_MIN(goal, prec); /* Handle tiny z directly. For k >= 2, |c_k| <= 4^k / 16. */ if (fmpz_is_zero(k) && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -goal / 2) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -goal / 2) < 0) { mag_t err; mag_init(err); acb_get_mag(err, z); mag_mul_2exp_si(err, err, 2); acb_set(res, z); acb_submul(res, res, res, prec); mag_geom_series(err, err, 3); mag_mul_2exp_si(err, err, -4); acb_add_error_mag(res, err); mag_clear(err); return; } if (arf_cmpabs(arb_midref(acb_realref(z)), arb_midref(acb_imagref(z))) >= 0) expo = ARF_EXPREF(arb_midref(acb_realref(z))); else expo = ARF_EXPREF(arb_midref(acb_imagref(z))); ebits = fmpz_bits(expo); /* ebits ~= log2(|log(z) + 2 pi i k|) */ /* ebits2 ~= log2(log(log(z))) */ ebits = FLINT_MAX(ebits, fmpz_bits(k)); ebits = FLINT_MAX(ebits, 1) - 1; ebits2 = FLINT_BIT_COUNT(ebits); ebits2 = FLINT_MAX(ebits2, 1) - 1; /* We gain accuracy from the exponent when W ~ log - log log */ if (fmpz_sgn(expo) > 0 || (fmpz_sgn(expo) < 0 && !fmpz_is_zero(k))) { goal += ebits - ebits2; goal = FLINT_MAX(goal, 10); goal = FLINT_MIN(goal, prec); /* The asymptotic series with truncation L, M gives us about t - max(2+lt+L*(2+ls), M*(2+lt)) bits of accuracy where ls = -ebits, lt = ebits2 - ebits. */ ls = 2 - ebits; lt = 2 + ebits2 - ebits; if (ebits - FLINT_MAX(lt + 1*ls, 1*lt) > goal) { acb_lambertw_asymp(res, z, k, 1, 1, goal); acb_set_round(res, res, prec); return; } else if (ebits - FLINT_MAX(lt + 3*ls, 5*lt) > goal) { acb_lambertw_asymp(res, z, k, 3, 5, goal); acb_set_round(res, res, prec); return; } } /* Extremely close to the branch point at -1/e, use the series expansion directly. */ if (acb_lambertw_try_near_branch_point(res, z, ez1, k, flags, goal)) { acb_set_round(res, res, prec); return; } /* compute union of both sides */ if (acb_lambertw_branch_crossing(z, ez1, k)) { acb_t za, zb, eza1, ezb1; fmpz_t kk; acb_init(za); acb_init(zb); acb_init(eza1); acb_init(ezb1); fmpz_init(kk); fmpz_neg(kk, k); acb_set(za, z); acb_conj(zb, z); arb_nonnegative_part(acb_imagref(za), acb_imagref(za)); arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb)); acb_set(eza1, ez1); acb_conj(ezb1, ez1); arb_nonnegative_part(acb_imagref(eza1), acb_imagref(eza1)); arb_nonnegative_part(acb_imagref(ezb1), acb_imagref(ezb1)); /* Check series expansion again, because now there is no crossing. */ if (!acb_lambertw_try_near_branch_point(res, za, eza1, k, flags, goal)) acb_lambertw_cleared_cut_fix_small(za, za, eza1, k, flags, goal); if (!acb_lambertw_try_near_branch_point(res, zb, ezb1, kk, flags, goal)) acb_lambertw_cleared_cut_fix_small(zb, zb, ezb1, kk, flags, goal); acb_conj(zb, zb); acb_union(res, za, zb, prec); acb_clear(za); acb_clear(zb); acb_clear(eza1); acb_clear(ezb1); fmpz_clear(kk); } else { acb_lambertw_cleared_cut_fix_small(res, z, ez1, k, flags, goal); acb_set_round(res, res, prec); } } void acb_lambertw_middle(acb_t res, const acb_t z, slong prec) { fmpz_t k; if (acb_contains_zero(z)) { acb_indeterminate(res); return; } fmpz_init(k); fmpz_set_si(k, -1); if (arb_is_positive(acb_imagref(z))) { acb_lambertw(res, z, k, 0, prec); } else if (arb_is_negative(acb_imagref(z))) { acb_conj(res, z); acb_lambertw(res, res, k, 0, prec); acb_conj(res, res); } else if (arb_is_negative(acb_realref(z))) { if (arb_is_nonnegative(acb_imagref(z))) { acb_lambertw(res, z, k, 0, prec); } else if (arb_is_negative(acb_imagref(z))) { acb_conj(res, z); acb_lambertw(res, res, k, 0, prec); acb_conj(res, res); } else { acb_t za, zb; acb_init(za); acb_init(zb); acb_set(za, z); acb_conj(zb, z); arb_nonnegative_part(acb_imagref(za), acb_imagref(za)); arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb)); acb_lambertw(za, za, k, 0, prec); acb_lambertw(zb, zb, k, 0, prec); acb_conj(zb, zb); acb_union(res, za, zb, prec); acb_clear(za); acb_clear(zb); } } else /* re is positive */ { if (arb_is_positive(acb_imagref(z))) { acb_lambertw(res, z, k, 0, prec); } else if (arb_is_nonpositive(acb_imagref(z))) { acb_conj(res, z); acb_lambertw(res, res, k, 0, prec); acb_conj(res, res); } else { acb_t za, zb; acb_init(za); acb_init(zb); acb_set(za, z); acb_conj(zb, z); arb_nonnegative_part(acb_imagref(za), acb_imagref(za)); arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb)); acb_lambertw(za, za, k, 0, prec); acb_lambertw(zb, zb, k, 0, prec); acb_conj(zb, zb); acb_union(res, za, zb, prec); acb_clear(za); acb_clear(zb); } } fmpz_clear(k); } void acb_lambertw_left(acb_t res, const acb_t z, const fmpz_t k, slong prec) { if (acb_contains_zero(z) && !(fmpz_equal_si(k, -1) && acb_is_real(z))) { acb_indeterminate(res); return; } if (arb_is_positive(acb_imagref(z))) { acb_lambertw(res, z, k, 0, prec); } else if (arb_is_nonpositive(acb_imagref(z))) { fmpz_t kk; fmpz_init(kk); fmpz_add_ui(kk, k, 1); fmpz_neg(kk, kk); acb_conj(res, z); acb_lambertw(res, res, kk, 0, prec); acb_conj(res, res); fmpz_clear(kk); } else { acb_t za, zb; fmpz_t kk; acb_init(za); acb_init(zb); fmpz_init(kk); acb_set(za, z); acb_conj(zb, z); arb_nonnegative_part(acb_imagref(za), acb_imagref(za)); arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb)); fmpz_add_ui(kk, k, 1); fmpz_neg(kk, kk); acb_lambertw(za, za, k, 0, prec); acb_lambertw(zb, zb, kk, 0, prec); acb_conj(zb, zb); acb_union(res, za, zb, prec); acb_clear(za); acb_clear(zb); fmpz_clear(kk); } } void acb_lambertw(acb_t res, const acb_t z, const fmpz_t k, int flags, slong prec) { acb_t ez1; if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (flags == ACB_LAMBERTW_LEFT) { acb_lambertw_left(res, z, k, prec); return; } if (flags == ACB_LAMBERTW_MIDDLE) { acb_lambertw_middle(res, z, prec); return; } if (acb_contains_zero(z) && !fmpz_is_zero(k)) { acb_indeterminate(res); return; } acb_init(ez1); /* precompute z*e + 1 */ arb_const_e(acb_realref(ez1), prec); acb_mul(ez1, ez1, z, prec); acb_add_ui(ez1, ez1, 1, prec); /* Compute standard branches */ /* use real code when possible */ if (acb_is_real(z) && arb_is_positive(acb_realref(ez1)) && (fmpz_is_zero(k) || (fmpz_equal_si(k, -1) && arb_is_negative(acb_realref(z))))) { arb_lambertw(acb_realref(res), acb_realref(z), !fmpz_is_zero(k), prec); arb_zero(acb_imagref(res)); } else { _acb_lambertw(res, z, ez1, k, flags, prec); } acb_clear(ez1); } arb-2.22.1/acb/lambertw_asymp.c000066400000000000000000000062601417376376500163100ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_lambertw_asymp(acb_t res, const acb_t z, const fmpz_t k, slong L, slong M, slong prec) { acb_t L1, L2, sigma, tau, s, c, u; slong l, m; fmpz_t t; fmpz * sc; /* For k = 0, the asymptotic expansion is not valid near 0. */ /* (It is sufficient to look at the midpoint as a test here.) */ if (fmpz_is_zero(k) && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 0) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_indeterminate(res); return; } acb_init(L1); acb_init(L2); acb_init(sigma); acb_init(tau); acb_init(s); acb_init(c); acb_init(u); fmpz_init(t); acb_const_pi(L2, prec); acb_mul_2exp_si(L2, L2, 1); acb_mul_fmpz(L2, L2, k, prec); acb_mul_onei(L2, L2); acb_log(L1, z, prec); acb_add(L1, L1, L2, prec); acb_log(L2, L1, prec); acb_inv(sigma, L1, prec); acb_mul(tau, L2, sigma, prec); acb_zero(s); /* Stirling numbers */ sc = _fmpz_vec_init(L); acb_one(u); for (m = 1; m < M; m++) { if (m == 1) { for (l = 0; l < L; l++) fmpz_one(sc + l); } else { for (l = 0; l < L; l++) { fmpz_mul_ui(sc + l, sc + l, m + l - 1); if (l > 0) fmpz_add(sc + l, sc + l, sc + l - 1); } } acb_zero(c); /* todo: precompute powers instead of horner */ for (l = L - 1; l >= 0; l--) { acb_mul(c, c, sigma, prec); if (l % 2) acb_sub_fmpz(c, c, sc + l, prec); else acb_add_fmpz(c, c, sc + l, prec); } acb_mul(u, u, tau, prec); acb_div_ui(u, u, m, prec); acb_addmul(s, c, u, prec); } _fmpz_vec_clear(sc, L); acb_sub(s, s, L2, prec); acb_add(s, s, L1, prec); { mag_t m4s, m4t, one, q, r; mag_init(m4s); mag_init(m4t); mag_init(one); mag_init(q); mag_init(r); acb_get_mag(m4s, sigma); mag_mul_2exp_si(m4s, m4s, 2); acb_get_mag(m4t, tau); mag_mul_2exp_si(m4t, m4t, 2); mag_one(one); mag_sub_lower(q, one, m4s); mag_sub_lower(r, one, m4t); mag_mul(q, q, r); mag_pow_ui(r, m4s, L); mag_mul(r, r, m4t); mag_pow_ui(m4t, m4t, M); mag_add(r, r, m4t); mag_div(q, r, q); acb_add_error_mag(s, q); mag_clear(m4s); mag_clear(m4t); mag_clear(one); mag_clear(q); mag_clear(r); } acb_set(res, s); acb_clear(sigma); acb_clear(tau); acb_clear(s); acb_clear(c); acb_clear(L1); acb_clear(L2); acb_clear(u); fmpz_clear(t); } arb-2.22.1/acb/lambertw_bound_deriv.c000066400000000000000000000057511417376376500174630ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_lambertw_bound_deriv(mag_t res, const acb_t z, const acb_t ez1, const fmpz_t k) { mag_t t, u, v; mag_init(t); mag_init(u); mag_init(v); if (fmpz_is_zero(k)) { acb_get_mag(t, z); /* |z| <= 64 */ if (mag_cmp_2exp_si(t, 6) < 0) { /* 2.25 / sqrt(|t|) / sqrt(1+|t|), t = |ez+1| */ acb_get_mag_lower(t, ez1); mag_one(u); mag_add_lower(u, u, t); mag_mul_lower(t, t, u); mag_rsqrt(t, t); if (arb_is_positive(acb_realref(ez1))) { mag_mul_ui(t, t, 135); /* x0.9375 for small improvement */ mag_mul_2exp_si(t, t, -6); } else { mag_mul_ui(t, t, 9); mag_mul_2exp_si(t, t, -2); } mag_set(res, t); } else { acb_get_mag_lower(t, z); if (mag_cmp_2exp_si(t, 2) >= 0) { mag_one(u); mag_div(res, u, t); } else /* unlikely */ { acb_get_mag_lower(u, ez1); mag_rsqrt(u, u); mag_mul_2exp_si(u, u, -1); mag_add_ui(u, u, 1); mag_mul_ui(u, u, 3); mag_div(res, u, t); } } } else if (fmpz_is_pm1(k)) { if (arb_is_nonnegative(acb_realref(z)) || (fmpz_is_one(k) && arb_is_nonnegative(acb_imagref(z))) || (fmpz_equal_si(k, -1) && arb_is_negative(acb_imagref(z)))) { /* (1 + 1/(4+|z|^2))/|z| */ acb_get_mag_lower(t, z); mag_mul_lower(u, t, t); mag_set_ui_lower(v, 4); mag_add_lower(u, u, v); mag_one(v); mag_div(u, v, u); mag_add(u, u, v); mag_div(res, u, t); } else { /* (1 + 0.71875/sqrt(|e*z+1|)) / |z| */ acb_get_mag_lower(t, ez1); mag_rsqrt(t, t); mag_mul_ui(t, t, 23); mag_mul_2exp_si(t, t, -5); mag_one(u); mag_add(t, t, u); acb_get_mag_lower(u, z); mag_div(res, t, u); } mag_clear(t); mag_clear(u); mag_clear(v); return; } else { /* |W'(z)| = |1/z| |W(z)/(1+W(z))| <= |1/z| (2pi) / (2pi-1) */ mag_set_ui_2exp_si(t, 77, -6); acb_get_mag_lower(res, z); mag_div(res, t, res); } mag_clear(t); mag_clear(u); mag_clear(v); } arb-2.22.1/acb/lambertw_check_branch.c000066400000000000000000000050221417376376500175440ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int _acb_lambertw_check_branch(const acb_t w, const fmpz_t k, slong prec) { arb_t t, u, v, a, b; int res = 0; arb_init(t); arb_init(u); arb_init(v); arb_init(a); arb_init(b); /* t = x sinc(y), v = -cos(y) */ if (arb_is_exact(acb_imagref(w))) { if (arb_is_zero(acb_imagref(w))) { arb_one(t); arb_one(v); } else { arb_sin_cos(t, v, acb_imagref(w), prec); arb_div(t, t, acb_imagref(w), prec); } } else { arb_sinc(t, acb_imagref(w), prec); arb_cos(v, acb_imagref(w), prec); } arb_mul(t, t, acb_realref(w), prec); arb_neg(v, v); /* u = y / pi, with conjugate relation for k */ arb_const_pi(u, prec); arb_div(u, acb_imagref(w), u, prec); if (fmpz_sgn(k) < 0) arb_neg(u, u); if (fmpz_is_zero(k)) { /* -1 < u < 1 and t > v */ arb_set_si(a, -1); arb_set_si(b, 1); if (arb_gt(u, a) && arb_lt(u, b) && arb_gt(t, v)) { res = 1; } } else { arb_set_fmpz(a, k); arb_abs(a, a); arb_mul_2exp_si(a, a, 1); arb_add_ui(b, a, 1, prec); arb_sub_ui(a, a, 2, prec); /* if u > 2|k|-2 and u < 2|k|+1 */ if (arb_gt(u, a) && arb_lt(u, b)) { arb_add_ui(a, a, 1, prec); arb_sub_ui(b, b, 1, prec); /* if u > 2|k|-1 and u < 2|k| */ if (arb_gt(u, a) && arb_lt(u, b)) { res = 1; } else if (arb_lt(u, b) && arb_lt(t, v)) /* u < 2|k| and t < v */ { res = 1; } else if (arb_gt(u, a) && arb_gt(t, v)) /* u > 2|k|-1 and t > v */ { res = 1; } } } arb_clear(t); arb_clear(u); arb_clear(v); arb_clear(a); arb_clear(b); return res; } int acb_lambertw_check_branch(const acb_t w, const fmpz_t k, slong prec) { if (prec > 64 && _acb_lambertw_check_branch(w, k, 32)) return 1; return _acb_lambertw_check_branch(w, k, prec); } arb-2.22.1/acb/log.c000066400000000000000000000047201417376376500140420ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_log(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { if (arb_is_positive(a)) { arb_log(acb_realref(r), a, prec); arb_zero(acb_imagref(r)); } else if (arb_is_negative(a)) { arb_neg(acb_realref(r), a); arb_log(acb_realref(r), acb_realref(r), prec); arb_const_pi(acb_imagref(r), prec); } else { acb_indeterminate(r); } } else if (arb_is_zero(a)) { if (arb_is_positive(b)) { arb_log(acb_realref(r), b, prec); arb_const_pi(acb_imagref(r), prec); arb_mul_2exp_si(acb_imagref(r), acb_imagref(r), -1); } else if (arb_is_negative(b)) { arb_neg(acb_realref(r), b); arb_log(acb_realref(r), acb_realref(r), prec); arb_const_pi(acb_imagref(r), prec); arb_mul_2exp_si(acb_imagref(r), acb_imagref(r), -1); arb_neg(acb_imagref(r), acb_imagref(r)); } else { acb_indeterminate(r); } } else { if (r != z) { arb_log_hypot(acb_realref(r), a, b, prec); if (arb_is_finite(acb_realref(r))) arb_atan2(acb_imagref(r), b, a, prec); else arb_indeterminate(acb_imagref(r)); } else { arb_t t; arb_init(t); arb_log_hypot(t, a, b, prec); if (arb_is_finite(t)) arb_atan2(acb_imagref(r), b, a, prec); else arb_indeterminate(acb_imagref(r)); arb_swap(acb_realref(r), t); arb_clear(t); } } #undef a #undef b } void acb_log_analytic(acb_ptr res, const acb_t z, int analytic, slong prec) { if (analytic && arb_contains_zero(acb_imagref(z)) && !arb_is_positive(acb_realref(z))) { acb_indeterminate(res); } else { acb_log(res, z, prec); } } arb-2.22.1/acb/log1p.c000066400000000000000000000031171417376376500143020ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void acb_log1p_tiny(acb_t r, const acb_t z, slong prec) { mag_t b, c; acb_t t; int real; mag_init(b); mag_init(c); acb_init(t); real = acb_is_real(z); /* if |z| < 1, then |log(1+z) - [z - z^2/2]| <= |z|^3/(1-|z|) */ acb_get_mag(b, z); mag_one(c); mag_sub_lower(c, c, b); mag_pow_ui(b, b, 3); mag_div(b, b, c); acb_mul(t, z, z, prec); acb_mul_2exp_si(t, t, -1); acb_sub(r, z, t, prec); if (real && mag_is_finite(b)) arb_add_error_mag(acb_realref(r), b); else acb_add_error_mag(r, b); mag_clear(b); mag_clear(c); acb_clear(t); } void acb_log1p(acb_t r, const acb_t z, slong prec) { slong magz, magx, magy; if (acb_is_zero(z)) { acb_zero(r); return; } magx = arf_abs_bound_lt_2exp_si(arb_midref(acb_realref(z))); magy = arf_abs_bound_lt_2exp_si(arb_midref(acb_imagref(z))); magz = FLINT_MAX(magx, magy); if (magz < -prec) { acb_log1p_tiny(r, z, prec); } else { if (magz < 0) acb_add_ui(r, z, 1, prec + (-magz) + 4); else acb_add_ui(r, z, 1, prec + 4); acb_log(r, r, prec); } } arb-2.22.1/acb/log_sin_pi.c000066400000000000000000000061551417376376500154070ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void acb_log_sin_pi_half(acb_t res, const acb_t z, slong prec, int upper) { acb_t t, u, zmid; arf_t n; arb_t pi; acb_init(t); acb_init(u); acb_init(zmid); arf_init(n); arb_init(pi); arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z))); arf_floor(n, arb_midref(acb_realref(zmid))); arb_sub_arf(acb_realref(zmid), acb_realref(zmid), n, prec); arb_const_pi(pi, prec); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(zmid)), 2) < 1) { acb_sin_pi(t, zmid, prec); acb_log(t, t, prec); } else /* i*pi*(z-0.5) + log((1-exp(-2i*pi*z))/2) */ { acb_mul_2exp_si(t, zmid, 1); acb_neg(t, t); if (upper) acb_conj(t, t); acb_exp_pi_i(t, t, prec); acb_sub_ui(t, t, 1, prec); acb_neg(t, t); acb_mul_2exp_si(t, t, -1); acb_log(t, t, prec); acb_one(u); acb_mul_2exp_si(u, u, -1); acb_sub(u, zmid, u, prec); if (upper) acb_conj(u, u); acb_mul_onei(u, u); acb_addmul_arb(t, u, pi, prec); if (upper) acb_conj(t, t); } if (upper) arb_submul_arf(acb_imagref(t), pi, n, prec); else arb_addmul_arf(acb_imagref(t), pi, n, prec); /* propagated error bound from the derivative pi cot(pi z) */ if (!acb_is_exact(z)) { mag_t zm, um; mag_init(zm); mag_init(um); acb_cot_pi(u, z, prec); acb_mul_arb(u, u, pi, prec); mag_hypot(zm, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); acb_get_mag(um, u); mag_mul(um, um, zm); acb_add_error_mag(t, um); mag_clear(zm); mag_clear(um); } acb_set(res, t); acb_clear(t); acb_clear(u); acb_clear(zmid); arf_clear(n); arb_clear(pi); } void acb_log_sin_pi(acb_t res, const acb_t z, slong prec) { if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (arb_is_positive(acb_imagref(z)) || (arb_is_zero(acb_imagref(z)) && arb_is_negative(acb_realref(z)))) { acb_log_sin_pi_half(res, z, prec, 1); } else if (arb_is_negative(acb_imagref(z)) || (arb_is_zero(acb_imagref(z)) && arb_is_positive(acb_realref(z)))) { acb_log_sin_pi_half(res, z, prec, 0); } else { acb_t t; acb_init(t); acb_log_sin_pi_half(t, z, prec, 1); acb_log_sin_pi_half(res, z, prec, 0); arb_union(acb_realref(res), acb_realref(res), acb_realref(t), prec); arb_union(acb_imagref(res), acb_imagref(res), acb_imagref(t), prec); acb_clear(t); } } arb-2.22.1/acb/mul.c000066400000000000000000000136251417376376500140620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(y) #define d acb_imagref(y) #define e acb_realref(z) #define f acb_imagref(z) #define ar arb_radref(a) #define br arb_radref(b) #define cr arb_radref(c) #define dr arb_radref(d) static void _acb_sqr_fast(acb_t z, const acb_t x, slong prec) { int inexact; mag_t am, bm, er, fr; mag_fast_init_set_arf(am, arb_midref(a)); mag_fast_init_set_arf(bm, arb_midref(b)); mag_init(er); mag_init(fr); mag_fast_addmul(er, am, ar); mag_fast_addmul(er, bm, br); mag_fast_mul_2exp_si(er, er, 1); mag_fast_addmul(er, ar, ar); mag_fast_addmul(er, br, br); mag_fast_addmul(fr, bm, ar); mag_fast_addmul(fr, am, br); mag_fast_addmul(fr, ar, br); mag_fast_mul_2exp_si(fr, fr, 1); inexact = arf_complex_sqr(arb_midref(e), arb_midref(f), arb_midref(a), arb_midref(b), prec, ARB_RND); if (inexact & 1) arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec); else mag_set(arb_radref(e), er); if (inexact & 2) arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec); else mag_set(arb_radref(f), fr); } static void _acb_sqr_slow(acb_t z, const acb_t x, slong prec) { int inexact; mag_t am, bm, er, fr; mag_init_set_arf(am, arb_midref(a)); mag_init_set_arf(bm, arb_midref(b)); mag_init(er); mag_init(fr); mag_addmul(er, am, ar); mag_addmul(er, bm, br); mag_mul_2exp_si(er, er, 1); mag_addmul(er, ar, ar); mag_addmul(er, br, br); mag_addmul(fr, bm, ar); mag_addmul(fr, am, br); mag_addmul(fr, ar, br); mag_mul_2exp_si(fr, fr, 1); inexact = arf_complex_sqr(arb_midref(e), arb_midref(f), arb_midref(a), arb_midref(b), prec, ARB_RND); if (inexact & 1) arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec); else mag_swap(arb_radref(e), er); if (inexact & 2) arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec); else mag_swap(arb_radref(f), fr); mag_clear(am); mag_clear(bm); mag_clear(er); mag_clear(fr); } static void _acb_mul_fast(acb_t z, const acb_t x, const acb_t y, slong prec) { int inexact; mag_t am, bm, cm, dm, er, fr; mag_fast_init_set_arf(am, arb_midref(a)); mag_fast_init_set_arf(bm, arb_midref(b)); mag_fast_init_set_arf(cm, arb_midref(c)); mag_fast_init_set_arf(dm, arb_midref(d)); mag_init(er); mag_init(fr); mag_fast_addmul(er, am, cr); mag_fast_addmul(er, bm, dr); mag_fast_addmul(er, cm, ar); mag_fast_addmul(er, dm, br); mag_fast_addmul(er, ar, cr); mag_fast_addmul(er, br, dr); mag_fast_addmul(fr, am, dr); mag_fast_addmul(fr, bm, cr); mag_fast_addmul(fr, cm, br); mag_fast_addmul(fr, dm, ar); mag_fast_addmul(fr, br, cr); mag_fast_addmul(fr, ar, dr); inexact = arf_complex_mul(arb_midref(e), arb_midref(f), arb_midref(a), arb_midref(b), arb_midref(c), arb_midref(d), prec, ARB_RND); if (inexact & 1) arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec); else mag_set(arb_radref(e), er); if (inexact & 2) arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec); else mag_set(arb_radref(f), fr); } static void _acb_mul_slow(acb_t z, const acb_t x, const acb_t y, slong prec) { int inexact; mag_t am, bm, cm, dm, er, fr; mag_init_set_arf(am, arb_midref(a)); mag_init_set_arf(bm, arb_midref(b)); mag_init_set_arf(cm, arb_midref(c)); mag_init_set_arf(dm, arb_midref(d)); mag_init(er); mag_init(fr); mag_addmul(er, am, cr); mag_addmul(er, bm, dr); mag_addmul(er, cm, ar); mag_addmul(er, dm, br); mag_addmul(er, ar, cr); mag_addmul(er, br, dr); mag_addmul(fr, am, dr); mag_addmul(fr, bm, cr); mag_addmul(fr, cm, br); mag_addmul(fr, dm, ar); mag_addmul(fr, br, cr); mag_addmul(fr, ar, dr); inexact = arf_complex_mul(arb_midref(e), arb_midref(f), arb_midref(a), arb_midref(b), arb_midref(c), arb_midref(d), prec, ARB_RND); if (inexact & 1) arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec); else mag_swap(arb_radref(e), er); if (inexact & 2) arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec); else mag_swap(arb_radref(f), fr); mag_clear(am); mag_clear(bm); mag_clear(cm); mag_clear(dm); mag_clear(er); mag_clear(fr); } void acb_mul(acb_t z, const acb_t x, const acb_t y, slong prec) { if (arb_is_zero(b)) { arb_mul(f, d, a, prec); arb_mul(e, c, a, prec); } else if (arb_is_zero(d)) { arb_mul(f, b, c, prec); arb_mul(e, a, c, prec); } else if (arb_is_zero(a)) { arb_mul(e, c, b, prec); arb_mul(f, d, b, prec); acb_mul_onei(z, z); } else if (arb_is_zero(c)) { arb_mul(e, a, d, prec); arb_mul(f, b, d, prec); acb_mul_onei(z, z); } /* squaring = a^2-b^2, 2ab */ else if (x == y) { if (ARB_IS_LAGOM(a) && ARB_IS_LAGOM(b)) _acb_sqr_fast(z, x, prec); else _acb_sqr_slow(z, x, prec); } else { if (ARB_IS_LAGOM(a) && ARB_IS_LAGOM(b) && ARB_IS_LAGOM(c) && ARB_IS_LAGOM(d)) _acb_mul_fast(z, x, y, prec); else _acb_mul_slow(z, x, y, prec); } } #undef a #undef b #undef c #undef d #undef e #undef f #undef ar #undef br #undef cr #undef dr arb-2.22.1/acb/mul_naive.c000066400000000000000000000055551417376376500152470ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_mul_naive(acb_t z, const acb_t x, const acb_t y, slong prec) { #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(y) #define d acb_imagref(y) #define e acb_realref(z) #define f acb_imagref(z) if (arb_is_zero(b)) { arb_mul(f, d, a, prec); arb_mul(e, c, a, prec); } else if (arb_is_zero(d)) { arb_mul(f, b, c, prec); arb_mul(e, a, c, prec); } else if (arb_is_zero(a)) { arb_mul(e, c, b, prec); arb_mul(f, d, b, prec); acb_mul_onei(z, z); } else if (arb_is_zero(c)) { arb_mul(e, a, d, prec); arb_mul(f, b, d, prec); acb_mul_onei(z, z); } /* squaring = a^2-b^2, 2ab */ else if (x == y) { /* aliasing */ if (z == x) { arb_t t; arb_init(t); arb_mul(t, a, b, prec); arb_mul_2exp_si(t, t, 1); arb_mul(e, a, a, prec); arb_mul(f, b, b, prec); arb_sub(e, e, f, prec); arb_swap(f, t); arb_clear(t); } else { arb_mul(e, a, a, prec); arb_mul(f, b, b, prec); arb_sub(e, e, f, prec); arb_mul(f, a, b, prec); arb_mul_2exp_si(f, f, 1); } } else { /* aliasing */ if (z == x) { arb_t t, u; arb_init(t); arb_init(u); arb_mul(t, a, c, prec); arb_mul(u, a, d, prec); arb_mul(e, b, d, prec); arb_sub(e, t, e, prec); arb_mul(f, b, c, prec); arb_add(f, u, f, prec); arb_clear(t); arb_clear(u); } else if (z == y) { arb_t t, u; arb_init(t); arb_init(u); arb_mul(t, a, c, prec); arb_mul(u, b, c, prec); arb_mul(e, b, d, prec); arb_sub(e, t, e, prec); arb_mul(f, a, d, prec); arb_add(f, u, f, prec); arb_clear(t); arb_clear(u); } else { arb_t t; arb_init(t); arb_mul(e, a, c, prec); arb_mul(t, b, d, prec); arb_sub(e, e, t, prec); arb_mul(f, a, d, prec); arb_mul(t, b, c, prec); arb_add(f, f, t, prec); arb_clear(t); } } #undef a #undef b #undef c #undef d #undef e #undef f } arb-2.22.1/acb/polygamma.c000066400000000000000000000031551417376376500152500ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #include "acb_poly.h" void acb_polygamma(acb_t res, const acb_t s, const acb_t z, slong prec) { if (acb_is_zero(s)) { acb_digamma(res, z, prec); } else if (acb_is_int(s) && arb_is_positive(acb_realref(s))) { acb_t t, u; acb_init(t); acb_init(u); acb_add_ui(t, s, 1, prec); acb_gamma(u, t, prec); acb_hurwitz_zeta(t, t, z, prec); if (acb_is_int_2exp_si(s, 1)) acb_neg(t, t); acb_mul(res, t, u, prec); acb_clear(t); acb_clear(u); } else { acb_t t, u; acb_struct v[2]; acb_init(t); acb_init(u); acb_init(v); acb_init(v + 1); /* u = psi(-s) + gamma */ acb_neg(t, s); acb_digamma(u, t, prec); arb_const_euler(acb_realref(v), prec); arb_add(acb_realref(u), acb_realref(u), acb_realref(v), prec); acb_add_ui(t, s, 1, prec); _acb_poly_zeta_cpx_series(v, t, z, 0, 2, prec); acb_addmul(v + 1, v, u, prec); acb_neg(t, s); acb_rgamma(u, t, prec); acb_mul(res, v + 1, u, prec); acb_clear(v); acb_clear(v + 1); acb_clear(t); acb_clear(u); } } arb-2.22.1/acb/polylog.c000066400000000000000000000014111417376376500147400ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #include "acb_poly.h" void acb_polylog(acb_t w, const acb_t s, const acb_t z, slong prec) { acb_t t; acb_init(t); _acb_poly_polylog_cpx(t, s, z, 1, prec); acb_swap(w, t); acb_clear(t); } void acb_polylog_si(acb_t w, slong s, const acb_t z, slong prec) { acb_t t; acb_init(t); acb_set_si(t, s); acb_polylog(w, t, z, prec); acb_clear(t); } arb-2.22.1/acb/pow.c000066400000000000000000000121531417376376500140650ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_pow_fmpz_binexp(acb_t y, const acb_t b, const fmpz_t e, slong prec) { slong i, wp, bits; if (-WORD(2) <= *e && *e <= WORD(4)) { if (*e == WORD(0)) { acb_one(y); } else if (*e == WORD(1)) { acb_set_round(y, b, prec); } else if (*e == -WORD(1)) { acb_inv(y, b, prec); } else if (*e == WORD(2)) { acb_mul(y, b, b, prec); } else if (*e == WORD(3)) { acb_cube(y, b, prec); } else if (*e == WORD(4)) { acb_mul(y, b, b, prec); acb_mul(y, y, y, prec); } else { acb_inv(y, b, prec); acb_mul(y, y, y, prec); } return; } if (fmpz_sgn(e) < 0) { fmpz_t f; fmpz_init(f); fmpz_neg(f, e); if (acb_is_exact(b)) { acb_pow_fmpz_binexp(y, b, f, prec + 2); acb_inv(y, y, prec); } else { acb_inv(y, b, prec + fmpz_bits(e) + 2); acb_pow_fmpz_binexp(y, y, f, prec); } fmpz_clear(f); return; } if (!COEFF_IS_MPZ(*e) && ((*e) % 3 == 0)) { fmpz e3 = (*e) / 3; acb_pow_fmpz_binexp(y, b, &e3, prec); acb_cube(y, y, prec); return; } if (y == b) { acb_t t; acb_init(t); acb_set(t, b); acb_pow_fmpz_binexp(y, t, e, prec); acb_clear(t); return; } acb_set(y, b); bits = fmpz_bits(e); wp = ARF_PREC_ADD(prec, bits); for (i = bits - 2; i >= 0; i--) { acb_mul(y, y, y, wp); if (fmpz_tstbit(e, i)) acb_mul(y, y, b, wp); } } void acb_pow_fmpz(acb_t y, const acb_t b, const fmpz_t e, slong prec) { acb_pow_fmpz_binexp(y, b, e, prec); } void acb_pow_ui(acb_t y, const acb_t b, ulong e, slong prec) { fmpz_t f; fmpz_init_set_ui(f, e); acb_pow_fmpz(y, b, f, prec); fmpz_clear(f); } void acb_pow_si(acb_t y, const acb_t b, slong e, slong prec) { fmpz_t f; fmpz_init(f); fmpz_set_si(f, e); acb_pow_fmpz(y, b, f, prec); fmpz_clear(f); } void _acb_pow_exp(acb_t z, const acb_t x, const acb_t y, slong prec) { acb_t t; acb_init(t); acb_log(t, x, prec); acb_mul(t, t, y, prec); acb_exp(z, t, prec); acb_clear(t); } void _acb_pow_arb_exp(acb_t z, const acb_t x, const arb_t y, slong prec) { acb_t t; acb_init(t); acb_log(t, x, prec); acb_mul_arb(t, t, y, prec); acb_exp(z, t, prec); acb_clear(t); } #define BINEXP_LIMIT 64 void acb_pow_arb(acb_t z, const acb_t x, const arb_t y, slong prec) { const arf_struct * ymid = arb_midref(y); const mag_struct * yrad = arb_radref(y); if (arb_is_zero(y)) { acb_one(z); return; } if (acb_is_zero(x)) { if (arb_is_positive(y)) acb_zero(z); else acb_indeterminate(z); return; } if (mag_is_zero(yrad)) { /* small half-integer or integer */ if (arf_cmpabs_2exp_si(ymid, BINEXP_LIMIT) < 0 && arf_is_int_2exp_si(ymid, -1)) { fmpz_t e; fmpz_init(e); if (arf_is_int(ymid)) { arf_get_fmpz_fixed_si(e, ymid, 0); acb_pow_fmpz_binexp(z, x, e, prec); } else { arf_get_fmpz_fixed_si(e, ymid, -1); if (fmpz_sgn(e) >= 0) { acb_sqrt(z, x, prec + fmpz_bits(e)); acb_pow_fmpz_binexp(z, z, e, prec); } else { fmpz_neg(e, e); acb_rsqrt(z, x, prec + fmpz_bits(e)); acb_pow_fmpz_binexp(z, z, e, prec); } } fmpz_clear(e); return; } } _acb_pow_arb_exp(z, x, y, prec); } void acb_pow(acb_t z, const acb_t x, const acb_t y, slong prec) { if (arb_is_zero(acb_imagref(y))) { acb_pow_arb(z, x, acb_realref(y), prec); } else { if (acb_is_zero(x)) { if (arb_is_positive(acb_realref(y))) acb_zero(z); else acb_indeterminate(z); return; } _acb_pow_exp(z, x, y, prec); } } void acb_pow_analytic(acb_ptr res, const acb_t z, const acb_t w, int analytic, slong prec) { if (analytic && !acb_is_int(w) && arb_contains_zero(acb_imagref(z)) && !arb_is_positive(acb_realref(z))) { acb_indeterminate(res); } else { acb_pow(res, z, w, prec); } } arb-2.22.1/acb/quadratic_roots_fmpz.c000066400000000000000000000022561417376376500175220ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_quadratic_roots_fmpz(acb_t r1, acb_t r2, const fmpz_t a, const fmpz_t b, const fmpz_t c, slong prec) { fmpz_t d; fmpz_init(d); /* d = b^2 - 4ac */ fmpz_mul(d, a, c); fmpz_mul_2exp(d, d, 2); fmpz_submul(d, b, b); fmpz_neg(d, d); /* +/- sqrt(d) */ acb_zero(r1); if (fmpz_sgn(d) >= 0) { arb_sqrt_fmpz(acb_realref(r1), d, prec + fmpz_bits(d) + 4); } else { fmpz_neg(d, d); arb_sqrt_fmpz(acb_imagref(r1), d, prec + fmpz_bits(d) + 4); } acb_neg(r2, r1); /* -b */ acb_sub_fmpz(r1, r1, b, prec + 4); acb_sub_fmpz(r2, r2, b, prec + 4); /* divide by 2a */ fmpz_mul_2exp(d, a, 1); acb_div_fmpz(r1, r1, d, prec); acb_div_fmpz(r2, r2, d, prec); fmpz_clear(d); return; } arb-2.22.1/acb/randtest.c000066400000000000000000000026571417376376500151140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_randtest(acb_t z, flint_rand_t state, slong prec, slong mag_bits) { arb_randtest(acb_realref(z), state, prec, mag_bits); arb_randtest(acb_imagref(z), state, prec, mag_bits); } void acb_randtest_special(acb_t z, flint_rand_t state, slong prec, slong mag_bits) { arb_randtest_special(acb_realref(z), state, prec, mag_bits); arb_randtest_special(acb_imagref(z), state, prec, mag_bits); } void acb_randtest_precise(acb_t z, flint_rand_t state, slong prec, slong mag_bits) { arb_randtest_precise(acb_realref(z), state, prec, mag_bits); arb_randtest_precise(acb_imagref(z), state, prec, mag_bits); } void acb_randtest_param(acb_t x, flint_rand_t state, slong prec, slong size) { if (n_randint(state, 8) == 0) { fmpz_t t; fmpz_init(t); fmpz_randtest(t, state, 1 + n_randint(state, prec)); arb_set_fmpz(acb_realref(x), t); arb_zero(acb_imagref(x)); acb_mul_2exp_si(x, x, -1); fmpz_clear(t); } else { acb_randtest(x, state, prec, size); } } arb-2.22.1/acb/real_abs.c000066400000000000000000000017571417376376500150400ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_abs(acb_t res, const acb_t z, int analytic, slong prec) { if (!acb_is_finite(z) || (analytic && arb_contains_zero(acb_realref(z)))) { acb_indeterminate(res); } else { if (arb_is_nonnegative(acb_realref(z))) { acb_set_round(res, z, prec); } else if (arb_is_negative(acb_realref(z))) { acb_neg_round(res, z, prec); } else { acb_t t; acb_init(t); acb_neg(t, z); acb_union(res, z, t, prec); acb_clear(t); } } } arb-2.22.1/acb/real_ceil.c000066400000000000000000000013061417376376500151750ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_ceil(acb_t res, const acb_t z, int analytic, slong prec) { if (!acb_is_finite(z) || (analytic && arb_contains_int(acb_realref(z)))) { acb_indeterminate(res); } else { arb_ceil(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } } arb-2.22.1/acb/real_floor.c000066400000000000000000000013071417376376500154030ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_floor(acb_t res, const acb_t z, int analytic, slong prec) { if (!acb_is_finite(z) || (analytic && arb_contains_int(acb_realref(z)))) { acb_indeterminate(res); } else { arb_floor(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } } arb-2.22.1/acb/real_heaviside.c000066400000000000000000000012001417376376500162130ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_heaviside(acb_t res, const acb_t z, int analytic, slong prec) { acb_real_sgn(res, z, analytic, prec); if (acb_is_finite(res)) { acb_add_ui(res, res, 1, prec); acb_mul_2exp_si(res, res, -1); } } arb-2.22.1/acb/real_max.c000066400000000000000000000016521417376376500150520ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_max(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec) { arb_t t; if (!acb_is_finite(x) || !acb_is_finite(y)) { acb_indeterminate(res); return; } arb_init(t); arb_sub(t, acb_realref(x), acb_realref(y), prec); if (arb_is_positive(t)) acb_set_round(res, x, prec); else if (arb_is_negative(t)) acb_set_round(res, y, prec); else if (!analytic) acb_union(res, x, y, prec); else acb_indeterminate(res); arb_clear(t); } arb-2.22.1/acb/real_min.c000066400000000000000000000016521417376376500150500ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_min(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec) { arb_t t; if (!acb_is_finite(x) || !acb_is_finite(y)) { acb_indeterminate(res); return; } arb_init(t); arb_sub(t, acb_realref(x), acb_realref(y), prec); if (arb_is_positive(t)) acb_set_round(res, y, prec); else if (arb_is_negative(t)) acb_set_round(res, x, prec); else if (!analytic) acb_union(res, x, y, prec); else acb_indeterminate(res); arb_clear(t); } arb-2.22.1/acb/real_sgn.c000066400000000000000000000012631417376376500150520ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_sgn(acb_t res, const acb_t z, int analytic, slong prec) { if (!acb_is_finite(z) || (analytic && arb_contains_zero(acb_realref(z)))) { acb_indeterminate(res); } else { acb_csgn(acb_realref(res), z); arb_zero(acb_imagref(res)); } } arb-2.22.1/acb/real_sqrtpos.c000066400000000000000000000014611417376376500157760ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_real_sqrtpos(acb_t res, const acb_t z, int analytic, slong prec) { if (arb_is_zero(acb_imagref(z)) && !analytic) { arb_sqrtpos(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } else if (arb_is_positive(acb_realref(z)) || !arb_contains_zero(acb_imagref(z))) { acb_sqrt(res, z, prec); } else { acb_indeterminate(res); } } arb-2.22.1/acb/rel_error_bits.c000066400000000000000000000042331417376376500162740ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" slong acb_rel_error_bits(const acb_t x) { int am, ar, bm, br; slong result; const fmpz * radmag; const fmpz * midmag; fmpz_t t; am = !arf_is_zero(arb_midref(acb_realref(x))); ar = !mag_is_zero(arb_radref(acb_realref(x))); bm = !arf_is_zero(arb_midref(acb_imagref(x))); br = !mag_is_zero(arb_radref(acb_imagref(x))); /* no radius -- exact */ if (!ar && !br) return -ARF_PREC_EXACT; /* no midpoint -- infinite relative error */ if (!am && !bm) return ARF_PREC_EXACT; if (!acb_is_finite(x)) return ARF_PREC_EXACT; #define ame ARF_EXPREF(arb_midref(acb_realref(x))) #define are MAG_EXPREF(arb_radref(acb_realref(x))) #define bme ARF_EXPREF(arb_midref(acb_imagref(x))) #define bre MAG_EXPREF(arb_radref(acb_imagref(x))) if (am && bm) midmag = fmpz_cmp(ame, bme) >= 0 ? ame : bme; else if (am) midmag = ame; else midmag = bme; if (ar && br) radmag = fmpz_cmp(are, bre) >= 0 ? are : bre; else if (ar) radmag = are; else radmag = bre; fmpz_init(t); fmpz_add_ui(t, radmag, 1); result = _fmpz_sub_small(t, midmag); fmpz_clear(t); return result; } slong acb_rel_one_accuracy_bits(const acb_t z) { if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -1) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -1) < 0) { acb_t t; arf_init(arb_midref(acb_realref(t))); arf_one(arb_midref(acb_realref(t))); arf_init(arb_midref(acb_imagref(t))); *arb_radref(acb_realref(t)) = *arb_radref(acb_realref(z)); *arb_radref(acb_imagref(t)) = *arb_radref(acb_imagref(z)); return acb_rel_accuracy_bits(t); } else { return acb_rel_accuracy_bits(z); } } arb-2.22.1/acb/rising2_ui.c000066400000000000000000000015271417376376500153350ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #include "acb_hypgeom.h" void acb_rising2_ui(acb_t u, acb_t v, const acb_t x, ulong n, slong prec) { if (x == u || x == v) { acb_t t; acb_init(t); acb_set(t, x); acb_rising2_ui(u, v, t, n, prec); acb_clear(t); } else { acb_struct tmp[2]; tmp[0] = *u; tmp[1] = *v; acb_hypgeom_rising_ui_jet(tmp, x, n, 2, prec); *u = tmp[0]; *v = tmp[1]; } } arb-2.22.1/acb/rising_ui.c000066400000000000000000000012051417376376500152440ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #include "acb_hypgeom.h" void acb_rising_ui(acb_t y, const acb_t x, ulong n, slong prec) { acb_hypgeom_rising_ui(y, x, n, prec); } void acb_rising(acb_t y, const acb_t x, const acb_t n, slong prec) { acb_hypgeom_rising(y, x, n, prec); } arb-2.22.1/acb/rising_ui_get_mag.c000066400000000000000000000042771417376376500167430ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void acb_rising_get_mag2_right(mag_t bound, const arb_t a, const arb_t b, ulong n) { mag_t t, u; ulong k; mag_init(t); mag_init(u); arb_get_mag(t, a); arb_get_mag(u, b); mag_mul(bound, t, t); mag_addmul(bound, u, u); mag_set(u, bound); mag_mul_2exp_si(t, t, 1); for (k = 1; k < n; k++) { mag_add_ui_2exp_si(u, u, 2 * k - 1, 0); mag_add(u, u, t); mag_mul(bound, bound, u); } mag_clear(t); mag_clear(u); } void acb_rising_ui_get_mag(mag_t bound, const acb_t s, ulong n) { if (n == 0) { mag_one(bound); return; } if (n == 1) { acb_get_mag(bound, s); return; } if (!acb_is_finite(s)) { mag_inf(bound); return; } if (arf_sgn(arb_midref(acb_realref(s))) >= 0) { acb_rising_get_mag2_right(bound, acb_realref(s), acb_imagref(s), n); } else { arb_t a; slong k; mag_t bound2, t, u; arb_init(a); mag_init(bound2); mag_init(t); mag_init(u); arb_get_mag(u, acb_imagref(s)); mag_mul(u, u, u); mag_one(bound); for (k = 0; k < n; k++) { arb_add_ui(a, acb_realref(s), k, MAG_BITS); if (arf_sgn(arb_midref(a)) >= 0) { acb_rising_get_mag2_right(bound2, a, acb_imagref(s), n - k); mag_mul(bound, bound, bound2); break; } else { arb_get_mag(t, a); mag_mul(t, t, t); mag_add(t, t, u); mag_mul(bound, bound, t); } } arb_clear(a); mag_clear(bound2); mag_clear(t); mag_clear(u); } mag_sqrt(bound, bound); } arb-2.22.1/acb/root_ui.c000066400000000000000000000020611417376376500147350ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_root_ui(acb_t res, const acb_t z, ulong n, slong prec) { if (n == 0) { acb_indeterminate(res); } else if (n == 1) { acb_set_round(res, z, prec); } else if (n == 2) { acb_sqrt(res, z, prec); } else if (n == 4) { acb_sqrt(res, z, prec + 4); acb_sqrt(res, res, prec); } else if (acb_is_real(z) && arb_is_nonnegative(acb_realref(z))) { arb_root(acb_realref(res), acb_realref(z), n, prec); arb_zero(acb_imagref(res)); } else { acb_log(res, z, prec + 4); acb_div_ui(res, res, n, prec + 4); acb_exp(res, res, prec); } } arb-2.22.1/acb/rsqrt.c000066400000000000000000000275211417376376500144400ustar00rootroot00000000000000/* Copyright (C) 2013, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" /* r - |m| */ void arb_get_mag_reverse(mag_t res, const arb_t x) { mag_t t; mag_init(t); arf_get_mag_lower(t, arb_midref(x)); mag_sub(res, arb_radref(x), t); mag_clear(t); } /* upper bound for re(rsqrt(x+yi)) / |rsqrt(x+yi)|, given upper bound for x, lower bound for y */ void mag_rsqrt_re_quadrant1_upper(mag_t res, const mag_t x, const mag_t y) { if (mag_is_zero(x)) { mag_one(res); mag_mul_2exp_si(res, res, -1); } else { mag_t t, u; mag_init(t); mag_init(u); /* t = (y/x)^2 -- the result is a decreasing function of t */ mag_div_lower(t, y, x); mag_mul_lower(t, t, t); /* (rsqrt(t^2+1)+1)/2 */ mag_add_ui_lower(u, t, 1); mag_rsqrt(u, u); mag_add_ui(u, u, 1); mag_mul_2exp_si(res, u, -1); mag_clear(t); mag_clear(u); } mag_sqrt(res, res); } /* lower bound for re(rsqrt(x+yi)) / |rsqrt(x+yi)|, given lower bound for x, upper bound for y */ void mag_rsqrt_re_quadrant1_lower(mag_t res, const mag_t x, const mag_t y) { if (mag_is_zero(x)) { mag_one(res); mag_mul_2exp_si(res, res, -1); } else { mag_t t, u; mag_init(t); mag_init(u); /* t = (y/x)^2 -- the result is a decreasing function of t */ mag_div(t, y, x); mag_mul(t, t, t); /* (rsqrt(t^2+1)+1)/2 */ mag_add_ui(u, t, 1); mag_rsqrt_lower(u, u); mag_add_ui_lower(u, u, 1); mag_mul_2exp_si(res, u, -1); mag_clear(t); mag_clear(u); } mag_sqrt_lower(res, res); } /* upper bound for re(rsqrt(-x+yi)) / |rsqrt(x+yi)|, given lower bound for -x, upper bound for y */ void mag_rsqrt_re_quadrant2_upper(mag_t res, const mag_t x, const mag_t y) { if (mag_is_zero(x)) { mag_one(res); mag_mul_2exp_si(res, res, -1); } else { mag_t t, u, v; mag_init(t); mag_init(u); mag_init(v); /* t = (y/x)^2 -- the result is an increasing function of t */ mag_div(t, y, x); mag_mul(t, t, t); /* t / (2*(t+1)*(rsqrt(t+1)+1)) */ mag_add_ui(u, t, 1); mag_rsqrt_lower(v, u); mag_add_ui_lower(v, v, 1); mag_add_ui_lower(u, t, 1); mag_mul_lower(v, v, u); mag_mul_2exp_si(v, v, 1); mag_div(res, t, v); mag_clear(t); mag_clear(u); mag_clear(v); } mag_sqrt(res, res); } /* lower bound for re(rsqrt(-x+yi)) / |rsqrt(x+yi)|, given upper bound for -x, lower bound for y */ void mag_rsqrt_re_quadrant2_lower(mag_t res, const mag_t x, const mag_t y) { if (mag_is_zero(x)) { mag_one(res); mag_mul_2exp_si(res, res, -1); } else { mag_t t, u, v; mag_init(t); mag_init(u); mag_init(v); /* t = (y/x)^2 -- the result is an increasing function of t */ mag_div_lower(t, y, x); mag_mul_lower(t, t, t); /* t / (2*(t+1)*(rsqrt(t+1)+1)) */ mag_add_ui_lower(u, t, 1); mag_rsqrt(v, u); mag_add_ui(v, v, 1); mag_add_ui(u, t, 1); mag_mul(v, v, u); mag_mul_2exp_si(v, v, 1); mag_div_lower(res, t, v); mag_clear(t); mag_clear(u); mag_clear(v); } mag_sqrt_lower(res, res); } void acb_rsqrt_wide(acb_t res, const acb_t z, slong prec) { mag_t ax, ay, bx, by, cx, cy, dx, dy, am, bm; mag_t one; mag_init(ax); mag_init(ay); mag_init(bx); mag_init(by); mag_init(cx); mag_init(cy); mag_init(dx); mag_init(dy); mag_init(am); mag_init(bm); mag_init(one); mag_one(one); /* magnitude */ acb_get_mag(am, z); mag_rsqrt_lower(am, am); acb_get_mag_lower(bm, z); mag_rsqrt(bm, bm); /* upper or lower half plane */ if (arb_is_nonnegative(acb_imagref(z)) || arb_is_negative(acb_imagref(z))) { if (arb_is_nonnegative(acb_realref(z))) { arb_get_mag_lower(ax, acb_realref(z)); arb_get_mag(ay, acb_imagref(z)); arb_get_mag(bx, acb_realref(z)); arb_get_mag_lower(by, acb_imagref(z)); mag_rsqrt_re_quadrant2_lower(cx, bx, by); mag_rsqrt_re_quadrant2_upper(dx, ax, ay); /* equivalent but more expensive than pythagoras mag_rsqrt_re_quadrant1_lower(ax, ax, ay); mag_rsqrt_re_quadrant1_upper(bx, bx, by); */ mag_mul(ax, dx, dx); mag_sub_lower(ax, one, ax); mag_sqrt_lower(ax, ax); mag_mul_lower(bx, cx, cx); mag_sub(bx, one, bx); mag_sqrt(bx, bx); } else { if (arb_is_nonpositive(acb_realref(z))) { arb_get_mag(ax, acb_realref(z)); arb_get_mag_lower(ay, acb_imagref(z)); arb_get_mag_lower(bx, acb_realref(z)); arb_get_mag(by, acb_imagref(z)); /* equivalent but more expensive than pythagoras mag_rsqrt_re_quadrant1_lower(cx, bx, by); mag_rsqrt_re_quadrant1_upper(dx, ax, ay); */ mag_rsqrt_re_quadrant2_lower(ax, ax, ay); mag_rsqrt_re_quadrant2_upper(bx, bx, by); } else if (arf_sgn(arb_midref(acb_realref(z))) >= 0) { arb_get_mag_reverse(ax, acb_realref(z)); arb_get_mag_lower(ay, acb_imagref(z)); arb_get_mag(bx, acb_realref(z)); arb_get_mag_lower(by, acb_imagref(z)); mag_rsqrt_re_quadrant2_lower(ax, ax, ay); mag_rsqrt_re_quadrant1_upper(bx, bx, by); } else { arb_get_mag(ax, acb_realref(z)); arb_get_mag_lower(ay, acb_imagref(z)); arb_get_mag_reverse(bx, acb_realref(z)); arb_get_mag_lower(by, acb_imagref(z)); mag_rsqrt_re_quadrant2_lower(ax, ax, ay); mag_rsqrt_re_quadrant1_upper(bx, bx, by); } /* pythagoras */ mag_mul(cx, bx, bx); mag_sub_lower(cx, one, bx); mag_sqrt_lower(cx, cx); mag_mul_lower(dx, ax, ax); mag_sub(dx, one, dx); mag_sqrt(dx, dx); } mag_mul_lower(ax, ax, am); mag_mul_lower(cx, cx, am); mag_mul(bx, bx, bm); mag_mul(dx, dx, bm); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { arb_set_interval_mag(acb_realref(res), ax, bx, prec); arb_set_interval_mag(acb_imagref(res), cx, dx, prec); arf_neg(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(res))); } else { arb_set_interval_mag(acb_realref(res), ax, bx, prec); arb_set_interval_mag(acb_imagref(res), cx, dx, prec); } } else if (arb_is_positive(acb_realref(z))) { /* right half plane, straddling real line */ int symmetric; symmetric = arf_is_zero(arb_midref(acb_imagref(z))); arb_get_mag_lower(ax, acb_realref(z)); arb_get_mag(dy, acb_imagref(z)); arb_get_mag_reverse(cy, acb_imagref(z)); if (!symmetric) mag_rsqrt_re_quadrant2_lower(cx, ax, cy); mag_rsqrt_re_quadrant2_upper(dx, ax, dy); mag_one(bx); /* mag_rsqrt_re_quadrant1_lower(ax, ax, dy); */ mag_mul(ax, dx, dx); mag_sub_lower(ax, one, ax); mag_sqrt_lower(ax, ax); mag_mul_lower(ax, ax, am); mag_mul(bx, bx, bm); mag_mul(cx, cx, bm); mag_mul(dx, dx, bm); if (symmetric) arb_set_interval_neg_pos_mag(acb_imagref(res), dx, dx, prec); else if (arf_sgn(arb_midref(acb_imagref(z))) > 0) arb_set_interval_neg_pos_mag(acb_imagref(res), dx, cx, prec); else arb_set_interval_neg_pos_mag(acb_imagref(res), cx, dx, prec); arb_set_interval_mag(acb_realref(res), ax, bx, prec); } else /* left half plane, straddling branch cut */ { mag_zero(ax); arb_get_mag_lower(bx, acb_realref(z)); arb_get_mag(by, acb_imagref(z)); mag_rsqrt_re_quadrant2_upper(bx, bx, by); mag_mul_lower(ax, ax, am); mag_mul(bx, bx, bm); arb_set_interval_mag(acb_realref(res), ax, bx, prec); /* cx, dx = 1,1 */ arb_set_interval_neg_pos_mag(acb_imagref(res), bm, bm, prec); } mag_clear(ax); mag_clear(ay); mag_clear(bx); mag_clear(by); mag_clear(cx); mag_clear(cy); mag_clear(dx); mag_clear(dy); mag_clear(am); mag_clear(bm); mag_clear(one); } void acb_rsqrt_precise(acb_t y, const acb_t x, slong prec) { #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(y) #define d acb_imagref(y) arb_t r, t, u, v; slong wp; /* based on the identity sqrt(z) = sqrt(r) (z+r) / |z+r|: */ /* 1/sqrt(a+bi) = (1/v)((a+r) - b*i), r = |a+bi|, v = sqrt(r*(b^2+(a+r)^2)) */ wp = prec + 6; arb_init(r); arb_init(t); arb_init(u); arb_init(v); /* u = b^2, r = |a+bi| */ arb_mul(t, a, a, wp); arb_mul(u, b, b, wp); arb_add(r, t, u, wp); arb_sqrtpos(r, r, wp); /* t = a+r, v = r*(b^2+(a+r)^2) */ arb_add(t, r, a, wp); arb_mul(v, t, t, wp); arb_add(v, v, u, wp); arb_mul(v, v, r, wp); /* v = 1/sqrt(v) */ arb_rsqrt(v, v, wp); arb_mul(c, t, v, prec); arb_mul(d, b, v, prec); arb_neg(d, d); arb_clear(r); arb_clear(t); arb_clear(u); arb_clear(v); #undef a #undef b #undef c #undef d } void acb_rsqrt(acb_t y, const acb_t x, slong prec) { slong acc; #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(y) #define d acb_imagref(y) if (acb_contains_zero(x)) { acb_indeterminate(y); return; } if (arb_is_zero(b)) { if (arb_is_nonnegative(a)) { arb_rsqrt(c, a, prec); arb_zero(d); return; } else if (arb_is_nonpositive(a)) { arb_neg(d, a); arb_rsqrt(d, d, prec); arb_neg(d, d); arb_zero(c); return; } } if (arb_is_zero(a)) { if (arb_is_nonnegative(b)) { arb_mul_2exp_si(c, b, 1); arb_rsqrt(c, c, prec); arb_neg(d, c); return; } else if (arb_is_nonpositive(b)) { arb_mul_2exp_si(c, b, 1); arb_neg(c, c); arb_rsqrt(c, c, prec); arb_set(d, c); return; } } acc = acb_rel_accuracy_bits(x); if (acc < 25) { acb_rsqrt_wide(y, x, prec); } else { if (arb_is_positive(a)) { acb_rsqrt_precise(y, x, prec); } else if (arb_is_nonnegative(b)) { acb_neg(y, x); acb_rsqrt_precise(y, y, prec); acb_div_onei(y, y); } else if (arb_is_negative(b)) { acb_neg(y, x); acb_rsqrt_precise(y, y, prec); acb_mul_onei(y, y); } else { acb_rsqrt_wide(y, x, prec); } } #undef a #undef b #undef c #undef d } void acb_rsqrt_analytic(acb_ptr res, const acb_t z, int analytic, slong prec) { if (analytic && arb_contains_zero(acb_imagref(z)) && !arb_is_positive(acb_realref(z))) { acb_indeterminate(res); } else { acb_rsqrt(res, z, prec); } } arb-2.22.1/acb/sech.c000066400000000000000000000026531417376376500142060ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sech(acb_t res, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_sech(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } else if (arb_is_zero(acb_realref(z))) { arb_sec(acb_realref(res), acb_imagref(z), prec); arb_zero(acb_imagref(res)); } else { if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 0) > 0) { acb_t t; acb_init(t); if (arf_sgn(arb_midref(acb_realref(z))) > 0) { acb_neg(t, z); acb_exp(t, t, prec + 4); } else { acb_exp(t, z, prec + 4); } acb_mul(res, t, t, prec + 4); acb_add_ui(res, res, 1, prec + 4); acb_div(res, t, res, prec); acb_mul_2exp_si(res, res, 1); acb_clear(t); } else { acb_cosh(res, z, prec + 4); acb_inv(res, res, prec); } } } arb-2.22.1/acb/sgn.c000066400000000000000000000022051417376376500140440ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sgn(acb_t res, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_sgn(acb_realref(res), acb_realref(z)); arb_zero(acb_imagref(res)); } else if (arb_is_zero(acb_realref(z))) { arb_sgn(acb_imagref(res), acb_imagref(z)); arb_zero(acb_realref(res)); } else { arb_t t; arb_init(t); acb_abs(t, z, prec); arb_inv(t, t, prec); if (arb_is_finite(t)) { acb_mul_arb(res, z, t, prec); } else { arf_zero(arb_midref(acb_realref(res))); mag_one(arb_radref(acb_realref(res))); arb_set(acb_imagref(res), acb_realref(res)); } arb_clear(t); } } arb-2.22.1/acb/sin.c000066400000000000000000000022061417376376500140470ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sin(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_sin(acb_realref(r), a, prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(a)) { arb_sinh(acb_imagref(r), b, prec); arb_zero(acb_realref(r)); } else { arb_t sa, ca, sb, cb; arb_init(sa); arb_init(ca); arb_init(sb); arb_init(cb); arb_sin_cos(sa, ca, a, prec); arb_sinh_cosh(sb, cb, b, prec); arb_mul(acb_realref(r), sa, cb, prec); arb_mul(acb_imagref(r), sb, ca, prec); arb_clear(sa); arb_clear(ca); arb_clear(sb); arb_clear(cb); } #undef a #undef b } arb-2.22.1/acb/sin_cos.c000066400000000000000000000026171417376376500147210ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sin_cos(acb_t s, acb_t c, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_sin_cos(acb_realref(s), acb_realref(c), a, prec); arb_zero(acb_imagref(s)); arb_zero(acb_imagref(c)); } else if (arb_is_zero(a)) { arb_sinh_cosh(acb_imagref(s), acb_realref(c), b, prec); arb_zero(acb_realref(s)); arb_zero(acb_imagref(c)); } else { arb_t sa, ca, sb, cb; arb_init(sa); arb_init(ca); arb_init(sb); arb_init(cb); arb_sin_cos(sa, ca, a, prec); arb_sinh_cosh(sb, cb, b, prec); arb_mul(acb_realref(s), sa, cb, prec); arb_mul(acb_imagref(s), sb, ca, prec); arb_mul(acb_realref(c), ca, cb, prec); arb_mul(acb_imagref(c), sa, sb, prec); arb_neg(acb_imagref(c), acb_imagref(c)); arb_clear(sa); arb_clear(ca); arb_clear(sb); arb_clear(cb); } #undef a #undef b } arb-2.22.1/acb/sin_cos_pi.c000066400000000000000000000031271417376376500154060ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sin_cos_pi(acb_t s, acb_t c, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_sin_cos_pi(acb_realref(s), acb_realref(c), a, prec); arb_zero(acb_imagref(s)); arb_zero(acb_imagref(c)); } else if (arb_is_zero(a)) { arb_t t; arb_init(t); arb_const_pi(t, prec); arb_mul(t, t, b, prec); arb_sinh_cosh(acb_imagref(s), acb_realref(c), t, prec); arb_zero(acb_realref(s)); arb_zero(acb_imagref(c)); arb_clear(t); } else { arb_t sa, ca, sb, cb; arb_init(sa); arb_init(ca); arb_init(sb); arb_init(cb); arb_const_pi(sb, prec); arb_mul(sb, sb, b, prec); arb_sin_cos_pi(sa, ca, a, prec); arb_sinh_cosh(sb, cb, sb, prec); arb_mul(acb_realref(s), sa, cb, prec); arb_mul(acb_imagref(s), sb, ca, prec); arb_mul(acb_realref(c), ca, cb, prec); arb_mul(acb_imagref(c), sa, sb, prec); arb_neg(acb_imagref(c), acb_imagref(c)); arb_clear(sa); arb_clear(ca); arb_clear(sb); arb_clear(cb); } #undef a #undef b } arb-2.22.1/acb/sin_pi.c000066400000000000000000000025141417376376500145410ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sin_pi(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { arb_sin_pi(acb_realref(r), a, prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(a)) { arb_t t; arb_init(t); arb_const_pi(t, prec); arb_mul(t, t, b, prec); arb_sinh(acb_imagref(r), t, prec); arb_zero(acb_realref(r)); arb_clear(t); } else { arb_t sa, ca, sb, cb; arb_init(sa); arb_init(ca); arb_init(sb); arb_init(cb); arb_sin_cos_pi(sa, ca, a, prec); arb_const_pi(cb, prec); arb_mul(cb, cb, b, prec); arb_sinh_cosh(sb, cb, cb, prec); arb_mul(acb_realref(r), sa, cb, prec); arb_mul(acb_imagref(r), sb, ca, prec); arb_clear(sa); arb_clear(ca); arb_clear(sb); arb_clear(cb); } #undef a #undef b } arb-2.22.1/acb/sinc.c000066400000000000000000000040661417376376500142200ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static int _acb_is_large(const acb_t z) { int res; mag_t t; mag_init(t); acb_get_mag_lower(t, z); res = mag_cmp_2exp_si(t, 0) >= 0; mag_clear(t); return res; } static void _acb_sinc_direct(acb_t res, const acb_t z, slong prec) { if (acb_is_zero(z)) { acb_one(res); } else { acb_t t; acb_init(t); acb_sin(t, z, prec + 2); acb_div(res, t, z, prec); acb_clear(t); } } static void _acb_sinc_diffbound(acb_t res, const acb_t z, slong prec) { mag_t u, v; int isreal; mag_init(u); mag_init(v); isreal = arb_is_zero(acb_realref(z)); /* exp(|im(z)|) is a crude bound for |sinc'(z)| */ arb_get_mag(u, acb_imagref(z)); mag_hypot(v, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); mag_exp(u, u); mag_mul(u, u, v); arf_set(arb_midref(acb_realref(res)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(z))); mag_zero(arb_radref(acb_realref(res))); mag_zero(arb_radref(acb_imagref(res))); _acb_sinc_direct(res, res, prec); if (isreal) arb_add_error_mag(acb_realref(res), u); else acb_add_error_mag(res, u); mag_clear(u); mag_clear(v); } void acb_sinc(acb_t res, const acb_t z, slong prec) { if (!acb_is_finite(z)) { acb_indeterminate(res); } else if (acb_is_real(z)) { arb_sinc(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } else if (acb_is_exact(z) || _acb_is_large(z)) { _acb_sinc_direct(res, z, prec); } else { _acb_sinc_diffbound(res, z, prec); } } arb-2.22.1/acb/sinc_pi.c000066400000000000000000000017231417376376500147050ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sinc_pi(acb_t res, const acb_t x, slong prec) { mag_t m; acb_t t; if (acb_is_zero(x)) { acb_one(res); return; } mag_init(m); acb_init(t); acb_get_mag_lower(m, x); if (mag_cmp_2exp_si(m, -1) > 0) { acb_const_pi(t, prec + 4); acb_mul(t, t, x, prec + 4); acb_sin_pi(res, x, prec + 4); acb_div(res, res, t, prec); } else { acb_const_pi(t, prec + 4); acb_mul(t, t, x, prec + 4); acb_sinc(res, t, prec); } mag_clear(m); acb_clear(t); } arb-2.22.1/acb/sqrt.c000066400000000000000000000071451417376376500142560ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_sqrt(acb_t y, const acb_t x, slong prec) { arb_t r, t, u; slong wp; int done; #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(y) #define d acb_imagref(y) if (arb_is_zero(b)) { if (arb_is_nonnegative(a)) { arb_sqrt(c, a, prec); arb_zero(d); return; } else if (arb_is_nonpositive(a)) { arb_neg(d, a); arb_sqrt(d, d, prec); arb_zero(c); return; } } if (arb_is_zero(a)) { if (arb_is_nonnegative(b)) { arb_mul_2exp_si(c, b, -1); arb_sqrt(c, c, prec); arb_set(d, c); return; } else if (arb_is_nonpositive(b)) { arb_mul_2exp_si(c, b, -1); arb_neg(c, c); arb_sqrt(c, c, prec); arb_neg(d, c); return; } } wp = prec + 4; arb_init(r); arb_init(t); arb_init(u); /* r = |a+bi| */ acb_abs(r, x, wp); done = 0; if (arf_sgn(arb_midref(a)) >= 0) { arb_add(t, r, a, wp); if (arb_rel_accuracy_bits(t) > 8) { /* sqrt(a+bi) = sqrt((r+a)/2) + b/sqrt(2*(r+a))*i */ arb_mul_2exp_si(u, t, 1); arb_sqrt(u, u, wp); arb_div(d, b, u, prec); arb_set_round(c, u, prec); arb_mul_2exp_si(c, c, -1); done = 1; } else { arb_sub(u, r, a, wp); } } else if (!arb_contains_zero(b)) { arb_sub(u, r, a, wp); if (arb_rel_accuracy_bits(u) > 8) { /* sqrt(a+bi) = |b|/sqrt(2*(r-a)) + sgn(b)*sqrt((r-a)/2)*i */ int sgn = arf_sgn(arb_midref(b)); arb_mul_2exp_si(t, u, 1); arb_sqrt(t, t, wp); arb_div(c, b, t, prec); arb_abs(c, c); arb_set_round(d, t, prec); arb_mul_2exp_si(d, d, -1); if (sgn < 0) arb_neg(d, d); done = 1; } else { arb_add(t, r, a, wp); } } else { arb_add(t, r, a, wp); arb_sub(u, r, a, wp); } /* t = r+a, u = r-a */ if (!done) { /* sqrt(a+bi) = sqrt((r+a)/2) + (b/|b|)*sqrt((r-a)/2)*i (sign) */ arb_mul_2exp_si(t, t, -1); arb_mul_2exp_si(u, u, -1); arb_sqrtpos(c, t, prec); if (arb_is_nonnegative(b)) { arb_sqrtpos(d, u, prec); } else if (arb_is_nonpositive(b)) { arb_sqrtpos(d, u, prec); arb_neg(d, d); } else { arb_sqrtpos(t, u, wp); arb_neg(u, t); arb_union(d, t, u, prec); } } arb_clear(r); arb_clear(t); arb_clear(u); #undef a #undef b #undef c #undef d } void acb_sqrt_analytic(acb_ptr res, const acb_t z, int analytic, slong prec) { if (analytic && arb_contains_zero(acb_imagref(z)) && !arb_is_positive(acb_realref(z))) { acb_indeterminate(res); } else { acb_sqrt(res, z, prec); } } arb-2.22.1/acb/submul.c000066400000000000000000000017661417376376500145770ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_submul(acb_t z, const acb_t x, const acb_t y, slong prec) { if (arb_is_zero(acb_imagref(y))) { arb_submul(acb_imagref(z), acb_imagref(x), acb_realref(y), prec); arb_submul(acb_realref(z), acb_realref(x), acb_realref(y), prec); } else if (arb_is_zero(acb_imagref(x))) { arb_submul(acb_imagref(z), acb_imagref(y), acb_realref(x), prec); arb_submul(acb_realref(z), acb_realref(y), acb_realref(x), prec); } else { acb_t t; acb_init(t); acb_mul(t, x, y, prec); acb_sub(z, z, t, prec); acb_clear(t); } } arb-2.22.1/acb/tan.c000066400000000000000000000033441417376376500140440ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_tan(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_tan(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_tanh(acb_imagref(r), acb_imagref(z), prec); arb_zero(acb_realref(r)); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos(r, t, z, prec + 4); acb_div(r, r, t, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_mul_onei(t, t); acb_exp(t, t, prec + 4); acb_add_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_div_onei(r, r); } else { acb_div_onei(t, t); acb_exp(t, t, prec + 4); acb_add_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_mul_onei(r, r); } } acb_clear(t); } } arb-2.22.1/acb/tan_pi.c000066400000000000000000000035211417376376500145310ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void acb_tan_pi(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_tan_pi(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_t t; arb_init(t); arb_const_pi(t, prec + 4); arb_mul(t, acb_imagref(z), t, prec + 4); arb_tanh(acb_imagref(r), t, prec); arb_zero(acb_realref(r)); arb_clear(t); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos_pi(r, t, z, prec + 4); acb_div(r, r, t, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_exp_pi_i(t, t, prec + 4); acb_add_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_div_onei(r, r); } else { acb_neg(t, t); acb_exp_pi_i(t, t, prec + 4); acb_add_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_mul_onei(r, r); } } acb_clear(t); } } arb-2.22.1/acb/test/000077500000000000000000000000001417376376500140715ustar00rootroot00000000000000arb-2.22.1/acb/test/t-acos.c000066400000000000000000000045031417376376500154250ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("acos...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_acos(a, x, prec1); acb_acos(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check cos(acos(x)) = x */ acb_cos(b, b, prec1); if (!acb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_acos(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-acosh.c000066400000000000000000000045121417376376500155750ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("acosh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_acosh(a, x, prec1); acb_acosh(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check cosh(acosh(x)) = x */ acb_cosh(b, b, prec1); if (!acb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_acosh(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-agm.c000066400000000000000000000465501417376376500152540ustar00rootroot00000000000000/* Copyright (C) 2020 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #define NUM_TESTS 256 const double agm_testdata[NUM_TESTS][6] = { {-1, -1, -1, -1, -1.00000000000000, -1.00000000000000}, {-1, -1, -1, 0, -1.04916052873278, -0.478155746088161}, {-1, -1, -1, 1, -1.19814023473559, 0.000000000000000}, {-1, -1, -1, 2, -1.35980258211696, 0.412918513270561}, {-1, -1, 0, -1, -0.478155746088161, -1.04916052873278}, {-1, -1, 0, 0, 0.000000000000000, 0.000000000000000}, {-1, -1, 0, 1, -0.778004078788958, 0.188411067988680}, {-1, -1, 0, 2, -0.966415146777638, 0.589593010800278}, {-1, -1, 1, -1, 0.000000000000000, -1.19814023473559}, {-1, -1, 1, 0, 0.188411067988680, -0.778004078788958}, {-1, -1, 1, 1, 0.000000000000000, 0.000000000000000}, {-1, -1, 1, 2, -0.574659643809835, 0.810208383866421}, {-1, -1, 2, -1, 0.412918513270561, -1.35980258211696}, {-1, -1, 2, 0, 0.589593010800278, -0.966415146777638}, {-1, -1, 2, 1, 0.810208383866421, -0.574659643809835}, {-1, -1, 2, 2, 1.08423239187061, -0.238299975053003}, {-1, 0, -1, -1, -1.04916052873278, -0.478155746088161}, {-1, 0, -1, 0, -1.00000000000000, 0.000000000000000}, {-1, 0, -1, 1, -1.04916052873278, 0.478155746088161}, {-1, 0, -1, 2, -1.13815978557677, 0.897764105638205}, {-1, 0, 0, -1, -0.599070117367796, -0.599070117367796}, {-1, 0, 0, 0, 0.000000000000000, 0.000000000000000}, {-1, 0, 0, 1, -0.599070117367796, 0.599070117367796}, {-1, 0, 0, 2, -0.742646422399778, 1.01005159361958}, {-1, 0, 1, -1, -0.188411067988680, -0.778004078788958}, {-1, 0, 1, 0, 0.000000000000000, 0.000000000000000}, {-1, 0, 1, 1, -0.188411067988680, 0.778004078788958}, {-1, 0, 1, 2, -0.363823969691055, 1.15631976909117}, {-1, 0, 2, -1, 0.178866979357132, -0.985872907297986}, {-1, 0, 2, 0, 0.422966208408802, 0.661266183461805}, {-1, 0, 2, 1, 0.178866979357132, 0.985872907297986}, {-1, 0, 2, 2, -0.0126420344317752, 1.32391495927282}, {-1, 1, -1, -1, -1.19814023473559, 0.000000000000000}, {-1, 1, -1, 0, -1.04916052873278, 0.478155746088161}, {-1, 1, -1, 1, -1.00000000000000, 1.00000000000000}, {-1, 1, -1, 2, -1.02005412633766, 1.47134936286465}, {-1, 1, 0, -1, -0.778004078788958, -0.188411067988680}, {-1, 1, 0, 0, 0.000000000000000, 0.000000000000000}, {-1, 1, 0, 1, -0.478155746088161, 1.04916052873278}, {-1, 1, 0, 2, -0.571004782644619, 1.52731627482094}, {-1, 1, 1, -1, 0.000000000000000, 0.000000000000000}, {-1, 1, 1, 0, 0.188411067988680, 0.778004078788958}, {-1, 1, 1, 1, 0.000000000000000, 1.19814023473559}, {-1, 1, 1, 2, -0.136827548397369, 1.62780548487271}, {-1, 1, 2, -1, 0.810208383866421, 0.574659643809835}, {-1, 1, 2, 0, 0.589593010800278, 0.966415146777638}, {-1, 1, 2, 1, 0.412918513270561, 1.35980258211696}, {-1, 1, 2, 2, 0.267405171219803, 1.75269801601936}, {-1, 2, -1, -1, -1.35980258211696, 0.412918513270561}, {-1, 2, -1, 0, -1.13815978557677, 0.897764105638205}, {-1, 2, -1, 1, -1.02005412633766, 1.47134936286465}, {-1, 2, -1, 2, -1.00000000000000, 2.00000000000000}, {-1, 2, 0, -1, -0.985872907297986, 0.178866979357132}, {-1, 2, 0, 0, 0.000000000000000, 0.000000000000000}, {-1, 2, 0, 1, -0.420983902077155, 1.47839688785392}, {-1, 2, 0, 2, -0.493004461502931, 2.02900451838781}, {-1, 2, 1, -1, 0.574659643809835, 0.810208383866421}, {-1, 2, 1, 0, 0.363823969691055, 1.15631976909117}, {-1, 2, 1, 1, 0.136827548397369, 1.62780548487271}, {-1, 2, 1, 2, 0.000000000000000, 2.11638793788003}, {-1, 2, 2, -1, 0.963366302386887, 0.963366302386887}, {-1, 2, 2, 0, 0.777111977967075, 1.37110999239961}, {-1, 2, 2, 1, 0.599070117367796, 1.79721035210339}, {-1, 2, 2, 2, 0.455159607692816, 2.23571522629432}, {0, -1, -1, -1, -0.478155746088161, -1.04916052873278}, {0, -1, -1, 0, -0.599070117367796, -0.599070117367796}, {0, -1, -1, 1, -0.778004078788958, -0.188411067988680}, {0, -1, -1, 2, -0.985872907297986, 0.178866979357132}, {0, -1, 0, -1, 0.000000000000000, -1.00000000000000}, {0, -1, 0, 0, 0.000000000000000, 0.000000000000000}, {0, -1, 0, 1, 0.000000000000000, 0.000000000000000}, {0, -1, 0, 2, 0.661266183461805, 0.422966208408802}, {0, -1, 1, -1, 0.478155746088161, -1.04916052873278}, {0, -1, 1, 0, 0.599070117367796, -0.599070117367796}, {0, -1, 1, 1, 0.778004078788958, -0.188411067988680}, {0, -1, 1, 2, 0.985872907297986, 0.178866979357132}, {0, -1, 2, -1, 0.897764105638205, -1.13815978557677}, {0, -1, 2, 0, 1.01005159361958, -0.742646422399778}, {0, -1, 2, 1, 1.15631976909117, -0.363823969691055}, {0, -1, 2, 2, 1.32391495927282, -0.0126420344317752}, {0, 0, -1, -1, 0.000000000000000, 0.000000000000000}, {0, 0, -1, 0, 0.000000000000000, 0.000000000000000}, {0, 0, -1, 1, 0.000000000000000, 0.000000000000000}, {0, 0, -1, 2, 0.000000000000000, 0.000000000000000}, {0, 0, 0, -1, 0.000000000000000, 0.000000000000000}, {0, 0, 0, 0, 0.000000000000000, 0.000000000000000}, {0, 0, 0, 1, 0.000000000000000, 0.000000000000000}, {0, 0, 0, 2, 0.000000000000000, 0.000000000000000}, {0, 0, 1, -1, 0.000000000000000, 0.000000000000000}, {0, 0, 1, 0, 0.000000000000000, 0.000000000000000}, {0, 0, 1, 1, 0.000000000000000, 0.000000000000000}, {0, 0, 1, 2, 0.000000000000000, 0.000000000000000}, {0, 0, 2, -1, 0.000000000000000, 0.000000000000000}, {0, 0, 2, 0, 0.000000000000000, 0.000000000000000}, {0, 0, 2, 1, 0.000000000000000, 0.000000000000000}, {0, 0, 2, 2, 0.000000000000000, 0.000000000000000}, {0, 1, -1, -1, -0.778004078788958, 0.188411067988680}, {0, 1, -1, 0, -0.599070117367796, 0.599070117367796}, {0, 1, -1, 1, -0.478155746088161, 1.04916052873278}, {0, 1, -1, 2, -0.420983902077155, 1.47839688785392}, {0, 1, 0, -1, 0.000000000000000, 0.000000000000000}, {0, 1, 0, 0, 0.000000000000000, 0.000000000000000}, {0, 1, 0, 1, 0.000000000000000, 1.00000000000000}, {0, 1, 0, 2, 0.000000000000000, 1.45679103104691}, {0, 1, 1, -1, 0.778004078788958, 0.188411067988680}, {0, 1, 1, 0, 0.599070117367796, 0.599070117367796}, {0, 1, 1, 1, 0.478155746088161, 1.04916052873278}, {0, 1, 1, 2, 0.420983902077155, 1.47839688785392}, {0, 1, 2, -1, 1.15631976909117, 0.363823969691055}, {0, 1, 2, 0, 1.01005159361958, 0.742646422399778}, {0, 1, 2, 1, 0.897764105638205, 1.13815978557677}, {0, 1, 2, 2, 0.820905313474926, 1.53147158277780}, {0, 2, -1, -1, -0.966415146777638, 0.589593010800278}, {0, 2, -1, 0, -0.742646422399778, 1.01005159361958}, {0, 2, -1, 1, -0.571004782644619, 1.52731627482094}, {0, 2, -1, 2, -0.493004461502931, 2.02900451838781}, {0, 2, 0, -1, 0.661266183461805, 0.422966208408802}, {0, 2, 0, 0, 0.000000000000000, 0.000000000000000}, {0, 2, 0, 1, 0.000000000000000, 1.45679103104691}, {0, 2, 0, 2, 0.000000000000000, 2.00000000000000}, {0, 2, 1, -1, 0.966415146777638, 0.589593010800278}, {0, 2, 1, 0, 0.742646422399778, 1.01005159361958}, {0, 2, 1, 1, 0.571004782644619, 1.52731627482094}, {0, 2, 1, 2, 0.493004461502931, 2.02900451838781}, {0, 2, 2, -1, 1.37110999239961, 0.777111977967075}, {0, 2, 2, 0, 1.19814023473559, 1.19814023473559}, {0, 2, 2, 1, 1.05542091981433, 1.64623191253177}, {0, 2, 2, 2, 0.956311492176322, 2.09832105746556}, {1, -1, -1, -1, 0.000000000000000, -1.19814023473559}, {1, -1, -1, 0, -0.188411067988680, -0.778004078788958}, {1, -1, -1, 1, 0.000000000000000, 0.000000000000000}, {1, -1, -1, 2, 0.574659643809835, 0.810208383866421}, {1, -1, 0, -1, 0.478155746088161, -1.04916052873278}, {1, -1, 0, 0, 0.000000000000000, 0.000000000000000}, {1, -1, 0, 1, 0.778004078788958, 0.188411067988680}, {1, -1, 0, 2, 0.966415146777638, 0.589593010800278}, {1, -1, 1, -1, 1.00000000000000, -1.00000000000000}, {1, -1, 1, 0, 1.04916052873278, -0.478155746088161}, {1, -1, 1, 1, 1.19814023473559, 0.000000000000000}, {1, -1, 1, 2, 1.35980258211696, 0.412918513270561}, {1, -1, 2, -1, 1.47134936286465, -1.02005412633766}, {1, -1, 2, 0, 1.52731627482094, -0.571004782644619}, {1, -1, 2, 1, 1.62780548487271, -0.136827548397369}, {1, -1, 2, 2, 1.75269801601936, 0.267405171219803}, {1, 0, -1, -1, 0.188411067988680, -0.778004078788958}, {1, 0, -1, 0, 0.000000000000000, 0.000000000000000}, {1, 0, -1, 1, 0.188411067988680, 0.778004078788958}, {1, 0, -1, 2, 0.363823969691055, 1.15631976909117}, {1, 0, 0, -1, 0.599070117367796, -0.599070117367796}, {1, 0, 0, 0, 0.000000000000000, 0.000000000000000}, {1, 0, 0, 1, 0.599070117367796, 0.599070117367796}, {1, 0, 0, 2, 0.742646422399778, 1.01005159361958}, {1, 0, 1, -1, 1.04916052873278, -0.478155746088161}, {1, 0, 1, 0, 1.00000000000000, 0.000000000000000}, {1, 0, 1, 1, 1.04916052873278, 0.478155746088161}, {1, 0, 1, 2, 1.13815978557677, 0.897764105638205}, {1, 0, 2, -1, 1.47839688785392, -0.420983902077155}, {1, 0, 2, 0, 1.45679103104691, 0.000000000000000}, {1, 0, 2, 1, 1.47839688785392, 0.420983902077155}, {1, 0, 2, 2, 1.53147158277780, 0.820905313474926}, {1, 1, -1, -1, 0.000000000000000, 0.000000000000000}, {1, 1, -1, 0, -0.188411067988680, 0.778004078788958}, {1, 1, -1, 1, 0.000000000000000, 1.19814023473559}, {1, 1, -1, 2, 0.136827548397369, 1.62780548487271}, {1, 1, 0, -1, 0.778004078788958, -0.188411067988680}, {1, 1, 0, 0, 0.000000000000000, 0.000000000000000}, {1, 1, 0, 1, 0.478155746088161, 1.04916052873278}, {1, 1, 0, 2, 0.571004782644619, 1.52731627482094}, {1, 1, 1, -1, 1.19814023473559, 0.000000000000000}, {1, 1, 1, 0, 1.04916052873278, 0.478155746088161}, {1, 1, 1, 1, 1.00000000000000, 1.00000000000000}, {1, 1, 1, 2, 1.02005412633766, 1.47134936286465}, {1, 1, 2, -1, 1.62780548487271, 0.136827548397369}, {1, 1, 2, 0, 1.52731627482094, 0.571004782644619}, {1, 1, 2, 1, 1.47134936286465, 1.02005412633766}, {1, 1, 2, 2, 1.45679103104691, 1.45679103104691}, {1, 2, -1, -1, -0.574659643809835, 0.810208383866421}, {1, 2, -1, 0, -0.363823969691055, 1.15631976909117}, {1, 2, -1, 1, -0.136827548397369, 1.62780548487271}, {1, 2, -1, 2, 0.000000000000000, 2.11638793788003}, {1, 2, 0, -1, 0.985872907297986, 0.178866979357132}, {1, 2, 0, 0, 0.000000000000000, 0.000000000000000}, {1, 2, 0, 1, 0.420983902077155, 1.47839688785392}, {1, 2, 0, 2, 0.493004461502931, 2.02900451838781}, {1, 2, 1, -1, 1.35980258211696, 0.412918513270561}, {1, 2, 1, 0, 1.13815978557677, 0.897764105638205}, {1, 2, 1, 1, 1.02005412633766, 1.47134936286465}, {1, 2, 1, 2, 1.00000000000000, 2.00000000000000}, {1, 2, 2, -1, 1.79721035210339, 0.599070117367796}, {1, 2, 2, 0, 1.64623191253177, 1.05542091981433}, {1, 2, 2, 1, 1.54030226799894, 1.54030226799894}, {1, 2, 2, 2, 1.48529284479956, 2.02010318723916}, {2, -1, -1, -1, 0.412918513270561, -1.35980258211696}, {2, -1, -1, 0, 0.178866979357132, -0.985872907297986}, {2, -1, -1, 1, 0.810208383866421, 0.574659643809835}, {2, -1, -1, 2, 0.963366302386887, 0.963366302386887}, {2, -1, 0, -1, 0.897764105638205, -1.13815978557677}, {2, -1, 0, 0, 0.000000000000000, 0.000000000000000}, {2, -1, 0, 1, 1.15631976909117, 0.363823969691055}, {2, -1, 0, 2, 1.37110999239961, 0.777111977967075}, {2, -1, 1, -1, 1.47134936286465, -1.02005412633766}, {2, -1, 1, 0, 1.47839688785392, -0.420983902077155}, {2, -1, 1, 1, 1.62780548487271, 0.136827548397369}, {2, -1, 1, 2, 1.79721035210339, 0.599070117367796}, {2, -1, 2, -1, 2.00000000000000, -1.00000000000000}, {2, -1, 2, 0, 2.02900451838781, -0.493004461502931}, {2, -1, 2, 1, 2.11638793788003, 0.000000000000000}, {2, -1, 2, 2, 2.23571522629432, 0.455159607692816}, {2, 0, -1, -1, 0.589593010800278, -0.966415146777638}, {2, 0, -1, 0, 0.422966208408802, 0.661266183461805}, {2, 0, -1, 1, 0.589593010800278, 0.966415146777638}, {2, 0, -1, 2, 0.777111977967075, 1.37110999239961}, {2, 0, 0, -1, 1.01005159361958, -0.742646422399778}, {2, 0, 0, 0, 0.000000000000000, 0.000000000000000}, {2, 0, 0, 1, 1.01005159361958, 0.742646422399778}, {2, 0, 0, 2, 1.19814023473559, 1.19814023473559}, {2, 0, 1, -1, 1.52731627482094, -0.571004782644619}, {2, 0, 1, 0, 1.45679103104691, 0.000000000000000}, {2, 0, 1, 1, 1.52731627482094, 0.571004782644619}, {2, 0, 1, 2, 1.64623191253177, 1.05542091981433}, {2, 0, 2, -1, 2.02900451838781, -0.493004461502931}, {2, 0, 2, 0, 2.00000000000000, 0.000000000000000}, {2, 0, 2, 1, 2.02900451838781, 0.493004461502931}, {2, 0, 2, 2, 2.09832105746556, 0.956311492176322}, {2, 1, -1, -1, 0.810208383866421, -0.574659643809835}, {2, 1, -1, 0, 0.178866979357132, 0.985872907297986}, {2, 1, -1, 1, 0.412918513270561, 1.35980258211696}, {2, 1, -1, 2, 0.599070117367796, 1.79721035210339}, {2, 1, 0, -1, 1.15631976909117, -0.363823969691055}, {2, 1, 0, 0, 0.000000000000000, 0.000000000000000}, {2, 1, 0, 1, 0.897764105638205, 1.13815978557677}, {2, 1, 0, 2, 1.05542091981433, 1.64623191253177}, {2, 1, 1, -1, 1.62780548487271, -0.136827548397369}, {2, 1, 1, 0, 1.47839688785392, 0.420983902077155}, {2, 1, 1, 1, 1.47134936286465, 1.02005412633766}, {2, 1, 1, 2, 1.54030226799894, 1.54030226799894}, {2, 1, 2, -1, 2.11638793788003, 0.000000000000000}, {2, 1, 2, 0, 2.02900451838781, 0.493004461502931}, {2, 1, 2, 1, 2.00000000000000, 1.00000000000000}, {2, 1, 2, 2, 2.02010318723916, 1.48529284479956}, {2, 2, -1, -1, 1.08423239187061, -0.238299975053003}, {2, 2, -1, 0, -0.0126420344317752, 1.32391495927282}, {2, 2, -1, 1, 0.267405171219803, 1.75269801601936}, {2, 2, -1, 2, 0.455159607692816, 2.23571522629432}, {2, 2, 0, -1, 1.32391495927282, -0.0126420344317752}, {2, 2, 0, 0, 0.000000000000000, 0.000000000000000}, {2, 2, 0, 1, 0.820905313474926, 1.53147158277780}, {2, 2, 0, 2, 0.956311492176322, 2.09832105746556}, {2, 2, 1, -1, 1.75269801601936, 0.267405171219803}, {2, 2, 1, 0, 1.53147158277780, 0.820905313474926}, {2, 2, 1, 1, 1.45679103104691, 1.45679103104691}, {2, 2, 1, 2, 1.48529284479956, 2.02010318723916}, {2, 2, 2, -1, 2.23571522629432, 0.455159607692816}, {2, 2, 2, 0, 2.09832105746556, 0.956311492176322}, {2, 2, 2, 1, 2.02010318723916, 1.48529284479956}, {2, 2, 2, 2, 2.00000000000000, 2.00000000000000}, }; int main() { slong iter; flint_rand_t state; flint_printf("agm...."); fflush(stdout); flint_randinit(state); /* test particular values against table */ { acb_t x, y, r, s; acb_init(x); acb_init(y); acb_init(r); acb_init(s); for (iter = 0; iter < NUM_TESTS; iter++) { acb_set_d_d(x, agm_testdata[iter][0], agm_testdata[iter][1]); acb_set_d_d(y, agm_testdata[iter][2], agm_testdata[iter][3]); acb_set_d_d(s, agm_testdata[iter][4], agm_testdata[iter][5]); mag_set_d(arb_radref(acb_realref(s)), 1e-13); mag_set_d(arb_radref(acb_imagref(s)), 1e-13); acb_agm(r, x, y, 64); if (!acb_overlaps(r, s)) { flint_printf("FAIL\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 15); flint_printf("\n\n"); flint_printf("r = "); acb_printd(r, 15); flint_printf("\n\n"); flint_printf("s = "); acb_printd(s, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(x); acb_clear(y); acb_clear(r); acb_clear(s); } /* self-consistency test */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t m1, m2; acb_t x1, x2, y1, y2, t; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); acb_init(x1); acb_init(x2); acb_init(y1); acb_init(y2); acb_init(m1); acb_init(m2); acb_init(t); acb_randtest(x1, state, prec1, 1 + n_randint(state, 100)); acb_randtest(y1, state, prec1, 1 + n_randint(state, 100)); acb_randtest(m1, state, prec1, 1 + n_randint(state, 100)); acb_randtest(m2, state, prec1, 1 + n_randint(state, 100)); if (n_randint(state, 2)) { acb_randtest(t, state, prec2, 1 + n_randint(state, 200)); acb_mul(y1, x1, t, prec1); } if (n_randint(state, 2)) acb_swap(x1, y1); if (n_randint(state, 2)) { acb_set(x2, x1); } else { acb_randtest(t, state, prec2, 1 + n_randint(state, 200)); acb_add(x2, x1, t, prec2); acb_sub(x2, x2, t, prec2); } if (n_randint(state, 2)) { acb_set(y2, y1); } else { acb_randtest(t, state, prec2, 1 + n_randint(state, 200)); acb_add(y2, y1, t, prec2); acb_sub(y2, y2, t, prec2); } acb_agm(m1, x1, y1, prec1); acb_agm(m2, x2, y2, prec2); if (!acb_overlaps(m1, m2)) { flint_printf("FAIL (overlap)\n\n"); flint_printf("iter = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, prec1, prec2); flint_printf("x1 = "); acb_printd(x1, 30); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 30); flint_printf("\n\n"); flint_printf("x2 = "); acb_printd(x2, 30); flint_printf("\n\n"); flint_printf("y2 = "); acb_printd(y2, 30); flint_printf("\n\n"); flint_printf("m1 = "); acb_printd(m1, 30); flint_printf("\n\n"); flint_printf("m2 = "); acb_printd(m2, 30); flint_printf("\n\n"); flint_abort(); } acb_div(t, x1, y1, prec1); if (acb_is_finite(t) && (!acb_is_real(t) || !arb_is_negative(acb_realref(t)))) { if (n_randint(state, 2)) { acb_div(t, x1, y1, prec1); acb_agm1(t, t, prec1); acb_mul(t, t, y1, prec1); } else { acb_div(t, y1, x1, prec1); acb_agm1(t, t, prec1); acb_mul(t, t, x1, prec1); } if (!acb_overlaps(t, m1)) { flint_printf("FAIL (overlap 2)\n\n"); flint_printf("iter = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, prec1, prec2); flint_printf("x1 = "); acb_printd(x1, 30); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 30); flint_printf("\n\n"); flint_printf("m1 = "); acb_printd(m1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } } acb_clear(x1); acb_clear(x2); acb_clear(y1); acb_clear(y2); acb_clear(m1); acb_clear(m2); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-agm1.c000066400000000000000000000154261417376376500153330ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #define EPS 1e-13 #define NUM_DERIVS 4 #define NUM_TESTS 11 const double agm_testdata[NUM_TESTS][10] = { {1.0, 0.0, 1.0, 0.0, 0.5, 0.0, -0.0625, 0.0, 0.03125, 0.0}, {0.25, 0.0, 0.56075714507190064253, 0.0, 0.76633907325304843764, 0.0, -0.58010113691169132987, 0.0, 1.2991960360521313649, 0.0}, {1.0, 1.0, 1.0491605287327802205, 0.47815574608816122933, 0.44643105633549979073, -0.08043578677710866283, -0.015455284495904882924, 0.031976374729700173479, -0.005073437378084728324, -0.010673958729796444985}, {0.0, 1.0, 0.59907011736779610372, 0.59907011736779610372, 0.43640657965245804105, -0.16266353771533806267, 0.031271486774469549792, 0.031271486774469549792, -0.0084910439043492636266, 0.022780442870120286166}, {-1.0, 1.0, 0.18841106798868002055, 0.77800407878895828015, 0.39320630832295102335, -0.19287323123455182026, 0.016808115488846724979, 0.020163502567351546742, -0.011189063384352573532, -0.0045629824424054816356}, {-0.25, 0.0, 0.24392673474953340413, 0.27799893427725564501, 0.079794586546549867566, -0.32574453868033984617, -0.27530931370867131683, -0.60287933825809104112, -0.54714813521966247214, -0.97291617788393560861}, {-2.0, 0.0, -0.42296620840880168736, 0.66126618346180476447, 0.29655367830470777795, -0.27314834694816402295, 0.018331225229748304014, -0.043277191398267359935, 0.0094104572902577354423, -0.021071819981331905571}, {-0.99999994039535522461, 0.0, 0.0069953999943208591971, 0.08334545077423930704, 12454.444757282471906, 73670.447089584396744, -87884330303.90316493, -553342797575.05204396, 909784741818095264.43, 5883796037072491540.4}, {-1.0000000596046447754, 0.0, -0.0069954003670321135601, 0.083345455480285282001, 12454.451634795395449, -73670.529975671147878, 87884324285.574775284, -553342761339.97964199, 909784713383817144.98, -5883795855289758433.3}, {-1.0, 5.9604644775390625e-8, 2.3677293150757997928e-9, 0.083932595219022127005, 75242.17179390509748, -0.041726661532440829443, -18488.306894081923308, 563725525035.34898339, -5988414396610684162.5, -92537341636.835656296}, {-1.0, -5.9604644775390625e-8, 2.3677293150757997928e-9, -0.083932595219022127005, 75242.17179390509748, 0.041726661532440829443, -18488.306894081923308, -563725525035.34898339, -5988414396610684162.5, 92537341636.835656296}, }; int main() { slong iter; flint_rand_t state; flint_printf("agm1...."); fflush(stdout); flint_randinit(state); /* check particular values against table */ { acb_t z, t; acb_ptr w1; slong i, j, prec, cnj; acb_init(z); acb_init(t); w1 = _acb_vec_init(NUM_DERIVS); for (prec = 32; prec <= 512; prec *= 4) { for (i = 0; i < NUM_TESTS; i++) { for (cnj = 0; cnj < 2; cnj++) { if (cnj == 1 && agm_testdata[i][0] < 0 && agm_testdata[i][1] == 0) continue; acb_zero(z); arf_set_d(arb_midref(acb_realref(z)), agm_testdata[i][0]); arf_set_d(arb_midref(acb_imagref(z)), cnj ? -agm_testdata[i][1] : agm_testdata[i][1]); acb_agm1_cpx(w1, z, NUM_DERIVS, prec); for (j = 0; j < NUM_DERIVS; j++) { arf_set_d(arb_midref(acb_realref(t)), agm_testdata[i][2+2*j]); mag_set_d(arb_radref(acb_realref(t)), fabs(agm_testdata[i][2+2*j]) * EPS); arf_set_d(arb_midref(acb_imagref(t)), cnj ? -agm_testdata[i][2+2*j+1] : agm_testdata[i][2+2*j+1]); mag_set_d(arb_radref(acb_imagref(t)), fabs(agm_testdata[i][2+2*j+1]) * EPS); if (!acb_overlaps(w1 + j, t)) { flint_printf("FAIL\n\n"); flint_printf("j = %wd\n\n", j); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 15); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1 + j, 15); flint_printf("\n\n"); flint_abort(); } } } } } _acb_vec_clear(w1, NUM_DERIVS); acb_clear(z); acb_clear(t); } /* self-consistency test */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_ptr m1, m2; acb_t z1, z2, t; slong i, len1, len2, prec1, prec2; len1 = n_randint(state, 10); len2 = n_randint(state, 10); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); m1 = _acb_vec_init(len1); m2 = _acb_vec_init(len2); acb_init(z1); acb_init(z2); acb_init(t); acb_randtest(z1, state, prec1, 1 + n_randint(state, 100)); if (n_randint(state, 2)) { acb_set(z2, z1); } else { acb_randtest(t, state, prec2, 1 + n_randint(state, 100)); acb_add(z2, z1, t, prec2); acb_sub(z2, z2, t, prec2); } acb_agm1_cpx(m1, z1, len1, prec1); acb_agm1_cpx(m2, z2, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(m1 + i, m2 + i)) { flint_printf("FAIL (overlap)\n\n"); flint_printf("iter = %wd, i = %wd, len1 = %wd, len2 = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, i, len1, len2, prec1, prec2); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 30); flint_printf("\n\n"); flint_printf("m1 = "); acb_printd(m1, 30); flint_printf("\n\n"); flint_printf("m2 = "); acb_printd(m2, 30); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(m1, len1); _acb_vec_clear(m2, len2); acb_clear(z1); acb_clear(z2); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-approx_dot.c000066400000000000000000000215121417376376500166560ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" ARB_DLL extern slong acb_dot_gauss_dot_cutoff; int main() { slong iter; flint_rand_t state; flint_printf("approx_dot...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_ptr x, y; acb_t s1, s2, z; slong i, len, prec, xbits, ybits, ebits; int initial, subtract, revx, revy; if (n_randint(state, 100) == 0) len = n_randint(state, 100); else if (n_randint(state, 10) == 0) len = n_randint(state, 10); else len = n_randint(state, 3); acb_dot_gauss_dot_cutoff = 3 + n_randint(state, 30); if (n_randint(state, 10) != 0 || len > 10) { prec = 2 + n_randint(state, 500); xbits = 2 + n_randint(state, 500); ybits = 2 + n_randint(state, 500); } else { prec = 2 + n_randint(state, 4000); xbits = 2 + n_randint(state, 4000); ybits = 2 + n_randint(state, 4000); } if (n_randint(state, 100) == 0) ebits = 2 + n_randint(state, 100); else ebits = 2 + n_randint(state, 10); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _acb_vec_init(len); y = _acb_vec_init(len); acb_init(s1); acb_init(s2); acb_init(z); switch (n_randint(state, 3)) { case 0: for (i = 0; i < len; i++) { acb_randtest(x + i, state, xbits, ebits); acb_randtest(y + i, state, ybits, ebits); } break; /* Test with cancellation */ case 1: for (i = 0; i < len; i++) { if (i <= len / 2) { acb_randtest(x + i, state, xbits, ebits); acb_randtest(y + i, state, ybits, ebits); } else { acb_neg(x + i, x + len - i - 1); acb_set(y + i, y + len - i - 1); } } break; default: for (i = 0; i < len; i++) { if (i <= len / 2) { acb_randtest(x + i, state, xbits, ebits); acb_randtest(y + i, state, ybits, ebits); } else { acb_neg_round(x + i, x + len - i - 1, 2 + n_randint(state, 500)); acb_set_round(y + i, y + len - i - 1, 2 + n_randint(state, 500)); } } break; } acb_randtest(s1, state, 200, 100); acb_randtest(s2, state, 200, 100); acb_randtest(z, state, xbits, ebits); acb_approx_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); mag_zero(arb_radref(acb_realref(s1))); mag_zero(arb_radref(acb_imagref(s1))); /* With the fast algorithm, we expect identical results when reversing the vectors. */ if (ebits <= 12) { acb_approx_dot(s2, initial ? z : NULL, subtract, !revx ? (x + len - 1) : x, !revx ? -1 : 1, !revy ? (y + len - 1) : y, !revy ? -1 : 1, len, prec); mag_zero(arb_radref(acb_realref(s2))); mag_zero(arb_radref(acb_imagref(s2))); if (!acb_equal(s1, s2)) { flint_printf("FAIL (reversal)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } } /* Verify that radii are ignored */ for (i = 0; i < len; i++) { arb_get_mid_arb(acb_realref(x + i), acb_realref(x + i)); arb_get_mid_arb(acb_imagref(x + i), acb_imagref(x + i)); arb_get_mid_arb(acb_realref(y + i), acb_realref(y + i)); arb_get_mid_arb(acb_imagref(y + i), acb_imagref(y + i)); } arb_get_mid_arb(acb_realref(z), acb_realref(z)); arb_get_mid_arb(acb_imagref(z), acb_imagref(z)); acb_approx_dot(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); mag_zero(arb_radref(acb_realref(s2))); mag_zero(arb_radref(acb_imagref(s2))); if (!acb_equal(s1, s2)) { flint_printf("FAIL (radii)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } /* Compare with acb_dot */ acb_approx_dot(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); { mag_t err, xx, yy; mag_init(err); mag_init(xx); mag_init(yy); if (initial) acb_get_mag(err, z); for (i = 0; i < len; i++) { acb_get_mag(xx, revx ? x + len - 1 - i : x + i); acb_get_mag(yy, revx ? y + len - 1 - i : y + i); mag_addmul(err, xx, yy); } mag_mul_2exp_si(err, err, -prec + 2); acb_add_error_mag(s2, err); if (!acb_contains(s2, s1)) { flint_printf("FAIL (inclusion)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } mag_clear(err); mag_clear(xx); mag_clear(yy); } acb_clear(s1); acb_clear(s2); acb_clear(z); _acb_vec_clear(x, len); _acb_vec_clear(y, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-asin.c000066400000000000000000000045041417376376500154330ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("asin...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_asin(a, x, prec1); acb_asin(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check sin(asin(x)) = x */ acb_sin(b, b, prec1); if (!acb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_asin(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-asinh.c000066400000000000000000000045121417376376500156020ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("asinh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_asinh(a, x, prec1); acb_asinh(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check sinh(asinh(x)) = x */ acb_sinh(b, b, prec1); if (!acb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_asinh(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-atan.c000066400000000000000000000045041417376376500154240ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("atan...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_atan(a, x, prec1); acb_atan(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check tan(atan(x)) = x */ acb_tan(b, b, prec1); if (!acb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_atan(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-atanh.c000066400000000000000000000045121417376376500155730ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("atanh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_atanh(a, x, prec1); acb_atanh(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check tanh(atanh(x)) = x */ acb_tanh(b, b, prec1); if (!acb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_atanh(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-barnes_g.c000066400000000000000000000055141417376376500162630ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("barnes_g...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); acb_init(d); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 300), 1 + n_randint(state, 8)); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 300), 1 + n_randint(state, 8)); acb_log_barnes_g(b, a, prec1); if (n_randint(state, 4) == 0) { acb_randtest(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_add(a, a, c, prec1); acb_sub(a, a, c, prec1); } acb_log_barnes_g(c, a, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_barnes_g(d, a, prec1); acb_exp(c, b, prec1); if (!acb_overlaps(c, d)) { flint_printf("FAIL: overlap 2\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } /* check lG(z+1) = lG(z) + lgamma(z) */ acb_lgamma(c, a, prec1); acb_add(b, b, c, prec1); acb_add_ui(c, a, 1, prec1); acb_log_barnes_g(c, c, prec1); if (!acb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-bernoulli_poly_ui.c000066400000000000000000000044061417376376500202350ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("bernoulli_poly_ui...."); fflush(stdout); flint_randinit(state); /* test multiplication theorem */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, t, res1, res2; ulong n, m, k; slong prec; n = n_randint(state, 50); m = 1 + n_randint(state, 5); prec = 2 + n_randint(state, 200); acb_init(x); acb_init(t); acb_init(res1); acb_init(res2); acb_randtest(x, state, 2 + n_randint(state, 200), 20); acb_randtest(res1, state, 2 + n_randint(state, 200), 20); acb_mul_ui(t, x, m, prec); acb_bernoulli_poly_ui(res1, n, t, prec); acb_zero(res2); for (k = 0; k < m; k++) { acb_set_ui(t, k); acb_div_ui(t, t, m, prec); acb_add(t, t, x, prec); acb_bernoulli_poly_ui(t, n, t, prec); acb_add(res2, res2, t, prec); } if (n > 0) { arb_ui_pow_ui(acb_realref(t), m, n - 1, prec); acb_mul_arb(res2, res2, acb_realref(t), prec); } else { acb_div_ui(res2, res2, m, prec); } if (!acb_overlaps(res1, res2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu, m = %wu\n\n", n, m); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 15); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(t); acb_clear(res1); acb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-chebyshev_t_ui.c000066400000000000000000000064221417376376500175020ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("chebyshev_t_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; ulong n; slong prec; n = n_randtest(state); prec = 2 + n_randint(state, 300); acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 300), 5); acb_randtest(c, state, 1 + n_randint(state, 300), 5); acb_cos(b, a, prec); acb_chebyshev_t_ui(c, n, b, prec); acb_mul_ui(d, a, n, prec); acb_cos(d, d, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: c = T_n(cos(a)) = d = cos(n*a)\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("d = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_chebyshev_t_ui(b, n, b, prec); if (!acb_equal(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_randtest(a, state, 1 + n_randint(state, 300), 5); acb_randtest(b, state, 1 + n_randint(state, 300), 5); acb_randtest(c, state, 1 + n_randint(state, 300), 5); acb_chebyshev_t2_ui(b, c, n, a, prec); acb_chebyshev_t_ui(d, n, a, prec); if (!acb_overlaps(b, d)) { flint_printf("FAIL: T_n\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } if (n == 0) acb_set(d, a); else acb_chebyshev_t_ui(d, n - 1, a, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: T_{n-1}\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-chebyshev_u_ui.c000066400000000000000000000073221417376376500175030ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("chebyshev_u_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e; ulong n; slong prec; n = n_randtest(state); prec = 2 + n_randint(state, 300); acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_randtest_precise(a, state, 1 + n_randint(state, 300), 5); acb_randtest_precise(c, state, 1 + n_randint(state, 300), 5); acb_sin_cos(d, b, a, prec); acb_chebyshev_u_ui(c, n, b, prec); acb_mul(d, c, d, prec); if (n == LIMB_ONES) acb_mul_2exp_si(e, a, FLINT_BITS); else acb_mul_ui(e, a, n + 1, prec); acb_sin(e, e, prec); if (!acb_overlaps(d, e)) { flint_printf("FAIL: sin(a)*U_n(cos(a)) = sin((n+1)a)\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 15); flint_printf("\n\n"); flint_printf("e = "); acb_printd(e, 15); flint_printf("\n\n"); flint_abort(); } acb_chebyshev_u_ui(b, n, b, prec); if (!acb_equal(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_randtest(a, state, 1 + n_randint(state, 300), 5); acb_randtest(b, state, 1 + n_randint(state, 300), 5); acb_randtest(c, state, 1 + n_randint(state, 300), 5); acb_chebyshev_u2_ui(b, c, n, a, prec); acb_chebyshev_u_ui(d, n, a, prec); if (!acb_overlaps(b, d)) { flint_printf("FAIL: U_n\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } if (n == 0) acb_zero(d); else acb_chebyshev_u_ui(d, n - 1, a, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: U_{n-1}\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-cos_pi.c000066400000000000000000000046431417376376500157610ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("cos_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_cos_pi(a, x, prec1); acb_cos_pi(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* compare with cos */ arb_const_pi(acb_realref(c), prec1); acb_mul_arb(y, x, acb_realref(c), prec1); acb_cos(c, y, prec1); if (!acb_overlaps(a, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_cos_pi(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-cot.c000066400000000000000000000052551417376376500152720ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("cot...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest(y, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_cot(a, x, prec1); acb_cot(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* check cot(x+y) = (cot(x) cot(y) - 1) / (cot(x) + cot(y)) */ acb_add(b, x, y, prec1); acb_cot(b, b, prec1); acb_cot(c, y, prec1); acb_add(d, a, c, prec1); acb_mul(c, a, c, prec1); acb_sub_ui(c, c, 1, prec1); acb_div(d, c, d, prec1); if (!acb_overlaps(b, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_cot(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-cot_pi.c000066400000000000000000000046441417376376500157630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("cot_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_cot_pi(a, x, prec1); acb_cot_pi(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* compare with cot */ arb_const_pi(acb_realref(c), prec1); acb_mul_arb(y, x, acb_realref(c), prec1); acb_cot(c, y, prec1); if (!acb_overlaps(a, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_cot_pi(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-coth.c000066400000000000000000000052641417376376500154420ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("coth...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(x, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); acb_randtest(y, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); acb_coth(a, x, prec1); acb_coth(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* check coth(x+y) = (1 + coth(x) coth(y)) / (coth(x) + coth(y)) */ acb_add(b, x, y, prec1); acb_coth(b, b, prec1); acb_coth(c, y, prec1); acb_add(d, a, c, prec1); acb_mul(c, a, c, prec1); acb_add_ui(c, c, 1, prec1); acb_div(d, c, d, prec1); if (!acb_overlaps(b, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_coth(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-csc.c000066400000000000000000000034341417376376500152520ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("csc...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 300), 100); acb_randtest_special(a, state, 1 + n_randint(state, 300), 100); acb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { acb_csc(a, x, prec1); } else { acb_set(a, x); acb_csc(a, a, prec1); } acb_sin(b, x, prec2); acb_inv(b, b, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-csc_pi.c000066400000000000000000000035171417376376500157440ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("csc_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 300), 100); acb_randtest_special(a, state, 1 + n_randint(state, 300), 100); acb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { acb_csc_pi(a, x, prec1); } else { acb_set(a, x); acb_csc_pi(a, a, prec1); } acb_sin_pi(b, x, prec2); acb_inv(b, b, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-csch.c000066400000000000000000000034401417376376500154170ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("csch...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 300), 100); acb_randtest_special(a, state, 1 + n_randint(state, 300), 100); acb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { acb_csch(a, x, prec1); } else { acb_set(a, x); acb_csch(a, a, prec1); } acb_sinh(b, x, prec2); acb_inv(b, b, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-csgn.c000066400000000000000000000033111417376376500154260ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("csgn...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y; arb_t a; slong prec; acb_init(x); acb_init(y); arb_init(a); acb_randtest_special(x, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); arb_randtest_special(a, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); prec = 2 + n_randint(state, 200); acb_csgn(a, x); if (acb_is_zero(x)) { acb_zero(y); } else { acb_mul(y, x, x, prec); acb_sqrt(y, y, prec); acb_div(y, y, x, prec); } if (!arb_contains(acb_realref(y), a)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); arb_clear(a); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-digamma.c000066400000000000000000000046641417376376500161070ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("digamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 3); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 3); acb_digamma(b, a, prec1); acb_digamma(c, a, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_set(c, a); acb_digamma(c, c, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } /* check digamma(z+1) = digamma(z) + 1/z */ acb_inv(c, a, prec1); acb_add(b, b, c, prec1); acb_add_ui(c, a, 1, prec1); acb_digamma(c, c, prec1); if (!acb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-div.c000066400000000000000000000133411417376376500152620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("div...."); fflush(stdout); flint_randinit(state); /* test aliasing of c and a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_div(c, a, b, prec); acb_div(a, a, b, prec); if (!acb_equal(a, c)) { flint_printf("FAIL: aliasing c, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing of c and b */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_div(c, a, b, prec); acb_div(b, a, b, prec); if (!acb_equal(b, c)) { flint_printf("FAIL: aliasing c, b\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_div(c, a, a, prec); acb_div(d, a, b, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } /* test aliasing a, a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_div(c, a, b, prec); acb_div(a, a, a, prec); if (!acb_overlaps(a, c)) { flint_printf("FAIL: aliasing a, a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test (a+b)/c = a/c + b/c */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e, f; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_init(f); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); acb_add(d, a, b, 2 + n_randint(state, 200)); acb_div(e, d, c, 2 + n_randint(state, 200)); acb_div(d, a, c, 2 + n_randint(state, 200)); acb_div(f, b, c, 2 + n_randint(state, 200)); acb_add(f, d, f, 2 + n_randint(state, 200)); if (!acb_overlaps(e, f)) { flint_printf("FAIL: (a+b)/c = a/c + b/c\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("e = "); acb_print(e); flint_printf("\n\n"); flint_printf("f = "); acb_print(f); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-dot.c000066400000000000000000000147011417376376500152670ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" ARB_DLL extern slong acb_dot_gauss_dot_cutoff; int main() { slong iter; flint_rand_t state; flint_printf("dot...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { acb_ptr x, y; acb_t s1, s2, z; slong i, len, prec, xbits, ybits, ebits; int ok, initial, subtract, revx, revy; if (n_randint(state, 100) == 0) len = n_randint(state, 50); else if (n_randint(state, 10) == 0) len = n_randint(state, 5); else len = n_randint(state, 3); acb_dot_gauss_dot_cutoff = 3 + n_randint(state, 30); if (n_randint(state, 10) != 0 || len > 10) { prec = 2 + n_randint(state, 500); xbits = 2 + n_randint(state, 500); ybits = 2 + n_randint(state, 500); } else { prec = 2 + n_randint(state, 5000); xbits = 2 + n_randint(state, 5000); ybits = 2 + n_randint(state, 5000); } if (n_randint(state, 100) == 0) ebits = 2 + n_randint(state, 100); else ebits = 2 + n_randint(state, 10); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _acb_vec_init(len); y = _acb_vec_init(len); acb_init(s1); acb_init(s2); acb_init(z); switch (n_randint(state, 3)) { case 0: for (i = 0; i < len; i++) { acb_randtest(x + i, state, xbits, ebits); acb_randtest(y + i, state, ybits, ebits); } break; /* Test with cancellation */ case 1: for (i = 0; i < len; i++) { if (i <= len / 2) { acb_randtest(x + i, state, xbits, ebits); acb_randtest(y + i, state, ybits, ebits); } else { acb_neg(x + i, x + len - i - 1); acb_set(y + i, y + len - i - 1); } } break; default: for (i = 0; i < len; i++) { if (i <= len / 2) { acb_randtest(x + i, state, xbits, ebits); acb_randtest(y + i, state, ybits, ebits); } else { acb_neg_round(x + i, x + len - i - 1, 2 + n_randint(state, 500)); acb_set_round(y + i, y + len - i - 1, 2 + n_randint(state, 500)); } } break; } acb_randtest(s1, state, 200, 100); acb_randtest(s2, state, 200, 100); acb_randtest(z, state, xbits, ebits); acb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); acb_dot_precise(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, ebits <= 12 ? ARF_PREC_EXACT : 2 * prec + 100); if (ebits <= 12) ok = acb_contains(s1, s2); else ok = acb_overlaps(s1, s2); if (!ok) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd, subtract = %d\n\n", iter, len, prec, ebits, subtract); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } /* With the fast algorithm, we expect identical results when reversing the vectors. */ if (ebits <= 12) { revx ^= 1; revy ^= 1; acb_dot(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); if (!acb_equal(s1, s2)) { flint_printf("FAIL (reversal)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } } acb_clear(s1); acb_clear(s2); acb_clear(z); _acb_vec_clear(x, len); _acb_vec_clear(y, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-dot_fmpz.c000066400000000000000000000057571417376376500163360ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_siui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_ptr x, y; fmpz * w; acb_t s1, s2, z; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _acb_vec_init(len); y = _acb_vec_init(len); w = _fmpz_vec_init(len); acb_init(s1); acb_init(s2); acb_init(z); for (i = 0; i < len; i++) { acb_randtest(x + i, state, 2 + n_randint(state, 200), 10); fmpz_randtest(w + i, state, 1 + n_randint(state, 200)); acb_set_fmpz(y + i, w + i); } acb_randtest(s1, state, 200, 10); acb_randtest(s2, state, 200, 10); acb_randtest(z, state, 200, 10); acb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); acb_dot_fmpz(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + len - 1) : w, revy ? -1 : 1, len, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z); _acb_vec_clear(x, len); _acb_vec_clear(y, len); _fmpz_vec_clear(w, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-dot_si.c000066400000000000000000000057141417376376500157660ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_ptr x, y; slong * w; acb_t s1, s2, z; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _acb_vec_init(len); y = _acb_vec_init(len); w = flint_malloc(sizeof(ulong) * len); acb_init(s1); acb_init(s2); acb_init(z); for (i = 0; i < len; i++) { acb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[i] = n_randtest(state); acb_set_si(y + i, w[i]); } acb_randtest(s1, state, 200, 10); acb_randtest(s2, state, 200, 10); acb_randtest(z, state, 200, 10); acb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); acb_dot_si(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + len - 1) : w, revy ? -1 : 1, len, prec); if (!acb_equal(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z); _acb_vec_clear(x, len); _acb_vec_clear(y, len); flint_free(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-dot_siui.c000066400000000000000000000062101417376376500163140ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_siui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_ptr x, y; ulong * w; acb_t s1, s2, z; fmpz_t c; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _acb_vec_init(len); y = _acb_vec_init(len); w = flint_malloc(2 * sizeof(ulong) * len); acb_init(s1); acb_init(s2); acb_init(z); fmpz_init(c); for (i = 0; i < len; i++) { acb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[2 * i] = n_randtest(state); w[2 * i + 1] = n_randtest(state); fmpz_set_signed_uiui(c, w[2 * i + 1], w[2 * i]); acb_set_fmpz(y + i, c); } acb_randtest(s1, state, 200, 10); acb_randtest(s2, state, 200, 10); acb_randtest(z, state, 200, 10); acb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); acb_dot_siui(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + 2 * len - 2) : w, revy ? -1 : 1, len, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z); _acb_vec_clear(x, len); _acb_vec_clear(y, len); flint_free(w); fmpz_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-dot_ui.c000066400000000000000000000057141417376376500157700ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_ptr x, y; ulong * w; acb_t s1, s2, z; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _acb_vec_init(len); y = _acb_vec_init(len); w = flint_malloc(sizeof(ulong) * len); acb_init(s1); acb_init(s2); acb_init(z); for (i = 0; i < len; i++) { acb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[i] = n_randtest(state); acb_set_ui(y + i, w[i]); } acb_randtest(s1, state, 200, 10); acb_randtest(s2, state, 200, 10); acb_randtest(z, state, 200, 10); acb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); acb_dot_ui(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + len - 1) : w, revy ? -1 : 1, len, prec); if (!acb_equal(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z); _acb_vec_clear(x, len); _acb_vec_clear(y, len); flint_free(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-dot_uiui.c000066400000000000000000000062011417376376500163160ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_uiui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_ptr x, y; ulong * w; acb_t s1, s2, z; fmpz_t c; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _acb_vec_init(len); y = _acb_vec_init(len); w = flint_malloc(2 * sizeof(ulong) * len); acb_init(s1); acb_init(s2); acb_init(z); fmpz_init(c); for (i = 0; i < len; i++) { acb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[2 * i] = n_randtest(state); w[2 * i + 1] = n_randtest(state); fmpz_set_uiui(c, w[2 * i + 1], w[2 * i]); acb_set_fmpz(y + i, c); } acb_randtest(s1, state, 200, 10); acb_randtest(s2, state, 200, 10); acb_randtest(z, state, 200, 10); acb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); acb_dot_uiui(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + 2 * len - 2) : w, revy ? -1 : 1, len, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); acb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", acb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); acb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(x + i)); flint_printf("y[%wd] = ", i); acb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", acb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z); _acb_vec_clear(x, len); _acb_vec_clear(y, len); flint_free(w); fmpz_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-exp.c000066400000000000000000000034221417376376500152730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("exp...."); fflush(stdout); flint_randinit(state); /* check exp(a+b) = exp(a)*exp(b) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); acb_randtest(c, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_add(c, a, b, prec); acb_exp(c, c, prec); acb_exp(d, a, prec); acb_exp(e, b, prec); acb_mul(d, d, e, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-exp_invexp.c000066400000000000000000000030501417376376500166610ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_invexp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); acb_randtest(c, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_exp_invexp(b, c, a, prec); acb_mul(b, b, c, prec); acb_one(c); if (!acb_contains(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-exp_pi_i.c000066400000000000000000000043501417376376500162740ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_pi_i...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); acb_randtest(c, state, 1 + n_randint(state, 200), 3); acb_randtest(d, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_exp_pi_i(b, a, prec); acb_const_pi(c, prec); acb_mul(c, c, a, prec); acb_mul_onei(c, c); acb_exp(d, c, prec); if (!acb_overlaps(d, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 30); flint_printf("\n\n"); flint_abort(); } acb_set(c, a); acb_exp_pi_i(c, c, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-expm1.c000066400000000000000000000042711417376376500155340ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("expm1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_expm1(a, x, prec1); acb_set(b, x); /* also test aliasing */ acb_expm1(b, b, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check expm1(x) = exp(x)-1 */ acb_exp(b, x, prec2); acb_sub_ui(b, b, 1, prec2); if (!acb_overlaps(a, b)) { flint_printf("FAIL: expm1 vs exp\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-gamma.c000066400000000000000000000037731417376376500155720ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 3); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 3); acb_gamma(b, a, prec1); acb_gamma(c, a, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } /* check gamma(z+1) = z gamma(z) */ acb_mul(b, b, a, prec1); acb_add_ui(c, a, 1, prec1); acb_gamma(c, c, prec1); if (!acb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-get_abs_lbound_arf.c000066400000000000000000000032411417376376500202750ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_abs_lbound_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a; arf_t m, m2, x, y, s; acb_init(a); arf_init(m); arf_init(m2); arf_init(x); arf_init(y); arf_init(s); acb_randtest_special(a, state, 200, 10); acb_get_abs_lbound_arf(m, a, 2 + n_randint(state, 100)); /* check m^2 <= x^2 + y^2 */ arf_mul(m2, m, m, ARF_PREC_EXACT, ARF_RND_DOWN); arb_get_abs_lbound_arf(x, acb_realref(a), ARF_PREC_EXACT); arb_get_abs_lbound_arf(y, acb_imagref(a), ARF_PREC_EXACT); arf_sosq(s, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); if (arf_cmp(m2, s) > 0) { flint_printf("FAIL:\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("m = "); arf_print(m); flint_printf("\n\n"); flint_abort(); } acb_clear(a); arf_clear(m); arf_clear(m2); arf_clear(x); arf_clear(y); arf_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-get_abs_ubound_arf.c000066400000000000000000000032411417376376500203060ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_abs_ubound_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a; arf_t m, m2, x, y, s; acb_init(a); arf_init(m); arf_init(m2); arf_init(x); arf_init(y); arf_init(s); acb_randtest_special(a, state, 200, 10); acb_get_abs_ubound_arf(m, a, 2 + n_randint(state, 100)); /* check m^2 >= x^2 + y^2 */ arf_mul(m2, m, m, ARF_PREC_EXACT, ARF_RND_DOWN); arb_get_abs_ubound_arf(x, acb_realref(a), ARF_PREC_EXACT); arb_get_abs_ubound_arf(y, acb_imagref(a), ARF_PREC_EXACT); arf_sosq(s, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); if (arf_cmp(m2, s) < 0) { flint_printf("FAIL:\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("m = "); arf_print(m); flint_printf("\n\n"); flint_abort(); } acb_clear(a); arf_clear(m); arf_clear(m2); arf_clear(x); arf_clear(y); arf_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-get_mag.c000066400000000000000000000032661417376376500161100ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mag...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a; arf_t m2, x, y, s; mag_t m; acb_init(a); mag_init(m); arf_init(m2); arf_init(x); arf_init(y); arf_init(s); acb_randtest_special(a, state, 200, 10); acb_get_mag(m, a); MAG_CHECK_BITS(m) /* check m^2 >= x^2 + y^2 */ arf_set_mag(m2, m); arf_mul(m2, m2, m2, ARF_PREC_EXACT, ARF_RND_DOWN); arb_get_abs_ubound_arf(x, acb_realref(a), ARF_PREC_EXACT); arb_get_abs_ubound_arf(y, acb_imagref(a), ARF_PREC_EXACT); arf_sosq(s, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); if (arf_cmp(m2, s) < 0) { flint_printf("FAIL:\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("m = "); mag_print(m); flint_printf("\n\n"); flint_abort(); } acb_clear(a); mag_clear(m); arf_clear(m2); arf_clear(x); arf_clear(y); arf_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-get_mag_lower.c000066400000000000000000000033021417376376500173070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mag_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a; arf_t m2, x, y, s; mag_t m; acb_init(a); mag_init(m); arf_init(m2); arf_init(x); arf_init(y); arf_init(s); acb_randtest_special(a, state, 200, 10); acb_get_mag_lower(m, a); MAG_CHECK_BITS(m) /* check m^2 <= x^2 + y^2 */ arf_set_mag(m2, m); arf_mul(m2, m2, m2, ARF_PREC_EXACT, ARF_RND_DOWN); arb_get_abs_lbound_arf(x, acb_realref(a), ARF_PREC_EXACT); arb_get_abs_lbound_arf(y, acb_imagref(a), ARF_PREC_EXACT); arf_sosq(s, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); if (arf_cmp(m2, s) > 0) { flint_printf("FAIL:\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("m = "); mag_print(m); flint_printf("\n\n"); flint_abort(); } acb_clear(a); mag_clear(m); arf_clear(m2); arf_clear(x); arf_clear(y); arf_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-inv.c000066400000000000000000000073471417376376500153050ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void acb_inv_naive(acb_t z, const acb_t x, slong prec) { #define a acb_realref(x) #define b acb_imagref(x) #define c acb_realref(z) #define d acb_imagref(z) if (arb_is_zero(b)) { arb_inv(c, a, prec); arb_zero(d); } else if (arb_is_zero(a)) { arb_inv(d, b, prec); arb_neg(d, d); arb_zero(c); } else { arb_t t; arb_init(t); arb_mul(t, a, a, prec); arb_addmul(t, b, b, prec); arb_div(c, a, t, prec); arb_div(d, b, t, prec); arb_neg(d, d); arb_clear(t); } #undef a #undef b #undef c #undef d } int main() { slong iter; flint_rand_t state; flint_printf("inv...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e, f; arf_t t; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_init(f); arf_init(t); prec = 2 + n_randint(state, 1000); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 100); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 100); acb_inv(b, a, prec); acb_inv_naive(c, a, prec); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_abort(); } acb_set(c, a); acb_inv(c, c, prec); if (!acb_equal(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_abort(); } acb_randtest(a, state, 1 + n_randint(state, 1000), 10); acb_randtest(b, state, 1 + n_randint(state, 1000), 10); acb_zero(d); arf_set_mag(t, arb_radref(acb_realref(a))); if (n_randint(state, 2)) arf_neg(t, t); arf_add(arb_midref(acb_realref(d)), arb_midref(acb_realref(a)), t, ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_mag(t, arb_radref(acb_imagref(a))); if (n_randint(state, 2)) arf_neg(t, t); arf_add(arb_midref(acb_imagref(d)), arb_midref(acb_imagref(a)), t, ARF_PREC_EXACT, ARF_RND_DOWN); acb_inv(b, a, 2 + n_randint(state, 1000)); acb_inv(d, d, 2 + n_randint(state, 1000)); if (!acb_overlaps(b, d)) { flint_printf("FAIL: corner test\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); arf_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-lambertw.c000066400000000000000000000125301417376376500163140ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("lambertw...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x1, x2, t, w1, w2; slong prec1, prec2, ebits; int flags; fmpz_t k; acb_init(x1); acb_init(x2); acb_init(t); acb_init(w1); acb_init(w2); fmpz_init(k); if (n_randint(state, 4) == 0) { prec1 = 2 + n_randint(state, 3000); prec2 = 2 + n_randint(state, 3000); ebits = 1 + n_randint(state, 1000); } else { prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 50); } acb_randtest(x1, state, 1 + n_randint(state, 1000), ebits); acb_randtest(x2, state, 1 + n_randint(state, 1000), ebits); acb_randtest(t, state, 1 + n_randint(state, 1000), ebits); acb_randtest(w1, state, 1 + n_randint(state, 1000), ebits); acb_randtest(w2, state, 1 + n_randint(state, 1000), ebits); fmpz_randtest(k, state, ebits); flags = 0; switch (n_randint(state, 10)) { case 0: flags = ACB_LAMBERTW_LEFT; break; case 1: flags = ACB_LAMBERTW_MIDDLE; fmpz_set_si(k, -1); break; default: break; } if (n_randint(state, 4) == 0) { arb_const_e(acb_realref(t), 2 * prec1); arb_inv(acb_realref(t), acb_realref(t), 2 * prec1); arb_sub(acb_realref(x1), acb_realref(x1), acb_realref(t), 2 * prec1); } if (n_randint(state, 2)) { acb_set(x2, x1); } else { acb_add(x2, x1, t, 2 * prec1); acb_sub(x2, x2, t, 2 * prec1); } if (n_randint(state, 4) == 0 && flags == 0) acb_lambertw_asymp(w1, x1, k, 1 + n_randint(state, 10), 1 + n_randint(state, 10), prec1); else acb_lambertw(w1, x1, k, flags, prec1); if (n_randint(state, 2)) { acb_set(w2, x2); acb_lambertw(w2, w2, k, flags, prec1); } else { acb_lambertw(w2, x2, k, flags, prec1); } if (!acb_overlaps(w1, w2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter %wd, flags = %d, branch = ", flags, iter); fmpz_print(k); flint_printf(" prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); acb_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); acb_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 50); flint_printf("\n\n"); flint_abort(); } acb_exp(t, w1, prec1); acb_mul(t, t, w1, prec1); if (!acb_contains(t, x1)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("iter %wd, flags = %d, branch = ", flags, iter); fmpz_print(k); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); acb_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); acb_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 50); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 50); flint_printf("\n\n"); flint_abort(); } if (!arb_contains_zero(acb_imagref(x1))) { acb_conj(x2, x1); fmpz_neg(k, k); if (flags == 2) fmpz_sub_ui(k, k, 1); acb_lambertw(w2, x2, k, flags, prec2); if (flags == 2) fmpz_add_ui(k, k, 1); fmpz_neg(k, k); acb_conj(w2, w2); if (!acb_overlaps(w1, w2)) { flint_printf("FAIL: conjugation\n\n"); flint_printf("iter %wd, flags = %d, branch = ", flags, iter); fmpz_print(k); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); acb_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); acb_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 50); flint_printf("\n\n"); flint_abort(); } } acb_clear(x1); acb_clear(x2); acb_clear(t); acb_clear(w1); acb_clear(w2); fmpz_clear(k); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-lgamma.c000066400000000000000000000044651417376376500157450ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("lgamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 500); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_lgamma(b, a, prec1); if (n_randint(state, 4) == 0) { acb_randtest(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_add(a, a, c, prec1); acb_sub(a, a, c, prec1); } acb_lgamma(c, a, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } /* check lgamma(z+1) = lgamma(z) + log(z) */ acb_log(c, a, prec1); acb_add(b, b, c, prec1); acb_add_ui(c, a, 1, prec1); acb_lgamma(c, c, prec1); if (!acb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-log.c000066400000000000000000000161421417376376500152630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" /* old acb_log code for comparison */ static int close_to_one(const acb_t z) { mp_limb_t top; if (arf_abs_bound_lt_2exp_si(arb_midref(acb_imagref(z))) > -3) return 0; if (ARF_EXP(arb_midref(acb_realref(z))) == 0) { ARF_GET_TOP_LIMB(top, arb_midref(acb_realref(z))); return (top >> (FLINT_BITS - 4)) == 15; } else if (ARF_EXP(arb_midref(acb_realref(z))) == 1) { ARF_GET_TOP_LIMB(top, arb_midref(acb_realref(z))); return (top >> (FLINT_BITS - 4)) == 8; } return 0; } void acb_log_old(acb_t r, const acb_t z, slong prec) { #define a acb_realref(z) #define b acb_imagref(z) if (arb_is_zero(b)) { if (arb_is_positive(a)) { arb_log(acb_realref(r), a, prec); arb_zero(acb_imagref(r)); } else if (arb_is_negative(a)) { arb_neg(acb_realref(r), a); arb_log(acb_realref(r), acb_realref(r), prec); arb_const_pi(acb_imagref(r), prec); } else { acb_indeterminate(r); } } else if (arb_is_zero(a)) { if (arb_is_positive(b)) { arb_log(acb_realref(r), b, prec); arb_const_pi(acb_imagref(r), prec); arb_mul_2exp_si(acb_imagref(r), acb_imagref(r), -1); } else if (arb_is_negative(b)) { arb_neg(acb_realref(r), b); arb_log(acb_realref(r), acb_realref(r), prec); arb_const_pi(acb_imagref(r), prec); arb_mul_2exp_si(acb_imagref(r), acb_imagref(r), -1); arb_neg(acb_imagref(r), acb_imagref(r)); } else { acb_indeterminate(r); } } else { arb_t t, u; arb_init(t); arb_init(u); if (close_to_one(z)) { arb_sub_ui(u, a, 1, prec + 8); arb_mul(t, u, u, prec + 8); arb_addmul(t, b, b, prec + 8); arb_mul_2exp_si(u, u, 1); arb_add(t, t, u, prec + 8); arb_log1p(t, t, prec); arb_mul_2exp_si(t, t, -1); } else { arb_mul(t, a, a, prec + 8); arb_addmul(t, b, b, prec + 8); if (arb_contains_zero(t) || arf_sgn(arb_midref(t)) < 0) arb_zero_pm_inf(t); else arb_log(t, t, prec); arb_mul_2exp_si(t, t, -1); } acb_arg(u, z, prec); arb_swap(acb_realref(r), t); arb_swap(acb_imagref(r), u); arb_clear(t); arb_clear(u); } if (!acb_is_finite(r)) acb_indeterminate(r); #undef a #undef b } int main() { slong iter; flint_rand_t state; flint_printf("log...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, a, b, d; slong prec1, prec2, acc1, acc2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_init(d); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); if (n_randint(state, 2)) { acb_log(a, x, prec1); } else { acb_set(a, x); /* test aliasing */ acb_log(a, a, prec1); } if (n_randint(state, 2)) { acb_log(b, x, prec2); } else { acb_set(b, x); /* test aliasing */ acb_log(b, b, prec2); } /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } if (!acb_contains_zero(x) && acb_is_finite(x) && !acb_is_finite(a)) { flint_printf("FAIL: not finite\n\n"); flint_printf("prec1 = %wd\n\n", prec1); flint_printf("x = "); acb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_abort(); } /* check exp(log(x)) = x */ acb_exp(b, b, prec1); if (!acb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_log_old(d, x, prec1); /* check consistency */ if (!acb_overlaps(a, d)) { flint_printf("FAIL: overlap 2\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* compare accuracy with log_old */ acc1 = arb_rel_accuracy_bits(acb_realref(a)); acc2 = arb_rel_accuracy_bits(acb_realref(d)); if (acc2 > 0 && acc1 < acc2 - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd, acc2 = %wd\n\n", prec1, acc1, acc2); flint_printf("x = "); acb_printd(x, 50); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 50); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(acb_imagref(a)); acc2 = arb_rel_accuracy_bits(acb_imagref(d)); if (acc2 > 0 && acc1 < acc2 - 2) { flint_printf("FAIL: accuracy 2\n\n"); flint_printf("prec1 = %wd, acc1 = %wd, acc2 = %wd\n\n", prec1, acc1, acc2); flint_printf("x = "); acb_printd(x, 50); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 50); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-log1p.c000066400000000000000000000047031417376376500155240ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("log1p...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_log1p(a, x, prec1); acb_log1p(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check log1p(x) = log(1+x) */ acb_add_ui(b, x, 1, prec2); acb_log(b, b, prec2); if (!acb_overlaps(a, b)) { flint_printf("FAIL: log1p vs log\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_log1p(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-log_sin_pi.c000066400000000000000000000043471417376376500166300ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("log_sin_pi...."); fflush(stdout); flint_randinit(state); /* check functional equation S(s+1) = S(s) + log(-s) - log(s) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t s, s1, r, r1, t; slong prec; acb_init(s); acb_init(s1); acb_init(r); acb_init(r1); acb_init(t); prec = 2 + n_randint(state, 500); acb_randtest(s, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); acb_randtest(r, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); acb_randtest(r1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); acb_log_sin_pi(r, s, prec); acb_add_ui(s1, s, 1, prec); if (n_randint(state, 4) == 0) { acb_randtest(t, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_add(s1, s1, t, prec); acb_sub(s1, s1, t, prec); } acb_log_sin_pi(r1, s1, prec); acb_log(t, s, prec); acb_sub(r, r, t, prec); acb_neg(t, s); acb_log(t, t, prec); acb_add(r, r, t, prec); if (!acb_overlaps(r, r1)) { flint_printf("FAIL: overlap\n\n"); flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n"); flint_printf("s1 = "); acb_printd(s1, 30); flint_printf("\n\n"); flint_printf("r = "); acb_printd(r, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(s); acb_clear(s1); acb_clear(r); acb_clear(r1); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-mul.c000066400000000000000000000221311417376376500152720ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); /* test aliasing of c and a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_mul(c, a, b, prec); acb_mul(a, a, b, prec); if (!acb_equal(a, c)) { flint_printf("FAIL: aliasing c, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing of c and b */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_mul(c, a, b, prec); acb_mul(b, a, b, prec); if (!acb_equal(b, c)) { flint_printf("FAIL: aliasing b, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_mul(c, a, a, prec); acb_mul(d, a, b, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } /* test aliasing a, a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_mul(c, a, b, prec); acb_mul(a, a, a, prec); if (!acb_overlaps(a, c)) { flint_printf("FAIL: aliasing a, a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test a*(b+c) = a*b + a*c */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e, f; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_init(f); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); acb_add(d, b, c, 2 + n_randint(state, 200)); acb_mul(e, a, d, 2 + n_randint(state, 200)); acb_mul(d, a, b, 2 + n_randint(state, 200)); acb_mul(f, a, c, 2 + n_randint(state, 200)); acb_add(f, d, f, 2 + n_randint(state, 200)); if (!acb_overlaps(e, f)) { flint_printf("FAIL: a*(b+c) = a*b + a*c\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("e = "); acb_print(e); flint_printf("\n\n"); flint_printf("f = "); acb_print(f); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); } /* compare with mul_naive */ /* main test */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, z, v; slong prec; acb_init(x); acb_init(y); acb_init(z); acb_init(v); for (iter2 = 0; iter2 < 100; iter2++) { acb_randtest_special(x, state, n_randint(state,2) ? 2000 : 200, 200); acb_randtest_special(y, state, n_randint(state,2) ? 2000 : 200, 200); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 5)) { case 0: acb_mul(z, x, y, prec); acb_mul_naive(v, x, y, prec); if (!acb_overlaps(z, v)) { flint_printf("FAIL!\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_printf("v = "); acb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 1: acb_set(y, x); acb_mul(z, x, y, prec); acb_mul(v, x, x, prec); if (!acb_overlaps(z, v)) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_printf("v = "); acb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 2: acb_mul(v, x, x, prec); acb_mul(x, x, x, prec); if (!acb_equal(v, x)) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_printf("v = "); acb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 3: acb_mul(v, x, y, prec); acb_mul(x, x, y, prec); if (!acb_equal(v, x)) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("v = "); acb_print(v); flint_printf("\n\n"); flint_abort(); } break; default: acb_mul(v, x, y, prec); acb_mul(x, y, x, prec); if (!acb_overlaps(v, x)) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("v = "); acb_print(v); flint_printf("\n\n"); flint_abort(); } break; } } acb_clear(x); acb_clear(y); acb_clear(z); acb_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-mul_naive.c000066400000000000000000000134511417376376500164610ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_naive...."); fflush(stdout); flint_randinit(state); /* test aliasing of c and a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_mul_naive(c, a, b, prec); acb_mul_naive(a, a, b, prec); if (!acb_equal(a, c)) { flint_printf("FAIL: aliasing c, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing of c and b */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_mul_naive(c, a, b, prec); acb_mul_naive(b, a, b, prec); if (!acb_equal(b, c)) { flint_printf("FAIL: aliasing b, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_mul_naive(c, a, a, prec); acb_mul_naive(d, a, b, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } /* test aliasing a, a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_mul_naive(c, a, b, prec); acb_mul_naive(a, a, a, prec); if (!acb_overlaps(a, c)) { flint_printf("FAIL: aliasing a, a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test a*(b+c) = a*b + a*c */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e, f; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_init(f); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); acb_add(d, b, c, 2 + n_randint(state, 200)); acb_mul_naive(e, a, d, 2 + n_randint(state, 200)); acb_mul_naive(d, a, b, 2 + n_randint(state, 200)); acb_mul_naive(f, a, c, 2 + n_randint(state, 200)); acb_add(f, d, f, 2 + n_randint(state, 200)); if (!acb_overlaps(e, f)) { flint_printf("FAIL: a*(b+c) = a*b + a*c\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("e = "); acb_print(e); flint_printf("\n\n"); flint_printf("f = "); acb_print(f); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-polygamma.c000066400000000000000000000055051417376376500164710ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static const char *testdata[5] = { "-0.2487544770337842625472529935761139760973697136685351169998556396906930329999105060928584336658420889 +/- 1e-90", "-0.9189385332046727417803297364056176398613974736377834128171515404827656959272603976947432986359541976 +/- 1e-90", "-0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495 +/- 1e-90", "1.644934066848226436472415166646025189218949901206798437735558229370007470403200873833628900619758705 +/- 1e-90", "-2.404113806319188570799476323022899981529972584680997763584543110683676411572626180372911747218670516 +/- 1e-90", }; int main() { slong iter; flint_rand_t state; flint_printf("polygamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, s, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 500); prec2 = prec1 + 30; acb_init(a); acb_init(s); acb_init(b); acb_init(c); if (iter < 200) { slong i = n_randint(state, 5); acb_set_si(s, -2 + i); acb_one(a); acb_randtest(c, state, 1 + n_randint(state, 500), 3); acb_add(s, s, c, prec2); acb_sub(s, s, c, prec2); acb_polygamma(b, s, a, prec1); acb_zero(c); arb_set_str(acb_realref(c), testdata[i], prec2); } else { acb_randtest(a, state, 1 + n_randint(state, 500), 3); acb_randtest(s, state, 1 + n_randint(state, 500), 3); acb_polygamma(b, s, a, prec1); acb_randtest(c, state, 1 + n_randint(state, 500), 3); acb_add(s, s, c, prec2); acb_sub(s, s, c, prec2); acb_polygamma(c, s, a, prec2); } if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("s = "); acb_print(s); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(s); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-pow.c000066400000000000000000000071341417376376500153100ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("pow...."); fflush(stdout); flint_randinit(state); /* check large arguments */ for (iter = 0; iter < 20000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e, f; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_init(f); acb_randtest(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); if (n_randint(state, 4) == 0) arb_zero(acb_imagref(a)); acb_randtest(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); if (n_randint(state, 4) == 0) arb_zero(acb_imagref(b)); acb_pow(c, a, b, prec1); acb_pow(d, a, b, prec2); if (!acb_overlaps(c, d)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_randtest(c, state, 1 + n_randint(state, 1000), 200); /* check a^(b+c) = a^b*a^c */ acb_add(e, b, c, prec1); acb_pow(d, a, e, prec1); acb_pow(e, a, b, prec1); acb_pow(f, a, c, prec1); acb_mul(e, e, f, prec1); if (!acb_overlaps(d, e)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_printf("e = "); acb_print(e); flint_printf("\n\n"); flint_abort(); } acb_pow(c, a, b, prec1); acb_set(d, a); acb_pow(d, d, b, prec2); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing 1\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_set(d, b); acb_pow(d, a, d, prec2); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing 2\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-pow_fmpz.c000066400000000000000000000051201417376376500163350ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; fmpz_t e1, e2, e3; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); acb_init(d); fmpz_init(e1); fmpz_init(e2); fmpz_init(e3); acb_randtest(a, state, 1 + n_randint(state, 1000), 200); acb_randtest(b, state, 1 + n_randint(state, 1000), 200); fmpz_randtest(e1, state, 200); fmpz_randtest(e2, state, 200); acb_pow_fmpz(b, a, e1, prec1); acb_pow_fmpz(c, a, e1, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("e1 = "); fmpz_print(e1); flint_printf("\n\n"); flint_abort(); } /* check a^(e1+e2) = a^e1*a^e2 */ acb_pow_fmpz(c, a, e2, prec1); acb_mul(d, b, c, prec1); fmpz_add(e3, e1, e2); acb_pow_fmpz(c, a, e3, prec1); if (!acb_overlaps(c, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_printf("e1 = "); fmpz_print(e1); flint_printf("\n\n"); flint_printf("e2 = "); fmpz_print(e2); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); fmpz_clear(e1); fmpz_clear(e2); fmpz_clear(e3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-quadratic_roots_fmpz.c000066400000000000000000000050221417376376500207340ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("quadratic_roots_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t r1, r2, x, y; fmpz_t a, b, c; slong prec; fmpz_init(a); fmpz_init(b); fmpz_init(c); acb_init(r1); acb_init(r2); acb_init(x); acb_init(y); prec = 2 + n_randint(state, 1000); fmpz_randtest_not_zero(a, state, 1 + n_randint(state, 1000)); fmpz_randtest(b, state, 1 + n_randint(state, 1000)); fmpz_randtest(c, state, 1 + n_randint(state, 1000)); acb_randtest(r1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(r2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_quadratic_roots_fmpz(r1, r2, a, b, c, prec); acb_mul(x, r1, r1, prec); acb_mul_fmpz(x, x, a, prec); acb_addmul_fmpz(x, r1, b, prec); acb_add_fmpz(x, x, c, prec); acb_mul(y, r2, r2, prec); acb_mul_fmpz(y, y, a, prec); acb_addmul_fmpz(y, r2, b, prec); acb_add_fmpz(y, y, c, prec); if (!acb_contains_zero(x) || !acb_contains_zero(y) || acb_rel_accuracy_bits(r1) < prec - 4 || acb_rel_accuracy_bits(r2) < prec - 4) { flint_printf("FAIL: containment / accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpz_print(c); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); acb_clear(r1); acb_clear(r2); acb_clear(x); acb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-rel_accuracy_bits.c000066400000000000000000000057171417376376500201650ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("rel_accuracy_bits...."); fflush(stdout); flint_randinit(state); /* test aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; acb_t z; slong a1, a2; arb_init(x); acb_init(z); arb_randtest_special(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 200)); acb_set_arb(z, x); a1 = arb_rel_accuracy_bits(x); a2 = acb_rel_accuracy_bits(z); if (a1 != a2) { flint_printf("FAIL: acb != arb\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_printf("a1 = %wd, a2 = %wd\n\n", a1, a2); flint_abort(); } acb_randtest_special(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 200)); a1 = acb_rel_accuracy_bits(z); if (n_randint(state, 2)) arf_swap(arb_midref(acb_realref(z)), arb_midref(acb_imagref(z))); if (n_randint(state, 2)) mag_swap(arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); a2 = acb_rel_accuracy_bits(z); if (a1 != a2) { flint_printf("FAIL: swapping\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_printf("a1 = %wd, a2 = %wd\n\n", a1, a2); flint_abort(); } acb_randtest_special(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 200)); if (arf_cmpabs(arb_midref(acb_realref(z)), arb_midref(acb_imagref(z))) >= 0) arf_set(arb_midref(x), arb_midref(acb_realref(z))); else arf_set(arb_midref(x), arb_midref(acb_imagref(z))); if (mag_cmp(arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))) >= 0) mag_set(arb_radref(x), arb_radref(acb_realref(z))); else mag_set(arb_radref(x), arb_radref(acb_imagref(z))); a1 = acb_rel_accuracy_bits(z); a2 = arb_rel_accuracy_bits(x); if (a1 != a2) { flint_printf("FAIL: acb != arb (2)\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_printf("a1 = %wd, a2 = %wd\n\n", a1, a2); flint_abort(); } arb_clear(x); acb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-rgamma.c000066400000000000000000000037751417376376500157560ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("rgamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 3); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 3); acb_rgamma(b, a, prec1); acb_rgamma(c, a, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } /* check 1/gamma(z+1) = 1/gamma(z)/z */ acb_div(b, b, a, prec1); acb_add_ui(c, a, 1, prec1); acb_rgamma(c, c, prec1); if (!acb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-rising2_ui.c000066400000000000000000000063571417376376500165630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rising2_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, u, v, u2, v2; fmpz *f; acb_ptr g; ulong n; slong i, prec; acb_init(a); acb_init(u); acb_init(v); acb_init(u2); acb_init(v2); acb_randtest(a, state, 1 + n_randint(state, 4000), 10); acb_randtest(u, state, 1 + n_randint(state, 4000), 10); acb_randtest(v, state, 1 + n_randint(state, 4000), 10); n = n_randint(state, 120); f = _fmpz_vec_init(n + 1); g = _acb_vec_init(n + 1); prec = 2 + n_randint(state, 4000); acb_rising2_ui(u, v, a, n, prec); arith_stirling_number_1u_vec(f, n, n + 1); for (i = 0; i <= n; i++) acb_set_fmpz(g + i, f + i); _acb_poly_evaluate(u2, g, n + 1, a, prec); _acb_poly_derivative(g, g, n + 1, prec); _acb_poly_evaluate(v2, g, n, a, prec); if (!acb_overlaps(u, u2) || !acb_overlaps(v, v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n", n); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); acb_printd(u2, 15); flint_printf("\n\n"); flint_printf("v = "); acb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); acb_printd(v2, 15); flint_printf("\n\n"); flint_abort(); } acb_set(u2, a); acb_rising2_ui(u2, v, u2, n, prec); if (!acb_equal(u2, u)) { flint_printf("FAIL: aliasing 1\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); acb_printd(u2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); flint_abort(); } acb_set(v2, a); acb_rising2_ui(u, v2, v2, n, prec); if (!acb_equal(v2, v)) { flint_printf("FAIL: aliasing 2\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("v = "); acb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); acb_printd(v2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); flint_abort(); } acb_clear(a); acb_clear(u); acb_clear(v); acb_clear(u2); acb_clear(v2); _fmpz_vec_clear(f, n + 1); _acb_vec_clear(g, n + 1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-rising_ui.c000066400000000000000000000052701417376376500164720ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("rising_ui...."); fflush(stdout); flint_randinit(state); /* check functional equation */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, xn, y, z; ulong n, m; acb_init(x); acb_init(xn); acb_init(y); acb_init(z); acb_randtest(x, state, 1 + n_randint(state, 4000), 10); n = n_randint(state, 80); m = n_randint(state, 40); acb_add_ui(xn, x, n, 1 + n_randint(state, 4000)); acb_rising_ui(y, x, n, 2 + n_randint(state, 4000)); acb_rising_ui(z, xn, m, 2 + n_randint(state, 4000)); acb_mul(y, y, z, 2 + n_randint(state, 4000)); acb_rising_ui(z, x, n + m, 2 + n_randint(state, 4000)); if (!acb_overlaps(y, z)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n", n); flint_printf("m = %wu\n", m); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("xn = "); acb_print(xn); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(xn); acb_clear(y); acb_clear(z); } /* aliasing of y and x */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y; ulong n; slong prec; acb_init(x); acb_init(y); acb_randtest(x, state, 1 + n_randint(state, 200), 10); acb_randtest(y, state, 1 + n_randint(state, 200), 10); n = n_randint(state, 100); prec = 2 + n_randint(state, 4000); acb_rising_ui(y, x, n, prec); acb_rising_ui(x, x, n, prec); if (!acb_equal(x, y)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("n = %wu\n", n); flint_abort(); } acb_clear(x); acb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-rising_ui_get_mag.c000066400000000000000000000031331417376376500201510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("rising_ui_get_mag...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, z; mag_t b; ulong n; acb_init(x); acb_init(y); acb_init(z); mag_init(b); acb_randtest(x, state, 1 + n_randint(state, 400), 1 + n_randint(state, 100)); n = n_randint(state, 80); acb_rising_ui(y, x, n, 2 + n_randint(state, 400)); acb_rising_ui_get_mag(b, x, n); acb_zero(z); acb_add_error_mag(z, b); if (!acb_overlaps(y, z)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n", n); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(z); mag_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-root_ui.c000066400000000000000000000033711417376376500161620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("root_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, b, c; ulong k; slong prec; prec = 2 + n_randint(state, 1000); k = n_randtest_not_zero(state); acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_root_ui(b, a, k, prec); acb_pow_ui(c, b, k, prec); if (!acb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("k = %wu\n", k); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_root_ui(a, a, k, prec); if (!acb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-rsqrt.c000066400000000000000000000127541417376376500156620ustar00rootroot00000000000000/* Copyright (C) 2013, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("rsqrt...."); fflush(stdout); flint_randinit(state); /* check union */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, x, ra, rb, rc, rx; acb_init(a); acb_init(b); acb_init(c); acb_init(x); acb_init(ra); acb_init(rb); acb_init(rc); acb_init(rx); acb_randtest_precise(a, state, 1 + n_randint(state, 500), 1 + n_randint(state, 80)); acb_randtest_precise(b, state, 1 + n_randint(state, 500), 1 + n_randint(state, 80)); acb_randtest_precise(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 80)); acb_randtest(ra, state, 1 + n_randint(state, 500), 1 + n_randint(state, 80)); acb_randtest(rb, state, 1 + n_randint(state, 500), 1 + n_randint(state, 80)); acb_randtest(rc, state, 1 + n_randint(state, 500), 1 + n_randint(state, 80)); acb_randtest(rx, state, 1 + n_randint(state, 500), 1 + n_randint(state, 80)); acb_union(x, a, b, 2 + n_randint(state, 500)); acb_union(x, x, c, 2 + n_randint(state, 500)); acb_rsqrt(rx, x, 2 + n_randint(state, 500)); acb_rsqrt(ra, a, 2 + n_randint(state, 500)); acb_rsqrt(rb, b, 2 + n_randint(state, 500)); acb_rsqrt(rc, c, 2 + n_randint(state, 500)); if (!acb_overlaps(rx, ra)) { flint_printf("FAIL: overlap a\n\n"); flint_printf("a = "); acb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); acb_printn(c, 50, 0); flint_printf("\n\n"); flint_printf("x = "); acb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("ra = "); acb_printn(ra, 50, 0); flint_printf("\n\n"); flint_printf("rx = "); acb_printn(rx, 50, 0); flint_printf("\n\n"); flint_abort(); } if (!acb_overlaps(rx, rb)) { flint_printf("FAIL: overlap b\n\n"); flint_printf("a = "); acb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); acb_printn(c, 50, 0); flint_printf("\n\n"); flint_printf("x = "); acb_printn(x, 50, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("rb = "); acb_printn(rb, 50, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("rx = "); acb_printn(rx, 50, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } if (!acb_overlaps(rx, rc)) { flint_printf("FAIL: overlap c\n\n"); flint_printf("a = "); acb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); acb_printn(c, 50, 0); flint_printf("\n\n"); flint_printf("x = "); acb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("rc = "); acb_printn(rc, 50, 0); flint_printf("\n\n"); flint_printf("rx = "); acb_printn(rx, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(x); acb_clear(ra); acb_clear(rb); acb_clear(rc); acb_clear(rx); } /* check (a^(-1/2))^(-2) = a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 2000), 10); acb_randtest(b, state, 1 + n_randint(state, 2000), 10); prec = 2 + n_randint(state, 2000); acb_rsqrt(b, a, prec); acb_inv(c, b, prec); acb_mul(c, c, c, prec); if (!acb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_log(c, a, FLINT_MIN(prec, 200)); acb_mul_2exp_si(c, c, -1); acb_neg(c, c); acb_exp(c, c, FLINT_MIN(prec, 200)); if (!acb_overlaps(c, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_rsqrt(a, a, prec); if (!acb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sec.c000066400000000000000000000034341417376376500152540ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sec...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 300), 100); acb_randtest_special(a, state, 1 + n_randint(state, 300), 100); acb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { acb_sec(a, x, prec1); } else { acb_set(a, x); acb_sec(a, a, prec1); } acb_cos(b, x, prec2); acb_inv(b, b, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sech.c000066400000000000000000000034401417376376500154210ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sech...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 300), 100); acb_randtest_special(a, state, 1 + n_randint(state, 300), 100); acb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { acb_sech(a, x, prec1); } else { acb_set(a, x); acb_sech(a, a, prec1); } acb_cosh(b, x, prec2); acb_inv(b, b, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); acb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sgn.c000066400000000000000000000040751417376376500152730ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sgn...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, a, b; slong prec; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); prec = 2 + n_randint(state, 200); acb_sgn(a, x, prec); if (acb_is_zero(x)) { acb_zero(b); } else { arb_zero(acb_realref(b)); acb_arg(acb_imagref(b), x, prec); acb_exp(b, b, prec); } if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_sgn(x, x, prec); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sin_cos.c000066400000000000000000000067241417376376500161440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos...."); fflush(stdout); flint_randinit(state); /* check sin(a+b) = cos(b)*sin(a) + cos(a)*sin(b) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, cosa, sina, cosb, sinb; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(cosa); acb_init(sina); acb_init(cosb); acb_init(sinb); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_add(c, a, b, prec); acb_sin(c, c, prec); acb_sin_cos(sina, cosa, a, prec); acb_sin_cos(sinb, cosb, b, prec); acb_mul(cosb, cosb, sina, prec); acb_mul(cosa, cosa, sinb, prec); acb_add(d, cosa, cosb, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: sin(a+b) = cos(b)*sin(a) + cos(a)*sin(b)\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(cosa); acb_clear(sina); acb_clear(cosb); acb_clear(sinb); } /* check cos(a+b) = cos(b)*cos(a) - sin(a)*sin(b) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, cosa, sina, cosb, sinb; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(cosa); acb_init(sina); acb_init(cosb); acb_init(sinb); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_add(c, a, b, prec); acb_cos(c, c, prec); acb_sin_cos(sina, cosa, a, prec); acb_sin_cos(sinb, cosb, b, prec); acb_mul(cosa, cosa, cosb, prec); acb_mul(sina, sina, sinb, prec); acb_sub(d, cosa, sina, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: cos(a+b) = cos(b)*cos(a) - sin(a)*sin(b)\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(cosa); acb_clear(sina); acb_clear(cosb); acb_clear(sinb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sin_pi.c000066400000000000000000000046431417376376500157660ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_sin_pi(a, x, prec1); acb_sin_pi(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* compare with cos */ arb_const_pi(acb_realref(c), prec1); acb_mul_arb(y, x, acb_realref(c), prec1); acb_sin(c, y, prec1); if (!acb_overlaps(a, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_sin_pi(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sinc.c000066400000000000000000000042511417376376500154340ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sinc...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 400), 2 + n_randint(state, 100)); acb_randtest(b, state, 1 + n_randint(state, 400), 2 + n_randint(state, 100)); acb_randtest(c, state, 1 + n_randint(state, 400), 2 + n_randint(state, 100)); acb_sinc(b, a, 2 + n_randint(state, 400)); acb_sin(c, a, 2 + n_randint(state, 400)); acb_mul(d, b, a, 2 + n_randint(state, 400)); /* check consistency */ if (!acb_overlaps(c, d)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 30); flint_printf("\n\n"); flint_abort(); } acb_set(c, a); acb_sinc(c, c, 2 + n_randint(state, 400)); if (!acb_overlaps(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(c, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sinc_pi.c000066400000000000000000000032701417376376500161240ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sinc_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, z; slong prec; acb_init(x); acb_init(y); acb_init(z); prec = 2 + n_randint(state, 200); acb_randtest(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); acb_randtest(y, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); if (n_randint(state, 2)) { acb_set(y, x); acb_sinc_pi(y, y, prec); } else acb_sinc_pi(y, x, prec); acb_const_pi(z, prec); acb_mul(z, z, x, prec); acb_sinc(z, z, prec); if (!acb_overlaps(y, z)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sinh_cosh.c000066400000000000000000000067641417376376500164700ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sinh_cosh...."); fflush(stdout); flint_randinit(state); /* check sinh(a+b) = cosh(b)*sinh(a) + cosh(a)*sinh(b) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, cosa, sina, cosb, sinb; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(cosa); acb_init(sina); acb_init(cosb); acb_init(sinb); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_add(c, a, b, prec); acb_sinh(c, c, prec); acb_sinh_cosh(sina, cosa, a, prec); acb_sinh_cosh(sinb, cosb, b, prec); acb_mul(cosb, cosb, sina, prec); acb_mul(cosa, cosa, sinb, prec); acb_add(d, cosa, cosb, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: sinh(a+b) = cosh(b)*sinh(a) + cosh(a)*sinh(b)\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(cosa); acb_clear(sina); acb_clear(cosb); acb_clear(sinb); } /* check cosh(a+b) = cosh(b)*cosh(a) + sinh(a)*sinh(b) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, cosa, sina, cosb, sinb; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(cosa); acb_init(sina); acb_init(cosb); acb_init(sinb); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_add(c, a, b, prec); acb_cosh(c, c, prec); acb_sinh_cosh(sina, cosa, a, prec); acb_sinh_cosh(sinb, cosb, b, prec); acb_mul(cosa, cosa, cosb, prec); acb_mul(sina, sina, sinb, prec); acb_add(d, cosa, sina, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: cosh(a+b) = cosh(b)*cosh(a) + sinh(a)*sinh(b)\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(cosa); acb_clear(sina); acb_clear(cosb); acb_clear(sinb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-sqrt.c000066400000000000000000000034021417376376500154660ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt...."); fflush(stdout); flint_randinit(state); /* check (a^(1/2))^2 = a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 2000), 10); acb_randtest(b, state, 1 + n_randint(state, 2000), 10); prec = 2 + n_randint(state, 2000); acb_sqrt(b, a, prec); acb_mul(c, b, b, prec); if (!acb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_sqrt(a, a, prec); if (!acb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-tan.c000066400000000000000000000053041417376376500152620ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("tan...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest(y, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_tan(a, x, prec1); acb_tan(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* check tan(x+y) = (tan(x) + tan(y)) / (1 - tan(x) tan(y)) */ acb_add(b, x, y, prec1); acb_tan(b, b, prec1); acb_tan(c, y, prec1); acb_add(d, a, c, prec1); acb_mul(c, a, c, prec1); acb_sub_ui(c, c, 1, prec1); acb_neg(c, c); acb_div(d, d, c, prec1); if (!acb_overlaps(b, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_tan(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-tan_pi.c000066400000000000000000000046441417376376500157600ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("tan_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_tan_pi(a, x, prec1); acb_tan_pi(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* compare with tan */ arb_const_pi(acb_realref(c), prec1); acb_mul_arb(y, x, acb_realref(c), prec1); acb_tan(c, y, prec1); if (!acb_overlaps(a, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_tan_pi(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-tanh.c000066400000000000000000000052641417376376500154370ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("tanh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(x, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); acb_randtest(y, state, 1 + n_randint(state, 200), 2 + n_randint(state, 100)); acb_tanh(a, x, prec1); acb_tanh(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_abort(); } /* check tanh(x+y) = (tanh(x) + tanh(y)) / (1 + tanh(x) tanh(y)) */ acb_add(b, x, y, prec1); acb_tanh(b, b, prec1); acb_tanh(c, y, prec1); acb_add(d, a, c, prec1); acb_mul(c, a, c, prec1); acb_add_ui(c, c, 1, prec1); acb_div(d, d, c, prec1); if (!acb_overlaps(b, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); flint_abort(); } acb_tanh(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-vec_unit_roots.c000066400000000000000000000044031417376376500175410ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong len; flint_rand_t state; flint_printf("vec_unit_roots...."); fflush(stdout); flint_randinit(state); for (len = 0; len < 100; len++) { slong iter; for (iter = 0; iter < 6; iter++) { acb_ptr vec; fmpq_t q; acb_t t; slong k; slong prec = 53; slong order; if (iter == 0) order = len; else if (iter == 1) order = -len; else if (iter == 2) order = 2 * len; else if (iter == 3) order = - 4 * len; else if (iter == 4) order = -1 - n_randint(state, 3 * len); else order = 1 + n_randint(state, 3 * len); vec = _acb_vec_init(len); acb_init(t); fmpq_init(q); _acb_vec_unit_roots(vec, order, len, prec); for (k = 0; k < len; k++) { if (order < 0) fmpq_set_si(q, -2 * k, -order); else fmpq_set_si(q, 2 * k, order); arb_sin_cos_pi_fmpq(acb_imagref(t), acb_realref(t), q, prec); if (!acb_overlaps(vec + k, t)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu order = %wd k = %wd\n\n", len, order, k); flint_printf("vec = "); acb_printn(vec + k, 30, 0); flint_printf("\n\n"); flint_printf("t = "); acb_printn(t, 30, 0); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(vec, len); acb_clear(t); fmpq_clear(q); } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/test/t-zeta.c000066400000000000000000000030041417376376500154360ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 500); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 500), 5); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 500), 3); acb_zeta(b, a, prec1); acb_zeta(c, a, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb/unit_root.c000066400000000000000000000017031417376376500153010ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" static void _acb_unit_root(acb_t res, ulong order, slong prec) { fmpq_t t; fmpq_init(t); fmpq_set_si(t, 2, order); arb_sin_cos_pi_fmpq(acb_imagref(res), acb_realref(res), t, prec); fmpq_clear(t); } void acb_unit_root(acb_t res, ulong order, slong prec) { switch (order) { case 1: acb_one(res); break; case 2: acb_set_si(res, -1); break; case 4: acb_onei(res); break; default: _acb_unit_root(res, order, prec); break; } } arb-2.22.1/acb/vec_clear.c000066400000000000000000000010201417376376500151720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void _acb_vec_clear(acb_ptr v, slong n) { slong i; for (i = 0; i < n; i++) acb_clear(v + i); flint_free(v); } arb-2.22.1/acb/vec_init.c000066400000000000000000000011031417376376500150510ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" acb_ptr _acb_vec_init(slong n) { slong i; acb_ptr v = (acb_ptr) flint_malloc(sizeof(acb_struct) * n); for (i = 0; i < n; i++) acb_init(v + i); return v; } arb-2.22.1/acb/vec_set_powers.c000066400000000000000000000014421417376376500163060ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void _acb_vec_set_powers(acb_ptr xs, const acb_t x, slong len, slong prec) { slong i; for (i = 0; i < len; i++) { if (i == 0) acb_one(xs + i); else if (i == 1) acb_set_round(xs + i, x, prec); else if (i % 2 == 0) acb_mul(xs + i, xs + i / 2, xs + i / 2, prec); else acb_mul(xs + i, xs + i - 1, x, prec); } } arb-2.22.1/acb/vec_sort_pretty.c000066400000000000000000000023261417376376500165140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #ifndef __compar_fn_t #if defined(_MSC_VER) typedef int(*__compar_fn_t) (const void *, const void *); #else typedef int(*__compar_fn_t) (__const void *, __const void *); #endif #endif int acb_cmp_pretty(const acb_t a, const acb_t b) { arb_t t, u, v; int res; arb_init(t); arb_init(u); arb_init(v); arb_abs(u, acb_imagref(a)); arb_abs(v, acb_imagref(b)); arb_sub(t, u, v, MAG_BITS); res = 0; if (arb_contains_zero(t)) { arb_sub(t, acb_realref(a), acb_realref(b), MAG_BITS); res = arb_is_positive(t) ? 1 : -1; } else { res = arb_is_positive(t) ? 1 : -1; } arb_clear(t); arb_clear(u); arb_clear(v); return res; } void _acb_vec_sort_pretty(acb_ptr vec, slong len) { qsort(vec, len, sizeof(acb_struct), (__compar_fn_t) acb_cmp_pretty); } arb-2.22.1/acb/vec_unit_roots.c000066400000000000000000000037241417376376500163260ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" void _acb_vec_unit_roots(acb_ptr res, slong n, slong len, slong prec) { int conj = 0; slong k, len1, wp; acb_t t; if (len <= 0) return; if (n == 0) { flint_printf("\n_acb_vec_unit_roots: need order != 0\n"); abort(); } if (n < 0) { n = -n; conj = 1; } if (n % 4 == 0) len1 = FLINT_MIN(len, n / 8 + 1); else if (n % 2 == 0) len1 = FLINT_MIN(len, n / 4 + 1); else len1 = FLINT_MIN(len, n / 2 + 1); wp = prec + 6 + 2 * FLINT_BIT_COUNT(len1); acb_init(t); acb_unit_root(t, n, prec); _acb_vec_set_powers(res, t, len1, wp); acb_clear(t); _acb_vec_set_round(res, res, len1, prec); if (n % 4 == 0) { for (k = n / 8 + 1; k <= n / 4 && k < len; k++) { arb_set(acb_realref(res + k), acb_imagref(res + n / 4 - k)); arb_set(acb_imagref(res + k), acb_realref(res + n / 4 - k)); } for (k = n / 4 + 1; k <= n / 2 && k < len; k++) acb_mul_onei(res + k, res + k - n / 4); } else if (n % 2 == 0) { for (k = n / 4 + 1; k <= n / 2 && k < len; k++) { acb_set(res + k, res + n / 2 - k); arb_neg(acb_realref(res + k), acb_realref(res + k)); } } for (k = n / 2 + 1; k < len && k < n; k++) acb_conj(res + k, res + n - k); for (k = n; k < len; k++) acb_set(res + k, res - n + k); if (conj) { for (k = 1; k < len; k++) acb_conj(res + k, res + k); } } arb-2.22.1/acb/zeta.c000066400000000000000000000017651417376376500142320ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb.h" #include "acb_poly.h" #include "acb_dirichlet.h" void acb_zeta_si(acb_t z, slong s, slong prec) { if (s >= 0) { arb_zeta_ui(acb_realref(z), s, prec); } else { arb_bernoulli_ui(acb_realref(z), 1-s, prec); arb_div_ui(acb_realref(z), acb_realref(z), 1-s, prec); arb_neg(acb_realref(z), acb_realref(z)); } arb_zero(acb_imagref(z)); return; } void acb_hurwitz_zeta(acb_t z, const acb_t s, const acb_t a, slong prec) { acb_dirichlet_hurwitz(z, s, a, prec); } void acb_zeta(acb_t z, const acb_t s, slong prec) { acb_dirichlet_zeta(z, s, prec); } arb-2.22.1/acb_calc.h000066400000000000000000000033631417376376500142520ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_CALC_H #define ACB_CALC_H #include "acb.h" #include "acb_poly.h" #include "acb_mat.h" #include "arb_calc.h" #ifdef __cplusplus extern "C" { #endif typedef int (*acb_calc_func_t)(acb_ptr out, const acb_t inp, void * param, slong order, slong prec); /* Integration (old) */ void acb_calc_cauchy_bound(arb_t bound, acb_calc_func_t func, void * param, const acb_t x, const arb_t radius, slong maxdepth, slong prec); int acb_calc_integrate_taylor(acb_t res, acb_calc_func_t func, void * param, const acb_t a, const acb_t b, const arf_t inner_radius, const arf_t outer_radius, slong accuracy_goal, slong prec); /* Integration */ typedef struct { slong deg_limit; slong eval_limit; slong depth_limit; int use_heap; int verbose; } acb_calc_integrate_opt_struct; typedef acb_calc_integrate_opt_struct acb_calc_integrate_opt_t[1]; void acb_calc_integrate_opt_init(acb_calc_integrate_opt_t options); int acb_calc_integrate(acb_t res, acb_calc_func_t f, void * param, const acb_t a, const acb_t b, slong goal, const mag_t tol, const acb_calc_integrate_opt_t options, slong prec); int acb_calc_integrate_gl_auto_deg(acb_t res, slong * eval_count, acb_calc_func_t f, void * param, const acb_t a, const acb_t b, const mag_t tol, slong deg_limit, int verbose, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_calc/000077500000000000000000000000001417376376500140745ustar00rootroot00000000000000arb-2.22.1/acb_calc/cauchy_bound.c000066400000000000000000000047371417376376500167160ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_calc.h" void acb_calc_cauchy_bound(arb_t bound, acb_calc_func_t func, void * param, const acb_t x, const arb_t radius, slong maxdepth, slong prec) { slong i, n, depth, wp; arb_t pi, theta, v, s1, c1, s2, c2, st, ct; acb_t t, u; arb_t b; arb_init(pi); arb_init(theta); arb_init(v); arb_init(s1); arb_init(c1); arb_init(s2); arb_init(c2); arb_init(st); arb_init(ct); acb_init(t); acb_init(u); arb_init(b); wp = prec + 20; arb_const_pi(pi, wp); arb_zero_pm_inf(b); for (depth = 0, n = 16; depth < maxdepth; n *= 2, depth++) { arb_zero(b); /* theta = 2 pi / n */ arb_div_ui(theta, pi, n, wp); arb_mul_2exp_si(theta, theta, 1); /* sine and cosine of i*theta and (i+1)*theta */ arb_zero(s1); arb_one(c1); arb_sin_cos(st, ct, theta, wp); arb_set(s2, st); arb_set(c2, ct); for (i = 0; i < n; i++) { /* sine and cosine of 2 pi ([i,i+1]/n) */ /* since we use power of two subdivision points, the sine and cosine are monotone on each subinterval */ arb_union(acb_realref(t), c1, c2, wp); arb_union(acb_imagref(t), s1, s2, wp); acb_mul_arb(t, t, radius, wp); acb_add(t, t, x, prec); /* next angle */ arb_mul(v, c2, ct, wp); arb_mul(c1, s2, st, wp); arb_sub(c1, v, c1, wp); arb_mul(v, c2, st, wp); arb_mul(s1, s2, ct, wp); arb_add(s1, v, s1, wp); arb_swap(c1, c2); arb_swap(s1, s2); func(u, t, param, 1, prec); acb_abs(v, u, prec); arb_add(b, b, v, prec); } arb_div_ui(b, b, n, prec); if (arb_is_positive(b)) break; } arb_set(bound, b); arb_clear(pi); arb_clear(theta); arb_clear(v); acb_clear(t); acb_clear(u); arb_clear(b); arb_clear(s1); arb_clear(c1); arb_clear(s2); arb_clear(c2); arb_clear(st); arb_clear(ct); } arb-2.22.1/acb_calc/integrate.c000066400000000000000000000227711417376376500162330ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_calc.h" static void quad_simple(acb_t res, acb_calc_func_t f, void * param, const acb_t a, const acb_t b, slong prec) { acb_t mid, delta, wide; mag_t tmpm; acb_init(mid); acb_init(delta); acb_init(wide); mag_init(tmpm); /* delta = (b-a)/2 */ acb_sub(delta, b, a, prec); acb_mul_2exp_si(delta, delta, -1); /* mid = (a+b)/2 */ acb_add(mid, a, b, prec); acb_mul_2exp_si(mid, mid, -1); /* wide = mid +- [delta] */ acb_set(wide, mid); arb_get_mag(tmpm, acb_realref(delta)); arb_add_error_mag(acb_realref(wide), tmpm); arb_get_mag(tmpm, acb_imagref(delta)); arb_add_error_mag(acb_imagref(wide), tmpm); /* Direct evaluation: integral = (b-a) * f([a,b]). */ f(res, wide, param, 0, prec); acb_mul(res, res, delta, prec); acb_mul_2exp_si(res, res, 1); acb_clear(mid); acb_clear(delta); acb_clear(wide); mag_clear(tmpm); } static void heap_up(acb_ptr as, acb_ptr bs, acb_ptr vs, mag_ptr ms, slong n) { slong i, max, l, r; i = 0; for (;;) { max = i; l = 2 * i + 1; r = 2 * i + 2; if (l < n && mag_cmp(ms + l, ms + max) > 0) max = l; if (r < n && mag_cmp(ms + r, ms + max) > 0) max = r; if (max != i) { acb_swap(as + i, as + max); acb_swap(bs + i, bs + max); acb_swap(vs + i, vs + max); mag_swap(ms + i, ms + max); i = max; } else { break; } } } static void heap_down(acb_ptr as, acb_ptr bs, acb_ptr vs, mag_ptr ms, slong n) { slong j, k; k = n - 1; j = (k - 1) / 2; while (k > 0 && mag_cmp(ms + j, ms + k) < 0) { acb_swap(as + j, as + k); acb_swap(bs + j, bs + k); acb_swap(vs + j, vs + k); mag_swap(ms + j, ms + k); k = j; j = (j - 1) / 2; } } static int _acb_overlaps(acb_t tmp, const acb_t a, const acb_t b, slong prec) { acb_sub(tmp, a, b, prec); return acb_contains_zero(tmp); } int acb_calc_integrate(acb_t res, acb_calc_func_t f, void * param, const acb_t a, const acb_t b, slong goal, const mag_t tol, const acb_calc_integrate_opt_t options, slong prec) { acb_ptr as, bs, vs; mag_ptr ms; acb_t s, t, u; mag_t tmpm, tmpn, new_tol; slong depth_limit, eval_limit, deg_limit; slong depth, depth_max, eval, feval, top; slong leaf_interval_count; slong alloc; int stopping, real_error, use_heap, status, gl_status, verbose; if (options == NULL) { acb_calc_integrate_opt_t opt; acb_calc_integrate_opt_init(opt); return acb_calc_integrate(res, f, param, a, b, goal, tol, opt, prec); } status = ARB_CALC_SUCCESS; acb_init(s); acb_init(t); acb_init(u); mag_init(tmpm); mag_init(tmpn); mag_init(new_tol); depth_limit = options->depth_limit; if (depth_limit <= 0) depth_limit = 2 * prec; depth_limit = FLINT_MAX(depth_limit, 1); eval_limit = options->eval_limit; if (eval_limit <= 0) eval_limit = 1000 * prec + prec * prec; eval_limit = FLINT_MAX(eval_limit, 1); goal = FLINT_MAX(goal, 0); deg_limit = options->deg_limit; if (deg_limit <= 0) deg_limit = 0.5 * FLINT_MIN(goal, prec) + 60; verbose = options->verbose; use_heap = options->use_heap; alloc = 4; as = _acb_vec_init(alloc); bs = _acb_vec_init(alloc); vs = _acb_vec_init(alloc); ms = _mag_vec_init(alloc); /* Compute initial crude estimate for the whole interval. */ acb_set(as, a); acb_set(bs, b); quad_simple(vs, f, param, as, bs, prec); mag_hypot(ms, arb_radref(acb_realref(vs)), arb_radref(acb_imagref(vs))); depth = depth_max = 1; eval = 1; stopping = 0; leaf_interval_count = 0; /* Adjust absolute tolerance based on new information. */ acb_get_mag_lower(tmpm, vs); mag_mul_2exp_si(tmpm, tmpm, -goal); mag_max(new_tol, tol, tmpm); acb_zero(s); while (depth >= 1) { if (stopping == 0 && eval >= eval_limit - 1) { if (verbose > 0) flint_printf("stopping at eval_limit %wd\n", eval_limit); status = ARB_CALC_NO_CONVERGENCE; stopping = 1; continue; } if (use_heap) top = 0; else top = depth - 1; /* We are done with this subinterval. */ if (mag_cmp(ms + top, new_tol) < 0 || _acb_overlaps(u, as + top, bs + top, prec) || stopping) { acb_add(s, s, vs + top, prec); leaf_interval_count++; depth--; if (use_heap && depth > 0) { acb_swap(as, as + depth); acb_swap(bs, bs + depth); acb_swap(vs, vs + depth); mag_swap(ms, ms + depth); heap_up(as, bs, vs, ms, depth); } continue; } /* Attempt using Gauss-Legendre rule. */ if (acb_is_finite(vs + top)) { gl_status = acb_calc_integrate_gl_auto_deg(u, &feval, f, param, as + top, bs + top, new_tol, deg_limit, verbose > 1, prec); eval += feval; /* We are done with this subinterval. */ if (gl_status == ARB_CALC_SUCCESS) { /* We know that the result is real. */ real_error = acb_is_finite(vs + top) && acb_is_real(vs + top); if (real_error) arb_zero(acb_imagref(u)); acb_add(s, s, u, prec); leaf_interval_count++; /* Adjust absolute tolerance based on new information. */ acb_get_mag_lower(tmpm, u); mag_mul_2exp_si(tmpm, tmpm, -goal); mag_max(new_tol, new_tol, tmpm); depth--; if (use_heap && depth > 0) { acb_swap(as, as + depth); acb_swap(bs, bs + depth); acb_swap(vs, vs + depth); mag_swap(ms, ms + depth); heap_up(as, bs, vs, ms, depth); } continue; } } if (depth >= depth_limit - 1) { if (verbose > 0) flint_printf("stopping at depth_limit %wd\n", depth_limit); status = ARB_CALC_NO_CONVERGENCE; stopping = 1; continue; } if (depth >= alloc - 1) { slong k; as = flint_realloc(as, 2 * alloc * sizeof(acb_struct)); bs = flint_realloc(bs, 2 * alloc * sizeof(acb_struct)); vs = flint_realloc(vs, 2 * alloc * sizeof(acb_struct)); ms = flint_realloc(ms, 2 * alloc * sizeof(mag_struct)); for (k = alloc; k < 2 * alloc; k++) { acb_init(as + k); acb_init(bs + k); acb_init(vs + k); mag_init(ms + k); } alloc *= 2; } /* Bisection. */ /* Interval [depth] becomes [mid, b]. */ acb_set(bs + depth, bs + top); acb_add(as + depth, as + top, bs + top, prec); acb_mul_2exp_si(as + depth, as + depth, -1); /* Interval [top] becomes [a, mid]. */ acb_set(bs + top, as + depth); /* Evaluate on [a, mid] */ quad_simple(vs + top, f, param, as + top, bs + top, prec); mag_hypot(ms + top, arb_radref(acb_realref(vs + top)), arb_radref(acb_imagref(vs + top))); eval++; /* Adjust absolute tolerance based on new information. */ acb_get_mag_lower(tmpm, vs + top); mag_mul_2exp_si(tmpm, tmpm, -goal); mag_max(new_tol, new_tol, tmpm); /* Evaluate on [mid, b] */ quad_simple(vs + depth, f, param, as + depth, bs + depth, prec); mag_hypot(ms + depth, arb_radref(acb_realref(vs + depth)), arb_radref(acb_imagref(vs + depth))); eval++; /* Adjust absolute tolerance based on new information. */ acb_get_mag_lower(tmpm, vs + depth); mag_mul_2exp_si(tmpm, tmpm, -goal); mag_max(new_tol, new_tol, tmpm); /* Make the interval with the larger error the priority. */ if (mag_cmp(ms + top, ms + depth) < 0) { acb_swap(as + top, as + depth); acb_swap(bs + top, bs + depth); acb_swap(vs + top, vs + depth); mag_swap(ms + top, ms + depth); } if (use_heap) { heap_up(as, bs, vs, ms, depth); heap_down(as, bs, vs, ms, depth + 1); } depth++; depth_max = FLINT_MAX(depth, depth_max); } if (verbose > 0) { flint_printf("depth %wd/%wd, eval %wd/%wd, %wd leaf intervals\n", depth_max, depth_limit, eval, eval_limit, leaf_interval_count); } acb_set(res, s); _acb_vec_clear(as, alloc); _acb_vec_clear(bs, alloc); _acb_vec_clear(vs, alloc); _mag_vec_clear(ms, alloc); acb_clear(s); acb_clear(t); acb_clear(u); mag_clear(tmpm); mag_clear(tmpn); mag_clear(new_tol); return status; } arb-2.22.1/acb_calc/integrate_gl_auto_deg.c000066400000000000000000000164121417376376500205570ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_calc.h" /* Gauss-Legendre quadrature nodes are cached to speed up multiple integrations and adaptive subdivision. The steps of 2^(n/2) used here give slightly better performance than steps of 2^n (we use at most 1.4x more points than needed and not 2x more points) but may require more precomputation. */ #define GL_STEPS 38 const slong gl_steps[GL_STEPS] = {1, 2, 4, 6, 8, 12, 16, 22, 32, 46, 64, 90, 128, 182, 256, 362, 512, 724, 1024, 1448, 2048, 2896, 4096, 5792, 8192, 11586, 16384, 23170, 32768, 46340, 65536, 92682, 131072, 185364, 262144, 370728, 524288, 741456}; typedef struct { slong gl_prec[GL_STEPS]; arb_ptr gl_nodes[GL_STEPS]; arb_ptr gl_weights[GL_STEPS]; } gl_cache_struct; TLS_PREFIX gl_cache_struct * gl_cache = NULL; void gl_cleanup() { slong i; if (gl_cache == NULL) return; for (i = 0; i < GL_STEPS; i++) { if (gl_cache->gl_prec[i] != 0) { _arb_vec_clear(gl_cache->gl_nodes[i], (gl_steps[i] + 1) / 2); _arb_vec_clear(gl_cache->gl_weights[i], (gl_steps[i] + 1) / 2); } } flint_free(gl_cache); gl_cache = NULL; } void gl_init() { gl_cache = flint_calloc(1, sizeof(gl_cache_struct)); flint_register_cleanup_function(gl_cleanup); } /* Compute GL node and weight of index k for n = gl_steps[i]. Cached. */ void acb_calc_gl_node(arb_t x, arb_t w, slong i, slong k, slong prec) { slong n, kk, jj, wp; if (i < 0 || i >= GL_STEPS || prec < 2) flint_abort(); if (gl_cache == NULL) gl_init(); n = gl_steps[i]; if (k < 0 || k >= n) flint_abort(); if (2 * k < n) kk = k; else kk = n - 1 - k; if (gl_cache->gl_prec[i] < prec) { if (gl_cache->gl_prec[i] == 0) { gl_cache->gl_nodes[i] = _arb_vec_init((n + 1) / 2); gl_cache->gl_weights[i] = _arb_vec_init((n + 1) / 2); } wp = FLINT_MAX(prec, gl_cache->gl_prec[i] * 2 + 30); for (jj = 0; 2 * jj < n; jj++) { arb_hypgeom_legendre_p_ui_root(gl_cache->gl_nodes[i] + jj, gl_cache->gl_weights[i] + jj, n, jj, wp); } gl_cache->gl_prec[i] = wp; } if (2 * k < n) arb_set_round(x, gl_cache->gl_nodes[i] + kk, prec); else arb_neg_round(x, gl_cache->gl_nodes[i] + kk, prec); arb_set_round(w, gl_cache->gl_weights[i] + kk, prec); } int acb_calc_integrate_gl_auto_deg(acb_t res, slong * eval_count, acb_calc_func_t f, void * param, const acb_t a, const acb_t b, const mag_t tol, slong deg_limit, int verbose, slong prec) { acb_t mid, delta, wide; mag_t tmpm; slong status; acb_t s, v; mag_t M, X, Y, rho, err, t, best_rho; slong k, Xexp; slong i, n, best_n; status = ARB_CALC_NO_CONVERGENCE; if (deg_limit <= 0) { acb_indeterminate(res); eval_count[0] = 0; return status; } acb_init(mid); acb_init(delta); acb_init(wide); mag_init(tmpm); /* delta = (b-a)/2 */ acb_sub(delta, b, a, prec); acb_mul_2exp_si(delta, delta, -1); /* mid = (a+b)/2 */ acb_add(mid, a, b, prec); acb_mul_2exp_si(mid, mid, -1); acb_init(s); acb_init(v); mag_init(M); mag_init(X); mag_init(Y); mag_init(rho); mag_init(t); mag_init(err); mag_init(best_rho); best_n = -1; eval_count[0] = 0; mag_inf(err); for (Xexp = 0; Xexp < prec /* && Xexp == 0 */; Xexp += FLINT_MAX(1, Xexp)) { mag_one(X); mag_mul_2exp_si(X, X, Xexp + 1); /* rho = X + sqrt(X^2 - 1) (lower bound) */ mag_mul_lower(rho, X, X); mag_one(t); mag_sub_lower(rho, rho, t); mag_sqrt_lower(rho, rho); mag_add_lower(rho, rho, X); /* Y = sqrt(X^2 - 1) (upper bound) */ mag_mul(Y, X, X); mag_one(t); mag_sub(Y, Y, t); mag_sqrt(Y, Y); acb_zero(wide); mag_set(arb_radref(acb_realref(wide)), X); mag_set(arb_radref(acb_imagref(wide)), Y); /* transform to [a,b] */ acb_mul(wide, wide, delta, prec); acb_add(wide, wide, mid, prec); f(v, wide, param, 1, prec); eval_count[0]++; /* no chance */ if (!acb_is_finite(v)) break; /* M = (b-a)/2 |f| */ acb_get_mag(M, v); acb_get_mag(tmpm, delta); mag_mul(M, M, tmpm); /* Search for the smallest n that gives err < tol (if possible) */ for (i = 0; i < GL_STEPS && gl_steps[i] <= deg_limit; i++) { n = gl_steps[i]; /* (64/15) M / ((rho-1) rho^(2n-1)) */ mag_pow_ui_lower(t, rho, 2 * n - 1); mag_one(tmpm); mag_sub_lower(tmpm, rho, tmpm); mag_mul_lower(t, t, tmpm); mag_mul_ui_lower(t, t, 15); mag_div(t, M, t); mag_mul_2exp_si(t, t, 6); if (mag_cmp(t, tol) < 0) { status = ARB_CALC_SUCCESS; /* The best so far. */ if (best_n == -1 || n < best_n) { mag_set(err, t); mag_set(best_rho, rho); best_n = n; } /* Best possible n. */ if (n == 1) break; } } } /* Evaluate best found Gauss-Legendre quadrature rule. */ if (status == ARB_CALC_SUCCESS) { arb_t x, w; arb_init(x); arb_init(w); if (verbose) { acb_get_mag(tmpm, delta); flint_printf(" {GL deg %wd on [", best_n); acb_printn(a, 10, ARB_STR_NO_RADIUS); flint_printf(", "); acb_printn(b, 10, ARB_STR_NO_RADIUS); flint_printf("], delta "); mag_printd(tmpm, 5); flint_printf(", rho "); mag_printd(best_rho, 5); flint_printf(", tol "); mag_printd(tol, 3); flint_printf("}\n"); } if (best_n == -1) flint_abort(); for (i = 0; i < GL_STEPS; i++) if (gl_steps[i] == best_n) break; acb_zero(s); for (k = 0; k < best_n; k++) { acb_calc_gl_node(x, w, i, k, prec); acb_mul_arb(wide, delta, x, prec); acb_add(wide, wide, mid, prec); f(v, wide, param, 0, prec); acb_addmul_arb(s, v, w, prec); } eval_count[0] += best_n; acb_mul(res, s, delta, prec); acb_add_error_mag(res, err); arb_clear(x); arb_clear(w); } else { acb_indeterminate(res); } acb_clear(s); acb_clear(v); mag_clear(M); mag_clear(X); mag_clear(Y); mag_clear(rho); mag_clear(t); mag_clear(err); mag_clear(best_rho); acb_clear(mid); acb_clear(delta); acb_clear(wide); mag_clear(tmpm); return status; } arb-2.22.1/acb_calc/integrate_opt_init.c000066400000000000000000000011471417376376500201320ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_calc.h" void acb_calc_integrate_opt_init(acb_calc_integrate_opt_t options) { options->deg_limit = 0; options->eval_limit = 0; options->depth_limit = 0; options->use_heap = 0; options->verbose = 0; } arb-2.22.1/acb_calc/integrate_taylor.c000066400000000000000000000147201417376376500176200ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_calc.h" #include "math.h" int acb_calc_integrate_taylor(acb_t res, acb_calc_func_t func, void * param, const acb_t a, const acb_t b, const arf_t inner_radius, const arf_t outer_radius, slong accuracy_goal, slong prec) { slong num_steps, step, N, bp; int result; acb_t delta, m, x, y1, y2, sum; acb_ptr taylor_poly; arf_t err; acb_init(delta); acb_init(m); acb_init(x); acb_init(y1); acb_init(y2); acb_init(sum); arf_init(err); acb_sub(delta, b, a, prec); /* precision used for bounds calculations */ bp = MAG_BITS; /* compute the number of steps */ { arf_t t; arf_init(t); acb_get_abs_ubound_arf(t, delta, bp); arf_div(t, t, inner_radius, bp, ARF_RND_UP); arf_mul_2exp_si(t, t, -1); num_steps = (slong) (arf_get_d(t, ARF_RND_UP) + 1.0); /* make sure it's not something absurd */ num_steps = FLINT_MIN(num_steps, 10 * prec); num_steps = FLINT_MAX(num_steps, 1); arf_clear(t); } result = ARB_CALC_SUCCESS; acb_zero(sum); for (step = 0; step < num_steps; step++) { /* midpoint of subinterval */ acb_mul_ui(m, delta, 2 * step + 1, prec); acb_div_ui(m, m, 2 * num_steps, prec); acb_add(m, m, a, prec); if (arb_calc_verbose) { flint_printf("integration point %wd/%wd: ", 2 * step + 1, 2 * num_steps); acb_printd(m, 15); flint_printf("\n"); } /* evaluate at +/- x */ /* TODO: exactify m, and include error in x? */ acb_div_ui(x, delta, 2 * num_steps, prec); /* compute bounds and number of terms to use */ { arb_t cbound, xbound, rbound; arf_t C, D, R, X, T; double DD, TT, NN; arb_init(cbound); arb_init(xbound); arb_init(rbound); arf_init(C); arf_init(D); arf_init(R); arf_init(X); arf_init(T); /* R is the outer radius */ arf_set(R, outer_radius); /* X = upper bound for |x| */ acb_get_abs_ubound_arf(X, x, bp); arb_set_arf(xbound, X); /* Compute C(m,R). Important subtlety: due to rounding when computing m, we will in general be farther than R away from the integration path. But since acb_calc_cauchy_bound actually integrates over the area traced by a complex interval, it will catch any extra singularities (giving an infinite bound). */ arb_set_arf(rbound, outer_radius); acb_calc_cauchy_bound(cbound, func, param, m, rbound, 8, bp); arf_set_mag(C, arb_radref(cbound)); arf_add(C, arb_midref(cbound), C, bp, ARF_RND_UP); /* Sanity check: we need C < inf and R > X */ if (arf_is_finite(C) && arf_cmp(R, X) > 0) { /* Compute upper bound for D = C * R * X / (R - X) */ arf_mul(D, C, R, bp, ARF_RND_UP); arf_mul(D, D, X, bp, ARF_RND_UP); arf_sub(T, R, X, bp, ARF_RND_DOWN); arf_div(D, D, T, bp, ARF_RND_UP); /* Compute upper bound for T = (X / R) */ arf_div(T, X, R, bp, ARF_RND_UP); /* Choose N */ /* TODO: use arf arithmetic to avoid overflow */ /* TODO: use relative accuracy (look at |f(m)|?) */ DD = arf_get_d(D, ARF_RND_UP); TT = arf_get_d(T, ARF_RND_UP); NN = -(accuracy_goal * 0.69314718055994530942 + log(DD)) / log(TT); N = NN + 0.5; N = FLINT_MIN(N, 100 * prec); N = FLINT_MAX(N, 1); /* Tail bound: D / (N + 1) * T^N */ { mag_t TT; mag_init(TT); arf_get_mag(TT, T); mag_pow_ui(TT, TT, N); arf_set_mag(T, TT); mag_clear(TT); } arf_mul(D, D, T, bp, ARF_RND_UP); arf_div_ui(err, D, N + 1, bp, ARF_RND_UP); } else { N = 1; arf_pos_inf(err); result = ARB_CALC_NO_CONVERGENCE; } if (arb_calc_verbose) { flint_printf("N = %wd; bound: ", N); arf_printd(err, 15); flint_printf("\n"); flint_printf("R: "); arf_printd(R, 15); flint_printf("\n"); flint_printf("C: "); arf_printd(C, 15); flint_printf("\n"); flint_printf("X: "); arf_printd(X, 15); flint_printf("\n"); } arb_clear(cbound); arb_clear(xbound); arb_clear(rbound); arf_clear(C); arf_clear(D); arf_clear(R); arf_clear(X); arf_clear(T); } /* evaluate Taylor polynomial */ taylor_poly = _acb_vec_init(N + 1); func(taylor_poly, m, param, N, prec); _acb_poly_integral(taylor_poly, taylor_poly, N + 1, prec); _acb_poly_evaluate(y2, taylor_poly, N + 1, x, prec); acb_neg(x, x); _acb_poly_evaluate(y1, taylor_poly, N + 1, x, prec); acb_neg(x, x); /* add truncation error */ arb_add_error_arf(acb_realref(y1), err); arb_add_error_arf(acb_imagref(y1), err); arb_add_error_arf(acb_realref(y2), err); arb_add_error_arf(acb_imagref(y2), err); acb_add(sum, sum, y2, prec); acb_sub(sum, sum, y1, prec); if (arb_calc_verbose) { flint_printf("values: "); acb_printd(y1, 15); flint_printf(" "); acb_printd(y2, 15); flint_printf("\n"); } _acb_vec_clear(taylor_poly, N + 1); if (result == ARB_CALC_NO_CONVERGENCE) break; } acb_set(res, sum); acb_clear(delta); acb_clear(m); acb_clear(x); acb_clear(y1); acb_clear(y2); acb_clear(sum); arf_clear(err); return result; } arb-2.22.1/acb_calc/test/000077500000000000000000000000001417376376500150535ustar00rootroot00000000000000arb-2.22.1/acb_calc/test/t-cauchy_bound.c000066400000000000000000000042101417376376500201200ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_calc.h" /* sin(x) */ int sin_x(acb_ptr out, const acb_t inp, void * params, slong order, slong prec) { int xlen = FLINT_MIN(2, order); acb_set(out, inp); if (xlen > 1) acb_one(out + 1); _acb_poly_sin_series(out, out, xlen, order, prec); return 0; } static const double answers[10] = { 1.04570093561423094, 2.0358667496686487, 4.82706400405656566, 11.2347033850581819, 27.1331828778516522, 67.210305990439042, 168.564351176369878, 427.496180295369909, 1093.56959348921777, 2815.70144392142227 }; int main() { slong iter; flint_rand_t state; flint_printf("cauchy_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_t b, radius, ans; acb_t x; slong r, prec, maxdepth; arb_init(b); arb_init(radius); arb_init(ans); acb_init(x); acb_set_ui(x, 5); r = 1 + n_randint(state, 10); arb_set_ui(radius, r); prec = 2 + n_randint(state, 100); maxdepth = n_randint(state, 10); acb_calc_cauchy_bound(b, sin_x, NULL, x, radius, maxdepth, prec); arf_set_d(arb_midref(ans), answers[r-1]); mag_set_d(arb_radref(ans), 1e-8); if (!arb_overlaps(b, ans)) { flint_printf("FAIL\n"); flint_printf("r = %wd, prec = %wd, maxdepth = %wd\n\n", r, prec, maxdepth); arb_printd(b, 15); flint_printf("\n\n"); arb_printd(ans, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(b); arb_clear(radius); arb_clear(ans); acb_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_calc/test/t-integrate.c000066400000000000000000000520371417376376500174510ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_calc.h" int f_zero(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_zero(res); return 0; } int f_indet(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_indeterminate(res); return 0; } int f_cube(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_cube(res, z, prec); return 0; } int f_sin(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_sin(res, z, prec); return 0; } int f_sqrt(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_sqrt_analytic(res, z, order != 0, prec); return 0; } int f_rsqrt(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_rsqrt_analytic(res, z, order != 0, prec); return 0; } int f_log(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_log_analytic(res, z, order != 0, prec); return 0; } int f_pow_pi(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_const_pi(res, prec); acb_pow_analytic(res, z, res, order != 0, prec); return 0; } int f_circle(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_one(res); acb_submul(res, z, z, prec); acb_real_sqrtpos(res, res, order != 0, prec); return 0; } /* f(z) = sin(z + exp(z)) -- Rump's oscillatory example */ int f_rump(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_exp(res, z, prec); acb_add(res, res, z, prec); acb_sin(res, res, prec); return 0; } /* f(z) = |z^4 + 10z^3 + 19z^2 - 6z - 6| exp(z) (for real z) -- Helfgott's integral on MathOverflow */ int f_helfgott(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_add_si(res, z, 10, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, 19, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, -6, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, -6, prec); acb_real_abs(res, res, order != 0, prec); if (acb_is_finite(res)) { acb_t t; acb_init(t); acb_exp(t, z, prec); acb_mul(res, res, t, prec); acb_clear(t); } return 0; } /* f(z) = z sin(1/z), assume on real interval */ int f_essing2(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ if ((order == 0) && acb_is_real(z) && arb_contains_zero(acb_realref(z))) { /* todo: arb_zero_pm_one, arb_unit_interval? */ acb_zero(res); mag_one(arb_radref(acb_realref(res))); } else { acb_inv(res, z, prec); acb_sin(res, res, prec); } acb_mul(res, res, z, prec); return 0; } /* f(z) = sech(10(x-0.2))^2 + sech(100(x-0.4))^4 + sech(1000(x-0.6))^6 */ int f_spike(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t a, b, c; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(a); acb_init(b); acb_init(c); acb_mul_ui(a, z, 10, prec); acb_sub_ui(a, a, 2, prec); acb_sech(a, a, prec); acb_pow_ui(a, a, 2, prec); acb_mul_ui(b, z, 100, prec); acb_sub_ui(b, b, 40, prec); acb_sech(b, b, prec); acb_pow_ui(b, b, 4, prec); acb_mul_ui(c, z, 1000, prec); acb_sub_ui(c, c, 600, prec); acb_sech(c, c, prec); acb_pow_ui(c, c, 6, prec); acb_add(res, a, b, prec); acb_add(res, res, c, prec); acb_clear(a); acb_clear(b); acb_clear(c); return 0; } /* more tests for the individual acb_real_* functions */ /* abs(sin(x))*cos(1+x) */ int f_abs(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, c; acb_init(s); acb_init(c); acb_sin(s, z, prec); acb_add_ui(c, z, 1, prec); acb_cos(c, c, prec); acb_real_abs(s, s, order != 0, prec); acb_mul(res, s, c, prec); acb_clear(s); acb_clear(c); return 0; } /* sign(sin(x))*cos(1+x) */ int f_sgn(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, c; acb_init(s); acb_init(c); acb_sin(s, z, prec); acb_add_ui(c, z, 1, prec); acb_cos(c, c, prec); acb_real_sgn(s, s, order != 0, prec); acb_mul(res, s, c, prec); acb_clear(s); acb_clear(c); return 0; } /* heaviside(sin(x))*cos(1+x) */ int f_heaviside(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, c; acb_init(s); acb_init(c); acb_sin(s, z, prec); acb_add_ui(c, z, 1, prec); acb_cos(c, c, prec); acb_real_heaviside(s, s, order != 0, prec); acb_mul(res, s, c, prec); acb_clear(s); acb_clear(c); return 0; } /* floor(x-5) cos(1+x) */ int f_floor(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t c; acb_init(c); acb_add_ui(c, z, 1, prec); acb_cos(c, c, prec); acb_sub_ui(res, z, 5, prec); acb_real_floor(res, res, order != 0, prec); acb_mul(res, res, c, prec); acb_clear(c); return 0; } /* ceil(x-5) cos(1+x) */ int f_ceil(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t c; acb_init(c); acb_add_ui(c, z, 1, prec); acb_cos(c, c, prec); acb_sub_ui(res, z, 5, prec); acb_real_ceil(res, res, order != 0, prec); acb_mul(res, res, c, prec); acb_clear(c); return 0; } /* max(sin(x),cos(x)) */ int f_max(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, c; acb_init(s); acb_init(c); acb_sin_cos(s, c, z, prec); acb_real_max(res, s, c, order != 0, prec); acb_clear(s); acb_clear(c); return 0; } /* min(sin(x),cos(x)) */ int f_min(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, c; acb_init(s); acb_init(c); acb_sin_cos(s, c, z, prec); acb_real_min(res, s, c, order != 0, prec); acb_clear(s); acb_clear(c); return 0; } int main() { slong iter; flint_rand_t state; flint_printf("integrate...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t ans, res, a, b, t; slong goal, prec, abs_goal; mag_t tol; acb_calc_integrate_opt_t opt; int integral; acb_init(ans); acb_init(res); acb_init(a); acb_init(b); acb_init(t); mag_init(tol); acb_calc_integrate_opt_init(opt); goal = 2 + n_randint(state, 300); prec = 2 + n_randint(state, 300); abs_goal = n_randint(state, 300); mag_set_ui_2exp_si(tol, n_randint(state, 2), -abs_goal); opt->eval_limit = n_randint(state, 10000); if (n_randint(state, 2)) opt->depth_limit = n_randint(state, 100); if (n_randint(state, 2)) opt->deg_limit = n_randint(state, 100); opt->use_heap = n_randint(state, 2); integral = n_randint(state, 9); if (integral == 0) { acb_randtest(a, state, 1 + n_randint(state, 200), 2); acb_randtest(b, state, 1 + n_randint(state, 200), 2); acb_cos(ans, a, prec); acb_cos(res, b, prec); acb_sub(ans, ans, res, prec); acb_calc_integrate(res, f_sin, NULL, a, b, goal, tol, opt, prec); } else if (integral == 1) { acb_randtest(a, state, 1 + n_randint(state, 200), 2); acb_randtest(b, state, 1 + n_randint(state, 200), 2); acb_pow_ui(ans, a, 4, prec); acb_pow_ui(res, b, 4, prec); acb_sub(ans, res, ans, prec); acb_mul_2exp_si(ans, ans, -2); acb_calc_integrate(res, f_cube, NULL, a, b, goal, tol, opt, prec); } else if (integral == 2) { acb_zero(a); acb_one(b); acb_const_pi(ans, prec); acb_mul_2exp_si(ans, ans, -2); if (n_randint(state, 2)) { acb_swap(a, b); acb_neg(ans, ans); } acb_calc_integrate(res, f_circle, NULL, a, b, goal, tol, opt, prec); } else if (integral == 3) { acb_zero(a); acb_one(b); acb_zero(ans); arb_set_str(acb_realref(ans), "0.3785300171241613098817352756283519095343133 +/- 1e-40", prec); if (n_randint(state, 2)) { acb_swap(a, b); acb_neg(ans, ans); } acb_calc_integrate(res, f_essing2, NULL, a, b, goal, tol, opt, prec); } else if (integral == 4) { acb_zero(a); acb_one(b); acb_zero(ans); arb_set_str(acb_realref(ans), "11.147310550057139733915902084255301415775813549800589418261584268232061665808482234384871404010464 +/- 2.28e-97", prec); if (n_randint(state, 2)) { acb_swap(a, b); acb_neg(ans, ans); } acb_calc_integrate(res, f_helfgott, NULL, a, b, goal, tol, opt, prec); } else if (integral == 5) { acb_zero(a); acb_set_ui(b, 8); acb_zero(ans); arb_set_str(acb_realref(ans), "0.34740017265724780787951215911989312465745625486618018388549271361674821398878532052968510434660 +/- 5.97e-96", prec); if (n_randint(state, 2)) { acb_swap(a, b); acb_neg(ans, ans); } acb_calc_integrate(res, f_rump, NULL, a, b, goal, tol, opt, prec); } else if (integral == 6) { acb_zero(a); acb_one(b); acb_zero(ans); arb_set_str(acb_realref(ans), "0.21080273550054927737564325570572915436090918643678119034785050587872061312814550020505868926155764 +/- 3.72e-99", prec); if (n_randint(state, 2)) { acb_swap(a, b); acb_neg(ans, ans); } acb_calc_integrate(res, f_spike, NULL, a, b, goal, tol, opt, prec); } else if (integral == 7) { acb_randtest_special(a, state, 1 + n_randint(state, 200), 2); acb_randtest_special(b, state, 1 + n_randint(state, 200), 2); acb_zero(ans); acb_calc_integrate(res, f_zero, NULL, a, b, goal, tol, opt, prec); } else if (integral == 8) { acb_randtest_special(a, state, 1 + n_randint(state, 200), 2); acb_randtest_special(b, state, 1 + n_randint(state, 200), 2); acb_indeterminate(ans); acb_calc_integrate(res, f_indet, NULL, a, b, goal, tol, opt, prec); } if (!acb_overlaps(res, ans)) { flint_printf("FAIL! (iter = %wd)\n", iter); flint_printf("integral = %d, prec = %wd, goal = %wd\n", integral, prec, goal); flint_printf("a = "); acb_printn(a, 150, 0); flint_printf("\n"); flint_printf("b = "); acb_printn(b, 150, 0); flint_printf("\n"); flint_printf("res = "); acb_printn(res, 150, 0); flint_printf("\n\n"); flint_printf("ans = "); acb_printn(ans, 150, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(ans); acb_clear(res); acb_clear(a); acb_clear(b); acb_clear(t); mag_clear(tol); } /* more tests for the individual real extensions and branched functions */ { acb_t a, b, z, w; slong prec; mag_t tol; acb_init(a); acb_init(b); acb_init(z); acb_init(w); mag_init(tol); acb_zero(a); acb_set_ui(b, 10); prec = 53; mag_set_ui_2exp_si(tol, 1, -prec); acb_calc_integrate(z, f_abs, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "-1.3517710956465318592 +/- 1e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (abs)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_sgn, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "-4.8903066871045720895 +/- 1e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (sgn)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_heaviside, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "-3.3658839392315860266 +/- 1e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (heaviside)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_floor, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "-0.36232328857344524392 +/- 1e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 16) { flint_printf("FAIL (floor)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_ceil, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "-2.2037844799320452076 +/- 1e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 16) { flint_printf("FAIL (ceil)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_max, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "5.0817122161957375987 +/- 1e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (max)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_min, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "-3.7866617980086549598 +/- 1e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (min)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } prec = 64; mag_set_ui_2exp_si(tol, 1, -prec); acb_set_ui(a, 10); acb_set_ui(b, 11); acb_calc_integrate(z, f_sqrt, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "3.2400640614837366802 +/- 1.65e-20", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (sqrt)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_rsqrt, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "0.30869426037404103423 +/- 2.08e-21", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (rsqrt)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_log, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "2.3509970708416191445 +/- 1.47e-21", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (log)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_pow_pi, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "1619.0628341842463436 +/- 2.79e-17", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10) { flint_printf("FAIL (pow_pi)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_set_d_d(a, -10, -1); acb_set_d_d(b, -10, +1); acb_zero(w); acb_calc_integrate(z, f_sqrt, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_imagref(w), "0.15801534879296271761 +/- 4.91e-21", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 25) { flint_printf("FAIL (sqrt 2)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_rsqrt, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_imagref(w), "0.015762235473606564294 +/- 2.80e-22", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 25) { flint_printf("FAIL (rsqrt 2)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_log, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_imagref(w), "4.6084935666644999985 +/- 4.69e-20", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 25) { flint_printf("FAIL (log 2)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_calc_integrate(z, f_pow_pi, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_imagref(w), "-2660.1245860252382407 +/- 8.64e-18", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 25) { flint_printf("FAIL (pow_pi 2)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } prec = 100; mag_set_ui_2exp_si(tol, 1, -prec); acb_set_d_d(a, -100, -1); acb_set_d_d(b, -100, +2); acb_zero(w); acb_calc_integrate(z, f_log, NULL, a, b, prec, tol, NULL, prec); arb_set_str(acb_realref(w), "-3.12659390337983876281336380373 +/- 3.97e-30", prec); arb_set_str(acb_imagref(w), "13.8156605414673448203655975232 +/- 2.39e-29", prec); if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 25) { flint_printf("FAIL (log 3)\n"); flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n"); flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(z); acb_clear(w); mag_clear(tol); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_calc/test/t-integrate_taylor.c000066400000000000000000000050351417376376500210370ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_calc.h" /* sin(x) */ int sin_x(acb_ptr out, const acb_t inp, void * params, slong order, slong prec) { int xlen = FLINT_MIN(2, order); acb_set(out, inp); if (xlen > 1) acb_one(out + 1); _acb_poly_sin_series(out, out, xlen, order, prec); return 0; } int main() { slong iter; flint_rand_t state; flint_printf("integrate_taylor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 150 * arb_test_multiplier(); iter++) { acb_t ans, res, a, b; arf_t inr, outr; double t; slong goal, prec; acb_init(ans); acb_init(res); acb_init(a); acb_init(b); arf_init(inr); arf_init(outr); goal = 2 + n_randint(state, 300); prec = 2 + n_randint(state, 300); acb_randtest(a, state, 1 + n_randint(state, 200), 2); acb_randtest(b, state, 1 + n_randint(state, 200), 2); acb_cos(ans, a, prec); acb_cos(res, b, prec); acb_sub(ans, ans, res, prec); t = (1 + n_randint(state, 20)) / 10.0; arf_set_d(inr, t); arf_set_d(outr, t + (1 + n_randint(state, 20)) / 5.0); acb_calc_integrate_taylor(res, sin_x, NULL, a, b, inr, outr, goal, prec); if (!acb_overlaps(res, ans)) { flint_printf("FAIL! (iter = %wd)\n", iter); flint_printf("prec = %wd, goal = %wd\n", prec, goal); flint_printf("inr = "); arf_printd(inr, 15); flint_printf("\n"); flint_printf("outr = "); arf_printd(outr, 15); flint_printf("\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 15); flint_printf("\n"); flint_printf("res = "); acb_printd(res, 15); flint_printf("\n\n"); flint_printf("ans = "); acb_printd(ans, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(ans); acb_clear(res); acb_clear(a); acb_clear(b); arf_clear(inr); arf_clear(outr); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dft.h000066400000000000000000000206601417376376500141240ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_DFT_H #define ACB_DFT_H #ifdef ACB_DFT_INLINES_C #define ACB_DFT_INLINE #else #define ACB_DFT_INLINE static __inline__ #endif #include "acb.h" #include "dlog.h" #ifdef __cplusplus extern "C" { #endif void _acb_dft_naive(acb_ptr w, acb_srcptr v, slong dv, acb_srcptr z, slong dz, slong len, slong prec); void acb_dft_naive(acb_ptr w, acb_srcptr v, slong len, slong prec); void acb_dft_crt(acb_ptr w, acb_srcptr v, slong len, slong prec); void acb_dft_cyc(acb_ptr w, acb_srcptr v, slong len, slong prec); void acb_dft_rad2_inplace(acb_ptr v, int e, slong prec); void acb_dft_rad2(acb_ptr w, acb_srcptr v, int e, slong prec); void acb_dft_bluestein(acb_ptr w, acb_srcptr v, slong len, slong prec); void acb_dft_prod(acb_ptr w, acb_srcptr v, slong * cyc, slong num, slong prec); void acb_dft_rad2_inplace_threaded(acb_ptr v, int e, slong prec); void acb_dft_convol_naive(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec); void acb_dft_convol_dft(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec); void acb_dft_convol_rad2(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec); void acb_dft_convol_mullow(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec); void acb_dft_convol(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec); #define CRT_MAX 15 typedef struct { int num; nmod_t n; slong m[CRT_MAX]; ulong M[CRT_MAX]; ulong vM[CRT_MAX]; } crt_struct; typedef crt_struct crt_t[1]; void crt_init(crt_t c, ulong n); void crt_decomp(acb_ptr y, acb_srcptr x, slong dx, const crt_t c, ulong len); void crt_recomp(acb_ptr y, acb_srcptr x, const crt_t c, ulong len); typedef struct acb_dft_step_struct acb_dft_step_struct; typedef acb_dft_step_struct * acb_dft_step_ptr; typedef struct { slong n; acb_ptr z; int zclear; slong num; acb_dft_step_ptr cyc; } acb_dft_cyc_struct; typedef acb_dft_cyc_struct acb_dft_cyc_t[1]; typedef struct { int e; slong n; /* = 1 << e */ slong dv; slong nz; /* = n but could be bigger */ acb_ptr z; } acb_dft_rad2_struct; typedef acb_dft_rad2_struct acb_dft_rad2_t[1]; typedef struct { slong n; slong dv; acb_ptr z; /* z[k] = e(k^2/2n) */ acb_ptr g; /* g[k] = dft( z ) */ acb_dft_rad2_t rad2; } acb_dft_bluestein_struct; typedef acb_dft_bluestein_struct acb_dft_bluestein_t[1]; typedef struct { slong n; slong num; acb_dft_step_ptr cyc; } acb_dft_prod_struct; typedef acb_dft_prod_struct acb_dft_prod_t[1]; typedef struct { slong n; crt_t c; slong dv; /* then a product */ acb_dft_step_ptr cyc; } acb_dft_crt_struct; typedef acb_dft_crt_struct acb_dft_crt_t[1]; typedef struct { slong n; slong dv; int zclear; acb_ptr z; slong dz; } acb_dft_naive_struct; typedef acb_dft_naive_struct acb_dft_naive_t[1]; typedef struct { slong n; int type; union { acb_dft_rad2_t rad2; acb_dft_cyc_t cyc; acb_dft_prod_t prod; acb_dft_crt_t crt; acb_dft_naive_t naive; acb_dft_bluestein_t bluestein; } t; } acb_dft_pre_struct; typedef acb_dft_pre_struct acb_dft_pre_t[1]; /* covers both product and cyclic case */ struct acb_dft_step_struct { /* [G:H] */ slong m; /* card H */ slong M; slong dv; /* = M for prod, also = M if cyc is reordered */ /* pointer on some roots of unity, if needed */ acb_srcptr z; /* index of mM in z */ slong dz; /* dft to call on H */ acb_dft_pre_t pre; /* dft to call on G/H ? */ }; /*typedef acb_dft_pre_struct acb_dft_pre_t[1];*/ #define DFT_VERB 0 enum { DFT_NAIVE, DFT_CYC, DFT_PROD, DFT_CRT , DFT_RAD2 , DFT_CONV }; void acb_dft_step(acb_ptr w, acb_srcptr v, acb_dft_step_ptr cyc, slong num, slong prec); void acb_dft_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec); void acb_dft_inverse_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec); void acb_dft_naive_precomp(acb_ptr w, acb_srcptr v, const acb_dft_naive_t pol, slong prec); void acb_dft_cyc_precomp(acb_ptr w, acb_srcptr v, const acb_dft_cyc_t cyc, slong prec); void acb_dft_rad2_precomp_inplace(acb_ptr v, const acb_dft_rad2_t rad2, slong prec); void acb_dft_rad2_precomp(acb_ptr w, acb_srcptr v, const acb_dft_rad2_t rad2, slong prec); void acb_dft_crt_precomp(acb_ptr w, acb_srcptr v, const acb_dft_crt_t crt, slong prec); void acb_dft_prod_precomp(acb_ptr w, acb_srcptr v, const acb_dft_prod_t prod, slong prec); void acb_dft_bluestein_precomp(acb_ptr w, acb_srcptr v, const acb_dft_bluestein_t t, slong prec); void acb_dft_rad2_precomp_inplace_threaded(acb_ptr v, const acb_dft_rad2_t rad2, slong prec); void acb_dft_inverse_rad2_precomp_inplace(acb_ptr v, const acb_dft_rad2_t rad2, slong prec); void acb_dft_inverse_rad2_precomp(acb_ptr w, acb_srcptr v, const acb_dft_rad2_t rad2, slong prec); void acb_dft_convol_rad2_precomp(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, const acb_dft_rad2_t, slong prec); void _acb_dft_precomp_init(acb_dft_pre_t pre, slong dv, acb_ptr z, slong dz, slong len, slong prec); void acb_dft_precomp_init(acb_dft_pre_t pre, slong len, slong prec); void acb_dft_precomp_clear(acb_dft_pre_t pre); void acb_dft(acb_ptr w, acb_srcptr v, slong len, slong prec); void acb_dft_inverse(acb_ptr w, acb_srcptr v, slong len, slong prec); acb_dft_step_ptr _acb_dft_steps_prod(slong * m, slong num, slong prec); ACB_DFT_INLINE void acb_dft_prod_init(acb_dft_prod_t t, slong * cyc, slong num, slong prec) { t->num = num; t->cyc = _acb_dft_steps_prod(cyc, num, prec); } void acb_dft_prod_clear(acb_dft_prod_t t); void _acb_dft_cyc_init_z_fac(acb_dft_cyc_t t, n_factor_t fac, slong dv, acb_ptr z, slong dz, slong len, slong prec); void _acb_dft_cyc_init(acb_dft_cyc_t t, slong dv, slong len, slong prec); ACB_DFT_INLINE void acb_dft_cyc_init(acb_dft_cyc_t t, slong len, slong prec) { _acb_dft_cyc_init(t, 1, len, prec); } void acb_dft_cyc_clear(acb_dft_cyc_t t); void _acb_dft_naive_init(acb_dft_naive_t pol, slong dv, acb_ptr z, slong dz, slong len, slong prec); ACB_DFT_INLINE void acb_dft_naive_init(acb_dft_naive_t pol, slong len, slong prec) { _acb_dft_naive_init(pol, 1, NULL, 0, len, prec); } ACB_DFT_INLINE void acb_dft_naive_clear(acb_dft_naive_t pol) { if (pol->zclear) _acb_vec_clear(pol->z, pol->n); } void _acb_dft_rad2_init(acb_dft_rad2_t t, slong dv, int e, slong prec); ACB_DFT_INLINE void acb_dft_rad2_init(acb_dft_rad2_t t, int e, slong prec) { _acb_dft_rad2_init(t, 1, e, prec); } ACB_DFT_INLINE void acb_dft_rad2_clear(acb_dft_rad2_t t) { _acb_vec_clear(t->z, t->nz); } void _acb_dft_bluestein_init(acb_dft_bluestein_t t, slong dv, slong n, slong prec); ACB_DFT_INLINE void acb_dft_bluestein_init(acb_dft_bluestein_t t, slong n, slong prec) { _acb_dft_bluestein_init(t, 1, n, prec); } ACB_DFT_INLINE void acb_dft_bluestein_clear(acb_dft_bluestein_t t) { if (t->n != 0) { _acb_vec_clear(t->z, t->n); _acb_vec_clear(t->g, t->rad2->n); acb_dft_rad2_clear(t->rad2); } } void _acb_dft_crt_init(acb_dft_crt_t crt, slong dv, slong len, slong prec); void acb_dft_crt_init(acb_dft_crt_t crt, slong len, slong prec); void acb_dft_crt_clear(acb_dft_crt_t crt); /* utils, could be moved elsewhere */ ACB_DFT_INLINE void acb_swap_ri(acb_t x) { arb_swap(acb_realref(x), acb_imagref(x)); } ACB_DFT_INLINE void acb_vec_swap_ri(acb_ptr v, slong len) { slong k; for (k = 0; k < len; k++) acb_swap_ri(v + k); } ACB_DFT_INLINE void _acb_vec_kronecker_mul(acb_ptr z, acb_srcptr x, acb_srcptr y, slong len, slong prec) { slong k; for (k = 0; k < len; k++) acb_mul(z + k, x + k, y + k, prec); } ACB_DFT_INLINE void _acb_vec_kronecker_mul_step(acb_ptr z, acb_srcptr x, acb_srcptr y, slong step, slong len, slong prec) { slong k; for (k = 0; k < len; k++) { acb_mul(z + k, x + k, y + k * step, prec); } } ACB_DFT_INLINE void acb_vec_printd_index(acb_srcptr vec, slong len, slong digits) { slong i; for (i = 0; i < len; i++) { flint_printf("[%wd] ", i); acb_printd(vec + i, digits); flint_printf("\n"); } } #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_dft/000077500000000000000000000000001417376376500137475ustar00rootroot00000000000000arb-2.22.1/acb_dft/bluestein.c000066400000000000000000000071721417376376500161140ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" #include "acb_modular.h" /* z[k] = z^(k^2), z a 2n-th root of unity */ static void _acb_vec_bluestein_factors(acb_ptr z, slong n, slong prec) { /* this function is used mostly with prime-power n * so the set of squares has index 2 only. * computing an addition sequence does not considerably improve things */ if (n < 30) { slong k, k2; acb_ptr z2n; nmod_t n2; z2n = _acb_vec_init(2 * n); _acb_vec_unit_roots(z2n, -2 * n, 2 * n, prec); nmod_init(&n2, FLINT_MAX(2 * n, 1)); for (k = 0, k2 = 0; k < n; k++) { acb_set(z + k, z2n + k2); k2 = nmod_add(k2, 2 * k + 1, n2); } _acb_vec_clear(z2n, 2 * n); } else { nmod_t n2; slong k, k2, dk; slong * v, * s; acb_ptr t; s = flint_malloc(n * sizeof(slong)); v = flint_malloc((n + 1)* sizeof(slong)); t = _acb_vec_init(n + 1); nmod_init(&n2, 2 * n); for (k = 0; k < n; k++) v[k] = 0; for (k = 0, k2 = 0, dk = 1; k < n; k++) { s[k] = k2; if (k2 < n) v[k2] = -1; else v[2 * n - k2] = -1; k2 = nmod_add(k2, dk, n2); dk = nmod_add(dk, 2, n2); } acb_modular_fill_addseq(v, n); acb_one(t + 0); acb_unit_root(t + 1, 2 * n, prec); acb_conj(t + 1, t + 1); acb_set_si(t + n, -1); for (k = 2; k < n; k++) if (v[k]) acb_mul(t + k, t + v[k], t + k - v[k], prec); for (k = 0; k < n; k++) { if (s[k] <= n) acb_set(z + k, t + s[k]); else acb_conj(z + k, t + 2 * n - s[k]); } _acb_vec_clear(t, n + 1); flint_free(s); flint_free(v); } } void _acb_dft_bluestein_init(acb_dft_bluestein_t t, slong dv, slong n, slong prec) { acb_ptr z, g; slong k, n2; int e; t->n = n; t->dv = dv; if (n == 0) return; e = n_clog(2 * n - 1, 2); if (DFT_VERB) flint_printf("dft_bluestein: init z[2^%i]\n", e); acb_dft_rad2_init(t->rad2, e, prec); t->z = z = _acb_vec_init(n); _acb_vec_bluestein_factors(t->z, n, prec); n2 = t->rad2->n; t->g = g = _acb_vec_init(n2); acb_one(g + 0); for (k = 1; k < n; k++) { acb_conj(g + k, z + k); acb_set(g + n2 - k, g + k); } acb_dft_rad2_precomp_inplace(g, t->rad2, prec); } void acb_dft_bluestein_precomp(acb_ptr w, acb_srcptr v, const acb_dft_bluestein_t t, slong prec) { slong n = t->n, np = t->rad2->n, dv = t->dv; acb_ptr fp; if (n == 0) return; fp = _acb_vec_init(np); _acb_vec_kronecker_mul_step(fp, t->z, v, dv, n, prec); acb_dft_rad2_precomp_inplace(fp, t->rad2, prec); _acb_vec_kronecker_mul(fp, t->g, fp, np, prec); acb_dft_inverse_rad2_precomp_inplace(fp, t->rad2, prec); _acb_vec_kronecker_mul(w, t->z, fp, n, prec); _acb_vec_clear(fp, n); } void acb_dft_bluestein(acb_ptr w, acb_srcptr v, slong len, slong prec) { acb_dft_bluestein_t t; acb_dft_bluestein_init(t, len, prec); acb_dft_bluestein_precomp(w, v, t, prec); acb_dft_bluestein_clear(t); } arb-2.22.1/acb_dft/convol.c000066400000000000000000000016541417376376500154210ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" static int use_dft(slong len, slong prec) { slong l2 = len; while (l2 >= 16) l2 >>= 1; if (l2 < 11) { while (!(len & 1)) len >>= 1; while (len % 3 == 0) len /= 3; while (len % 5 == 0) len /= 5; while (len % 7 == 0) len /= 7; return (len == 1); } return 0; } void acb_dft_convol(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) { if (use_dft(len, prec)) acb_dft_convol_dft(w, f, g, len, prec); else acb_dft_convol_rad2(w, f, g, len, prec); } arb-2.22.1/acb_dft/convol_dft.c000066400000000000000000000020711417376376500162500ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" void acb_dft_convol_dft_precomp(acb_ptr w, acb_srcptr f, acb_srcptr g, const acb_dft_pre_t pre, slong prec) { acb_ptr fp, gp; fp = _acb_vec_init(pre->n); gp = _acb_vec_init(pre->n); acb_dft_precomp(fp, f, pre, prec); acb_dft_precomp(gp, g, pre, prec); _acb_vec_kronecker_mul(gp, gp, fp, pre->n, prec); acb_dft_inverse_precomp(w, gp, pre, prec); _acb_vec_clear(fp, pre->n); _acb_vec_clear(gp, pre->n); } void acb_dft_convol_dft(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) { acb_dft_pre_t pre; acb_dft_precomp_init(pre, len, prec); acb_dft_convol_dft_precomp(w, f, g, pre, prec); acb_dft_precomp_clear(pre); } arb-2.22.1/acb_dft/convol_mullow.c000066400000000000000000000017401417376376500170140ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" #include "acb_poly.h" void acb_dft_convol_mullow(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) { /* TODO: should probably use (acb_struct *) arrays */ acb_ptr gg, ww; if (len == 0) return; gg = _acb_vec_init(2 * len - 1); ww = _acb_vec_init(2 * len - 1); _acb_vec_set(gg, g, len); _acb_vec_set(gg + len, g, len - 1); _acb_poly_mullow(ww, f, len, gg, 2 * len - 1, 2 * len - 1, prec); _acb_vec_set(w, ww + len, len - 1); acb_set(w + len - 1, ww + len - 1); _acb_vec_clear(gg, 2 * len - 1); _acb_vec_clear(ww, 2 * len - 1); } arb-2.22.1/acb_dft/convol_naive.c000066400000000000000000000014651417376376500166030ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" void acb_dft_convol_naive(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) { slong x, y; for (x = 0; x < len; x ++) { acb_ptr wx; acb_srcptr fx; wx = w + x; fx = f + x; acb_zero(wx); for (y = 0; y <= x; y++) acb_addmul(wx, fx - y, g + y, prec); for (; y < len; y++) acb_addmul(wx, fx + (len - y), g + y, prec); } } arb-2.22.1/acb_dft/convol_rad2.c000066400000000000000000000041211417376376500163210ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" /* assume np >= 2 * n - 1 */ void acb_dft_convol_pad(acb_ptr fp, acb_ptr gp, acb_srcptr f, acb_srcptr g, slong n, slong np) { slong k; if (np < 2 * n - 1) { flint_printf("dft_convol_pad: overlapping padding %wd < 2*%wd-1\n", np, n); abort(); } for (k = 0; k < n; k++) acb_set(gp + k, g + k); for (; k < np; k++) acb_zero(gp + k); for (k = 0; k < n; k++) acb_set(fp + k, f + k); for (k = 1; k < n; k++) acb_set(fp + np - k, f + n - k); for (k = n; k <= np - n; k++) acb_zero(fp + k); } void acb_dft_convol_rad2_precomp(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, const acb_dft_rad2_t rad2, slong prec) { slong np; acb_ptr fp, gp; np = rad2->n; if (len <= 0) return; fp = _acb_vec_init(np); gp = _acb_vec_init(np); if (len == np) { _acb_vec_set(fp, f, len); _acb_vec_set(gp, g, len); } else acb_dft_convol_pad(fp, gp, f, g, len, np); acb_dft_rad2_precomp_inplace(fp, rad2, prec); acb_dft_rad2_precomp_inplace(gp, rad2, prec); _acb_vec_kronecker_mul(gp, gp, fp, np, prec); acb_dft_inverse_rad2_precomp_inplace(gp, rad2, prec); _acb_vec_set(w, gp, len); _acb_vec_clear(fp, np); _acb_vec_clear(gp, np); } void acb_dft_convol_rad2(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) { int e; acb_dft_rad2_t dft; /* catch power of 2 */ if (len <= 0) return; else if ((len & (len - 1)) == 0) e = n_clog(len, 2); else e = n_clog(2 * len - 1, 2); acb_dft_rad2_init(dft, e, prec); acb_dft_convol_rad2_precomp(w, f, g, len, dft, prec); acb_dft_rad2_clear(dft); } arb-2.22.1/acb_dft/crt.c000066400000000000000000000111721417376376500147050ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" void crt_init(crt_t c, ulong n) { int k; n_factor_t fac; n_factor_init(&fac); if (n) n_factor(&fac, n, 1); else fac.num = 0; nmod_init(&c->n, FLINT_MAX(n, 1)); c->num = fac.num; for (k = 0; k < fac.num; k++) { c->m[k] = n_pow(fac.p[k], fac.exp[k]); c->M[k] = n / c->m[k]; c->vM[k] = c->M[k] * n_invmod(c->M[k] % c->m[k], c->m[k]); /* flint_printf("m[%ld]=%ld, M[%ld]=%wu, vM[%ld]=%wu\n", k, c->m[k], k, c->M[k], k, c->vM[k]); */ } } void crt_print(const crt_t c) { slong k; if (c->num == 0) { flint_printf("trivial group\n"); abort(); } for (k = 0; k < c->num; k++) flint_printf("Z/%wuZ ", c->m[k]); flint_printf("\n"); } #if 0 /* lexicographic index of crt elt j */ static ulong index_crt(crt_t c, ulong j) { int k; ulong res = 0; for (k = 0; k < c->num; k ++) res = res * c->m[k] + (j % c->m[k]); return res; } /* crt elt of lexicographic index i */ static ulong crt_index(crt_t c, ulong i) { int k; ulong j, res = 0; for (k = 0; k < c->num; k ++) { j = i % c->m[k]; i = i / c->m[k]; res = nmod_add(res, j * c->vM[k], c->n); } return res; } /* for all elements can do fast conrey-like loop just adding vM[k] */ static acb_ptr reorder_to_crt(acb_srcptr v, crt_t c, ulong len) { ulong k; acb_ptr res; res = flint_malloc(len * sizeof(acb_struct)); for (k = 0; k < len; k++) res[index_crt(c, k)] = v[k]; return res; } static acb_ptr reorder_from_crt(acb_srcptr v, crt_t c, ulong len) { ulong k; acb_ptr res; res = flint_malloc(len * sizeof(acb_struct)); for (k = 0; k < len; k++) res[k] = v[index_crt(c, k)]; return res; } #endif void crt_decomp(acb_ptr y, acb_srcptr x, slong dv, const crt_t c, ulong len) { int j, e[CRT_MAX]; ulong k, l; for (j = 0; j < c->num; j++) e[j] = 0; l = 0; for(k = 0; k < len; k++) { acb_set(y + k, x + l * dv); for (j = c->num - 1; j >= 0; e[j] = 0, j--) { e[j]++; l = nmod_add(l, c->vM[j], c->n); if (e[j] < c->m[j]) break; } } } void crt_recomp(acb_ptr y, acb_srcptr x, const crt_t c, ulong len) { int j, e[CRT_MAX]; ulong k, l; for (j = 0; j < c->num; j++) e[j] = 0; l = 0; for(k = 0; k < len; k++) { acb_set(y + l, x + k); for (j = c->num - 1; j >= 0; e[j] = 0, j--) { e[j]++; l = nmod_add(l, c->M[j], c->n); if (e[j] < c->m[j]) break; } } } void _acb_dft_crt_init(acb_dft_crt_t crt, slong dv, slong len, slong prec) { crt->n = len; crt_init(crt->c, len); crt->dv = dv; crt->cyc = _acb_dft_steps_prod(crt->c->m, crt->c->num, prec); } void acb_dft_crt_init(acb_dft_crt_t crt, slong len, slong prec) { crt->n = len; crt_init(crt->c, len); crt->dv = 1; crt->cyc = _acb_dft_steps_prod(crt->c->m, crt->c->num, prec); } void acb_dft_crt_clear(acb_dft_crt_t crt) { slong i; for (i = 0; i < crt->c->num; i++) acb_dft_precomp_clear(crt->cyc[i].pre); flint_free(crt->cyc); } void acb_dft_crt_precomp(acb_ptr w, acb_srcptr v, const acb_dft_crt_t crt, slong prec) { if (crt->n <= 1) { if (crt->n == 1) acb_set(w, v); } else { acb_ptr t; t = _acb_vec_init(crt->n); if (w == v) { _acb_vec_set(t, v, crt->n); v = t; } crt_decomp(w, v, crt->dv, crt->c, crt->n); acb_dft_step(t, w, crt->cyc, crt->c->num, prec); crt_recomp(w, t, crt->c, crt->n); _acb_vec_clear(t, crt->n); } } void acb_dft_crt(acb_ptr w, acb_srcptr v, slong len, slong prec) { if (len <= 1) { if (len == 1) acb_set(w, v); } else { crt_t c; acb_ptr t; t = _acb_vec_init(len); if (w == v) { _acb_vec_set(t, v, len); v = t; } crt_init(c, len); crt_decomp(w, v, 1, c, len); acb_dft_prod(t, w, c->m, c->num, prec); crt_recomp(w, t, c, len); _acb_vec_clear(t, len); } } arb-2.22.1/acb_dft/cyc.c000066400000000000000000000056261417376376500147020ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" void _acb_dft_cyc_init_z_fac(acb_dft_cyc_t t, n_factor_t fac, slong dv, acb_ptr z, slong dz, slong len, slong prec) { slong i, j, num; t->n = len; num = 0; for (i = 0; i < fac.num; i++) num += fac.exp[i]; t->num = num; t->cyc = flint_malloc(num * sizeof(acb_dft_step_struct)); if (z == NULL) { if (DFT_VERB) flint_printf("dft_cyc: init z[%wu]\n", t->n); z = _acb_vec_init(t->n); _acb_vec_unit_roots(z, -t->n, t->n, prec); dz = 1; t->zclear = 1; } else { if (DFT_VERB) flint_printf("dft_cyc: roots of order %wu already computed\n", t->n); t->zclear = 0; } t->z = z; num = 0; for (i = 0; i < fac.num; i++) { for (j = 0; j < fac.exp[i]; j++) { slong m, M; m = fac.p[i]; M = (len /= m); t->cyc[num].m = m; t->cyc[num].M = M; t->cyc[num].dv = dv; t->cyc[num].z = z; t->cyc[num].dz = dz; /* TODO: ugly, reorder should solve this */ if (num == t->num - 1) _acb_dft_precomp_init(t->cyc[num].pre, dv, z, dz, m, prec); else _acb_dft_precomp_init(t->cyc[num].pre, M, z, dz * M, m, prec); dv *= m; dz *= m; num++; } } } void _acb_dft_cyc_init(acb_dft_cyc_t t, slong dv, slong len, slong prec) { n_factor_t fac; n_factor_init(&fac); if (len) n_factor(&fac, len, 1); else fac.num = 0; _acb_dft_cyc_init_z_fac(t, fac, dv, NULL, 0, len, prec); } void acb_dft_cyc_clear(acb_dft_cyc_t t) { slong i; for (i = 0; i < t->num; i++) acb_dft_precomp_clear(t->cyc[i].pre); if (t->zclear) _acb_vec_clear(t->z, t->n); flint_free(t->cyc); } void acb_dft_cyc_precomp(acb_ptr w, acb_srcptr v, const acb_dft_cyc_t cyc, slong prec) { if (cyc->num == 0) { if (cyc->n == 1) acb_set(w, v); } else acb_dft_step(w, v, cyc->cyc, cyc->num, prec); } void acb_dft_cyc(acb_ptr w, acb_srcptr v, slong len, slong prec) { acb_dft_cyc_t cyc; acb_dft_cyc_init(cyc, len, prec); acb_dft_cyc_precomp(w, v, cyc, prec); acb_dft_cyc_clear(cyc); } void acb_dft_inverse_cyc(acb_ptr w, acb_srcptr v, slong len, slong prec) { /* divide before to keep v const */ _acb_vec_scalar_div_ui(w, v, len, len, prec); acb_vec_swap_ri(w, len); acb_dft_cyc(w, w, len, prec); acb_vec_swap_ri(w, len); } arb-2.22.1/acb_dft/naive.c000066400000000000000000000043271417376376500152230ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_dft.h" /* all roots are already computed, w != v */ void _acb_dft_naive(acb_ptr w, acb_srcptr v, slong dv, acb_srcptr z, slong dz, slong len, slong prec) { slong i, j; acb_ptr wi, v1 = NULL; acb_srcptr vj; if (w == v) { flint_printf("\n_acb_dft_naive: does not accept aliasing\n"); abort(); } for (i = 0, wi = w; i < len; i++, wi++) { acb_zero(wi); for (j = 0, vj = v; j < len; j++, vj += dv) acb_addmul(wi, vj, z + dz * (i * j % len), prec); } if (v1) _acb_vec_clear(v1, len); } void acb_dft_naive_precomp(acb_ptr w, acb_srcptr v, const acb_dft_naive_t pol, slong prec) { if (v == w) { acb_ptr v1 = _acb_vec_init(pol->n); _acb_vec_set(v1, v, pol->n); _acb_dft_naive(w, v1, pol->dv, pol->z, pol->dz, pol->n, prec); _acb_vec_clear(v1, pol->n); } else _acb_dft_naive(w, v, pol->dv, pol->z, pol->dz, pol->n, prec); } void acb_dft_naive(acb_ptr w, acb_srcptr v, slong len, slong prec) { acb_ptr z, v1 = NULL; z = _acb_vec_init(len); _acb_vec_unit_roots(z, -len, len, prec); if (w == v) { v1 = _acb_vec_init(len); _acb_vec_set(v1, v, len); v = v1; } _acb_dft_naive(w, v, 1, z, 1, len, prec); if (v1) _acb_vec_clear(v1, len); _acb_vec_clear(z, len); } void _acb_dft_naive_init(acb_dft_naive_t pol, slong dv, acb_ptr z, slong dz, slong len, slong prec) { pol->n = len; pol->dv = dv; if (z == NULL) { if (DFT_VERB) flint_printf("dft_naive: init z[%wd]\n",len); pol->z = _acb_vec_init(len); _acb_vec_unit_roots(pol->z, -len, len, prec); pol->dz = 1; pol->zclear = 1; } else { pol->z = z; pol->dz = dz; pol->zclear = 0; } } arb-2.22.1/acb_dft/precomp.c000066400000000000000000000101751417376376500155640ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" void _acb_dft_precomp_init(acb_dft_pre_t pre, slong dv, acb_ptr z, slong dz, slong len, slong prec) { pre->n = len; if (len <= 1) { pre->type = DFT_NAIVE; _acb_dft_naive_init(pre->t.naive, dv, z, dz, len, prec); } else if (n_is_prime(len)) { if (len < 100) { pre->type = DFT_NAIVE; _acb_dft_naive_init(pre->t.naive, dv, z, dz, len, prec); } else { pre->type = DFT_CONV; /* FIXME: do not recompute the same bluestein * scheme if needed several times */ _acb_dft_bluestein_init(pre->t.bluestein, dv, len, prec); } } else { n_factor_t fac; n_factor_init(&fac); n_factor(&fac, len, 1); if (fac.num == 1) { /* TODO: could be p^e, or 2^e, but with dv shift */ if (fac.p[0] == 2) { pre->type = DFT_RAD2; _acb_dft_rad2_init(pre->t.rad2, dv, fac.exp[0], prec); } else { pre->type = DFT_CYC; _acb_dft_cyc_init_z_fac(pre->t.cyc, fac, dv, z, dz, len, prec); } } else { pre->type = DFT_CRT; _acb_dft_crt_init(pre->t.crt, dv, len, prec); } } } void acb_dft_precomp_init(acb_dft_pre_t pre, slong len, slong prec) { _acb_dft_precomp_init(pre, 1, NULL, 0, len, prec); } void acb_dft_precomp_clear(acb_dft_pre_t pre) { switch (pre->type) { case DFT_NAIVE: acb_dft_naive_clear(pre->t.naive); break; case DFT_CYC: acb_dft_cyc_clear(pre->t.cyc); break; case DFT_PROD: acb_dft_prod_clear(pre->t.prod); break; case DFT_CRT: acb_dft_crt_clear(pre->t.crt); break; case DFT_RAD2: acb_dft_rad2_clear(pre->t.rad2); break; case DFT_CONV: acb_dft_bluestein_clear(pre->t.bluestein); break; default: flint_printf("acb_dft_clear: unknown strategy code %i\n", pre->type); abort(); break; } } void acb_dft_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec) { switch (pre->type) { case DFT_NAIVE: acb_dft_naive_precomp(w, v, pre->t.naive, prec); break; case DFT_CYC: acb_dft_cyc_precomp(w, v, pre->t.cyc, prec); break; case DFT_PROD: acb_dft_prod_precomp(w, v, pre->t.prod, prec); break; case DFT_CRT: acb_dft_crt_precomp(w, v, pre->t.crt, prec); break; case DFT_RAD2: acb_dft_rad2_precomp(w, v, pre->t.rad2, prec); break; case DFT_CONV: acb_dft_bluestein_precomp(w, v, pre->t.bluestein, prec); break; default: flint_printf("acb_dft_precomp: unknown strategy code %i\n", pre->type); abort(); break; } } void acb_dft(acb_ptr w, acb_srcptr v, slong len, slong prec) { acb_dft_pre_t t; acb_dft_precomp_init(t, len, prec); acb_dft_precomp(w, v, t, prec); acb_dft_precomp_clear(t); } void acb_dft_inverse_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec) { slong k; acb_dft_precomp(w, v, pre, prec); for (k = 1; 2 * k < pre->n; k++) acb_swap(w + k, w + pre->n - k); _acb_vec_scalar_div_ui(w, w, pre->n, pre->n, prec); } void acb_dft_inverse(acb_ptr w, acb_srcptr v, slong len, slong prec) { slong k; acb_dft(w, v, len, prec); for (k = 1; 2 * k < len; k++) acb_swap(w + k, w + len - k); _acb_vec_scalar_div_ui(w, w, len, len, prec); } arb-2.22.1/acb_dft/prod.c000066400000000000000000000027141417376376500150630ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" acb_dft_step_ptr _acb_dft_steps_prod(slong * cyc, slong num, slong prec) { slong i, len; acb_dft_step_ptr s; s = flint_malloc(num * sizeof(acb_dft_step_struct)); len = 1; for (i = 0; i < num; i++) len *= cyc[i]; for (i = 0; i < num; i++) { slong m, M; m = cyc[i]; M = (len /= m); s[i].m = m; s[i].M = M; s[i].dv = M; s[i].dz = 0; s[i].z = NULL; _acb_dft_precomp_init(s[i].pre, M, NULL, 0, m, prec); } return s; } void acb_dft_prod_clear(acb_dft_prod_t t) { slong i; for (i = 0; i < t->num; i++) acb_dft_precomp_clear(t->cyc[i].pre); flint_free(t->cyc); } void acb_dft_prod_precomp(acb_ptr w, acb_srcptr v, const acb_dft_prod_t prod, slong prec) { if (prod->num >= 1) acb_dft_step(w, v, prod->cyc, prod->num, prec); } void acb_dft_prod(acb_ptr w, acb_srcptr v, slong * cyc, slong num, slong prec) { acb_dft_prod_t t; acb_dft_prod_init(t, cyc, num, prec); acb_dft_prod_precomp(w, v, t, prec); acb_dft_prod_clear(t); } arb-2.22.1/acb_dft/profile/000077500000000000000000000000001417376376500154075ustar00rootroot00000000000000arb-2.22.1/acb_dft/profile/p-convol.c000066400000000000000000000071621417376376500173160ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_dft.h" #include "flint/profiler.h" #define LOG 0 #define CSV 1 #define JSON 2 typedef void (*do_f) (acb_ptr z, acb_srcptr x, acb_srcptr y, slong len, slong prec); int main(int argc, char *argv[]) { int out; ulong n, nref, maxq = 5000; flint_rand_t state; slong r, nr; int l, nf = 5; do_f func[5] = { acb_dft_convol_naive, acb_dft_convol_dft, acb_dft_convol_rad2, acb_dft_convol_mullow, acb_dft_convol, }; char * name[5] = { "naive", "dft", "rad2", "mullow", "default" }; int i, ni = 14; ulong len[14] = { 60, 5*5*5, 131, 2*3*5*7, 256, 3*3*3*3*3, 2*2*2*43, 503, 2*2*2*101, 3001, 8192, 13*11*61, 10000, 101*103 }; char * factor[14] = { "2^2*3*5", "5^3", "131", "2*3*5*7", "2^8", "3^5", "2^3*43", "503", "2^3*101", "3001", "2^13", "11*13*61", "2^4*5^4", "101*103" }; slong ml[14] = { 20, 10, 10, 5, 5, 5, 3, 3, 2, 2, 1, 1, 1, 1}; int j, nj = 4; slong prec[4] = { 64, 128, 512, 1024 }; slong mp[4] = { 40, 20, 5, 2 }; if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } if (out == CSV) flint_printf("# %-12s, %7s, %7s, %7s\n","name", "prec", "len", "factor", "time"); flint_randinit(state); for (j = 0; j < nj; j++) { for (i = 0; i < ni; i++) { slong k, nm; acb_ptr u, v, w; nm = mp[j] * ml[i]; u = _acb_vec_init(len[i]); v = _acb_vec_init(len[i]); w = _acb_vec_init(len[i]); for (k = 0; k < len[i]; k++) { acb_randtest_precise(u + k, state, prec[j], 4); acb_randtest_precise(v + k, state, prec[j], 4); } if (out == LOG) flint_printf("%wu * CONV(%wu = %s), prec %wu....\n", nm, len[i], factor[i], prec[j]); for (l = 0; l < nf; l++) { slong m; if (len[i] > 1000 && l == 0) continue; if (out == LOG) flint_printf("%-14s ... ", name[l]); else if (out == CSV) flint_printf("%-12s, %7d, %8s, %7d, ", name[l], prec[j], len[i], factor[i]); else if (out == JSON) flint_printf("{ \"name\": \"%s\", \"prec\": %d, \"len\": %d, \"factor\": %s, \"time\": ", name[l], prec[j], len[i], factor[i]); TIMEIT_ONCE_START for (m = 0; m < nm; m++) func[l](w, u, v, len[i], prec[j]); TIMEIT_ONCE_STOP if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } _acb_vec_clear(u, len[i]); _acb_vec_clear(v, len[i]); _acb_vec_clear(w, len[i]); } } flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/acb_dft/profile/p-dft.c000066400000000000000000000074261417376376500165760ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_dft.h" #include "flint/profiler.h" #define LOG 0 #define CSV 1 #define JSON 2 typedef void (*do_f) (acb_ptr y, acb_srcptr x, slong len, slong prec); int main(int argc, char *argv[]) { int out; ulong n, nref, maxq = 5000; flint_rand_t state; slong r, nr; int l, nf = 5; do_f func[5] = { acb_dft_naive, acb_dft_crt, acb_dft_cyc, acb_dft_bluestein, acb_dft }; char * name[6] = { "naive", "crt", "cyc", "bluestein", "default", "precomp" }; int i, ni = 14; ulong len[14] = { 60, 5*5*5, 131, 2*3*5*7, 256, 3*3*3*3*3, 2*2*2*43, 503, 2*2*2*101, 3001, 8192, 13*11*61, 10000, 101*103 }; char * factor[14] = { "2^2*3*5", "5^3", "131", "2*3*5*7", "2^8", "3^5", "2^3*43", "503", "2^3*101", "3001", "2^13", "11*13*61", "2^4*5^4", "101*103" }; slong ml[14] = { 20, 10, 20, 20, 10, 10, 10, 5, 5, 5, 3, 3, 3, 3}; int j, nj = 4; slong prec[4] = { 64, 128, 512, 1024 }; slong mp[4] = { 40, 20, 5, 2 }; if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } if (out == CSV) flint_printf("# %-12s, %7s, %7s, %7s\n","name", "prec", "len", "factor", "time"); flint_randinit(state); for (j = 0; j < nj; j++) { for (i = 0; i < ni; i++) { slong k, nm; acb_ptr u, v; nm = mp[j] * ml[i]; u = _acb_vec_init(len[i]); v = _acb_vec_init(len[i]); for (k = 0; k < len[i]; k++) acb_randtest_precise(u + k, state, prec[j], 4); if (out == LOG) flint_printf("%wu * DFT(%wu = %s), prec %wu....\n", nm, len[i], factor[i], prec[j]); for (l = 0; l <= nf; l++) { slong m; if (len[i] > 300 && l == 0) continue; if (out == LOG) flint_printf("%-14s ... ", name[l]); else if (out == CSV) flint_printf("%-12s, %7d, %8s, %7d, ", name[l], prec[j], len[i], factor[i]); else if (out == JSON) flint_printf("{ \"name\": \"%s\", \"prec\": %d, \"len\": %d, \"factor\": %s, \"time\": ", name[l], prec[j], len[i], factor[i]); TIMEIT_ONCE_START if (l < nf) { for (m = 0; m < nm; m++) func[l](v, u, len[i], prec[j]); } else { acb_dft_pre_t t; acb_dft_precomp_init(t, len[i], prec[j]); for (m = 0; m < nm; m++) acb_dft_precomp(v, u, t, prec[j]); acb_dft_precomp_clear(t); } TIMEIT_ONCE_STOP if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } _acb_vec_clear(u, len[i]); _acb_vec_clear(v, len[i]); } } flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/acb_dft/rad2.c000066400000000000000000000060221417376376500147430ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" /* swap each element with one with bit-reversed index */ void acb_dft_rad2_reorder(acb_ptr v, slong n) { slong i, j, k, l; for (i = 0, l = n>>1; i < l; i++) { /* j = bit reversal of i */ for (k = 1, j = 0; k < n; k <<= 1) { j <<= 1; if (i & k) j |= 1; } if (i < j) acb_swap(v + i, v + j); else if (i > j) acb_swap(v + n - 1 - i, v + n - 1 - j); i++, j |= l; acb_swap(v + i, v + j); } } void _acb_dft_rad2_init(acb_dft_rad2_t t, slong dv, int e, slong prec) { if (e < 0) { flint_printf("acb_dft_rad2_init: need e >= 0"); abort(); } t->e = e; t->n = WORD(1) << e; t->dv = dv; t->nz = t->n >> 1; t->z = _acb_vec_init(t->nz); /* set n/2 roots of order n */ _acb_vec_unit_roots(t->z, -t->n, t->nz, prec); } /* remark: can use same rad2 with smaller power of 2 */ void acb_dft_rad2_precomp_inplace(acb_ptr v, const acb_dft_rad2_t rad2, slong prec) { if (flint_get_num_threads() > 1 && rad2-> e > 9) { acb_dft_rad2_precomp_inplace_threaded(v, rad2, prec); } else { slong j, k, l; slong n = rad2->n, nz = rad2->nz; acb_ptr p, vend = v + n, w = rad2->z; acb_t tmp; acb_init(tmp); acb_dft_rad2_reorder(v, n); for (k = 1, l = nz; k < n; k <<= 1, l >>= 1) for (p = v; p < vend; p += k) for (j = 0; j < nz; j += l, p++) { acb_mul(tmp, p + k, w + j, prec); acb_sub(p + k, p + 0, tmp, prec); acb_add(p + 0, p + 0, tmp, prec); } acb_clear(tmp); } } void acb_dft_inverse_rad2_precomp_inplace(acb_ptr v, const acb_dft_rad2_t rad2, slong prec) { slong k, n = rad2->n; acb_dft_rad2_precomp_inplace(v, rad2, prec); _acb_vec_scalar_mul_2exp_si(v, v, n, - rad2->e); for (k = 1; k < n / 2; k++) acb_swap(v + k, v + n - k); } void acb_dft_rad2_inplace(acb_ptr v, int e, slong prec) { acb_dft_rad2_t rad2; acb_dft_rad2_init(rad2, e, prec); acb_dft_rad2_precomp_inplace(v, rad2, prec); acb_dft_rad2_clear(rad2); } void acb_dft_rad2_precomp(acb_ptr w, acb_srcptr v, const acb_dft_rad2_t rad2, slong prec) { slong k; for (k = 0; k < rad2->n; k++, v += rad2->dv) acb_set(w + k, v + 0); acb_dft_rad2_precomp_inplace(w, rad2, prec); } void acb_dft_rad2(acb_ptr w, acb_srcptr v, int e, slong prec) { acb_dft_rad2_t rad2; acb_dft_rad2_init(rad2, e, prec); acb_dft_rad2_precomp(w, v, rad2, prec); acb_dft_rad2_clear(rad2); } arb-2.22.1/acb_dft/rad2_threaded.c000066400000000000000000000063401417376376500166060ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" #include "pthread.h" void acb_dft_rad2_reorder(acb_ptr v, slong n); typedef struct { acb_ptr v; acb_ptr vend; slong k; slong l; slong jstart; slong jend; acb_srcptr w; slong prec; } acb_dft_rad2_arg_t; void * _acb_dft_rad2_thread(void * arg_ptr) { acb_dft_rad2_arg_t arg = *((acb_dft_rad2_arg_t *) arg_ptr); slong j, rstart, pstep; acb_ptr p, r; acb_t tmp; acb_init(tmp); rstart = arg.jstart / arg.l; pstep = 2 * arg.k; for (p = arg.v; p < arg.vend; p += pstep) { for (r = p + rstart, j = arg.jstart; j < arg.jend; j += arg.l, r++) { acb_mul(tmp, r + arg.k, arg.w + j, arg.prec); acb_sub(r + arg.k, r + 0, tmp, arg.prec); acb_add(r + 0, r + 0, tmp, arg.prec); } } acb_clear(tmp); flint_cleanup(); return NULL; } void acb_dft_rad2_precomp_inplace_threaded(acb_ptr v, const acb_dft_rad2_t rad2, slong prec) { slong num_threads; pthread_t * threads; acb_dft_rad2_arg_t * args; slong t, logt, logk, logl; slong n = rad2->n; slong nz = rad2->nz; /* always n/2 ? */ slong logn = rad2->e; num_threads = FLINT_MIN(flint_get_num_threads(), nz); for (logt = 0; WORD(1) << (logt + 1) <= num_threads; logt++); t = WORD(1) << logt; threads = flint_malloc(sizeof(pthread_t) * t); args = flint_malloc(sizeof(acb_dft_rad2_arg_t) * t); acb_dft_rad2_reorder(v, n); for (logk = 0, logl = logn - 1; logk < logn; logk += 1, logl -= 1) { slong i, j, p; slong logpstep = logk + 1 + FLINT_MAX(0, logl - logt); slong logjstep = logl + FLINT_MIN(logk, logn - 1 - logt); slong pstep = WORD(1) << logpstep; slong jstep = WORD(1) << logjstep; i = 0; for (p = 0; p < n; p += pstep) { for (j = 0; j < nz ; j += jstep) { args[i].v = v + p; args[i].vend = v + p + pstep; args[i].jstart = j; args[i].jend = j + jstep; args[i].k = WORD(1) << logk; args[i].l = WORD(1) << logl; args[i].w = rad2->z; args[i].prec = prec; pthread_create(&threads[i], NULL, _acb_dft_rad2_thread, &args[i]); i++; } } if (i != t) { flint_printf("threaded dft error: unequal i=%wd t=%wd\n", i, t); flint_abort(); } for (i = 0; i < t; i++) { pthread_join(threads[i], NULL); } } flint_free(threads); flint_free(args); } void acb_dft_rad2_inplace_threaded(acb_ptr v, int e, slong prec) { acb_dft_rad2_t rad2; acb_dft_rad2_init(rad2, e, prec); acb_dft_rad2_precomp_inplace_threaded(v, rad2, prec); acb_dft_rad2_clear(rad2); } arb-2.22.1/acb_dft/step.c000066400000000000000000000042161417376376500150710ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" #define REORDER 0 void acb_dft_step(acb_ptr w, acb_srcptr v, acb_dft_step_ptr cyc, slong num, slong prec) { acb_dft_step_struct c; if (num == 0) return; c = cyc[0]; if (num == 1) { acb_dft_precomp(w, v, c.pre, prec); /*_acb_dft_base(w, v, c.dv, c.z, c.dz, c.m, prec);*/ } else { slong i, j; slong m = c.m, M = c.M, dv = c.dv, dz = c.dz; acb_srcptr z = c.z; acb_ptr t; #if REORDER acb_ptr w2; #endif t = _acb_vec_init(m * M); if (w == v) { _acb_vec_set(t, v, m * M); v = t; } /* m DFT of size M */ for (i = 0; i < m; i++) acb_dft_step(w + i * M, v + i * dv, cyc + 1, num - 1, prec); /* twiddle if non trivial product */ if (c.z != NULL) { acb_ptr wi; for (wi = w + M, i = 1; i < m; i++, wi += M) for (j = 1; j < M; j++) { if (DFT_VERB) flint_printf("z[%wu*%wu]",dz,i*j); acb_mul(wi + j, wi + j, z + dz * i * j, prec); } if (DFT_VERB) flint_printf("\n"); } #if REORDER /* reorder w to avoid dv shifts in next DFT */ w2 = flint_malloc(m * M * sizeof(acb_struct)); for (j = 0; j < M; j++) for (i = 0; i < m; i++) w2[j + M * i] = w[i + m * j]; #endif /* M DFT of size m */ for (j = 0; j < M; j++) acb_dft_precomp(t + m * j, w + j, c.pre, prec); /* reorder */ for (i = 0; i < m; i++) for (j = 0; j < M; j++) acb_set(w + j + M * i, t + i + m * j); _acb_vec_clear(t, m * M); } } arb-2.22.1/acb_dft/test/000077500000000000000000000000001417376376500147265ustar00rootroot00000000000000arb-2.22.1/acb_dft/test/t-convol.c000066400000000000000000000066451417376376500166460ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" typedef void (*do_f) (acb_ptr z, acb_srcptr x, acb_srcptr y, slong len, slong prec); void check_vec_eq_prec(acb_srcptr w1, acb_srcptr w2, slong len, slong prec, slong digits, ulong q, char f1[], char f2[]) { slong i; for (i = 0; i < len; i++) { if (!acb_overlaps(w1 + i, w2 + i)) { flint_printf("FAIL\n\n"); flint_printf("q = %wu, size = %wd\n", q, len); flint_printf("\nDFT differ from index %wd / %wd \n", i, len); flint_printf("\n%s =\n", f1); acb_vec_printd_index(w1, len, digits); flint_printf("\n%s =\n", f2); acb_vec_printd_index(w2, len, digits); flint_printf("\n\n"); abort(); } else if (!acb_is_zero(w1+i) && (acb_rel_accuracy_bits(w1 + i) < 30 || acb_rel_accuracy_bits(w2 + i) < 30)) { flint_printf("FAIL\n\n"); flint_printf("q = %wu\n", q); flint_printf("\nDFT inaccurate from index %wd / %wd \n", i, len); flint_printf("\n%s =\n", f1); acb_printd(w1 + i, digits); flint_printf("\n%s =\n", f2); acb_printd(w2 + i, digits); flint_printf("\nerrors %wd & %wd [prec = %wd]\n", acb_rel_accuracy_bits(w1 + i), acb_rel_accuracy_bits(w2 + i), prec); abort(); } } } int main() { slong k; slong prec = 100, digits = 30; slong nq = 17; ulong q[17] = { 0, 1, 2, 3, 4, 5, 6, 23, 10, 15, 30, 59, 256, 308, 335, 344, 961}; ulong nr = 5; flint_rand_t state; slong f, nf = 4; do_f func[4] = { acb_dft_convol_naive, acb_dft_convol_rad2, acb_dft_convol_dft, acb_dft_convol_mullow }; char * name[4] = { "naive", "rad2", "dft", "mullow" }; flint_printf("convol...."); fflush(stdout); flint_randinit(state); for (k = 0; k < nq + nr; k++) { slong i, len; acb_ptr z1, z2, x, y; if (k < nq) len = q[k]; else len = n_randint(state, 2000); z1 = _acb_vec_init(len); z2 = _acb_vec_init(len); x = _acb_vec_init(len); y = _acb_vec_init(len); for (i = 0; i < len; i++) { #if 1 acb_set_si(x + i, n_randint(state, 4 * len)); acb_set_si(y + i, n_randint(state, 4 * len)); #else acb_set_si_si(x + i, n_randint(state, 4 * len), n_randint(state, 4 * len)); acb_set_si_si(y + i, n_randint(state, 4 * len), n_randint(state, 4 * len)); #endif } for (f = 0; f < nf; f++) { acb_ptr z = (f == 0) ? z1 : z2; func[f](z, x, y, len, prec); if (f == 0) continue; check_vec_eq_prec(z1, z2, len, prec, digits, len, name[0], name[f]); } _acb_vec_clear(x, len); _acb_vec_clear(y, len); _acb_vec_clear(z1, len); _acb_vec_clear(z2, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dft/test/t-dft.c000066400000000000000000000116401417376376500161120ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" typedef void (*do_f) (acb_ptr w, acb_srcptr v, slong len, slong prec); void check_vec_eq_prec(acb_srcptr w1, acb_srcptr w2, slong len, slong prec, slong digits, ulong q, char d[], char f1[], char f2[]) { slong i; for (i = 0; i < len; i++) { if (!acb_overlaps(w1 + i, w2 + i)) { flint_printf("FAIL\n\n"); flint_printf("q = %wu, size = %wd\n", q, len); flint_printf("\nDFT %s differ from index %wd / %wd \n", d, i, len); flint_printf("\n%s =\n", f1); acb_vec_printd_index(w1, len, digits); flint_printf("\n%s =\n", f2); acb_vec_printd_index(w2, len, digits); flint_printf("\n\n"); abort(); } else if (!acb_is_zero(w1+i) && (acb_rel_accuracy_bits(w1 + i) < 30 || acb_rel_accuracy_bits(w2 + i) < 30)) { flint_printf("FAIL\n\n"); flint_printf("q = %wu\n", q); flint_printf("\nDFT inaccurate from index %wd / %wd \n", i, len); flint_printf("\n%s =\n", f1); acb_printd(w1 + i, digits); flint_printf("\n%s =\n", f2); acb_printd(w2 + i, digits); flint_printf("\nerrors %wd & %wd [prec = %wd]\n", acb_rel_accuracy_bits(w1 + i), acb_rel_accuracy_bits(w2 + i), prec); abort(); } } } int main() { slong k; slong prec = 100, digits = 30; slong nq = 19; ulong q[19] = { 0, 1, 2, 3, 4, 5, 6, 23, 10, 15, 16, 30, 59, 125, 308, 335, 525, 961, 1225}; slong nr = 5; flint_rand_t state; slong f, nf = 5; do_f func[5] = { acb_dft_naive, acb_dft_cyc, acb_dft_crt, acb_dft_bluestein, acb_dft }; char * name[5] = { "naive", "cyc", "crt", "bluestein", "default" }; flint_printf("dft...."); fflush(stdout); flint_randinit(state); /* cyclic dft */ for (k = 0; k < nq + nr; k++) { slong i, len, f0; acb_ptr v, w1, w2, w3; if (k < nq) len = q[k]; else len = n_randint(state, 1000); v = _acb_vec_init(len); w1 = _acb_vec_init(len); w2 = _acb_vec_init(len); w3 = _acb_vec_init(len); for (i = 0; i < len; i++) acb_set_si_si(v + i, i, 3 - i); /* avoid naive for long transforms */ f0 = (len > 50); for (f = f0; f < nf; f++) { acb_ptr w = (f == f0) ? w1 : w2; if (DFT_VERB) flint_printf("\n%s %wu\n", name[f], len); /* compute DFT */ func[f](w, v, len, prec); if (len < 500) { /* check aliasing */ _acb_vec_set(w3, v, len); func[f](w3, w3, len, prec); check_vec_eq_prec(w1, w3, len, prec, digits, len, "alias", name[0], name[f]); } if (f > f0) { /* check non aliased */ check_vec_eq_prec(w1, w2, len, prec, digits, len, "no alias", name[0], name[f]); } else { /* check inverse */ acb_dft_inverse(w2, w1, len, prec); check_vec_eq_prec(v, w2, len, prec, digits, len, "inverse", "original", "inverse"); } } _acb_vec_clear(v, len); _acb_vec_clear(w1, len); _acb_vec_clear(w2, len); _acb_vec_clear(w3, len); } /* radix2 dft */ for (k = 0; k < 11; k++) { slong n = 1 << k, j; acb_ptr v, w1, w2; v = w2 = _acb_vec_init(n); w1 = _acb_vec_init(n); for (j = 0; j < n; j++) acb_set_si_si(v + j, j, j + 2); acb_dft_cyc(w1, v, n, prec); acb_dft_rad2_inplace(w2, k, prec); check_vec_eq_prec(w1, w2, n, prec, digits, n, "rad2", "cyc", "rad2"); _acb_vec_clear(v, n); _acb_vec_clear(w1, n); } /* multi-threaded radix2 dft */ for (k = 0; k < 11; k++) { slong n = 1 << k, j; acb_ptr v, w1, w2; v = w2 = _acb_vec_init(n); w1 = _acb_vec_init(n); flint_set_num_threads(k % 5 + 1); for (j = 0; j < n; j++) acb_set_si_si(v + j, j, j + 2); acb_dft_cyc(w1, v, n, prec); acb_dft_rad2_inplace_threaded(w2, k, prec); check_vec_eq_prec(w1, w2, n, prec, digits, n, "rad2", "cyc", "rad2"); _acb_vec_clear(v, n); _acb_vec_clear(w1, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet.h000066400000000000000000000363421417376376500153220ustar00rootroot00000000000000/* Copyright (C) 2015 Jonathan Bober Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_DIRICHLET_H #define ACB_DIRICHLET_H #ifdef ACB_DIRICHLET_INLINES_C #define ACB_DIRICHLET_INLINE #else #define ACB_DIRICHLET_INLINE static __inline__ #endif #include "acb.h" #include "acb_poly.h" #include "dirichlet.h" #ifdef __cplusplus extern "C" { #endif void acb_dirichlet_powsum_term(acb_ptr res, arb_t log_prev, ulong * prev, const acb_t s, ulong k, int integer, int critical_line, slong len, slong prec); void acb_dirichlet_powsum_sieved(acb_ptr z, const acb_t s, ulong n, slong len, slong prec); void acb_dirichlet_powsum_smooth(acb_ptr z, const acb_t s, ulong n, slong len, slong prec); void acb_dirichlet_zeta_bound(mag_t res, const acb_t s); void acb_dirichlet_zeta_deriv_bound(mag_t der1, mag_t der2, const acb_t s); void acb_dirichlet_zeta_rs_f_coeffs(acb_ptr c, const arb_t p, slong N, slong prec); void acb_dirichlet_zeta_rs_d_coeffs(arb_ptr d, const arb_t sigma, slong k, slong prec); void acb_dirichlet_zeta_rs_bound(mag_t err, const acb_t s, slong K); void acb_dirichlet_zeta_rs_r(acb_t res, const acb_t s, slong K, slong prec); void acb_dirichlet_zeta_rs(acb_t res, const acb_t s, slong K, slong prec); void acb_dirichlet_zeta(acb_t res, const acb_t s, slong prec); void acb_dirichlet_zeta_jet_rs(acb_ptr res, const acb_t s, slong len, slong prec); void acb_dirichlet_zeta_jet(acb_t res, const acb_t s, int deflate, slong len, slong prec); void acb_dirichlet_hurwitz(acb_t res, const acb_t s, const acb_t a, slong prec); void acb_dirichlet_stieltjes(acb_t res, const fmpz_t n, const acb_t a, slong prec); typedef struct { acb_struct s; mag_struct err; acb_ptr coeffs; int deflate; slong A; slong N; slong K; } acb_dirichlet_hurwitz_precomp_struct; typedef acb_dirichlet_hurwitz_precomp_struct acb_dirichlet_hurwitz_precomp_t[1]; void acb_dirichlet_hurwitz_precomp_init(acb_dirichlet_hurwitz_precomp_t pre, const acb_t s, int deflate, slong A, slong K, slong N, slong prec); void acb_dirichlet_hurwitz_precomp_init_num(acb_dirichlet_hurwitz_precomp_t pre, const acb_t s, int deflate, double num_eval, slong prec); void acb_dirichlet_hurwitz_precomp_clear(acb_dirichlet_hurwitz_precomp_t pre); void acb_dirichlet_hurwitz_precomp_bound(mag_t res, const acb_t s, slong A, slong K, slong N); void acb_dirichlet_hurwitz_precomp_eval(acb_t res, const acb_dirichlet_hurwitz_precomp_t pre, ulong p, ulong q, slong prec); void acb_dirichlet_hurwitz_precomp_choose_param(ulong * A, ulong * K, ulong * N, const acb_t s, double num_eval, slong prec); void _acb_dirichlet_euler_product_real_ui(arb_t res, ulong s, const signed char * chi, int mod, int reciprocal, slong prec); void acb_dirichlet_eta(acb_t res, const acb_t s, slong prec); void acb_dirichlet_xi(acb_t res, const acb_t s, slong prec); void acb_dirichlet_pairing(acb_t res, const dirichlet_group_t G, ulong m, ulong n, slong prec); void acb_dirichlet_pairing_char(acb_t res, const dirichlet_group_t G, const dirichlet_char_t a, const dirichlet_char_t b, slong prec); /* precompute roots of unity */ typedef struct { ulong order; ulong reduced_order; acb_t z; slong size; slong depth; acb_ptr * Z; int use_pow; } acb_dirichlet_roots_struct; typedef acb_dirichlet_roots_struct acb_dirichlet_roots_t[1]; void acb_dirichlet_roots_init(acb_dirichlet_roots_t t, ulong order, slong num, slong prec); void acb_dirichlet_roots_clear(acb_dirichlet_roots_t t); void acb_dirichlet_root(acb_t z, const acb_dirichlet_roots_t t, ulong n, slong prec); void acb_dirichlet_chi(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, ulong n, slong prec); void acb_dirichlet_chi_vec(acb_ptr v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv, slong prec); void acb_dirichlet_arb_quadratic_powers(arb_ptr v, slong nv, const arb_t x, slong prec); void acb_dirichlet_qseries_arb(acb_t res, acb_srcptr a, const arb_t x, slong len, slong prec); void acb_dirichlet_qseries_arb_powers_naive(acb_t res, const arb_t x, int parity, const ulong *a, const acb_dirichlet_roots_t z, slong len, slong prec); void acb_dirichlet_qseries_arb_powers_smallorder(acb_t res, const arb_t x, int parity, const ulong *a, const acb_dirichlet_roots_t z, slong len, slong prec); ulong acb_dirichlet_theta_length_d(ulong q, double x, slong prec); ulong acb_dirichlet_theta_length(ulong q, const arb_t x, slong prec); void mag_tail_kexpk2_arb(mag_t res, const arb_t a, ulong n); void _acb_dirichlet_theta_argument_at_arb(arb_t xt, ulong q, const arb_t t, slong prec); void acb_dirichlet_theta_arb(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t t, slong prec); void acb_dirichlet_ui_theta_arb(acb_t res, const dirichlet_group_t G, ulong a, const arb_t t, slong prec); void acb_dirichlet_gauss_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_gauss_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_gauss_sum_order2(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_gauss_sum_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_gauss_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_root_number_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_root_number(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_si_poly_evaluate(acb_t res, slong * v, slong len, const acb_t z, slong prec); void acb_dirichlet_jacobi_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec); ulong jacobi_one_prime(ulong p, ulong e, ulong pe, ulong cond); void acb_dirichlet_jacobi_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec); void acb_dirichlet_jacobi_sum_gauss(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec); void acb_dirichlet_jacobi_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec); void acb_dirichlet_jacobi_sum_ui(acb_t res, const dirichlet_group_t G, ulong a, ulong b, slong prec); void acb_dirichlet_l_euler_product(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, const acb_dirichlet_hurwitz_precomp_t precomp, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_l(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_l_vec_hurwitz(acb_ptr res, const acb_t s, const acb_dirichlet_hurwitz_precomp_t precomp, const dirichlet_group_t G, slong prec); void acb_dirichlet_l_jet(acb_ptr res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec); void acb_dirichlet_l_fmpq_afe(acb_t res, const fmpq_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void acb_dirichlet_l_fmpq(acb_t res, const fmpq_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); void _acb_dirichlet_l_series(acb_ptr res, acb_srcptr s, slong slen, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec); void acb_dirichlet_l_series(acb_poly_t res, const acb_poly_t s, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec); void acb_dirichlet_hardy_theta(acb_ptr res, const acb_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec); void acb_dirichlet_hardy_z(acb_ptr res, const acb_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec); void _acb_dirichlet_hardy_theta_series(acb_ptr res, acb_srcptr s, slong slen, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec); void acb_dirichlet_hardy_theta_series(acb_poly_t res, const acb_poly_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec); void _acb_dirichlet_hardy_z_series(acb_ptr res, acb_srcptr s, slong slen, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec); void acb_dirichlet_hardy_z_series(acb_poly_t res, const acb_poly_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec); void acb_dirichlet_gram_point(arb_t res, const fmpz_t n, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); ulong acb_dirichlet_turing_method_bound(const fmpz_t p); int _acb_dirichlet_definite_hardy_z(arb_t res, const arf_t t, slong *pprec); void _acb_dirichlet_isolate_gram_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n); void _acb_dirichlet_isolate_rosser_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n); void _acb_dirichlet_isolate_turing_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n); void acb_dirichlet_isolate_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n); void _acb_dirichlet_refine_hardy_z_zero(arb_t res, const arf_t a, const arf_t b, slong prec); void acb_dirichlet_hardy_z_zeros(arb_ptr res, const fmpz_t n, slong len, slong prec); void acb_dirichlet_zeta_zeros(acb_ptr res, const fmpz_t n, slong len, slong prec); slong acb_dirichlet_platt_zeta_zeros(acb_ptr res, const fmpz_t n, slong len, slong prec); void _acb_dirichlet_exact_zeta_nzeros(fmpz_t res, const arf_t t); void acb_dirichlet_zeta_nzeros(arb_t res, const arb_t t, slong prec); void acb_dirichlet_backlund_s(arb_t res, const arb_t t, slong prec); void acb_dirichlet_backlund_s_bound(mag_t res, const arb_t t); void acb_dirichlet_zeta_nzeros_gram(fmpz_t res, const fmpz_t n); slong acb_dirichlet_backlund_s_gram(const fmpz_t n); ACB_DIRICHLET_INLINE void acb_dirichlet_hardy_z_zero(arb_t res, const fmpz_t n, slong prec) { acb_dirichlet_hardy_z_zeros(res, n, 1, prec); } ACB_DIRICHLET_INLINE void acb_dirichlet_zeta_zero(acb_t res, const fmpz_t n, slong prec) { acb_dirichlet_zeta_zeros(res, n, 1, prec); } /* Platt zeta zeros */ typedef struct { slong len; arb_ptr p; arb_struct Xa; arb_struct Xb; } acb_dirichlet_platt_c_precomp_struct; typedef acb_dirichlet_platt_c_precomp_struct acb_dirichlet_platt_c_precomp_t[1]; typedef struct { arb_struct c1; arb_struct c2; } acb_dirichlet_platt_i_precomp_struct; typedef acb_dirichlet_platt_i_precomp_struct acb_dirichlet_platt_i_precomp_t[1]; typedef struct { acb_dirichlet_platt_c_precomp_struct pre_c; acb_dirichlet_platt_i_precomp_struct pre_i; } acb_dirichlet_platt_ws_precomp_struct; typedef acb_dirichlet_platt_ws_precomp_struct acb_dirichlet_platt_ws_precomp_t[1]; /* Platt C bound */ void acb_dirichlet_platt_c_precomp_init(acb_dirichlet_platt_c_precomp_t pre, slong sigma, const arb_t h, ulong k, slong prec); void acb_dirichlet_platt_c_precomp_clear(acb_dirichlet_platt_c_precomp_t pre); void acb_dirichlet_platt_c_bound_precomp(arb_t res, const acb_dirichlet_platt_c_precomp_t pre, slong sigma, const arb_t t0, const arb_t h, slong k, slong prec); void acb_dirichlet_platt_c_bound(arb_t res, slong sigma, const arb_t t0, const arb_t h, slong k, slong prec); /* Platt I bound */ void acb_dirichlet_platt_i_precomp_init(acb_dirichlet_platt_i_precomp_t pre, slong A, const arb_t H, slong sigma, slong prec); void acb_dirichlet_platt_i_precomp_clear(acb_dirichlet_platt_i_precomp_t pre); void acb_dirichlet_platt_i_bound_precomp(arb_t res, const acb_dirichlet_platt_i_precomp_t pre_i, const acb_dirichlet_platt_c_precomp_t pre_c, const arb_t t0, slong A, const arb_t H, slong sigma, slong prec); void acb_dirichlet_platt_i_bound(arb_t res, const arb_t t0, slong A, const arb_t H, slong sigma, slong prec); /* Platt Gaussian-windowed Whittaker-Shannon interpolation */ void acb_dirichlet_platt_ws_precomp_init(acb_dirichlet_platt_ws_precomp_t pre, slong A, const arb_t H, slong sigma, slong prec); void acb_dirichlet_platt_ws_precomp_clear(acb_dirichlet_platt_ws_precomp_t pre); void acb_dirichlet_platt_ws_interpolation_precomp(arb_t res, arf_t deriv, const acb_dirichlet_platt_ws_precomp_t pre, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong Ns_max, const arb_t H, slong sigma, slong prec); void acb_dirichlet_platt_ws_interpolation(arb_t res, arf_t deriv, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong Ns_max, const arb_t H, slong sigma, slong prec); void acb_dirichlet_platt_bound_C3(arb_t res, const arb_t t0, slong A, const arb_t H, slong Ns, slong prec); void acb_dirichlet_platt_scaled_lambda(arb_t res, const arb_t t, slong prec); void acb_dirichlet_platt_scaled_lambda_vec(arb_ptr res, const fmpz_t T, slong A, slong B, slong prec); /* Platt lemma bounds of errors in the DFT grid evaluation of scaled Lambda */ void acb_dirichlet_platt_beta(arb_t res, const arb_t t, slong prec); void acb_dirichlet_platt_lemma_32(arb_t out, const arb_t h, const arb_t t0, const arb_t x, slong prec); void acb_dirichlet_platt_lemma_A5(arb_t out, slong B, const arb_t h, slong k, slong prec); void acb_dirichlet_platt_lemma_A7(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong k, slong A, slong prec); void acb_dirichlet_platt_lemma_A9(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong A, slong prec); void acb_dirichlet_platt_lemma_A11(arb_t out, const arb_t t0, const arb_t h, slong B, slong prec); void acb_dirichlet_platt_lemma_B1(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong J, slong prec); void acb_dirichlet_platt_lemma_B2(arb_t out, slong K, const arb_t h, const arb_t xi, slong prec); /* Platt DFT grid evaluation of scaled Lambda */ void acb_dirichlet_platt_multieval(arb_ptr out, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec); void acb_dirichlet_platt_multieval_threaded(arb_ptr out, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec); /* Platt Hardy Z zeros */ slong _acb_dirichlet_platt_local_hardy_z_zeros( arb_ptr res, const fmpz_t n, slong len, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma_grid, slong Ns_max, const arb_t H, slong sigma_interp, slong prec); slong acb_dirichlet_platt_local_hardy_z_zeros( arb_ptr res, const fmpz_t n, slong len, slong prec); slong acb_dirichlet_platt_hardy_z_zeros( arb_ptr res, const fmpz_t n, slong len, slong prec); /* Discrete Fourier Transform */ void acb_dirichlet_dft_index(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec); void acb_dirichlet_dft(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec); /* utils */ ACB_DIRICHLET_INLINE void acb_vec_printd(acb_srcptr vec, slong len, slong digits) { slong i; for (i = 0; i < len; i++) acb_printd(vec + i, digits), flint_printf("\n"); } #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_dirichlet/000077500000000000000000000000001417376376500151415ustar00rootroot00000000000000arb-2.22.1/acb_dirichlet/arb_quadratic_powers.c000066400000000000000000000017051417376376500215100ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* TODO: BSGS can reduce to nv mul */ void acb_dirichlet_arb_quadratic_powers(arb_ptr v, slong nv, const arb_t x, slong prec) { slong i; arb_t dx, x2; arb_init(dx); arb_init(x2); arb_set(dx, x); arb_mul(x2, x, x, prec); for (i = 0; i < nv; i++) { if (i == 0) arb_one(v + i); else if (i == 1) arb_set_round(v + i, x, prec); else { arb_mul(dx, dx, x2, prec); arb_mul(v + i, v + i - 1, dx, prec); } } arb_clear(dx); arb_clear(x2); } arb-2.22.1/acb_dirichlet/backlund_s.c000066400000000000000000000044271417376376500174210ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* S(t) = N(t) - theta(t)/pi - 1 */ static void _backlund_s(arb_t res, const arb_t t, slong prec) { arb_t N; acb_t z; arb_init(N); acb_init(z); acb_dirichlet_zeta_nzeros(N, t, prec); acb_set_arb(z, t); acb_dirichlet_hardy_theta(z, z, NULL, NULL, 1, prec); arb_const_pi(acb_imagref(z), prec); arb_div(acb_realref(z), acb_realref(z), acb_imagref(z), prec); arb_sub(res, N, acb_realref(z), prec); arb_sub_ui(res, res, 1, prec); arb_clear(N); acb_clear(z); } void acb_dirichlet_backlund_s(arb_t res, const arb_t t, slong prec) { mag_t m, b; mag_init(m); mag_init(b); arb_get_mag(m, t); if (!arb_is_nonnegative(t)) { arb_indeterminate(res); } else if (mag_cmp_2exp_si(m, 6) < 0) /* If t is small then N(t) is fast. */ { _backlund_s(res, t, prec); } else { /* * If the error radius of t is greater than 8/log(t) then use a fast * bound. The threshold doesn't matter for correctness, but note that * the average spacing of zeros is 2*pi/log(t) asymptotically. * Otherwise if the radius is smaller use S(t) = N(t) - theta(t)/pi - 1. */ mag_log(b, m); mag_mul_2exp_si(b, b, -3); mag_inv(b, b); if (mag_cmp(arb_radref(t), b) > 0) { arb_zero(res); acb_dirichlet_backlund_s_bound(arb_radref(res), t); } else { acb_t z; acb_init(z); /* * The difference (N(t) - theta(t)/pi) loses precision from * cancellation. Add extra bits to mitigate the loss. */ acb_set_arb(z, t); acb_dirichlet_hardy_theta(z, z, NULL, NULL, 1, prec); _backlund_s(res, t, prec + mag_get_d_log2_approx(m)); acb_clear(z); } } mag_clear(m); mag_clear(b); } arb-2.22.1/acb_dirichlet/backlund_s_bound.c000066400000000000000000000031551417376376500206050ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _mag_div_ui_ui(mag_t res, ulong a, ulong b) { mag_set_ui(res, a); mag_div_ui(res, res, b); } void acb_dirichlet_backlund_s_bound(mag_t res, const arb_t t) { if (!arb_is_nonnegative(t)) { mag_inf(res); } else { mag_t m; mag_init(m); arb_get_mag(m, t); if (mag_cmp_2exp_si(m, 8) < 0) /* 2^8 < 280 */ { mag_one(res); } else if (mag_cmp_2exp_si(m, 22) < 0) /* 2^22 < 6.8*10^6 */ { mag_set_ui(res, 2); } else if (mag_cmp_2exp_si(m, 29) < 0) /* 2^29 < 5.45*10^8 */ { _mag_div_ui_ui(res, 231366, 100000); } else { /* |S(t)| <= 0.112*log(t) + 0.278*log(log(t)) + 2.51 */ mag_t c, logm; mag_init(c); mag_init(logm); mag_log(logm, m); _mag_div_ui_ui(c, 278, 1000); mag_log(res, logm); mag_mul(res, res, c); _mag_div_ui_ui(c, 112, 1000); mag_addmul(res, c, logm); _mag_div_ui_ui(c, 251, 100); mag_add(res, res, c); mag_clear(c); mag_clear(logm); } mag_clear(m); } } arb-2.22.1/acb_dirichlet/backlund_s_gram.c000066400000000000000000000014361417376376500204240ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" slong acb_dirichlet_backlund_s_gram(const fmpz_t n) { slong res = 0; if (fmpz_cmp_si(n, -1) < 0) { flint_printf("n must be >= -1\n"); flint_abort(); } else { fmpz_t k; fmpz_init(k); acb_dirichlet_zeta_nzeros_gram(k, n); fmpz_sub(k, k, n); res = fmpz_get_si(k) - 1; fmpz_clear(k); } return res; } arb-2.22.1/acb_dirichlet/chi.c000066400000000000000000000016161417376376500160540ustar00rootroot00000000000000/* Copyright (C) 2015 Jonathan Bober Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_chi(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, ulong n, slong prec) { ulong expo; expo = dirichlet_chi(G, chi, n); if (expo == DIRICHLET_CHI_NULL) acb_zero(res); else { fmpq_t t; fmpq_init(t); fmpq_set_si(t, 2 * expo , G->expo); arb_sin_cos_pi_fmpq(acb_imagref(res), acb_realref(res), t, prec); fmpq_clear(t); } } arb-2.22.1/acb_dirichlet/chi_vec.c000066400000000000000000000020021417376376500166770ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_chi_vec(acb_ptr v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv, slong prec) { slong k; ulong * a, order; acb_dirichlet_roots_t t; a = flint_malloc(nv * sizeof(ulong)); order = dirichlet_order_char(G, chi); dirichlet_chi_vec_order(a, G, chi, order, nv); acb_dirichlet_roots_init(t, order, nv, prec); acb_zero(v + 0); for (k = 0; k < nv; k++) { if (a[k] != DIRICHLET_CHI_NULL) acb_dirichlet_root(v + k, t, a[k], prec); else acb_zero(v + k); } acb_dirichlet_roots_clear(t); flint_free(a); } arb-2.22.1/acb_dirichlet/dft.c000066400000000000000000000031461417376376500160660ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dft.h" #include "acb_dirichlet.h" /* dft, lexicographic conrey indexing, array size G->phi_q */ void acb_dirichlet_dft_index(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec) { if (G->phi_q == 1) { acb_set(w, v); } else { slong k, l, * cyc; cyc = flint_malloc(G->num * sizeof(slong)); for (k = 0, l = G->num - 1; l >= 0; k++, l--) cyc[k] = G->P[k].phi.n; acb_dft_prod(w, v, cyc, G->num, prec); flint_free(cyc); } } /* dft, number indexing, array size G->q */ void acb_dirichlet_dft(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec) { ulong i, len; acb_ptr t1, t2; dirichlet_char_t x; len = G->phi_q; t1 = flint_malloc(len * sizeof(acb_struct)); dirichlet_char_init(x, G); dirichlet_char_one(x, G); for (i = 0; i < len; i++) { t1[i] = v[x->n]; dirichlet_char_next(x, G); }; t2 = _acb_vec_init(len); acb_dirichlet_dft_index(t2, t1, G, prec); dirichlet_char_one(x, G); for (i = 0; i < len; i++) { acb_set(w + x->n, t2 + i); dirichlet_char_next(x, G); }; _acb_vec_clear(t2, len); dirichlet_char_clear(x); flint_free(t1); } arb-2.22.1/acb_dirichlet/eta.c000066400000000000000000000032721417376376500160620ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_eta(acb_t res, const acb_t s, slong prec) { if (!acb_is_finite(s)) { acb_indeterminate(res); } else if (arb_contains_si(acb_realref(s), 1) && arb_contains_zero(acb_imagref(s))) { if (acb_is_one(s)) { arb_const_log2(acb_realref(res), prec); arb_zero(acb_imagref(res)); } else { mag_t m; int is_real = acb_is_real(s); mag_init(m); /* Taylor coefficients at s = 1 are bounded by |c_k| < 1/4^k. */ acb_sub_ui(res, s, 1, prec); acb_get_mag(m, res); mag_mul_2exp_si(m, m, -2); mag_geom_series(m, m, 1); arb_const_log2(acb_realref(res), prec); arb_zero(acb_imagref(res)); if (is_real) arb_add_error_mag(acb_realref(res), m); else acb_add_error_mag(res, m); mag_clear(m); } } else { acb_t t; acb_init(t); acb_one(t); acb_mul_2exp_si(t, t, -1); acb_pow(t, t, s, prec); acb_mul_2exp_si(t, t, 1); acb_sub_ui(t, t, 1, prec); acb_neg(t, t); acb_zeta(res, s, prec); acb_mul(res, res, t, prec); acb_clear(t); } } arb-2.22.1/acb_dirichlet/euler_product_real_ui.c000066400000000000000000000062501417376376500216640ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #define ONE_OVER_LOG2 1.4426950408889634 void _acb_dirichlet_euler_product_real_ui(arb_t res, ulong s, const signed char * chi, int mod, int reciprocal, slong prec) { slong wp, powprec; double logp, powmag, errmag, limit; arb_t t, u; ulong p; mag_t err; if (s <= 1) { arb_indeterminate(res); return; } if (prec < 2) flint_abort(); /* assert */ /* L(s), 1/L(s) = 1 + ... For s >= 3, zeta(s,2) < 2^(1-s). */ if (s > (ulong) prec) { arf_one(arb_midref(res)); mag_set_ui_2exp_si(arb_radref(res), 1, -prec); return; } /* L(s), 1/L(s) = 1 +/- chi(2) 2^(-s) + ... For s >= 2, zeta(s,3) < 2^(2-floor(3s/2)). */ if (s > 0.7 * prec) { arb_one(res); if (chi[2 % mod] != 0) { arf_t t; arf_init(t); arf_set_si_2exp_si(t, chi[2 % mod], -s); if (reciprocal) arf_neg(t, t); arb_add_arf(res, res, t, prec); arf_clear(t); } arb_add_error_2exp_si(res, 2 - (3 * s) / 2); return; } /* Heuristic. */ wp = prec + FLINT_BIT_COUNT(prec) + (prec / s) + 4; arb_init(t); arb_init(u); /* 1 - chi(2) 2^(-s) */ arb_one(res); arf_set_ui_2exp_si(arb_midref(t), 1, -s); /* -s cannot overflow */ if (chi[2 % mod] == 1) arb_sub(res, res, t, wp); else if (chi[2 % mod] == -1) arb_add(res, res, t, wp); /* Cut at some point if this algorithm just isn't a good fit... */ /* The C * prec / log(prec) cutoff in arb_zeta_ui implies that the limit should be at least prec ^ (log(2) / C) for the Riemann zeta function, which gives prec ^ 1.2956 here. */ limit = 100 + prec * sqrt(prec); for (p = 3; p < limit; p = n_nextprime(p, 1)) { if (mod == 1 || chi[p % mod] != 0) { /* p^s */ logp = log(p); powmag = s * logp * ONE_OVER_LOG2; /* zeta(s,p) ~= 1/p^s + 1/((s-1) p^(s-1)) */ errmag = (log(s - 1.0) + (s - 1.0) * logp) * ONE_OVER_LOG2; errmag = FLINT_MIN(powmag, errmag); if (errmag > prec + 2) break; powprec = FLINT_MAX(wp - powmag, 8); arb_ui_pow_ui(t, p, s, powprec); arb_set_round(u, res, powprec); arb_div(t, u, t, powprec); if (mod == 1 || (chi[p % mod] == 1)) arb_sub(res, res, t, wp); else arb_add(res, res, t, wp); } } mag_init(err); mag_hurwitz_zeta_uiui(err, s, p); arb_add_error_mag(res, err); mag_clear(err); if (reciprocal) arb_set_round(res, res, prec); else arb_inv(res, res, prec); arb_clear(t); arb_clear(u); } arb-2.22.1/acb_dirichlet/gauss_sum.c000066400000000000000000000052641417376376500173220ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void gauss_sum_non_primitive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, ulong cond, slong prec) { slong k, mu = 1; ulong NN0 = G->q / cond; /* G(chi) = mu(N/N0)chi0(N/N0)G(chi0) */ if (NN0 % 2 == 0) { if (G->q % 4) mu = -1; else { acb_zero(res); return; } } for (k = G->neven; k < G->num; k++) { ulong p = G->P[k].p; if (G->P[k].e > 1 && NN0 % (p*p) == 0) { acb_zero(res); return; } if (NN0 % p == 0) mu *= -1; } if (chi->n == 1) { acb_set_si(res, mu); } else { dirichlet_group_t G0; dirichlet_char_t chi0; acb_t z; /* primitive char associated to chi */ dirichlet_subgroup_init(G0, G, cond); dirichlet_char_init(chi0, G0); dirichlet_char_lower(chi0, G0, chi, G); acb_init(z); acb_dirichlet_gauss_sum(z, G0, chi0, prec); acb_dirichlet_chi(res, G0, chi0, NN0, prec); acb_mul(res, res, z, prec); acb_mul_si(res, res, mu, prec); dirichlet_group_clear(G0); dirichlet_char_clear(chi0); acb_clear(z); } } void acb_dirichlet_gauss_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { ulong cond = dirichlet_conductor_char(G, chi); /* TODO: no need, factor also does it... */ if (cond != G->q) { gauss_sum_non_primitive(res, G, chi, cond, prec); } else if (dirichlet_char_is_real(G, chi)) { acb_dirichlet_gauss_sum_order2(res, G, chi, prec); } else if (G->num > 1 && G->num > G->neven) { acb_dirichlet_gauss_sum_factor(res, G, chi, prec); } else { /* must be non primitive */ if (acb_dirichlet_theta_length_d(G->q, 1, prec) > G->q) acb_dirichlet_gauss_sum_naive(res, G, chi, prec); else acb_dirichlet_gauss_sum_theta(res, G, chi, prec); } } void acb_dirichlet_gauss_sum_ui(acb_t res, const dirichlet_group_t G, ulong a, slong prec) { dirichlet_char_t chi; dirichlet_char_init(chi, G); dirichlet_char_log(chi, G, a); acb_dirichlet_gauss_sum(res, G, chi, prec); dirichlet_char_clear(chi); } arb-2.22.1/acb_dirichlet/gauss_sum_factor.c000066400000000000000000000032451417376376500206550ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_gauss_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { slong k; acb_t tmp; /* early check */ for (k = (G->neven == 2); k < G->num; k++) { /* if e > 1 and not primitive, 0 */ if (chi->log[k] % G->P[k].p == 0 && G->P[k].e > 1) { acb_zero(res); return; } } /* factor */ acb_one(res); acb_init(tmp); for (k = (G->neven == 2); k < G->num; k++) { ulong pe = G->P[k].pe.n; dirichlet_group_t Gp; dirichlet_char_t chip; dirichlet_subgroup_init(Gp, G, pe); dirichlet_char_init(chip, Gp); chip->n = chi->n % pe; if (k == 1 && G->neven == 2) { chip->log[0] = chi->log[0]; chip->log[1] = chi->log[1]; } else chip->log[0] = chi->log[k]; /* chi_pe(a, q/pe) * G_pe(a) */ acb_dirichlet_gauss_sum(tmp, Gp, chip, prec); acb_mul(res, res, tmp, prec); acb_dirichlet_chi(tmp, Gp, chip, (G->q / pe) % pe, prec); acb_mul(res, res, tmp, prec); dirichlet_char_clear(chip); dirichlet_group_clear(Gp); } if (G->q_even == 2) acb_neg(res, res); acb_clear(tmp); } arb-2.22.1/acb_dirichlet/gauss_sum_naive.c000066400000000000000000000014361417376376500205010ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_gauss_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { acb_t z; acb_ptr v; v = _acb_vec_init(G->q); acb_dirichlet_chi_vec(v, G, chi, G->q, prec); acb_init(z); acb_unit_root(z, G->q, prec); _acb_poly_evaluate(res, v, G->q, z, prec); acb_clear(z); _acb_vec_clear(v, G->q); } arb-2.22.1/acb_dirichlet/gauss_sum_order2.c000066400000000000000000000013771417376376500206000ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_gauss_sum_order2(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { if (dirichlet_parity_char(G, chi)) { arb_zero(acb_realref(res)); arb_sqrt_ui(acb_imagref(res), G->q, prec); } else { arb_zero(acb_imagref(res)); arb_sqrt_ui(acb_realref(res), G->q, prec); } } arb-2.22.1/acb_dirichlet/gauss_sum_theta.c000066400000000000000000000022531417376376500205020ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_gauss_sum_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { ulong cond = dirichlet_conductor_char(G, chi); if (cond < G->q || (G->q == 300 && (chi->n == 71 || chi->n == 131)) || (G->q == 600 && (chi->n == 11 || chi->n == 491))) { flint_printf("gauss_sum_theta: non available for non primitive character" "or exceptional characters chi_300(71,.), chi_300(131,.), " "chi_600(11,.) and chi_600(491,.)\n"); flint_abort(); } else { acb_t iq; acb_init(iq); acb_dirichlet_gauss_sum_order2(iq, G, chi, prec); acb_dirichlet_root_number_theta(res, G, chi, prec); acb_mul(res, res, iq, prec); acb_clear(iq); } } arb-2.22.1/acb_dirichlet/gram_point.c000066400000000000000000000110071417376376500174430ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* Claim: the error is bounded by 1/64 if n <= 1 and (1/64) (log(n)/n) if n >= 2. A crude lower bound for g_n is 2 pi exp(W(n)), or 8*n/log(n) for n >= 8. We want to solve pi n = -t/2 log(2 pi/t) - t/2 - pi/8 + epsilon for t (= g_n). Using (47) in Brent [https://arxiv.org/abs/1609.03682], |epsilon| <= 1/(8 t) for for t >= 2. Also, for x >= 3, |f'(x)| < 0.5 where f(x) = exp(W(x)). Assume n >= 9, so that (n+1/8)/e >= 3.35. Then inverting gives t = 2 pi exp[W( [pi n - epsilon + pi/8] / (pi e) ) + 1] = 2 pi e exp[W((n+1/8)/e - epsilon / (pi e))] = 2 pi e exp[W((n+1/8)/e)] + epsilon2, |epsilon2| <= 1/(8 t) <= (1/64) (log(n)/n) One can check 0 <= n <= 8 separately. */ static void gram_point_initial(arb_t x, const fmpz_t n, slong prec) { arb_t pi, e; mag_t b; arb_init(pi); arb_init(e); mag_init(b); arb_const_pi(pi, prec); arb_const_e(e, prec); /* x = 2*pi*exp(1 + W((n+1/8)/e)) */ arb_one(x); arb_mul_2exp_si(x, x, -3); arb_add_fmpz(x, x, n, prec); arb_div(x, x, e, prec); arb_lambertw(x, x, 0, prec); arb_add_ui(x, x, 1, prec); arb_exp(x, x, prec); arb_mul(x, x, pi, prec); arb_mul_2exp_si(x, x, 1); if (fmpz_cmp_ui(n, 1) <= 0) { mag_set_ui_2exp_si(b, 1, -6); } else { mag_set_fmpz(b, n); mag_log(b, b); mag_div_fmpz(b, b, n); mag_mul_2exp_si(b, b, -6); } arb_add_error_mag(x, b); arb_clear(pi); arb_clear(e); mag_clear(b); } void acb_dirichlet_gram_point(arb_t res, const fmpz_t n, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { slong asymp_accuracy; /* Only implemented for n >= -1 and Riemann zeta. */ if (fmpz_cmp_si(n, -1) < 0 || G != NULL || chi != NULL) { arb_indeterminate(res); return; } asymp_accuracy = 2 * fmpz_bits(n); asymp_accuracy = FLINT_MIN(asymp_accuracy, prec); gram_point_initial(res, n, asymp_accuracy + 20); asymp_accuracy = arb_rel_accuracy_bits(res); if (asymp_accuracy < prec) { acb_struct tmp[2]; arb_t f, fprime, root; mag_t C, r; slong * steps; slong wp, step; acb_init(tmp); acb_init(tmp + 1); arb_init(f); arb_init(fprime); arb_init(root); mag_init(C); mag_init(r); steps = flint_malloc(sizeof(slong) * FLINT_BITS); step = 0; steps[step] = prec * 1.05 + 10; while (steps[step] / 2 > asymp_accuracy) { steps[step + 1] = steps[step] / 2; step++; } arb_set(root, res); /* theta''(x) <= C = 1/x, x >= 1 */ arb_get_mag_lower(C, root); if (mag_cmp_2exp_si(C, 0) >= 0) mag_inv(C, C); else mag_inf(C); arb_set(root, res); for ( ; step >= 0; step--) { wp = steps[step] + 10; wp = FLINT_MAX(wp, arb_rel_accuracy_bits(root) + 10); /* store radius, set root to the midpoint */ mag_set(r, arb_radref(root)); mag_zero(arb_radref(root)); acb_set_arb(tmp, root); acb_dirichlet_hardy_theta(tmp, tmp, NULL, NULL, 2, wp); arb_set(f, acb_realref(tmp)); arb_const_pi(acb_imagref(tmp), wp); arb_submul_fmpz(f, acb_imagref(tmp), n, wp); arb_set(fprime, acb_realref(tmp + 1)); /* f'([m+/-r]) = f'(m) +/- f''([m +/- r]) * r */ mag_mul(r, C, r); arb_add_error_mag(fprime, r); arb_div(f, f, fprime, wp); arb_sub(root, root, f, wp); /* Verify inclusion so that C is still valid. */ if (!arb_contains(res, root)) { flint_printf("unexpected: no containment computing Gram point\n"); arb_set(root, res); break; } } arb_set(res, root); acb_clear(tmp); acb_clear(tmp + 1); arb_clear(f); arb_clear(fprime); arb_clear(root); mag_clear(C); mag_clear(r); flint_free(steps); } arb_set_round(res, res, prec); } arb-2.22.1/acb_dirichlet/hardy_theta.c000066400000000000000000000057231417376376500176100ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_hardy_theta(acb_ptr res, const acb_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) { acb_struct y[2]; arb_t c; slong k; int parity; ulong q; if (len <= 0) return; if (t == res) { acb_init(y); acb_set(y, t); acb_dirichlet_hardy_theta(res, y, G, chi, len, prec); acb_clear(y); return; } if (G == NULL) { parity = 0; q = 1; } else { parity = dirichlet_parity_char(G, chi); q = G->q; if (q != dirichlet_conductor_char(G, chi)) { flint_printf("hardy theta: need primitive character\n"); flint_abort(); } } if (!acb_is_finite(t)) { _acb_vec_indeterminate(res, len); return; } acb_init(y + 0); acb_init(y + 1); arb_init(c); /* res = log gamma((s+parity)/2), s = 0.5+i(t+x) */ acb_mul_onei(y, t); arb_set_d(c, 0.5 + parity); arb_add(acb_realref(y), acb_realref(y), c, prec); acb_mul_2exp_si(y, y, -1); acb_onei(y + 1); acb_mul_2exp_si(y + 1, y + 1, -1); _acb_poly_lgamma_series(res, y, FLINT_MIN(len, 2), len, prec); if (acb_is_real(t)) { for (k = 0; k < len; k++) { arb_set(acb_realref(res + k), acb_imagref(res + k)); arb_zero(acb_imagref(res + k)); } } else { acb_ptr v = _acb_vec_init(len); /* v = log gamma(((1-s)+parity)/2), s = 0.5+i(t+x) */ acb_div_onei(y, t); arb_set_d(c, 0.5 + parity); arb_add(acb_realref(y), acb_realref(y), c, prec); acb_mul_2exp_si(y, y, -1); acb_neg(y + 1, y + 1); _acb_poly_lgamma_series(v, y, FLINT_MIN(len, 2), len, prec); _acb_vec_sub(res, res, v, len, prec); for (k = 0; k < len; k++) { acb_div_onei(res + k, res + k); acb_mul_2exp_si(res + k, res + k, -1); } _acb_vec_clear(v, len); } /* (t+x) [-(1/2) log(pi/q)] */ arb_const_pi(c, prec); arb_div_ui(c, c, q, prec); arb_log(c, c, prec); arb_mul_2exp_si(c, c, -1); acb_submul_arb(res, t, c, prec); if (len > 1) acb_sub_arb(res + 1, res + 1, c, prec); /* i log(eps) / 2 */ if (q > 1) { acb_dirichlet_root_number(y, G, chi, prec); acb_arg(c, y, prec); arb_mul_2exp_si(c, c, -1); arb_sub(acb_realref(res), acb_realref(res), c, prec); } acb_clear(y + 0); acb_clear(y + 1); arb_clear(c); } arb-2.22.1/acb_dirichlet/hardy_theta_series.c000066400000000000000000000034461417376376500211620ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void _acb_dirichlet_hardy_theta_series(acb_ptr res, acb_srcptr s, slong slen, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) { slen = FLINT_MIN(slen, len); if (len == 0) return; if (slen == 1) { acb_dirichlet_hardy_theta(res, s, G, chi, 1, prec); _acb_vec_zero(res + 1, len - 1); } else { acb_ptr t, u; t = _acb_vec_init(len); u = _acb_vec_init(slen); acb_dirichlet_hardy_theta(t, s, G, chi, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, s + 1, slen - 1); _acb_poly_compose_series(res, t, len, u, slen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, slen); } } void acb_dirichlet_hardy_theta_series(acb_poly_t res, const acb_poly_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) { if (len == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, len); if (s->length == 0) { acb_t t; acb_init(t); _acb_dirichlet_hardy_theta_series(res->coeffs, t, 1, G, chi, len, prec); acb_clear(t); } else { _acb_dirichlet_hardy_theta_series(res->coeffs, s->coeffs, s->length, G, chi, len, prec); } _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_dirichlet/hardy_z.c000066400000000000000000000036311417376376500167500ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_hardy_z(acb_ptr res, const acb_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) { acb_ptr v, w; slong k; int is_real; if (len <= 0) return; /* use reflection formula -- todo for other characters */ if ((G == NULL || G->q == 1) && arf_sgn(arb_midref(acb_imagref(t))) > 0) { acb_neg(res, t); acb_dirichlet_hardy_z(res, res, G, chi, len, prec); for (k = 1; k < len; k += 2) acb_neg(res + k, res + k); return; } v = _acb_vec_init(len); w = _acb_vec_init(len); is_real = acb_is_real(t); /* v = exp(i theta(t+x)) */ acb_dirichlet_hardy_theta(v, t, G, chi, len, prec); _acb_vec_scalar_mul_onei(v, v, len); _acb_poly_exp_series(v, v, len, len, prec); /* w = L(1/2 + i (t+x)) */ acb_one(w); acb_mul_2exp_si(w, w, -1); arb_sub(acb_realref(w), acb_realref(w), acb_imagref(t), prec); arb_set(acb_imagref(w), acb_realref(t)); acb_dirichlet_l_jet(w, w, G, chi, 0, len, prec); for (k = 0; k < len; k++) { if (k % 4 == 1) acb_mul_onei(w + k, w + k); else if (k % 4 == 2) acb_neg(w + k, w + k); else if (k % 4 == 3) acb_div_onei(w + k, w + k); } _acb_poly_mullow(res, v, len, w, len, len, prec); if (is_real) for (k = 0; k < len; k++) arb_zero(acb_imagref(res + k)); _acb_vec_clear(v, len); _acb_vec_clear(w, len); } arb-2.22.1/acb_dirichlet/hardy_z_series.c000066400000000000000000000034161417376376500203230ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void _acb_dirichlet_hardy_z_series(acb_ptr res, acb_srcptr s, slong slen, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) { slen = FLINT_MIN(slen, len); if (len == 0) return; if (slen == 1) { acb_dirichlet_hardy_z(res, s, G, chi, 1, prec); _acb_vec_zero(res + 1, len - 1); } else { acb_ptr t, u; t = _acb_vec_init(len); u = _acb_vec_init(slen); acb_dirichlet_hardy_z(t, s, G, chi, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, s + 1, slen - 1); _acb_poly_compose_series(res, t, len, u, slen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, slen); } } void acb_dirichlet_hardy_z_series(acb_poly_t res, const acb_poly_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) { if (len == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, len); if (s->length == 0) { acb_t t; acb_init(t); _acb_dirichlet_hardy_z_series(res->coeffs, t, 1, G, chi, len, prec); acb_clear(t); } else { _acb_dirichlet_hardy_z_series(res->coeffs, s->coeffs, s->length, G, chi, len, prec); } _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_dirichlet/hardy_z_zero.c000066400000000000000000000135121417376376500200060ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_calc.h" static void _acb_set_arf(acb_t res, const arf_t t) { acb_zero(res); arb_set_arf(acb_realref(res), t); } int _acb_dirichlet_definite_hardy_z(arb_t res, const arf_t t, slong *pprec) { int msign; acb_t z; acb_init(z); while (1) { _acb_set_arf(z, t); acb_dirichlet_hardy_z(z, z, NULL, NULL, 1, *pprec); msign = arb_sgn_nonzero(acb_realref(z)); if (msign) { break; } *pprec *= 2; } acb_get_real(res, z); acb_clear(z); return msign; } void _refine_hardy_z_zero_illinois(arb_t res, const arf_t ra, const arf_t rb, slong prec) { arf_t a, b, fa, fb, c, fc, t; arb_t z; slong k, nmag, abs_tol, wp; int asign, bsign, csign; arf_init(a); arf_init(b); arf_init(c); arf_init(fa); arf_init(fb); arf_init(fc); arf_init(t); arb_init(z); arf_set(a, ra); arf_set(b, rb); nmag = arf_abs_bound_lt_2exp_si(b); abs_tol = nmag - prec - 4; wp = prec + nmag + 8; asign = _acb_dirichlet_definite_hardy_z(z, a, &wp); arf_set(fa, arb_midref(z)); bsign = _acb_dirichlet_definite_hardy_z(z, b, &wp); arf_set(fb, arb_midref(z)); if (asign == bsign) { flint_printf("isolate a zero before bisecting the interval\n"); flint_abort(); } for (k = 0; k < 40; k++) { /* c = a - fa * (b - a) / (fb - fa) */ arf_sub(c, b, a, wp, ARF_RND_NEAR); arf_sub(t, fb, fa, wp, ARF_RND_NEAR); arf_div(c, c, t, wp, ARF_RND_NEAR); arf_mul(c, c, fa, wp, ARF_RND_NEAR); arf_sub(c, a, c, wp, ARF_RND_NEAR); /* if c is not sandwiched between a and b, improve precision and fall back to one bisection step */ if (!arf_is_finite(c) || !((arf_cmp(a, c) < 0 && arf_cmp(c, b) < 0) || (arf_cmp(b, c) < 0 && arf_cmp(c, a) < 0))) { /* flint_printf("no sandwich (k = %wd)\n", k); */ wp += 32; arf_add(c, a, b, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul_2exp_si(c, c, -1); } csign = _acb_dirichlet_definite_hardy_z(z, c, &wp); arf_set(fc, arb_midref(z)); if (csign != bsign) { arf_set(a, b); arf_set(fa, fb); asign = bsign; arf_set(b, c); arf_set(fb, fc); bsign = csign; } else { arf_set(b, c); arf_set(fb, fc); bsign = csign; arf_mul_2exp_si(fa, fa, -1); } arf_sub(t, a, b, wp, ARF_RND_DOWN); arf_abs(t, t); if (arf_cmpabs_2exp_si(t, abs_tol) < 0) break; } /* a and b may have changed places */ if (arf_cmp(a, b) > 0) arf_swap(a, b); arb_set_interval_arf(res, a, b, prec); arf_clear(a); arf_clear(b); arf_clear(c); arf_clear(fa); arf_clear(fb); arf_clear(fc); arf_clear(t); arb_clear(z); } void _refine_hardy_z_zero_newton(arb_t res, const arf_t ra, const arf_t rb, slong prec) { acb_t z, zstart; acb_ptr v; mag_t der1, der2, err; slong nbits, initial_prec, extraprec, wp, step; slong * steps; acb_init(z); acb_init(zstart); v = _acb_vec_init(2); mag_init(der1); mag_init(der2); mag_init(err); nbits = arf_abs_bound_lt_2exp_si(rb); extraprec = nbits + 10; initial_prec = 3 * nbits + 30; _refine_hardy_z_zero_illinois(acb_imagref(zstart), ra, rb, initial_prec); arb_set_d(acb_realref(zstart), 0.5); /* Real part is exactly 1/2, but need an epsilon-enclosure (for bounds) since we work with the complex function. */ mag_set_ui_2exp_si(arb_radref(acb_realref(zstart)), 1, nbits - initial_prec - 4); /* Bound |zeta''(zstart)| for Newton error bound. */ acb_dirichlet_zeta_deriv_bound(der1, der2, zstart); steps = flint_malloc(sizeof(slong) * FLINT_BITS); step = 0; steps[step] = prec; while (steps[step] / 2 + extraprec > initial_prec) { steps[step + 1] = steps[step] / 2 + extraprec; step++; } acb_set(z, zstart); for ( ; step >= 0; step--) { wp = steps[step] + extraprec; mag_set(err, arb_radref(acb_imagref(z))); acb_get_mid(z, z); acb_dirichlet_zeta_jet(v, z, 0, 2, wp); mag_mul(err, err, der2); acb_add_error_mag(v + 1, err); acb_div(v, v, v + 1, wp); acb_sub(v, z, v, wp); if (acb_contains(zstart, v)) { acb_set(z, v); arb_set_d(acb_realref(z), 0.5); } else { /* can this happen? should we fallback to illinois? */ flint_printf("no inclusion for interval newton!\n"); flint_abort(); } } arb_set(res, acb_imagref(z)); flint_free(steps); acb_clear(z); acb_clear(zstart); _acb_vec_clear(v, 2); mag_clear(der1); mag_clear(der2); mag_clear(err); } void _acb_dirichlet_refine_hardy_z_zero(arb_t res, const arf_t a, const arf_t b, slong prec) { slong bits; arb_set_interval_arf(res, a, b, prec + 8); bits = arb_rel_accuracy_bits(res); if (bits < prec) { if (prec < 4 * arf_abs_bound_lt_2exp_si(b) + 40) _refine_hardy_z_zero_illinois(res, a, b, prec); else _refine_hardy_z_zero_newton(res, a, b, prec); } arb_set_round(res, res, prec); } arb-2.22.1/acb_dirichlet/hurwitz.c000066400000000000000000000026771417376376500170350ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_hurwitz(acb_t res, const acb_t s, const acb_t a, slong prec) { if (acb_is_one(a)) { acb_dirichlet_zeta(res, s, prec); return; } if (acb_is_zero(s)) { acb_mul_2exp_si(res, a, 1); acb_sub_ui(res, res, 1, prec); acb_neg(res, res); acb_mul_2exp_si(res, res, -1); return; } if (acb_is_zero(a) && acb_is_int(s) && arf_sgn(arb_midref(acb_realref(s))) < 0) { acb_dirichlet_zeta(res, s, prec); return; } if (acb_is_int(s) && arf_sgn(arb_midref(acb_realref(s))) < 0 && arf_cmpabs_ui(arb_midref(acb_realref(s)), prec / 2) < 0) { slong n = arf_get_si(arb_midref(acb_realref(s)), ARF_RND_FLOOR); acb_bernoulli_poly_ui(res, 1 - n, a, prec); acb_div_si(res, res, n - 1, prec); return; } if (arb_contains_zero(acb_imagref(s)) && arb_contains_si(acb_realref(s), 1)) { acb_indeterminate(res); return; } _acb_poly_zeta_cpx_series(res, s, a, 0, 1, prec); } arb-2.22.1/acb_dirichlet/hurwitz_precomp_bound.c000066400000000000000000000041671417376376500217450ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_hurwitz_precomp_bound(mag_t res, const acb_t s, slong A, slong K, slong N) { acb_t s1; mag_t x, t, TK, C; slong sigmaK; arf_t u; if (A < 1 || K < 1 || N < 1) { mag_inf(res); return; } /* sigmaK = re(s) + K, floor bound */ arf_init(u); arf_set_mag(u, arb_radref(acb_realref(s))); arf_sub(u, arb_midref(acb_realref(s)), u, MAG_BITS, ARF_RND_FLOOR); arf_add_ui(u, u, K, MAG_BITS, ARF_RND_FLOOR); if (arf_cmp_ui(u, 2) < 0 || arf_cmp_2exp_si(u, FLINT_BITS - 2) > 0) { mag_inf(res); arf_clear(u); return; } sigmaK = arf_get_si(u, ARF_RND_FLOOR); arf_clear(u); acb_init(s1); mag_init(x); mag_init(t); mag_init(TK); mag_init(C); /* With N grid points, we will have |x| <= 1 / (2N). */ mag_one(x); mag_div_ui(x, x, 2 * N); /* T(K) = |x|^K |(s)_K| / K! * [1/A^(sigma+K) + ...] */ mag_pow_ui(TK, x, K); acb_rising_ui_get_mag(t, s, K); mag_mul(TK, TK, t); mag_rfac_ui(t, K); mag_mul(TK, TK, t); /* Note: here we assume that mag_hurwitz_zeta_uiui uses an error bound that is at least as large as the one used in the proof. */ mag_hurwitz_zeta_uiui(t, sigmaK, A); mag_mul(TK, TK, t); /* C = |x|/A (1 + 1/(K+sigma+A-1)) (1 + |s-1|/(K+1)) */ mag_div_ui(C, x, A); mag_one(t); mag_div_ui(t, t, sigmaK + A - 1); mag_add_ui(t, t, 1); mag_mul(C, C, t); acb_sub_ui(s1, s, 1, MAG_BITS); acb_get_mag(t, s1); mag_div_ui(t, t, K + 1); mag_add_ui(t, t, 1); mag_mul(C, C, t); mag_geom_series(t, C, 0); mag_mul(res, TK, t); acb_clear(s1); mag_clear(x); mag_clear(t); mag_clear(TK); mag_clear(C); } arb-2.22.1/acb_dirichlet/hurwitz_precomp_choose_param.c000066400000000000000000000060601417376376500232700ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_hurwitz_precomp_choose_param(ulong * _A, ulong *_K, ulong *_N, const acb_t s, double num_eval, slong prec) { double MUL_COST, POW_COST, ZETA_COST, height, abss, cost, best_cost; ulong A, K, N, best_A, best_K, best_N; mag_t err; /* Default algorithm: separate evaluations with no precomputation. */ best_A = best_K = best_N = 0; *_A = *_K = *_N = 0; /* This is pointless. */ if (num_eval < 10) return; /* Precomputation fails at nonpositive integers. */ if (acb_contains_int(s) && !arb_is_positive(acb_realref(s))) return; prec = FLINT_MAX(prec, 8); height = arf_get_d(arb_midref(acb_imagref(s)), ARF_RND_DOWN); height = fabs(height); abss = arf_get_d(arb_midref(acb_realref(s)), ARF_RND_DOWN); abss = sqrt(abss*abss + height*height); /* Relative evaluation time, estimated empirically. */ MUL_COST = 1.0; POW_COST = 10.0 + FLINT_MIN(0.005 * prec, 200.0); ZETA_COST = 200.0 + 2.0*height + (3.0*prec + 0.0002*height*prec)*prec; /* Cost for the default algorithm. */ best_cost = num_eval * ZETA_COST; /* Give the default algorithm some more leeway. */ best_cost *= 0.5; if (acb_is_int(s)) best_cost *= 0.5; mag_init(err); for (N = 1; N <= FLINT_MIN(num_eval, 2048); N = FLINT_MAX(N+1, N*1.2)) { /* AN should be at least as large as |s| */ A = FLINT_MAX(abss / N + 1.0, 1); /* Estimate K based on asymptotics for the error term. We will have to adjust up by actually computing the error bound. */ K = FLINT_MAX(prec * log(2) / (log(2*A*N) + 1.0) + 1.0, 1); for ( ; K < num_eval; K = FLINT_MAX(K+1, K*1.2)) { /* Too much space. */ if (_acb_vec_estimate_allocated_bytes(N * K, prec) > 1e9) break; acb_dirichlet_hurwitz_precomp_bound(err, s, A, K, N); cost = (K * num_eval) * MUL_COST + /* polynomial evaluation */ (A * num_eval) * POW_COST + /* power sum */ (N * K) * ZETA_COST; /* precomputation cost */ /* The accuracy is good enough. */ if (mag_cmp_2exp_si(err, -prec) <= 0) { if (cost < best_cost) { best_cost = cost; best_A = A; best_K = K; best_N = N; } break; } /* It will only get worse from here. */ if (cost > best_cost) break; } } *_A = best_A; *_K = best_K; *_N = best_N; mag_clear(err); } arb-2.22.1/acb_dirichlet/hurwitz_precomp_clear.c000066400000000000000000000011711417376376500217140ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_hurwitz_precomp_clear(acb_dirichlet_hurwitz_precomp_t pre) { acb_clear(&pre->s); if (pre->A != 0) { mag_clear(&pre->err); _acb_vec_clear(pre->coeffs, pre->N * pre->K); } } arb-2.22.1/acb_dirichlet/hurwitz_precomp_eval.c000066400000000000000000000035501417376376500215600ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_hurwitz_precomp_eval(acb_t res, const acb_dirichlet_hurwitz_precomp_t pre, ulong p, ulong q, slong prec) { slong i; acb_t a, t; if (p > q) { flint_printf("hurwitz_precomp_eval: require p <= n\n"); flint_abort(); } if (pre->A == 0) { acb_init(a); acb_set_ui(a, p); acb_div_ui(a, a, q, prec); if (pre->deflate == 0) acb_hurwitz_zeta(res, &pre->s, a, prec); else _acb_poly_zeta_cpx_series(res, &pre->s, a, 1, 1, prec); acb_clear(a); return; } acb_init(a); acb_init(t); /* todo: avoid integer overflows below */ if (p == q) i = pre->N - 1; else i = (pre->N * p) / q; acb_set_si(a, 2 * pre->N * p - q * (2 * i + 1)); acb_div_ui(a, a, 2 * q * pre->N, prec); /* compute zeta(s,A+p/q) */ _acb_poly_evaluate(res, pre->coeffs + i * pre->K, pre->K, a, prec); /* error bound */ if (acb_is_real(&pre->s)) arb_add_error_mag(acb_realref(res), &pre->err); else acb_add_error_mag(res, &pre->err); /* zeta(s,p/q) = (p/q)^-s + ... + (p/q+A-1)^-s zeta(s,A+p/q) */ for (i = 0; i < pre->A; i++) { acb_set_ui(a, p); acb_div_ui(a, a, q, prec); acb_add_ui(a, a, i, prec); acb_neg(t, &pre->s); acb_pow(a, a, t, prec); acb_add(res, res, a, prec); } acb_clear(a); acb_clear(t); } arb-2.22.1/acb_dirichlet/hurwitz_precomp_init.c000066400000000000000000000051031417376376500215700ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_hurwitz_precomp_init(acb_dirichlet_hurwitz_precomp_t pre, const acb_t s, int deflate, slong A, slong K, slong N, slong prec) { slong i, k; pre->deflate = deflate; pre->A = A; pre->K = K; pre->N = N; acb_init(&pre->s); acb_set(&pre->s, s); if (A == 0) return; if (A < 1 || K < 1 || N < 1) { flint_printf("hurwitz_precomp_init: require A, K, N >= 1 (unless A == 0)\n"); flint_abort(); } pre->coeffs = _acb_vec_init(N * K); mag_init(&pre->err); acb_dirichlet_hurwitz_precomp_bound(&pre->err, s, A, K, N); if (mag_is_finite(&pre->err)) { acb_t t, a; acb_init(t); acb_init(a); /* (-1)^k (s)_k / k! */ acb_one(pre->coeffs + 0); for (k = 1; k < K; k++) { acb_add_ui(pre->coeffs + k, s, k - 1, prec); acb_mul(pre->coeffs + k, pre->coeffs + k, pre->coeffs + k - 1, prec); acb_div_ui(pre->coeffs + k, pre->coeffs + k, k, prec); acb_neg(pre->coeffs + k, pre->coeffs + k); } for (i = 1; i < N; i++) _acb_vec_set(pre->coeffs + i * K, pre->coeffs, K); /* zeta(s+k,a) where a = A + (2*i+1)/(2*N) */ for (i = 0; i < N; i++) { acb_set_ui(a, 2 * i + 1); acb_div_ui(a, a, 2 * N, prec); acb_add_ui(a, a, A, prec); for (k = 0; k < K; k++) { acb_add_ui(t, s, k, prec); if (deflate && k == 0) _acb_poly_zeta_cpx_series(t, t, a, 1, 1, prec); else acb_hurwitz_zeta(t, t, a, prec); acb_mul(pre->coeffs + i * K + k, pre->coeffs + i * K + k, t, prec); } } acb_clear(t); acb_clear(a); } } void acb_dirichlet_hurwitz_precomp_init_num(acb_dirichlet_hurwitz_precomp_t pre, const acb_t s, int deflate, double num_eval, slong prec) { ulong A, K, N; acb_dirichlet_hurwitz_precomp_choose_param(&A, &K, &N, s, num_eval, prec); acb_dirichlet_hurwitz_precomp_init(pre, s, deflate, A, K, N, prec); } arb-2.22.1/acb_dirichlet/isolate_hardy_z_zero.c000066400000000000000000001120551417376376500215300ustar00rootroot00000000000000/* Copyright (C) 2010 Juan Arias de Reyna Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_calc.h" /* * For a detailed explanation of the algorithm implemented in this file, see: * * J. Arias de Reyna, "Programs for Riemann's zeta function", (J. A. J. van * Vonderen, Ed.) Leven met getallen : liber amicorum ter gelegenheid van de * pensionering van Herman te Riele, CWI (2012) 102-112, * https://ir.cwi.nl/pub/19724 */ /* * These constants define the largest n such that for every k <= n * the kth zero of the Hardy Z function is governed by Gram's law * or by Rosser's rule respectively. */ static const slong GRAMS_LAW_MAX = 126; static const slong ROSSERS_RULE_MAX = 13999526; /* * This structure describes a node of a doubly linked list. * Each node represents a height t at which the Hardy Z-function * Z(t) has been evaluated. * * As it relates to this data structure, the big picture of the algorithm * to isolate the nth zero is roughly: * * 1) Initialize a two-node list consisting of the two points * predicted by Gram's law to surround the nth zero. * 2) Append and prepend as many additional Gram points as are indicated * by the theory behind Turing's method, and occasionally insert points * between existing points for the purpose of certifying blocks of intervals * as 'good'. * 3) Repeatedly insert new points into the list, interleaving existing points, * until the number of sign changes indicated by theory is observed. * This is where the algorithm would enter an infinite loop if it encountered * a counterexample to the Riemann hypothesis. * 4) Traverse the list until we find the pair of adjacent nodes with opposite * signs of Z(t) that corresponds to the nth zero; the t heights of the * two nodes define the endpoints of an isolating interval. * 5) Delete the list. */ typedef struct _zz_node_struct { arf_struct t; /* height t where v = Z(t) is evaluated */ arb_struct v; /* Z(t) */ fmpz *gram; /* Gram point index or NULL if not a Gram point */ slong prec; /* precision of evaluation of v */ struct _zz_node_struct *prev; struct _zz_node_struct *next; } zz_node_struct; typedef zz_node_struct zz_node_t[1]; typedef zz_node_struct * zz_node_ptr; typedef const zz_node_struct * zz_node_srcptr; static int zz_node_is_gram_node(const zz_node_t p) { return p->gram != NULL; } static int zz_node_sgn(const zz_node_t p) { int s = arb_sgn_nonzero(&p->v); if (!s) { flint_printf("unexpectedly imprecise evaluation of Z(t)\n"); flint_abort(); } return s; } /* Good Gram points are Gram points where sgn(Z(g(n)))*(-1)^n > 0. */ static int zz_node_is_good_gram_node(const zz_node_t p) { if (zz_node_is_gram_node(p)) { int s = zz_node_sgn(p); if ((s > 0 && fmpz_is_even(p->gram)) || (s < 0 && fmpz_is_odd(p->gram))) { return 1; } } return 0; } static void zz_node_init(zz_node_t p) { arf_init(&p->t); arb_init(&p->v); arb_indeterminate(&p->v); p->prec = 0; p->gram = NULL; p->prev = NULL; p->next = NULL; } static void zz_node_clear(zz_node_t p) { arf_clear(&p->t); arb_clear(&p->v); if (p->gram) { fmpz_clear(p->gram); flint_free(p->gram); } p->prec = 0; p->gram = NULL; p->prev = NULL; p->next = NULL; } /* * The node p represents the evaluation of the Hardy Z-function * at a point t with some precision. This function re-evaluates * the Hardy Z-function at t with greater precision, and it also * guarantees that the precision is high enough to determine the * sign of Z(t). */ static int zz_node_refine(zz_node_t p) { slong default_prec = arf_bits(&p->t) + 8; if (p->prec < default_prec) { p->prec = default_prec; } else { p->prec *= 2; } return _acb_dirichlet_definite_hardy_z(&p->v, &p->t, &p->prec); } /* * Create a node representing an evaluation of the Hardy Z-function * at arbitrary point t. Upon creation the sign of Z(t) will * be known with certainty. */ static zz_node_ptr create_non_gram_node(const arf_t t) { zz_node_ptr p = flint_malloc(sizeof(zz_node_struct)); zz_node_init(p); arf_set(&p->t, t); zz_node_refine(p); return p; } /* * Create a node representing an evaluation of the Hardy Z-function * at the nth Gram point g(n). Upon creation a floating point number t will be * assigned to this node, with the property that there are no zeros of the * Hardy Z-function between t and the actual value of g(n). * The sign of Z(t) will also be known with certainty. */ static zz_node_ptr create_gram_node(const fmpz_t n) { zz_node_ptr p; arb_t t, v; acb_t z; slong prec = fmpz_bits(n) + 8; arb_init(t); arb_init(v); acb_init(z); while (1) { /* Computing the Gram point to higher precision improves performance significantly. The likely explanation (not verified) is that when evaluating the Z-function at an inexact ball using the Riemann-Siegel formula, error propagation uses a bound for Z' that is far from tight. The extra precision compensates for this lack of tightness. */ acb_dirichlet_gram_point(t, n, NULL, NULL, prec + fmpz_bits(n)); acb_set_arb(z, t); acb_dirichlet_hardy_z(z, z, NULL, NULL, 1, prec); acb_get_real(v, z); if (!arb_contains_zero(v)) { break; } prec *= 2; } p = flint_malloc(sizeof(zz_node_struct)); zz_node_init(p); p->gram = flint_malloc(sizeof(fmpz)); fmpz_init(p->gram); /* t contains g(n) and does not contain a zero of the Z function */ fmpz_set(p->gram, n); arf_set(&p->t, arb_midref(t)); arb_set(&p->v, v); p->prec = prec; arb_clear(t); arb_clear(v); acb_clear(z); return p; } /* * Count the number of Gram intervals between the Gram point * represented by node a and the Gram point represented by node b. * Traversing the linked list is not necessary because the Gram indices * of nodes a and b can be accessed directly. */ static slong count_gram_intervals(zz_node_srcptr a, zz_node_srcptr b) { slong out = 0; if (!a || !b) { flint_printf("a and b must be non-NULL\n"); flint_abort(); } if (!zz_node_is_good_gram_node(a) || !zz_node_is_good_gram_node(b)) { flint_printf("both nodes must be good Gram points\n"); flint_abort(); } else { fmpz_t m; fmpz_init(m); fmpz_sub(m, b->gram, a->gram); out = fmpz_get_si(m); fmpz_clear(m); } return out; } /* * Count the observed number of sign changes of Z(t) by traversing * a linked list of evaluated points from node a to node b. */ static slong count_sign_changes(zz_node_srcptr a, zz_node_srcptr b) { zz_node_srcptr p, q; slong n = 0; if (!a || !b) { flint_printf("a and b must be non-NULL\n"); flint_abort(); } p = a; q = a->next; while (p != b) { if (!q) { flint_printf("prematurely reached end of list\n"); flint_abort(); } if (zz_node_sgn(p) != zz_node_sgn(q)) { n++; } p = q; q = q->next; } return n; } /* * Modify a linked list that ends with node p, * by appending nodes representing Gram points. * Continue until a 'good' Gram point is found. */ static zz_node_ptr extend_to_next_good_gram_node(zz_node_t p) { fmpz_t n; zz_node_ptr q, r; fmpz_init(n); if (!zz_node_is_gram_node(p)) { flint_printf("expected to begin at a gram point\n"); flint_abort(); } if (p->next) { flint_printf("expected to extend from the end of a list\n"); flint_abort(); } fmpz_set(n, p->gram); q = p; while (1) { fmpz_add_ui(n, n, 1); r = create_gram_node(n); q->next = r; r->prev = q; q = r; r = NULL; if (zz_node_is_good_gram_node(q)) { break; } } fmpz_clear(n); return q; } /* * Modify a linked list that begins with node p, * by prepending nodes representing Gram points. * Continue until a 'good' Gram point is found. */ static zz_node_ptr extend_to_prev_good_gram_node(zz_node_t p) { fmpz_t n; zz_node_ptr q, r; fmpz_init(n); if (!zz_node_is_gram_node(p)) { flint_printf("expected to begin at a gram point\n"); flint_abort(); } if (p->prev) { flint_printf("expected to extend from the start of a list\n"); flint_abort(); } fmpz_set(n, p->gram); q = p; while (1) { fmpz_sub_ui(n, n, 1); r = create_gram_node(n); q->prev = r; r->next = q; q = r; r = NULL; if (zz_node_is_good_gram_node(q)) { break; } } fmpz_clear(n); return q; } /* * TODO: This is probably redundant. * Can arb_get_lbound_arf ever give a negative arf given a nonnegative arb? * If the answer is no, and it's probably no, then this function * can be deleted. */ static void _arb_get_lbound_arf_nonnegative(arf_t res, const arb_t x, slong prec) { arb_get_lbound_arf(res, x, prec); if (arf_cmp_si(res, 0) < 0) { arf_zero(res); } } /* * res = (x1*w1 + x2*w2) / (w1 + w2) * Undefined if weights are not nonnegative. * If w1 and w2 are zero, the resulting interval contains x1 and x2. */ static void _weighted_arithmetic_mean(arb_t res, const arf_t x1, const arf_t x2, const arb_t w1, const arb_t w2, slong prec) { if (!arb_is_nonnegative(w1) || !arb_is_nonnegative(w2)) { arb_indeterminate(res); } else if (arb_is_zero(w1) && arb_is_zero(w2)) { arb_set_interval_arf(res, x1, x2, prec); } else if (arb_is_zero(w1)) { arb_set_arf(res, x2); } else if (arb_is_zero(w2)) { arb_set_arf(res, x1); } else if (arb_is_exact(w1) && arb_is_exact(w2)) { arb_t a, b; arb_init(a); arb_init(b); arb_mul_arf(a, w1, x1, prec); arb_addmul_arf(a, w2, x2, prec); arb_add(b, w1, w2, prec); arb_div(res, a, b, prec); arb_clear(a); arb_clear(b); } else { arb_t a, b, r1, r2; arb_init(a); arb_init(b); arb_init(r1); arb_init(r2); arb_zero(a); arb_zero(b); _arb_get_lbound_arf_nonnegative(arb_midref(a), w1, prec); arb_get_ubound_arf(arb_midref(b), w2, prec); _weighted_arithmetic_mean(r1, x1, x2, a, b, prec); arb_zero(a); arb_zero(b); arb_get_ubound_arf(arb_midref(a), w1, prec); _arb_get_lbound_arf_nonnegative(arb_midref(b), w2, prec); _weighted_arithmetic_mean(r2, x1, x2, a, b, prec); arb_union(res, r1, r2, prec); arb_clear(a); arb_clear(b); arb_clear(r1); arb_clear(r2); } } /* * Split the interval (t1, t2) into the intervals (t1, out) and (out, t2) * in an attempt to increase the number of observed sign changes of Z(t) * between endpoints. * v1 and v2 are the Hardy Z-function values at t1 and t2 respectively. * sign1 and sign2 are the signs of v1 and v2 respectively. */ static void split_interval(arb_t out, const arf_t t1, const arb_t v1, slong sign1, const arf_t t2, const arb_t v2, slong sign2, slong prec) { if (sign1 == sign2) { /* * out = (sqrt(v2/v1)*t1 + t2) / (sqrt(v2/v1) + 1) * We have f(t1)=v1, f(t2)=v2 where v1 and v2 have the same sign, * and we want to guess t between t1 and t2 so that f(t) * has the opposite sign. Try the vertex of a parabola that would touch * f(t)=0 between t1 and t2 and would pass through (t1,v1) and (t2,v2). */ arb_t w1, w2; arb_init(w1); arb_init(w2); arb_abs(w1, v2); /* w1, v2 is deliberate */ arb_sqrt(w1, w1, prec); arb_abs(w2, v1); /* w2, v1 is deliberate */ arb_sqrt(w2, w2, prec); _weighted_arithmetic_mean(out, t1, t2, w1, w2, prec); arb_clear(w1); arb_clear(w2); } else { /* * out = (t1 + t2) / 2 * There is already one sign change in this interval. * To find additional sign changes we would need to evaluate * at least two more points in the interval, * so begin by just splitting the interval in half at the midpoint. */ arb_set_arf(out, t1); arb_add_arf(out, out, t2, prec); arb_mul_2exp_si(out, out, -1); } } /* * Add a new node between each pair of existing nodes in the linked list * of evaluated values of t, within the sublist demarcated by nodes a and b. */ static void intercalate(zz_node_t a, zz_node_t b) { arb_t t; zz_node_ptr q, r, mid_node; if (a == NULL || b == NULL) { flint_printf("a and b must be non-NULL\n"); flint_abort(); } if (!zz_node_is_good_gram_node(a) || !zz_node_is_good_gram_node(b)) { flint_printf("a and b must represent good Gram points\n"); flint_abort(); } if (a == b) return; arb_init(t); q = a; r = a->next; while (q != b) { if (!r) { flint_printf("prematurely reached end of list\n"); flint_abort(); } while (1) { split_interval(t, &q->t, &q->v, zz_node_sgn(q), &r->t, &r->v, zz_node_sgn(r), FLINT_MIN(q->prec, r->prec)); if (!arb_contains_arf(t, &q->t) && !arb_contains_arf(t, &r->t)) { break; } zz_node_refine((q->prec < r->prec) ? q : r); } mid_node = create_non_gram_node(arb_midref(t)); q->next = mid_node; mid_node->prev = q; mid_node->next = r; r->prev = mid_node; q = r; r = r->next; } arb_clear(t); } /* * Virtually trim k Gram/Rosser blocks from the head and from the tail * of the sublist (a, b). The resulting sublist is (*A, *B). * No nodes or connections between nodes are modified, added, or deleted. */ static void trim(zz_node_ptr *A, zz_node_ptr *B, zz_node_ptr a, zz_node_ptr b, slong k) { slong n; for (n = 0; n < k; n++) { a = a->next; while (!zz_node_is_good_gram_node(a)) { a = a->next; } b = b->prev; while (!zz_node_is_good_gram_node(b)) { b = b->prev; } } *A = a; *B = b; } /* * Given a linked sublist beginning at U and ending at V defining function * evaluations at points that fully separate zeros of Z(t) in the vicinity * of the nth zero, traverse the list until the nth zero is found. * Continue traversing the list until len consecutive isolating intervals * have been found, or until the end of the sublist is reached. * Return the number of isolated zeros found, starting at the nth zero. */ static slong count_up_separated_zeros(arf_interval_ptr res, zz_node_srcptr U, zz_node_srcptr V, const fmpz_t n, slong len) { if (len <= 0) { return 0; } else if (fmpz_sgn(n) < 1) { flint_printf("nonpositive indices of zeros are not supported\n"); flint_abort(); } else if (U == NULL || V == NULL) { flint_printf("U and V must not be NULL\n"); flint_abort(); } if (!zz_node_is_good_gram_node(U) || !zz_node_is_good_gram_node(V)) { flint_printf("U and V must be good Gram points\n"); flint_abort(); } else { slong i = 0; zz_node_srcptr p = U; fmpz_t N, k; fmpz_init(N); fmpz_init(k); fmpz_add_ui(N, p->gram, 1); fmpz_set(k, n); while (p != V) { if (!p->next) { flint_printf("prematurely reached end of list\n"); flint_abort(); } if (zz_node_sgn(p) != zz_node_sgn(p->next)) { fmpz_add_ui(N, N, 1); if (fmpz_equal(N, k)) { arf_set(&res[i].a, &p->t); arf_set(&res[i].b, &p->next->t); fmpz_add_ui(k, k, 1); i++; if (i == len) break; } } p = p->next; } fmpz_clear(k); return i; } return 0; } /* * Find one 'superblock' below n and one 'superblock' above n. * The term 'superblock' in this context means a stretch of * enough consecutive 'good' Rosser/Gram blocks to meet the Turing method bound. * The output *psb is the number of blocks in the superblock. * The output nodes *pu and *pv are the first node of the first superblock * and the last node of the second superblock respectively. */ static void turing_search_near(zz_node_ptr *pu, zz_node_ptr *pv, slong *psb, const fmpz_t n) { zz_node_ptr u, v; slong i; slong zn; /* target number of sign changes */ slong sb; /* the number of padding blocks required by Turing's method */ slong cgb; /* the number of consecutive good blocks */ const slong loopcount = 4; fmpz_t k; fmpz_init(k); fmpz_sub_ui(k, n, 2); u = create_gram_node(k); fmpz_sub_ui(k, n, 1); v = create_gram_node(k); u->next = v; v->prev = u; if (!zz_node_is_good_gram_node(u)) u = extend_to_prev_good_gram_node(u); if (!zz_node_is_good_gram_node(v)) v = extend_to_next_good_gram_node(v); /* * Extend the search to greater heights t. * * Continue adding Gram points until the number of consecutive * 'good' Gram/Rosser blocks reaches the Turing method bound. */ sb = 0; cgb = 0; while (1) { zz_node_ptr nv; nv = extend_to_next_good_gram_node(v); zn = count_gram_intervals(v, nv); for (i = 0; i < loopcount && count_sign_changes(v, nv) < zn; i++) { intercalate(v, nv); } if (count_sign_changes(v, nv) >= zn) { cgb++; if (cgb > sb) { sb = cgb; if (acb_dirichlet_turing_method_bound(nv->gram) <= sb) { v = nv; break; } } } else { cgb = 0; } v = nv; } /* Extend the search to smaller heights t. */ cgb = 0; while (1) { zz_node_ptr pu; pu = extend_to_prev_good_gram_node(u); zn = count_gram_intervals(pu, u); for (i = 0; i < loopcount && count_sign_changes(pu, u) < zn; i++) { intercalate(pu, u); } if (count_sign_changes(pu, u) >= zn) { cgb++; if (cgb == sb) { u = pu; break; } } else { cgb = 0; } u = pu; } *pu = u; *pv = v; *psb = sb; fmpz_clear(k); } /* * Find one 'double superblock' beginning below the point represented * by node u, and find one 'double superblock' ending above the point * represented by node v. The term 'double superblock' in this context * means a stretch of twice as many consecutive 'good' Rosser/Gram blocks * as would meet the Turing method bound. * The output nodes *pu and *pv are the first node of the first double * superblock and the last node of the second double superblock respectively. * The output integer *psb reports one half of the number * of blocks in the double superblock. * The parameter initial_cgb is the number of consecutive good blocks * above and below the points represented by nodes u and v respectively. */ static void turing_search_far(zz_node_ptr *pu, zz_node_ptr *pv, slong *psb, zz_node_ptr u, zz_node_ptr v, slong initial_cgb) { slong i; slong zn; /* target number of sign changes */ slong sb; /* the number of padding blocks required by Turing's method */ slong cgb; /* the number of consecutive good blocks */ const slong loopcount = 4; /* * Extend the search to greater heights t. * * Continue adding Gram points until the number of consecutive * 'good' Gram/Rosser blocks is twice the number required by * the Turing method bound. */ sb = 0; cgb = initial_cgb; while (1) { zz_node_ptr nv; nv = extend_to_next_good_gram_node(v); zn = count_gram_intervals(v, nv); for (i = 0; i < loopcount && count_sign_changes(v, nv) < zn; i++) { intercalate(v, nv); } if (count_sign_changes(v, nv) >= zn) { cgb++; if (cgb % 2 == 0 && sb < cgb / 2) { sb = cgb / 2; if (acb_dirichlet_turing_method_bound(nv->gram) <= sb) { v = nv; break; } } } else { cgb = 0; } v = nv; } /* Extend the search to smaller heights t. */ cgb = initial_cgb; while (1) { zz_node_ptr pu; pu = extend_to_prev_good_gram_node(u); zn = count_gram_intervals(pu, u); for (i = 0; i < loopcount && count_sign_changes(pu, u) < zn; i++) { intercalate(pu, u); } if (count_sign_changes(pu, u) >= zn) { cgb++; if (cgb == sb*2) { u = pu; break; } } else { cgb = 0; } u = pu; } *pu = u; *pv = v; *psb = sb; } /* * Used for both zero isolation and for N(t). * n is the index of a Hardy Z-function zero of interest. * *pu and *pv are the first and last node of an output list. * *pU and *pV are the first and last nodes of a sublist with * fully separated zeros, within the *pu -- *pv list. */ static void _separated_turing_list(zz_node_ptr *pU, zz_node_ptr *pV, zz_node_ptr *pu, zz_node_ptr *pv, const fmpz_t n) { zz_node_ptr U, V, u, v; slong i; slong sb_near; /* Turing method bound for near search */ slong sb_far; /* Turing method bound for far search */ slong zn; /* target number of sign changes */ slong variations; /* observed number of sign changes */ const slong loopcount = 4; /* * The loopcount controls how hard we try to find zeros in Gram/Rosser * blocks. If the loopcount is too high then when Rosser's rule is violated * we will spend too much time searching for zeros that don't exist. * If the loopcount is too low then we will miss some 'good' blocks, * causing the search to be extended unnecessarily far from the initial * guess before eventually making another pass in which loopcount * is effectively infinite. */ if (fmpz_cmp_si(n, 2) < 0) { flint_printf("invalid n: "); fmpz_print(n); flint_printf("\n"); flint_abort(); } turing_search_near(&u, &v, &sb_near, n); trim(&U, &V, u, v, sb_near); zn = count_gram_intervals(U, V); for (i = 0; i < loopcount && count_sign_changes(U, V) < zn; i++) { intercalate(U, V); } variations = count_sign_changes(U, V); if (variations > zn) { flint_printf("unexpected number of sign changes\n"); flint_abort(); } else if (variations < zn) { zz_node_ptr r = U; zz_node_ptr s = V; turing_search_far(&u, &v, &sb_far, u, v, sb_near); trim(&U, &V, u, v, 2*sb_far); zn = count_gram_intervals(U, V); for (i = 0; i < loopcount && count_sign_changes(U, V) < zn; i++) { intercalate(U, r); intercalate(s, V); } variations = count_sign_changes(U, V); if (variations > zn) { flint_printf("unexpected number of sign changes\n"); flint_abort(); } else if (variations < zn) { trim(&U, &V, u, v, sb_far); zn = count_gram_intervals(U, V); while (count_sign_changes(U, V) < zn) { intercalate(U, V); } if (count_sign_changes(U, V) != zn) { flint_printf("unexpected number of sign changes\n"); flint_abort(); } } } *pu = u; *pv = v; *pU = U; *pV = V; } /* * Used for both zero isolation and for N(t). * n is the index of a Hardy Z-function zero of interest. * *pu and *pv are the first and last node of an output list * with fully separated zeros. */ static void _separated_rosser_list(zz_node_ptr *pu, zz_node_ptr *pv, const fmpz_t n) { fmpz_t k; zz_node_ptr u, v; if (fmpz_cmp_si(n, 1) < 0 || fmpz_cmp_si(n, ROSSERS_RULE_MAX) > 0) { flint_printf("invalid n: "); fmpz_print(n); flint_printf("\n"); flint_abort(); } fmpz_init(k); fmpz_sub_ui(k, n, 2); u = create_gram_node(k); fmpz_sub_ui(k, n, 1); v = create_gram_node(k); u->next = v; v->prev = u; if (!zz_node_is_good_gram_node(u)) u = extend_to_prev_good_gram_node(u); if (!zz_node_is_good_gram_node(v)) v = extend_to_next_good_gram_node(v); while (count_sign_changes(u, v) != count_gram_intervals(u, v)) { intercalate(u, v); } *pu = u; *pv = v; fmpz_clear(k); } /* * Used for both zero isolation and for N(t). * n is the index of a Hardy Z-function zero of interest. * *pu and *pv are the first and last node of an output list * with fully separated zeros. */ static void _separated_gram_list(zz_node_ptr *pu, zz_node_ptr *pv, const fmpz_t n) { fmpz_t k; zz_node_ptr u, v; if (fmpz_cmp_si(n, 1) < 0 || fmpz_cmp_si(n, GRAMS_LAW_MAX) > 0) { flint_printf("invalid n: "); fmpz_print(n); flint_printf("\n"); flint_abort(); } fmpz_init(k); fmpz_sub_ui(k, n, 2); u = create_gram_node(k); fmpz_sub_ui(k, n, 1); v = create_gram_node(k); u->next = v; v->prev = u; *pu = u; *pv = v; fmpz_clear(k); } /* * Get a list of points that fully separate zeros of Z. * Used for both zero isolation and for N(t). * n is the index of a Hardy Z-function zero of interest. * *pu and *pv are the first and last node of an output list. * *pU and *pV are the first and last nodes of a sublist with * fully separated zeros, within the *pu -- *pv list. */ static void _separated_list(zz_node_ptr *pU, zz_node_ptr *pV, zz_node_ptr *pu, zz_node_ptr *pv, const fmpz_t n) { zz_node_ptr U, V, u, v; if (fmpz_cmp_si(n, GRAMS_LAW_MAX) <= 0) { _separated_gram_list(&u, &v, n); U = u; V = v; } else if (fmpz_cmp_si(n, ROSSERS_RULE_MAX) <= 0) { _separated_rosser_list(&u, &v, n); U = u; V = v; } else { _separated_turing_list(&U, &V, &u, &v, n); } if (U == NULL || V == NULL) { flint_printf("U and V must not be NULL\n"); flint_abort(); } if (!zz_node_is_good_gram_node(U) || !zz_node_is_good_gram_node(V)) { flint_printf("U and V must be good Gram points\n"); flint_abort(); } if (U == V) { flint_printf("the list must include at least one interval\n"); flint_abort(); } *pU = U; *pV = V; *pu = u; *pv = v; } /* * Isolate up to len zeros, starting from the nth zero. * Return the number of isolated zeros. */ static slong _isolate_hardy_z_zeros(arf_interval_ptr res, const fmpz_t n, slong len) { zz_node_ptr U, V, u, v; slong count; _separated_list(&U, &V, &u, &v, n); count = count_up_separated_zeros(res, U, V, n, len); while (u) { v = u; u = u->next; zz_node_clear(v); flint_free(v); } return count; } /* Isolate len zeros, starting from the nth zero. */ void acb_dirichlet_isolate_hardy_z_zeros(arf_interval_ptr res, const fmpz_t n, slong len) { if (len <= 0) { return; } else if (fmpz_sgn(n) < 1) { flint_printf("nonpositive indices of zeros are not supported\n"); flint_abort(); } else { slong c = 0; fmpz_t k; fmpz_init(k); while (c < len) { fmpz_add_si(k, n, c); c += _isolate_hardy_z_zeros(res + c, k, len - c); } fmpz_clear(k); } } void acb_dirichlet_isolate_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) { if (fmpz_sgn(n) < 1) { flint_printf("nonpositive indices of zeros are not supported\n"); flint_abort(); } else { arf_interval_t r; arf_interval_init(r); _isolate_hardy_z_zeros(r, n, 1); arf_set(a, &r->a); arf_set(b, &r->b); arf_interval_clear(r); } } static void count_up(arf_t a, arf_t b, zz_node_srcptr U, zz_node_srcptr V, const fmpz_t n) { arf_interval_t r; arf_interval_init(r); count_up_separated_zeros(r, U, V, n, 1); arf_set(a, &r->a); arf_set(b, &r->b); arf_interval_clear(r); } void _acb_dirichlet_isolate_turing_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) { zz_node_ptr U, V, u, v; _separated_turing_list(&U, &V, &u, &v, n); count_up(a, b, U, V, n); while (u) { v = u; u = u->next; zz_node_clear(v); flint_free(v); } } void _acb_dirichlet_isolate_rosser_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) { zz_node_ptr u, v; _separated_rosser_list(&u, &v, n); count_up(a, b, u, v, n); while (u) { v = u; u = u->next; zz_node_clear(v); flint_free(v); } } void _acb_dirichlet_isolate_gram_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) { zz_node_ptr u, v; _separated_gram_list(&u, &v, n); count_up(a, b, u, v, n); while (u) { v = u; u = u->next; zz_node_clear(v); flint_free(v); } } static void _acb_set_arf(acb_t res, const arf_t t) { acb_zero(res); arb_set_arf(acb_realref(res), t); } /* * Find the index of the largest Gram point less than t. * Requires t > 10. */ static void gram_index(fmpz_t res, const arf_t t) { if (arf_cmp_si(t, 10) < 0) { flint_printf("gram_index requires t > 10\n"); flint_abort(); } else { acb_t z; slong prec = arf_abs_bound_lt_2exp_si(t) + 8; acb_init(z); while (1) { _acb_set_arf(z, t); acb_dirichlet_hardy_theta(z, z, NULL, NULL, 1, prec); arb_const_pi(acb_imagref(z), prec); arb_div(acb_realref(z), acb_realref(z), acb_imagref(z), prec); arb_floor(acb_realref(z), acb_realref(z), prec); if (arb_get_unique_fmpz(res, acb_realref(z))) { break; } prec *= 2; } acb_clear(z); } } /* * Compute nzeros(t) for up to len values of t * and return the number computed. p must be in increasing order, * and all entries must be greater than 10. */ static slong _exact_zeta_multi_nzeros(fmpz *res, arf_srcptr points, slong len) { zz_node_ptr U, V, u, v, p; arb_t x; fmpz_t n, N; slong i; arf_srcptr t; int s; slong prec; arb_init(x); fmpz_init(n); fmpz_init(N); /* * The first point is located between two Gram points. Find the unique n * such that the nth zero is also predicted to be located between these * Gram points. */ gram_index(n, points); fmpz_add_ui(n, n, 2); /* Get a list of points that fully separate zeros of Z. */ _separated_list(&U, &V, &u, &v, n); p = U; fmpz_add_ui(N, U->gram, 1); /* * It's possible that one or more points are located between * the first Gram point and the arf_t representative of that Gram point. */ for (i = 0, t = points; i < len && arf_cmp(t, &p->t) <= 0; i++, t++) { fmpz_set(res + i, N); } while (i < len && p != V) { if (!p->next) { flint_printf("prematurely reached the end of the list\n"); flint_abort(); } if (zz_node_sgn(p) != zz_node_sgn(p->next)) { while (i < len && arf_cmp(t, &p->next->t) <= 0) { prec = arf_abs_bound_lt_2exp_si(t) + 8; s = _acb_dirichlet_definite_hardy_z(x, t, &prec); if (zz_node_sgn(p->next) == s) { fmpz_add_ui(res + i, N, 1); } else { fmpz_set(res + i, N); } t++; i++; } fmpz_add_ui(N, N, 1); } p = p->next; } /* * It's possible that the first point in the array is located between * the last Gram point and the arf_t representative of that Gram point. */ if (i == 0) { fmpz_set(res, N); i++; } while (u) { v = u; u = u->next; zz_node_clear(v); flint_free(v); } arb_clear(x); fmpz_clear(n); fmpz_clear(N); return i; } /* * Compute nzeros for len values of t. The array p must be in increasing order. */ static void exact_zeta_multi_nzeros(fmpz *res, arf_srcptr p, slong len) { slong i, c; arf_srcptr q; if (len <= 0) { return; } for (i = 0, q = p; i < len - 1; i++, q++) { if (arf_cmp(q, p) > 0) { flint_printf("p must be in increasing order\n"); flint_abort(); } } c = 0; while (c < len) { if (arf_cmp_si(p + c, 14) < 0) { fmpz_zero(res + c); c++; } else { c += _exact_zeta_multi_nzeros(res + c, p + c, len - c); } } } void _acb_dirichlet_exact_zeta_nzeros(fmpz_t res, const arf_t t) { exact_zeta_multi_nzeros(res, t, 1); } void acb_dirichlet_hardy_z_zeros(arb_ptr res, const fmpz_t n, slong len, slong prec) { if (len <= 0) { return; } else if (fmpz_sgn(n) < 1) { flint_printf("nonpositive indices of zeros are not supported\n"); flint_abort(); } else { slong i; arf_interval_ptr p = _arf_interval_vec_init(len); acb_dirichlet_isolate_hardy_z_zeros(p, n, len); for (i = 0; i < len; i++) { _acb_dirichlet_refine_hardy_z_zero(res + i, &p[i].a, &p[i].b, prec); } _arf_interval_vec_clear(p, len); } } static void _arb_set_interval_fmpz(arb_t res, const fmpz_t a, const fmpz_t b) { fmpz_t n; fmpz_init(n); fmpz_add(n, a, b); arf_set_fmpz(arb_midref(res), n); fmpz_sub(n, b, a); mag_set_fmpz(arb_radref(res), n); arb_mul_2exp_si(res, res, -1); fmpz_clear(n); } void acb_dirichlet_zeta_nzeros(arb_t res, const arb_t t, slong prec) { if (arb_is_exact(t)) { fmpz_t n; fmpz_init(n); _acb_dirichlet_exact_zeta_nzeros(n, arb_midref(t)); arb_set_fmpz(res, n); fmpz_clear(n); } else { arf_struct b[2]; fmpz n[2]; arf_init(b); arf_init(b + 1); fmpz_init(n); fmpz_init(n + 1); arb_get_lbound_arf(b, t, prec); arb_get_ubound_arf(b + 1, t, prec); exact_zeta_multi_nzeros(n, b, 2); _arb_set_interval_fmpz(res, n, n + 1); arf_clear(b); arf_clear(b + 1); fmpz_clear(n); fmpz_clear(n + 1); } arb_set_round(res, res, prec); } void acb_dirichlet_zeta_nzeros_gram(fmpz_t res, const fmpz_t n) { zz_node_ptr U, V, u, v, p; fmpz_t k, N; if (fmpz_cmp_si(n, -1) < 0) { flint_printf("n must be >= -1\n"); flint_abort(); } fmpz_init(k); fmpz_init(N); /* * Get a list of points that fully separate zeros of Z. * The kth zero is expected to be between the k-2 and the k-1 gram points. */ fmpz_add_ui(k, n, 2); _separated_list(&U, &V, &u, &v, k); p = U; fmpz_add_ui(N, U->gram, 1); fmpz_set_si(res, -1); while (1) { if (p == NULL) { flint_printf("prematurely reached the end of the list\n"); flint_abort(); } if (zz_node_is_gram_node(p) && fmpz_equal(n, p->gram)) { fmpz_set(res, N); break; } if (zz_node_sgn(p) != zz_node_sgn(p->next)) { fmpz_add_ui(N, N, 1); } if (p == V) { break; } p = p->next; } if (fmpz_sgn(res) < 0) { flint_printf("failed to find the gram point\n"); flint_abort(); } while (u) { v = u; u = u->next; zz_node_clear(v); flint_free(v); } fmpz_clear(k); fmpz_clear(N); } arb-2.22.1/acb_dirichlet/jacobi_sum.c000066400000000000000000000056351417376376500174310ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* J_N(1,a) = sum on x = 1 mod some p | q */ ulong jacobi_one_prime(ulong p, ulong e, ulong pe, ulong cond) { if (e > 1 && cond % (p*p) == 0) { return 0; } else { slong r = (e > 1) ? pe / p : 1; if (cond % p) return r * (p - 2); else return -r; } } static ulong jacobi_one(const dirichlet_group_t G, ulong cond) { slong k, r = 1; for (k = 0; k < G->num; k++) r *= jacobi_one_prime(G->P[k].p, G->P[k].e, G->P[k].pe.n, cond); return r; } void acb_dirichlet_jacobi_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) { if (G->q_even > 1) { acb_zero(res); } else if (chi1->n == 1 || chi2->n == 1) { ulong cond = (chi1->n == 1) ? dirichlet_conductor_char(G, chi2) : dirichlet_conductor_char(G, chi1); acb_set_si(res, jacobi_one(G, cond)); } else if (nmod_mul(chi1->n, chi2->n, G->mod) == 1) { ulong n; n = jacobi_one(G, dirichlet_conductor_char(G, chi1)); if (dirichlet_parity_char(G, chi1)) acb_set_si(res, -n); else acb_set_si(res, n); } else { if (G->q <= 150) acb_dirichlet_jacobi_sum_naive(res, G, chi1, chi2, prec); else if (G->num > 1) acb_dirichlet_jacobi_sum_factor(res, G, chi1, chi2, prec); else if (G->P[0].e > 1) acb_dirichlet_jacobi_sum_naive(res, G, chi1, chi2, prec); else acb_dirichlet_jacobi_sum_gauss(res, G, chi1, chi2, prec); } } void acb_dirichlet_jacobi_sum_ui(acb_t res, const dirichlet_group_t G, ulong a, ulong b, slong prec) { if (G->q_even > 1) { acb_zero(res); } else if (a == 1 || b == 1) { ulong cond = (a == 1) ? dirichlet_conductor_ui(G, b) : dirichlet_conductor_ui(G, a); acb_set_si(res, jacobi_one(G, cond)); } else if (nmod_mul(a, b, G->mod) == 1) { ulong n; n = jacobi_one(G, dirichlet_conductor_ui(G, a)); if (dirichlet_parity_ui(G, a)) acb_set_si(res, -n); else acb_set_si(res, n); } else { dirichlet_char_t chi1, chi2; dirichlet_char_init(chi1, G); dirichlet_char_init(chi2, G); dirichlet_char_log(chi1, G, a); dirichlet_char_log(chi2, G, b); acb_dirichlet_jacobi_sum(res, G, chi1, chi2, prec); dirichlet_char_clear(chi1); dirichlet_char_clear(chi2); } } arb-2.22.1/acb_dirichlet/jacobi_sum_factor.c000066400000000000000000000041621417376376500207610ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_jacobi_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) { slong k; acb_t tmp; acb_init(tmp); acb_one(res); /* TODO: efficient subgroup */ for (k = 0; k < G->num; k++) { nmod_t pe; ulong p, e, ap, bp; p = G->P[k].p; e = G->P[k].e; pe = G->P[k].pe; ap = chi1->n % pe.n; bp = chi2->n % pe.n; if (ap == 1 || bp == 1 || nmod_mul(ap, bp, pe) == 1) { slong r; ulong cond; cond = (ap == 1) ? dirichlet_conductor_char(G, chi2) : dirichlet_conductor_char(G, chi1); r = jacobi_one_prime(p, e, pe.n, cond); /* chi(a,-1) if ap * bp = 1 */ if (ap != 1 && bp != 1) r *= n_jacobi_unsigned(ap, p); acb_mul_si(res, res, r, prec); } else { dirichlet_group_t Gp; dirichlet_char_t chi1p, chi2p; dirichlet_group_init(Gp, pe.n); dirichlet_char_init(chi1p, Gp); dirichlet_char_init(chi2p, Gp); chi1p->n = ap; chi1p->log[0] = chi1->log[k]; chi2p->n = ap; chi2p->log[0] = chi2->log[k]; /* TODO: work out gauss relations for e > 1 */ if (p <= 100 || e > 1) acb_dirichlet_jacobi_sum_naive(tmp, Gp, chi1p, chi2p, prec); else acb_dirichlet_jacobi_sum_gauss(tmp, Gp, chi1p, chi2p, prec); acb_mul(res, res, tmp, prec); dirichlet_char_clear(chi1p); dirichlet_char_clear(chi2p); dirichlet_group_clear(Gp); } } acb_clear(tmp); } arb-2.22.1/acb_dirichlet/jacobi_sum_gauss.c000066400000000000000000000021421417376376500206210ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* should use only for prime power modulus */ void acb_dirichlet_jacobi_sum_gauss(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) { /* J_q(a,b)G_q(ab) = G_q(a)G_q(b) */ acb_t tmp; dirichlet_char_t chi12; dirichlet_char_init(chi12, G); dirichlet_char_mul(chi12, G, chi1, chi2); acb_init(tmp); acb_dirichlet_gauss_sum(res, G, chi1, prec); if (chi2->n == chi1->n) acb_set(tmp, res); else acb_dirichlet_gauss_sum(tmp, G, chi2, prec); acb_mul(res, res, tmp, prec); acb_dirichlet_gauss_sum(tmp, G, chi12, prec); acb_div(res, res, tmp, prec); dirichlet_char_clear(chi12); acb_clear(tmp); } arb-2.22.1/acb_dirichlet/jacobi_sum_naive.c000066400000000000000000000030751417376376500206070ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_jacobi_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) { ulong k1, k2, m1, m2, g, e, m; ulong * v1, * v2; slong *v; nmod_t expo; acb_t z; v1 = flint_malloc(G->q * sizeof(ulong)); v2 = flint_malloc(G->q * sizeof(ulong)); dirichlet_vec_set_null(v1, G, G->q); dirichlet_chi_vec_loop(v1, G, chi1, G->q); dirichlet_vec_set_null(v2, G, G->q); dirichlet_chi_vec_loop(v2, G, chi2, G->q); nmod_init(&expo, G->expo); m1 = dirichlet_order_char(G, chi1); m2 = dirichlet_order_char(G, chi2); g = m1 * m2 / n_gcd(m1, m2); m = G->expo / g; v = flint_malloc(g * sizeof(slong)); for (e = 0; e < g; e++) v[e] = 0; for (k1 = 2, k2 = G->q - 1; k2 > 1; k1++, k2--) { if (v1[k1] == DIRICHLET_CHI_NULL || v2[k2] == DIRICHLET_CHI_NULL) continue; e = nmod_add(v1[k1], v2[k2], expo) / m; v[e]++; } acb_init(z); acb_unit_root(z, g, prec); acb_dirichlet_si_poly_evaluate(res, v, g, z, prec); acb_clear(z); flint_free(v); flint_free(v2); flint_free(v1); } arb-2.22.1/acb_dirichlet/l.c000066400000000000000000000062351417376376500155460ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_l_general(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { /* this cutoff is probably too conservative when q is large */ if (arf_cmp_d(arb_midref(acb_realref(s)), 8 + 0.5 * prec / log(prec)) >= 0) { acb_dirichlet_l_euler_product(res, s, G, chi, prec); } else { slong wp = prec + n_clog(G->phi_q, 2); acb_dirichlet_hurwitz_precomp_t pre; acb_dirichlet_hurwitz_precomp_init_num(pre, s, acb_is_one(s), G->phi_q, wp); acb_dirichlet_l_hurwitz(res, s, pre, G, chi, prec); acb_dirichlet_hurwitz_precomp_clear(pre); } } void acb_dirichlet_l(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { if (!acb_is_finite(s)) { acb_indeterminate(res); } else if (G == NULL || G->q == 1) { acb_dirichlet_zeta(res, s, prec); } else if (dirichlet_char_is_primitive(G, chi) && (arf_cmp_d(arb_midref(acb_realref(s)), -0.5) < 0 || (G->q != 1 && dirichlet_parity_char(G, chi) == 0 && arf_cmpabs_d(arb_midref(acb_imagref(s)), 0.125) < 0 && arf_cmp_d(arb_midref(acb_realref(s)), 0.125) < 0))) { /* use functional equation */ acb_t t, u, v; int parity; ulong q; parity = dirichlet_parity_char(G, chi); q = G->q; acb_init(t); acb_init(u); acb_init(v); /* gamma((1-s+p)/2) / gamma((s+p)/2) */ acb_add_ui(t, s, parity, prec); acb_mul_2exp_si(t, t, -1); acb_rgamma(t, t, prec); if (!acb_is_zero(t)) /* assumes q != 1 when s = 0 */ { acb_neg(u, s); acb_add_ui(u, u, 1 + parity, prec); acb_mul_2exp_si(u, u, -1); acb_gamma(u, u, prec); acb_mul(t, t, u, prec); /* epsilon */ acb_dirichlet_root_number(u, G, chi, prec); acb_mul(t, t, u, prec); /* (pi/q)^(s-1/2) */ acb_const_pi(u, prec); acb_div_ui(u, u, q, prec); acb_set_d(v, -0.5); acb_add(v, v, s, prec); acb_pow(u, u, v, prec); acb_mul(t, t, u, prec); acb_sub_ui(u, s, 1, prec); acb_neg(u, u); acb_conj(u, u); acb_dirichlet_l_general(u, u, G, chi, prec); acb_conj(u, u); acb_mul(t, t, u, prec); if (dirichlet_char_is_real(G, chi) && acb_is_real(s)) arb_zero(acb_imagref(t)); } acb_set(res, t); acb_clear(t); acb_clear(u); acb_clear(v); } else { acb_dirichlet_l_general(res, s, G, chi, prec); } } arb-2.22.1/acb_dirichlet/l_euler_product.c000066400000000000000000000077551417376376500205120ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #define ONE_OVER_LOG2 1.4426950408889634 void acb_dirichlet_l_euler_product(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { arf_t left; slong wp, powprec, left_s, acc; ulong val, p, p_limit; double p_needed_approx, powmag, logp, errmag; int is_real, is_int; acb_t t, u, v, c, negs; acb_dirichlet_roots_t roots; mag_t err; if (!acb_is_finite(s)) { acb_indeterminate(res); return; } arf_init(left); arf_set_mag(left, arb_radref(acb_realref(s))); arf_sub(left, arb_midref(acb_realref(s)), left, 2 * MAG_BITS, ARF_RND_FLOOR); /* Require re(s) >= 2. */ if (arf_cmp_si(left, 2) < 0) { acb_indeterminate(res); arf_clear(left); return; } is_real = acb_is_real(s) && dirichlet_char_is_real(G, chi); /* L(s) ~= 1. */ if (arf_cmp_si(left, prec) > 0) { acb_one(res); mag_hurwitz_zeta_uiui(arb_radref(acb_realref(res)), prec, 2); if (!is_real) mag_set(arb_radref(acb_imagref(res)), arb_radref(acb_realref(res))); acb_inv(res, res, prec); arf_clear(left); return; } left_s = arf_get_si(left, ARF_RND_FLOOR); /* Adjust precision based on possible accuracy. */ acc = acb_rel_accuracy_bits(s); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); acc += left_s; prec = FLINT_MIN(prec, acc + 10); /* Heuristic. */ wp = prec + FLINT_BIT_COUNT(prec) + (prec / left_s) + 4; /* Don't work too hard if a small s was passed as input. */ p_limit = 100 + prec * sqrt(prec); /* Truncating at p ~= 2^(prec/s) gives an error of 2^-prec */ if (((double) prec) / left_s > 50.0) p_needed_approx = pow(2.0, 50.0); else p_needed_approx = pow(2.0, ((double) prec) / left_s); p_needed_approx = FLINT_MIN(p_limit, p_needed_approx); /* todo: use exponent of chi instead of G? */ acb_dirichlet_roots_init(roots, G->expo, p_needed_approx / (1.0 + log(p_needed_approx)), wp); acb_init(t); acb_init(u); acb_init(v); acb_init(c); acb_init(negs); is_int = acb_is_int(s); acb_neg(negs, s); acb_one(v); for (p = 2; p < p_limit; p = n_nextprime(p, 1)) { /* p^s */ logp = log(p); powmag = left_s * logp * ONE_OVER_LOG2; /* zeta(s,p) ~= 1/p^s + 1/((s-1) p^(s-1)) */ errmag = (log(left_s - 1.0) + (left_s - 1.0) * logp) * ONE_OVER_LOG2; errmag = FLINT_MIN(powmag, errmag); if (errmag > prec + 2) break; powprec = FLINT_MAX(wp - powmag, 8); val = dirichlet_chi(G, chi, p); if (val != DIRICHLET_CHI_NULL) { acb_dirichlet_root(c, roots, val, powprec); acb_set_ui(t, p); if (is_int) { acb_pow(t, t, s, powprec); acb_set_round(u, v, powprec); acb_div(t, u, t, powprec); } else { acb_pow(t, t, negs, powprec); acb_set_round(u, v, powprec); acb_mul(t, u, t, powprec); } acb_mul(t, t, c, powprec); acb_sub(v, v, t, wp); } } mag_init(err); mag_hurwitz_zeta_uiui(err, left_s, p); if (is_real) arb_add_error_mag(acb_realref(v), err); else acb_add_error_mag(v, err); mag_clear(err); acb_inv(res, v, prec); acb_dirichlet_roots_clear(roots); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(c); acb_clear(negs); arf_clear(left); } arb-2.22.1/acb_dirichlet/l_fmpq.c000066400000000000000000000031751417376376500165710ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" #include "arb_hypgeom.h" #include "acb_dirichlet.h" int acb_dirichlet_l_fmpq_use_afe(ulong q, const fmpq_t s, slong prec) { double cutoff; if ((slong) fmpz_bits(fmpq_numref(s)) - (slong) fmpz_bits(fmpq_denref(s)) > 20) return 0; if (fabs(fmpq_get_d(s)) > 10 + prec * 0.01) return 0; if (q == 1) { if (fmpz_is_one(fmpq_denref(s))) return 0; if (fmpz_is_one(fmpq_numref(s)) && fmpz_equal_si(fmpq_denref(s), 2)) return prec > 32000; return prec > 70000; } if (fmpq_is_zero(s)) return 0; if (fmpz_cmp_ui(fmpq_denref(s), 2) <= 0) { if (prec > 30000) return 1; if (fmpq_is_one(s)) return q > 1000; return q > 50; } cutoff = 15000.0 / q; return prec > cutoff; } void acb_dirichlet_l_fmpq(acb_t res, const fmpq_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { ulong q; q = (G == NULL) ? 1 : G->q; if (acb_dirichlet_l_fmpq_use_afe(q, s, prec)) { acb_dirichlet_l_fmpq_afe(res, s, G, chi, prec); if (acb_is_finite(res)) return; } acb_set_fmpq(res, s, prec + 10); acb_dirichlet_l(res, res, G, chi, prec); } arb-2.22.1/acb_dirichlet/l_fmpq_afe.c000066400000000000000000000407261417376376500174070ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" #include "arb_hypgeom.h" #include "acb_dirichlet.h" #define VERBOSE 0 static double log_gamma_upper_approx(double a, double z) { if (a < z) return (a - 1) * log(z) - z; else return a * (log(a) - 1); } void acb_dirichlet_root_number2(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { acb_dirichlet_root_number(res, G, chi, prec); if (dirichlet_char_is_real(G, chi)) arb_zero(acb_imagref(res)); } static void _arf_trunc(arf_t x) { if (arf_sgn(x) < 0) arf_ceil(x, x); else arf_floor(x, x); } static void arb_extract_bits(arb_t t, const arb_t z, slong b) { arb_mul_2exp_si(t, z, b); _arf_trunc(arb_midref(t)); mag_zero(arb_radref(t)); arb_mul_2exp_si(t, t, -b); } static void acb_dirichlet_afe_tail_bound(mag_t res, const fmpq_t sd2, slong N, ulong q, int parity) { mag_t pi_n2_q, t, u; fmpz_t sprime; mag_init(pi_n2_q); mag_init(t); mag_init(u); fmpz_init(sprime); /* pi_n2_q = pi * N^2 / q (lower bound) */ mag_const_pi_lower(pi_n2_q); mag_mul_ui_lower(pi_n2_q, pi_n2_q, N); mag_mul_ui_lower(pi_n2_q, pi_n2_q, N); mag_set_ui(t, q); mag_div_lower(pi_n2_q, pi_n2_q, t); /* upper bound for sd2 */ fmpz_cdiv_q(sprime, fmpq_numref(sd2), fmpq_denref(sd2)); /* require pi_n2_q > s' */ mag_set_fmpz(t, sprime); if (fmpz_sgn(sprime) > 0 && mag_cmp(pi_n2_q, t) <= 0) { mag_inf(res); } else { mag_expinv(res, pi_n2_q); mag_div_ui(res, res, N); if (!parity) mag_div_ui(res, res, N); /* (1 + q/pi) */ mag_set_ui(t, q); mag_const_pi_lower(u); mag_div(t, t, u); mag_add_ui(t, t, 1); mag_mul(res, res, t); /* max(1, 2^s') */ if (fmpz_sgn(sprime) > 0) mag_mul_2exp_fmpz(res, res, sprime); /* (pi/q)^(s'-1) */ fmpz_sub_ui(sprime, sprime, 1); if (fmpz_sgn(sprime) >= 0) { mag_const_pi(t); mag_set_ui_lower(u, q); mag_div(t, t, u); mag_pow_fmpz(t, t, sprime); } else { mag_const_pi_lower(t); mag_set_ui(u, q); mag_div_lower(t, t, u); fmpz_neg(sprime, sprime); mag_pow_fmpz_lower(t, t, sprime); mag_inv(t, t); } mag_mul(res, res, t); } mag_clear(pi_n2_q); mag_clear(t); mag_clear(u); fmpz_clear(sprime); } void acb_dirichlet_fmpq_sum_afe(acb_t res, const fmpq_t s, const dirichlet_group_t G, const dirichlet_char_t chi, const mag_t abs_tol, slong prec) { slong NN, n, start_bits, bits, wp, wp2, gamma_cached_prec; mag_t AE, err, abs_tol_gamma; arb_t ns, t, u, v, z, z0, z1, x, x2, Ga, Gz1, Gz0, expmz0, z0_prevn, Gz0_prevn, expmz0_prevn; acb_t c; fmpq_t s2; int parity, gamma_singular; ulong q; double abs_tol_mag; double gammainc_mag, gamma_mag, ns_mag; double aa, zz; #if VERBOSE double t1, t2, t3; #endif mag_init(AE); mag_init(err); mag_init(abs_tol_gamma); arb_init(ns); arb_init(t); arb_init(u); arb_init(v); arb_init(z); arb_init(z0); arb_init(z1); arb_init(x); arb_init(x2); arb_init(Ga); arb_init(Gz0); arb_init(Gz1); arb_init(expmz0); arb_init(z0_prevn); arb_init(Gz0_prevn); arb_init(expmz0_prevn); acb_init(c); fmpq_init(s2); if (G == NULL) { parity = 0; q = 1; } else { parity = dirichlet_parity_char(G, chi); q = G->q; } acb_zero(res); /* Initial precision for gamma; may have to be increased later. */ gamma_cached_prec = prec * 1.05 + 30; /* s2 = (s+parity)/2 */ fmpq_add_ui(s2, s, parity); fmpq_div_2exp(s2, s2, 1); gamma_singular = (fmpz_is_one(fmpq_denref(s2)) && fmpz_sgn(fmpq_numref(s2)) <= 0); if (!gamma_singular) arb_gamma_fmpq(Ga, s2, gamma_cached_prec); for (n = 1; ; n += 1) { #if VERBOSE printf("-----------------------------------------------------------\n"); flint_printf("n = %wd (s+parity)/2 = %f z = %f q = %wu\n", n, fmpq_get_d(s2), 3.1415926535897932 * n * n / q, q); #endif acb_dirichlet_afe_tail_bound(err, s2, n, q, parity); #if VERBOSE printf(" abs_tol = "); mag_printd(abs_tol, 5); printf("\n"); printf(" truncation error = "); mag_printd(err, 5); printf("\n"); #endif if (mag_cmp(err, abs_tol) < 0) { if (G == NULL || dirichlet_char_is_real(G, chi)) arb_add_error_mag(acb_realref(res), err); else acb_add_error_mag(res, err); break; } /* Compute local precision and tolerances. */ abs_tol_mag = mag_get_d_log2_approx(abs_tol); aa = fmpq_get_d(s2); zz = 3.1415926535897932385 * n * n / q; /* Gamma((s+parity)/2, z) (want lower bound, to estimate cancellation) */ gammainc_mag = log_gamma_upper_approx(aa, zz) / log(2); /* n^-s */ ns_mag = -fmpq_get_d(s) * log(n) / log(2); /* Want Gamma(a,z) n^-s with abs_tol --> want Gamma(a,z) with abs_tol * n^s */ mag_set_ui_2exp_si(abs_tol_gamma, 1, abs_tol_mag - ns_mag); /* wp = Precision needed sans cancellation. */ wp = gammainc_mag + ns_mag - abs_tol_mag + 5; wp = FLINT_MAX(wp, 30); /* wp2 = Precision needed with cancellation. */ if (gamma_singular) { /* Max term is roughly n^(-s) * z^((s+parity)/2) * exp(z) */ wp2 = -abs_tol_mag + ns_mag + aa * log(zz) + zz / log(2) + 5; wp2 = FLINT_MAX(wp2, 30); } else { /* Estimate of Gamma((s+parity)/2) */ gamma_mag = ARF_EXP(arb_midref(Ga)); wp2 = FLINT_MAX(gamma_mag, gammainc_mag) + ns_mag - abs_tol_mag + 5; wp2 = FLINT_MAX(wp2, 30); } #if VERBOSE printf(" abs_tol_gamma = "); mag_printd(abs_tol_gamma, 5); printf("\n"); printf(" gamma(a) = "); arb_printd(Ga, 10); printf("\n"); printf(" wp = %ld wp2 = %ld\n", wp, wp2); #endif if (G == NULL) acb_one(c); else acb_dirichlet_chi(c, G, chi, n, wp); if (acb_is_zero(c)) continue; arb_const_pi(z, wp2); arb_mul_ui(z, z, n, wp2); arb_mul_ui(z, z, n, wp2); arb_div_ui(z, z, q, wp2); start_bits = 32; arb_extract_bits(z0, z, start_bits); /* Can we use the asymptotic series? */ NN = _arb_hypgeom_gamma_upper_fmpq_inf_choose_N(AE, s2, z0, abs_tol_gamma); #if VERBOSE t1 = clock(); #endif /* For each new point, evaluate from scratch or use continuation? The former seems to be faster. */ if (1) { if (NN != -1) { /* OK to use the asymptotic series. */ _arb_hypgeom_gamma_upper_fmpq_inf_bsplit(Gz0, s2, z0, NN, wp); arb_add_error_mag(Gz0, AE); #if VERBOSE flint_printf(" asymptotic series with N = %wd: ", NN); arb_printd(Gz0, 10); printf("\n"); #endif } else { /* Otherwise fallback to the series at 0. */ if (gamma_singular) { slong nn; nn = *fmpq_numref(s2); if (COEFF_IS_MPZ(nn)) { arb_indeterminate(Gz0); } else { nn = -nn; NN = _arb_hypgeom_gamma_upper_singular_si_choose_N(AE, nn, z0, abs_tol_gamma); _arb_hypgeom_gamma_upper_singular_si_bsplit(Gz0, nn, z0, NN, wp2); arb_add_error_mag(Gz0, AE); #if VERBOSE flint_printf(" singular series with N = %wd, z0 = ", NN); arb_printd(z0, 10); printf(" "); mag_printd(AE, 10); printf("\n"); #endif } } else { NN = _arb_hypgeom_gamma_lower_fmpq_0_choose_N(AE, s2, z0, abs_tol_gamma); _arb_hypgeom_gamma_lower_fmpq_0_bsplit(Gz0, s2, z0, NN, wp2); arb_add_error_mag(Gz0, AE); #if VERBOSE flint_printf(" lower series with N = %wd, z0 = ", NN); arb_printd(z0, 10); printf(" "); mag_printd(AE, 10); printf("\n"); #endif while (mag_cmp(arb_radref(Ga), abs_tol_gamma) > 0) { gamma_cached_prec *= 2; arb_gamma_fmpq(Ga, s2, gamma_cached_prec); } #if VERBOSE flint_printf(" lower series with N = %wd: ", NN); arb_printd(Gz0, 10); printf("\n"); #endif arb_sub(Gz0, Ga, Gz0, wp); #if VERBOSE flint_printf(" G(a) - lower series: "); arb_printd(Gz0, 10); printf("\n"); #endif } } } else { _arb_gamma_upper_fmpq_step_bsplit(Gz0, s2, z0_prevn, z0, Gz0_prevn, expmz0_prevn, abs_tol_gamma, wp); } #if VERBOSE printf(" Gz0 = "); arb_printd(Gz0, 10); printf("\n"); #endif if (n == 1) { arb_neg(expmz0, z0); arb_exp(expmz0, expmz0, wp); } else { arb_sub(t, z0_prevn, z0, wp); arb_exp(t, t, wp); arb_mul(expmz0, expmz0_prevn, t, wp); } arb_set(z0_prevn, z0); arb_set(expmz0_prevn, expmz0); arb_set(Gz0_prevn, Gz0); #if VERBOSE t2 = clock(); #endif /* Bit-burst steps */ for (bits = start_bits * 2; bits < wp / 8; bits *= 2) { arb_extract_bits(z1, z, bits); _arb_gamma_upper_fmpq_step_bsplit(Gz1, s2, z0, z1, Gz0, expmz0, abs_tol_gamma, wp); arb_sub(t, z0, z1, wp); arb_exp(t, t, wp); arb_mul(expmz0, expmz0, t, wp); arb_set(Gz0, Gz1); arb_set(z0, z1); } /* Final step, including error bound */ _arb_gamma_upper_fmpq_step_bsplit(Gz1, s2, z0, z, Gz0, expmz0, abs_tol_gamma, wp); arb_set(Gz0, Gz1); #if VERBOSE printf(" Gz0 = "); arb_printd(Gz0, 10); printf(" tol "); mag_printd(abs_tol_gamma, 5); printf("\n"); #endif /* Multiply by prefactor n^-s */ arb_set_ui(ns, n); arb_pow_fmpq(ns, ns, s, wp); arb_div(Gz0, Gz0, ns, wp); #if VERBOSE printf(" 1/n^s = "); arb_printn(ns, 5, ARB_STR_NO_RADIUS); printf("\n"); printf(" Gz0 * pre = "); arb_printd(Gz0, 10); printf(" tol "); mag_printd(abs_tol, 5); printf("\n"); #endif acb_addmul_arb(res, c, Gz0, prec); #if VERBOSE printf(" sum = "); acb_printd(res, 10); printf("\n"); t3 = clock(); printf(" time: %f, %f\n", (t2 - t1) / CLOCKS_PER_SEC, (t3 - t2) / CLOCKS_PER_SEC); #endif } mag_clear(AE); mag_clear(err); mag_clear(abs_tol_gamma); arb_clear(ns); arb_clear(t); arb_clear(u); arb_clear(v); arb_clear(z); arb_clear(z0); arb_clear(z1); arb_clear(x); arb_clear(x2); arb_clear(Ga); arb_clear(Gz0); arb_clear(Gz1); arb_clear(expmz0); arb_clear(z0_prevn); arb_clear(Gz0_prevn); arb_clear(expmz0_prevn); acb_clear(c); fmpq_clear(s2); } #define PI 3.1415926535897932385 #define INV_LOG2 1.4426950408889634074; /* max(pi/q,s/2)**(s/2-1) * exp(-max(pi/q,s/2)) static double estimate_sum1_mag(double s, double q) { return ((0.5 * s - 1) * log(FLINT_MAX(PI / q, 0.5 * s)) - FLINT_MAX(PI / q, 0.5 * s)) * INV_LOG2; } */ void acb_dirichlet_l_fmpq_afe(acb_t res, const fmpq_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { arb_t t; acb_t S1, S2, w; fmpq_t s2; mag_t tol1, tol2; double ds, m1, m2, m2pre; slong origprec, prec1, prec2; ulong q; int parity; /* Todo: implement decomposition for imprimitive characters. */ if (G != NULL && !dirichlet_char_is_primitive(G, chi)) { acb_indeterminate(res); return; } q = (G == NULL) ? 1 : G->q; parity = (G == NULL) ? 0 : dirichlet_parity_char(G, chi); /* Division by gamma((s+parity)/2) at a pole. */ if (fmpz_is_one(fmpq_denref(s))) { const fmpz * n = fmpq_numref(s); if ((parity == 0 && fmpz_sgn(n) <= 0 && fmpz_is_even(n)) || (parity == 1 && fmpz_sgn(n) < 0 && fmpz_is_odd(n))) { /* Special case for zeta */ if (q == 1 && fmpz_is_zero(n)) acb_set_d(res, -0.5); else acb_zero(res); return; } } origprec = prec; prec = prec * 1.001 + 2 * FLINT_BIT_COUNT(q); acb_init(S1); acb_init(S2); acb_init(w); arb_init(t); fmpq_init(s2); mag_init(tol1); mag_init(tol2); ds = fmpq_get_d(s); m1 = log_gamma_upper_approx(0.5 * (ds + parity), PI / q) * INV_LOG2; m2 = log_gamma_upper_approx(0.5 * (1.0 - ds + parity), PI / q) * INV_LOG2; m2pre = (ds - 0.5) * log(PI / q) * INV_LOG2; mag_one(tol1); mag_mul_2exp_si(tol1, tol1, FLINT_MAX(m1, m2 + m2pre) - prec); mag_mul_2exp_si(tol2, tol1, -m2pre); prec1 = prec - (FLINT_MAX(m1, m2 + m2pre) - m1); prec1 = FLINT_MAX(prec1, 32); prec2 = prec - (FLINT_MAX(m1, m2 + m2pre) - (m2 + m2pre)); prec2 = FLINT_MAX(prec2, 32); #if VERBOSE printf("mag1 = %ld mag2 = %ld mag2 + pre = %ld prec, prec1, prec2 = %ld, %ld, %ld\n", (slong) m1, (slong) m2, (slong) (m2 + m2pre), prec, prec1, prec2); printf("tol1 = %ld tol2 = %ld\n", MAG_EXP(tol1), MAG_EXP(tol2)); #endif acb_dirichlet_fmpq_sum_afe(S1, s, G, chi, tol1, prec1); #if VERBOSE printf("=====================================================\n"); printf("S1 = "); acb_printd(S1, 20); printf(" estimate = "); printf(" %g\n", ldexp(1.0, m1)); printf("=====================================================\n"); #endif if (q == 1 && fmpz_is_one(fmpq_numref(s)) && fmpz_equal_ui(fmpq_denref(s), 2)) { acb_mul_2exp_si(res, S1, 1); } else { /* rootnum (pi/q)^(s-1/2) sum(1-s) */ if (fmpz_is_one(fmpq_numref(s)) && fmpz_equal_ui(fmpq_denref(s), 2)) { acb_conj(S2, S1); } else { fmpq_sub_ui(s2, s, 1); fmpq_neg(s2, s2); acb_dirichlet_fmpq_sum_afe(S2, s2, G, chi, tol2, prec2); acb_conj(S2, S2); } #if VERBOSE printf("=====================================================\n"); printf("S1 = "); acb_printd(S1, 20); printf(" estimate = "); printf(" %g\n", ldexp(1.0, m1)); printf("S2 = "); acb_printd(S2, 20); printf(" estimate = "); printf(" %g\n", ldexp(1.0, m2)); printf("=====================================================\n"); #endif arb_const_pi(t, prec); arb_div_ui(t, t, q, prec); fmpq_set_si(s2, 1, 2); fmpq_sub(s2, s, s2); arb_pow_fmpq(t, t, s2, prec); acb_mul_arb(S2, S2, t, prec); if (q != 1) { acb_dirichlet_root_number2(w, G, chi, prec); acb_mul(S2, S2, w, prec); } #if VERBOSE printf("S2 * prefactor = "); acb_printd(S2, 20); printf(" estimate = "); printf(" %g\n", ldexp(1.0, m2 + m2pre)); #endif acb_add(res, S1, S2, prec); } /* add pi^(s/2) / (s (s-1)) */ if (q == 1) { arb_const_pi(t, prec); fmpq_div_2exp(s2, s, 1); arb_pow_fmpq(t, t, s2, prec); fmpq_sub_ui(s2, s, 1); fmpq_mul(s2, s2, s); arb_div_fmpz(t, t, fmpq_numref(s2), prec); arb_mul_fmpz(t, t, fmpq_denref(s2), prec); acb_add_arb(res, res, t, prec); } /* divide by gamma((s+parity)/2) */ fmpq_add_ui(s2, s, parity); fmpq_div_2exp(s2, s2, 1); arb_gamma_fmpq(t, s2, prec); acb_div_arb(res, res, t, prec); acb_set_round(res, res, origprec); acb_clear(S1); acb_clear(S2); acb_clear(w); arb_clear(t); fmpq_clear(s2); mag_clear(tol1); mag_clear(tol2); } arb-2.22.1/acb_dirichlet/l_hurwitz.c000066400000000000000000000042241417376376500173360ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, const acb_dirichlet_hurwitz_precomp_t precomp, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { ulong order, chin, mult; acb_t t, u, a, w; dirichlet_char_t cn; acb_dirichlet_roots_t roots; int deflate; /* remove pole in Hurwitz zeta at s = 1 */ deflate = 0; if (acb_is_one(s)) { if (dirichlet_char_is_principal(G, chi)) { acb_indeterminate(res); return; } deflate = 1; } dirichlet_char_init(cn, G); acb_init(t); acb_init(u); acb_init(a); acb_init(w); dirichlet_char_one(cn, G); acb_zero(t); prec += n_clog(G->phi_q, 2); order = dirichlet_order_char(G, chi); mult = G->expo / order; acb_dirichlet_roots_init(roots, order, dirichlet_group_size(G), prec); do { chin = dirichlet_pairing_char(G, chi, cn) / mult; if (precomp == NULL) { acb_set_ui(a, cn->n); acb_div_ui(a, a, G->q, prec); if (deflate == 0) acb_hurwitz_zeta(u, s, a, prec); else _acb_poly_zeta_cpx_series(u, s, a, 1, 1, prec); } else { acb_dirichlet_hurwitz_precomp_eval(u, precomp, cn->n, G->q, prec); } acb_dirichlet_root(w, roots, chin, prec); acb_addmul(t, u, w, prec); } while (dirichlet_char_next(cn, G) >= 0); acb_set_ui(u, G->q); acb_neg(a, s); acb_pow(u, u, a, prec); acb_mul(res, t, u, prec); dirichlet_char_clear(cn); acb_dirichlet_roots_clear(roots); acb_clear(t); acb_clear(u); acb_clear(a); acb_clear(w); } arb-2.22.1/acb_dirichlet/l_jet.c000066400000000000000000000067421417376376500164130ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" /* todo: move implemetation to the acb_dirichlet module */ void _acb_poly_zeta_cpx_reflect(acb_ptr t, const acb_t h, const acb_t a, int deflate, slong len, slong prec); void acb_dirichlet_l_jet(acb_ptr res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec) { ulong order, chin, mult, phi; acb_t a, w; acb_ptr t, u; dirichlet_char_t cn; acb_dirichlet_roots_t roots; int deflate_hurwitz; if (len <= 0) return; /* special-case Riemann zeta */ if (G == NULL || G->q == 1) { if (len == 1 && !deflate) acb_dirichlet_zeta(res, s, prec); else acb_dirichlet_zeta_jet(res, s, deflate, len, prec); return; } if (len == 1 && !(deflate && dirichlet_char_is_principal(G, chi))) { acb_dirichlet_l(res, s, G, chi, prec); return; } if (dirichlet_char_is_principal(G, chi)) deflate_hurwitz = deflate; else deflate_hurwitz = acb_is_one(s); dirichlet_char_init(cn, G); t = _acb_vec_init(len); u = _acb_vec_init(len + 2); acb_init(a); acb_init(w); dirichlet_char_one(cn, G); prec += n_clog(G->phi_q, 2); order = dirichlet_order_char(G, chi); mult = G->expo / order; acb_dirichlet_roots_init(roots, order, dirichlet_group_size(G), prec); phi = 0; do { chin = dirichlet_pairing_char(G, chi, cn) / mult; acb_set_ui(a, cn->n); acb_div_ui(a, a, G->q, prec); _acb_poly_zeta_cpx_series(u, s, a, deflate_hurwitz, len, prec); acb_dirichlet_root(w, roots, chin, prec); _acb_vec_scalar_addmul(t, u, len, w, prec); phi++; } while (dirichlet_char_next(cn, G) >= 0); if (dirichlet_char_is_principal(G, chi) && deflate) { /* res = t * q^(-(s+x)) + [phi(q) * (q^(-(s+x)) - q^-1) / ((s+x)-1)] */ if (acb_is_one(s)) { acb_set_ui(a, G->q); _acb_poly_acb_invpow_cpx(u, a, s, len + 1, prec); _acb_poly_mullow(res, t, len, u, len, len, prec); acb_set_ui(u, phi); _acb_vec_scalar_addmul(res, u + 1, len, u, prec); } else { acb_sub_ui(u, s, 1, prec); acb_one(u + 1); acb_set_ui(a, G->q); _acb_poly_acb_invpow_cpx(u + 2, a, s, len, prec); _acb_poly_mullow(res, t, len, u + 2, len, len, prec); acb_inv(a, a, prec); acb_sub(u + 2, u + 2, a, prec); _acb_poly_div_series(t, u + 2, len, u, 2, len, prec); acb_set_ui(u, phi); _acb_vec_scalar_addmul(res, t, len, u, prec); } } else { /* res = t * q^(-(s+x)) */ acb_set_ui(a, G->q); _acb_poly_acb_invpow_cpx(u, a, s, len, prec); _acb_poly_mullow(res, t, len, u, len, len, prec); } dirichlet_char_clear(cn); acb_dirichlet_roots_clear(roots); _acb_vec_clear(t, len); _acb_vec_clear(u, len + 2); acb_clear(a); acb_clear(w); } arb-2.22.1/acb_dirichlet/l_series.c000066400000000000000000000034541417376376500171200ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void _acb_dirichlet_l_series(acb_ptr res, acb_srcptr s, slong slen, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec) { slen = FLINT_MIN(slen, len); if (len == 0) return; if (slen == 1 && !deflate) { acb_dirichlet_l(res, s, G, chi, prec); _acb_vec_zero(res + 1, len - 1); } else { acb_ptr t, u; t = _acb_vec_init(len); u = _acb_vec_init(slen); acb_dirichlet_l_jet(t, s, G, chi, deflate, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, s + 1, slen - 1); _acb_poly_compose_series(res, t, len, u, slen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, slen); } } void acb_dirichlet_l_series(acb_poly_t res, const acb_poly_t s, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec) { if (len == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, len); if (s->length == 0) { acb_t t; acb_init(t); _acb_dirichlet_l_series(res->coeffs, t, 1, G, chi, deflate, len, prec); acb_clear(t); } else { _acb_dirichlet_l_series(res->coeffs, s->coeffs, s->length, G, chi, deflate, len, prec); } _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_dirichlet/l_vec_hurwitz.c000066400000000000000000000035321417376376500201740ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_l_vec_hurwitz(acb_ptr res, const acb_t s, const acb_dirichlet_hurwitz_precomp_t precomp, const dirichlet_group_t G, slong prec) { acb_t a, qs; acb_ptr zeta, z; dirichlet_char_t cn; int deflate; /* remove pole in Hurwitz zeta at s = 1 */ deflate = acb_is_one(s); dirichlet_char_init(cn, G); acb_init(qs); acb_init(a); prec += n_clog(G->phi_q, 2); acb_set_ui(qs, G->q); acb_neg(a, s); acb_pow(qs, qs, a, prec); zeta = z = _acb_vec_init(G->phi_q); dirichlet_char_one(cn, G); do { if (precomp == NULL) { acb_set_ui(a, cn->n); acb_div_ui(a, a, G->q, prec); if (deflate == 0) acb_hurwitz_zeta(z, s, a, prec); else _acb_poly_zeta_cpx_series(z, s, a, 1, 1, prec); } else { acb_dirichlet_hurwitz_precomp_eval(z, precomp, cn->n, G->q, prec); } acb_mul(z, z, qs, prec); acb_conj(z, z); z++; } while (dirichlet_char_next(cn, G) >= 0); acb_dirichlet_dft_index(res, zeta, G, prec); { slong k; for (k = 0; k < G->phi_q; k++) acb_conj(res + k, res + k); } /* restore pole for the principal character */ if (deflate) acb_indeterminate(res); dirichlet_char_clear(cn); _acb_vec_clear(zeta, G->phi_q); acb_clear(qs); acb_clear(a); } arb-2.22.1/acb_dirichlet/pairing.c000066400000000000000000000014611417376376500167400ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_pairing(acb_t res, const dirichlet_group_t G, ulong m, ulong n, slong prec) { ulong expo; expo = dirichlet_pairing(G, m, n); if (expo == DIRICHLET_CHI_NULL) acb_zero(res); else { fmpq_t t; fmpq_init(t); fmpq_set_si(t, 2 * expo, G->expo); arb_sin_cos_pi_fmpq(acb_imagref(res), acb_realref(res), t, prec); fmpq_clear(t); } } arb-2.22.1/acb_dirichlet/pairing_conrey.c000066400000000000000000000015351417376376500203210ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_pairing_char(acb_t res, const dirichlet_group_t G, const dirichlet_char_t a, const dirichlet_char_t b, slong prec) { ulong expo; expo = dirichlet_pairing_char(G, a, b); if (expo == DIRICHLET_CHI_NULL) acb_zero(res); else { fmpq_t t; fmpq_init(t); fmpq_set_si(t, 2 * expo, G->expo); arb_sin_cos_pi_fmpq(acb_imagref(res), acb_realref(res), t, prec); fmpq_clear(t); } } arb-2.22.1/acb_dirichlet/platt_beta.c000066400000000000000000000014621417376376500174270ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _arb_inv_ui(arb_t res, ulong n, slong prec) { arb_set_ui(res, n); arb_inv(res, res, prec); } void acb_dirichlet_platt_beta(arb_t res, const arb_t t, slong prec) { arb_t u, v; arb_init(u); arb_init(v); arb_log(u, t, prec); arb_log(v, u, prec); arb_div(u, v, u, prec); _arb_inv_ui(res, 6, prec); arb_add(res, res, u, prec); arb_clear(u); arb_clear(v); } arb-2.22.1/acb_dirichlet/platt_c_bound.c000066400000000000000000000136511417376376500201300ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_hypgeom.h" static void _arb_pow_si(arb_t res, const arb_t x, slong y, slong prec) { arb_t a; arb_init(a); arb_set_si(a, y); arb_pow(res, x, a, prec); arb_clear(a); } static void _arb_add_d(arb_t res, const arb_t x, double y, slong prec) { arb_t a; arb_init(a); arb_set_d(a, y); arb_add(res, x, a, prec); arb_clear(a); } static void _arb_sub_d(arb_t res, const arb_t x, double y, slong prec) { _arb_add_d(res, x, -y, prec); } /* res = 2^((6*k+5-sigma)/4) * pi^k * (sigma + 1/2)^k * h */ static void _pre_c_Xa(arb_t res, slong sigma, const arb_t h, ulong k, slong prec) { arb_t pi, two, x1, x2; arb_init(pi); arb_init(two); arb_init(x1); arb_init(x2); arb_const_pi(pi, prec); arb_set_si(two, 2); arb_set_si(x1, (6*k + 5 - sigma)); arb_mul_2exp_si(x1, x1, -2); arb_pow(x1, two, x1, prec); arb_set_si(x2, sigma); _arb_add_d(x2, x2, 0.5, prec); arb_mul(x2, x2, pi, prec); arb_pow_ui(x2, x2, k, prec); arb_mul(res, x1, x2, prec); arb_mul(res, res, h, prec); arb_clear(pi); arb_clear(two); arb_clear(x1); arb_clear(x2); } /* res = 2^((6*k+7-sigma)/4) * pi^(k - 1/2) */ static void _pre_c_Xb(arb_t res, slong sigma, ulong k, slong prec) { arb_t pi, two, x1, x2; arb_init(pi); arb_init(two); arb_init(x1); arb_init(x2); arb_const_pi(pi, prec); arb_set_si(two, 2); arb_set_si(x1, (6*k + 7 - sigma)); arb_mul_2exp_si(x1, x1, -2); arb_pow(x1, two, x1, prec); arb_set_ui(x2, k); _arb_sub_d(x2, x2, 0.5, prec); arb_pow(x2, pi, x2, prec); arb_mul(res, x1, x2, prec); arb_clear(pi); arb_clear(two); arb_clear(x1); arb_clear(x2); } /* * res[(sigma-1)/2 - l] = binom((sigma-1)/2, l) * 2^((k+l-1)/2) * * h^(k+l+1) * gamma((k+l+1)/2, (sigma+1/2)^2 / 2*h^2) */ static void _pre_c_p(arb_ptr res, slong sigma, const arb_t h, ulong k, slong prec) { slong l; slong len = (sigma - 1)/2 + 1; arb_t two, f, f1, f2, u, base, x; arb_init(two); arb_init(f); arb_init(f1); arb_init(f2); arb_init(u); arb_init(base); arb_init(x); /* precompute 2^((k-1)/2) * h^(k+1) */ arb_set_ui(two, 2); arb_set_si(f1, k-1); arb_mul_2exp_si(f1, f1, -1); arb_pow(f1, two, f1, prec); _arb_pow_si(f2, h, k+1, prec); arb_mul(f, f1, f2, prec); /* precompute (sigma + 1/2)^2 / 2*h^2 */ arb_set_si(u, sigma); _arb_add_d(u, u, 0.5, prec); arb_div(u, u, h, prec); arb_sqr(u, u, prec); arb_mul_2exp_si(u, u, -1); /* precompute powers of sqrt(2)*h */ arb_sqrt_ui(base, 2, prec); arb_mul(base, base, h, prec); _arb_vec_set_powers(res, base, len, prec); for (l = 0; l < len; l++) { arb_mul(res + l, res + l, f, prec); arb_bin_uiui(x, (sigma - 1)/2, l, prec); arb_mul(res + l, res + l, x, prec); arb_set_si(x, k + l + 1); arb_mul_2exp_si(x, x, -1); arb_hypgeom_gamma_upper(x, x, u, 0, prec); arb_mul(res + l, res + l, x, prec); } _arb_poly_reverse(res, res, len, len); arb_clear(two); arb_clear(f); arb_clear(f1); arb_clear(f2); arb_clear(u); arb_clear(base); arb_clear(x); } void acb_dirichlet_platt_c_precomp_init(acb_dirichlet_platt_c_precomp_t pre, slong sigma, const arb_t h, ulong k, slong prec) { if (!arb_is_positive(h)) { flint_printf("requires positive h\n"); flint_abort(); } else if (sigma % 2 == 0 || sigma < 3) { flint_printf("requires odd integer sigma >= 3 (sigma=%wd)\n", sigma); flint_abort(); } else { pre->len = (sigma - 1) / 2 + 1; arb_init(&pre->Xa); arb_init(&pre->Xb); pre->p = _arb_vec_init(pre->len); _pre_c_Xa(&pre->Xa, sigma, h, k, prec); _pre_c_Xb(&pre->Xb, sigma, k, prec); _pre_c_p(pre->p, sigma, h, k, prec); } } void acb_dirichlet_platt_c_precomp_clear(acb_dirichlet_platt_c_precomp_t pre) { arb_clear(&pre->Xa); arb_clear(&pre->Xb); _arb_vec_clear(pre->p, pre->len); } void acb_dirichlet_platt_c_bound_precomp(arb_t res, const acb_dirichlet_platt_c_precomp_t pre, slong sigma, const arb_t t0, const arb_t h, slong k, slong prec) { /* requires sigma + 1/2 <= t0 */ arb_t lhs; arb_init(lhs); arb_set_si(lhs, sigma); _arb_add_d(lhs, lhs, 0.5, prec); if (!arb_le(lhs, t0)) { arb_zero_pm_inf(res); } else { arb_t u, v; arb_init(u); arb_init(v); /* u = exp((1 + sqrt(8))/(6*t0)) */ arb_sqrt_ui(u, 8, prec); arb_add_ui(u, u, 1, prec); arb_div_ui(u, u, 6, prec); arb_div(u, u, t0, prec); arb_exp(u, u, prec); /* v = (sigma + 1/2 + t0)^((sigma - 1)/2) */ arb_add_si(v, t0, sigma, prec); _arb_add_d(v, v, 0.5, prec); _arb_pow_si(v, v, (sigma - 1)/2, prec); /* res = u*(v*Xa + Xb*X(t0)) */ _arb_poly_evaluate(res, pre->p, pre->len, t0, prec); arb_mul(res, res, &pre->Xb, prec); arb_addmul(res, v, &pre->Xa, prec); arb_mul(res, res, u, prec); arb_clear(u); arb_clear(v); } arb_clear(lhs); } void acb_dirichlet_platt_c_bound(arb_t res, slong sigma, const arb_t t0, const arb_t h, slong k, slong prec) { acb_dirichlet_platt_c_precomp_t pre; acb_dirichlet_platt_c_precomp_init(pre, sigma, h, k, prec); acb_dirichlet_platt_c_bound_precomp(res, pre, sigma, t0, h, k, prec); acb_dirichlet_platt_c_precomp_clear(pre); } arb-2.22.1/acb_dirichlet/platt_hardy_z_zeros.c000066400000000000000000000021041417376376500213700ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" slong acb_dirichlet_platt_hardy_z_zeros( arb_ptr res, const fmpz_t n, slong len, slong prec) { if (len <= 0 || fmpz_sizeinbase(n, 10) < 5) { return 0; } else if (fmpz_sgn(n) < 1) { flint_printf("Nonpositive indices of Hardy Z zeros are not supported.\n"); flint_abort(); } else { slong r, s; fmpz_t k; fmpz_init(k); fmpz_set(k, n); for (s = 0; s < len; s += r) { r = acb_dirichlet_platt_local_hardy_z_zeros(res + s, k, len - s, prec); if (!r) break; fmpz_add_si(k, k, r); } return s; } return 0; } arb-2.22.1/acb_dirichlet/platt_i_bound.c000066400000000000000000000076161417376376500201420ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_hypgeom.h" /* c1 = 4*zeta(sigma)/(2*sigma-1) * pi^((-3-2*sigma)/4) * exp(...) */ static void _pre_i_c1(arb_t res, slong A, const arb_t H, slong sigma, slong prec) { arb_t pi, x1, x2, x3, x4; arb_init(pi); arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_const_pi(pi, prec); /* x1 = 4*zeta(sigma) / (2*sigma - 1) */ arb_set_si(x1, sigma); arb_zeta(x1, x1, prec); arb_mul_2exp_si(x1, x1, 2); arb_div_si(x1, x1, 2*sigma - 1, prec); /* x2 = pi^((-3-2*sigma)/4) */ arb_inv(x2, pi, prec); arb_root_ui(x2, x2, 4, prec); arb_pow_ui(x2, x2, 3 + 2*sigma, prec); /* x3 = (2*sigma-1)^2 / (8*H^2) */ arb_set_si(x3, 2*sigma - 1); arb_div(x3, x3, H, prec); arb_sqr(x3, x3, prec); arb_mul_2exp_si(x3, x3, -3); /* x4 = pi*A*(2*sigma-1)/2 */ arb_mul_si(x4, pi, A*(2*sigma-1), prec); arb_mul_2exp_si(x4, x4, -1); /* res = x1*x2*exp(x3 - x4) */ arb_sub(res, x3, x4, prec); arb_exp(res, res, prec); arb_mul(res, res, x1, prec); arb_mul(res, res, x2, prec); arb_clear(pi); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); } /* c2 = 8*pi^(1/4) */ static void _pre_i_c2(arb_t res, slong prec) { arb_t pi; arb_init(pi); arb_const_pi(pi, prec); arb_root_ui(res, pi, 4, prec); arb_mul_2exp_si(res, res, 3); arb_clear(pi); } void acb_dirichlet_platt_i_precomp_init(acb_dirichlet_platt_i_precomp_t pre, slong A, const arb_t H, slong sigma, slong prec) { arb_init(&pre->c1); arb_init(&pre->c2); _pre_i_c1(&pre->c1, A, H, sigma, prec); _pre_i_c2(&pre->c2, prec); } void acb_dirichlet_platt_i_precomp_clear(acb_dirichlet_platt_i_precomp_t pre) { arb_clear(&pre->c1); arb_clear(&pre->c2); } void acb_dirichlet_platt_i_bound_precomp(arb_t res, const acb_dirichlet_platt_i_precomp_t pre_i, const acb_dirichlet_platt_c_precomp_t pre_c, const arb_t t0, slong A, const arb_t H, slong sigma, slong prec) { arb_t pi, cbound, x1, x2, x3, x4, x5; arb_init(pi); arb_init(cbound); arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_init(x5); arb_const_pi(pi, prec); /* x1 = (1 - 4*t0^2)/(8*H^2) */ arb_sqr(x1, t0, prec); arb_mul_2exp_si(x1, x1, 2); arb_sub_ui(x1, x1, 1, prec); arb_neg(x1, x1); arb_div(x1, x1, H, prec); arb_div(x1, x1, H, prec); arb_mul_2exp_si(x1, x1, -3); /* x2 = pi*A/2 */ arb_mul_si(x2, pi, A, prec); arb_mul_2exp_si(x2, x2, -1); /* x3 = exp(x1 - x2) */ arb_sub(x3, x1, x2, prec); arb_exp(x3, x3, prec); acb_dirichlet_platt_c_bound_precomp( cbound, pre_c, sigma, t0, H, 0, prec); /* res = c1*cbound + c2*x3 */ arb_mul(x4, &pre_i->c1, cbound, prec); arb_mul(x5, &pre_i->c2, x3, prec); arb_add(res, x4, x5, prec); arb_clear(pi); arb_clear(cbound); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); arb_clear(x5); } void acb_dirichlet_platt_i_bound(arb_t res, const arb_t t0, slong A, const arb_t H, slong sigma, slong prec) { acb_dirichlet_platt_c_precomp_t pre_c; acb_dirichlet_platt_i_precomp_t pre_i; acb_dirichlet_platt_c_precomp_init(pre_c, sigma, H, 0, prec); acb_dirichlet_platt_i_precomp_init(pre_i, A, H, sigma, prec); acb_dirichlet_platt_i_bound_precomp( res, pre_i, pre_c, t0, A, H, sigma, prec); acb_dirichlet_platt_c_precomp_clear(pre_c); acb_dirichlet_platt_i_precomp_clear(pre_i); } arb-2.22.1/acb_dirichlet/platt_lemma_32.c000066400000000000000000000023451417376376500201140ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* out = 2*pi^(5/4)*exp(1/(8*h^2) - (t0^2)/(2*h^2) - pi*x) */ void acb_dirichlet_platt_lemma_32(arb_t out, const arb_t h, const arb_t t0, const arb_t x, slong prec) { arb_t pi, one_fourth; arb_t x1, x2; arb_init(pi); arb_init(one_fourth); arb_init(x1); arb_init(x2); arb_const_pi(pi, prec); arb_set_d(one_fourth, 0.25); arb_set_d(x1, 1.25); arb_pow(x1, pi, x1, prec); arb_mul_2exp_si(x1, x1, 1); arb_sqr(x2, t0, prec); arb_sub(x2, x2, one_fourth, prec); arb_div(x2, x2, h, prec); arb_div(x2, x2, h, prec); arb_mul_2exp_si(x2, x2, -1); arb_mul(out, pi, x, prec); arb_add(out, out, x2, prec); arb_neg(out, out); arb_exp(out, out, prec); arb_mul(out, out, x1, prec); arb_clear(pi); arb_clear(one_fourth); arb_clear(x1); arb_clear(x2); } arb-2.22.1/acb_dirichlet/platt_lemma_A11.c000066400000000000000000000101121417376376500202010ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_hypgeom.h" static void _platt_lemma_A11_X(arb_t out, const arb_t t0, const arb_t h, slong B, const arb_t beta, slong prec) { arb_t x1, x2; arb_init(x1); arb_init(x2); arb_set_si(x1, B); arb_mul_2exp_si(x1, x1, -1); arb_add(x1, x1, t0, prec); arb_pow(x1, x1, beta, prec); arb_set_si(x2, B); arb_div(x2, x2, h, prec); arb_sqr(x2, x2, prec); arb_mul_2exp_si(x2, x2, -3); arb_neg(x2, x2); arb_exp(x2, x2, prec); arb_mul(out, x1, x2, prec); arb_clear(x1); arb_clear(x2); } static void _platt_lemma_A11_Y(arb_t out, const arb_t t0, const arb_t h, slong B, const arb_t beta, slong prec) { arb_t x1, x2, x3, x4, x5; arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_init(x5); arb_rsqrt_ui(x1, 2, prec); arb_pow(x2, t0, beta, prec); arb_one(x3); arb_mul_2exp_si(x3, x3, -1); arb_set_si(x4, B); arb_div(x4, x4, h, prec); arb_sqr(x4, x4, prec); arb_mul_2exp_si(x4, x4, -3); arb_hypgeom_gamma_upper(x5, x3, x4, 0, prec); arb_mul(out, x1, x2, prec); arb_mul(out, out, x5, prec); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); arb_clear(x5); } static void _platt_lemma_A11_Z(arb_t out, const arb_t t0, const arb_t h, const arb_t beta, slong prec) { arb_t two; arb_t x1, x2, x3, x4, x5; arb_init(two); arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_init(x5); arb_set_ui(two, 2); arb_sub_ui(x1, beta, 1, prec); arb_mul_2exp_si(x1, x1, -1); arb_pow(x1, two, x1, prec); arb_pow(x2, h, beta, prec); arb_add_ui(x3, beta, 1, prec); arb_mul_2exp_si(x3, x3, -1); arb_div(x4, t0, h, prec); arb_sqr(x4, x4, prec); arb_mul_2exp_si(x4, x4, -1); arb_hypgeom_gamma_upper(x5, x3, x4, 0, prec); arb_mul(out, x1, x2, prec); arb_mul(out, out, x5, prec); arb_clear(two); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); arb_clear(x5); } static int _platt_lemma_A11_constraint(const arb_t t0, const arb_t h, slong B, const arb_t beta, slong prec) { int result; arb_t a, b, expe; arb_init(a); arb_init(b); arb_init(expe); /* expe = exp(e) */ arb_const_e(expe, prec); arb_exp(expe, expe, prec); /* a = beta*h^2 / t0 */ arb_sqr(a, h, prec); arb_mul(a, a, beta, prec); arb_div(a, a, t0, prec); /* b = B/2 */ arb_set_si(b, B); arb_mul_2exp_si(b, b, -1); result = arb_le(a, b) && arb_le(b, t0) && arb_gt(t0, expe); arb_clear(a); arb_clear(b); arb_clear(expe); return result; } void acb_dirichlet_platt_lemma_A11(arb_t out, const arb_t t0, const arb_t h, slong B, slong prec) { arb_t beta; arb_init(beta); acb_dirichlet_platt_beta(beta, t0, prec); if (_platt_lemma_A11_constraint(t0, h, B, beta, prec)) { arb_t X, Y, Z; arb_t x1, x2; arb_init(X); arb_init(Y); arb_init(Z); arb_init(x1); arb_init(x2); _platt_lemma_A11_X(X, t0, h, B, beta, prec); _platt_lemma_A11_Y(Y, t0, h, B, beta, prec); _platt_lemma_A11_Z(Z, t0, h, beta, prec); arb_set_ui(x1, 2); arb_pow(x1, x1, beta, prec); arb_mul(x1, x1, h, prec); arb_div_si(x1, x1, B, prec); arb_add(x2, Y, Z, prec); arb_mul(x2, x2, x1, prec); arb_add(x2, x2, X, prec); arb_mul_ui(x2, x2, 6, prec); arb_set(out, x2); arb_clear(X); arb_clear(Y); arb_clear(Z); arb_clear(x1); arb_clear(x2); } else { arb_zero_pm_inf(out); } arb_clear(beta); } arb-2.22.1/acb_dirichlet/platt_lemma_A5.c000066400000000000000000000040631417376376500201340ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_hypgeom.h" /* Lemma A5 requires B > h*sqrt(k) */ static int _platt_lemma_A5_constraint(slong B, const arb_t h, slong k, slong prec) { int result; arb_t lhs, rhs; arb_init(rhs); arb_init(lhs); arb_set_si(lhs, B); arb_sqrt_ui(rhs, (ulong) k, prec); arb_mul(rhs, rhs, h, prec); result = arb_gt(lhs, rhs); arb_clear(rhs); arb_clear(lhs); return result; } void acb_dirichlet_platt_lemma_A5(arb_t out, slong B, const arb_t h, slong k, slong prec) { arb_t a, b; arb_t x1, x2, x3, x4, x5, x6; if (!_platt_lemma_A5_constraint(B, h, k, prec)) { arb_zero_pm_inf(out); return; } arb_init(a); arb_init(b); arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_init(x5); arb_init(x6); arb_const_pi(x1, prec); arb_mul_si(x1, x1, B, prec); arb_pow_ui(x1, x1, (ulong) k, prec); arb_mul_2exp_si(x1, x1, 3); arb_set_si(a, B); arb_div(a, a, h, prec); arb_sqr(a, a, prec); arb_mul_2exp_si(a, a, -3); arb_neg(x2, a); arb_exp(x2, x2, prec); arb_set_si(x3, 3*k - 1); arb_mul_2exp_si(x3, x3, -1); arb_set_ui(x4, 2); arb_pow(x4, x4, x3, prec); arb_set_si(b, k+1); arb_div_si(x5, h, B, prec); arb_pow_ui(x5, x5, (ulong) (k+1), prec); arb_mul_2exp_si(x6, b, -1); arb_hypgeom_gamma_upper(x6, x6, a, 0, prec); arb_mul(out, x4, x5, prec); arb_mul(out, out, x6, prec); arb_add(out, out, x2, prec); arb_mul(out, out, x1, prec); arb_clear(a); arb_clear(b); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); arb_clear(x5); arb_clear(x6); } arb-2.22.1/acb_dirichlet/platt_lemma_A7.c000066400000000000000000000075271417376376500201460ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _platt_lemma_A7_S(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong k, slong A, slong prec) { slong l; arb_t total, summand; arb_t pi, half; arb_t a; arb_t l_factorial, kd2, t02; arb_t x1, x2, x3, x4, x5; arb_init(total); arb_init(summand); arb_init(pi); arb_init(half); arb_init(a); arb_init(l_factorial); arb_init(kd2); arb_init(t02); arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_init(x5); arb_one(half); arb_mul_2exp_si(half, half, -1); arb_const_pi(pi, prec); arb_one(l_factorial); arb_set_si(kd2, k); arb_mul_2exp_si(kd2, kd2, -1); arb_sqr(t02, t0, prec); for (l=0; l<=(sigma-1)/2; l++) { if (l > 1) { arb_mul_si(l_factorial, l_factorial, l, prec); } arb_mul_si(a, pi, 4*l+1, prec); arb_mul_si(a, a, A, prec); arb_inv(x1, a, prec); arb_add_ui(x1, x1, 1, prec); arb_add_si(x2, half, 2*l, prec); arb_sqr(x2, x2, prec); arb_add(x2, x2, t02, prec); arb_pow(x2, x2, kd2, prec); arb_div(x2, x2, l_factorial, prec); arb_set_si(x3, 4*l + 1); arb_div(x3, x3, h, prec); arb_sqr(x3, x3, prec); arb_mul_2exp_si(x3, x3, -3); arb_mul_2exp_si(x4, a, -1); arb_sub(x5, x3, x4, prec); arb_exp(x5, x5, prec); arb_mul(summand, x1, x2, prec); arb_mul(summand, summand, x5, prec); arb_add(total, total, summand, prec); } arb_set(out, total); arb_clear(total); arb_clear(summand); arb_clear(pi); arb_clear(half); arb_clear(a); arb_clear(l_factorial); arb_clear(kd2); arb_clear(t02); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); arb_clear(x5); } void acb_dirichlet_platt_lemma_A7(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong k, slong A, slong prec) { arb_t S, C; arb_t pi, a; arb_t x1, x2; arb_t y1, y2, y3, y4; arb_t z1, z2; if (sigma % 2 == 0 || sigma < 3) { arb_zero_pm_inf(out); return; } arb_init(S); arb_init(C); arb_init(pi); arb_init(a); arb_init(x1); arb_init(x2); arb_init(y1); arb_init(y2); arb_init(y3); arb_init(y4); arb_init(z1); arb_init(z2); arb_const_pi(pi, prec); arb_pow_ui(x1, pi, (ulong) (k+1), prec); arb_mul_2exp_si(x1, x1, k+3); arb_div(x2, t0, h, prec); arb_sqr(x2, x2, prec); arb_mul_2exp_si(x2, x2, -1); arb_neg(x2, x2); arb_exp(x2, x2, prec); _platt_lemma_A7_S(S, sigma, t0, h, k, A, prec); arb_mul(z1, x1, x2, prec); arb_mul(z1, z1, S, prec); arb_mul_si(a, pi, 2*sigma-1, prec); arb_mul_si(a, a, A, prec); arb_inv(y1, a, prec); arb_add_ui(y1, y1, 1, prec); arb_set_si(y2, 2*sigma + 1); arb_div(y2, y2, h, prec); arb_sqr(y2, y2, prec); arb_mul_2exp_si(y2, y2, -3); arb_mul_2exp_si(y3, a, -1); arb_sub(y4, y2, y3, prec); arb_exp(y4, y4, prec); acb_dirichlet_platt_c_bound(C, sigma, t0, h, k, prec); arb_mul(z2, y1, y4, prec); arb_mul(z2, z2, C, prec); arb_mul_2exp_si(z2, z2, 1); arb_add(out, z1, z2, prec); arb_clear(S); arb_clear(C); arb_clear(pi); arb_clear(a); arb_clear(x1); arb_clear(x2); arb_clear(y1); arb_clear(y2); arb_clear(y3); arb_clear(y4); arb_clear(z1); arb_clear(z2); } arb-2.22.1/acb_dirichlet/platt_lemma_A9.c000066400000000000000000000063751417376376500201500ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _arb_pow_d(arb_t z, const arb_t x, double d, slong prec) { arb_t u; arb_init(u); arb_set_d(u, d); arb_pow(z, x, u, prec); arb_clear(u); } static void _platt_lemma_A9_a(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong A, slong prec) { arb_t a, pi, C; arb_t y1, y2, y3, y4; arb_t z1, z2, z3; arb_init(a); arb_init(pi); arb_init(C); arb_init(y1); arb_init(y2); arb_init(y3); arb_init(y4); arb_init(z1); arb_init(z2); arb_init(z3); arb_const_pi(pi, prec); arb_mul_si(a, pi, 2*sigma-1, prec); arb_mul_si(a, a, A, prec); arb_inv(y1, a, prec); arb_add_ui(y1, y1, 1, prec); arb_set_si(y2, 2*sigma - 1); arb_div(y2, y2, h, prec); arb_sqr(y2, y2, prec); arb_mul_2exp_si(y2, y2, -3); arb_mul_2exp_si(y3, a, -1); arb_sub(y4, y2, y3, prec); arb_exp(y4, y4, prec); acb_dirichlet_platt_c_bound(C, sigma, t0, h, 0, prec); arb_zeta_ui(z1, (ulong) sigma, prec); arb_mul_2exp_si(z1, z1, 1); arb_set_si(z2, 1-2*sigma); arb_mul_2exp_si(z2, z2, -2); arb_pow(z2, pi, z2, prec); arb_sub(z3, y2, y3, prec); arb_exp(z3, z3, prec); arb_mul(out, z1, z2, prec); arb_mul(out, out, z3, prec); arb_mul(out, out, C, prec); arb_mul(out, out, y1, prec); arb_clear(a); arb_clear(pi); arb_clear(C); arb_clear(y1); arb_clear(y2); arb_clear(y3); arb_clear(y4); arb_clear(z1); arb_clear(z2); arb_clear(z3); } static void _platt_lemma_A9_b(arb_t out, const arb_t t0, const arb_t h, slong A, slong prec) { arb_t pi; arb_t x1, x2, x3, x4, x5; arb_init(pi); arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_init(x5); arb_const_pi(pi, prec); _arb_pow_d(x1, pi, 1.25, prec); arb_mul_2exp_si(x1, x1, 2); arb_sqr(x2, t0, prec); arb_mul_2exp_si(x2, x2, 2); arb_sub_ui(x2, x2, 1, prec); arb_neg(x2, x2); arb_div(x2, x2, h, prec); arb_div(x2, x2, h, prec); arb_mul_2exp_si(x2, x2, -3); arb_mul_si(x3, pi, A, prec); arb_mul_2exp_si(x3, x3, -1); arb_mul_si(x4, pi, A, prec); arb_inv(x4, x4, prec); arb_add_ui(x4, x4, 1, prec); arb_sub(x5, x2, x3, prec); arb_exp(x5, x5, prec); arb_mul(out, x1, x4, prec); arb_mul(out, out, x5, prec); arb_clear(pi); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); arb_clear(x5); } void acb_dirichlet_platt_lemma_A9(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong A, slong prec) { arb_t a, b; if (sigma % 2 == 0 || sigma < 3) { arb_zero_pm_inf(out); return; } arb_init(a); arb_init(b); _platt_lemma_A9_a(a, sigma, t0, h, A, prec); _platt_lemma_A9_b(b, t0, h, A, prec); arb_add(out, a, b, prec); arb_clear(a); arb_clear(b); } arb-2.22.1/acb_dirichlet/platt_lemma_B1.c000066400000000000000000000030551417376376500201310ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _arb_ui_pow_arb(arb_t res, ulong n, const arb_t x, slong prec) { arb_t a; arb_init(a); arb_set_ui(a, n); arb_pow(res, a, x, prec); arb_clear(a); } void acb_dirichlet_platt_lemma_B1(arb_t out, slong sigma, const arb_t t0, const arb_t h, slong J, slong prec) { arb_t pi, C; arb_t x1, x2, x3; if (sigma % 2 == 0 || sigma < 3) { arb_zero_pm_inf(out); return; } arb_init(pi); arb_init(C); arb_init(x1); arb_init(x2); arb_init(x3); arb_const_pi(pi, prec); acb_dirichlet_platt_c_bound(C, sigma, t0, h, 0, prec); arb_set_si(x1, 2*sigma - 1); arb_div(x1, x1, h, prec); arb_sqr(x1, x1, prec); arb_mul_2exp_si(x1, x1, -3); arb_exp(x1, x1, prec); arb_set_si(x2, 1 - 2*sigma); arb_mul_2exp_si(x2, x2, -2); arb_pow(x2, pi, x2, prec); arb_set_si(x3, 1 - sigma); _arb_ui_pow_arb(x3, (ulong) J, x3, prec); arb_div_si(x3, x3, sigma - 1, prec); arb_mul(out, x1, x2, prec); arb_mul(out, out, x3, prec); arb_mul(out, out, C, prec); arb_clear(pi); arb_clear(C); arb_clear(x1); arb_clear(x2); arb_clear(x3); } arb-2.22.1/acb_dirichlet/platt_lemma_B2.c000066400000000000000000000026321417376376500201320ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_platt_lemma_B2(arb_t out, slong K, const arb_t h, const arb_t xi, slong prec) { arb_t two, half, pi; arb_t x1, x2, x3, x4, x5; arb_init(two); arb_init(half); arb_init(pi); arb_init(x1); arb_init(x2); arb_init(x3); arb_init(x4); arb_init(x5); arb_set_ui(two, 2); arb_mul_2exp_si(half, two, -2); arb_const_pi(pi, prec); arb_set_si(x1, K + 5); arb_mul_2exp_si(x1, x1, -1); arb_pow(x1, two, x1, prec); arb_add_si(x2, half, K, prec); arb_pow(x2, pi, x2, prec); arb_pow_ui(x3, h, (ulong) (K + 1), prec); arb_pow_ui(x4, xi, (ulong) K, prec); arb_set_si(x5, K + 2); arb_mul_2exp_si(x5, x5, -1); arb_rgamma(x5, x5, prec); arb_mul(out, x1, x2, prec); arb_mul(out, out, x3, prec); arb_mul(out, out, x4, prec); arb_mul(out, out, x5, prec); arb_clear(two); arb_clear(half); arb_clear(pi); arb_clear(x1); arb_clear(x2); arb_clear(x3); arb_clear(x4); arb_clear(x5); } arb-2.22.1/acb_dirichlet/platt_local_hardy_z_zeros.c000066400000000000000000001155631417376376500225600ustar00rootroot00000000000000/* Copyright (C) 2010 Juan Arias de Reyna Copyright (C) 2019 D.H.J. Polymath Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_calc.h" static const slong LOOPCOUNT = 4; /* * For a detailed explanation of the variant of Turing's method * implemented in this file, see: * * J. Arias de Reyna, "Programs for Riemann's zeta function", (J. A. J. van * Vonderen, Ed.) Leven met getallen : liber amicorum ter gelegenheid van de * pensionering van Herman te Riele, CWI (2012) 102-112, * https://ir.cwi.nl/pub/19724 */ /* * This structure describes the local context in which Platt's scaled Lambda * function f may be estimated by Gaussian-windowed Whittaker-Shannon * interpolation. */ typedef struct { /* grid location and shape */ fmpz T; /* midpoint */ slong A; /* resolution */ slong B; /* width */ /* interpolation tuning parameters */ slong Ns_max; /* max number of support points per side */ arb_struct H; /* standard deviation of Gaussian window */ slong sigma; arb_ptr p; /* f evaluated at N = A*B points on the grid */ acb_dirichlet_platt_ws_precomp_struct pre; /* precomp interpolation stuff */ } platt_ctx_struct; typedef platt_ctx_struct platt_ctx_t[1]; typedef platt_ctx_struct * platt_ctx_ptr; typedef const platt_ctx_struct * platt_ctx_srcptr; static void platt_ctx_init(platt_ctx_t ctx, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma_grid, slong Ns_max, const arb_t H, slong sigma_interp, slong prec) { fmpz_init(&ctx->T); arb_init(&ctx->H); ctx->p = _arb_vec_init(A*B); ctx->A = A; ctx->B = B; ctx->Ns_max = Ns_max; ctx->sigma = sigma_interp; fmpz_set(&ctx->T, T); arb_set(&ctx->H, H); acb_dirichlet_platt_ws_precomp_init(&ctx->pre, A, H, sigma_interp, prec); acb_dirichlet_platt_multieval(ctx->p, T, A, B, h, J, K, sigma_grid, prec); } static void platt_ctx_clear(platt_ctx_t ctx) { slong N = ctx->A * ctx->B; fmpz_clear(&ctx->T); arb_clear(&ctx->H); _arb_vec_clear(ctx->p, N); acb_dirichlet_platt_ws_precomp_clear(&ctx->pre); } static void platt_ctx_interpolate(arb_t res, arf_t deriv, const platt_ctx_t ctx, const arb_t t0, slong prec) { acb_dirichlet_platt_ws_interpolation_precomp(res, deriv, &ctx->pre, t0, ctx->p, &ctx->T, ctx->A, ctx->B, ctx->Ns_max, &ctx->H, ctx->sigma, prec); } static void platt_ctx_interpolate_arf(arb_t res, arf_t deriv, const platt_ctx_t ctx, const arf_t t0, slong prec) { arb_t t; arb_init(t); arb_set_arf(t, t0); platt_ctx_interpolate(res, deriv, ctx, t, prec); arb_clear(t); } /* * This structure describes a node of a doubly linked list. * Each node represents a height t at which Platt's scaled Lambda function * f(t) has been evaluated by interpolation on a grid. */ typedef struct _zz_node_struct { arf_struct t; /* height t where v = f(t) is evaluated */ arb_struct v; /* f(t) */ fmpz *gram; /* Gram point index or NULL if not a Gram point */ struct _zz_node_struct *prev; struct _zz_node_struct *next; } zz_node_struct; typedef zz_node_struct zz_node_t[1]; typedef zz_node_struct * zz_node_ptr; typedef const zz_node_struct * zz_node_srcptr; static int zz_node_is_gram_node(const zz_node_t p) { return p->gram != NULL; } static int zz_node_sgn(const zz_node_t p) { int s = arb_sgn_nonzero(&p->v); if (!s) { flint_printf("unexpectedly imprecise evaluation of f(t)\n"); flint_abort(); } return s; } /* Good Gram points are Gram points where sgn(f(g(n)))*(-1)^n > 0. */ static int zz_node_is_good_gram_node(const zz_node_t p) { if (zz_node_is_gram_node(p)) { int s = zz_node_sgn(p); if ((s > 0 && fmpz_is_even(p->gram)) || (s < 0 && fmpz_is_odd(p->gram))) { return 1; } } return 0; } static void zz_node_init(zz_node_t p) { arf_init(&p->t); arb_init(&p->v); arb_indeterminate(&p->v); p->gram = NULL; p->prev = NULL; p->next = NULL; } static void zz_node_clear(zz_node_t p) { arf_clear(&p->t); arb_clear(&p->v); if (p->gram) { fmpz_clear(p->gram); flint_free(p->gram); } p->gram = NULL; p->prev = NULL; p->next = NULL; } static void delete_list_to(zz_node_ptr head, zz_node_srcptr target) { zz_node_ptr u, v; if (head) { if (head->prev) { flint_printf("expected the first node in the list\n"); flint_abort(); } } u = head; while (u != target) { if (u == NULL) { flint_printf("failed to find target within list\n"); flint_abort(); } v = u; u = u->next; zz_node_clear(v); flint_free(v); } if (u != NULL) { u->prev = NULL; } } static void delete_list(zz_node_ptr head) { delete_list_to(head, NULL); } /* * Create a node representing an evaluation of the scaled Lambda function * at arbitrary point t. Upon creation the sign of f(t) will * be known with certainty. If this is not possible then NULL is returned. */ static zz_node_ptr create_non_gram_node(const arf_t t, const platt_ctx_t ctx, slong prec) { zz_node_ptr p = flint_malloc(sizeof(zz_node_struct)); zz_node_init(p); arf_set(&p->t, t); platt_ctx_interpolate_arf(&p->v, NULL, ctx, t, prec); if (arb_contains_zero(&p->v)) { zz_node_clear(p); p = NULL; } return p; } /* * Create a node representing an evaluation of the scaled Lambda function * at the nth Gram point g(n). Upon creation a floating point number t will be * assigned to this node, with the property that there are no zeros of the * scaled Lambda function between t and the actual value of g(n). * The sign of f(t) will also be known with certainty, otherwise NULL * is returned. */ static zz_node_ptr create_gram_node(const fmpz_t n, const platt_ctx_t ctx, slong prec) { zz_node_ptr p = NULL; arb_t t, v; acb_t z; arb_init(t); arb_init(v); acb_init(z); acb_dirichlet_gram_point(t, n, NULL, NULL, prec + fmpz_sizeinbase(n, 2)); acb_set_arb(z, t); platt_ctx_interpolate(v, NULL, ctx, t, prec); if (!arb_contains_zero(v)) { /* t contains g(n) and does not contain a zero of the f function */ p = flint_malloc(sizeof(zz_node_struct)); zz_node_init(p); p->gram = flint_malloc(sizeof(fmpz)); fmpz_init(p->gram); fmpz_set(p->gram, n); arf_set(&p->t, arb_midref(t)); arb_set(&p->v, v); } arb_clear(t); arb_clear(v); acb_clear(z); return p; } /* * Count the number of Gram intervals between the Gram point * represented by node a and the Gram point represented by node b. * Traversing the linked list is not necessary because the Gram indices * of nodes a and b can be accessed directly. */ static slong count_gram_intervals(zz_node_srcptr a, zz_node_srcptr b) { slong out = 0; if (!a || !b) { flint_printf("a and b must be non-NULL\n"); flint_abort(); } if (!zz_node_is_good_gram_node(a) || !zz_node_is_good_gram_node(b)) { flint_printf("both nodes must be good Gram points\n"); flint_abort(); } else { fmpz_t m; fmpz_init(m); fmpz_sub(m, b->gram, a->gram); out = fmpz_get_si(m); fmpz_clear(m); } return out; } /* * Count the observed number of sign changes of f(t) by traversing * a linked list of evaluated points from node a to node b. */ static slong count_sign_changes(zz_node_srcptr a, zz_node_srcptr b) { zz_node_srcptr p, q; slong n = 0; if (!a || !b) { flint_printf("a and b must be non-NULL\n"); flint_abort(); } p = a; q = a->next; while (p != b) { if (!q) { flint_printf("prematurely reached end of list\n"); flint_abort(); } if (zz_node_sgn(p) != zz_node_sgn(q)) { n++; } p = q; q = q->next; } return n; } /* * Modify a linked list that ends with node p, * by appending nodes representing Gram points. * Continue until a 'good' Gram point is found. * Returns nonzero on success. * Sets *out to the last point in the list. */ static int extend_to_next_good_gram_node( zz_node_ptr *out, zz_node_t p, const platt_ctx_t ctx, slong prec) { fmpz_t n; zz_node_ptr q, r; int result = 1; fmpz_init(n); if (!zz_node_is_gram_node(p)) { flint_printf("expected to begin at a gram point\n"); flint_abort(); } if (p->next) { flint_printf("expected to extend from the end of a list\n"); flint_abort(); } fmpz_set(n, p->gram); q = p; while (1) { fmpz_add_ui(n, n, 1); r = create_gram_node(n, ctx, prec); if (r) { q->next = r; r->prev = q; q = r; r = NULL; if (zz_node_is_good_gram_node(q)) { break; } } else { result = 0; break; } } fmpz_clear(n); *out = q; return result; } /* * Modify a linked list that begins with node p, * by prepending nodes representing Gram points. * Continue until a 'good' Gram point is found. * Returns nonzero on success. * Sets *out to the first point in the list. */ static int extend_to_prev_good_gram_node(zz_node_ptr *out, zz_node_t p, const platt_ctx_t ctx, slong prec) { fmpz_t n; zz_node_ptr q, r; int result = 1; fmpz_init(n); if (!zz_node_is_gram_node(p)) { flint_printf("expected to begin at a gram point\n"); flint_abort(); } if (p->prev) { flint_printf("expected to extend from the start of a list\n"); flint_abort(); } fmpz_set(n, p->gram); q = p; while (1) { fmpz_sub_ui(n, n, 1); r = create_gram_node(n, ctx, prec); if (r) { q->prev = r; r->next = q; q = r; r = NULL; if (zz_node_is_good_gram_node(q)) { break; } } else { result = 0; break; } } fmpz_clear(n); *out = q; return result; } static zz_node_ptr _scan_to_prev_good_gram_node(zz_node_ptr p) { zz_node_ptr u = p->prev; while (u) { if (zz_node_is_good_gram_node(u)) { return u; } u = u->prev; } return NULL; } static zz_node_ptr scan_to_prev_good_gram_node(zz_node_ptr p, slong count) { slong i; zz_node_ptr u = p; for (i = 0; i < count; i++) { if ((u = _scan_to_prev_good_gram_node(u)) == NULL) { return NULL; } } return u; } static zz_node_ptr _scan_to_next_good_gram_node(zz_node_ptr p) { zz_node_ptr u = p->next; while (u) { if (zz_node_is_good_gram_node(u)) { return u; } u = u->next; } return NULL; } static zz_node_ptr scan_to_next_good_gram_node(zz_node_ptr p, slong count) { slong i; zz_node_ptr u = p; for (i = 0; i < count; i++) { if ((u = _scan_to_next_good_gram_node(u)) == NULL) { return NULL; } } return u; } /* * res = (x1*w1 + x2*w2) / (w1 + w2) * Undefined if weights are not nonnegative. * If w1 and w2 are zero, the resulting interval contains x1 and x2. */ static void _weighted_arithmetic_mean(arb_t res, const arf_t x1, const arf_t x2, const arb_t w1, const arb_t w2, slong prec) { if (!arb_is_nonnegative(w1) || !arb_is_nonnegative(w2)) { arb_indeterminate(res); } else if (arb_is_zero(w1) && arb_is_zero(w2)) { arb_set_interval_arf(res, x1, x2, prec); } else if (arb_is_zero(w1)) { arb_set_arf(res, x2); } else if (arb_is_zero(w2)) { arb_set_arf(res, x1); } else if (arb_is_exact(w1) && arb_is_exact(w2)) { arb_t a, b; arb_init(a); arb_init(b); arb_mul_arf(a, w1, x1, prec); arb_addmul_arf(a, w2, x2, prec); arb_add(b, w1, w2, prec); arb_div(res, a, b, prec); arb_clear(a); arb_clear(b); } else { arb_t a, b, r1, r2; arb_init(a); arb_init(b); arb_init(r1); arb_init(r2); arb_zero(a); arb_zero(b); arb_get_lbound_arf(arb_midref(a), w1, prec); arb_get_ubound_arf(arb_midref(b), w2, prec); _weighted_arithmetic_mean(r1, x1, x2, a, b, prec); arb_zero(a); arb_zero(b); arb_get_ubound_arf(arb_midref(a), w1, prec); arb_get_lbound_arf(arb_midref(b), w2, prec); _weighted_arithmetic_mean(r2, x1, x2, a, b, prec); arb_union(res, r1, r2, prec); arb_clear(a); arb_clear(b); arb_clear(r1); arb_clear(r2); } } /* * Split the interval (t1, t2) into the intervals (t1, out) and (out, t2) * in an attempt to increase the number of observed sign changes of f(t) * between endpoints. * v1 and v2 are the scaled Lambda function values at t1 and t2 respectively. * sign1 and sign2 are the signs of v1 and v2 respectively. */ static void split_interval(arb_t out, const arf_t t1, const arb_t v1, slong sign1, const arf_t t2, const arb_t v2, slong sign2, slong prec) { if (sign1 == sign2) { /* * out = (sqrt(v2/v1)*t1 + t2) / (sqrt(v2/v1) + 1) * We have f(t1)=v1, f(t2)=v2 where v1 and v2 have the same sign, * and we want to guess t between t1 and t2 so that f(t) * has the opposite sign. Try the vertex of a parabola that would touch * f(t)=0 between t1 and t2 and would pass through (t1,v1) and (t2,v2). */ arb_t w1, w2; arb_init(w1); arb_init(w2); arb_abs(w1, v2); /* w1, v2 is deliberate */ arb_sqrt(w1, w1, prec); arb_abs(w2, v1); /* w2, v1 is deliberate */ arb_sqrt(w2, w2, prec); _weighted_arithmetic_mean(out, t1, t2, w1, w2, prec); arb_clear(w1); arb_clear(w2); } else { /* * out = (t1 + t2) / 2 * There is already one sign change in this interval. * To find additional sign changes we would need to evaluate * at least two more points in the interval, * so begin by just splitting the interval in half at the midpoint. */ arb_set_arf(out, t1); arb_add_arf(out, out, t2, prec); arb_mul_2exp_si(out, out, -1); } } /* * Add a new node between each pair of existing nodes in the linked list * of evaluated values of t, within the sublist demarcated by nodes a and b. * Returns nonzero on success. */ static int intercalate(const platt_ctx_t ctx, zz_node_t a, zz_node_t b, slong prec) { arb_t t; zz_node_ptr q, r, mid_node; int result = 1; if (a == NULL || b == NULL) { flint_printf("a and b must be non-NULL\n"); flint_abort(); } if (!zz_node_is_good_gram_node(a) || !zz_node_is_good_gram_node(b)) { flint_printf("a and b must represent good Gram points\n"); flint_abort(); } if (a == b) return result; arb_init(t); q = a; r = a->next; while (q != b) { if (!r) { flint_printf("prematurely reached end of list\n"); flint_abort(); } split_interval(t, &q->t, &q->v, zz_node_sgn(q), &r->t, &r->v, zz_node_sgn(r), prec); if (arb_contains_arf(t, &q->t) || arb_contains_arf(t, &r->t)) { result = 0; break; } mid_node = create_non_gram_node(arb_midref(t), ctx, prec); if (!mid_node) { result = 0; break; } q->next = mid_node; mid_node->prev = q; mid_node->next = r; r->prev = mid_node; q = r; r = r->next; } arb_clear(t); return result; } /* * Given a linked sublist beginning at U and ending at V defining function * evaluations at points that fully separate zeros of f(t) in the vicinity * of the nth zero, traverse the list until the nth zero is found. * Continue traversing the list until len consecutive isolating intervals * have been found, or until the end of the sublist is reached. * Return the number of isolated zeros found, starting at the nth zero. */ static slong count_up_separated_zeros(arf_interval_ptr res, zz_node_srcptr U, zz_node_srcptr V, const fmpz_t n, slong len) { if (len <= 0) { return 0; } else if (fmpz_sgn(n) < 1) { flint_printf("nonpositive indices of zeros are not supported\n"); flint_abort(); } else if (U == NULL || V == NULL) { flint_printf("U and V must not be NULL\n"); flint_abort(); } if (!zz_node_is_good_gram_node(U) || !zz_node_is_good_gram_node(V)) { flint_printf("U and V must be good Gram points\n"); flint_abort(); } else { slong i = 0; zz_node_srcptr p = U; fmpz_t N, k; fmpz_init(N); fmpz_init(k); fmpz_add_ui(N, p->gram, 1); fmpz_set(k, n); while (p != V) { if (!p->next) { flint_printf("prematurely reached end of list\n"); flint_abort(); } if (zz_node_sgn(p) != zz_node_sgn(p->next)) { fmpz_add_ui(N, N, 1); if (fmpz_equal(N, k)) { arf_set(&res[i].a, &p->t); arf_set(&res[i].b, &p->next->t); fmpz_add_ui(k, k, 1); i++; if (i == len) break; } } p = p->next; } fmpz_clear(k); return i; } return 0; } /* * Create a small linked list defining the Gram block that is expected * to contain the nth zero according to the Gram heuristic. * Returns 0 if unable to create the Gram block. * The output node *p is the first node in the Gram block on success * or NULL on failure. * The output node *q is the last node in the Gram block on success * or NULL on failure. * Success does not necessarily mean that the Gram block contains the nth zero. */ static int create_initial_gram_block(zz_node_ptr *p, zz_node_ptr *q, const platt_ctx_t ctx, const fmpz_t n, slong prec) { zz_node_ptr u, v; fmpz_t k; slong result = 1; fmpz_init(k); *p = NULL; *q = NULL; fmpz_sub_ui(k, n, 2); u = create_gram_node(k, ctx, prec); if (!u) { result = 0; goto finish; } fmpz_sub_ui(k, n, 1); v = create_gram_node(k, ctx, prec); if (!v) { result = 0; goto finish; } u->next = v; v->prev = u; if (!zz_node_is_good_gram_node(u)) { if (!extend_to_prev_good_gram_node(&u, u, ctx, prec)) { result = 0; goto finish; } } if (!zz_node_is_good_gram_node(v)) { if (!extend_to_next_good_gram_node(&v, v, ctx, prec)) { result = 0; goto finish; } } finish: if (result) { *p = u; *q = v; } else { delete_list(u); } return result; } /* * On failure returns 0 and output variables are NULL or zero. * The output variable *pu is the head of the output list. * The output variable *pv is the tail of the output list. * The first *pbound Gram blocks in the output list are certified as 'good', * and the list probably contains a few more trailing Gram blocks (not * necessarily certified as 'good'). */ static int create_initial_double_superblock(zz_node_ptr *pu, zz_node_ptr *pv, slong *pbound, const platt_ctx_t ctx, const fmpz_t n, slong prec) { zz_node_ptr p, q, u, v; slong i, k, bound, zn; slong good_block_count; slong result = 1; *pu = NULL; *pv = NULL; *pbound = 0; if (!create_initial_gram_block(&p, &q, ctx, n, prec)) { result = 0; goto finish; } /* * Add blocks in the forward direction until we have at least k Gram blocks, * where k is the turing method bound. * Note that these blocks are not necessarily good Gram blocks * and will not necessarily belong to the initial double superblock. * The bound may increase as the list is extended. */ for (k = 1; k < acb_dirichlet_turing_method_bound(q->gram); k++) { if (!extend_to_next_good_gram_node(&q, q, ctx, prec)) { result = 0; goto finish; } } bound = k; /* * Scan the list backwards, attempting to certify blocks as 'good' * and tracking the current number of consecutive good Gram blocks. */ good_block_count = 0; v = q; while ((u = _scan_to_prev_good_gram_node(v)) != NULL) { zn = count_gram_intervals(u, v); for (i = 0; i < LOOPCOUNT && count_sign_changes(u, v) < zn; i++) { if (!intercalate(ctx, u, v, prec)) { result = 0; goto finish; } } if (count_sign_changes(u, v) >= zn) { good_block_count++; } else { good_block_count = 0; } v = u; } if (v != p) { flint_printf("unexpected endpoint of backwards scan\n"); flint_abort(); } /* * Add blocks in the backwards direction until the number * of consecutive good Gram blocks is twice the computed bound. */ while (good_block_count < 2*bound) { if (!extend_to_prev_good_gram_node(&p, v, ctx, prec)) { result = 0; goto finish; } zn = count_gram_intervals(p, v); for (i = 0; i < LOOPCOUNT && count_sign_changes(p, v) < zn; i++) { if (!intercalate(ctx, p, v, prec)) { result = 0; goto finish; } } if (count_sign_changes(p, v) >= zn) { good_block_count++; } else { good_block_count = 0; } v = p; } finish: if (result) { *pu = p; *pv = q; *pbound = bound; } else { delete_list(p); } return result; } static slong _isolate_zeros(arf_interval_ptr res, const platt_ctx_t ctx, const fmpz_t n, slong len, slong prec) { zz_node_ptr x, y; /* Anchor nodes where N(t) is known */ zz_node_ptr u, v; /* For certifying Gram nodes as 'good' */ zz_node_ptr p, q; fmpz_t nnext; slong i, k, bound, zn, zc, zeros_count; fmpz_init(nnext); fmpz_set(nnext, n); p = NULL; zeros_count = 0; if (!create_initial_double_superblock(&p, &q, &bound, ctx, n, prec)) { goto finish; } /* * Set the anchor to the central good Gram node of the * initial double superblock. * Delete the nodes in the list before the anchor. */ x = scan_to_next_good_gram_node(p, bound); if (x == NULL) { flint_printf("missing or incomplete initial block\n"); flint_abort(); } delete_list_to(p, x); p = x; /* * Set v to the forward-most node in the list, * and track the number of consecutive good Gram blocks at that point. */ v = scan_to_next_good_gram_node(p, bound); if (v == NULL) { flint_printf("missing or incomplete initial block\n"); flint_abort(); } k = 2*bound; u = v; while ((v = _scan_to_next_good_gram_node(v)) != NULL) { zn = count_gram_intervals(u, v); if (count_sign_changes(u, v) >= zn) { k++; } else { k = 0; } u = v; } if (u != q) { flint_printf("failed to scan the initial list\n"); flint_abort(); } v = u; /* * Iterate through Gram blocks. The central good Gram point in each * stretch of 2*bound consecutive good Gram blocks is an 'anchor' point * where the number of zeros less than that point is known. * Therefore the number of zeros between each pair of anchor points * is known. As anchor points are certified, isolate the zeros falling * between each pair. */ while (1) { u = v; if (!extend_to_next_good_gram_node(&v, v, ctx, prec)) { goto finish; } zn = count_gram_intervals(u, v); for (i = 0; i < LOOPCOUNT && count_sign_changes(u, v) < zn; i++) { if (!intercalate(ctx, u, v, prec)) { goto finish; } } if (count_sign_changes(u, v) >= zn) { k++; } else { k = 0; } bound = acb_dirichlet_turing_method_bound(v->gram); if (k >= 2*bound && fmpz_cmp(x->gram, v->gram) < 0) { /* There are exactly zn zeros between the anchor points x and y. */ y = scan_to_prev_good_gram_node(v, bound); if (!y) { flint_printf("failed to scan backwards to anchor point\n"); flint_abort(); } zn = count_gram_intervals(x, y); while (count_sign_changes(x, y) < zn) { if (!intercalate(ctx, x, y, prec)) { goto finish; } } zc = count_up_separated_zeros(res + zeros_count, x, y, nnext, len - zeros_count); if (zc < 0 || zc > len - zeros_count) { flint_printf("unexpected number of isolated zeros\n"); flint_abort(); } zeros_count += zc; if (zeros_count == len) { goto finish; } fmpz_add_ui(nnext, nnext, zc); x = y; delete_list_to(p, x); p = x; } } finish: fmpz_clear(nnext); delete_list(p); return zeros_count; } slong _acb_dirichlet_platt_isolate_local_hardy_z_zeros( arf_interval_ptr res, const fmpz_t n, slong len, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma_grid, slong Ns_max, const arb_t H, slong sigma_interp, slong prec) { slong zeros_count; platt_ctx_t ctx; platt_ctx_init(ctx, T, A, B, h, J, K, sigma_grid, Ns_max, H, sigma_interp, prec); zeros_count = _isolate_zeros(res, ctx, n, len, prec); platt_ctx_clear(ctx); return zeros_count; } static void _refine_local_hardy_z_zero_illinois(arb_t res, const platt_ctx_t ctx, const arf_t ra, const arf_t rb, slong prec) { arf_t a, b, fa, fb, c, fc, t; arb_t z; slong k, nmag, abs_tol, wp; int asign, bsign, csign; arf_init(a); arf_init(b); arf_init(c); arf_init(fa); arf_init(fb); arf_init(fc); arf_init(t); arb_init(z); arf_set(a, ra); arf_set(b, rb); nmag = arf_abs_bound_lt_2exp_si(b); abs_tol = nmag - prec - 4; wp = prec + nmag + 8; platt_ctx_interpolate_arf(z, NULL, ctx, a, wp); asign = arb_sgn_nonzero(z); arf_set(fa, arb_midref(z)); platt_ctx_interpolate_arf(z, NULL, ctx, b, wp); bsign = arb_sgn_nonzero(z); arf_set(fb, arb_midref(z)); if (!asign || !bsign) { flint_printf("the function evaluations at the endpoints of the initial " "interval must not contain zero\n"); flint_abort(); } if (asign == bsign) { flint_printf("isolate a zero before bisecting the interval\n"); flint_abort(); } for (k = 0; k < 40; k++) { /* c = a - fa * (b - a) / (fb - fa) */ arf_sub(c, b, a, wp, ARF_RND_NEAR); arf_sub(t, fb, fa, wp, ARF_RND_NEAR); arf_div(c, c, t, wp, ARF_RND_NEAR); arf_mul(c, c, fa, wp, ARF_RND_NEAR); arf_sub(c, a, c, wp, ARF_RND_NEAR); /* if c is not sandwiched between a and b, fall back to one bisection step */ if (!arf_is_finite(c) || !((arf_cmp(a, c) < 0 && arf_cmp(c, b) < 0) || (arf_cmp(b, c) < 0 && arf_cmp(c, a) < 0))) { /* flint_printf("no sandwich (k = %wd)\n", k); */ arf_add(c, a, b, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul_2exp_si(c, c, -1); } platt_ctx_interpolate_arf(z, NULL, ctx, c, wp); csign = arb_sgn_nonzero(z); /* If the guess is close enough to a zero that the sign * cannot be determined, then use the derivative to * make an appropriately small interval around the guess. */ if (!csign) { arf_t deriv, aprime, bprime, faprime, fbprime, err, delta; slong i, aprimesign, bprimesign; arf_init(deriv); arf_init(aprime); arf_init(bprime); arf_init(faprime); arf_init(fbprime); arf_init(err); arf_init(delta); arf_set_mag(err, arb_radref(z)); platt_ctx_interpolate_arf(NULL, deriv, ctx, c, wp); arf_div(delta, err, deriv, wp, ARF_RND_NEAR); arf_mul_si(delta, delta, 3, wp, ARF_RND_NEAR); arf_mul_2exp_si(delta, delta, -1); arf_set(aprime, c); arf_set(bprime, c); /* When the context allows the interval endpoints to * be evaluated to relatively high precision, * this should not require more than one or two iterations. */ for (i = 0; i < 5; i++) { arf_sub(aprime, aprime, delta, wp, ARF_RND_DOWN); arf_add(bprime, bprime, delta, wp, ARF_RND_UP); if (arf_cmp(a, b) < 0) { if (arf_cmp(aprime, a) < 0) arf_set(aprime, a); if (arf_cmp(b, bprime) < 0) arf_set(bprime, b); } else { if (arf_cmp(aprime, b) < 0) arf_set(aprime, b); if (arf_cmp(a, bprime) < 0) arf_set(bprime, a); } platt_ctx_interpolate_arf(z, NULL, ctx, aprime, wp); arf_set(faprime, arb_midref(z)); aprimesign = arb_sgn_nonzero(z); platt_ctx_interpolate_arf(z, NULL, ctx, bprime, wp); arf_set(fbprime, arb_midref(z)); bprimesign = arb_sgn_nonzero(z); if (aprimesign && bprimesign && aprimesign != bprimesign) { arf_set(a, aprime); arf_set(b, bprime); arf_set(fa, faprime); arf_set(fb, fbprime); break; } } arf_clear(deriv); arf_clear(aprime); arf_clear(bprime); arf_clear(faprime); arf_clear(fbprime); arf_clear(err); arf_clear(delta); break; } arf_set(fc, arb_midref(z)); if (csign != bsign) { arf_set(a, b); arf_set(fa, fb); asign = bsign; arf_set(b, c); arf_set(fb, fc); bsign = csign; } else { arf_set(b, c); arf_set(fb, fc); bsign = csign; arf_mul_2exp_si(fa, fa, -1); } arf_sub(t, a, b, wp, ARF_RND_DOWN); arf_abs(t, t); if (arf_cmpabs_2exp_si(t, abs_tol) < 0) break; } /* a and b may have changed places */ if (arf_cmp(a, b) > 0) arf_swap(a, b); arb_set_interval_arf(res, a, b, prec); arf_clear(a); arf_clear(b); arf_clear(c); arf_clear(fa); arf_clear(fb); arf_clear(fc); arf_clear(t); arb_clear(z); } slong _acb_dirichlet_platt_local_hardy_z_zeros( arb_ptr res, const fmpz_t n, slong len, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma_grid, slong Ns_max, const arb_t H, slong sigma_interp, slong prec) { slong zeros_count, i; arf_interval_ptr p; platt_ctx_t ctx; platt_ctx_init( ctx, T, A, B, h, J, K, sigma_grid, Ns_max, H, sigma_interp, prec); p = _arf_interval_vec_init(len); zeros_count = _isolate_zeros(p, ctx, n, len, prec); for (i = 0; i < zeros_count; i++) { _refine_local_hardy_z_zero_illinois(res+i, ctx, &p[i].a, &p[i].b, prec); } platt_ctx_clear(ctx); _arf_interval_vec_clear(p, len); return zeros_count; } static void _arb_get_lbound_fmpz(fmpz_t z, const arb_t x, slong prec) { arf_t u; arf_init(u); arb_get_lbound_arf(u, x, prec); arf_get_fmpz(z, u, ARF_RND_DOWN); arf_clear(u); } /* Compares f to g=a*10^b. * Returns a negative value if f < g, positive value if g < f, otherwise 0. */ static int _fmpz_cmp_a_10exp_b(const fmpz_t f, slong a, slong b) { int result; fmpz_t g; fmpz_init(g); fmpz_set_ui(g, 10); fmpz_pow_ui(g, g, b); fmpz_mul_si(g, g, a); result = fmpz_cmp(f, g); fmpz_clear(g); return result; } static platt_ctx_ptr _create_heuristic_context(const fmpz_t n, slong prec) { platt_ctx_ptr p = NULL; slong J, K, A, B, Ns_max, sigma_grid, sigma_interp; slong kbits; fmpz_t T, k; arb_t g, h, H, logT; double dlogJ, dK, dgrid, dh, dH, dinterp; double x, x2, x3, x4; fmpz_init(T); fmpz_init(k); arb_init(g); arb_init(h); arb_init(H); arb_init(logT); /* Estimate the height of the nth zero using gram points -- * it's predicted to fall between g(n-2) and g(n-1). */ fmpz_sub_ui(k, n, 2); kbits = fmpz_sizeinbase(k, 2); acb_dirichlet_gram_point(g, k, NULL, NULL, prec + kbits); /* Let T be the integer at the center of the evaluation grid. */ _arb_get_lbound_fmpz(T, g, prec + kbits); arb_log_fmpz(logT, T, prec); x = arf_get_d(arb_midref(logT), ARF_RND_NEAR); x2 = x*x; x3 = x2*x; x4 = x2*x2; if (_fmpz_cmp_a_10exp_b(n, 1, 4) < 0) { goto finish; } else if (_fmpz_cmp_a_10exp_b(n, 1, 5) < 0) { /* interpolated for n in [1e4, 1e5] */ A = 4; B = 64; Ns_max = 100; dinterp = 25; dK = 28; dgrid = 31; dlogJ = 8.4398 + -0.40306*x + 0.029866*x2 + -2.2858e-05*x3; dh = 1.0844 + 0.25524*x + -0.0046997*x2 + -6.3447e-05*x3; dH = -11.882 + 3.9521*x + -0.38654*x2 + 0.012728*x3; } else if (_fmpz_cmp_a_10exp_b(n, 1, 7) < 0) { /* interpolated for n in [1e4, 1e7] */ A = 8; B = 4096; Ns_max = 200; dinterp = 25; dlogJ = 0.88323 + 0.21392*x + 0.020846*x2 + -0.00053151*x3; dK = 137.27 + -15.609*x + 1.0778*x2 + -0.025927*x3; dgrid = -1711.1 + 701.03*x + -48.424*x2 + 1.2075*x3; dh = 448.2 + -84.087*x + 6.2089*x2 + -0.14565*x3; dH = 0.94123 + 0.021136*x + -0.00093042*x2 + 3.1007e-05*x3; } else if (_fmpz_cmp_a_10exp_b(n, 2, 17) < 0) { /* interpolated for n in [1e7, 5e22] */ A = 8; B = 4096; Ns_max = 200; dlogJ = -0.4035 + 0.49086*x + 0.00016299*x2 + -3.6139e-06*x3 + 2.9323e-08*x4; dK = 79.032 + -1.781*x + 0.039243*x2 + -0.00094859*x3 + 7.3149e-06*x4; dgrid = 1186.9 + 130.17*x + -7.4059*x2 + 0.17895*x3 + -0.001602*x4; dinterp = -24.252 + 7.3231*x + -0.38971*x2 + 0.0088745*x3 + -7.4331e-05*x4; dh = 178.66 + -15.127*x + 0.93132*x2 + -0.02311*x3 + 0.00022146*x4; dH = 2.5499 + -0.24402*x + 0.014953*x2 + -0.00037347*x3 + 3.5596e-06*x4; } else if (_fmpz_cmp_a_10exp_b(n, 1, 37) < 0) { /* interpolated for n in [1e7, 1e37] */ A = 16; B = 8192; Ns_max = 300; dlogJ = -0.50566 + 0.49723*x + 1.7964e-05*x2 + -2.3664e-07*x3 + 1.1234e-09*x4; dK = 100.97 + -0.709*x + -0.0020664*x2 + 3.1633e-05*x3 + -2.2912e-07*x4; dgrid = 3998.1 + 6.68*x + -0.3202*x2 + 0.0051782*x3 + -3.3829e-05*x4; dinterp = 21.203 + -0.2797*x + 0.01191*x2 + -0.00019769*x3 + 1.0395e-06*x4; dh = 137.6 + -0.16471*x + 0.039086*x2 + -0.00063299*x3 + 4.9674e-06*x4; dH = 0.64172 + -0.0017413*x + 0.0002195*x2 + -3.5247e-06*x3 + 2.6633e-08*x4; } else { goto finish; } arb_set_d(h, dh); arb_set_d(H, dH); J = (slong) exp(dlogJ); K = (slong) dK; sigma_grid = ((slong) (dgrid/2))*2 + 1; sigma_interp = ((slong) (dinterp/2))*2 + 1; p = malloc(sizeof(platt_ctx_struct)); platt_ctx_init(p, T, A, B, h, J, K, sigma_grid, Ns_max, H, sigma_interp, prec); finish: fmpz_clear(T); fmpz_clear(k); arb_clear(g); arb_clear(h); arb_clear(H); arb_clear(logT); return p; } /* Returns the number of zeros found. */ slong acb_dirichlet_platt_isolate_local_hardy_z_zeros( arf_interval_ptr res, const fmpz_t n, slong len, slong prec) { if (len <= 0 || fmpz_sizeinbase(n, 10) < 5) { return 0; } else if (fmpz_sgn(n) < 1) { flint_printf("Nonpositive indices of Hardy Z zeros are not supported.\n"); flint_abort(); } else { slong zeros_count = 0; platt_ctx_ptr ctx = _create_heuristic_context(n, prec); if (ctx) { zeros_count = _isolate_zeros(res, ctx, n, len, prec); platt_ctx_clear(ctx); free(ctx); } return zeros_count; } return 0; } /* Returns the number of zeros found. */ slong acb_dirichlet_platt_local_hardy_z_zeros( arb_ptr res, const fmpz_t n, slong len, slong prec) { if (len <= 0 || fmpz_sizeinbase(n, 10) < 5) { return 0; } else if (fmpz_sgn(n) < 1) { flint_printf("Nonpositive indices of Hardy Z zeros are not supported.\n"); flint_abort(); } else { slong zeros_count = 0; platt_ctx_ptr ctx; ctx = _create_heuristic_context(n, prec); if (ctx) { slong i; arf_interval_ptr p = _arf_interval_vec_init(len); zeros_count = _isolate_zeros(p, ctx, n, len, prec); for (i = 0; i < zeros_count; i++) { _refine_local_hardy_z_zero_illinois( res+i, ctx, &p[i].a, &p[i].b, prec); } _arf_interval_vec_clear(p, len); platt_ctx_clear(ctx); free(ctx); } return zeros_count; } return 0; } arb-2.22.1/acb_dirichlet/platt_multieval.c000066400000000000000000000402121417376376500205120ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_hypgeom.h" #include "acb_dft.h" static void _acb_dot_arb(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) { arb_ptr a; arb_srcptr b, c; if (sizeof(acb_struct) != 2*sizeof(arb_struct)) { flint_printf("expected sizeof(acb_struct)=%zu " "to be twice sizeof(arb_struct)=%zu\n", sizeof(acb_struct), sizeof(arb_struct)); flint_abort(); } if (initial == NULL) { flint_printf("not implemented for NULL initial value\n"); flint_abort(); } a = acb_realref(res); b = acb_realref(initial); c = acb_realref(x); arb_dot(a, b, subtract, c, xstep*2, y, ystep, len, prec); a = acb_imagref(res); b = acb_imagref(initial); c = acb_imagref(x); arb_dot(a, b, subtract, c, xstep*2, y, ystep, len, prec); } static void _arb_add_d(arb_t z, const arb_t x, double d, slong prec) { arb_t u; arb_init(u); arb_set_d(u, d); arb_add(z, x, u, prec); arb_clear(u); } static void _arb_div_si_si(arb_t z, slong a, slong b, slong prec) { arb_set_si(z, a); arb_div_si(z, z, b, prec); } static void _arb_inv_si(arb_t z, slong n, slong prec) { arb_set_si(z, n); arb_inv(z, z, prec); } static void platt_g_gamma_term(acb_t out, const arb_t t0, const acb_t t, slong prec) { acb_t z; acb_init(z); acb_add_arb(z, t, t0, prec); acb_mul_onei(z, z); acb_mul_2exp_si(z, z, 1); acb_add_ui(z, z, 1, prec); acb_mul_2exp_si(z, z, -2); acb_gamma(out, z, prec); acb_clear(z); } static void platt_g_exp_term(acb_t out, const arb_t t0, const arb_t h, const acb_t t, slong prec) { arb_t pi; acb_t z1, z2; arb_init(pi); acb_init(z1); acb_init(z2); arb_const_pi(pi, prec); acb_add_arb(z1, t, t0, prec); acb_mul_arb(z1, z1, pi, prec); acb_mul_2exp_si(z1, z1, -2); acb_div_arb(z2, t, h, prec); acb_sqr(z2, z2, prec); acb_mul_2exp_si(z2, z2, -1); acb_sub(out, z1, z2, prec); acb_exp(out, out, prec); arb_clear(pi); acb_clear(z1); acb_clear(z2); } static void platt_g_base(acb_t out, const acb_t t, slong prec) { arb_t pi; arb_init(pi); arb_const_pi(pi, prec); acb_mul_arb(out, t, pi, prec); acb_mul_onei(out, out); acb_mul_2exp_si(out, out, 1); acb_neg(out, out); arb_clear(pi); } static void platt_g_table(acb_ptr table, slong A, slong B, const arb_t t0, const arb_t h, slong K, slong prec) { slong N = A*B; slong i, n, k; acb_t t, base; acb_t gamma_term, exp_term, coeff; acb_ptr precomputed_powers; acb_init(t); acb_init(base); acb_init(gamma_term); acb_init(exp_term); acb_init(coeff); precomputed_powers = _acb_vec_init(K); for (i=0; i= m/B - 1/(2*B) */ void get_smk_points(slong * res, slong A, slong B) { slong m, N, prec; arb_t x, u, v; fmpz_t z; arb_init(x); arb_init(u); /* pi / B */ arb_init(v); /* 1 / sqrt(pi) */ fmpz_init(z); N = A*B; prec = 4; arb_indeterminate(u); arb_indeterminate(v); for (m = 0; m < N; m++) { while (1) { arb_set_si(x, 2*m - 1); arb_mul(x, x, u, prec); arb_exp(x, x, prec); arb_mul(x, x, v, prec); arb_ceil(x, x, prec); if (arb_get_unique_fmpz(z, x)) { res[m] = fmpz_get_si(z); break; } else { prec *= 2; arb_const_pi(u, prec); arb_div_si(u, u, B, prec); arb_const_sqrt_pi(v, prec); arb_inv(v, v, prec); } } } arb_clear(x); arb_clear(u); arb_clear(v); fmpz_clear(z); } slong platt_get_smk_index(slong B, slong j, slong prec) { slong m; arb_t pi, x; fmpz_t z; arb_init(pi); arb_init(x); fmpz_init(z); m = -1; while (1) { arb_const_pi(pi, prec); logjsqrtpi(x, j, prec); arb_div(x, x, pi, prec); arb_mul_2exp_si(x, x, -1); arb_mul_si(x, x, B, prec); _arb_add_d(x, x, 0.5, prec); arb_floor(x, x, prec); if (arb_get_unique_fmpz(z, x)) { m = fmpz_get_si(z); break; } else { prec *= 2; } } arb_clear(pi); arb_clear(x); fmpz_clear(z); return m; } typedef struct { slong bmax; slong b; slong K; arb_ptr M; /* (b, K) */ acb_ptr v; /* (b, ) */ } smk_block_struct; typedef smk_block_struct smk_block_t[1]; static void smk_block_init(smk_block_t p, slong K, slong bmax) { p->bmax = bmax; p->b = 0; p->K = K; p->M = _arb_vec_init(K*bmax); p->v = _acb_vec_init(bmax); } static void smk_block_clear(smk_block_t p) { _arb_vec_clear(p->M, p->K * p->bmax); _acb_vec_clear(p->v, p->bmax); } static int smk_block_is_full(smk_block_t p) { return p->b == p->bmax; } static void smk_block_reset(smk_block_t p) { p->b = 0; } static void smk_block_increment(smk_block_t p, const acb_t z, arb_srcptr v) { if (smk_block_is_full(p)) { flint_printf("trying to increment a full block\n"); flint_abort(); } acb_set(p->v + p->b, z); _arb_vec_set(p->M + p->K * p->b, v, p->K); p->b += 1; } static void smk_block_accumulate(smk_block_t p, acb_ptr res, slong prec) { slong i; for (i = 0; i < p->K; i++) _acb_dot_arb(res + i, res + i, 0, p->v, 1, p->M + i, p->K, p->b, prec); } void _platt_smk(acb_ptr table, acb_ptr startvec, acb_ptr stopvec, const slong * smk_points, const arb_t t0, slong A, slong B, slong jstart, slong jstop, slong mstart, slong mstop, slong K, slong prec) { slong j, k, m; slong N = A * B; smk_block_t block; acb_ptr accum; arb_ptr diff_powers; arb_t rpi, logsqrtpi, rsqrtj, um, a, base; acb_t z; arb_init(rpi); arb_init(logsqrtpi); arb_init(rsqrtj); arb_init(um); arb_init(a); arb_init(base); acb_init(z); smk_block_init(block, K, 32); diff_powers = _arb_vec_init(K); accum = _acb_vec_init(K); arb_const_pi(rpi, prec); arb_inv(rpi, rpi, prec); arb_const_sqrt_pi(logsqrtpi, prec); arb_log(logsqrtpi, logsqrtpi, prec); m = platt_get_smk_index(B, jstart, prec); _arb_div_si_si(um, m, B, prec); for (j = jstart; j <= jstop; j++) { arb_log_ui(a, (ulong) j, prec); arb_add(a, a, logsqrtpi, prec); arb_mul(a, a, rpi, prec); arb_rsqrt_ui(rsqrtj, (ulong) j, prec); acb_set_arb(z, t0); acb_mul_arb(z, z, a, prec); acb_neg(z, z); acb_exp_pi_i(z, z, prec); acb_mul_arb(z, z, rsqrtj, prec); while (m < N - 1 && smk_points[m + 1] <= j) { m += 1; _arb_div_si_si(um, m, B, prec); } if (m < mstart || m > mstop) { flint_printf("out of bounds error: m = %ld not in [%ld, %ld]\n", m, mstart, mstop); flint_abort(); } arb_mul_2exp_si(base, a, -1); arb_sub(base, base, um, prec); _arb_vec_set_powers(diff_powers, base, K, prec); smk_block_increment(block, z, diff_powers); { int j_stops = j == jstop; int m_increases = m < N - 1 && smk_points[m + 1] <= j + 1; if (j_stops || m_increases || smk_block_is_full(block)) { smk_block_accumulate(block, accum, prec); smk_block_reset(block); } if (j_stops || m_increases) { if (startvec && m == mstart) { _acb_vec_set(startvec, accum, K); } else if (stopvec && m == mstop) { _acb_vec_set(stopvec, accum, K); } else { for (k = 0; k < K; k++) acb_set(table + N*k + m, accum + k); } _acb_vec_zero(accum, K); } } } arb_clear(rpi); arb_clear(logsqrtpi); arb_clear(rsqrtj); arb_clear(um); arb_clear(a); arb_clear(base); acb_clear(z); smk_block_clear(block); _arb_vec_clear(diff_powers, K); _acb_vec_clear(accum, K); } static void do_convolutions(acb_ptr out_table, acb_srcptr table, acb_srcptr S_table, slong N, slong K, slong prec) { slong i, k; acb_ptr padded_table_row, padded_S_table_row, padded_out_table; acb_ptr fp, gp; acb_dft_pre_t pre; padded_table_row = _acb_vec_init(N*2); padded_S_table_row = _acb_vec_init(N*2); padded_out_table = _acb_vec_init(N*2); fp = _acb_vec_init(N*2); gp = _acb_vec_init(N*2); acb_dft_precomp_init(pre, N*2, prec); for (k = 0; k < K; k++) { _acb_vec_zero(padded_table_row, N*2); _acb_vec_zero(padded_S_table_row, N*2); _acb_vec_zero(padded_out_table, N*2); _acb_vec_set(padded_table_row, table + k*N, N); _acb_vec_set(padded_S_table_row, S_table + k*N, N); for (i = 1; i < N; i++) { acb_swap(padded_S_table_row + i, padded_S_table_row + N*2 - i); } acb_dft_precomp(fp, padded_S_table_row, pre, prec); acb_dft_precomp(gp, padded_table_row, pre, prec); _acb_vec_kronecker_mul(gp, gp, fp, N*2, prec); acb_dft_inverse_precomp(padded_out_table, gp, pre, prec); for (i = 0; i <= N/2; i++) { acb_add(out_table + i, out_table + i, padded_out_table + i, prec); } } _acb_vec_clear(padded_table_row, N*2); _acb_vec_clear(padded_S_table_row, N*2); _acb_vec_clear(padded_out_table, N*2); _acb_vec_clear(fp, N*2); _acb_vec_clear(gp, N*2); acb_dft_precomp_clear(pre); } static void remove_gaussian_window(arb_ptr out, slong A, slong B, const arb_t h, slong prec) { slong i, n; slong N = A*B; arb_t t, x; arb_init(t); arb_init(x); for (i = 0; i < N; i++) { n = i - N/2; arb_set_si(t, n); arb_div_si(t, t, A, prec); arb_div(x, t, h, prec); arb_sqr(x, x, prec); arb_mul_2exp_si(x, x, -1); arb_exp(x, x, prec); arb_mul(out + i, out + i, x, prec); } arb_clear(t); arb_clear(x); } void _acb_dirichlet_platt_multieval(arb_ptr out, acb_srcptr S_table, const arb_t t0, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec) { slong N = A*B; slong i, k; acb_ptr table, out_a, out_b; acb_ptr row; arb_t t, x, k_factorial, err, ratio, c, xi; acb_t z; acb_dft_pre_t pre_N; arb_init(t); arb_init(x); arb_init(k_factorial); arb_init(err); arb_init(ratio); arb_init(c); arb_init(xi); acb_init(z); table = _acb_vec_init(K*N); out_a = _acb_vec_init(N); out_b = _acb_vec_init(N); acb_dft_precomp_init(pre_N, N, prec); _arb_inv_si(xi, B, prec); arb_mul_2exp_si(xi, xi, -1); platt_g_table(table, A, B, t0, h, K, prec); for (k = 0; k < K; k++) { acb_dirichlet_platt_lemma_A5(err, B, h, k, prec); _acb_vec_scalar_add_error_arb_mag(table + N*k, N, err); } for (k = 0; k < K; k++) { row = table + N*k; for (i = 0; i < N/2; i++) { acb_swap(row + i, row + i + N/2); } acb_dft_precomp(row, row, pre_N, prec); } _acb_vec_scalar_div_ui(table, table, N*K, (ulong) A, prec); for (k = 0; k < K; k++) { acb_dirichlet_platt_lemma_A7(err, sigma, t0, h, k, A, prec); _acb_vec_scalar_add_error_arb_mag(table + N*k, N, err); } arb_one(k_factorial); for (k = 2; k < K; k++) { row = table + N*k; arb_mul_ui(k_factorial, k_factorial, (ulong) k, prec); _acb_vec_scalar_div_arb(row, row, N, k_factorial, prec); } do_convolutions(out_a, table, S_table, N, K, prec); for (i = 0; i < N/2 + 1; i++) { arb_set_si(x, i); arb_div_si(x, x, B, prec); acb_dirichlet_platt_lemma_32(err, h, t0, x, prec); _acb_add_error_arb_mag(out_a + i, err); } acb_dirichlet_platt_lemma_B1(err, sigma, t0, h, J, prec); _acb_vec_scalar_add_error_arb_mag(out_a, N/2 + 1, err); arb_sqrt_ui(c, (ulong) J, prec); arb_mul_2exp_si(c, c, 1); arb_sub_ui(c, c, 1, prec); acb_dirichlet_platt_lemma_B2(err, K, h, xi, prec); arb_mul(err, err, c, prec); _acb_vec_scalar_add_error_arb_mag(out_a, N/2 + 1, err); for (i = 1; i < N/2; i++) { acb_conj(out_a + N - i, out_a + i); } acb_dirichlet_platt_lemma_A9(err, sigma, t0, h, A, prec); _acb_vec_scalar_add_error_arb_mag(out_a, N, err); acb_dft_inverse_precomp(out_b, out_a, pre_N, prec); _acb_vec_scalar_mul_ui(out_b, out_b, N, (ulong) A, prec); for (i = 0; i < N/2; i++) { acb_swap(out_b + i, out_b + i + N/2); } acb_dirichlet_platt_lemma_A11(err, t0, h, B, prec); _acb_vec_scalar_add_error_arb_mag(out_b, N, err); for (i = 0; i < N; i++) { arb_swap(out + i, acb_realref(out_b + i)); } remove_gaussian_window(out, A, B, h, prec); arb_clear(t); arb_clear(x); arb_clear(k_factorial); arb_clear(err); arb_clear(ratio); arb_clear(c); arb_clear(xi); acb_clear(z); _acb_vec_clear(table, K*N); _acb_vec_clear(out_a, N); _acb_vec_clear(out_b, N); acb_dft_precomp_clear(pre_N); } void acb_dirichlet_platt_multieval(arb_ptr out, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec) { if (flint_get_num_threads() > 1) { acb_dirichlet_platt_multieval_threaded( out, T, A, B, h, J, K, sigma, prec); } else { slong N = A*B; acb_ptr S; arb_t t0; slong * smk_points; smk_points = flint_malloc(N * sizeof(slong)); get_smk_points(smk_points, A, B); arb_init(t0); S = _acb_vec_init(K*N); arb_set_fmpz(t0, T); _platt_smk(S, NULL, NULL, smk_points, t0, A, B, 1, J, 0, N-1, K, prec); _acb_dirichlet_platt_multieval(out, S, t0, A, B, h, J, K, sigma, prec); arb_clear(t0); _acb_vec_clear(S, K*N); flint_free(smk_points); } } arb-2.22.1/acb_dirichlet/platt_multieval_threaded.c000066400000000000000000000072301417376376500223550ustar00rootroot00000000000000/* Copyright (C) 2020 Rudolph Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "pthread.h" slong platt_get_smk_index(slong B, slong j, slong prec); void get_smk_points(slong * res, slong A, slong B); void _platt_smk(acb_ptr table, acb_ptr startvec, acb_ptr stopvec, const slong * smk_points, const arb_t t0, slong A, slong B, slong jstart, slong jstop, slong mstart, slong mstop, slong K, slong prec); void _acb_dirichlet_platt_multieval(arb_ptr out, acb_srcptr S_table, const arb_t t0, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec); typedef struct { acb_ptr S; acb_ptr startvec; acb_ptr stopvec; const slong * smk_points; arb_srcptr t0; slong A; slong B; slong K; slong jstart; slong jstop; slong mstart; slong mstop; slong prec; } platt_smk_arg_t; static void * _platt_smk_thread(void * arg_ptr) { platt_smk_arg_t *p = (platt_smk_arg_t *) arg_ptr; _platt_smk(p->S, p->startvec, p->stopvec, p->smk_points, p->t0, p->A, p->B, p->jstart, p->jstop, p->mstart, p->mstop, p->K, p->prec); flint_cleanup(); return NULL; } void acb_dirichlet_platt_multieval_threaded(arb_ptr out, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec) { slong i, num_threads, N, threadtasks; slong * smk_points; pthread_t * threads; platt_smk_arg_t * args; acb_ptr S; arb_t t0; N = A*B; num_threads = flint_get_num_threads(); threads = flint_malloc(sizeof(pthread_t) * num_threads); args = flint_malloc(sizeof(platt_smk_arg_t) * num_threads); threadtasks = (J+num_threads-1)/num_threads; smk_points = flint_malloc(N * sizeof(slong)); arb_init(t0); get_smk_points(smk_points, A, B); arb_set_fmpz(t0, T); S = _acb_vec_init(K*N); for (i = 0; i < num_threads; i++) { args[i].S = S; args[i].startvec = _acb_vec_init(K); args[i].stopvec = _acb_vec_init(K); args[i].smk_points = smk_points; args[i].t0 = t0; args[i].A = A; args[i].B = B; args[i].K = K; args[i].prec = prec; args[i].jstart = i*threadtasks + 1; args[i].jstop = (i+1)*threadtasks; args[i].mstart = platt_get_smk_index(B, args[i].jstart, prec); args[i].mstop = platt_get_smk_index(B, args[i].jstop, prec); } args[num_threads-1].jstop = J; args[num_threads-1].mstop = platt_get_smk_index(B, J, prec); for (i = 0; i < num_threads; i++) { pthread_create(&threads[i], NULL, _platt_smk_thread, &args[i]); } for (i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); } for (i = 0; i < num_threads; i++) { slong k; for (k = 0; k < K; k++) { acb_ptr z; z = S + N*k + args[i].mstart; acb_add(z, z, args[i].startvec + k, prec); z = S + N*k + args[i].mstop; acb_add(z, z, args[i].stopvec + k, prec); } _acb_vec_clear(args[i].startvec, K); _acb_vec_clear(args[i].stopvec, K); } _acb_dirichlet_platt_multieval(out, S, t0, A, B, h, J, K, sigma, prec); arb_clear(t0); _acb_vec_clear(S, K*N); flint_free(smk_points); flint_free(args); flint_free(threads); } arb-2.22.1/acb_dirichlet/platt_ws_interpolation.c000066400000000000000000000374451417376376500221260ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "arb_hypgeom.h" #include "arb_poly.h" static void _arb_div_si_si(arb_t res, slong x, slong y, slong prec) { arb_set_si(res, x); arb_div_si(res, res, y, prec); } static void _arb_ui_pow_arb(arb_t res, ulong n, const arb_t x, slong prec) { arb_t a; arb_init(a); arb_set_ui(a, n); arb_pow(res, a, x, prec); arb_clear(a); } /* * Follows the notation in https://en.wikipedia.org/wiki/Gaussian_function * res = a*exp(-(x-b)^2 / (2*c^2)) * If 'a' is NULL a default coefficient of 1 is used. * If 'b' is NULL a default mean of 0 is used. */ static void _arb_gaussian(arb_t res, const arb_t a, const arb_t b, const arb_t c, const arb_t x, slong prec) { arb_t z; arb_init(z); if (b == NULL) arb_set(z, x); else arb_sub(z, x, b, prec); arb_div(z, z, c, prec); arb_sqr(z, z, prec); arb_mul_2exp_si(z, z, -1); arb_neg(z, z); arb_exp(z, z, prec); if (a == NULL) arb_set(res, z); else arb_mul(res, z, a, prec); arb_clear(z); } static void _platt_lambda(arb_t res, const arb_t t, slong prec) { acb_t pi, s, z, s1, s2; acb_init(pi); acb_init(s); acb_init(z); acb_init(s1); acb_init(s2); arb_set_d(acb_realref(s), 0.5); arb_set(acb_imagref(s), t); acb_const_pi(pi, prec); arb_mul_2exp_si(acb_imagref(s1), t, -1); acb_neg(s1, s1); acb_pow(s1, pi, s1, prec); acb_mul_2exp_si(s2, s, -1); acb_gamma(s2, s2, prec); acb_zeta(z, s, prec); acb_mul(z, z, s1, prec); acb_mul(z, z, s2, prec); if (!arb_contains_zero(acb_imagref(z))) { flint_abort(); } arb_set(res, acb_realref(z)); acb_clear(pi); acb_clear(s); acb_clear(z); acb_clear(s1); acb_clear(s2); } void acb_dirichlet_platt_scaled_lambda(arb_t res, const arb_t t, slong prec) { arb_t pi, lam; arb_init(pi); arb_init(lam); arb_const_pi(pi, prec); _platt_lambda(lam, t, prec); arb_mul(res, pi, t, prec); arb_mul_2exp_si(res, res, -2); arb_exp(res, res, prec); arb_mul(res, res, lam, prec); arb_clear(pi); arb_clear(lam); } void acb_dirichlet_platt_scaled_lambda_vec(arb_ptr res, const fmpz_t T, slong A, slong B, slong prec) { slong N = A*B; if (A < 1 || B < 1 || N % 2) { flint_printf("requires an even number of grid points\n"); flint_abort(); } else { slong i; arb_t t; arb_init(t); for (i = 0; i < N; i++) { slong n = i - N/2; _arb_div_si_si(t, n, A, prec); arb_add_fmpz(t, t, T, prec); acb_dirichlet_platt_scaled_lambda(res + i, t, prec); } arb_clear(t); } } static void _platt_bound_C3_X(arb_t res, const arb_t t0, slong A, const arb_t H, slong Ns, const arb_t beta, slong prec) { arb_t a, c, x; arb_init(a); arb_init(c); arb_init(x); /* res = gaussian(a=(t0+Ns/A)^beta, b=NULL, c=A*H, x=Ns) */ _arb_div_si_si(a, Ns, A, prec); arb_add(a, a, t0, prec); arb_pow(a, a, beta, prec); arb_mul_si(c, H, A, prec); arb_set_si(x, Ns); _arb_gaussian(res, a, NULL, c, x, prec); arb_clear(a); arb_clear(c); arb_clear(x); } static void _platt_bound_C3_Y(arb_t res, const arb_t t0, slong A, const arb_t H, slong Ns, const arb_t beta, slong prec) { arb_t a, b, g, g1, g2; arb_init(a); arb_init(b); arb_init(g); arb_init(g1); arb_init(g2); /* a = 2^((2*beta - 1)/2) */ arb_mul_2exp_si(a, beta, 1); arb_sub_ui(a, a, 1, prec); arb_mul_2exp_si(a, a, -1); _arb_ui_pow_arb(a, 2, a, prec); /* b = t0^beta */ arb_pow(b, t0, beta, prec); /* g = incomplete_gamma(1/2, Ns^2 / (2*A^2*H^2)) */ arb_set_d(g1, 0.5); _arb_div_si_si(g2, Ns, A, prec); arb_div(g2, g2, H, prec); arb_sqr(g2, g2, prec); arb_mul_2exp_si(g2, g2, -1); arb_hypgeom_gamma_upper(g, g1, g2, 0, prec); /* res = a*b*A*H*g */ arb_mul_si(res, H, A, prec); arb_mul(res, res, a, prec); arb_mul(res, res, b, prec); arb_mul(res, res, g, prec); arb_clear(a); arb_clear(b); arb_clear(g); arb_clear(g1); arb_clear(g2); } static void _platt_bound_C3_Z(arb_t res, const arb_t t0, slong A, const arb_t H, const arb_t beta, slong prec) { arb_t a, b, g, g1, g2; arb_init(a); arb_init(b); arb_init(g); arb_init(g1); arb_init(g2); /* a = 2^((3*beta - 1)/2) */ arb_mul_ui(a, beta, 3, prec); arb_sub_ui(a, a, 1, prec); arb_mul_2exp_si(a, a, -1); _arb_ui_pow_arb(a, 2, a, prec); /* b = H^(beta + 1) */ arb_add_ui(b, beta, 1, prec); arb_pow(b, H, b, prec); /* g = incomplete_gamma((beta+1)/2, t0^2 / (2*H^2)) */ arb_add_ui(g1, beta, 1, prec); arb_mul_2exp_si(g1, g1, -1); arb_div(g2, t0, H, prec); arb_sqr(g2, g2, prec); arb_mul_2exp_si(g2, g2, -1); arb_hypgeom_gamma_upper(g, g1, g2, 0, prec); /* res = a*b*A*g */ arb_mul_si(res, g, A, prec); arb_mul(res, res, a, prec); arb_mul(res, res, b, prec); arb_clear(a); arb_clear(b); arb_clear(g); arb_clear(g1); arb_clear(g2); } /* * An improvement of Lemma C.3 is used, which is tighter by a factor of A. * https://github.com/fredrik-johansson/arb/pull/269#issuecomment-468488347 */ void acb_dirichlet_platt_bound_C3(arb_t res, const arb_t t0, slong A, const arb_t H, slong Ns, slong prec) { arb_t pi, ee, beta, X, Y, Z, lhs, rhs; arb_init(pi); arb_init(ee); arb_init(beta); arb_init(X); arb_init(Y); arb_init(Z); arb_init(lhs); arb_init(rhs); /* t0 > exp(exp(1) is required for valid error bounds. */ arb_const_e(ee, prec); arb_exp(ee, ee, prec); if (!arb_gt(t0, ee)) { arb_zero_pm_inf(res); goto finish; } /* 0 < Ns <= t0*A is required for valid error bounds. */ arb_set_si(lhs, Ns); arb_mul_si(rhs, t0, A, prec); if (!arb_is_positive(lhs) || !arb_le(lhs, rhs)) { arb_zero_pm_inf(res); goto finish; } /* res = (X + Y + Z) * 6 / (pi * Ns) */ arb_const_pi(pi, prec); acb_dirichlet_platt_beta(beta, t0, prec); _platt_bound_C3_X(X, t0, A, H, Ns, beta, prec); _platt_bound_C3_Y(Y, t0, A, H, Ns, beta, prec); _platt_bound_C3_Z(Z, t0, A, H, beta, prec); arb_add(res, X, Y, prec); arb_add(res, res, Z, prec); arb_mul_ui(res, res, 6, prec); arb_div(res, res, pi, prec); arb_div_si(res, res, Ns, prec); finish: arb_clear(pi); arb_clear(ee); arb_clear(beta); arb_clear(X); arb_clear(Y); arb_clear(Z); arb_clear(lhs); arb_clear(rhs); } /* Does not account for limited resolution and supporting points. */ static void _interpolation_helper_raw(arb_t res, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong i0, slong Ns, const arb_t H, slong prec) { mag_t m; arb_t accum1; /* sum of terms where the argument of sinc is small */ arb_t accum2; /* sum of terms where the argument of sinc is large */ arb_t dt0, dt, a, b, s, pi, g, x, c; slong i; slong N = A*B; mag_init(m); arb_init(accum1); arb_init(accum2); arb_init(dt0); arb_init(dt); arb_init(a); arb_init(b); arb_init(s); arb_init(pi); arb_init(g); arb_init(x); arb_init(c); arb_const_pi(pi, prec); arb_sub_fmpz(dt0, t0, T, prec + fmpz_clog_ui(T, 2)); /* x = -N/2 - A*dt0 */ arb_mul_si(x, dt0, A, prec); arb_add_si(x, x, N/2, prec); arb_neg(x, x); /* c = sin(pi*x) / pi */ arb_sin_pi(c, x, prec); arb_div(c, c, pi, prec); for (i = i0; i < i0 + 2*Ns; i++) { slong n = i - N/2; _arb_div_si_si(dt, n, A, prec); _arb_gaussian(g, NULL, dt0, H, dt, prec); arb_mul(s, g, p + i, prec); arb_add_si(a, x, i, prec); arb_get_mag(m, a); if (mag_cmp_2exp_si(m, -1) < 0) { arb_sinc_pi(b, a, prec); arb_addmul(accum1, s, b, prec); } else { arb_div(b, s, a, prec); if (i % 2) { arb_neg(b, b); } arb_add(accum2, accum2, b, prec); } } arb_set(res, accum1); arb_addmul(res, accum2, c, prec); mag_clear(m); arb_clear(accum1); arb_clear(accum2); arb_clear(dt0); arb_clear(dt); arb_clear(a); arb_clear(b); arb_clear(s); arb_clear(pi); arb_clear(g); arb_clear(x); arb_clear(c); } /* Sets res to the function (a * exp(-(b-h)^2 / c)) * sinc_pi(d*(b-h))) * of the power series h, for the purpose of computing derivatives * of the Gaussian-windowed Whittaker-Shannon interpolation. * Supports aliasing. */ static void _arb_poly_gwws_series(arb_ptr res, arb_srcptr h, slong hlen, const arb_t a, const arb_t b, const arb_t c, const arb_t d, slong len, slong prec) { arb_ptr u, u2, v, w; hlen = FLINT_MIN(hlen, len); u = _arb_vec_init(hlen); u2 = _arb_vec_init(len); v = _arb_vec_init(len); w = _arb_vec_init(len); /* u = b-h; u2 = (b-h)^2 */ _arb_vec_neg(u, h, hlen); arb_add(u, u, b, prec); _arb_poly_mullow(u2, u, hlen, u, hlen, len, prec); /* v = exp(-(b-h)^2 / c) */ _arb_vec_scalar_div(v, u2, len, c, prec); _arb_vec_neg(v, v, len); _arb_poly_exp_series(v, v, len, len, prec); /* w = sinc_pi(d*(b-h)) */ _arb_vec_scalar_mul(w, u, hlen, d, prec); _arb_poly_sinc_pi_series(w, w, hlen, len, prec); /* res = a * exp(-(b-h)^2 / c)) * sinc_pi(d*(b-h)) */ _arb_poly_mullow(res, v, len, w, len, len, prec); _arb_vec_scalar_mul(res, res, len, a, prec); _arb_vec_clear(u, hlen); _arb_vec_clear(u2, len); _arb_vec_clear(v, len); _arb_vec_clear(w, len); } /* Does not account for limited resolution and supporting points. */ static void _interpolation_helper_raw_series(arb_ptr res, arb_srcptr t0, slong t0len, arb_srcptr p, const fmpz_t T, slong A, slong B, slong i0, slong Ns, const arb_t H, slong trunc, slong prec) { t0len = FLINT_MIN(t0len, trunc); if (t0len == 1) { _interpolation_helper_raw(res, t0, p, T, A, B, i0, Ns, H, prec); _arb_vec_zero(res + 1, trunc - 1); } else { arb_ptr h, g, accum; arb_t b, c, d; slong N = A*B; slong i; arb_init(b); arb_init(c); arb_init(d); h = _arb_vec_init(t0len); g = _arb_vec_init(trunc); accum = _arb_vec_init(trunc); arb_sqr(c, H, prec); arb_mul_2exp_si(c, c, 1); arb_set_si(d, A); _arb_vec_set(h, t0, t0len); arb_sub_fmpz(h, t0, T, prec + fmpz_clog_ui(T, 2)); for (i = i0; i < i0 + 2*Ns; i++) { slong n = i - N/2; _arb_div_si_si(b, n, A, prec); _arb_poly_gwws_series(g, h, t0len, p + i, b, c, d, trunc, prec); _arb_vec_add(accum, accum, g, trunc, prec); } _arb_vec_set(res, accum, trunc); arb_clear(b); arb_clear(c); arb_clear(d); _arb_vec_clear(h, t0len); _arb_vec_clear(g, trunc); _arb_vec_clear(accum, trunc); } } static void _interpolation_deriv_helper(arf_t res, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong i0, slong Ns, const arb_t H, slong prec) { arb_ptr t, h; t = _arb_vec_init(2); h = _arb_vec_init(2); arb_set(t+0, t0); arb_one(t+1); _interpolation_helper_raw_series( h, t, 2, p, T, A, B, i0, Ns, H, 2, prec); arf_set(res, arb_midref(h+1)); _arb_vec_clear(t, 2); _arb_vec_clear(h, 2); } /* Accounts for limited resolution and supporting points. */ static void _interpolation_helper(arb_t res, const acb_dirichlet_platt_ws_precomp_t pre, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong i0, slong Ns, const arb_t H, slong sigma, slong prec) { arb_t total, err; arb_init(total); arb_init(err); _interpolation_helper_raw( total, t0, p, T, A, B, i0, Ns, H, prec); acb_dirichlet_platt_bound_C3(err, t0, A, H, Ns, prec); arb_add_error(total, err); acb_dirichlet_platt_i_bound_precomp( err, &pre->pre_i, &pre->pre_c, t0, A, H, sigma, prec); arb_add_error(total, err); arb_set(res, total); arb_clear(total); arb_clear(err); } void acb_dirichlet_platt_ws_precomp_init(acb_dirichlet_platt_ws_precomp_t pre, slong A, const arb_t H, slong sigma, slong prec) { acb_dirichlet_platt_c_precomp_init(&pre->pre_c, sigma, H, 0, prec); acb_dirichlet_platt_i_precomp_init(&pre->pre_i, A, H, sigma, prec); } void acb_dirichlet_platt_ws_precomp_clear(acb_dirichlet_platt_ws_precomp_t pre) { acb_dirichlet_platt_c_precomp_clear(&pre->pre_c); acb_dirichlet_platt_i_precomp_clear(&pre->pre_i); } void acb_dirichlet_platt_ws_interpolation_precomp(arb_t res, arf_t deriv, const acb_dirichlet_platt_ws_precomp_t pre, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong Ns_max, const arb_t H, slong sigma, slong prec) { slong N = A*B; if (A < 1 || B < 1 || N % 2) { flint_printf("requires an even number of grid points\n"); flint_abort(); } else { arb_t x, dt0, dt0A, total; arf_t lower_f; slong n, lower_n; arb_init(x); arb_init(dt0); arb_init(dt0A); arb_init(total); arf_init(lower_f); arb_sub_fmpz(dt0, t0, T, prec + fmpz_clog_ui(T, 2)); arb_mul_si(dt0A, dt0, A, prec); arb_get_lbound_arf(lower_f, dt0A, prec); lower_n = arf_get_si(lower_f, ARF_RND_FLOOR); if (deriv) { arf_zero(deriv); } /* * More than one iteration is needed only when the set of * supporting points for interpolation is uncertain. */ for (n = lower_n; n == lower_n || arb_contains_si(dt0A, n); n++) { slong nlow = N/2 + n + 1; slong nhigh = N/2 - n - 1; slong Ns = FLINT_MIN(Ns_max, FLINT_MIN(nlow, nhigh)); if (Ns < 1) { arb_zero_pm_inf(total); } else { slong i0 = N/2 + n - (Ns - 1); if (res) { _interpolation_helper( x, pre, t0, p, T, A, B, i0, Ns, H, sigma, prec); if (n == lower_n) { arb_set(total, x); } else { arb_union(total, total, x, prec); } } if (deriv) { _interpolation_deriv_helper( deriv, t0, p, T, A, B, i0, Ns, H, prec); } } } if (res) { arb_set(res, total); } arb_clear(x); arb_clear(dt0); arb_clear(dt0A); arb_clear(total); arf_clear(lower_f); } } void acb_dirichlet_platt_ws_interpolation(arb_t res, arf_t deriv, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong Ns_max, const arb_t H, slong sigma, slong prec) { acb_dirichlet_platt_ws_precomp_t pre; acb_dirichlet_platt_ws_precomp_init(pre, A, H, sigma, prec); acb_dirichlet_platt_ws_interpolation_precomp( res, deriv, pre, t0, p, T, A, B, Ns_max, H, sigma, prec); acb_dirichlet_platt_ws_precomp_clear(pre); } arb-2.22.1/acb_dirichlet/platt_zeta_zeros.c000066400000000000000000000021101417376376500206700ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" slong acb_dirichlet_platt_zeta_zeros(acb_ptr res, const fmpz_t n, slong len, slong prec) { if (len <= 0 || fmpz_sizeinbase(n, 10) < 5) { return 0; } else if (fmpz_sgn(n) < 1) { flint_printf("nonpositive indices of zeta zeros are not supported\n"); flint_abort(); } else { slong i, found; arb_ptr p; p = _arb_vec_init(len); found = acb_dirichlet_platt_hardy_z_zeros(p, n, len, prec); for (i = 0; i < found; i++) { acb_set_d(res + i, 0.5); arb_set(acb_imagref(res + i), p + i); } _arb_vec_clear(p, len); return found; } return 0; } arb-2.22.1/acb_dirichlet/powsum_sieved.c000066400000000000000000000060111417376376500201740ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" #define POWER(_k) (powers + (((_k)-1)/2) * (len)) #define DIVISOR(_k) (divisors[((_k)-1)/2]) void acb_dirichlet_powsum_sieved(acb_ptr z, const acb_t s, ulong n, slong len, slong prec) { slong * divisors; slong powers_alloc; slong i, j, k, ibound, power_of_two, horner_point; ulong kprev; int critical_line, integer; acb_ptr powers; acb_ptr t, u, x; acb_ptr p1, p2; arb_t logk, v, w; if (n <= 1) { acb_set_ui(z, n); _acb_vec_zero(z + 1, len - 1); return; } critical_line = arb_is_exact(acb_realref(s)) && (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0); integer = arb_is_zero(acb_imagref(s)) && arb_is_int(acb_realref(s)); divisors = flint_calloc(n / 2 + 1, sizeof(slong)); powers_alloc = (n / 6 + 1) * len; powers = _acb_vec_init(powers_alloc); ibound = n_sqrt(n); for (i = 3; i <= ibound; i += 2) if (DIVISOR(i) == 0) for (j = i * i; j <= n; j += 2 * i) DIVISOR(j) = i; t = _acb_vec_init(len); u = _acb_vec_init(len); x = _acb_vec_init(len); arb_init(logk); arb_init(v); arb_init(w); power_of_two = 1; while (power_of_two * 2 <= n) power_of_two *= 2; horner_point = n / power_of_two; _acb_vec_zero(z, len); kprev = 1; acb_dirichlet_powsum_term(x, logk, &kprev, s, 2, integer, critical_line, len, prec); for (k = 1; k <= n; k += 2) { /* t = k^(-s) */ if (DIVISOR(k) == 0) { acb_dirichlet_powsum_term(t, logk, &kprev, s, k, integer, critical_line, len, prec); } else { p1 = POWER(DIVISOR(k)); p2 = POWER(k / DIVISOR(k)); if (len == 1) acb_mul(t, p1, p2, prec); else _acb_poly_mullow(t, p1, len, p2, len, len, prec); } if (k * 3 <= n) _acb_vec_set(POWER(k), t, len); _acb_vec_add(u, u, t, len, prec); while (k == horner_point && power_of_two != 1) { _acb_poly_mullow(t, z, len, x, len, len, prec); _acb_vec_add(z, t, u, len, prec); power_of_two /= 2; horner_point = n / power_of_two; horner_point -= (horner_point % 2 == 0); } } _acb_poly_mullow(t, z, len, x, len, len, prec); _acb_vec_add(z, t, u, len, prec); flint_free(divisors); _acb_vec_clear(powers, powers_alloc); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(x, len); arb_clear(logk); arb_clear(v); arb_clear(w); } arb-2.22.1/acb_dirichlet/powsum_smooth.c000066400000000000000000000123301417376376500202270ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" /* bound number of 5-smooth numbers up to n; see http://oeis.org/A188425 */ /* this does not need to be tight */ static slong smooth_bound(ulong n) { if (n <= 256) return 52; if (n <= 65536) return 284; if (n <= 16777216) return 836; return 13283; /* ok up to 2^64 */ } static ulong smul(ulong x, ulong y) { ulong hi, lo; umul_ppmm(hi, lo, x, y); if (hi) return UWORD_MAX; else return lo; } static slong index(const ulong * v, ulong c) { slong i; for (i = 0; ; i++) if (v[i] == c) return i; } void acb_dirichlet_powsum_smooth(acb_ptr res, const acb_t s, ulong N, slong d, slong prec) { ulong * smooth; /* numbers 2^i 3^j 5^k <= N */ slong num_smooth; /* the number of such numbers */ acb_ptr sums; /* partial sum for each smooth prefactor */ acb_ptr powers; /* (3^j 5^k)^(-s) */ acb_ptr t; /* temporary */ arb_t log_n; ulong x2, x3, x5, m, n, nprev; slong i2, i3, i5, i, j, iu; int critical_line, integer; if (N <= 1) { acb_set_ui(res, N); _acb_vec_zero(res + 1, d - 1); return; } if (N >= UWORD_MAX - 2) flint_abort(); critical_line = arb_is_exact(acb_realref(s)) && (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0); integer = arb_is_zero(acb_imagref(s)) && arb_is_int(acb_realref(s)); /* generate the smooth numbers */ smooth = flint_malloc(smooth_bound(N) * sizeof(ulong)); smooth[0] = 1; num_smooth = 1; x2 = 2; x3 = 3; x5 = 5; i2 = i3 = i5 = 0; while ((m = FLINT_MIN(FLINT_MIN(x2, x3), x5)) <= N) { smooth[num_smooth++] = m; if (m == x2) x2 = smul(2, smooth[++i2]); if (m == x3) x3 = smul(3, smooth[++i3]); if (m == x5) x5 = smul(5, smooth[++i5]); } sums = _acb_vec_init(num_smooth * d); powers = _acb_vec_init(num_smooth * d); t = _acb_vec_init(d); arb_init(log_n); arb_zero(log_n); nprev = 1; /* add 1^-s */ for (i = 0; i < num_smooth; i++) acb_one(sums + i * d); /* compute all the non-smooth index terms (bulk of the work) */ for (n = 7; n <= N; n += 2) { if ((n % 3 != 0) && (n % 5 != 0)) { acb_dirichlet_powsum_term(t, log_n, &nprev, s, n, integer, critical_line, d, prec); _acb_vec_add(sums, sums, t, d, prec); for (i = 1; i < num_smooth && (smooth[i] <= (N / n)); i++) _acb_vec_add(sums + i * d, sums + i * d, t, d, prec); } } /* compute 2^(-s) and powers (3^j 3^k)^(-s) */ arb_zero(log_n); nprev = 1; for (i = 1; i < num_smooth; i++) { n = smooth[i]; if (n == 2) { acb_dirichlet_powsum_term(powers + i * d, log_n, &nprev, s, n, integer, critical_line, d, prec); } else if (n % 2 != 0) { if (n <= 5) { acb_dirichlet_powsum_term(powers + i * d, log_n, &nprev, s, n, integer, critical_line, d, prec); } else if (n % 3 == 0) { i3 = index(smooth, 3); iu = index(smooth, n / 3); _acb_poly_mullow(powers + i * d, powers + i3 * d, d, powers + iu * d, d, d, prec); } else { i5 = index(smooth, 5); iu = index(smooth, n / 5); _acb_poly_mullow(powers + i * d, powers + i5 * d, d, powers + iu * d, d, d, prec); } } } /* merge the sums into the power-of-two sums */ for (i = 0; i < num_smooth; i++) { ulong u, v; m = smooth[i]; u = m; v = 0; while ((u & 1) == 0) { u >>= 1; v++; } if ((UWORD(1) << v) != m) { j = index(smooth, UWORD(1) << v); iu = index(smooth, u); if (u == 1) { _acb_vec_add(sums + j * d, sums + j * d, sums + i * d, d, prec); } else { _acb_poly_mullow(t, sums + i * d, d, powers + iu * d, d, d, prec); _acb_vec_add(sums + j * d, sums + j * d, t, d, prec); } } } /* finally evaluate with respect to powers of 2 using horner */ _acb_vec_zero(res, d); i2 = index(smooth, 2); for (i = num_smooth - 1; i >= 0; i--) { n = smooth[i]; if ((n & (n - 1)) == 0) { _acb_poly_mullow(t, powers + i2 * d, d, res, d, d, prec); _acb_vec_add(res, sums + i * d, t, d, prec); } } _acb_vec_clear(sums, num_smooth * d); _acb_vec_clear(powers, num_smooth * d); _acb_vec_clear(t, d); arb_clear(log_n); flint_free(smooth); } arb-2.22.1/acb_dirichlet/powsum_term.c000066400000000000000000000035421417376376500176720ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_powsum_term(acb_ptr res, arb_t log_prev, ulong * prev, const acb_t s, ulong k, int integer, int critical_line, slong len, slong prec) { slong i; if (integer) { arb_neg(acb_realref(res), acb_realref(s)); arb_set_ui(acb_imagref(res), k); arb_pow(acb_realref(res), acb_imagref(res), acb_realref(res), prec); arb_zero(acb_imagref(res)); if (len != 1) { arb_log_ui_from_prev(log_prev, k, log_prev, *prev, prec); *prev = k; } } else { arb_t w; arb_init(w); arb_log_ui_from_prev(log_prev, k, log_prev, *prev, prec); *prev = k; arb_mul(w, log_prev, acb_imagref(s), prec); arb_sin_cos(acb_imagref(res), acb_realref(res), w, prec); arb_neg(acb_imagref(res), acb_imagref(res)); if (critical_line) { arb_rsqrt_ui(w, k, prec); acb_mul_arb(res, res, w, prec); } else { arb_mul(w, acb_realref(s), log_prev, prec); arb_neg(w, w); arb_exp(w, w, prec); acb_mul_arb(res, res, w, prec); } arb_clear(w); } if (len > 1) { arb_neg(log_prev, log_prev); for (i = 1; i < len; i++) { acb_mul_arb(res + i, res + i - 1, log_prev, prec); acb_div_ui(res + i, res + i, i, prec); } arb_neg(log_prev, log_prev); } } arb-2.22.1/acb_dirichlet/profile/000077500000000000000000000000001417376376500166015ustar00rootroot00000000000000arb-2.22.1/acb_dirichlet/profile/p-gauss.c000066400000000000000000000070211417376376500203240ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_dirichlet.h" #include "flint/profiler.h" #define LOG 0 #define CSV 1 #define JSON 2 typedef void (*do_f) (acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec); int main(int argc, char *argv[]) { int out; ulong n, nref, maxq = 5000; ulong * rand; flint_rand_t state; slong r, nr; int l, nf = 5; do_f func[5] = { acb_dirichlet_gauss_sum_naive, acb_dirichlet_gauss_sum_factor, acb_dirichlet_gauss_sum_theta, acb_dirichlet_gauss_sum, acb_dirichlet_gauss_sum }; char * name[5] = { "naive", "factor", "theta", "default", "precomp" }; int i, ni = 5; ulong qmin[5] = { 3, 50, 500, 1000, 10000 }; ulong qmax[5] = { 50, 100, 599, 1050, 10030 }; int j, nj = 3; slong prec[3] = { 64, 128, 1024 }; if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } if (out == CSV) flint_printf("# %-12s, %7s, %7s, %7s, %7s\n","name", "prec", "qmin", "qmax", "time"); for (j = 0; j < nj; j++) { for (i = 0; i < ni; i++) { if (out == LOG) flint_printf("G_q(a) at prec %wu for all %wu <= q <= %wu....\n", prec[j], qmin[i], qmax[i]); for (l = 0; l < nf; l++) { ulong q; if (qmin[i] > 2000 && l == 0) continue; if (out == LOG) flint_printf("%-14s ... ", name[l]); else if (out == CSV) flint_printf("%-12s, %7d, %7d, %7d, ", name[l], prec[j], qmin[i], qmax[i]); else if (out == JSON) flint_printf("{ \"name\": \"%s\", \"prec\": %d, \"qmin\": %d, \"qmax\": %d, \"time\": ", name[l], prec[j], qmin[i], qmax[i]); TIMEIT_ONCE_START for (q = qmin[i]; q <= qmax[i]; q++) { dirichlet_group_t G; dirichlet_char_t chi; acb_t res; if (q % 4 == 2) continue; dirichlet_group_init(G, q); if (l == 4) dirichlet_group_dlog_precompute(G, 1); dirichlet_char_init(chi, G); dirichlet_char_first_primitive(chi, G); acb_init(res); do { func[l](res, G, chi, prec[j]); } while (dirichlet_char_next_primitive(chi, G) >= 0); acb_clear(res); dirichlet_char_clear(chi); if (l == 4) dirichlet_group_dlog_clear(G); dirichlet_group_clear(G); } TIMEIT_ONCE_STOP if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } } } flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/profile/p-jacobi.c000066400000000000000000000066611417376376500204420ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_dirichlet.h" #include "flint/profiler.h" #define LOG 0 #define CSV 1 #define JSON 2 typedef void (*do_f) (acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec); int main(int argc, char *argv[]) { int out; ulong n, nref, maxq = 5000; ulong * rand; flint_rand_t state; slong r, nr; int l, nf = 4; do_f func[4] = { acb_dirichlet_jacobi_sum_naive, acb_dirichlet_jacobi_sum_factor, acb_dirichlet_jacobi_sum_gauss, acb_dirichlet_jacobi_sum }; char * name[4] = { "naive", "factor", "gauss", "default" }; int i, ni = 4; ulong qmin[4] = { 3, 51, 501, 10001 }; ulong qmax[4] = { 30, 100, 550, 10050 }; int j, nj = 3; slong prec[3] = { 64, 128, 1024 }; if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } if (out == CSV) flint_printf("# %-12s, %7s, %7s, %7s, %7s\n","name", "prec", "qmin", "qmax", "time"); for (j = 0; j < nj; j++) { for (i = 0; i < ni; i++) { if (out == LOG) flint_printf("J_q(a,b) at prec %wu for all %wu <= q <= %wu....\n", prec[j], qmin[i], qmax[i]); for (l = 0; l < nf; l++) { ulong q; if (out == LOG) flint_printf("%-14s ... ", name[l]); else if (out == CSV) flint_printf("%-12s, %7d, %7d, %7d, ", name[l], prec[j], qmin[i], qmax[i]); else if (out == JSON) flint_printf("{ \"name\": \"%s\", \"prec\": %d, \"qmin\": %d, \"qmax\": %d, \"time\": ", name[l], prec[j], qmin[i], qmax[i]); TIMEIT_ONCE_START for (q = qmin[i]; q <= qmax[i]; q+=2) { dirichlet_group_t G; dirichlet_char_t chi1, chi2; acb_t res; dirichlet_group_init(G, q); dirichlet_char_init(chi1, G); dirichlet_char_init(chi2, G); acb_init(res); do { slong c = 0; dirichlet_char_set(chi2, G, chi1); do { func[l](res, G, chi1, chi2, prec[j]); } while (dirichlet_char_next(chi2, G) >= 0 && c++ < 30); } while (dirichlet_char_next(chi1, G) >= 0); acb_clear(res); dirichlet_char_clear(chi1); dirichlet_char_clear(chi2); dirichlet_group_clear(G); } TIMEIT_ONCE_STOP if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } } } flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/profile/p-thetanull.c000066400000000000000000000115261417376376500212070ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_dirichlet.h" static int usage(char *argv[]) { printf("usage: %s [--progress ] [--all] [--odd] [--prec ] [--onlymod] {qmin qmax | --value q a}\n", argv[0]); return 1; } static void value(ulong q, ulong a, slong prec, slong digits) { dirichlet_group_t G; dirichlet_char_t chi; acb_t res; arb_t one; dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_log(chi, G, a); acb_init(res); arb_init(one); arb_one(one); acb_dirichlet_theta_arb(res, G, chi, one, prec); acb_printd(res, digits); flint_printf("\n"); arb_clear(one); acb_clear(res); dirichlet_group_clear(G); dirichlet_char_clear(chi); } static void check_q(ulong q, int odd, slong prec, slong digits, int onlymod) { slong s; ulong k, len; dirichlet_group_t G; dirichlet_char_t x; dirichlet_group_init(G, q); dirichlet_char_init(x, G); acb_ptr theta, z; arb_t z1; arb_ptr t; theta = _acb_vec_init(G->phi_q); z = _acb_vec_init(G->phi_q); arb_init(z1); arb_const_pi(z1, prec); arb_div_ui(z1, z1, q, prec); arb_neg(z1, z1); arb_exp(z1, z1, prec); /* len = acb_dirichlet_theta_length_d(q, 1., prec); */ t = _arb_vec_init(q); acb_dirichlet_arb_quadratic_powers(t, q, z1, prec); for (s = 0; s <= odd; s++) { k = 0; dirichlet_char_one(x, G); do { acb_set_arb(z + k, t + x->n); k++; } while (dirichlet_char_next(x, G) >= 0); acb_dirichlet_dft_index(theta, z, G, prec); /* check zeros */ dirichlet_char_one(x, G); for (k = 0; k < G->phi_q; k++) { if (acb_contains_zero(theta + k) && dirichlet_conductor_char(G, x) == q && dirichlet_parity_char(G, x) == s) { if (onlymod) { flint_printf("%wu,%wu\n",q,x->n); } else { flint_printf("\ntheta null q = %wu, n = %wu\n",q, x->n); acb_printd(theta + k, digits); flint_printf("\n"); } } dirichlet_char_next(x, G); } if (odd) { /* change t for odd characters */ for (k = 0; k < q; k++) arb_mul_ui(t + k, t + k, k, prec); } } _arb_vec_clear(t, q); _acb_vec_clear(theta, G->phi_q); _acb_vec_clear(z, G->phi_q); arb_clear(z1); dirichlet_char_clear(x); dirichlet_group_clear(G); } int main(int argc, char *argv[]) { int i, all = 0, odd = 0, onlymod = 0, eval = 0; slong prec = 50, digits = 10; slong step = 0; ulong q, qmin, qmax; n_primes_t iter; if (argc < 3) return usage(argv); for (i = 1; i < argc - 2; i++) { if (!strcmp(argv[i],"--eval")) eval = 1; if (!strcmp(argv[i],"--all")) all = 1; if (!strcmp(argv[i],"--onlymod")) onlymod = 1; else if (!strcmp(argv[i],"--odd")) odd = 1; else if (!strcmp(argv[i],"--progress")) { i++; step = atol(argv[i]); } else if (!strcmp(argv[i],"--prec")) { i++; prec = atol(argv[i]); digits = floor(prec * 0.3); } } if (argc < i + 2) return usage(argv); qmin = atol(argv[i]); qmax = atol(argv[i+1]); if (eval) { value(qmin, qmax, prec, digits); } else { if (all) { for (q = qmin; q <= qmax; q++) { if (q % 4 == 2) continue; check_q(q, odd, prec, digits, onlymod); if (step && q % step == 0) flint_printf("[%wu]",q); } } else { ulong p; slong it = 0; /* look for vanishing theta values for prime power moduli */ n_primes_init(iter); while ((p = n_primes_next(iter)) < qmax) { for (q = p; q < qmin; q*= p); for (; q < qmax; q *= p) check_q(q, odd, prec, digits, onlymod); if (step && (it++ % step == 0)) flint_printf("[%wu]",p); } n_primes_clear(iter); } } flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/profile/p-vec.c000066400000000000000000000122121417376376500177550ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_dirichlet.h" #include "flint/profiler.h" #define LOG 0 #define CSV 1 #define JSON 2 typedef void (*do_f) (ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv); static void do_empty(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv) { return; } static void do_dlog_primeloop(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv) { slong k, l; nmod_t order; nmod_init(&order, dirichlet_order_char(G, chi)); for (k = 0; k < nv; k++) v[k] = 0; for (l = G->neven; l < G->num; l++) { dirichlet_prime_group_struct P = G->P[l]; dlog_vec_loop_add(v, nv, P.g, chi->log[l], P.pe, P.phi.n, order); } dirichlet_vec_set_null(v, G, nv); } static void do_eratos(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv) { slong k, p, pmax; nmod_t order; n_primes_t iter; n_primes_init(iter); nmod_init(&order, dirichlet_order_char(G, chi)); pmax = (nv < G->q) ? nv : G->q; v[1] = 0; while ((p = n_primes_next(iter)) < pmax) { if (G->q % p == 0) { for (k = p; k < nv; k += p) v[k] = DIRICHLET_CHI_NULL; } else { long chip; chip = dirichlet_chi(G, chi, p); for (k = p; k < nv; k += p) if (v[k] != -1) v[k] = nmod_add(v[k], chip, order); } } n_primes_clear(iter); } int main(int argc, char *argv[]) { int out; ulong n, nref, maxq = 5000; ulong * rand; flint_rand_t state; slong r, nr; int l, nf = 9; do_f func[9] = { do_empty, dirichlet_chi_vec_loop, do_dlog_primeloop, dirichlet_chi_vec_primeloop, do_eratos, dirichlet_chi_vec, dirichlet_chi_vec, dirichlet_chi_vec, dirichlet_chi_vec }; char * name[9] = { "char only", "big loop", "prime loops", "prime dlog_vec", "manual eratos", "default", "precomp 1", "precomp 20", "precomp 100" }; int i, ni = 5; ulong qmin[5] = { 2, 1000, 3000, 10000, 100000 }; ulong qmax[5] = { 500, 2000, 5000, 12000, 100500 }; int j, nj = 3; slong nv[3] = { 50, 300, 2000 }; nr = 20; flint_randinit(state); rand = flint_malloc(nr * sizeof(ulong)); for (r = 0; r < nr; r++) rand[r] = n_randprime(state, 42, 0); if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } if (out == CSV) flint_printf("# %-12s, %7s, %7s, %7s, %7s\n","name", "num", "qmin", "qmax", "time"); for (j = 0; j < nj; j++) { ulong * v; v = flint_malloc(nv[j] * sizeof(ulong)); for (i = 0; i < ni; i++) { if (out == LOG) flint_printf("%wu * ui_chi(rand, 1..%wu) for all %wu <= q <= %wu....\n", nr, nv[j], qmin[i], qmax[i]); for (l = 0; l < nf; l++) { ulong q; /* eratos too slow */ if (l == 4 && i > 2) continue; if (out == LOG) flint_printf("%-14s ... ", name[l]); else if (out == CSV) flint_printf("%-12s, %7d, %7d, %7d, ", name[l], nv[j], qmin[i], qmax[i]); else if (out == JSON) flint_printf("{ \"name\": \"%s\", \"num\": %d, \"qmin\": %d, \"qmax\": %d, \"time\": ", name[l], nv[j], qmin[i], qmax[i]); TIMEIT_ONCE_START for (q = qmin[i]; q <= qmax[i]; q++) { dirichlet_group_t G; dirichlet_char_t chi; dirichlet_group_init(G, q); dirichlet_char_init(chi, G); if (l >= 6) dirichlet_group_dlog_precompute(G, (l == 6) ? 1 : (l==7) ? 20 : 100); for (r = 0; r < nr; r++) { dirichlet_char_log(chi, G, rand[r] % q); func[l](v, G, chi, nv[j]); } if (l >= 6) dirichlet_group_dlog_clear(G); dirichlet_char_clear(chi); dirichlet_group_clear(G); } TIMEIT_ONCE_STOP if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } } flint_free(v); } flint_free(rand); flint_randclear(state); flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/qseries_arb.c000066400000000000000000000017441417376376500176120ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* sum a_k x^(k^2), assume a[0] = 0 */ void acb_dirichlet_qseries_arb(acb_t res, acb_srcptr a, const arb_t x, slong len, slong prec) { slong k; arb_t xk2, dx, x2; arb_init(xk2); arb_init(dx); arb_init(x2); arb_set(dx, x); arb_set(xk2, dx); arb_mul(x2, dx, dx, prec); acb_mul_arb(res, a + 1, xk2, prec); /* TODO: reduce prec */ for (k = 2; k < len; k++) { arb_mul(dx, dx, x2, prec); arb_mul(xk2, xk2, dx, prec); acb_addmul_arb(res, a + k, xk2, prec); } arb_clear(xk2); arb_clear(x2); arb_clear(dx); } arb-2.22.1/acb_dirichlet/qseries_arb_powers.c000066400000000000000000000047761417376376500212210ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_qseries_arb_powers_naive(acb_t res, const arb_t x, int parity, const ulong *a, const acb_dirichlet_roots_t roots, slong len, slong prec) { slong k; arb_t xk2, dx, x2; acb_t zk; arb_init(xk2); arb_init(dx); arb_init(x2); acb_init(zk); arb_set(dx, x); arb_set(xk2, dx); arb_mul(x2, dx, dx, prec); acb_set_arb(res, xk2); /* TODO: reduce prec */ for (k = 2; k < len; k++) { arb_mul(dx, dx, x2, prec); arb_mul(xk2, xk2, dx, prec); if (a[k] != DIRICHLET_CHI_NULL) { acb_dirichlet_root(zk, roots, a[k], prec); if (parity) acb_mul_si(zk, zk, k, prec); acb_addmul_arb(res, zk, xk2, prec); } } arb_clear(xk2); arb_clear(x2); arb_clear(dx); acb_clear(zk); } /* small order, multiply by chi at the end */ void acb_dirichlet_qseries_arb_powers_smallorder(acb_t res, const arb_t x, int parity, const ulong *a, const acb_dirichlet_roots_t roots, slong len, slong prec) { slong k; ulong order = roots->order; arb_t xk2, kxk2, dx, x2; acb_ptr t; arb_init(xk2); arb_init(dx); arb_init(x2); arb_init(kxk2); arb_set(dx, x); arb_set(xk2, x); arb_mul(x2, x, x, prec); t = _acb_vec_init(order); _acb_vec_zero(t, order); arb_set(acb_realref(t + 0), xk2); /* TODO: reduce precision at each step */ for (k = 2; k < len; k++) { arb_mul(dx, dx, x2, prec); arb_mul(xk2, xk2, dx, prec); if (a[k] != DIRICHLET_CHI_NULL) { if (parity) { arb_mul_si(kxk2, xk2, k, prec); arb_add(acb_realref(t + a[k]), acb_realref(t + a[k]), kxk2, prec); } else { arb_add(acb_realref(t + a[k]), acb_realref(t + a[k]), xk2, prec); } } } /* now Horner */ acb_dirichlet_root(res, roots, 1, prec); _acb_poly_evaluate(res, t, order, res, prec); _acb_vec_clear(t, order); arb_clear(xk2); arb_clear(x2); arb_clear(dx); arb_clear(kxk2); } arb-2.22.1/acb_dirichlet/root.c000066400000000000000000000043041417376376500162710ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_root(acb_t z, const acb_dirichlet_roots_t t, ulong k, slong prec) { ulong n = t->order; int swap, flip, conjugate; slong wp; if (k > n) k %= n; swap = flip = conjugate = 0; if (k > n / 2) { conjugate = 1; k = n - k; } if (n % 2 == 0 && k > n / 4) { flip = 1; k = n / 2 - k; } if (n % 4 == 0 && k > n / 8) { swap = 1; k = n / 4 - k; } wp = prec + 6 + 2 * FLINT_BIT_COUNT(t->reduced_order); if (k == 0) { acb_one(z); } else if (t->depth == 0) { if (t->use_pow) { acb_pow_ui(z, t->z, k, wp); acb_set_round(z, z, prec); } else { ulong r; fmpq_t t; fmpq_init(t); r = n_gcd(n, 2 * k); /* no overflow since since k <= n / 2 */ fmpz_set_ui(fmpq_numref(t), (2 * k) / r); fmpz_set_ui(fmpq_denref(t), n / r); arb_sin_cos_pi_fmpq(acb_imagref(z), acb_realref(z), t, prec); fmpq_clear(t); } } else if (t->depth == 1) { acb_set_round(z, t->Z[0] + k, prec); } else { slong j; ulong r; r = k % t->size; k = k / t->size; acb_set(z, t->Z[0] + r); for (j = 1; j < t->depth && k != 0; j++) { r = k % t->size; k = k / t->size; acb_mul(z, z, t->Z[j] + r, wp); } if (k != 0) flint_abort(); acb_set_round(z, z, prec); } if (swap) arb_swap(acb_realref(z), acb_imagref(z)); if (flip) arb_neg(acb_realref(z), acb_realref(z)); if (conjugate) arb_neg(acb_imagref(z), acb_imagref(z)); } arb-2.22.1/acb_dirichlet/root_number.c000066400000000000000000000027301417376376500176420ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_root_number_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { arb_t x; acb_t eps; arb_init(x); arb_one(x); acb_dirichlet_theta_arb(res, G, chi, x, prec); acb_init(eps); acb_conj(eps, res); acb_div(res, res, eps, prec); if (dirichlet_char_is_real(G, chi)) arb_zero(acb_imagref(res)); arb_clear(x); acb_clear(eps); } void acb_dirichlet_root_number(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { if (dirichlet_conductor_char(G, chi) < G->q) { flint_printf("root number: need primitive character\n"); flint_abort(); } else if (G->num > 1) { acb_t iq; acb_init(iq); acb_dirichlet_gauss_sum_order2(iq, G, chi, prec); acb_dirichlet_gauss_sum(res, G, chi, prec); acb_div(res, res, iq, prec); acb_clear(iq); } else { acb_dirichlet_root_number_theta(res, G, chi, prec); } if (dirichlet_char_is_real(G, chi)) arb_zero(acb_imagref(res)); } arb-2.22.1/acb_dirichlet/roots_clear.c000066400000000000000000000011331417376376500176170ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_roots_clear(acb_dirichlet_roots_t t) { slong k; for (k = 0; k < t->depth; k++) _acb_vec_clear(t->Z[k], t->size + 1); flint_free(t->Z); acb_clear(t->z); } arb-2.22.1/acb_dirichlet/roots_init.c000066400000000000000000000055201417376376500175000ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_roots_init(acb_dirichlet_roots_t t, ulong order, slong num, slong prec) { slong k, size, depth, best_depth, wp; ulong reduced_order; double cost, best_cost; /* exploit 90 deg symmetries */ if (order % 4 == 0) reduced_order = order / 8 + 1; else if (order % 2 == 0) reduced_order = order / 4 + 1; else reduced_order = order / 2 + 1; wp = prec + 6 + 2 * FLINT_BIT_COUNT(reduced_order); t->order = order; t->reduced_order = reduced_order; t->use_pow = 0; if (reduced_order <= 2 || num <= 2) { depth = 0; size = 0; } else { /* At depth = d and reduced_order = n, for k evaluations we need about log_2(n) * k muls if d == 0 d * n^(1/d) + (d-1) * k muls if d > 0 */ best_cost = FLINT_BIT_COUNT(reduced_order) * (double) num; best_depth = 0; for (depth = 1; depth <= 4; depth++) { size = n_root(reduced_order, depth) + 1; /* limit memory usage */ if (depth * _acb_vec_estimate_allocated_bytes(size, wp) > 1e9) continue; cost = depth * (double) size + (depth - 1) * (double) num; if (cost < best_cost) { best_depth = depth; best_cost = cost; } } depth = best_depth; size = n_root(reduced_order, depth) + 1; } t->size = size; t->depth = depth; acb_init(t->z); if (depth != 0) { acb_struct * z; acb_unit_root(t->z, order, wp); z = t->z; t->Z = flint_malloc(depth * sizeof(acb_ptr)); /* todo: at the last level, we could avoid computing entries that will never be reached */ for (k = 0; k < depth; k++) { t->Z[k] = _acb_vec_init(size + 1); _acb_vec_set_powers(t->Z[k], z, size + 1, wp); z = t->Z[k] + size; } } else { /* this tuning could be improved */ if (reduced_order < 30) t->use_pow = 1; else if (reduced_order < 100) t->use_pow = (prec >= 512); else if (reduced_order < 10000) t->use_pow = (prec >= 4096); else t->use_pow = (prec >= 16384); if (t->use_pow) acb_unit_root(t->z, order, wp); t->Z = NULL; } } arb-2.22.1/acb_dirichlet/si_poly_evaluate.c000066400000000000000000000025701417376376500206550ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* bsgs evaluation */ void acb_dirichlet_si_poly_evaluate(acb_t res, slong * v, slong len, const acb_t z, slong prec) { slong k, r, m; acb_t sq; acb_ptr zk; if (len < 3) { if (len == 0) { acb_zero(res); } else if (len == 1) { acb_set_si(res, v[0]); } else if (len == 2) { acb_mul_si(res, z, v[1], prec); acb_add_si(res, res, v[0], prec); } return; } m = n_sqrt(len) + 1; zk = _acb_vec_init(m + 1); _acb_vec_set_powers(zk, z, m + 1, prec); acb_init(sq); acb_zero(res); k = len - 1; r = k % m; for (; k >= 0; r = m - 1) { acb_zero(sq); for (; r >= 0; r--, k--) acb_addmul_si(sq, zk + r, v[k], prec); acb_mul(res, res, zk + m, prec); acb_add(res, res, sq, prec); } _acb_vec_clear(zk, m + 1); acb_clear(sq); } arb-2.22.1/acb_dirichlet/stieltjes.c000066400000000000000000000417121417376376500173200ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "flint/double_extras.h" #include "acb_dirichlet.h" #include "acb_calc.h" /* Bound the quadratic Taylor error term. */ static void stieltjes_bound_quadratic_term(arb_t B, const acb_t z, const fmpz_t n1, const acb_t alpha, slong prec) { acb_t t, log_t; mag_t b, c, d; acb_init(t); acb_init(log_t); mag_init(b); mag_init(c); mag_init(d); /* g''(z) = (n+1)(1+1/log(t)) / (t^2 log(t)) */ /* t = alpha + iz, log_t = log(t) */ acb_mul_onei(t, z); acb_add(t, t, alpha, prec); acb_log(log_t, t, prec); acb_get_mag_lower(b, t); acb_get_mag_lower(c, log_t); /* d = 1+1/log(t) */ mag_inv(d, c); mag_add_ui(d, d, 1); /* divide by t^2 log(t) */ mag_div(d, d, b); mag_div(d, d, b); mag_div(d, d, c); mag_mul_fmpz(d, d, n1); /* For Taylor remainder: 1/2 rad(z)^2 */ mag_hypot(b, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); mag_mul(b, b, b); mag_mul_2exp_si(b, b, -1); mag_mul(d, d, b); arf_set_mag(arb_midref(B), d); mag_zero(arb_radref(B)); acb_clear(t); acb_clear(log_t); mag_clear(b); mag_clear(c); mag_clear(d); } static void stieltjes_bound_large3(arb_t B, const acb_t x, const fmpz_t n1, const acb_t alpha, slong prec) { acb_t m, t, log_t, u, v; acb_t g0, g1, g2; mag_t C, D; acb_init(m); acb_init(t); acb_init(log_t); acb_init(u); acb_init(v); acb_init(g0); acb_init(g1); acb_init(g2); mag_init(C); mag_init(D); /* m = mid(x) */ acb_set(m, x); mag_zero(arb_radref(acb_realref(m))); mag_zero(arb_radref(acb_imagref(m))); /* t = alpha + im */ acb_mul_onei(t, m); acb_add(t, t, alpha, prec); /* log_t = log(alpha+im) */ acb_log(log_t, t, prec); /* u = x - m */ acb_sub(u, x, m, prec); acb_get_mag(D, u); /* g0 = g(m) = (n+1) log(log(alpha+im)) - 2 pi m */ acb_log(g0, log_t, prec); acb_mul_fmpz(g0, g0, n1, prec); acb_const_pi(v, prec); acb_mul(v, v, m, prec); acb_mul_2exp_si(v, v, 1); acb_sub(g0, g0, v, prec); /* g1 = g'(m) (x-m); g'(m) = i(n+1)/((alpha+im) log(alpha+im)) - 2 pi */ acb_mul(g1, t, log_t, prec); acb_inv(g1, g1, prec); acb_mul_fmpz(g1, g1, n1, prec); acb_mul_onei(g1, g1); acb_const_pi(t, prec); /* recycle t */ acb_mul_2exp_si(t, t, 1); acb_sub(g1, g1, t, prec); acb_mul(g1, g1, u, prec); /* absolute value -- optional (does not seem to affect speed much) */ acb_abs(acb_realref(g1), g1, prec); arb_zero(acb_imagref(g1)); stieltjes_bound_quadratic_term(acb_realref(g2), x, n1, alpha, prec); acb_exp(g0, g0, prec); acb_exp(g1, g1, prec); acb_exp(g2, g2, prec); acb_get_mag(C, g0); acb_get_mag(D, g1); mag_mul(C, C, D); acb_get_mag(D, g2); mag_mul(C, C, D); mag_mul_ui(C, C, 5); arb_zero(B); arf_set_mag(arb_midref(B), C); acb_clear(m); acb_clear(t); acb_clear(log_t); acb_clear(u); acb_clear(v); mag_clear(C); mag_clear(D); acb_clear(g0); acb_clear(g1); acb_clear(g2); } static void stieltjes_bound_large(acb_t res, const acb_t x, const fmpz_t n1, const acb_t alpha, slong prec) { arb_t B; mag_t t; arb_init(B); mag_init(t); prec = FLINT_MIN(prec, 30 + fmpz_bits(n1)); stieltjes_bound_large3(B, x, n1, alpha, prec); arb_get_mag(t, B); acb_zero(res); arb_add_error_mag(acb_realref(res), t); arb_add_error_mag(acb_imagref(res), t); arb_clear(B); mag_clear(t); } static void stieltjes_integrand(acb_t res, const acb_t x, const fmpz_t n1, const acb_t alpha, int analytic, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_mul_onei(t, x); acb_add(t, t, alpha, prec); acb_set_ui(u, 5); /* check branch cut of logarithm */ if (arb_contains_zero(acb_imagref(t)) && !arb_is_positive(acb_realref(t))) { acb_indeterminate(res); } else if ((analytic || acb_rel_accuracy_bits(t) < prec - 10) && arb_gt(acb_realref(x), acb_realref(u))) { /* note: requires re(x) > 1 */ stieltjes_bound_large(res, x, n1, alpha, prec); } else { acb_const_pi(u, prec); acb_mul(u, u, x, prec); acb_sech(u, u, prec); if (acb_is_finite(u)) { acb_mul(u, u, u, prec); acb_log(t, t, prec); acb_pow_fmpz(t, t, n1, prec); acb_mul(res, t, u, prec); } else { acb_indeterminate(res); } } acb_clear(t); acb_clear(u); } typedef struct { const fmpz * n1; const acb_struct * alpha; } _stieltjes_param; /* Compute the approximate saddle point. */ static void stieltjes_omega(acb_t omega, const fmpz_t n1, const acb_t alpha, slong prec) { acb_t t, u; fmpz_t k; acb_init(t); acb_init(u); fmpz_init(k); /* u = (n+1)i / (2pi) */ arb_set_fmpz(acb_imagref(t), n1); acb_const_pi(u, prec); acb_mul_2exp_si(u, u, 1); acb_div(u, t, u, prec); /* u / W(u) */ acb_lambertw(t, u, k, 0, prec); acb_div(t, u, t, prec); acb_sub(t, alpha, t, prec); acb_mul_onei(t, t); acb_set(omega, t); acb_clear(t); acb_clear(u); fmpz_clear(k); } /* Compute an approximation of the magnitude of gamma_n. */ static void stieltjes_mag_approx(arb_t C, mag_t tol, const fmpz_t n1, const acb_t alpha) { slong prec; acb_t w, v, q; prec = 32 + 2 * fmpz_bits(n1); acb_init(w); acb_init(v); acb_init(q); stieltjes_omega(w, n1, alpha, prec); stieltjes_integrand(v, w, n1, alpha, 0, prec); acb_set_fmpz(q, n1); acb_sqrt(q, q, prec); acb_mul(v, v, q, prec); acb_get_mag(tol, v); arb_set(C, acb_imagref(w)); mag_zero(arb_radref(C)); acb_clear(w); acb_clear(v); acb_clear(q); } int _f_stieltjes(acb_ptr res, const acb_t x, void * param, slong order, slong prec) { const fmpz * n1; const acb_struct * alpha; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ n1 = ((const _stieltjes_param *) param)->n1; alpha = ((const _stieltjes_param *) param)->alpha; stieltjes_integrand(res, x, n1, alpha, order != 0, prec); return 0; } /* Estimate log2(|gamma_n|), for fast cancellation estimate when n is small. */ static double stieltjes_mag(double n) { double u, v, A, B; double va, vb, t; double pi = 3.141592653589793; int i; if (n <= 1.0) return 0.0; va = 1e-6; vb = 0.5 * pi - 1e-6; for (i = 0; i < 53; i++) /* bisection */ { v = (va + vb) * 0.5; t = 2 * pi * exp(v * tan(v)) - n * cos(v) / v; if (t < 0.0) va = v; else vb = v; } v = va; u = v * tan(v); A = 0.5 * log(u * u + v * v) - u / (u * u + v * v); B = 2 * sqrt(2 * pi) * sqrt(u * u + v * v) * pow((u + 1) * (u + 1) + v * v, -0.25); t = (log(B) + n * A - 0.5 * log(n)) / log(2); return t; } static double _d_approx_hypot(double x, double y) { return sqrt(x * x + y * y); } /* log2 magnitude of integrand at z = x+yi; alpha = a+bi */ static double integrand_mag(double n, double x, double y, double a, double b) { double t, u; t = log(_d_approx_hypot(a - y, b + x)); u = atan2(b + x, a - y); t = log(_d_approx_hypot(t,u)) * (n+1) - 2.0 * 3.1415926535897932 * x; return t * 1.44269504088896341; } static double find_x_maximizing_mag(double n, double y) { double xa, xb, xma, xmb, ma, mb; int i; xa = 1.0; xb = n; for (i = 0; i < 80; i++) { xma = xa + (xb - xa) / 3; xmb = xb - (xb - xa) / 3; ma = integrand_mag(n, xma, y, 0.5, 0.0); mb = integrand_mag(n, xmb, y, 0.5, 0.0); if (ma < mb) xa = xma; else xb = xmb; } return xa; } static void stieltjes_choose_N(arb_t N, const fmpz_t n1, const acb_t alpha, slong prec) { if (fmpz_bits(n1) < 30) { double nn, NN, aa, bb; nn = fmpz_get_d(n1) - 1.0; NN = FLINT_MAX(nn, 4); aa = arf_get_d(arb_midref(acb_realref(alpha)), ARF_RND_DOWN); bb = arf_get_d(arb_midref(acb_imagref(alpha)), ARF_RND_DOWN); while (integrand_mag(nn, NN, 0.0, aa, bb) > -prec - 20) { NN *= 2.0; if (NN > 1e30) break; } arb_set_d(N, NN); } else { /* todo: account for huge alpha? */ arb_set_fmpz(N, n1); } } static void stieltjes_tail_bound(mag_t bound, const arb_t N, const fmpz_t n1, const acb_t alpha) { slong prec; arb_t x, y, D; acb_t aNi, logaNi; mag_t t, u; prec = MAG_BITS + fmpz_bits(n1); arb_init(x); arb_init(y); arb_init(D); acb_init(aNi); acb_init(logaNi); mag_init(t); mag_init(u); /* alpha + Ni */ acb_set(aNi, alpha); arb_add(acb_imagref(aNi), acb_imagref(aNi), N, prec); /* log(alpha + Ni) */ acb_log(logaNi, aNi, prec); /* check (n+1)/(|alpha+Ni| log(alpha + Ni)|) < 2 */ acb_get_mag_lower(t, aNi); acb_get_mag_lower(u, logaNi); mag_mul_lower(t, t, u); mag_inv(t, t); mag_mul_fmpz(t, t, n1); /* also check N >= |im(alpha)| + 2 */ arb_abs(x, acb_imagref(alpha)); arb_add_ui(x, x, 2, prec); if (mag_cmp_2exp_si(t, 1) >= 0 || !arb_ge(N, x)) { mag_inf(bound); } else { /* exp(-2 pi N) */ arb_set(x, N); arb_mul_2exp_si(x, x, 1); arb_const_pi(y, prec); arb_mul(y, y, x, prec); arb_neg(y, y); arb_exp(y, y, prec); /* |log|^(n+1) */ acb_get_mag(t, logaNi); arf_set_mag(arb_midref(x), t); mag_zero(arb_radref(x)); arb_pow_fmpz(x, x, n1, prec); arb_mul(x, x, y, prec); arb_get_mag(bound, x); } arb_clear(x); arb_clear(y); arb_clear(D); acb_clear(aNi); acb_clear(logaNi); mag_clear(t); mag_clear(u); } void _acb_dirichlet_stieltjes_integral2(acb_t res, const fmpz_t n, const acb_t alpha, slong prec) { double gamma_mag, max_mag, cancellation, xa; fmpz_t n1; acb_t a, b, v, w; slong wp; mag_t tol, bound; acb_calc_integrate_opt_t opt; _stieltjes_param param; /* integration points */ arb_t M, N, C; /* required for the integral representation to be valid */ if (!arb_is_positive(acb_realref(alpha))) { acb_indeterminate(res); return; } fmpz_init(n1); arb_init(M); arb_init(N); arb_init(C); acb_init(a); acb_init(b); acb_init(v); acb_init(w); mag_init(tol); mag_init(bound); fmpz_add_ui(n1, n, 1); param.n1 = n1; param.alpha = alpha; arb_set_ui(M, 10); stieltjes_choose_N(N, n1, alpha, prec); stieltjes_tail_bound(bound, N, n1, alpha); if (acb_is_real(alpha) && arf_cmpabs_2exp_si(arb_midref(acb_realref(alpha)), 2) < 0 && fmpz_cmp_ui(n1, 5000) < 0) { double nn = fmpz_get_ui(n1) - 1; gamma_mag = stieltjes_mag(nn); xa = find_x_maximizing_mag(nn, 0.0); max_mag = integrand_mag(nn, xa, 0.0, 0.5, 0.0); cancellation = FLINT_MAX(0, max_mag - gamma_mag); if (cancellation < 10 + 0.1 * prec) { arb_zero(C); mag_one(tol); mag_mul_2exp_si(tol, tol, gamma_mag); } else { stieltjes_mag_approx(C, tol, n1, alpha); cancellation = 0; } } else { stieltjes_mag_approx(C, tol, n1, alpha); cancellation = 0; } mag_mul_2exp_si(tol, tol, -prec - 5); /* todo: 1 * fmpz_bits(n1) should be enough, but acb powering is inaccurate */ wp = prec + 2 * fmpz_bits(n1) + cancellation + 10; acb_calc_integrate_opt_init(opt); /* opt->verbose = 1; */ opt->deg_limit = 100 + 1.2 * prec; /* Small speedup. */ if (arb_is_zero(C)) { acb_zero(a); acb_set_arb(b, N); acb_calc_integrate(w, _f_stieltjes, ¶m, a, b, wp, tol, opt, wp); acb_add(v, v, w, wp); } else { acb_zero(a); /* a = 0 */ acb_set_arb(b, M); /* b = M */ acb_calc_integrate(w, _f_stieltjes, ¶m, a, b, wp, tol, opt, wp); acb_add(v, v, w, wp); acb_set(a, b); acb_set_arb(b, M); arb_set(acb_imagref(b), C); /* b = M + i C */ acb_calc_integrate(w, _f_stieltjes, ¶m, a, b, wp, tol, opt, wp); acb_add(v, v, w, wp); acb_set(a, b); arb_set(acb_realref(b), N); /* b = N + i C */ acb_calc_integrate(w, _f_stieltjes, ¶m, a, b, wp, tol, opt, wp); acb_add(v, v, w, wp); acb_set(a, b); arb_zero(acb_imagref(b)); /* b = N */ acb_calc_integrate(w, _f_stieltjes, ¶m, a, b, wp, tol, opt, wp); acb_add(v, v, w, wp); } acb_add_error_mag(v, bound); acb_const_pi(b, wp); acb_mul(v, v, b, wp); acb_div_fmpz(v, v, n1, wp); acb_neg(v, v); if (acb_is_real(alpha)) arb_zero(acb_imagref(v)); acb_set_round(res, v, prec); fmpz_clear(n1); acb_clear(a); acb_clear(b); acb_clear(v); acb_clear(w); mag_clear(tol); mag_clear(bound); arb_clear(M); arb_clear(N); arb_clear(C); } void _acb_dirichlet_stieltjes_integral(acb_t res, const fmpz_t n, const acb_t a, slong prec) { acb_t alpha; acb_init(alpha); /* alpha = a-1/2 */ acb_set_d(alpha, 0.5); acb_sub(alpha, a, alpha, prec); if (acb_is_real(a)) { acb_conj(alpha, alpha); _acb_dirichlet_stieltjes_integral2(res, n, alpha, prec); } else { acb_t r1, r2; acb_init(r1); acb_init(r2); _acb_dirichlet_stieltjes_integral2(r1, n, alpha, prec); acb_conj(alpha, alpha); _acb_dirichlet_stieltjes_integral2(r2, n, alpha, prec); acb_conj(r2, r2); acb_add(res, r1, r2, prec); acb_mul_2exp_si(res, res, -1); acb_clear(r1); acb_clear(r2); } acb_clear(alpha); } void acb_dirichlet_stieltjes_integral(acb_t res, const fmpz_t n, const acb_t a, slong prec) { /* the algorithm only works for re(a) > 1/2 */ if (arf_cmp_si(arb_midref(acb_realref(a)), 1) < 0) { slong k, m, wp; acb_t ak, t, s; if (arf_cmp_si(arb_midref(acb_realref(a)), -prec) < 0) { acb_indeterminate(res); return; } m = 1 - arf_get_si(arb_midref(acb_realref(a)), ARF_RND_FLOOR); acb_init(ak); acb_init(t); acb_init(s); wp = prec + 2 * fmpz_bits(n); for (k = 0; k < m; k++) { acb_add_si(ak, a, k, wp); acb_log(t, ak, wp); acb_pow_fmpz(t, t, n, wp); acb_div(t, t, ak, wp); acb_add(s, s, t, wp); } acb_add_si(ak, a, m, wp); _acb_dirichlet_stieltjes_integral(t, n, ak, prec); acb_add(res, s, t, prec); acb_clear(s); acb_clear(t); acb_clear(ak); } else { _acb_dirichlet_stieltjes_integral(res, n, a, prec); } } void acb_dirichlet_stieltjes_em(acb_t res, const fmpz_t n, const acb_t a, slong prec) { if (fmpz_cmp_ui(n, 10000) > 0) { acb_indeterminate(res); } else { slong nn, wp; acb_ptr z; acb_t s; nn = fmpz_get_ui(n); acb_init(s); z = _acb_vec_init(nn + 1); wp = prec * 1.05 + 2.2*nn + 10; /* todo: bogus */ /* todo: we don't want to compute all the coefficients */ acb_one(s); _acb_poly_zeta_cpx_series(z, s, a, 1, nn + 1, wp); arb_fac_ui(acb_realref(s), nn, prec + 10); acb_mul_arb(res, z + nn, acb_realref(s), prec); if (fmpz_is_odd(n)) acb_neg(res, res); acb_clear(s); _acb_vec_clear(z, nn + 1); } } void acb_dirichlet_stieltjes(acb_t res, const fmpz_t n, const acb_t a, slong prec) { slong cutoff; if (acb_is_one(a) && fmpz_is_zero(n)) { arb_const_euler(acb_realref(res), prec); arb_zero(acb_imagref(res)); return; } if (fmpz_sgn(n) < 0) { flint_printf("stieltjes constants only defined for n >= 0"); flint_abort(); } /* undefined at a = 0, -1, -2, ... */ if (acb_contains_int(a) && !arb_is_positive(acb_realref(a))) { acb_indeterminate(res); return; } cutoff = FLINT_MAX(100, prec / 2); cutoff = FLINT_MIN(cutoff, 10000); if (fmpz_cmp_ui(n, cutoff) >= 0) { acb_dirichlet_stieltjes_integral(res, n, a, prec); } else { acb_dirichlet_stieltjes_em(res, n, a, prec); } } arb-2.22.1/acb_dirichlet/test/000077500000000000000000000000001417376376500161205ustar00rootroot00000000000000arb-2.22.1/acb_dirichlet/test/t-backlund_s.c000066400000000000000000000032171417376376500206350ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("backlund_s...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); arb_init(a); arb_init(b); arb_init(c); arb_randtest(a, state, 1 + n_randint(state, 1000), 4); acb_dirichlet_backlund_s(b, a, prec1); if (n_randint(state, 2)) { acb_dirichlet_backlund_s(c, a, prec2); } else /* test aliasing */ { arb_set(c, a); acb_dirichlet_backlund_s(c, c, prec2); } if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-backlund_s_bound.c000066400000000000000000000036711417376376500220300ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("backlund_s_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { arb_t a, b; mag_t u, v; slong aprec, bprec; slong abits, bbits; aprec = 2 + n_randint(state, 1000); bprec = 2 + n_randint(state, 1000); abits = 2 + n_randint(state, 100); bbits = 2 + n_randint(state, 100); arb_init(a); arb_init(b); mag_init(u); mag_init(v); arb_randtest(a, state, aprec, abits); arb_randtest(b, state, bprec, bbits); if (arb_is_nonnegative(a) && arb_is_nonnegative(b)) { acb_dirichlet_backlund_s_bound(u, a); acb_dirichlet_backlund_s_bound(v, b); if ((arb_lt(a, b) && mag_cmp(u, v) > 0) || (arb_gt(a, b) && mag_cmp(u, v) < 0)) { flint_printf("FAIL: increasing on t >= 0\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("u = "); mag_print(u); flint_printf("\n\n"); flint_printf("v = "); mag_print(v); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(b); mag_clear(u); mag_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-backlund_s_gram.c000066400000000000000000000034651417376376500216500ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("backlund_s_gram...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 130 + 20 * arb_test_multiplier(); iter++) { arb_t t, x; fmpz_t n; slong S, prec1, prec2; arb_init(t); arb_init(x); fmpz_init(n); if (iter < 130) { fmpz_set_si(n, iter - 1); } else { fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 129); } prec1 = 2 + n_randtest(state) % 100; prec2 = 2 + n_randtest(state) % 100; S = acb_dirichlet_backlund_s_gram(n); acb_dirichlet_gram_point(t, n, NULL, NULL, prec1); acb_dirichlet_backlund_s(x, t, prec2); if (!arb_contains_si(x, S)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("S = %wd\n\n", S); flint_printf("t = "); arb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(t); arb_clear(x); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-chi.c000066400000000000000000000103521417376376500172710ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("chi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t zn1, zn2, zn1n2, zn1zn2; dirichlet_group_t G; dirichlet_char_t chi; ulong q, m, n1, n2, iter2; int res; q = 1 + n_randint(state, 1000); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); acb_init(zn1); acb_init(zn2); acb_init(zn1n2); acb_init(zn1zn2); /* check chi(n1) chi(n2) = chi(n1 n2) */ for (iter2 = 0; iter2 < 10; iter2++) { do { m = 1 + n_randint(state, q); } while (n_gcd(q, m) != 1); dirichlet_char_log(chi, G, m); n1 = n_randint(state, 1000); n2 = n_randint(state, 1000); acb_dirichlet_chi(zn1, G, chi, n1, 53); acb_dirichlet_pairing(zn2, G, m, n1, 53); if (!acb_overlaps(zn1, zn2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("n = %wu\n\n", n1); flint_printf("char = "); acb_printd(zn1, 15); flint_printf("\n\n"); flint_printf("pairing = "); acb_printd(zn2, 15); flint_printf("\n\n"); dirichlet_char_print(G, chi); dirichlet_char_log(chi, G, m); flint_printf("log(m) = "); dirichlet_char_print(G, chi); dirichlet_char_log(chi, G, n1); flint_printf("log(n1) = "); dirichlet_char_print(G, chi); flint_abort(); } acb_dirichlet_pairing(zn2, G, m, n2, 53); acb_dirichlet_pairing(zn1n2, G, m, n1 * n2, 53); acb_mul(zn1zn2, zn1, zn2, 53); if (!acb_overlaps(zn1n2, zn1zn2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("n1 = %wu\n\n", n1); flint_printf("n2 = %wu\n\n", n2); flint_printf("zn1 = "); acb_printd(zn1, 15); flint_printf("\n\n"); flint_printf("zn2 = "); acb_printd(zn2, 15); flint_printf("\n\n"); flint_printf("zn1n2 = "); acb_printd(zn1n2, 15); flint_printf("\n\n"); flint_printf("zn1zn2 = "); acb_printd(zn1zn2, 15); flint_printf("\n\n"); flint_abort(); } } if (iter % 10 == 0) { /* check orthogonality */ acb_zero(zn1); n1 = n_randint(state, 1000); for (m = 1; m <= q; m++) { if (n_gcd(q, m) == 1) { acb_dirichlet_pairing(zn2, G, m, n1, 53); acb_add(zn1, zn1, zn2, 53); } } if (n1 % q == 1 % q) res = arb_contains_si(acb_realref(zn1), n_euler_phi(q)) && arb_contains_zero(acb_imagref(zn1)); else res = acb_contains_zero(zn1); if (!res) { flint_printf("FAIL: orthogonality\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("phi = %wu\n\n", n_euler_phi(q)); flint_printf("n1 = %wu\n\n", n1); flint_printf("zn1 = "); acb_printd(zn1, 15); flint_printf("\n\n"); flint_abort(); } } dirichlet_group_clear(G); dirichlet_char_clear(chi); acb_clear(zn1); acb_clear(zn2); acb_clear(zn1n2); acb_clear(zn1zn2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-dft.c000066400000000000000000000071521417376376500173070ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" typedef void (*do_f) (acb_ptr w, acb_srcptr v, slong len, slong prec); void check_vec_eq_prec(acb_srcptr w1, acb_srcptr w2, slong len, slong prec, slong digits, ulong q, char f1[], char f2[]) { slong i; for (i = 0; i < len; i++) { if (!acb_overlaps(w1 + i, w2 + i)) { flint_printf("FAIL\n\n"); flint_printf("q = %wu, size = %wd\n", q, len); flint_printf("\nDFT differ from index %wd / %wd \n", i, len); flint_printf("\n%s =\n", f1); acb_vec_printd(w1, len, digits); flint_printf("\n%s =\n", f2); acb_vec_printd(w2, len, digits); flint_printf("\n\n"); abort(); } else if (acb_rel_accuracy_bits(w1 + i) < 30 || acb_rel_accuracy_bits(w2 + i) < 30) { flint_printf("FAIL\n\n"); flint_printf("q = %wu\n", q); flint_printf("\nDFT inaccurate from index %wd / %wd \n", i, len); flint_printf("\nnaive =\n"); acb_printd(w1 + i, digits); flint_printf("\nfast =\n"); acb_printd(w2 + i, digits); flint_printf("\nerrors %wd & %wd [prec = %wd]\n", acb_rel_accuracy_bits(w1 + i), acb_rel_accuracy_bits(w2 + i), prec); abort(); } } } int main() { slong k; slong prec = 100, digits = 30; slong nq = 13; ulong q[13] = { 2, 3, 4, 5, 6, 23, 10, 15, 30, 59, 308, 335, 961}; flint_rand_t state; flint_printf("dft...."); fflush(stdout); flint_randinit(state); /* Dirichlet group DFT */ for (k = 0; k < nq; k++) { slong i, j, len; dirichlet_group_t G; dirichlet_char_t x, y; acb_dirichlet_roots_t roots; acb_t chiy; acb_ptr v, w1, w2; dirichlet_group_init(G, q[k]); len = G->phi_q; v = _acb_vec_init(len); w1 = _acb_vec_init(len); w2 = _acb_vec_init(len); acb_init(chiy); acb_dirichlet_roots_init(roots, G->expo, len, prec); dirichlet_char_init(x, G); dirichlet_char_init(y, G); for (i = 0; i < len; i++) acb_randtest_precise(v + i, state, prec, 0); /* naive */ dirichlet_char_one(x, G); for (i = 0; i < len; i++) { acb_zero(w1 + i); dirichlet_char_one(y, G); for (j = 0; j < len; j++) { acb_dirichlet_root(chiy, roots, dirichlet_pairing_char(G, x, y), prec); acb_conj(chiy, chiy); acb_addmul(w1 + i, chiy, v + j, prec); dirichlet_char_next(y, G); } dirichlet_char_next(x, G); } /* dft */ acb_dirichlet_dft_index(w2, v, G, prec); check_vec_eq_prec(w1, w2, len, prec, digits, q[k], "naive", "group"); _acb_vec_clear(v, len); _acb_vec_clear(w1, len); _acb_vec_clear(w2, len); acb_dirichlet_roots_clear(roots); dirichlet_char_clear(x); dirichlet_char_clear(y); dirichlet_group_clear(G); acb_clear(chiy); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-eta.c000066400000000000000000000034661417376376500173070ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("eta...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { acb_t z1, z2, s1, s2; slong prec1, prec2; acb_init(z1); acb_init(z2); acb_init(s1); acb_init(s2); acb_randtest(s1, state, 2 + n_randint(state, 100), 3); acb_randtest(z1, state, 2 + n_randint(state, 100), 3); acb_randtest(z2, state, 2 + n_randint(state, 100), 3); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); acb_add(s2, s1, z1, prec2); acb_sub(s2, s2, z1, prec2); acb_dirichlet_eta(z1, s1, prec1); acb_dirichlet_eta(z2, s2, prec2); if (!acb_overlaps(z1, z2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("s1 = "); acb_printn(s1, 50, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 50, 0); flint_printf("\n\n"); flint_printf("z1 = "); acb_printn(z1, 50, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z1); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-euler_product_real_ui.c000066400000000000000000000074421417376376500231100ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" const signed char chi[8][6] = { {1, 1}, {2, 0, 1}, {3, 0, 1, 1}, {3, 0, 1, -1}, {4, 0, 1, 0, 1}, {4, 0, 1, 0, -1}, {5, 0, 1, 1, 1, 1}, {5, 0, 1, -1, -1, 1}, }; const double L10[8] = { 1.0009945751278180853371459589, 1.0000170413630448254881839023, 1.00097762319679253337038382667, 0.999024291448866695201196896346, 1.0000170413630448254881839023, 0.999983164026196877405540729958, 1.00099447262597359224857402038, 0.999007468458940084215357132419 }; int main() { slong iter; flint_rand_t state; flint_printf("euler_product_real_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { arb_t res1, res2; ulong s; slong prec1, prec2, accuracy; int choice, reciprocal1, reciprocal2; if (iter % 10 == 0) { s = n_randtest(state); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); } else { s = 6 + n_randint(state, 1 << n_randint(state, 12)); prec1 = 2 + n_randint(state, 12 * s); prec2 = 2 + n_randint(state, 12 * s); } if (n_randint(state, 30) == 0) prec1 = 2 + n_randint(state, 4000); choice = n_randint(state, 7); reciprocal1 = n_randint(state, 2); reciprocal2 = n_randint(state, 2); arb_init(res1); arb_init(res2); arb_randtest(res1, state, 200, 100); _acb_dirichlet_euler_product_real_ui(res1, s, chi[choice] + 1, chi[choice][0], reciprocal1, prec1); _acb_dirichlet_euler_product_real_ui(res2, s, chi[choice] + 1, chi[choice][0], reciprocal2, prec2); if (reciprocal1 != reciprocal2) arb_inv(res2, res2, prec2); if (!arb_overlaps(res1, res2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("s = %wu\n\n", s); flint_printf("chi: %d\n", choice); flint_printf("res1 = "); arb_printd(res1, prec1 / 3.33); flint_printf("\n\n"); flint_printf("res2 = "); arb_printd(res2, prec2 / 3.33); flint_printf("\n\n"); flint_abort(); } if (s >= 6 && prec1 < 2 * s * log(s)) { accuracy = arb_rel_accuracy_bits(res1); if (accuracy < prec1 - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec1); flint_printf("res1 = "); arb_printd(res1, prec1 / 3.33); flint_printf("\n\n"); flint_abort(); } } if (s == 10) { arf_set_d(arb_midref(res2), L10[choice]); mag_set_d(arb_radref(res2), 1e-15); if (reciprocal1) arb_inv(res2, res2, 53); if (!arb_overlaps(res1, res2)) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("s = %wu\n\n", s); flint_printf("chi: %d\n", choice); flint_printf("res1 = "); arb_printd(res1, prec1 / 3.33); flint_printf("\n\n"); flint_printf("res2 = "); arb_printd(res2, prec2 / 3.33); flint_printf("\n\n"); flint_abort(); } } arb_clear(res1); arb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-gauss.c000066400000000000000000000041251417376376500176510ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong prec = 128; ulong q; flint_printf("gauss...."); fflush(stdout); /* check Gauss sums */ for (q = 3; q < 250; q ++) { dirichlet_group_t G; dirichlet_char_t chi; acb_t s1, s2, s3, s4; dirichlet_group_init(G, q); dirichlet_char_init(chi, G); acb_init(s1); acb_init(s2); acb_init(s3); acb_init(s4); dirichlet_char_one(chi, G); while (1) { acb_dirichlet_gauss_sum_naive(s1, G, chi, prec); acb_dirichlet_gauss_sum(s2, G, chi, prec); acb_dirichlet_gauss_sum_factor(s3, G, chi, prec); if (dirichlet_conductor_char(G, chi) == G->q) acb_dirichlet_gauss_sum_theta(s4, G, chi, prec); else acb_set(s4, s1); if (!acb_overlaps(s1, s2) || !acb_overlaps(s1, s3) || !acb_overlaps(s1, s4)) { flint_printf("FAIL: G(chi_%wu(%wu))\n\n", q, chi->n); flint_printf("\nnaive "); acb_printd(s1, 25); flint_printf("\ndefault "); acb_printd(s2, 25); flint_printf("\nfactor "); acb_printd(s3, 25); flint_printf("\ntheta "); acb_printd(s4, 25); flint_abort(); } if (dirichlet_char_next(chi, G) < 0) break; } acb_clear(s1); acb_clear(s2); acb_clear(s3); acb_clear(s4); dirichlet_group_clear(G); dirichlet_char_clear(chi); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-gram_point.c000066400000000000000000000057441417376376500206760ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("gram_point...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x1, x2, v1, v2, pin; acb_t t; fmpz_t n; slong prec1, prec2; arb_init(x1); arb_init(x2); arb_init(v1); arb_init(v2); arb_init(pin); acb_init(t); fmpz_init(n); fmpz_randtest_unsigned(n, state, 500); fmpz_sub_ui(n, n, 1); prec1 = 2 + n_randtest(state) % 500; prec2 = 2 + n_randtest(state) % 2000; acb_dirichlet_gram_point(x1, n, NULL, NULL, prec1); acb_dirichlet_gram_point(x2, n, NULL, NULL, prec2); arb_const_pi(pin, FLINT_MAX(prec1, prec2) + 20); arb_mul_fmpz(pin, pin, n, FLINT_MAX(prec1, prec2) + 20); acb_set_arb(t, x1); acb_dirichlet_hardy_theta(t, t, NULL, NULL, 1, prec1 + 20); arb_set(v1, acb_realref(t)); acb_set_arb(t, x2); acb_dirichlet_hardy_theta(t, t, NULL, NULL, 1, prec2 + 20); arb_set(v2, acb_realref(t)); if (!arb_overlaps(x1, x2) || !arb_contains(v1, pin) || !arb_contains(v2, pin)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_printf("v1 = "); arb_printn(v1, 100, 0); flint_printf("\n\n"); flint_printf("v2 = "); arb_printn(v2, 100, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(x1) < prec1 - 3 || arb_rel_accuracy_bits(x2) < prec2 - 3) { flint_printf("FAIL: accuracy\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("acc(x1) = %wd, acc(x2) = %wd\n\n", arb_rel_accuracy_bits(x1), arb_rel_accuracy_bits(x2)); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x1); arb_clear(x2); arb_clear(v1); arb_clear(v2); arb_clear(pin); acb_clear(t); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-hardy_theta_series.c000066400000000000000000000046051417376376500224000ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("hardy_theta_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; dirichlet_group_t G; dirichlet_char_t chi; ulong q; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 8); n1 = 1 + n_randint(state, 8); n2 = 1 + n_randint(state, 8); do { q = 1 + n_randint(state, 15); } while (q % 4 == 2); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); do { dirichlet_char_index(chi, G, n_randint(state, G->phi_q)); } while (!dirichlet_char_is_primitive(G, chi)); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 3); acb_dirichlet_hardy_theta_series(A, S, G, chi, n1, bits2); acb_poly_set(B, S); /* aliasing */ acb_dirichlet_hardy_theta_series(B, B, G, chi, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); dirichlet_char_clear(chi); dirichlet_group_clear(G); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-hardy_z.c000066400000000000000000000074031417376376500201710ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("hardy_z...."); fflush(stdout); flint_randinit(state); /* test self-consistency */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t s, s2; dirichlet_group_t G; dirichlet_char_t chi; acb_ptr vec1, vec2; slong len1, len2; slong prec1, prec2; ulong q, k; slong i; len1 = n_randint(state, 6); len2 = n_randint(state, 6); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); do { q = 1 + n_randint(state, 30); } while (q % 4 == 2); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); do { k = n_randint(state, n_euler_phi(q)); dirichlet_char_index(chi, G, k); } while (dirichlet_conductor_char(G, chi) != q); acb_init(s); acb_init(s2); vec1 = _acb_vec_init(len1); vec2 = _acb_vec_init(len2); acb_randtest(s, state, 2 + n_randint(state, 200), 2); acb_randtest(s2, state, 2 + n_randint(state, 200), 2); acb_sub(s2, s2, s2, 200); acb_add(s2, s, s2, 200); acb_dirichlet_hardy_z(vec1, s, G, chi, len1, prec1); acb_dirichlet_hardy_z(vec2, s2, G, chi, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(vec1 + i, vec2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd q = %wu k = %wu i = %wd\n\n", iter, q, k, i); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); acb_printn(vec1 + i, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); acb_printn(vec2 + i, 50, 0); flint_printf("\n\n"); flint_abort(); } } if (arb_contains_zero(acb_imagref(s))) { for (i = 0; i < len1; i++) { if (!arb_contains_zero(acb_imagref(vec1 + i))) { flint_printf("FAIL: real 1\n\n"); flint_printf("iter = %wd q = %wu k = %wu i = %wd\n\n", iter, q, k, i); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); acb_printn(vec1 + i, 50, 0); flint_printf("\n\n"); flint_abort(); } } } if (arb_contains_zero(acb_imagref(s2))) { for (i = 0; i < len2; i++) { if (!arb_contains_zero(acb_imagref(vec2 + i))) { flint_printf("FAIL: real 1\n\n"); flint_printf("iter = %wd q = %wu k = %wu i = %wd\n\n", iter, q, k, i); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); acb_printn(vec2 + i, 50, 0); flint_printf("\n\n"); flint_abort(); } } } dirichlet_char_clear(chi); dirichlet_group_clear(G); acb_clear(s); acb_clear(s2); _acb_vec_clear(vec1, len1); _acb_vec_clear(vec2, len2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-hardy_z_series.c000066400000000000000000000047041417376376500215440ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("hardy_z_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; dirichlet_group_t G; dirichlet_char_t chi; ulong q; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 8); n1 = 1 + n_randint(state, 8); n2 = 1 + n_randint(state, 8); do { q = 1 + n_randint(state, 15); } while (q % 4 == 2); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); do { dirichlet_char_index(chi, G, n_randint(state, G->phi_q)); } while (!dirichlet_char_is_primitive(G, chi)); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 3); acb_dirichlet_hardy_z_series(A, S, G, chi, n1, bits2); acb_poly_set(B, S); /* aliasing */ if (q == 1 && n_randint(state, 2)) acb_poly_neg(B, B); acb_dirichlet_hardy_z_series(B, B, G, chi, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); dirichlet_char_clear(chi); dirichlet_group_clear(G); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-hardy_z_zero.c000066400000000000000000000054241417376376500212310ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("hardy_z_zero...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 20 * arb_test_multiplier(); iter++) { arb_t x1, x2, v1, v2; acb_t t; fmpz_t n; slong prec1, prec2; arb_init(x1); arb_init(x2); arb_init(v1); arb_init(v2); acb_init(t); fmpz_init(n); fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 1); prec1 = 2 + n_randtest(state) % 50; prec2 = 2 + n_randtest(state) % 200; acb_dirichlet_hardy_z_zero(x1, n, prec1); acb_dirichlet_hardy_z_zero(x2, n, prec2); acb_set_arb(t, x1); acb_dirichlet_hardy_z(t, t, NULL, NULL, 1, prec1 + 20); arb_set(v1, acb_realref(t)); acb_set_arb(t, x2); acb_dirichlet_hardy_z(t, t, NULL, NULL, 1, prec2 + 20); arb_set(v2, acb_realref(t)); if (!arb_overlaps(x1, x2) || !arb_contains_zero(v1) || !arb_contains_zero(v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_printf("v1 = "); arb_printn(v1, 100, 0); flint_printf("\n\n"); flint_printf("v2 = "); arb_printn(v2, 100, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(x1) < prec1 - 3 || arb_rel_accuracy_bits(x2) < prec2 - 3) { flint_printf("FAIL: accuracy\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("acc(x1) = %wd, acc(x2) = %wd\n\n", arb_rel_accuracy_bits(x1), arb_rel_accuracy_bits(x2)); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x1); arb_clear(x2); arb_clear(v1); arb_clear(v2); acb_clear(t); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-hardy_z_zeros.c000066400000000000000000000061431417376376500214130ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("hardy_z_zeros...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 20 * arb_test_multiplier(); iter++) { arb_t x1, x2, v1, v2; acb_t t; fmpz_t n, k; slong prec1, prec2; slong len, i; const slong maxlen = 5; arb_ptr p; arb_init(x1); arb_init(x2); arb_init(v1); arb_init(v2); acb_init(t); fmpz_init(n); fmpz_init(k); p = _arb_vec_init(maxlen); fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 1); prec1 = 2 + n_randtest(state) % 50; prec2 = 2 + n_randtest(state) % 200; len = 1 + n_randint(state, maxlen); i = n_randint(state, len); acb_dirichlet_hardy_z_zeros(p, n, len, prec1); arb_set(x1, p + i); fmpz_add_si(k, n, i); acb_dirichlet_hardy_z_zero(x2, k, prec2); acb_set_arb(t, x1); acb_dirichlet_hardy_z(t, t, NULL, NULL, 1, prec1 + 20); arb_set(v1, acb_realref(t)); acb_set_arb(t, x2); acb_dirichlet_hardy_z(t, t, NULL, NULL, 1, prec2 + 20); arb_set(v2, acb_realref(t)); if (!arb_overlaps(x1, x2) || !arb_contains_zero(v1) || !arb_contains_zero(v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_printf("v1 = "); arb_printn(v1, 100, 0); flint_printf("\n\n"); flint_printf("v2 = "); arb_printn(v2, 100, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(x1) < prec1 - 3 || arb_rel_accuracy_bits(x2) < prec2 - 3) { flint_printf("FAIL: accuracy\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("acc(x1) = %wd, acc(x2) = %wd\n\n", arb_rel_accuracy_bits(x1), arb_rel_accuracy_bits(x2)); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x1); arb_clear(x2); arb_clear(v1); arb_clear(v2); acb_clear(t); fmpz_clear(n); fmpz_clear(k); _arb_vec_clear(p, maxlen); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-hurwitz.c000066400000000000000000000046761417376376500202560ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("hurwitz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t s, a, b, z1, z2; slong prec1, prec2; acb_init(s); acb_init(a); acb_init(b); acb_init(z1); acb_init(z2); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); acb_randtest(s, state, 1 + n_randint(state, 500), 3); acb_randtest(a, state, 1 + n_randint(state, 500), 3); acb_randtest(b, state, 1 + n_randint(state, 500), 10); acb_randtest(z1, state, 1 + n_randint(state, 500), 10); acb_randtest(z2, state, 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) acb_set_si(a, n_randint(state, 100) - 50); if (n_randint(state, 2)) acb_set_si(s, n_randint(state, 100) - 50); /* test zeta(s,a) = 2^(-s) (zeta(s,a/2) + zeta(s,(a+1)/2)) */ acb_mul_2exp_si(b, a, -1); acb_dirichlet_hurwitz(z2, s, b, prec2); acb_add_ui(b, a, 1, prec2); acb_mul_2exp_si(b, b, -1); acb_dirichlet_hurwitz(b, s, b, prec2); acb_add(z2, z2, b, prec2); acb_neg(b, s); acb_set_ui(z1, 2); acb_pow(b, z1, b, prec2); acb_mul(z2, z2, b, prec2); acb_dirichlet_hurwitz(z1, s, a, prec1); if (!acb_overlaps(z1, z2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(s); acb_clear(a); acb_clear(b); acb_clear(z1); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-hurwitz_precomp.c000066400000000000000000000047001417376376500217670ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("hurwitz_precomp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_t s, a, z1, z2; ulong p, q; slong prec1, prec2, A, K, N, i; acb_dirichlet_hurwitz_precomp_t pre; int deflate; prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); A = 1 + n_randint(state, 10); K = 1 + n_randint(state, 10); N = 1 + n_randint(state, 10); deflate = (n_randint(state, 3) == 0); acb_init(s); acb_init(a); acb_init(z1); acb_init(z2); acb_randtest(s, state, 1 + n_randint(state, 200), 2); acb_dirichlet_hurwitz_precomp_init(pre, s, deflate, A, K, N, prec1); for (i = 0; i < 10; i++) { q = 1 + n_randint(state, 1000); p = 1 + n_randint(state, q); acb_dirichlet_hurwitz_precomp_eval(z1, pre, p, q, prec1); acb_set_ui(a, p); acb_div_ui(a, a, q, prec2); if (deflate) _acb_poly_zeta_cpx_series(z2, s, a, 1, 1, prec2); else acb_hurwitz_zeta(z2, s, a, prec2); if (!acb_overlaps(z1, z2)) { flint_printf("FAIL! (overlap)"); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("A = %wd K = %wd N = %wd\n\n", A, K, N); flint_printf("p = %wu q = %wu\n\n", p, q); flint_printf("z1 = "); acb_printn(z1, 50, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 50, 0); flint_printf("\n\n"); flint_abort(); } } acb_dirichlet_hurwitz_precomp_clear(pre); acb_clear(s); acb_clear(a); acb_clear(z1); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-isolate_hardy_z_zero.c000066400000000000000000000052171417376376500227510ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _check_interval(const arf_t a, const arf_t b, const fmpz_t n) { arb_t v; int sa, sb; slong prec = arf_bits(b) + 8; arb_init(v); if (arf_cmp(a, b) >= 0) { flint_printf("FAIL: interval endpoint ordering\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_abort(); } sa = _acb_dirichlet_definite_hardy_z(v, a, &prec); sb = _acb_dirichlet_definite_hardy_z(v, b, &prec); if (sa == sb) { flint_printf("FAIL: interval endpoint function signs\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("sa = %d\n\n", sa); flint_printf("sb = %d\n\n", sb); flint_abort(); } arb_clear(v); } int main() { slong iter; flint_rand_t state; flint_printf("isolate_hardy_z_zero...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 126 + 20 * arb_test_multiplier(); iter++) { arf_t a, b; fmpz_t n; arf_init(a); arf_init(b); fmpz_init(n); if (iter < 126) { fmpz_set_si(n, iter + 1); } else { fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 127); } acb_dirichlet_isolate_hardy_z_zero(a, b, n); _check_interval(a, b, n); if (fmpz_cmp_si(n, 126) <= 0) { _acb_dirichlet_isolate_gram_hardy_z_zero(a, b, n); _check_interval(a, b, n); } if (fmpz_cmp_si(n, 13999526) <= 0) { _acb_dirichlet_isolate_rosser_hardy_z_zero(a, b, n); _check_interval(a, b, n); } if (fmpz_cmp_si(n, 2) >= 0) { _acb_dirichlet_isolate_turing_hardy_z_zero(a, b, n); _check_interval(a, b, n); } arf_clear(a); arf_clear(b); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-jacobi.c000066400000000000000000000044471417376376500177650ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong prec = 128; ulong q; flint_printf("jacobi...."); fflush(stdout); /* check Jacobi sums */ for (q = 29 * 29; q > 1; q = q%2 ? 3*q+1 : q/2) { slong m1, m2; dirichlet_group_t G; dirichlet_char_t chi1, chi2; acb_t s1, s2; dirichlet_group_init(G, q); dirichlet_char_init(chi1, G); dirichlet_char_init(chi2, G); acb_init(s1); acb_init(s2); dirichlet_char_one(chi1, G); for (m1 = 0; m1 < 50; m1++) { dirichlet_char_one(chi2, G); for (m2 = 0; m2 < 50; m2++) { acb_dirichlet_jacobi_sum_naive(s1, G, chi1, chi2, prec); acb_dirichlet_jacobi_sum(s2, G, chi1, chi2, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL: J_%wu(%wu,%wu)", q, chi1->n, chi2->n); flint_printf("\nnaive "); acb_printd(s1, 25); flint_printf("\ndefault "); acb_printd(s2, 25); flint_printf("\n"); flint_printf("cond = %wu, %wu, %wu\n", dirichlet_conductor_char(G, chi1), dirichlet_conductor_char(G, chi2), dirichlet_conductor_ui(G, nmod_mul(chi1->n, chi2->n, G->mod)) ); flint_abort(); } if (dirichlet_char_next(chi2, G) < 0) break; } if (dirichlet_char_next(chi1, G) < 0) break; } acb_clear(s1); acb_clear(s2); dirichlet_group_clear(G); dirichlet_char_clear(chi1); dirichlet_char_clear(chi2); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l.c000066400000000000000000000037361417376376500167710ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("l...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t s, t, u; dirichlet_group_t G; dirichlet_char_t chi; ulong q, k; slong prec; acb_init(s); acb_init(t); acb_init(u); q = 1 + n_randint(state, 50); prec = 2 + n_randint(state, 100); k = n_randint(state, n_euler_phi(q)); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_index(chi, G, k); if (n_randint(state, 2)) acb_set_si(s, n_randint(state, 50) - 25); else acb_randtest(s, state, 2 + n_randint(state, 200), 2); acb_dirichlet_l_hurwitz(t, s, NULL, G, chi, prec); acb_dirichlet_l(u, s, G, chi, prec); if (!acb_overlaps(t, u)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd q = %wu k = %wu prec = %wd\n\n", iter, q, k, prec); flint_printf("s = "); acb_printn(s, 100, 0); flint_printf("\n\n"); flint_printf("t = "); acb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("u = "); acb_printn(u, 100, 0); flint_printf("\n\n"); flint_abort(); } dirichlet_char_clear(chi); dirichlet_group_clear(G); acb_clear(s); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l_euler_product.c000066400000000000000000000044631417376376500217230ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("l_euler_product...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_t s, t, u; dirichlet_group_t G; dirichlet_char_t chi; ulong q, k; slong prec; acb_init(s); acb_init(t); acb_init(u); q = 1 + n_randint(state, 50); prec = 2 + n_randint(state, 500); k = n_randint(state, n_euler_phi(q)); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_index(chi, G, k); if (n_randint(state, 2)) { acb_set_ui(s, 2 + n_randint(state, prec + 50)); } else { acb_randtest(s, state, 2 + n_randint(state, 200), 2); arb_abs(acb_realref(s), acb_realref(s)); if (n_randint(state, 2)) acb_add_ui(s, s, n_randtest(state), prec); } if (n_randint(state, 2)) acb_dirichlet_l_hurwitz(t, s, NULL, G, chi, prec); else acb_dirichlet_l_euler_product(t, s, G, chi, prec * 1.5); acb_dirichlet_l_euler_product(u, s, G, chi, prec); if (!acb_overlaps(t, u)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd q = %wu k = %wu prec = %wd\n\n", iter, q, k, prec); flint_printf("s = "); acb_printn(s, 100, 0); flint_printf("\n\n"); flint_printf("t = "); acb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("u = "); acb_printn(u, 100, 0); flint_printf("\n\n"); flint_abort(); } dirichlet_char_clear(chi); dirichlet_group_clear(G); acb_clear(s); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l_fmpq.c000066400000000000000000000044721417376376500200120ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("l_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { fmpq_t x; acb_t s, t, u; dirichlet_group_t G; dirichlet_char_t chi; ulong q, k; slong prec; fmpq_init(x); acb_init(s); acb_init(t); acb_init(u); q = 1 + n_randint(state, 50); prec = 2 + n_randint(state, 300); k = n_randint(state, n_euler_phi(q)); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_index(chi, G, k); fmpq_randtest(x, state, 2 + n_randint(state, 100)); if (fmpq_get_d(x) < -100.0) fmpq_neg(x, x); acb_set_fmpq(s, x, prec); if (n_randint(state, 2)) acb_dirichlet_l_hurwitz(t, s, NULL, G, chi, prec); else acb_dirichlet_l(t, s, G, chi, prec); acb_dirichlet_l_fmpq(u, x, G, chi, prec); if (!acb_overlaps(t, u)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd q = %wu k = %wu prec = %wd\n\n", iter, q, k, prec); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("s = "); acb_printn(s, 100, 0); flint_printf("\n\n"); flint_printf("t = "); acb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("u = "); acb_printn(u, 100, 0); flint_printf("\n\n"); acb_sub(t, t, u, prec); flint_printf("t - u = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } dirichlet_char_clear(chi); dirichlet_group_clear(G); fmpq_clear(x); acb_clear(s); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l_fmpq_afe.c000066400000000000000000000050221417376376500206150ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("l_fmpq_afe...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { fmpq_t x; acb_t s, t, u; dirichlet_group_t G; dirichlet_char_t chi; ulong q, k; slong prec; fmpq_init(x); acb_init(s); acb_init(t); acb_init(u); q = 1 + n_randint(state, 50); prec = 2 + n_randint(state, 400); k = n_randint(state, n_euler_phi(q)); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_index(chi, G, k); if (dirichlet_char_is_primitive(G, chi)) { if (n_randint(state, 2)) fmpq_set_si(x, -8 + (slong) n_randint(state, 8), 1); else fmpq_randtest(x, state, 2 + n_randint(state, 8)); acb_set_fmpq(s, x, prec); if (n_randint(state, 2)) acb_dirichlet_l_hurwitz(t, s, NULL, G, chi, prec); else acb_dirichlet_l(t, s, G, chi, prec); acb_dirichlet_l_fmpq_afe(u, x, G, chi, prec); if (!acb_overlaps(t, u)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd q = %wu k = %wu prec = %wd\n\n", iter, q, k, prec); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("s = "); acb_printn(s, 100, 0); flint_printf("\n\n"); flint_printf("t = "); acb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("u = "); acb_printn(u, 100, 0); flint_printf("\n\n"); acb_sub(t, t, u, prec); flint_printf("t - u = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } } dirichlet_char_clear(chi); dirichlet_group_clear(G); fmpq_clear(x); acb_clear(s); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l_hurwitz.c000066400000000000000000000115221417376376500205550ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #define nq 5 #define nx 3 int main() { slong i, j; ulong q[nq] = {3, 5, 61, 91, 800}; ulong m[nq] = {2, 4, 11, 2, 3}; slong prec = 150; acb_ptr x; /* cannot test at s = 1 with hurwitz */ const char * x_r[nx] = { "1", "0.5", "0.5" }; const char * x_i[nx] = { "1", "0", "6" }; acb_t ref, res; /* default(realprecision, 54) X = [ 1 + I, 1/2, 1/2 + 6 * I ] C = [Mod(2,3),Mod(4,5),Mod(11,61),Mod(2,91),Mod(3,800)] v = concat([ [lfun(c,x) | x<-X] | c<-C]) apply(z->printf("\"%s\",\n",real(z)),v) apply(z->printf("\"%s\",\n",imag(z)),v) */ const char * ref_r[nq * nx] = { "0.655527984002548033786648216345221087939439503905627469", "0.480867557696828626181220063235589877776829730832371863", "1.56831301727577320813799211138797101541772722814204757", "0.521271244517346991221550773660594765406476858135844321", "0.231750947504015755883383661760877226427886696409005898", "0.275543455389521803395512886745330595086898302178508437", "0.598221809458540554839300433683735304093606595684903281", "0.489264190003695740292779374874163221990017067040417393", "0.573331076412428980263984182365365715292560207445592018", "0.510279695870740409778738767334484809708615155539404548", "0.635626509594367380604827545000418331455019188562281349", "0.129304857274642475564179442785425797926079767522671163", "1.18088858810025653590356481638012816019876881487868657", "2.17175778983760437737667738885959799183430688287297767", "3.41568550810774629867945639900431994221065497147578087" }; const char * ref_i[nq * nx] = { "0.220206044893215842652155131408935133596486560067476474", "0", "-0.969458654385732175077973304161399773236957587792986099", "0.354614573267731219242838516784605303288232150760467423", "0", "-0.995392028773643947872231871832838543767598301887892796", "1.04370497561090171487193145841005574472705644411957863", "-0.108902811943905225853677097712717212629591264759957602", "-0.232114369998608907337769019848201890558327186146689311", "-0.133300066189980774635445078240315148544665020358019145", "0.0119464572932630291870372694406253796888930803905106876", "-0.567660589679294457801153713636532209809112025502518666", "-0.654079942571300523223917775358845549990877148918886474", "0.970337207245832214408380510793679653538607483205616894", "-1.43652482351673593824956935036654893593947145947637807" }; flint_printf("l_hurwitz...."); fflush(stdout); x = _acb_vec_init(nx); for (j = 0; j < nx; j++) { if (arb_set_str(acb_realref(x + j), x_r[j], prec) || arb_set_str(acb_imagref(x + j), x_i[j], prec) ) { flint_printf("error while setting x[%wd] <- %s+I*%s\n", j, x_r[j], x_i[j]); flint_abort(); } } acb_init(ref); acb_init(res); for (i = 0; i < nq; i++) { dirichlet_group_t G; dirichlet_char_t chi; dirichlet_group_init(G, q[i]); dirichlet_char_init(chi, G); dirichlet_char_log(chi, G, m[i]); for (j = 0; j < nx; j++) { if (arb_set_str(acb_realref(ref), ref_r[i * nx + j], prec - 10) || arb_set_str(acb_imagref(ref), ref_i[i * nx + j], prec - 10) ) { flint_printf("error while setting ref <- %s+I*%s\n", ref_r[i * nx + j], ref_i[i * nx + j]); flint_abort(); } acb_dirichlet_l_hurwitz(res, x + j, NULL, G, chi, prec + 10); if (!acb_contains(ref, res)) { flint_printf("FAIL:\n\n"); flint_printf("q = %wu\n", q[i]); flint_printf("m = %wu\n", m[i]); flint_printf("x = "); acb_printd(x, 54); flint_printf("\nref = "); acb_printd(ref, 54); flint_printf("\nl(chi,x) = "); acb_printd(res, 54); flint_printf("\n\n"); flint_abort(); } } dirichlet_char_clear(chi); dirichlet_group_clear(G); } acb_clear(ref); acb_clear(res); _acb_vec_clear(x, nx); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l_jet.c000066400000000000000000000153031417376376500176240ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* Laurent expansions at s = 1 of first 10 principal L-functions */ /* with mpmath: chis = [[1],[0,1],[0,1,1],[0,1,0,1],[0,1,1,1,1],[0,1,0,0,0,1],[0,1,1,1,1,1,1], [0,1,0,1,0,1,0,1],[0,1,1,0,1,1,0,1,1],[0,1,0,1,0,0,0,1,0,1]] mp.dps = 40 for chi in chis: phi = chi.count(1); q = len(chi) L = lambda s: dirichlet(s, chi) - phi/((s-1)*q) c0 = taylor(L, 1, 0, method="quad") c1 = taylor(L, 1, 5, singular=True)[1:] for c in c0 + c1: print nstr(c, 20) + ",", print */ #define TESTQ 10 #define TESTLEN 6 static const double laurent_data[TESTQ][TESTLEN] = { {0.57721566490153286061, 0.072815845483676724861, -0.0048451815964361592423, -0.00034230573671722431103, 0.000096890419394470835728, -6.6110318108421891813e-6}, {0.63518142273073908501, 0.11634237461305384831, -0.018765738937942729408, 0.00061334298434914532242, 0.00042338142025747308027, -0.00010545096447379519004}, {0.7510145394903918042, 0.058764477744540050414, -0.019011359100973296683, 0.0056382252365739175151, -0.0009550480622176659462, 0.000021808301216554848718}, {0.63518142273073908501, 0.11634237461305384831, -0.018765738937942729408, 0.00061334298434914532242, 0.00042338142025747308027, -0.00010545096447379519004}, {0.78366011440804636341, -0.014977808062405260803, 0.0090104707969118845102, 0.003603799084856807634, -0.0029351216034181476022, 0.00093077685173004747355}, {0.60655632993184433857, 0.2095885418562151802, -0.060844893711330538429, 0.0068080382961291386117, 0.0022236616427578346453, -0.0013581825996235430782}, {0.77274344835207292411, -0.047596894381510269689, 0.035406039531261788462, -0.0054159870134630085898, -0.0019749752308692423114, 0.0014492998471928196325}, {0.63518142273073908501, 0.11634237461305384831, -0.018765738937942729408, 0.00061334298434914532242, 0.00042338142025747308027, -0.00010545096447379519004}, {0.7510145394903918042, 0.058764477744540050414, -0.019011359100973296683, 0.0056382252365739175151, -0.0009550480622176659462, 0.000021808301216554848718}, {0.66908892942800130547, 0.16801639259476784034, -0.072611999814034642781, 0.024624650443138705595, -0.004951850872731033514, -0.00020178815459414925709} }; int main() { slong iter; flint_rand_t state; flint_printf("l_jet...."); fflush(stdout); flint_randinit(state); /* test Laurent series at s = 1 */ { acb_t s, t; dirichlet_group_t G; dirichlet_char_t chi; acb_ptr vec; ulong q; slong i; acb_init(s); acb_init(t); vec = _acb_vec_init(TESTLEN); acb_one(s); for (q = 1; q <= TESTQ; q++) { dirichlet_group_init(G, q); dirichlet_char_init(chi, G); acb_dirichlet_l_jet(vec, s, G, chi, 1, TESTLEN, 100); for (i = 0; i < TESTLEN; i++) { acb_set_d(t, laurent_data[q - 1][i]); mag_set_d(arb_radref(acb_realref(t)), fabs(laurent_data[q - 1][i]) * 1e-14); if (!acb_overlaps(vec + i, t)) { flint_printf("FAIL: Laurent series\n\n"); flint_printf("q = %wu i = %wd\n\n", q, i); flint_printf("r1 = "); acb_printn(vec + i, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); acb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } } dirichlet_char_clear(chi); dirichlet_group_clear(G); } acb_clear(s); acb_clear(t); _acb_vec_clear(vec, TESTLEN); } /* test self-consistency */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t s; dirichlet_group_t G; dirichlet_char_t chi; acb_ptr vec1, vec2; slong len1, len2; slong prec1, prec2; int deflate1, deflate2; ulong q, k; slong i; len1 = n_randint(state, 5); len2 = n_randint(state, 5); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); deflate1 = n_randint(state, 2); deflate2 = n_randint(state, 2); q = 1 + n_randint(state, 20); k = n_randint(state, n_euler_phi(q)); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_index(chi, G, k); acb_init(s); vec1 = _acb_vec_init(len1); vec2 = _acb_vec_init(len2); if (n_randint(state, 4) == 0) acb_one(s); else acb_randtest(s, state, 2 + n_randint(state, 200), 2); acb_dirichlet_l_jet(vec1, s, G, chi, deflate1, len1, prec1); acb_dirichlet_l_jet(vec2, s, G, chi, deflate2, len2, prec2); if (deflate1 != deflate2 && dirichlet_char_is_principal(G, chi)) { /* add or subtract phi(q)/((s+x-1)q) */ acb_t t, u; acb_init(t); acb_init(u); acb_set_ui(t, n_euler_phi(q)); acb_div_ui(t, t, q, prec1); acb_sub_ui(u, s, 1, prec1); for (i = 0; i < len1; i++) { acb_div(t, t, u, prec1); if (deflate1) acb_add(vec1 + i, vec1 + i, t, prec1); else acb_sub(vec1 + i, vec1 + i, t, prec1); acb_neg(t, t); } acb_clear(t); acb_clear(u); } for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(vec1 + i, vec2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd q = %wu k = %wu i = %wd\n\n", iter, q, k, i); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); acb_printn(vec1 + i, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); acb_printn(vec2 + i, 50, 0); flint_printf("\n\n"); flint_abort(); } } dirichlet_char_clear(chi); dirichlet_group_clear(G); acb_clear(s); _acb_vec_clear(vec1, len1); _acb_vec_clear(vec2, len2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l_series.c000066400000000000000000000044341417376376500203370ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("l_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; int deflate; acb_poly_t S, A, B, C; dirichlet_group_t G; dirichlet_char_t chi; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 8); n1 = 1 + n_randint(state, 8); n2 = 1 + n_randint(state, 8); dirichlet_group_init(G, 1 + n_randint(state, 12)); dirichlet_char_init(chi, G); dirichlet_char_index(chi, G, n_randint(state, G->phi_q)); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); deflate = n_randint(state, 2); acb_poly_randtest(S, state, m, bits1, 3); acb_dirichlet_l_series(A, S, G, chi, deflate, n1, bits2); acb_poly_set(B, S); /* aliasing */ acb_dirichlet_l_series(B, B, G, chi, deflate, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); dirichlet_char_clear(chi); dirichlet_group_clear(G); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-l_vec_hurwitz.c000066400000000000000000000067411417376376500214210ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("l_vec_hurwitz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { ulong i, q; slong prec; dirichlet_group_t G; dirichlet_char_t chi; acb_t s, z; acb_ptr v; acb_dirichlet_hurwitz_precomp_t pre; prec = 50 + n_randint(state, 50); q = 1 + n_randint(state, 50); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); acb_init(s); acb_one(s); acb_div_si(s, s, 2, prec); v = _acb_vec_init(G->phi_q); if (n_randint(state, 2)) { ulong A, K, N; acb_dirichlet_hurwitz_precomp_choose_param(&A, &K, &N, s, G->phi_q, prec); acb_dirichlet_hurwitz_precomp_init(pre, s, acb_is_one(s), A, K, N, prec); } else { acb_dirichlet_hurwitz_precomp_init_num(pre, s, acb_is_one(s), G->phi_q, prec); } /* all at once */ if (n_randint(state, 2)) acb_dirichlet_l_vec_hurwitz(v, s, pre, G, prec); else acb_dirichlet_l_vec_hurwitz(v, s, NULL, G, prec); /* check with complete loop */ i = 0; acb_init(z); dirichlet_char_one(chi, G); do { if (n_randint(state, 2)) acb_dirichlet_l_hurwitz(z, s, pre, G, chi, prec); else acb_dirichlet_l_hurwitz(z, s, NULL, G, chi, prec); if (!acb_overlaps(z, v + i)) { flint_printf("\n L value differ"); flint_printf("\nL(1/2, %wu) single = ", chi->n); acb_printd(z, 20); flint_printf("\nL(1/2, %wu) multi = ", chi->n); acb_printd(v + i, 20); flint_printf("\n\n"); acb_vec_printd(v, G->phi_q, 10); flint_printf("\n\n"); abort(); } else if (acb_rel_accuracy_bits(z) < prec - 8 || acb_rel_accuracy_bits(v + i) < prec - 8) { flint_printf("FAIL\n\n"); flint_printf("q = %wu\n", q); flint_printf("\nL(1/2,chi_%wu(%wu,)) inaccurate\n", q, chi->n); flint_printf("\nsingle =\n"); acb_printd(z, 30); flint_printf("\ndft =\n"); acb_printd(v + i, 30); flint_printf("\nerrors %wd & %wd [prec = %wd]\n", acb_rel_accuracy_bits(z), acb_rel_accuracy_bits(v + i), prec); abort(); } i++; } while (dirichlet_char_next(chi, G) >= 0); acb_clear(s); _acb_vec_clear(v, G->phi_q); dirichlet_char_clear(chi); dirichlet_group_clear(G); acb_dirichlet_hurwitz_precomp_clear(pre); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-platt_beta.c000066400000000000000000000063751417376376500206570ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _arb_div_ui_ui(arb_t res, ulong a, ulong b, slong prec) { arb_set_ui(res, a); arb_div_ui(res, res, b, prec); } static int _arb_lt_d(const arb_t a, double d) { int result; arb_t x; arb_init(x); arb_set_d(x, d); result = arb_lt(a, x); arb_clear(x); return result; } int main() { slong iter; flint_rand_t state; arb_t x, t, t0, expe; flint_printf("platt_beta...."); fflush(stdout); flint_randinit(state); arb_init(x); arb_init(t); arb_init(t0); arb_init(expe); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t beta, a, b, c; acb_t z; slong prec, mbits; prec = 2 + n_randint(state, 300); mbits = 2 + n_randint(state, 20); arb_randtest(t, state, prec, mbits); arb_randtest(t0, state, prec, mbits); arb_abs(t, t); arb_abs(t0, t0); arb_add(x, t, t0, prec); arb_const_e(expe, prec); arb_exp(expe, expe, prec); if (!arb_is_nonnegative(t) || !arb_gt(t0, expe) || !_arb_lt_d(x, 1e8)) { continue; } arb_init(beta); arb_init(a); arb_init(b); arb_init(c); acb_init(z); acb_dirichlet_platt_beta(beta, t0, prec); /* Lemma A.10 in "Isolating some non-trivial zeros of zeta" */ arb_pow(a, x, beta, prec); arb_mul_ui(a, a, 3, prec); acb_dirichlet_platt_scaled_lambda(c, t, prec); arb_abs(c, c); if (arb_gt(c, a)) { flint_printf("FAIL: Lemma A.10 |f(t)|\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("prec = %wd\n\n", prec); flint_printf("t = "); arb_printd(t, 15); flint_printf("\n\n"); flint_printf("t0 = "); arb_printd(t0, 15); flint_printf("\n\n"); flint_abort(); } /* In Lemma A.10 proof in "Isolating some non-trivial zeros of zeta" */ arb_pow(a, x, beta, prec); _arb_div_ui_ui(b, 732, 1000, prec); arb_mul(a, a, b, prec); acb_set_d(z, 0.5); arb_set(acb_imagref(z), x); acb_zeta(z, z, prec); acb_abs(c, z, prec); if (arb_gt(c, a)) { flint_printf("FAIL: Lemma A.10 |zeta(1/2 + i(t + t0))|\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("prec = %wd\n\n", prec); flint_printf("t = "); arb_printd(t, 15); flint_printf("\n\n"); flint_printf("t0 = "); arb_printd(t0, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(beta); arb_clear(a); arb_clear(b); arb_clear(c); acb_clear(z); } arb_clear(x); arb_clear(t); arb_clear(t0); arb_clear(expe); flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-platt_hardy_z_zeros.c000066400000000000000000000030531417376376500226140ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { fmpz_t n; arb_ptr pa, pb; slong count, i; slong maxcount = 50; slong prec = 64; flint_printf("platt_hardy_z_zeros...."); fflush(stdout); fmpz_init(n); pa = _arb_vec_init(maxcount); pb = _arb_vec_init(maxcount); fmpz_set_si(n, 10000); count = acb_dirichlet_platt_hardy_z_zeros(pa, n, maxcount, prec); acb_dirichlet_hardy_z_zeros(pb, n, count, prec); if (count != maxcount) { flint_printf("FAIL: not enough zeros were isolated\n\n"); flint_printf("count = %wd maxcount = %wd\n\n", count, maxcount); flint_abort(); } for (i = 0; i < count; i++) { if (!arb_overlaps(pa+i, pb+i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("observed[%wd] = ", i); arb_printd(pa+i, 20); flint_printf("\n\n"); flint_printf("expected[%wd] = ", i); arb_printd(pb+i, 20); flint_printf("\n\n"); flint_abort(); } } fmpz_clear(n); _arb_vec_clear(pa, maxcount); _arb_vec_clear(pb, maxcount); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-platt_local_hardy_z_zeros.c000066400000000000000000000044651417376376500237760ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { /* Check a specific combination of parameter values that is relatively fast * to evaluate and that has relatively tight bounds. */ slong A, B, J, K, sigma_grid, Ns_max, sigma_interp; arb_t h, H; fmpz_t T, n; arb_ptr pa, pb; slong count, i; slong maxcount = 50; slong prec = 128; flint_printf("platt_local_hardy_z_zeros...."); fflush(stdout); arb_init(h); arb_init(H); fmpz_init(T); fmpz_init(n); pa = _arb_vec_init(maxcount); pb = _arb_vec_init(maxcount); fmpz_set_si(n, 10142); /* parameters related to the location/resolution/width of the grid */ fmpz_set_si(T, 10000); A = 8; B = 128; /* tuning parameters for the evaluation of grid points */ J = 1000; K = 30; sigma_grid = 63; arb_set_d(h, 4.5); /* tuning parameters for interpolation on the grid */ Ns_max = 200; sigma_interp = 21; arb_one(H); count = _acb_dirichlet_platt_local_hardy_z_zeros(pa, n, maxcount, T, A, B, h, J, K, sigma_grid, Ns_max, H, sigma_interp, prec); acb_dirichlet_hardy_z_zeros(pb, n, count, prec); if (count != maxcount) { flint_printf("FAIL: not enough zeros were isolated\n\n"); flint_printf("count = %wd maxcount = %wd\n\n", count, maxcount); flint_abort(); } for (i = 0; i < count; i++) { if (!arb_overlaps(pa+i, pb+i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("observed[%wd] = ", i); arb_printd(pa+i, 20); flint_printf("\n\n"); flint_printf("expected[%wd] = ", i); arb_printd(pb+i, 20); flint_printf("\n\n"); flint_abort(); } } arb_clear(h); arb_clear(H); fmpz_clear(T); fmpz_clear(n); _arb_vec_clear(pa, maxcount); _arb_vec_clear(pb, maxcount); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-platt_multieval.c000066400000000000000000000155321417376376500217410ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _arb_inv_si(arb_t res, slong a, slong prec) { arb_set_si(res, a); arb_inv(res, res, prec); } static void _arb_div_si_si(arb_t res, slong a, slong b, slong prec) { arb_set_si(res, a); arb_div_si(res, res, b, prec); } static int _arb_vec_overlaps(arb_srcptr a, arb_srcptr b, slong len) { slong i; for (i = 0; i < len; i++) { if (!arb_overlaps(a + i, b + i)) { return 0; } } return 1; } static void _check_containment(const char *name, const arb_t x, const char *s) { arb_t u; slong prec = 300; arb_init(u); arb_set_str(u, s, prec); if (!arb_contains(u, x)) { flint_printf("FAIL: %s\n\n", name); flint_printf("observed = "); arb_printn(x, 30, 0); flint_printf("\n\n"); flint_printf("expected = "); arb_printn(u, 30, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(u); } int main() { slong iter; flint_rand_t state; flint_printf("platt_multieval...."); fflush(stdout); flint_randinit(state); /* Check a specific combination of parameter values that is relatively fast * to evaluate and that has relatively tight bounds. */ { slong A = 8; slong B = 128; slong N = A*B; slong J = 1000; slong K = 30; slong sigma = 63; slong prec = 128; fmpz_t T; arb_t h; arb_ptr vec; arb_init(h); fmpz_init(T); fmpz_set_si(T, 10000); arb_set_d(h, 4.5); /* Spot-check lemma bound containment * in intervals calculated with PARI/GP. */ { arb_t lem, xi, x, beta, t0; slong i = 201; slong k = 5; slong wp = 300; arb_init(lem); arb_init(xi); arb_init(x); arb_init(t0); arb_init(beta); _arb_inv_si(xi, B, wp); arb_mul_2exp_si(xi, xi, -1); _arb_div_si_si(x, i, B, wp); arb_set_fmpz(t0, T); acb_dirichlet_platt_beta(beta, t0, wp); acb_dirichlet_platt_lemma_32(lem, h, t0, x, wp); _check_containment("Lemma 3.2", lem, "[5.3526496753240991744e-1072334 +/- 2.55e-1072354]"); acb_dirichlet_platt_c_bound(lem, sigma, t0, h, k, wp); _check_containment("Lemma A.3", lem, "[1.3516642396389823078e+134 +/- 2.65e+114]"); acb_dirichlet_platt_lemma_A5(lem, B, h, k, wp); _check_containment("Lemma A.5", lem, "[1.0075390047893384632e-30 +/- 5.57e-51]"); acb_dirichlet_platt_lemma_A7(lem, sigma, t0, h, k, A, wp); _check_containment("Lemma A.7", lem, "[3.0406705491484062400e-505 +/- 1.57e-525]"); acb_dirichlet_platt_lemma_A9(lem, sigma, t0, h, A, wp); _check_containment("Lemma A.9", lem, "[6.8953211848420326275e-536 +/- 3.52e-556]"); acb_dirichlet_platt_lemma_A11(lem, t0, h, B, wp); _check_containment("Lemma A.11", lem, "[3.0825745863006335768e-42 +/- 3.68e-62]"); acb_dirichlet_platt_lemma_B1(lem, sigma, t0, h, J, wp); _check_containment("Lemma B.1", lem, "[8.5737638613320328274e-42 +/- 7.50e-63]"); acb_dirichlet_platt_lemma_B2(lem, K, h, xi, wp); _check_containment("Lemma B.2", lem, "[2.0748437544358592615e-44 +/- 4.76e-64]"); arb_clear(lem); arb_clear(xi); arb_clear(x); arb_clear(t0); arb_clear(beta); } /* Check a few random entries in the multieval vector. */ vec = _arb_vec_init(N); acb_dirichlet_platt_multieval(vec, T, A, B, h, J, K, sigma, prec); for (iter = 0; iter < 20; iter++) { arb_t t, r; slong i = n_randint(state, N); slong n = i - N/2; arb_init(t); arb_init(r); _arb_div_si_si(t, n, A, prec); arb_add_fmpz(t, t, T, prec); acb_dirichlet_platt_scaled_lambda(r, t, prec); if (!arb_overlaps(vec + i, r)) { flint_printf("FAIL: overlap for hardcoded example\n\n"); flint_printf("i = %wd n = %wd\n\n", i, n); flint_printf("vec[%wd] = ", i); arb_printn(vec + i, 30, 0); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, 30, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(t); arb_clear(r); } fmpz_clear(T); arb_clear(h); _arb_vec_clear(vec, N); } for (iter = 0; iter < 10 * arb_test_multiplier(); iter++) { slong prec; ulong A, B, N, J, K; slong sigma, Tbits; fmpz_t T; arb_t h; arb_ptr v1, v2; /* better but slower limits are in parentheses below */ prec = 2 + n_randint(state, 300); sigma = 1 + 2*(1 + n_randint(state, 100)); /* (200) */ J = 1 + n_randint(state, 100); /* (10000) */ K = 1 + n_randint(state, 20); /* (50) */ A = 1 + n_randint(state, 10); B = 1 + n_randint(state, 10); /* (500) */ if (n_randint(state, 2)) A *= 2; else B *= 2; N = A*B; fmpz_init(T); Tbits = 5 + n_randint(state, 15); fmpz_set_ui(T, n_randtest_bits(state, Tbits)); arb_init(h); arb_set_si(h, 1 + n_randint(state, 20000)); arb_div_si(h, h, 1000, prec); v1 = _arb_vec_init(N); v2 = _arb_vec_init(N); acb_dirichlet_platt_scaled_lambda_vec(v1, T, A, B, prec); acb_dirichlet_platt_multieval(v2, T, A, B, h, J, K, sigma, prec); if (!_arb_vec_overlaps(v1, v2, N)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd prec = %wd\n\n", iter, prec); flint_printf("sigma = %wd\n\n", sigma); flint_printf("A = %wu B = %wu J = %wu K = %wu\n\n", A, B, J, K); flint_printf("T = "); fmpz_print(T); flint_printf("\n\n"); flint_printf("h = "); arb_printn(h, 30, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(h); fmpz_clear(T); _arb_vec_clear(v1, N); _arb_vec_clear(v2, N); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-platt_multieval_threaded.c000066400000000000000000000104371417376376500236000ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _arb_div_si_si(arb_t res, slong a, slong b, slong prec) { arb_set_si(res, a); arb_div_si(res, res, b, prec); } static int _arb_vec_overlaps(arb_srcptr a, arb_srcptr b, slong len) { slong i; for (i = 0; i < len; i++) { if (!arb_overlaps(a + i, b + i)) { return 0; } } return 1; } int main() { slong iter; flint_rand_t state; flint_printf("platt_multieval_threaded...."); fflush(stdout); flint_randinit(state); /* Check a specific combination of parameter values that is relatively fast * to evaluate and that has relatively tight bounds. */ { slong A = 8; slong B = 128; slong N = A*B; slong J = 1000; slong K = 30; slong sigma = 63; slong prec = 128; fmpz_t T; arb_t h; arb_ptr vec; arb_init(h); fmpz_init(T); fmpz_set_si(T, 10000); arb_set_d(h, 4.5); flint_set_num_threads(5); /* Check a few random entries in the multieval vector. */ vec = _arb_vec_init(N); acb_dirichlet_platt_multieval_threaded(vec, T, A, B, h, J, K, sigma, prec); for (iter = 0; iter < 20; iter++) { arb_t t, r; slong i = n_randint(state, N); slong n = i - N/2; arb_init(t); arb_init(r); _arb_div_si_si(t, n, A, prec); arb_add_fmpz(t, t, T, prec); acb_dirichlet_platt_scaled_lambda(r, t, prec); if (!arb_overlaps(vec + i, r)) { flint_printf("FAIL: overlap for hardcoded example\n\n"); flint_printf("i = %wd n = %wd\n\n", i, n); flint_printf("vec[%wd] = ", i); arb_printn(vec + i, 30, 0); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, 30, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(t); arb_clear(r); } fmpz_clear(T); arb_clear(h); _arb_vec_clear(vec, N); } for (iter = 0; iter < 10 * arb_test_multiplier(); iter++) { slong prec; ulong A, B, N, J, K; slong sigma, Tbits; fmpz_t T; arb_t h; arb_ptr v1, v2; /* better but slower limits are in parentheses below */ prec = 2 + n_randint(state, 300); sigma = 1 + 2*(1 + n_randint(state, 100)); /* (200) */ J = 1 + n_randint(state, 100); /* (10000) */ K = 1 + n_randint(state, 20); /* (50) */ A = 1 + n_randint(state, 10); B = 1 + n_randint(state, 10); /* (500) */ if (n_randint(state, 2)) A *= 2; else B *= 2; N = A*B; fmpz_init(T); Tbits = 5 + n_randint(state, 15); fmpz_set_ui(T, n_randtest_bits(state, Tbits)); arb_init(h); arb_set_si(h, 1 + n_randint(state, 20000)); arb_div_si(h, h, 1000, prec); flint_set_num_threads(1 + n_randint(state, 5)); v1 = _arb_vec_init(N); v2 = _arb_vec_init(N); acb_dirichlet_platt_scaled_lambda_vec(v1, T, A, B, prec); acb_dirichlet_platt_multieval_threaded(v2, T, A, B, h, J, K, sigma, prec); if (!_arb_vec_overlaps(v1, v2, N)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd prec = %wd\n\n", iter, prec); flint_printf("sigma = %wd\n\n", sigma); flint_printf("A = %wu B = %wu J = %wu K = %wu\n\n", A, B, J, K); flint_printf("T = "); fmpz_print(T); flint_printf("\n\n"); flint_printf("h = "); arb_printn(h, 30, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(h); fmpz_clear(T); _arb_vec_clear(v1, N); _arb_vec_clear(v2, N); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-platt_ws_interpolation.c000066400000000000000000000061461417376376500233400ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("platt_ws_interpolation...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5 * arb_test_multiplier(); iter++) { ulong A, B, iter2; int Tbits; fmpz_t T; arb_ptr vec; slong vprec; A = 1 + n_randint(state, 10); B = 1 + n_randint(state, 10); if (n_randint(state, 2)) A *= 2; else B *= 2; fmpz_init(T); Tbits = 5 + n_randint(state, 20); fmpz_set_ui(T, n_randtest_bits(state, Tbits)); vprec = 2 + n_randint(state, 300); vec = _arb_vec_init(A*B); acb_dirichlet_platt_scaled_lambda_vec(vec, T, A, B, vprec); for (iter2 = 0; iter2 < 50; iter2++) { ulong Ns_max, sigma; arb_t expected, observed; arb_t t0, H; slong prec; arb_init(t0); arb_init(H); arb_init(expected); arb_init(observed); prec = 2 + n_randint(state, 300); Ns_max = 1 + n_randint(state, 100); sigma = 1 + 2*(1 + n_randint(state, 100)); arb_set_si(t0, A*B*500 - n_randint(state, A*B*1000) - 1); arb_div_ui(t0, t0, A*1000, prec); arb_add_fmpz(t0, t0, T, prec); arb_set_ui(H, 1 + n_randint(state, 10000)); arb_div_ui(H, H, 1000, prec); arb_abs(H, H); acb_dirichlet_platt_scaled_lambda(expected, t0, prec); acb_dirichlet_platt_ws_interpolation(observed, NULL, t0, vec, T, A, B, Ns_max, H, sigma, prec); if (!arb_overlaps(expected, observed)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("iter2 = %wd\n\n", iter2); flint_printf("A = %wu\n\n", A); flint_printf("B = %wu\n\n", B); flint_printf("T = "); fmpz_print(T); flint_printf("\n\n"); flint_printf("vprec = %wd\n\n", vprec); flint_printf("Ns_max = %wu\n\n", Ns_max); flint_printf("sigma = %wu\n\n", sigma); flint_printf("prec = %wd\n\n", prec); flint_printf("t0 = "); arb_printd(t0, 15); flint_printf("\n\n"); flint_printf("H = "); arb_printd(H, 15); flint_printf("\n\n"); } arb_clear(t0); arb_clear(H); arb_clear(expected); arb_clear(observed); } fmpz_clear(T); _arb_vec_clear(vec, A*B); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-platt_zeta_zeros.c000066400000000000000000000030421417376376500221150ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { fmpz_t n; acb_ptr pa, pb; slong count, i; slong maxcount = 50; slong prec = 64; flint_printf("platt_zeta_zeros...."); fflush(stdout); fmpz_init(n); pa = _acb_vec_init(maxcount); pb = _acb_vec_init(maxcount); fmpz_set_si(n, 10000); count = acb_dirichlet_platt_zeta_zeros(pa, n, maxcount, prec); acb_dirichlet_zeta_zeros(pb, n, count, prec); if (count != maxcount) { flint_printf("FAIL: not enough zeros were isolated\n\n"); flint_printf("count = %wd maxcount = %wd\n\n", count, maxcount); flint_abort(); } for (i = 0; i < count; i++) { if (!acb_overlaps(pa+i, pb+i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("observed[%wd] = ", i); acb_printd(pa+i, 20); flint_printf("\n\n"); flint_printf("expected[%wd] = ", i); acb_printd(pb+i, 20); flint_printf("\n\n"); flint_abort(); } } fmpz_clear(n); _acb_vec_clear(pa, maxcount); _acb_vec_clear(pb, maxcount); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-powsum_smooth.c000066400000000000000000000042451417376376500214550ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("powsum_smooth...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t s; acb_ptr z1, z2; slong i, n, len, prec; acb_init(s); if (n_randint(state, 2)) { acb_randtest(s, state, 1 + n_randint(state, 200), 3); } else { arb_set_ui(acb_realref(s), 1); arb_mul_2exp_si(acb_realref(s), acb_realref(s), -1); arb_randtest(acb_imagref(s), state, 1 + n_randint(state, 200), 4); } prec = 2 + n_randint(state, 200); n = n_randtest(state) % 500; len = 1 + n_randint(state, 4); z1 = _acb_vec_init(len); z2 = _acb_vec_init(len); acb_dirichlet_powsum_sieved(z1, s, n, len, prec); acb_dirichlet_powsum_smooth(z2, s, n, len, prec); for (i = 0; i < len; i++) { if (!acb_overlaps(z1 + i, z2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("n = %wd, prec = %wd, len = %wd, i = %wd\n\n", n, prec, len, i); flint_printf("s = "); acb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1 + i, prec / 3.33); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2 + i, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } acb_clear(s); _acb_vec_clear(z1, len); _acb_vec_clear(z2, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-roots.c000066400000000000000000000034431417376376500176770ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("roots...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, z; acb_dirichlet_roots_t roots; ulong n, k; slong prec; slong iter2; n = 1 + n_randint(state, 1000); prec = 2 + n_randint(state, 200); acb_init(x); acb_init(y); acb_init(z); acb_dirichlet_roots_init(roots, n, n_randtest(state), prec); acb_unit_root(y, n, prec); for (iter2 = 0; iter2 <= FLINT_MIN(n, 20); iter2++) { k = n_randint(state, 2 * n); acb_dirichlet_root(x, roots, k, prec); acb_pow_ui(z, y, k, prec); if (!acb_overlaps(x, z)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd n = %wu k = %wu prec = %wd\n\n", iter, n, k, prec); flint_printf("x = "); acb_printn(x, 30, 0); flint_printf("\n\n"); flint_printf("z = "); acb_printn(z, 30, 0); flint_printf("\n\n"); flint_abort(); } } acb_dirichlet_roots_clear(roots); acb_clear(x); acb_clear(y); acb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-stieltjes.c000066400000000000000000000075541417376376500205460ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_stieltjes_integral(acb_t res, const fmpz_t n, const acb_t a, slong prec); void acb_dirichlet_stieltjes_em(acb_t res, const fmpz_t n, const acb_t a, slong prec); int main() { slong iter; flint_rand_t state; flint_printf("stieltjes...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { acb_t b1, b2, a; fmpz_t n; slong prec1, prec2, acc1, acc2; int alg1, alg2; fmpz_init(n); acb_init(b1); acb_init(b2); acb_init(a); if (n_randint(state, 10) == 0) { acb_one(a); fmpz_randtest(n, state, 1 + n_randint(state, 100)); fmpz_abs(n, n); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); } else if (n_randint(state, 7) != 0) { acb_one(a); fmpz_randtest(n, state, 2 + n_randint(state, 12)); fmpz_abs(n, n); prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); } else { acb_randtest_precise(a, state, 400, 3); fmpz_randtest(n, state, 7); fmpz_abs(n, n); prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); } alg1 = n_randint(state, 3); alg2 = n_randint(state, 3); if (fmpz_cmp_ui(n, 40) >= 0) { alg1 = 1 + n_randint(state, 2); alg2 = 1 + n_randint(state, 2); } else { alg1 = n_randint(state, 3); alg2 = n_randint(state, 3); } if (alg1 == 0) acb_dirichlet_stieltjes_em(b1, n, a, prec1); else if (alg1 == 1) acb_dirichlet_stieltjes_integral(b1, n, a, prec1); else acb_dirichlet_stieltjes(b1, n, a, prec1); if (alg2 == 0) acb_dirichlet_stieltjes_em(b2, n, a, prec2); else if (alg2 == 1) acb_dirichlet_stieltjes_integral(b2, n, a, prec2); else acb_dirichlet_stieltjes(b2, n, a, prec2); if (!acb_overlaps(b1, b2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd, alg1 = %d, alg2 = %d\n\n", iter, alg1, alg2); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 100, 0); flint_printf("\n\n"); flint_printf("b1 = "); acb_printn(b1, 1000, 0); flint_printf("\n\n"); flint_printf("b2 = "); acb_printn(b2, 1000, 0); flint_printf("\n\n"); flint_abort(); } acc1 = acb_rel_accuracy_bits(b1); acc2 = acb_rel_accuracy_bits(b2); if (acb_is_one(a) && (acc1 < prec1 - 10 || acc2 < prec2 - 10)) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd\n", prec1, acc1); flint_printf("prec2 = %wd, acc2 = %wd\n", prec2, acc2); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("b1 = "); acb_printn(b1, 500, 0); flint_printf("\n\n"); flint_printf("b2 = "); acb_printn(b2, 500, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(b1); acb_clear(b2); acb_clear(a); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-thetanull.c000066400000000000000000000063171417376376500205340ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong prec = 64; ulong q; flint_printf("thetanull...."); fflush(stdout); /* check the only theta functions * theta(chi) = sum chi(k)* k^odd * exp(-Pi * k^2 / q) * vanishing at 1 correspond to two specific * characters of moduli 300 and 600 + conjugates */ for (q = 3; q < 1000; q ++) { dirichlet_group_t G; dirichlet_char_t chi; ulong * v, nv, k; acb_t sum; acb_ptr z; arb_t eq; arb_ptr t, kt, tt; if (q % 4 == 2) /* no primitive character mod q */ continue; dirichlet_group_init(G, q); dirichlet_char_init(chi, G); z = _acb_vec_init(G->expo); _acb_vec_unit_roots(z, G->expo, G->expo, prec); nv = acb_dirichlet_theta_length_d(q, 1, prec); v = flint_malloc(nv * sizeof(ulong)); arb_init(eq); arb_const_pi(eq, prec); arb_div_ui(eq, eq, q, prec); arb_neg(eq, eq); arb_exp(eq, eq, prec); t = _arb_vec_init(nv); acb_dirichlet_arb_quadratic_powers(t, nv, eq, prec); kt = _arb_vec_init(nv); for (k = 1; k < nv; k++) arb_mul_ui(kt + k, t + k, k, prec); /* theta function on primitive characters */ acb_init(sum); dirichlet_char_first_primitive(chi, G); do { acb_zero(sum); dirichlet_chi_vec(v, G, chi, nv); tt = dirichlet_parity_char(G, chi) ? kt : t; for (k = 1; k < nv; k++) if (v[k] != DIRICHLET_CHI_NULL) acb_addmul_arb(sum, z + v[k], tt + k, prec); if ((q == 300 && (chi->n == 71 || chi->n == 131)) || (q == 600 && (chi->n == 11 || chi->n == 491))) { if (!acb_contains_zero(sum)) { flint_printf("FAIL: Theta(chi_%wu(%wu))=", q, chi->n); acb_printd(sum, 10); flint_printf("\n"); dirichlet_char_print(G, chi); flint_printf("\n"); flint_abort(); } } else if (acb_contains_zero(sum)) { flint_printf("FAIL: Theta(chi_%wu(%wu))=", q, chi->n); acb_printd(sum, 10); flint_printf("\n"); dirichlet_char_print(G, chi); flint_printf("\n"); flint_abort(); } } while (dirichlet_char_next_primitive(chi, G) >= 0); _acb_vec_clear(z, G->expo); _arb_vec_clear(kt, nv); _arb_vec_clear(t, nv); acb_clear(sum); arb_clear(eq); flint_free(v); dirichlet_group_clear(G); dirichlet_char_clear(chi); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-turing_method_bound.c000066400000000000000000000030111417376376500225570ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("turing_method_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { ulong u, v; fmpz_t a, b; fmpz_init(a); fmpz_init(b); fmpz_randtest_unsigned(a, state, 500); fmpz_randtest_unsigned(b, state, 500); fmpz_sub_ui(a, a, 1); fmpz_sub_ui(b, b, 1); u = acb_dirichlet_turing_method_bound(a); v = acb_dirichlet_turing_method_bound(b); if ((fmpz_cmp(a, b) < 0 && u > v) || (fmpz_cmp(a, b) > 0 && u < v)) { flint_printf("FAIL: increasing on p >= -1\n\n"); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf("u = %wu\n", u); flint_printf("v = %wu\n", v); flint_abort(); } fmpz_clear(a); fmpz_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-xi.c000066400000000000000000000041351417376376500171500ustar00rootroot00000000000000/* Copyright (C) 2018 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("xi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); acb_init(a); acb_init(b); acb_init(c); acb_randtest_precise(a, state, 1 + n_randint(state, 1000), 3); acb_dirichlet_xi(b, a, prec1); if (n_randint(state, 2)) { acb_dirichlet_xi(c, a, prec2); } else /* test aliasing */ { acb_set(c, a); acb_dirichlet_xi(c, c, prec2); } if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } /* check xi(s) = xi(1-s) */ acb_sub_ui(c, a, 1, prec1); acb_neg(c, c); acb_dirichlet_xi(c, c, prec1); if (!acb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_bound.c000066400000000000000000000106631417376376500206650ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t s, sb, z; arb_t x, y; slong prec, i; mag_t zbound; acb_init(s); acb_init(sb); acb_init(z); arb_init(x); arb_init(y); mag_init(zbound); acb_randtest(s, state, 2 + n_randint(state, 100), 4); if (n_randint(state, 2)) arb_set_d(acb_realref(s), -0.5 + n_randint(state, 32) / 16.0); mag_zero(arb_radref(acb_realref(s))); mag_zero(arb_radref(acb_imagref(s))); /* create a larger interval containing s */ acb_set(sb, s); for (i = 0; i < 2; i++) { arb_randtest(x, state, 2 + n_randint(state, 100), 2); arb_add(x, x, acb_realref(s), 2 * MAG_BITS); arb_intersection(acb_realref(sb), acb_realref(sb), x, 2 * MAG_BITS); arb_randtest(x, state, 2 + n_randint(state, 100), 2); arb_add(x, x, acb_imagref(s), 2 * MAG_BITS); arb_intersection(acb_imagref(sb), acb_imagref(sb), x, 2 * MAG_BITS); } acb_dirichlet_zeta_bound(zbound, sb); if (!mag_is_inf(zbound)) { for (prec = 64; ; prec *= 2) { acb_zeta(z, s, prec); if (acb_rel_accuracy_bits(z) > MAG_BITS) break; } acb_abs(x, z, 2 * MAG_BITS); arb_zero(y); arf_set_mag(arb_midref(y), zbound); if (!arb_le(x, y)) { flint_printf("FAIL: bound\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("sb = "); acb_printn(sb, 50, 0); flint_printf("\n\n"); flint_printf("z = "); acb_printn(z, 50, 0); flint_printf("\n\n"); flint_printf("zbound = "); mag_printd(zbound, 10); flint_printf("\n\n"); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 50, 0); flint_printf("\n\n"); flint_abort(); } } acb_clear(s); acb_clear(sb); acb_clear(z); arb_clear(x); arb_clear(y); mag_clear(zbound); } /* test deriv_bound */ for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { acb_t s; acb_ptr v; mag_t b, b1, b2, m, m1, m2; acb_init(s); v = _acb_vec_init(3); mag_init(b); mag_init(b1); mag_init(b2); mag_init(m); mag_init(m1); mag_init(m2); acb_randtest(s, state, 2 + n_randint(state, 100), 2); arb_mul_ui(acb_realref(s), acb_realref(s), n_randtest(state) % 100, 100); arb_mul_ui(acb_imagref(s), acb_imagref(s), n_randtest(state) % 10000, 100); acb_dirichlet_zeta_bound(b, s); acb_dirichlet_zeta_deriv_bound(b1, b2, s); acb_get_mid(s, s); acb_dirichlet_zeta_jet(v, s, 0, 3, 53); acb_get_mag(m, v); acb_get_mag(m1, v + 1); acb_get_mag(m2, v + 2); if (mag_cmp(m, b) > 0 || mag_cmp(m1, b1) > 0 || mag_cmp(m2, b2) > 0) { flint_printf("FAIL\n\n"); acb_printn(s, 30, 0); flint_printf("\n\n"); mag_printd(m, 10); flint_printf(" "); mag_printd(b, 10); flint_printf("\n\n"); mag_printd(m1, 10); flint_printf(" "); mag_printd(b1, 10); flint_printf("\n\n"); mag_printd(m2, 10); flint_printf(" "); mag_printd(b2, 10); flint_printf("\n\n"); flint_abort(); } acb_clear(s); _acb_vec_clear(v, 3); mag_clear(b); mag_clear(b1); mag_clear(b2); mag_clear(m); mag_clear(m1); mag_clear(m2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_jet_rs.c000066400000000000000000000070351417376376500210430ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_jet_rs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { acb_t s1, s2, a; acb_ptr r1, r2; slong prec1, prec2, len; acb_init(a); acb_init(s1); acb_init(s2); r1 = _acb_vec_init(2); r2 = _acb_vec_init(2); len = 1 + n_randint(state, 2); if (n_randint(state, 2)) arb_set_d(acb_realref(s1), 0.5); else arb_randtest(acb_realref(s1), state, 2 + n_randint(state, 100), 2); arb_randtest(acb_imagref(s1), state, 2 + n_randint(state, 100), 2); arb_add_ui(acb_imagref(s1), acb_imagref(s1), n_randtest(state) % 1000, 100); acb_set(s2, s1); acb_randtest(r1, state, 2 + n_randint(state, 100), 3); acb_randtest(r2, state, 2 + n_randint(state, 100), 3); if (len > 1) { acb_randtest(r1 + 1, state, 2 + n_randint(state, 100), 3); acb_randtest(r2 + 1, state, 2 + n_randint(state, 100), 3); } prec1 = 2 + n_randint(state, 150); prec2 = 2 + n_randint(state, 150); if (n_randint(state, 4) == 0) { mag_zero(arb_radref(acb_realref(s2))); mag_zero(arb_radref(acb_imagref(s2))); } if (n_randint(state, 4) == 0) { if (n_randint(state, 2)) arb_get_ubound_arf(arb_midref(acb_realref(s2)), acb_realref(s2), ARF_PREC_EXACT); else arb_get_lbound_arf(arb_midref(acb_realref(s2)), acb_realref(s2), ARF_PREC_EXACT); mag_zero(arb_radref(acb_realref(s2))); } if (n_randint(state, 4) == 0) { if (n_randint(state, 2)) arb_get_ubound_arf(arb_midref(acb_imagref(s2)), acb_imagref(s2), ARF_PREC_EXACT); else arb_get_lbound_arf(arb_midref(acb_imagref(s2)), acb_imagref(s2), ARF_PREC_EXACT); mag_zero(arb_radref(acb_imagref(s2))); } acb_dirichlet_zeta_jet_rs(r1, s1, len, prec1); acb_one(a); _acb_poly_zeta_cpx_series(r2, s2, a, 0, len, prec2); if (!acb_overlaps(r1, r2) || !acb_overlaps(r1 + 1, r2 + 1)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd, len = %wd\n", iter, len); flint_printf("s1 = "); acb_printn(s1, 50, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 50, 0); flint_printf("\n\n"); flint_printf("r1[0] = "); acb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2[0] = "); acb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("r1[1] = "); acb_printn(r1 + 1, 50, 0); flint_printf("\n\n"); flint_printf("r2[1] = "); acb_printn(r2 + 1, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(s1); acb_clear(s2); _acb_vec_clear(r1, 2); _acb_vec_clear(r2, 2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_nzeros.c000066400000000000000000000077201417376376500210760ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_nzeros...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 130 + 20 * arb_test_multiplier(); iter++) { arb_t x, y, t; arf_t f1, f2; fmpz_t n, m, k1, k2; acb_t z; slong prec1, prec2; arb_init(x); arb_init(y); arb_init(t); acb_init(z); arf_init(f1); arf_init(f2); fmpz_init(n); fmpz_init(m); fmpz_init(k1); fmpz_init(k2); if (iter < 130) { fmpz_set_si(n, iter + 1); } else { fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 131); } prec1 = 2 + n_randtest(state) % 50; prec2 = 2 + n_randtest(state) % 200; acb_dirichlet_hardy_z_zero(t, n, prec1); acb_dirichlet_zeta_nzeros(x, t, prec2); fmpz_sub_ui(m, n, 1); if (!arb_contains_fmpz(x, n) || !arb_contains_fmpz(x, m)) { flint_printf("FAIL: zero containment\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("t = "); arb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_get_lbound_arf(f1, t, prec1); arb_get_ubound_arf(f2, t, prec1); _acb_dirichlet_exact_zeta_nzeros(k1, f1); _acb_dirichlet_exact_zeta_nzeros(k2, f2); if (!(fmpz_cmp(k1, n) < 0 && fmpz_cmp(k2, n) >= 0)) { flint_printf("FAIL: near a zero\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("f2 = "); arf_print(f2); flint_printf("\n\n"); flint_printf("k1 = "); fmpz_print(k1); flint_printf("\n\n"); flint_printf("k2 = "); fmpz_print(k2); flint_printf("\n\n"); flint_abort(); } fmpz_sub_ui(m, n, 2); acb_dirichlet_gram_point(t, m, NULL, NULL, prec1); arb_get_lbound_arf(f1, t, prec1); arb_get_ubound_arf(f2, t, prec1); arb_set_interval_arf(t, f1, f2, prec1); acb_set_arb(z, t); acb_dirichlet_hardy_z(z, z, NULL, NULL, 1, prec1); if (!acb_contains_zero(z)) { _acb_dirichlet_exact_zeta_nzeros(k1, f1); _acb_dirichlet_exact_zeta_nzeros(k2, f2); if (!fmpz_equal(k1, k2)) { flint_printf("FAIL: near a gram point\n\n"); flint_printf("m = "); fmpz_print(m); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("f2 = "); arf_print(f2); flint_printf("\n\n"); flint_printf("k1 = "); fmpz_print(k1); flint_printf("\n\n"); flint_printf("k2 = "); fmpz_print(k2); flint_printf("\n\n"); flint_abort(); } } arb_clear(x); arb_clear(y); arb_clear(t); acb_clear(z); arf_clear(f1); arf_clear(f2); fmpz_clear(n); fmpz_clear(m); fmpz_clear(k1); fmpz_clear(k2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_nzeros_gram.c000066400000000000000000000036011417376376500220760ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_nzeros_gram...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 130 + 20 * arb_test_multiplier(); iter++) { arb_t t, x; fmpz_t N, n; slong prec1, prec2; arb_init(t); arb_init(x); fmpz_init(n); fmpz_init(N); if (iter < 130) { fmpz_set_si(n, iter - 1); } else { fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 129); } prec1 = 2 + n_randtest(state) % 100; prec2 = 2 + n_randtest(state) % 100; acb_dirichlet_zeta_nzeros_gram(N, n); acb_dirichlet_gram_point(t, n, NULL, NULL, prec1); acb_dirichlet_zeta_nzeros(x, t, prec2); if (!arb_contains_fmpz(x, N)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("N = "); fmpz_print(N); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 100, 0); flint_printf("\n\n"); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(t); arb_clear(x); fmpz_clear(n); fmpz_clear(N); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_rs.c000066400000000000000000000045351417376376500202030ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_rs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t z1, z2, s1, s2; slong prec1, prec2, K1; acb_init(z1); acb_init(z2); acb_init(s1); acb_init(s2); if (n_randint(state, 2)) arb_set_d(acb_realref(s1), 0.5); else arb_randtest(acb_realref(s1), state, 2 + n_randint(state, 100), 2); arb_randtest(acb_imagref(s1), state, 2 + n_randint(state, 100), 2); arb_add_ui(acb_imagref(s1), acb_imagref(s1), n_randtest(state) % 1000, 100); acb_randtest(z1, state, 2 + n_randint(state, 100), 3); acb_randtest(z2, state, 2 + n_randint(state, 100), 3); prec1 = 2 + n_randint(state, 150); prec2 = 2 + n_randint(state, 150); K1 = n_randint(state, 10); if (n_randint(state, 2)) { mag_zero(arb_radref(acb_realref(s1))); mag_zero(arb_radref(acb_imagref(s1))); } acb_set(s2, s1); acb_dirichlet_zeta_rs(z1, s1, K1, prec1); acb_zeta(z2, s2, prec2); /* should be Euler-Maclaurin */ if (!acb_overlaps(z1, z2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("K1 = %wd\n\n", K1); flint_printf("s1 = "); acb_printn(s1, 50, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 50, 0); flint_printf("\n\n"); flint_printf("z1 = "); acb_printn(z1, 50, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z1); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_rs_r.c000066400000000000000000000051501417376376500205160ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_rs_r...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t z1, z2, s1, s2; slong prec1, prec2, K1, K2; acb_init(z1); acb_init(z2); acb_init(s1); acb_init(s2); if (n_randint(state, 2)) arb_set_d(acb_realref(s1), 0.5); else arb_randtest(acb_realref(s1), state, 2 + n_randint(state, 100), 2); arb_randtest(acb_imagref(s1), state, 2 + n_randint(state, 100), 2); arb_abs(acb_imagref(s1), acb_imagref(s1)); arb_add_ui(acb_imagref(s1), acb_imagref(s1), n_randtest(state) % 1000000, 100); acb_randtest(z1, state, 2 + n_randint(state, 100), 3); acb_randtest(z2, state, 2 + n_randint(state, 100), 3); prec1 = 2 + n_randint(state, 150); prec2 = 2 + n_randint(state, 150); K1 = n_randint(state, 10); K2 = n_randint(state, 10); if (n_randint(state, 2)) { mag_zero(arb_radref(acb_realref(s1))); mag_zero(arb_radref(acb_imagref(s1))); } if (n_randint(state, 2)) { acb_set(s2, s1); } else { acb_add(s2, s1, z1, prec2); acb_sub(s2, s2, z1, prec2); } acb_dirichlet_zeta_rs_r(z1, s1, K1, prec1); acb_dirichlet_zeta_rs_r(z2, s2, K2, prec2); if (!acb_overlaps(z1, z2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("K1 = %wd, K2 = %wd\n\n", K1, K2); flint_printf("s1 = "); acb_printn(s1, 50, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 50, 0); flint_printf("\n\n"); flint_printf("z1 = "); acb_printn(z1, 50, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(s1); acb_clear(s2); acb_clear(z1); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_zero.c000066400000000000000000000054431417376376500205350ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_zero...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { acb_t v1, v2, z1, z2; fmpz_t n, m; slong prec1, prec2; acb_init(v1); acb_init(v2); acb_init(z1); acb_init(z2); fmpz_init(n); fmpz_init(m); fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 1); if (n_randint(state, 10) != 0) { prec1 = 2 + n_randtest(state) % 50; prec2 = 2 + n_randtest(state) % 200; } else { prec1 = 2 + n_randtest(state) % 200; prec2 = 2 + n_randtest(state) % 600; } acb_dirichlet_zeta_zero(z1, n, prec1); acb_dirichlet_zeta_zero(z2, n, prec2); acb_dirichlet_zeta(v1, z1, prec1 + 20); acb_dirichlet_zeta(v2, z2, prec2 + 20); if (!acb_overlaps(z1, z2) || !acb_contains_zero(v1) || !acb_contains_zero(v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("z1 = "); acb_printn(z1, 100, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 100, 0); flint_printf("\n\n"); flint_printf("v1 = "); acb_printn(v1, 100, 0); flint_printf("\n\n"); flint_printf("v2 = "); acb_printn(v2, 100, 0); flint_printf("\n\n"); flint_abort(); } if (acb_rel_accuracy_bits(z1) < prec1 - 3 || acb_rel_accuracy_bits(z2) < prec2 - 3) { flint_printf("FAIL: accuracy\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("acc(z1) = %wd, acc(z2) = %wd\n\n", acb_rel_accuracy_bits(z1), acb_rel_accuracy_bits(z2)); flint_printf("z1 = "); acb_printn(z1, 100, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 100, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(z1); acb_clear(z2); acb_clear(v1); acb_clear(v2); fmpz_clear(n); fmpz_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/test/t-zeta_zeros.c000066400000000000000000000056551417376376500207250ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_zeros...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { acb_t v1, v2, z1, z2; fmpz_t n, m, k; acb_ptr p; slong prec1, prec2; slong i, len; const slong maxlen = 5; acb_init(v1); acb_init(v2); acb_init(z1); acb_init(z2); fmpz_init(n); fmpz_init(m); fmpz_init(k); p = _acb_vec_init(maxlen); fmpz_randtest_unsigned(n, state, 20); fmpz_add_ui(n, n, 1); prec1 = 2 + n_randtest(state) % 50; prec2 = 2 + n_randtest(state) % 200; len = 1 + n_randint(state, maxlen); i = n_randint(state, len); acb_dirichlet_zeta_zeros(p, n, len, prec1); acb_set(z1, p + i); fmpz_add_si(k, n, i); acb_dirichlet_zeta_zero(z2, k, prec2); acb_dirichlet_zeta(v1, z1, prec1 + 20); acb_dirichlet_zeta(v2, z2, prec2 + 20); if (!acb_overlaps(z1, z2) || !acb_contains_zero(v1) || !acb_contains_zero(v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("z1 = "); acb_printn(z1, 100, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 100, 0); flint_printf("\n\n"); flint_printf("v1 = "); acb_printn(v1, 100, 0); flint_printf("\n\n"); flint_printf("v2 = "); acb_printn(v2, 100, 0); flint_printf("\n\n"); flint_abort(); } if (acb_rel_accuracy_bits(z1) < prec1 - 3 || acb_rel_accuracy_bits(z2) < prec2 - 3) { flint_printf("FAIL: accuracy\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("acc(z1) = %wd, acc(z2) = %wd\n\n", acb_rel_accuracy_bits(z1), acb_rel_accuracy_bits(z2)); flint_printf("z1 = "); acb_printn(z1, 100, 0); flint_printf("\n\n"); flint_printf("z2 = "); acb_printn(z2, 100, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(z1); acb_clear(z2); acb_clear(v1); acb_clear(v2); fmpz_clear(n); fmpz_clear(m); fmpz_clear(k); _acb_vec_clear(p, maxlen); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_dirichlet/theta_arb.c000066400000000000000000000055261417376376500172460ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void _acb_dirichlet_theta_arb_smallorder(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t xt, slong len, slong prec) { ulong order; ulong * a; int parity; acb_dirichlet_roots_t z; parity = dirichlet_parity_char(G, chi); order = dirichlet_order_char(G, chi); a = flint_malloc(len * sizeof(ulong)); dirichlet_chi_vec_order(a, G, chi, order, len); acb_dirichlet_roots_init(z, order, 0, prec); acb_dirichlet_qseries_arb_powers_smallorder(res, xt, parity, a, z, len, prec); acb_dirichlet_roots_clear(z); flint_free(a); } void _acb_dirichlet_theta_arb_series(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t xt, slong len, slong prec) { acb_ptr a; a = _acb_vec_init(len); acb_dirichlet_chi_vec(a, G, chi, len, prec); if (dirichlet_parity_char(G, chi)) { slong k; for (k = 2; k < len; k++) acb_mul_si(a + k, a + k, k, prec); } acb_dirichlet_qseries_arb(res, a, xt, len, prec); _acb_vec_clear(a, len); } void _acb_dirichlet_theta_arb_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t xt, slong len, slong prec) { ulong order, * a; acb_dirichlet_roots_t z; int parity; parity = dirichlet_parity_char(G, chi); order = dirichlet_order_char(G, chi); a = flint_malloc(len * sizeof(ulong)); dirichlet_chi_vec_order(a, G, chi, order, len); acb_dirichlet_roots_init(z, order, len, prec); acb_dirichlet_qseries_arb_powers_naive(res, xt, parity, a, z, len, prec); acb_dirichlet_roots_clear(z); flint_free(a); } void acb_dirichlet_theta_arb(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t t, slong prec) { slong len; ulong order; arb_t xt; mag_t e; len = acb_dirichlet_theta_length(G->q, t, prec); arb_init(xt); _acb_dirichlet_theta_argument_at_arb(xt, G->q, t, prec); mag_init(e); mag_tail_kexpk2_arb(e, xt, len); arb_neg(xt, xt); arb_exp(xt, xt, prec); /* TODO: tune this limit */ order = dirichlet_order_char(G, chi); if (order < 30) _acb_dirichlet_theta_arb_smallorder(res, G, chi, xt, len, prec); else _acb_dirichlet_theta_arb_naive(res, G, chi, xt, len, prec); arb_add_error_mag(acb_realref(res), e); arb_add_error_mag(acb_imagref(res), e); mag_clear(e); acb_mul_2exp_si(res, res, 1); arb_clear(xt); } arb-2.22.1/acb_dirichlet/theta_length.c000066400000000000000000000037071417376376500177620ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include #define PI 3.14159265358 #define LOG2 0.69314718055 ulong acb_dirichlet_theta_length_d(ulong q, double t, slong prec) { double a, la; a = PI / (double)q * t * t; la = (a < .3) ? -log(2*a*(1-a)) : .8; la = ((double)prec * LOG2 + la) / a; return ceil(sqrt(la)+.5); } ulong acb_dirichlet_theta_length(ulong q, const arb_t t, slong prec) { double dt; ulong len; arf_t at; arf_init(at); arb_get_lbound_arf(at, t, 53); dt = arf_get_d(at, ARF_RND_DOWN); len = acb_dirichlet_theta_length_d(q, dt, prec); arf_clear(at); return len; } /* bound for sum_{k>n} k*exp(-a k^2) */ void mag_tail_kexpk2_arb(mag_t res, const arb_t a, ulong n) { mag_t m; mag_init(m); arb_get_mag_lower(m, a); /* a < 1/4 */ if (mag_cmp_2exp_si(m, -2) <= 0) { mag_t c; mag_init(c); mag_mul_ui_lower(res, m, n*n-n+1); /* todo: possible overflow */ mag_expinv(res, res); /* c = 2a(1+2a) */ mag_mul_2exp_si(m, m, 1); mag_one(c); mag_add_lower(c, m, c); mag_mul_lower(c, m, c); mag_div(res, res, c); mag_clear(c); } else { mag_mul_ui_lower(res, m, n*n-n-1); /* todo: possible overflow */ mag_expinv(res, res); mag_mul_ui(res, res, 2); } mag_clear(m); } /* a(t) = Pi / q * t^2 */ void _acb_dirichlet_theta_argument_at_arb(arb_t xt, ulong q, const arb_t t, slong prec) { arb_const_pi(xt, prec); arb_div_ui(xt, xt, q, prec); arb_mul(xt, xt, t, prec); arb_mul(xt, xt, t, prec); } arb-2.22.1/acb_dirichlet/turing_method_bound.c000066400000000000000000000027451417376376500213540ustar00rootroot00000000000000/* Copyright (C) 2019 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _mag_div_ui_ui(mag_t res, ulong a, ulong b) { mag_set_ui(res, a); mag_div_ui(res, res, b); } ulong acb_dirichlet_turing_method_bound(const fmpz_t p) { ulong result; arb_t t; fmpz_t k; mag_t m, b1, b2, c; arb_init(t); fmpz_init(k); mag_init(m); mag_init(b1); mag_init(b2); mag_init(c); acb_dirichlet_gram_point(t, p, NULL, NULL, FLINT_MAX(8, fmpz_bits(p))); arb_get_mag(m, t); mag_log(m, m); /* b1 = 0.0061*log(gram(p))^2 + 0.08*log(gram(p)) */ _mag_div_ui_ui(c, 61, 10000); mag_mul(b1, c, m); _mag_div_ui_ui(c, 8, 100); mag_add(b1, b1, c); mag_mul(b1, b1, m); /* b2 = 0.0031*log(gram(p))^2 + 0.11*log(gram(p)) */ _mag_div_ui_ui(c, 31, 10000); mag_mul(b2, c, m); _mag_div_ui_ui(c, 11, 100); mag_add(b2, b2, c); mag_mul(b2, b2, m); /* result = ceil(min(b1, b2)) */ mag_min(m, b1, b2); mag_get_fmpz(k, m); result = fmpz_get_ui(k); arb_clear(t); fmpz_clear(k); mag_clear(m); mag_clear(b1); mag_clear(b2); mag_clear(c); return result; } arb-2.22.1/acb_dirichlet/ui_theta_arb.c000066400000000000000000000012641417376376500177360ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_ui_theta_arb(acb_t res, const dirichlet_group_t G, ulong a, const arb_t t, slong prec) { dirichlet_char_t chi; dirichlet_char_init(chi, G); dirichlet_char_log(chi, G, a); acb_dirichlet_theta_arb(res, G, chi, t, prec); dirichlet_char_clear(chi); } arb-2.22.1/acb_dirichlet/vec_mellin_arb.c000066400000000000000000000030351417376376500202470ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_vec_mellin_arb(acb_ptr res, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, const arb_t t, slong n, slong prec) { slong k; arb_t tk, xt, stk, st; acb_ptr a; mag_t e; a = _acb_vec_init(len); acb_dirichlet_chi_vec(a, G, chi, len, prec); if (dirichlet_parity_char(G, chi)) { for (k = 2; k < len; k++) acb_mul_si(a + k, a + k, k, prec); } arb_init(tk); arb_init(xt); arb_init(st); arb_init(stk); mag_init(e); arb_sqrt(st, t, prec); arb_one(tk); arb_one(stk); for (k = 0; k < n; k++) { _acb_dirichlet_theta_argument_at_arb(xt, G->q, tk, prec); mag_tail_kexpk2_arb(e, xt, len); arb_neg(xt, xt); arb_exp(xt, xt, prec); /* TODO: reduce len */ acb_dirichlet_qseries_arb(res + k, a, xt, len, prec); acb_add_error_mag(res + k, e); acb_mul_arb(res + k, res + k, stk, prec); arb_mul(tk, tk, t, prec); arb_mul(stk, stk, st, prec); } mag_clear(e); arb_clear(xt); arb_clear(tk); arb_clear(stk); arb_clear(st); _acb_vec_clear(a, len); } arb-2.22.1/acb_dirichlet/xi.c000066400000000000000000000032551417376376500157320ustar00rootroot00000000000000/* Copyright (C) 2018 D.H.J Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _acb_dirichlet_xi(acb_t res, const acb_t s, slong prec) { acb_t pi, z1, z2, z3; acb_init(pi); acb_init(z1); acb_init(z2); acb_init(z3); /* (s-1) * pi^(-s/2) * gamma(1 + s/2) * zeta(s) */ acb_const_pi(pi, prec); acb_mul_2exp_si(z1, s, -1); acb_neg(z1, z1); acb_pow(z1, pi, z1, prec); acb_mul_2exp_si(z2, s, -1); acb_add_ui(z2, z2, 1, prec); acb_gamma(z2, z2, prec); acb_zeta(z3, s, prec); acb_sub_ui(res, s, 1, prec); acb_mul(res, res, z1, prec); acb_mul(res, res, z2, prec); acb_mul(res, res, z3, prec); acb_clear(pi); acb_clear(z1); acb_clear(z2); acb_clear(z3); } void acb_dirichlet_xi(acb_t res, const acb_t s, slong prec) { if (!acb_is_finite(s)) { acb_indeterminate(res); } else if (acb_is_one(s)) { acb_one(res); acb_mul_2exp_si(res, res, -1); } else if ((arf_sgn(arb_midref(acb_realref(s))) < 0 && !acb_contains_zero(s)) || (arb_contains_si(acb_realref(s), 1) && /* also intervals around s = 1 */ arb_contains_zero(acb_imagref(s)))) { acb_sub_ui(res, s, 1, prec); acb_neg(res, res); _acb_dirichlet_xi(res, res, prec); } else { _acb_dirichlet_xi(res, s, prec); } } arb-2.22.1/acb_dirichlet/zeta.c000066400000000000000000000044051417376376500162530ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_zeta_si(acb_t z, slong s, slong prec); static void _acb_dirichlet_zeta(acb_t res, const acb_t s, slong prec) { acb_t a; acb_init(a); acb_one(a); _acb_poly_zeta_cpx_series(res, s, a, 0, 1, prec); acb_clear(a); } /* todo: use euler product for complex s, and check efficiency for large negative integers */ void acb_dirichlet_zeta(acb_t res, const acb_t s, slong prec) { double cutoff; if (acb_is_int(s) && arf_cmpabs_2exp_si(arb_midref(acb_realref(s)), FLINT_BITS - 1) < 0) { acb_zeta_si(res, arf_get_si(arb_midref(acb_realref(s)), ARF_RND_DOWN), prec); return; } if (arb_contains_zero(acb_imagref(s)) && arb_contains_si(acb_realref(s), 1)) { acb_indeterminate(res); return; } cutoff = 24.0 * prec * sqrt(prec); if (arf_cmpabs_d(arb_midref(acb_imagref(s)), cutoff) >= 0 && arf_cmpabs_d(arb_midref(acb_realref(s)), 10 + prec * 0.1) <= 0) { acb_dirichlet_zeta_rs(res, s, 0, prec); return; } if ((arf_sgn(arb_midref(acb_realref(s))) < 0) && !acb_contains_zero(s)) { acb_t t, u, v; slong wp = prec + 6; acb_init(t); acb_init(u); acb_init(v); acb_sub_ui(t, s, 1, wp); /* 2 * (2pi)^(s-1) */ arb_const_pi(acb_realref(u), wp); acb_mul_2exp_si(u, u, 1); acb_pow(u, u, t, wp); acb_mul_2exp_si(u, u, 1); /* sin(pi*s/2) */ acb_mul_2exp_si(v, s, -1); acb_sin_pi(v, v, wp); acb_mul(u, u, v, wp); /* gamma(1-s) zeta(1-s) */ acb_neg(t, t); acb_gamma(v, t, wp); acb_mul(u, u, v, wp); _acb_dirichlet_zeta(v, t, prec); acb_mul(res, u, v, prec); acb_clear(t); acb_clear(u); acb_clear(v); } else { _acb_dirichlet_zeta(res, s, prec); } } arb-2.22.1/acb_dirichlet/zeta_bound.c000066400000000000000000000166531417376376500174520ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" static void _mag_pow(mag_t res, const mag_t x, const mag_t y) { arb_t t, u; arb_init(t); arb_init(u); arf_set_mag(arb_midref(t), x); arf_set_mag(arb_midref(u), y); arb_pow(t, t, u, 2 * MAG_BITS); arb_get_mag(res, t); arb_clear(t); arb_clear(u); } /* zeta(1+s) < 1+1/s */ static void mag_zeta1p(mag_t res, const mag_t s) { mag_t t; mag_init(t); mag_one(t); mag_div(t, t, s); mag_add_ui(res, t, 1); mag_clear(t); } /* |zeta(s)| <= (2pi)^sigma |gamma(1-s)| exp(pi|t|/2) zeta(1-sigma) / pi */ void acb_dirichlet_zeta_bound_functional_equation(mag_t res, const acb_t s) { slong prec, p; acb_t z; arb_t x; mag_t t; if (!arb_is_negative(acb_realref(s))) { mag_inf(res); return; } acb_init(z); arb_init(x); mag_init(t); prec = 0; p = arf_abs_bound_lt_2exp_si(arb_midref(acb_imagref(s))); prec = FLINT_MAX(p, prec); p = arf_abs_bound_lt_2exp_si(arb_midref(acb_realref(s))); prec = FLINT_MAX(p, prec); /* we *could* increase the precision even further to return finite results for huge input... but there's not much practical reason to... */ prec = FLINT_MIN(prec, 1000); prec += MAG_BITS; /* gamma(1-s) */ acb_sub_ui(z, s, 1, prec); acb_neg(z, z); acb_gamma(z, z, prec); acb_get_mag(res, z); /* (2pi)^sigma */ arb_const_pi(x, prec); arb_mul_2exp_si(x, x, 1); arb_pow(x, x, acb_realref(s), prec); arb_get_mag(t, x); mag_mul(res, res, t); /* 1/pi */ mag_div_ui(res, res, 3); /* exp(pi|t|/2) */ arb_const_pi(x, prec); arb_mul(x, x, acb_imagref(s), prec); arb_abs(x, x); arb_mul_2exp_si(x, x, -1); arb_exp(x, x, prec); arb_get_mag(t, x); mag_mul(res, res, t); /* zeta(1-s) */ arb_neg(x, acb_realref(s)); arb_get_mag_lower(t, x); mag_zeta1p(t, t); mag_mul(res, res, t); acb_clear(z); arb_clear(x); mag_clear(t); } /* Rademacher 43.3: Assume -eta <= sigma <= 1 + eta where 0 < eta <= 1/2. Then: |zeta(s)| < 3 |(1+s)/(1-s)| |(1+s)/(2pi)|^e zeta(1+eta) where e = (1+eta-sigma)/2. Inside the strip, we use this formula with eta = 0.1 (this could be improved). */ void acb_dirichlet_zeta_bound_strip(mag_t res, const acb_t s) { arf_t eta, a; acb_t s1; mag_t t, u, v; acb_init(s1); arf_init(eta); arf_init(a); mag_init(t); mag_init(u); mag_init(v); /* We need -eta <= sigma <= 1 + eta where sigma = m +/- r, i.e. eta >= max(-m, m-1) + r. */ arf_neg(eta, arb_midref(acb_realref(s))); arf_sub_ui(a, arb_midref(acb_realref(s)), 1, MAG_BITS, ARF_RND_CEIL); arf_max(eta, eta, a); arf_set_mag(a, arb_radref(acb_realref(s))); arf_add(eta, eta, a, MAG_BITS, ARF_RND_CEIL); /* eta = max(eta, 0.1), to avoid the pole */ arf_set_d(a, 0.1); arf_max(eta, eta, a); /* Requires 0 <= eta <= 1/2. */ if (arf_cmpabs_2exp_si(eta, -1) <= 0) { /* t = |1+s|/(2pi) */ acb_add_ui(s1, s, 1, MAG_BITS); acb_get_mag(t, s1); mag_set_ui_2exp_si(u, 163, -10); /* 1/(2pi) < 163/1024 */ mag_mul(t, t, u); /* a = (1+eta-sigma)/2 */ arf_set_mag(a, arb_radref(acb_realref(s))); arf_add(a, eta, a, MAG_BITS, ARF_RND_CEIL); arf_sub(a, a, arb_midref(acb_realref(s)), MAG_BITS, ARF_RND_CEIL); arf_add_ui(a, a, 1, MAG_BITS, ARF_RND_CEIL); arf_mul_2exp_si(a, a, -1); if (arf_sgn(a) < 0) arf_zero(a); arf_get_mag(u, a); /* t = (|1+s|/(2pi))^((1+eta-sigma)/2) */ _mag_pow(t, t, u); /* 3|1+s|/|1-s| */ acb_get_mag(u, s1); mag_mul(t, t, u); acb_sub_ui(s1, s, 1, MAG_BITS); acb_get_mag_lower(u, s1); mag_div(t, t, u); mag_mul_ui(t, t, 3); /* zeta(1+eta) */ arf_get_mag_lower(u, eta); mag_zeta1p(u, u); mag_mul(t, t, u); mag_set(res, t); } else { mag_inf(res); } acb_clear(s1); arf_clear(eta); arf_clear(a); mag_clear(t); mag_clear(u); mag_clear(v); } /* We have three cases: Rademacher's bound valid on -0.5 <= sigma <= 1.5, the trivial bound on sigma > 1, and the functional equation valid on sigma < 0. We intersect s with three separate domains for evaluation: right, inside, and left of the extended strip [-0.25,1.25]. Sharper bounds could be used precisely when sigma = 1/2, or very close to the line sigma = 1. */ void acb_dirichlet_zeta_bound(mag_t res, const acb_t s) { arb_t strip; mag_t t; if (!acb_is_finite(s)) { mag_inf(res); return; } arb_init(strip); mag_init(t); arf_set_ui_2exp_si(arb_midref(strip), 1, -1); mag_set_ui_2exp_si(arb_radref(strip), 3, -2); if (arb_le(strip, acb_realref(s))) { arb_get_mag_lower(res, acb_realref(s)); mag_one(t); mag_sub_lower(res, res, t); mag_zeta1p(res, res); } else if (arb_contains(strip, acb_realref(s))) { acb_dirichlet_zeta_bound_strip(res, s); } else if (arb_le(acb_realref(s), strip)) { acb_dirichlet_zeta_bound_functional_equation(res, s); } else { acb_t ss; arf_t x1, x2; acb_init(ss); arf_init(x1); arf_init(x2); /* Since s overlaps at least two regions, it must certainly overlap with the extended strip. */ arb_set(acb_imagref(ss), acb_imagref(s)); arb_intersection(acb_realref(ss), acb_realref(s), strip, MAG_BITS); acb_dirichlet_zeta_bound_strip(res, ss); /* We may have real parts > 1.25. */ /* The bound computed for the extended strip *should* already be larger than zeta(1.25) < 5, but just to be sure... */ mag_set_ui(t, 5); mag_max(res, res, t); /* Finally, we may have have real parts < -0.25. */ arf_set_mag(x1, arb_radref(acb_realref(s))); arf_sub(x1, arb_midref(acb_realref(s)), x1, MAG_BITS, ARF_RND_FLOOR); arf_set_d(x2, -0.25); if (arf_cmp(x1, x2) < 0) { arb_set_interval_arf(acb_realref(ss), x1, x2, MAG_BITS); acb_dirichlet_zeta_bound_functional_equation(t, ss); mag_max(res, res, t); } acb_clear(ss); arf_clear(x1); arf_clear(x2); } arb_clear(strip); mag_clear(t); } /* |f'(s)| <= |f(s +/- R)| / R |f''(s)| <= 2 |f(s +/- R)| / R^2 */ void acb_dirichlet_zeta_deriv_bound(mag_t der1, mag_t der2, const acb_t s) { mag_t R, M; acb_t t; mag_init(R); mag_init(M); acb_init(t); /* R = 1/8 */ mag_set_ui_2exp_si(R, 1, -3); /* t = s +/- R */ acb_set(t, s); mag_add(arb_radref(acb_realref(t)), arb_radref(acb_realref(t)), R); mag_add(arb_radref(acb_imagref(t)), arb_radref(acb_imagref(t)), R); /* M = |f(s +/- R)| */ acb_dirichlet_zeta_bound(M, t); /* der1 = |f'(s)| */ mag_div(der1, M, R); /* der2 = |f''(s)| */ mag_div(der2, der1, R); mag_mul_2exp_si(der2, der2, 1); acb_clear(t); mag_clear(R); mag_clear(M); } arb-2.22.1/acb_dirichlet/zeta_jet.c000066400000000000000000000075071417376376500171230ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void _acb_dirichlet_zeta_jet(acb_t t, const acb_t h, int deflate, slong len, slong prec) { acb_t a; acb_init(a); acb_one(a); /* use reflection formula */ if (arf_sgn(arb_midref(acb_realref(h))) < 0) { /* zeta(s) = (2*pi)**s * sin(pi*s/2) / pi * gamma(1-s) * zeta(1-s) */ acb_t pi, hcopy; acb_ptr f, s1, s2, s3, s4, u; slong i; acb_init(pi); acb_init(hcopy); f = _acb_vec_init(2); s1 = _acb_vec_init(len); s2 = _acb_vec_init(len); s3 = _acb_vec_init(len); s4 = _acb_vec_init(len); u = _acb_vec_init(len); acb_set(hcopy, h); acb_const_pi(pi, prec); /* s1 = (2*pi)**s */ acb_mul_2exp_si(pi, pi, 1); _acb_poly_pow_cpx(s1, pi, h, len, prec); acb_mul_2exp_si(pi, pi, -1); /* s2 = sin(pi*s/2) / pi */ acb_set(f, h); acb_one(f + 1); acb_mul_2exp_si(f, f, -1); acb_mul_2exp_si(f + 1, f + 1, -1); _acb_poly_sin_pi_series(s2, f, 2, len, prec); _acb_vec_scalar_div(s2, s2, len, pi, prec); /* s3 = gamma(1-s) */ acb_sub_ui(f, hcopy, 1, prec); acb_neg(f, f); acb_set_si(f + 1, -1); _acb_poly_gamma_series(s3, f, 2, len, prec); /* s4 = zeta(1-s) */ acb_sub_ui(f, hcopy, 1, prec); acb_neg(f, f); _acb_poly_zeta_cpx_series(s4, f, a, 0, len, prec); for (i = 1; i < len; i += 2) acb_neg(s4 + i, s4 + i); _acb_poly_mullow(u, s1, len, s2, len, len, prec); _acb_poly_mullow(s1, s3, len, s4, len, len, prec); _acb_poly_mullow(t, u, len, s1, len, len, prec); /* add 1/(1-(s+t)) = 1/(1-s) + t/(1-s)^2 + ... */ if (deflate) { acb_sub_ui(u, hcopy, 1, prec); acb_neg(u, u); acb_inv(u, u, prec); for (i = 1; i < len; i++) acb_mul(u + i, u + i - 1, u, prec); _acb_vec_add(t, t, u, len, prec); } acb_clear(pi); acb_clear(hcopy); _acb_vec_clear(f, 2); _acb_vec_clear(s1, len); _acb_vec_clear(s2, len); _acb_vec_clear(s3, len); _acb_vec_clear(s4, len); _acb_vec_clear(u, len); } else { _acb_poly_zeta_cpx_series(t, h, a, deflate, len, prec); } acb_clear(a); } /* todo: should adjust precision to input accuracy */ void acb_dirichlet_zeta_jet(acb_t res, const acb_t s, int deflate, slong len, slong prec) { double cutoff; if (len == 1 && deflate == 0) { acb_zeta(res, s, prec); return; } if (deflate == 0 && (arb_contains_zero(acb_imagref(s)) && arb_contains_si(acb_realref(s), 1))) { _acb_vec_indeterminate(res, len); return; } if (len > 2 || deflate != 0) { _acb_dirichlet_zeta_jet(res, s, deflate, len, prec); } else { cutoff = 24.0 * prec * sqrt(prec); if (arb_is_exact(acb_realref(s)) && arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0) cutoff *= 2.5; else cutoff *= 4.0; if (arf_cmpabs_d(arb_midref(acb_imagref(s)), cutoff) >= 0 && arf_cmpabs_d(arb_midref(acb_realref(s)), 10 + prec * 0.1) <= 0) { acb_dirichlet_zeta_jet_rs(res, s, len, prec); } else { _acb_dirichlet_zeta_jet(res, s, deflate, len, prec); } } } arb-2.22.1/acb_dirichlet/zeta_jet_rs.c000066400000000000000000000104451417376376500176220ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* f(s) = (f(s+hi) + f(s-hi))/2 + err0 f'(s) = (f(s+hi) - f(s-hi))/(2hi) + err1 |err0| <= |f(s +/- R)| (1/R)^2 h^2 / (1 - h/R) |err1| <= |f(s +/- R)| (1/R)^3 h^2 / (1 - h/R) assuming h/R < 1 */ static void acb_dirichlet_zeta_jet_rs_mid(acb_ptr res, const acb_t s, slong prec) { acb_t t, u; arb_t hh; mag_t h, R, err0, err1, tmp; slong hexp; acb_init(t); acb_init(u); arb_init(hh); mag_init(h); mag_init(R); mag_init(err0); mag_init(err1); mag_init(tmp); hexp = -(prec / 2) - 10; mag_set_ui_2exp_si(h, 1, hexp); mag_set_ui_2exp_si(R, 1, -5); acb_set(t, s); mag_add(arb_radref(acb_realref(t)), arb_radref(acb_realref(t)), R); mag_add(arb_radref(acb_imagref(t)), arb_radref(acb_imagref(t)), R); /* tmp = |f(s +/- R)| */ acb_dirichlet_zeta_bound(tmp, t); /* err0 = (1/R)^2 h^2 / (1 - h/R) */ mag_div(err0, h, R); mag_geom_series(err0, err0, 2); /* err0 *= tmp */ mag_mul(err0, err0, tmp); /* err1 = err0 / R */ mag_div(err1, err0, R); /* hh = h as an arb_t */ arb_one(hh); arb_mul_2exp_si(hh, hh, hexp); acb_set(t, s); acb_set(u, s); arb_add(acb_imagref(t), acb_imagref(t), hh, 10 * prec); arb_sub(acb_imagref(u), acb_imagref(u), hh, 10 * prec); /* zeta(mid(s)+ih) */ acb_dirichlet_zeta_rs(res, t, 0, 1.5 * prec + 10); /* zeta(mid(s)-ih) */ acb_dirichlet_zeta_rs(res + 1, u, 0, 1.5 * prec + 10); acb_sub(t, res, res + 1, prec); acb_add(res, res, res + 1, prec); acb_swap(res + 1, t); acb_mul_2exp_si(res, res, -1); acb_mul_2exp_si(res + 1, res + 1, -1); acb_mul_2exp_si(res + 1, res + 1, -hexp); acb_div_onei(res + 1, res + 1); acb_add_error_mag(res, err0); acb_add_error_mag(res + 1, err1); acb_clear(t); acb_clear(u); arb_clear(hh); mag_clear(h); mag_clear(R); mag_clear(err0); mag_clear(err1); mag_clear(tmp); } void acb_dirichlet_zeta_jet_rs(acb_ptr res, const acb_t s, slong len, slong prec) { if (len > 2) { flint_printf("acb_dirichlet_zeta_jet_rs: len > 2 not implemented\n"); flint_abort(); } if (len <= 0) return; if (len == 1) { acb_dirichlet_zeta_rs(res, s, 0, prec); } else if (acb_is_exact(s)) { acb_dirichlet_zeta_jet_rs_mid(res, s, prec); } else { acb_t t; mag_t r, err0, err1, der1, der2, M; /* slong acc; acc = acb_rel_accuracy_bits(s); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + 20); */ /* assume s = m +/- r f(s) = f(m) + err0 f'(s) = f'(m) + err1 |err1| <= |f''(s)| r |err0| <= min(|f'(s)| r, |f'(m)| r + 0.5 |f''(s)| r^2) = r min(|f'(s)|, |f'(m)| + 0.5 |f''(s)| r) */ acb_init(t); mag_init(r); mag_init(err0); mag_init(err1); mag_init(der1); mag_init(der2); mag_init(M); /* r = rad(s) */ mag_hypot(r, arb_radref(acb_realref(s)), arb_radref(acb_imagref(s))); /* Bound zeta'(s), zeta''(s) */ acb_dirichlet_zeta_deriv_bound(der1, der2, s); /* f(m), f'(m) */ acb_get_mid(t, s); acb_dirichlet_zeta_jet_rs_mid(res, t, prec); /* err1 = |f''(s)| r */ mag_mul(err1, der2, r); /* err0 = |f'(m)| + 0.5 |f''(s)| r */ acb_get_mag(M, res + 1); mag_mul_2exp_si(err0, err1, -1); mag_add(err0, err0, M); /* err0 = min(err0, |f'(s)| */ mag_min(err0, err0, der1); /* err0 = err0 * r */ mag_mul(err0, err0, r); acb_add_error_mag(res, err0); acb_add_error_mag(res + 1, err1); acb_clear(t); mag_clear(r); mag_clear(err0); mag_clear(err1); mag_clear(der1); mag_clear(der2); mag_clear(M); } } arb-2.22.1/acb_dirichlet/zeta_rs.c000066400000000000000000000060361417376376500167610ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_zeta_rs_mid(acb_t res, const acb_t s, slong K, slong prec) { acb_t R1, R2, X, t; slong wp; if (arf_sgn(arb_midref(acb_imagref(s))) < 0) { acb_init(t); acb_conj(t, s); acb_dirichlet_zeta_rs(res, t, K, prec); acb_conj(res, res); acb_clear(t); return; } acb_init(R1); acb_init(R2); acb_init(X); acb_init(t); /* rs_r increases the precision internally */ wp = prec; acb_dirichlet_zeta_rs_r(R1, s, K, wp); if (arb_is_exact(acb_realref(s)) && (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0)) { acb_conj(R2, R1); } else { /* conj(R(conj(1-s))) */ arb_sub_ui(acb_realref(t), acb_realref(s), 1, 10 * wp); arb_neg(acb_realref(t), acb_realref(t)); arb_set(acb_imagref(t), acb_imagref(s)); acb_dirichlet_zeta_rs_r(R2, t, K, wp); acb_conj(R2, R2); } if (acb_is_finite(R1) && acb_is_finite(R2)) { wp += 10 + arf_abs_bound_lt_2exp_si(arb_midref(acb_imagref(s))); wp = FLINT_MAX(wp, 10); /* X = pi^(s-1/2) gamma((1-s)/2) rgamma(s/2) = (2 pi)^s rgamma(s) / (2 cos(pi s / 2)) */ acb_rgamma(X, s, wp); acb_const_pi(t, wp); acb_mul_2exp_si(t, t, 1); acb_pow(t, t, s, wp); acb_mul(X, X, t, wp); acb_mul_2exp_si(t, s, -1); acb_cos_pi(t, t, wp); acb_mul_2exp_si(t, t, 1); acb_div(X, X, t, wp); acb_mul(R2, R2, X, wp); } /* R1 + X * R2 */ acb_add(res, R1, R2, prec); acb_clear(R1); acb_clear(R2); acb_clear(X); acb_clear(t); } void acb_dirichlet_zeta_rs(acb_t res, const acb_t s, slong K, slong prec) { if (acb_is_exact(s)) { acb_dirichlet_zeta_rs_mid(res, s, K, prec); } else { acb_t t; mag_t rad, err, err2; slong acc; acc = acb_rel_accuracy_bits(s); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + 20); acb_init(t); mag_init(rad); mag_init(err); mag_init(err2); /* rad = rad(s) */ mag_hypot(rad, arb_radref(acb_realref(s)), arb_radref(acb_imagref(s))); /* bound |zeta'(s)| */ acb_dirichlet_zeta_deriv_bound(err, err2, s); /* error <= |zeta'(s)| * rad(s) */ mag_mul(err, err, rad); /* evaluate at midpoint */ acb_get_mid(t, s); acb_dirichlet_zeta_rs_mid(res, t, K, prec); acb_add_error_mag(res, err); acb_clear(t); mag_clear(rad); mag_clear(err); mag_clear(err2); } } arb-2.22.1/acb_dirichlet/zeta_rs_bound.c000066400000000000000000000042341417376376500201460ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" /* Arias de Reyna, Theorem 4.2 */ void acb_dirichlet_zeta_rs_bound(mag_t err, const acb_t s, slong K) { arb_t a; mag_t c1, c2, c3; slong e; if (!arb_is_positive(acb_imagref(s)) || K < 1 || !acb_is_finite(s)) { mag_inf(err); return; } arb_init(a); arb_add_ui(a, acb_realref(s), K, MAG_BITS); arb_sub_ui(a, a, 2, MAG_BITS); if (!arb_is_nonnegative(acb_realref(s)) && !arb_is_nonnegative(a)) { mag_inf(err); arb_clear(a); return; } mag_init(c1); mag_init(c2); mag_init(c3); /* c1 = 1/7 2^(3 sigma / 2) re(sigma) >= 0 */ /* c1 < 1/2 re(sigma) < 0 */ arf_set_mag(arb_midref(a), arb_radref(acb_realref(s))); arf_add(arb_midref(a), arb_midref(a), arb_midref(acb_realref(s)), MAG_BITS, ARF_RND_CEIL); if (arf_sgn(arb_midref(a)) <= 0) { mag_set_ui_2exp_si(c1, 1, -1); } else if (arf_cmp_2exp_si(arb_midref(a), FLINT_BITS - 4) < 0) { mag_one(c1); mag_div_ui(c1, c1, 7); e = arf_get_si(arb_midref(a), ARF_RND_CEIL); mag_mul_2exp_si(c1, c1, (3 * e + 1) / 2); if (mag_cmp_2exp_si(c1, -1) < 0) mag_set_ui_2exp_si(c1, 1, -1); } else { mag_inf(c1); } /* c2 = 1 / ((10/11) sqrt(t/(2pi))) = (11/10) sqrt((2pi)/t) */ arb_get_mag_lower(c3, acb_imagref(s)); mag_const_pi(c2); mag_mul_2exp_si(c2, c2, 1); mag_div(c2, c2, c3); mag_sqrt(c2, c2); mag_mul_ui(c2, c2, 11); mag_div_ui(c2, c2, 10); /* c2 = c2^(K+1) */ mag_pow_ui(c2, c2, K + 1); /* c3 = gamma((K+1)/2) */ mag_fac_ui(c3, K / 2); mag_mul(err, c1, c2); mag_mul(err, err, c3); mag_clear(c1); mag_clear(c2); mag_clear(c3); arb_clear(a); } arb-2.22.1/acb_dirichlet/zeta_rs_d_coeffs.c000066400000000000000000000027501417376376500206100ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_zeta_rs_d_coeffs(arb_ptr d, const arb_t sigma, slong k, slong prec) { slong j, r, m; arb_t u; arb_init(u); arb_one(u); arb_submul_ui(u, sigma, 2, prec); if (k == 0) { arb_one(d); arb_zero(d + 1); return; } for (j = (3 * k) / 2; j >= 0; j--) { m = 3 * k - 2 * j; if (m != 0) { arb_mul_2exp_si(d + j, d + j, -1); if (j >= 1) arb_addmul(d + j, d + j - 1, u, prec); arb_div_ui(d + j, d + j, 2 * m, prec); if (j >= 2) arb_submul_ui(d + j, d + j - 2, m + 1, prec); } } if (k % 2 == 0) { j = (3 * k) / 2; arb_zero(d + j); arb_set_ui(u, 2); for (r = j - 1; r >= 0; r--) { if ((j - r) % 2 == 0) arb_submul(d + j, d + r, u, prec); else arb_addmul(d + j, d + r, u, prec); arb_mul_ui(u, u, 4 * j - 4 * r + 2, prec); } } arb_zero(d + (3 * k) / 2 + 1); arb_clear(u); } arb-2.22.1/acb_dirichlet/zeta_rs_f_coeffs.c000066400000000000000000000037161417376376500206150ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" #include "acb_poly.h" void acb_dirichlet_zeta_rs_f_coeffs(acb_ptr c, const arb_t p, slong N, slong prec) { arb_ptr R, I, T, X; slong i, len; R = _arb_vec_init(N); I = _arb_vec_init(N); T = _arb_vec_init(N); X = _arb_vec_init(2); arb_set(X, p); arb_one(X + 1); /* I, R = sin,cos(pi*(X^2/2 + 3/8)) */ len = FLINT_MIN(N, 3); _arb_poly_mullow(T, X, 2, X, 2, len, prec); _arb_vec_scalar_mul_2exp_si(T, T, len, -1); arb_set_d(R, 0.375); arb_add(T, T, R, prec); _arb_poly_sin_cos_pi_series(I, R, T, len, N, prec); /* I -= cos(pi*x/2) * sqrt(2) */ _arb_vec_scalar_mul_2exp_si(X, X, 2, -1); _arb_poly_cos_pi_series(T, X, 2, N, prec); arb_sqrt_ui((arb_ptr) c, 2, prec); _arb_vec_scalar_mul(T, T, N, (arb_ptr) c, prec); _arb_vec_sub(I, I, T, N, prec); _arb_vec_scalar_mul_2exp_si(X, X, 2, 1); /* T = 1 / (2 cos(pi*x)) */ _arb_poly_cos_pi_series(T, X, 2, N, prec); _arb_vec_scalar_mul_2exp_si(T, T, N, 1); _arb_poly_inv_series((arb_ptr) c, T, N, N, prec); _arb_vec_swap(T, (arb_ptr) c, N); /* R, I *= T */ _arb_poly_mullow((arb_ptr) c, R, N, T, N, N, prec); _arb_vec_swap(R, (arb_ptr) c, N); _arb_poly_mullow((arb_ptr) c, I, N, T, N, N, prec); _arb_vec_swap(I, (arb_ptr) c, N); for (i = 0; i < N; i++) { arb_swap(acb_realref(c + i), R + i); arb_swap(acb_imagref(c + i), I + i); } _acb_poly_inv_borel_transform(c, c, N, prec); _arb_vec_clear(R, N); _arb_vec_clear(I, N); _arb_vec_clear(T, N); _arb_vec_clear(X, 2); } arb-2.22.1/acb_dirichlet/zeta_rs_r.c000066400000000000000000000137631417376376500173070ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_zeta_rs_r(acb_t res, const acb_t s, slong K, slong prec) { arb_ptr dk, pipow; acb_ptr Fp; arb_t a, p, api2, api2pow; acb_t U, S, u, v; fmpz_t N; mag_t err; slong j, k, wp, K_limit; /* determinate K automatically */ if (K <= 0) { double sigma, t, log2err, best_log2err; slong best_K; sigma = arf_get_d(arb_midref(acb_realref(s)), ARF_RND_DOWN); t = arf_get_d(arb_midref(acb_imagref(s)), ARF_RND_DOWN); if (!(sigma > -1e6 && sigma < 1e6) || !(t > 1 && t < 1e40)) { acb_indeterminate(res); return; } best_K = 1; best_log2err = 1e300; /* todo: also break if too slow rate of decay? */ K_limit = 10 + prec * 0.25; K_limit += pow(t, 0.2); /* possibly useful for off-strip evaluation */ for (K = 1; K < K_limit; K++) { if (sigma < 0 && K + sigma < 3) continue; /* Asymptotic approximation of the error term */ log2err = 2.7889996532222537064 - 0.12022458674074695061 / K + 0.2419040680416126037 * K + 0.7213475204444817037 * K * log(K) + (-0.7213475204444817037 - 0.7213475204444817037 * K) * log(t); if (sigma >= 0.0) log2err += -2.8073549220576041074 + 1.5 * sigma; if (log2err < best_log2err) { best_log2err = log2err; best_K = K; } if (log2err < -prec) break; } K = best_K; } mag_init(err); acb_dirichlet_zeta_rs_bound(err, s, K); if (!mag_is_finite(err)) { acb_indeterminate(res); mag_clear(err); return; } arb_init(a); arb_init(p); arb_init(api2); arb_init(api2pow); acb_init(U); acb_init(S); acb_init(u); acb_init(v); fmpz_init(N); dk = _arb_vec_init((3 * K) / 2 + 2); Fp = _acb_vec_init(3 * K + 1); pipow = _arb_vec_init((3 * K) / 2 + 2); for (wp = 2 * prec; ; wp *= 2) { /* a = sqrt(t / (2pi)) */ arb_const_pi(a, wp); arb_mul_2exp_si(a, a, 1); arb_div(a, acb_imagref(s), a, wp); arb_sqrt(a, a, wp); /* N = floor(a) */ arb_floor(p, a, wp); if (!arb_get_unique_fmpz(N, p)) { if (wp > 4 * prec && wp > arb_rel_accuracy_bits(acb_imagref(s))) { acb_indeterminate(res); goto cleanup; } continue; } /* p = 1 + 2(N-a) */ arb_sub_fmpz(p, a, N, wp); arb_neg(p, p); arb_mul_2exp_si(p, p, 1); arb_add_ui(p, p, 1, wp); acb_dirichlet_zeta_rs_f_coeffs(Fp, p, 3 * K + 1, wp); if (acb_rel_accuracy_bits(Fp + 3 * K) >= prec) break; if (wp > 4 * prec && wp > arb_rel_accuracy_bits(acb_imagref(s))) break; } if (!fmpz_fits_si(N)) { acb_indeterminate(res); goto cleanup; } wp = prec + 10 + 3 * fmpz_bits(N); /* xxx */ wp = FLINT_MAX(wp, prec + 10); wp = wp + FLINT_BIT_COUNT(K); acb_zero(S); arb_const_pi(api2, wp); _arb_vec_set_powers(pipow, api2, (3 * K) / 2 + 2, wp); arb_mul(api2, api2, api2, wp); arb_mul(api2, api2, a, wp); arb_inv(api2, api2, wp); arb_one(api2pow); for (k = 0; k <= K; k++) { acb_dirichlet_zeta_rs_d_coeffs(dk, acb_realref(s), k, wp); acb_zero(u); for (j = 0; j <= (3 * k) / 2; j++) { /* (pi/(2i))^j d^(k)_j F^(3k-2j)(p) */ arb_mul(acb_realref(v), pipow + j, dk + j, wp); arb_mul_2exp_si(acb_realref(v), acb_realref(v), -j); arb_zero(acb_imagref(v)); if (j % 4 == 1) acb_div_onei(v, v); else if (j % 4 == 2) acb_neg(v, v); else if (j % 4 == 3) acb_mul_onei(v, v); acb_addmul(u, v, Fp + 3 * k - 2 * j, wp); } acb_addmul_arb(S, u, api2pow, wp); arb_mul(api2pow, api2pow, api2, wp); } acb_add_error_mag(S, err); /* U = exp(-i[(t/2) log(t/(2pi)) - t/2 - pi/8]) */ arb_log(acb_realref(u), a, wp); arb_mul_2exp_si(acb_realref(u), acb_realref(u), 1); arb_sub_ui(acb_realref(u), acb_realref(u), 1, wp); arb_mul(acb_realref(u), acb_realref(u), acb_imagref(s), wp); arb_mul_2exp_si(acb_realref(u), acb_realref(u), -1); arb_const_pi(acb_imagref(u), wp); arb_mul_2exp_si(acb_imagref(u), acb_imagref(u), -3); arb_sub(acb_realref(u), acb_realref(u), acb_imagref(u), wp); arb_neg(acb_realref(u), acb_realref(u)); arb_sin_cos(acb_imagref(U), acb_realref(U), acb_realref(u), wp); /* S = (-1)^(N-1) * U * a^(-sigma) * S */ acb_mul(S, S, U, wp); arb_neg(acb_realref(u), acb_realref(s)); arb_pow(acb_realref(u), a, acb_realref(u), wp); acb_mul_arb(S, S, acb_realref(u), wp); if (fmpz_is_even(N)) acb_neg(S, S); if (_acb_vec_estimate_allocated_bytes(fmpz_get_ui(N) / 6, wp) < 4e9) acb_dirichlet_powsum_sieved(u, s, fmpz_get_ui(N), 1, wp); else acb_dirichlet_powsum_smooth(u, s, fmpz_get_ui(N), 1, wp); acb_add(S, S, u, wp); acb_set(res, S); /* don't set_round here; the extra precision is useful */ cleanup: _arb_vec_clear(dk, (3 * K) / 2 + 2); _acb_vec_clear(Fp, 3 * K + 1); _arb_vec_clear(pipow, (3 * K) / 2 + 2); arb_clear(a); arb_clear(p); arb_clear(api2); arb_clear(api2pow); acb_clear(U); acb_clear(S); acb_clear(u); acb_clear(v); fmpz_clear(N); mag_clear(err); } arb-2.22.1/acb_dirichlet/zeta_zeros.c000066400000000000000000000020211417376376500174650ustar00rootroot00000000000000/* Copyright (C) 2010 Juan Arias de Reyna Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_dirichlet.h" void acb_dirichlet_zeta_zeros(acb_ptr res, const fmpz_t n, slong len, slong prec) { if (len <= 0) { return; } else if (fmpz_sgn(n) < 1) { flint_printf("nonpositive indices of zeta zeros are not supported\n"); flint_abort(); } else { slong i; arb_ptr p; p = _arb_vec_init(len); acb_dirichlet_hardy_z_zeros(p, n, len, prec); for (i = 0; i < len; i++) { acb_set_d(res + i, 0.5); arb_set(acb_imagref(res + i), p + i); } _arb_vec_clear(p, len); } } arb-2.22.1/acb_elliptic.h000066400000000000000000000053731417376376500151600ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_ELLIPTIC_H #define ACB_ELLIPTIC_H #include #include "acb.h" #include "acb_poly.h" #ifdef __cplusplus extern "C" { #endif void acb_elliptic_k(acb_t k, const acb_t m, slong prec); void acb_elliptic_k_jet(acb_ptr w, const acb_t m, slong len, slong prec); void _acb_elliptic_k_series(acb_ptr res, acb_srcptr m, slong zlen, slong len, slong prec); void acb_elliptic_k_series(acb_poly_t res, const acb_poly_t m, slong len, slong prec); void acb_elliptic_e(acb_t res, const acb_t m, slong prec); void acb_elliptic_rf(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec); void acb_elliptic_rj(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec); void acb_elliptic_rj_carlson(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec); void acb_elliptic_rj_integration(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec); void acb_elliptic_rg(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec); void acb_elliptic_rc1(acb_t res, const acb_t x, slong prec); void acb_elliptic_f(acb_t res, const acb_t phi, const acb_t m, int times_pi, slong prec); void acb_elliptic_e_inc(acb_t res, const acb_t phi, const acb_t m, int times_pi, slong prec); void acb_elliptic_pi(acb_t r, const acb_t n, const acb_t m, slong prec); void acb_elliptic_pi_inc(acb_t res, const acb_t n, const acb_t phi, const acb_t m, int times_pi, slong prec); void acb_elliptic_p(acb_t r, const acb_t z, const acb_t tau, slong prec); void acb_elliptic_p_prime(acb_t r, const acb_t z, const acb_t tau, slong prec); void acb_elliptic_p_jet(acb_ptr r, const acb_t z, const acb_t tau, slong len, slong prec); void _acb_elliptic_p_series(acb_ptr res, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec); void acb_elliptic_p_series(acb_poly_t res, const acb_poly_t z, const acb_t tau, slong len, slong prec); void acb_elliptic_zeta(acb_t res, const acb_t z, const acb_t tau, slong prec); void acb_elliptic_sigma(acb_t res, const acb_t z, const acb_t tau, slong prec); void acb_elliptic_roots(acb_t e1, acb_t e2, acb_t e3, const acb_t tau, slong prec); void acb_elliptic_invariants(acb_t g2, acb_t g3, const acb_t tau, slong prec); void acb_elliptic_inv_p(acb_t res, const acb_t z, const acb_t tau, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_elliptic/000077500000000000000000000000001417376376500147775ustar00rootroot00000000000000arb-2.22.1/acb_elliptic/e.c000066400000000000000000000020401417376376500153630ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" void acb_elliptic_e(acb_t res, const acb_t m, slong prec) { if (acb_is_zero(m)) { acb_const_pi(res, prec); acb_mul_2exp_si(res, res, -1); } else if (acb_is_one(m)) { acb_one(res); } else { acb_struct t[2]; acb_init(t + 0); acb_init(t + 1); acb_elliptic_k_jet(t, m, 2, prec); acb_mul(t + 1, t + 1, m, prec); acb_mul_2exp_si(t + 1, t + 1, 1); acb_add(t, t, t + 1, prec); acb_sub_ui(t + 1, m, 1, prec); acb_mul(res, t, t + 1, prec); acb_neg(res, res); acb_clear(t + 0); acb_clear(t + 1); } } arb-2.22.1/acb_elliptic/e_inc.c000066400000000000000000000125031417376376500162210ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" /* Evaluation on -pi/2 <= re(z) <= pi/2, no aliasing. */ /* s*(RF(x,y,1) - m*s^2*RD(x,y,1)/3), x = c^2, y=1-m*s^2 */ void acb_elliptic_e_reduced(acb_t r, const acb_t z, const acb_t m, int times_pi, slong prec) { acb_t s, c, x, y, rf, rd; acb_init(s); acb_init(c); acb_init(x); acb_init(y); acb_init(rf); acb_init(rd); if (times_pi) acb_sin_cos_pi(s, c, z, prec); else acb_sin_cos(s, c, z, prec); acb_mul(x, c, c, prec); acb_mul(y, s, s, prec); acb_mul(y, y, m, prec); acb_sub_ui(y, y, 1, prec); acb_neg(y, y); acb_one(rf); acb_one(rd); acb_elliptic_rf(rf, x, y, rf, 0, prec); acb_elliptic_rj(rd, x, y, rd, rd, 0, prec); acb_mul(y, s, s, prec); acb_mul(y, y, m, prec); acb_mul(rd, rd, y, prec); acb_div_ui(rd, rd, 3, prec); acb_sub(r, rf, rd, prec); acb_mul(r, r, s, prec); acb_clear(s); acb_clear(c); acb_clear(x); acb_clear(y); acb_clear(rf); acb_clear(rd); } void acb_elliptic_e_inc(acb_t res, const acb_t phi, const acb_t m, int times_pi, slong prec) { arb_t x, d, pi; acb_t z, w, r; if (!acb_is_finite(phi) || !acb_is_finite(m)) { acb_indeterminate(res); return; } if (acb_is_zero(m)) { if (times_pi) { arb_init(pi); arb_const_pi(pi, prec); acb_mul_arb(res, phi, pi, prec); arb_clear(pi); } else { acb_set_round(res, phi, prec); } return; } if (acb_is_zero(phi)) { acb_zero(res); return; } if (times_pi && acb_is_int_2exp_si(phi, -1)) { acb_t t; acb_init(t); acb_mul_2exp_si(t, phi, 1); acb_elliptic_e(res, m, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } arb_init(x); arb_init(d); arb_init(pi); acb_init(z); acb_init(w); acb_init(r); arb_set(x, acb_realref(phi)); arb_const_pi(pi, prec); if (times_pi) arb_set(d, x); else arb_div(d, x, pi, prec); arb_mul_2exp_si(d, d, 1); arb_add_ui(d, d, 1, prec); arb_mul_2exp_si(d, d, -1); if (mag_cmp_2exp_si(arb_radref(d), -1) >= 0) { /* may span multiple periods... don't bother */ acb_indeterminate(res); } else if (arb_contains_int(d) && !arb_is_exact(d)) /* two adjacent d */ { acb_t r2, w2; int is_real; acb_init(r2); acb_init(w2); arb_sub_ui(x, acb_realref(m), 1, prec); is_real = acb_is_real(phi) && acb_is_real(m) && arb_is_negative(x); /* left d */ acb_zero(z); arf_set_mag(arb_midref(acb_realref(z)), arb_radref(d)); mag_zero(arb_radref(d)); arb_sub(d, d, acb_realref(z), 2 * prec + 100); /* meant to be exact */ arb_floor(d, d, prec); /* w = 2 E(m) */ acb_elliptic_e(w, m, prec); acb_mul_2exp_si(w, w, 1); /* z = phi - d * pi */ if (times_pi) { acb_sub_arb(z, phi, d, prec); } else { arb_mul(acb_realref(z), pi, d, prec); arb_sub(acb_realref(z), acb_realref(phi), acb_realref(z), prec); arb_set(acb_imagref(z), acb_imagref(phi)); } acb_elliptic_e_reduced(r, z, m, times_pi, prec); acb_addmul_arb(r, w, d, prec); /* z = phi - (d + 1) * pi */ if (times_pi) acb_sub_ui(z, z, 1, prec); else acb_sub_arb(z, z, pi, prec); acb_elliptic_e_reduced(r2, z, m, times_pi, prec); arb_add_ui(d, d, 1, prec); acb_addmul_arb(r2, w, d, prec); arb_union(acb_realref(res), acb_realref(r), acb_realref(r2), prec); arb_union(acb_imagref(res), acb_imagref(r), acb_imagref(r2), prec); if (is_real) arb_zero(acb_imagref(res)); acb_clear(r2); acb_clear(w2); } else { /* this could still be inexact if d is large (which is fine) */ arb_floor(d, d, prec); if (arb_is_zero(d)) { acb_set(z, phi); acb_zero(w); } else { /* z = phi - d*pi */ if (times_pi) { acb_sub_arb(z, phi, d, prec); } else { arb_mul(acb_realref(z), pi, d, prec); arb_sub(acb_realref(z), acb_realref(phi), acb_realref(z), prec); arb_set(acb_imagref(z), acb_imagref(phi)); } /* w = 2 d E(m) */ acb_elliptic_e(w, m, prec); acb_mul_arb(w, w, d, prec); acb_mul_2exp_si(w, w, 1); } acb_elliptic_e_reduced(r, z, m, times_pi, prec); acb_add(r, r, w, prec); acb_set(res, r); } arb_clear(x); arb_clear(d); arb_clear(pi); acb_clear(z); acb_clear(w); acb_clear(r); } arb-2.22.1/acb_elliptic/f.c000066400000000000000000000117141417376376500153740ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" /* Evaluation on -pi/2 <= re(z) <= pi/2, no aliasing. */ /* s*RF(c^2, 1-m*s^2, 1) */ void acb_elliptic_f_reduced(acb_t r, const acb_t z, const acb_t m, int times_pi, slong prec) { acb_t s, c, a; acb_init(s); acb_init(c); acb_init(a); if (times_pi) acb_sin_cos_pi(s, c, z, prec); else acb_sin_cos(s, c, z, prec); acb_mul(c, c, c, prec); acb_mul(r, s, s, prec); acb_mul(r, r, m, prec); acb_sub_ui(r, r, 1, prec); acb_neg(r, r); acb_one(a); acb_elliptic_rf(r, c, r, a, 0, prec); acb_mul(r, r, s, prec); acb_clear(s); acb_clear(c); acb_clear(a); } void acb_elliptic_f(acb_t res, const acb_t phi, const acb_t m, int times_pi, slong prec) { arb_t x, d, pi; acb_t z, w, r; if (!acb_is_finite(phi) || !acb_is_finite(m)) { acb_indeterminate(res); return; } if (acb_is_zero(m)) { if (times_pi) { arb_init(pi); arb_const_pi(pi, prec); acb_mul_arb(res, phi, pi, prec); arb_clear(pi); } else { acb_set_round(res, phi, prec); } return; } if (acb_is_zero(phi)) { acb_zero(res); return; } if (times_pi && acb_is_int_2exp_si(phi, -1)) { acb_t t; acb_init(t); acb_mul_2exp_si(t, phi, 1); acb_elliptic_k(res, m, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } arb_init(x); arb_init(d); arb_init(pi); acb_init(z); acb_init(w); acb_init(r); arb_set(x, acb_realref(phi)); arb_const_pi(pi, prec); if (times_pi) arb_set(d, x); else arb_div(d, x, pi, prec); arb_mul_2exp_si(d, d, 1); arb_add_ui(d, d, 1, prec); arb_mul_2exp_si(d, d, -1); if (mag_cmp_2exp_si(arb_radref(d), -1) >= 0) { /* may span multiple periods... don't bother */ acb_indeterminate(res); } else if (arb_contains_int(d) && !arb_is_exact(d)) /* two adjacent d */ { acb_t r2, w2; int is_real; acb_init(r2); acb_init(w2); arb_sub_ui(x, acb_realref(m), 1, prec); is_real = acb_is_real(phi) && acb_is_real(m) && arb_is_negative(x); /* left d */ acb_zero(z); arf_set_mag(arb_midref(acb_realref(z)), arb_radref(d)); mag_zero(arb_radref(d)); arb_sub(d, d, acb_realref(z), 2 * prec + 100); /* meant to be exact */ arb_floor(d, d, prec); /* w = 2 K(m) */ acb_elliptic_k(w, m, prec); acb_mul_2exp_si(w, w, 1); /* z = phi - d * pi */ if (times_pi) { acb_sub_arb(z, phi, d, prec); } else { arb_mul(acb_realref(z), pi, d, prec); arb_sub(acb_realref(z), acb_realref(phi), acb_realref(z), prec); arb_set(acb_imagref(z), acb_imagref(phi)); } acb_elliptic_f_reduced(r, z, m, times_pi, prec); acb_addmul_arb(r, w, d, prec); /* z = phi - (d + 1) * pi */ if (times_pi) acb_sub_ui(z, z, 1, prec); else acb_sub_arb(z, z, pi, prec); acb_elliptic_f_reduced(r2, z, m, times_pi, prec); arb_add_ui(d, d, 1, prec); acb_addmul_arb(r2, w, d, prec); arb_union(acb_realref(res), acb_realref(r), acb_realref(r2), prec); arb_union(acb_imagref(res), acb_imagref(r), acb_imagref(r2), prec); if (is_real) arb_zero(acb_imagref(res)); acb_clear(r2); acb_clear(w2); } else { /* this could still be inexact if d is large (which is fine) */ arb_floor(d, d, prec); if (arb_is_zero(d)) { acb_set(z, phi); acb_zero(w); } else { /* z = phi - d*pi */ if (times_pi) { acb_sub_arb(z, phi, d, prec); } else { arb_mul(acb_realref(z), pi, d, prec); arb_sub(acb_realref(z), acb_realref(phi), acb_realref(z), prec); arb_set(acb_imagref(z), acb_imagref(phi)); } /* w = 2 d K(m) */ acb_elliptic_k(w, m, prec); acb_mul_arb(w, w, d, prec); acb_mul_2exp_si(w, w, 1); } acb_elliptic_f_reduced(r, z, m, times_pi, prec); acb_add(r, r, w, prec); acb_set(res, r); } arb_clear(x); arb_clear(d); arb_clear(pi); acb_clear(z); acb_clear(w); acb_clear(r); } arb-2.22.1/acb_elliptic/inv_p.c000066400000000000000000000014551417376376500162630ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" void acb_elliptic_inv_p(acb_t res, const acb_t z, const acb_t tau, slong prec) { acb_t e1, e2, e3; acb_init(e1); acb_init(e2); acb_init(e3); acb_elliptic_roots(e1, e2, e3, tau, prec); acb_sub(e1, z, e1, prec); acb_sub(e2, z, e2, prec); acb_sub(e3, z, e3, prec); acb_elliptic_rf(res, e1, e2, e3, 0, prec); acb_clear(e1); acb_clear(e2); acb_clear(e3); } arb-2.22.1/acb_elliptic/invariants.c000066400000000000000000000013361417376376500173240ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" void acb_elliptic_invariants(acb_t g2, acb_t g3, const acb_t tau, slong prec) { acb_struct t[2]; acb_init(t); acb_init(t + 1); acb_modular_eisenstein(t, tau, 2, prec); acb_mul_ui(g2, t, 60, prec); acb_mul_ui(g3, t + 1, 140, prec); acb_clear(t); acb_clear(t + 1); } arb-2.22.1/acb_elliptic/k.c000066400000000000000000000013001417376376500153670ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" void acb_elliptic_k(acb_t k, const acb_t m, slong prec) { acb_t t; acb_init(t); acb_sub_ui(t, m, 1, prec); acb_neg(t, t); acb_sqrt(t, t, prec); acb_agm1(k, t, prec); acb_const_pi(t, prec); acb_div(k, t, k, prec); acb_mul_2exp_si(k, k, -1); acb_clear(t); } arb-2.22.1/acb_elliptic/k_jet.c000066400000000000000000000040621417376376500162410ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" void acb_elliptic_k_jet(acb_ptr w, const acb_t m, slong len, slong prec) { acb_t t, u, msub1m, m2sub1; slong k, n; if (len < 1) return; if (len == 1) { acb_elliptic_k(w, m, prec); return; } if (acb_is_zero(m)) { acb_const_pi(w, prec); acb_mul_2exp_si(w, w, -1); for (k = 1; k < len; k++) { acb_mul_ui(w + k, w + k - 1, (2 * k - 1) * (2 * k - 1), prec); acb_div_ui(w + k, w + k, 4 * k * k, prec); } return; } acb_init(t); acb_init(u); acb_init(msub1m); acb_init(m2sub1); acb_sub_ui(msub1m, m, 1, prec); acb_neg(t, msub1m); acb_sqrt(t, t, prec); acb_mul(msub1m, msub1m, m, prec); acb_mul_2exp_si(m2sub1, m, 1); acb_sub_ui(m2sub1, m2sub1, 1, prec); acb_agm1_cpx(w, t, 2, prec); /* pi M'(t) / (4 t M(t)^2) */ acb_mul(u, w, w, prec); acb_mul(t, t, u, prec); acb_div(w + 1, w + 1, t, prec); acb_const_pi(u, prec); acb_mul(w + 1, w + 1, u, prec); acb_mul_2exp_si(w + 1, w + 1, -2); /* pi / (2 M(t)) */ acb_const_pi(u, prec); acb_div(w, u, w, prec); acb_mul_2exp_si(w, w, -1); acb_inv(t, msub1m, prec); for (k = 2; k < len; k++) { n = k - 2; acb_mul_ui(w + k, w + n, (2 * n + 1) * (2 * n + 1), prec); acb_mul(u, w + n + 1, m2sub1, prec); acb_addmul_ui(w + k, u, (n + 1) * (n + 1) * 4, prec); acb_mul(w + k, w + k, t, prec); acb_div_ui(w + k, w + k, 4 * (n + 1) * (n + 2), prec); acb_neg(w + k, w + k); } acb_clear(t); acb_clear(u); acb_clear(msub1m); acb_clear(m2sub1); } arb-2.22.1/acb_elliptic/k_series.c000066400000000000000000000025521417376376500167530ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" void _acb_elliptic_k_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) { acb_ptr t, u; zlen = FLINT_MIN(zlen, len); t = _acb_vec_init(len); u = _acb_vec_init(len); acb_elliptic_k_jet(t, z, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, z + 1, zlen - 1); _acb_poly_compose_series(res, t, len, u, zlen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void acb_elliptic_k_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec) { if (n == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, n); if (z->length == 0) { acb_t t; acb_init(t); _acb_elliptic_k_series(res->coeffs, t, 1, n, prec); acb_clear(t); } else { _acb_elliptic_k_series(res->coeffs, z->coeffs, z->length, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_elliptic/p.c000066400000000000000000000027621417376376500154110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" void acb_elliptic_p(acb_t r, const acb_t z, const acb_t tau, slong prec) { acb_struct t0[4], tz[4]; acb_t t; int i, real; real = acb_is_real(z) && arb_is_int_2exp_si(acb_realref(tau), -1) && arb_is_positive(acb_imagref(tau)); acb_init(t); for (i = 0; i < 4; i++) { acb_init(t0 + i); acb_init(tz + i); } acb_modular_theta(tz + 0, tz + 1, tz + 2, tz + 3, z, tau, prec); acb_zero(t); acb_modular_theta(t0 + 0, t0 + 1, t0 + 2, t0 + 3, t, tau, prec); acb_mul(t, t0 + 1, t0 + 2, prec); acb_mul(t, t, tz + 3, prec); acb_div(t, t, tz + 0, prec); acb_mul(t, t, t, prec); acb_pow_ui(t0 + 1, t0 + 1, 4, prec); acb_pow_ui(t0 + 2, t0 + 2, 4, prec); acb_add(r, t0 + 1, t0 + 2, prec); acb_div_ui(r, r, 3, prec); acb_sub(r, t, r, prec); acb_const_pi(t, prec); acb_mul(t, t, t, prec); acb_mul(r, r, t, prec); if (real) arb_zero(acb_imagref(r)); acb_clear(t); for (i = 0; i < 4; i++) { acb_clear(t0 + i); acb_clear(tz + i); } } arb-2.22.1/acb_elliptic/p_jet.c000066400000000000000000000042601417376376500162460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" #include "acb_poly.h" void acb_elliptic_p_jet(acb_ptr r, const acb_t z, const acb_t tau, slong len, slong prec) { acb_t t01, t02, t03, t04; acb_ptr tz1, tz2, tz3, tz4; acb_t t; int real; slong k; if (len < 1) return; if (len == 1) { acb_elliptic_p(r, z, tau, prec); return; } real = acb_is_real(z) && arb_is_int_2exp_si(acb_realref(tau), -1) && arb_is_positive(acb_imagref(tau)); acb_init(t); acb_init(t01); acb_init(t02); acb_init(t03); acb_init(t04); tz1 = _acb_vec_init(len); tz2 = _acb_vec_init(len); tz3 = _acb_vec_init(len); tz4 = _acb_vec_init(len); acb_modular_theta_jet(tz1, tz2, tz3, tz4, z, tau, len, prec); /* [theta_4(z) / theta_1(z)]^2 */ _acb_poly_div_series(tz2, tz4, len, tz1, len, len, prec); _acb_poly_mullow(tz1, tz2, len, tz2, len, len, prec); acb_zero(t); acb_modular_theta(t01, t02, t03, t04, t, tau, prec); /* [theta_2(0) * theta_3(0)] ^2 */ acb_mul(t, t02, t03, prec); acb_mul(t, t, t, prec); _acb_vec_scalar_mul(tz1, tz1, len, t, prec); /* - [theta_2(0)^4 + theta_3(0)^4] / 3 */ acb_pow_ui(t02, t02, 4, prec); acb_pow_ui(t03, t03, 4, prec); acb_add(t, t02, t03, prec); acb_div_ui(t, t, 3, prec); acb_sub(tz1, tz1, t, prec); /* times pi^2 */ acb_const_pi(t, prec); acb_mul(t, t, t, prec); _acb_vec_scalar_mul(r, tz1, len, t, prec); if (real) { for (k = 0; k < len; k++) arb_zero(acb_imagref(r + k)); } acb_clear(t); acb_clear(t01); acb_clear(t02); acb_clear(t03); acb_clear(t04); _acb_vec_clear(tz1, len); _acb_vec_clear(tz2, len); _acb_vec_clear(tz3, len); _acb_vec_clear(tz4, len); } arb-2.22.1/acb_elliptic/p_prime.c000066400000000000000000000027051417376376500166020ustar00rootroot00000000000000/* Copyright (C) 2021 Daniel Schultz This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" void acb_elliptic_p_prime(acb_t r, const acb_t z, const acb_t tau, slong prec) { acb_struct tz[4]; acb_t t1, t2, t3; int i, real; real = acb_is_real(z) && arb_is_int_2exp_si(acb_realref(tau), -1) && arb_is_positive(acb_imagref(tau)); acb_init(t1); acb_init(t2); acb_init(t3); for (i = 0; i < 4; i++) acb_init(tz + i); acb_modular_theta(tz + 0, tz + 1, tz + 2, tz + 3, z, tau, prec); /* (-2*pi*eta^2/theta1)^3*theta2*theta3*theta4 */ acb_const_pi(t2, prec); acb_mul_2exp_si(t2, t2, 1); acb_neg(t2, t2); acb_modular_eta(t3, tau, prec); acb_mul(t1, t3, t3, prec); acb_mul(t3, t1, t2, prec); acb_div(t1, t3, tz + 0, prec); acb_mul(t2, t1, t1, prec); acb_mul(t3, t1, t2, prec); acb_mul(t1, tz + 1, tz + 2, prec); acb_mul(t2, t1, tz + 3, prec); acb_mul(r, t3, t2, prec); if (real) arb_zero(acb_imagref(r)); acb_clear(t1); acb_clear(t2); acb_clear(t3); for (i = 0; i < 4; i++) acb_clear(tz + i); } arb-2.22.1/acb_elliptic/p_series.c000066400000000000000000000026331417376376500167600ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" void _acb_elliptic_p_series(acb_ptr res, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec) { acb_ptr t, u; zlen = FLINT_MIN(zlen, len); t = _acb_vec_init(len); u = _acb_vec_init(len); acb_elliptic_p_jet(t, z, tau, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, z + 1, zlen - 1); _acb_poly_compose_series(res, t, len, u, zlen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void acb_elliptic_p_series(acb_poly_t res, const acb_poly_t z, const acb_t tau, slong n, slong prec) { if (n == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, n); if (z->length == 0) { acb_t t; acb_init(t); _acb_elliptic_p_series(res->coeffs, t, 1, tau, n, prec); acb_clear(t); } else { _acb_elliptic_p_series(res->coeffs, z->coeffs, z->length, tau, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_elliptic/pi.c000066400000000000000000000151211417376376500155530ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" /* Evaluation on -pi/2 <= re(z) <= pi/2, no aliasing. */ /* s*(RF(x,y,1) + n*s^2*RJ(x,y,1,p)/3), x = c^2, y=1-m*s^2, p=1-n*s^2 */ /* complete: c = 0, s = 1 */ void acb_elliptic_pi_reduced(acb_t r, const acb_t n, const acb_t z, const acb_t m, int times_pi, slong prec) { acb_t s, c, x, y, p, rf, rj; acb_init(s); acb_init(c); acb_init(x); acb_init(y); acb_init(p); acb_init(rf); acb_init(rj); if (times_pi) acb_sin_cos_pi(s, c, z, prec); else acb_sin_cos(s, c, z, prec); acb_mul(x, c, c, prec); acb_mul(y, s, s, prec); acb_mul(p, y, n, prec); acb_mul(y, y, m, prec); acb_sub_ui(y, y, 1, prec); acb_neg(y, y); acb_sub_ui(p, p, 1, prec); acb_neg(p, p); acb_one(rf); acb_one(rj); acb_elliptic_rf(rf, x, y, rf, 0, prec); acb_elliptic_rj(rj, x, y, rj, p, 0, prec); acb_mul(y, s, s, prec); acb_mul(y, y, n, prec); acb_mul(rj, rj, y, prec); acb_div_ui(rj, rj, 3, prec); acb_add(r, rf, rj, prec); acb_mul(r, r, s, prec); acb_clear(s); acb_clear(c); acb_clear(x); acb_clear(y); acb_clear(p); acb_clear(rf); acb_clear(rj); } void acb_elliptic_pi(acb_t r, const acb_t n, const acb_t m, slong prec) { if (acb_is_zero(n)) { acb_elliptic_k(r, m, prec); } else if (acb_is_zero(m)) { arb_t pi; arb_init(pi); arb_const_pi(pi, prec); acb_sub_ui(r, n, 1, prec); acb_neg(r, r); acb_rsqrt(r, r, prec); acb_mul_arb(r, r, pi, prec); acb_mul_2exp_si(r, r, -1); arb_clear(pi); } else { acb_t z; acb_init(z); acb_one(z); acb_mul_2exp_si(z, z, -1); acb_elliptic_pi_reduced(r, n, z, m, 1, prec); acb_clear(z); } } void acb_elliptic_pi_inc(acb_t res, const acb_t n, const acb_t phi, const acb_t m, int times_pi, slong prec) { arb_t x, d, pi; acb_t z, w, r; if (!acb_is_finite(n) || !acb_is_finite(phi) || !acb_is_finite(m)) { acb_indeterminate(res); return; } if (acb_is_zero(n)) { acb_elliptic_f(res, phi, m, times_pi, prec); return; } if (acb_is_zero(phi) || (times_pi && acb_is_int_2exp_si(phi, -1))) { acb_t t; acb_init(t); acb_mul_2exp_si(t, phi, 1); acb_elliptic_pi(res, n, m, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } /* Fixme: the exact argument reduction sometimes does not work when re(phi) = k/2 and we end up exactly on a branch cut, presumably due to getting the wrong sign in R_J? Should investigate and find a better solution. */ if (times_pi && !acb_is_real(phi)) { acb_init(z); arb_init(pi); arb_const_pi(pi, prec); acb_mul_arb(z, phi, pi, prec); acb_elliptic_pi_inc(res, n, z, m, 0, prec); acb_clear(z); arb_clear(pi); return; } arb_init(x); arb_init(d); arb_init(pi); acb_init(z); acb_init(w); acb_init(r); arb_set(x, acb_realref(phi)); arb_const_pi(pi, prec); if (times_pi) arb_set(d, x); else arb_div(d, x, pi, prec); arb_mul_2exp_si(d, d, 1); arb_add_ui(d, d, 1, prec); arb_mul_2exp_si(d, d, -1); if (mag_cmp_2exp_si(arb_radref(d), -1) >= 0) { /* may span multiple periods... don't bother */ acb_indeterminate(res); } else if (arb_contains_int(d) && !arb_is_exact(d)) /* two adjacent d */ { acb_t r2, w2; int is_real; acb_init(r2); acb_init(w2); is_real = acb_is_real(phi) && acb_is_real(m) && acb_is_real(n); arb_sub_ui(x, acb_realref(m), 1, prec); is_real = is_real && arb_is_negative(x); arb_sub_ui(x, acb_realref(n), 1, prec); is_real = is_real && arb_is_negative(x); /* left d */ acb_zero(z); arf_set_mag(arb_midref(acb_realref(z)), arb_radref(d)); mag_zero(arb_radref(d)); arb_sub(d, d, acb_realref(z), 2 * prec + 100); /* meant to be exact */ arb_floor(d, d, prec); /* w = 2 Pi(n, m) */ acb_elliptic_pi(w, n, m, prec); acb_mul_2exp_si(w, w, 1); /* z = phi - d * pi */ if (times_pi) { acb_sub_arb(z, phi, d, prec); } else { arb_mul(acb_realref(z), pi, d, prec); arb_sub(acb_realref(z), acb_realref(phi), acb_realref(z), prec); arb_set(acb_imagref(z), acb_imagref(phi)); } acb_elliptic_pi_reduced(r, n, z, m, times_pi, prec); acb_addmul_arb(r, w, d, prec); /* z = phi - (d + 1) * pi */ if (times_pi) acb_sub_ui(z, z, 1, prec); else acb_sub_arb(z, z, pi, prec); acb_elliptic_pi_reduced(r2, n, z, m, times_pi, prec); arb_add_ui(d, d, 1, prec); acb_addmul_arb(r2, w, d, prec); arb_union(acb_realref(res), acb_realref(r), acb_realref(r2), prec); arb_union(acb_imagref(res), acb_imagref(r), acb_imagref(r2), prec); if (is_real) arb_zero(acb_imagref(res)); acb_clear(r2); acb_clear(w2); } else { /* this could still be inexact if d is large (which is fine) */ arb_floor(d, d, prec); if (arb_is_zero(d)) { acb_set(z, phi); acb_zero(w); } else { /* z = phi - d*pi */ if (times_pi) { acb_sub_arb(z, phi, d, prec); } else { arb_mul(acb_realref(z), pi, d, prec); arb_sub(acb_realref(z), acb_realref(phi), acb_realref(z), prec); arb_set(acb_imagref(z), acb_imagref(phi)); } /* w = 2 d Pi(n, m) */ acb_elliptic_pi(w, n, m, prec); acb_mul_arb(w, w, d, prec); acb_mul_2exp_si(w, w, 1); } acb_elliptic_pi_reduced(r, n, z, m, times_pi, prec); acb_add(r, r, w, prec); acb_set(res, r); } arb_clear(x); arb_clear(d); arb_clear(pi); acb_clear(z); acb_clear(w); acb_clear(r); } arb-2.22.1/acb_elliptic/rc1.c000066400000000000000000000054241417376376500156350ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" /* Compute R_C(1,1+x) = atan(sqrt(x))/sqrt(x) = 2F1(1,1/2,3/2,-x) */ static void _acb_elliptic_rc1(acb_t res, const acb_t x, slong prec) { acb_t t; acb_init(t); acb_sqrt(t, x, prec + 2); acb_atan(res, t, prec + 2); acb_div(res, res, t, prec); acb_clear(t); } void acb_elliptic_rc1(acb_t res, const acb_t x, slong prec) { mag_t xm; mag_init(xm); acb_get_mag(xm, x); if (mag_cmp_2exp_si(xm, 0) < 0) { slong k, n; for (n = 1; n <= 6; n++) { if (mag_cmp_2exp_si(xm, -prec / n) < 0) break; } /* Use Taylor series: 1 - x/3 + x^2/5 - x^3/7 + x^4/9 + ... */ if (n <= 6) { const short coeffs[] = {3465, -1155, 693, -495, 385, -315}; acb_t s; acb_init(s); for (k = n - 1; k >= 0; k--) { acb_mul(s, s, x, prec); acb_add_si(s, s, coeffs[k], prec); } acb_div_si(s, s, coeffs[0], prec); mag_geom_series(xm, xm, n); if (acb_is_real(x)) arb_add_error_mag(acb_realref(s), xm); else acb_add_error_mag(s, xm); acb_set(res, s); acb_clear(s); } else if (acb_is_exact(x)) { _acb_elliptic_rc1(res, x, prec); } else { acb_t w; mag_t err, rad; acb_init(w); mag_init(err); mag_init(rad); /* On the unit disc, |f'(x)| <= 0.5 / |1+x| */ acb_add_ui(w, x, 1, MAG_BITS); acb_get_mag_lower(err, w); mag_one(rad); mag_mul_2exp_si(rad, rad, -1); mag_div(err, rad, err); mag_hypot(rad, arb_radref(acb_realref(x)), arb_radref(acb_imagref(x))); mag_mul(err, err, rad); acb_set(w, x); mag_zero(arb_radref(acb_realref(w))); mag_zero(arb_radref(acb_imagref(w))); _acb_elliptic_rc1(w, w, prec); if (acb_is_real(x)) arb_add_error_mag(acb_realref(w), err); else acb_add_error_mag(w, err); acb_set(res, w); acb_clear(w); mag_clear(err); mag_clear(rad); } } else { _acb_elliptic_rc1(res, x, prec); } mag_clear(xm); } arb-2.22.1/acb_elliptic/rf.c000066400000000000000000000213261417376376500155560ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" static const unsigned short den_ratio_tab[512] = { 1,1,10,7,12,11,26,1,136,19,2,23,20,1,58,31, 16,1,74,1,164,43,2,47,56,1,106,1,4,59,122,1, 32,67,2,71,292,1,2,79,24,83,2,1,356,1,2,1, 1552,1,202,103,4,107,218,1,904,1,2,1,44,1,10,127, 64,131,2,1,548,139,2,1,8,1,298,151,4,1,314,1, 16,163,2,167,52,1,346,1,8,179,362,1,4,1,2,191, 6176,1,394,199,4,1,2,1,8,211,2,1,4,1,2,223, 16,227,458,1,932,1,2,239,1928,1,2,1,4,251,2,1, 32896,1,2,263,4,1,538,271,8,1,554,1,1124,283,2,1, 272,1,586,1,4,1,2,1,8,307,2,311,1252,1,634,1, 32,1,2,1,4,331,2,1,2696,1,2,7,4,347,698,1, 5648,1,2,359,76,1,2,367,8,1,746,1,4,379,2,383, 64,1,778,1,4,1,794,1,3208,1,2,1,1636,1,2,1, 16,419,842,1,4,1,2,431,3464,1,2,439,4,443,2,1, 14368,1,2,1,1828,1,922,463,8,467,2,1,4,1,2,479, 16,1,2,487,4,491,2,1,8,499,2,503,4,1,1018,1, 256,1,2,1,2084,523,2,1,184,1,2,1,4,1,1082,1, 16,547,2,1,4,1,1114,1,8,563,2,1,2276,571,2,1, 18464,1,2,1,4,587,2,1,4744,1,2,599,2404,1,2,607, 16,1,1226,1,2468,619,2,1,40,1,2,631,4,1,2,1, 41024,643,2,647,4,1,1306,1,8,659,1322,1,4,1,2,1, 10768,1,1354,1,4,683,2,1,8,691,2,1,4,1,1402,1, 32,1,1418,1,4,1,2,719,8,1,2,727,12,1,1466,1, 16,739,2,743,4,1,2,751,8,1,1514,1,3044,1,2,2, 49216,1,1546,1,4,1,2,1,8,787,2,1,4,1,1594,1, 16,1,2,1,3236,811,2,1,8,1,1642,823,4,827,1658,1, 32,1,2,839,116,1,2,1,8,1,1706,1,3428,859,2,863, 16,1,2,1,4,1,1754,1,7048,883,2,887,4,1,2,1, 64,1,2,1,4,907,2,911,8,1,2,919,4,1,2,1, 14864,1,2,1,3748,1,1882,1,8,947,2,1,3812,1,2,1, 992,1,2,967,4,971,2,1,7816,1,2,983,4,1,2,991, 16,1,1994,1,4,1,2,1,8072,1,2026,1,4,1019,2042,1, }; void acb_elliptic_rf_taylor_sum(acb_t res, const acb_t E2, const acb_t E3, slong nterms, slong prec) { fmpz_t den, c, d, e; acb_ptr E2pow; arb_ptr E2powr; acb_t s; slong x, y, XMAX, YMAX, NMAX, N; int real; NMAX = nterms - 1; YMAX = NMAX / 3; XMAX = NMAX / 2; real = acb_is_real(E2) && acb_is_real(E3); fmpz_init(den); fmpz_init(c); fmpz_init(d); fmpz_init(e); acb_init(s); if (real) { E2powr = _arb_vec_init(XMAX + 1); E2pow = NULL; _arb_vec_set_powers(E2powr, acb_realref(E2), XMAX + 1, prec); } else { E2pow = _acb_vec_init(XMAX + 1); E2powr = NULL; _acb_vec_set_powers(E2pow, E2, XMAX + 1, prec); } /* Compute universal denominator. */ fmpz_one(den); for (N = 1; N <= NMAX; N++) fmpz_mul_ui(den, den, den_ratio_tab[N]); /* Compute initial coefficient rf(1/2,y) / y! */ fmpz_set(c, den); for (y = 0; y < YMAX; y++) { fmpz_mul_ui(c, c, 2 * y + 1); fmpz_divexact_ui(c, c, 2 * y + 2); } acb_zero(res); for (y = YMAX; y >= 0; y--) { acb_zero(s); if (y != YMAX) { fmpz_mul_ui(c, c, 2 * y + 2); fmpz_divexact_ui(c, c, 2 * y + 1); } fmpz_set(d, c); /* Use powers with respect to E2 */ for (x = 0; x <= XMAX; x++) { N = 2 * x + 3 * y; if (N <= NMAX) { fmpz_divexact_ui(e, d, 2 * N + 1); if (x % 2 == 1) fmpz_neg(e, e); if (x != 0 || y != 0) { if (real) arb_addmul_fmpz(acb_realref(s), E2powr + x, e, prec); else acb_addmul_fmpz(s, E2pow + x, e, prec); } fmpz_mul_ui(d, d, 2 * x + 2 * y + 1); fmpz_divexact_ui(d, d, 2 * x + 2); } } /* Horner with respect to E3 */ acb_mul(res, res, E3, prec); acb_add(res, res, s, prec); } acb_div_fmpz(res, res, den, prec); acb_add_ui(res, res, 1, prec); fmpz_clear(den); fmpz_clear(c); fmpz_clear(d); fmpz_clear(e); acb_clear(s); if (real) _arb_vec_clear(E2powr, XMAX + 1); else _acb_vec_clear(E2pow, XMAX + 1); } void acb_elliptic_rf(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec) { acb_t xx, yy, zz, sx, sy, sz, t; acb_t X, Y, Z, E2, E3; mag_t err, err2, prev_err; slong k, wp, accx, accy, accz, order; if (!acb_is_finite(x) || !acb_is_finite(y) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (acb_contains_zero(x) + acb_contains_zero(y) + acb_contains_zero(z) > 1) { acb_indeterminate(res); return; } acb_init(xx); acb_init(yy); acb_init(zz); acb_init(sx); acb_init(sy); acb_init(sz); acb_init(X); acb_init(Y); acb_init(Z); acb_init(E2); acb_init(E3); acb_init(t); mag_init(err); mag_init(err2); mag_init(prev_err); order = 5; /* will be set later */ acb_set(xx, x); acb_set(yy, y); acb_set(zz, z); /* First guess precision based on the inputs. */ /* This does not account for mixing. */ accx = acb_rel_accuracy_bits(xx); accy = acb_rel_accuracy_bits(yy); accz = acb_rel_accuracy_bits(zz); accx = FLINT_MAX(accx, accy); accx = FLINT_MAX(accx, accz); if (accx < prec - 20) prec = FLINT_MAX(2, accx + 20); wp = prec + 10 + FLINT_BIT_COUNT(prec); /* Must do at least one iteration. */ for (k = 0; k < prec; k++) { acb_sqrt(sx, xx, wp); acb_sqrt(sy, yy, wp); acb_sqrt(sz, zz, wp); acb_add(t, sy, sz, wp); acb_mul(t, t, sx, wp); acb_addmul(t, sy, sz, wp); acb_add(xx, xx, t, wp); acb_add(yy, yy, t, wp); acb_add(zz, zz, t, wp); acb_mul_2exp_si(xx, xx, -2); acb_mul_2exp_si(yy, yy, -2); acb_mul_2exp_si(zz, zz, -2); /* Improve precision estimate and set expansion order. */ /* Should this done for other k also? */ if (k == 0) { accx = acb_rel_accuracy_bits(xx); accy = acb_rel_accuracy_bits(yy); accz = acb_rel_accuracy_bits(zz); accx = FLINT_MAX(accx, accy); accx = FLINT_MAX(accx, accz); if (accx < prec - 20) prec = FLINT_MAX(2, accx + 20); wp = prec + 10 + FLINT_BIT_COUNT(prec); if (acb_is_real(xx) && acb_is_real(yy) && acb_is_real(zz)) order = 2.1 * pow(prec, 0.4); else order = 2.5 * pow(prec, 0.4); order = FLINT_MIN(order, 500); order = FLINT_MAX(order, 2); } /* Close enough? Quick estimate based on |x-y|/|x| and |x-z|/|x| */ /* We also terminate if there is no improvement. */ acb_sub(t, xx, yy, wp); acb_get_mag(err, t); acb_sub(t, xx, zz, wp); acb_get_mag(err2, t); mag_max(err, err, err2); acb_get_mag_lower(err2, xx); mag_div(err, err, err2); mag_pow_ui(err, err, order); if (mag_cmp_2exp_si(err, -prec) < 0 || (k > 2 && mag_cmp(err, prev_err) > 0)) break; mag_set(prev_err, err); } /* X = 1-x/t, Y = 1-y/t, Z = -X-Y, t = (x+y+z)/3 */ acb_add(t, xx, yy, wp); acb_add(t, t, zz, wp); acb_div_ui(t, t, 3, wp); acb_div(X, xx, t, wp); acb_sub_ui(X, X, 1, wp); acb_neg(X, X); acb_div(Y, yy, t, wp); acb_sub_ui(Y, Y, 1, wp); acb_neg(Y, Y); acb_add(Z, X, Y, wp); acb_neg(Z, Z); /* E2 = XY-Z^2, E3 = XYZ */ acb_mul(E2, X, Y, wp); acb_mul(E3, E2, Z, wp); acb_submul(E2, Z, Z, wp); /* Crude bound for the coefficient of X^n1 Y^n2 Z^n3 with n1+n2+n3=n: 2*(9/8)^n. */ /* Error bound. */ acb_get_mag(err, X); acb_get_mag(err2, Y); mag_max(err, err, err2); acb_get_mag(err2, Z); mag_max(err, err, err2); mag_mul_ui(err, err, 9); mag_mul_2exp_si(err, err, -3); mag_geom_series(err, err, order); mag_mul_2exp_si(err, err, 1); acb_elliptic_rf_taylor_sum(sx, E2, E3, order, wp); if (acb_is_real(X) && acb_is_real(Y)) arb_add_error_mag(acb_realref(sx), err); else acb_add_error_mag(sx, err); acb_rsqrt(t, t, wp); acb_mul(res, sx, t, prec); acb_clear(xx); acb_clear(yy); acb_clear(zz); acb_clear(sx); acb_clear(sy); acb_clear(sz); acb_clear(X); acb_clear(Y); acb_clear(Z); acb_clear(E2); acb_clear(E3); acb_clear(t); mag_clear(err); mag_clear(err2); mag_clear(prev_err); } arb-2.22.1/acb_elliptic/rg.c000066400000000000000000000037061417376376500155610ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" void _acb_elliptic_rg(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec) { acb_t a, b, c, t; slong wp; wp = prec + 10; acb_init(a); acb_init(b); acb_init(c); acb_init(t); acb_elliptic_rf(a, x, y, z, 0, wp); acb_mul(a, a, z, wp); acb_elliptic_rj(b, x, y, z, z, 0, wp); acb_sub(c, x, z, wp); acb_mul(b, b, c, wp); acb_sub(c, z, y, wp); acb_mul(b, b, c, wp); acb_div_ui(b, b, 3, wp); acb_sqrt(c, x, wp); acb_sqrt(t, y, wp); acb_mul(c, c, t, wp); acb_rsqrt(t, z, wp); acb_mul(c, c, t, wp); acb_add(res, a, b, wp); acb_add(res, res, c, prec); acb_mul_2exp_si(res, res, -1); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(t); } void acb_elliptic_rg(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec) { if (acb_is_zero(x) && acb_is_zero(y)) { acb_sqrt(res, z, prec); acb_mul_2exp_si(res, res, -1); } else if (acb_is_zero(x) && acb_is_zero(z)) { acb_sqrt(res, y, prec); acb_mul_2exp_si(res, res, -1); } else if (acb_is_zero(y) && acb_is_zero(z)) { acb_sqrt(res, x, prec); acb_mul_2exp_si(res, res, -1); } else if (acb_contains_zero(z)) { if (acb_contains_zero(y)) _acb_elliptic_rg(res, y, z, x, flags, prec); else _acb_elliptic_rg(res, x, z, y, flags, prec); } else { _acb_elliptic_rg(res, x, y, z, flags, prec); } } arb-2.22.1/acb_elliptic/rj.c000066400000000000000000000574021417376376500155660ustar00rootroot00000000000000/* Copyright (C) 2017, 2020 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_calc.h" static const unsigned short den_ratio_tab[512] = { 1,1,14,3,44,13,10,17,152,1,46,1,12,29,62,1, 16,37,2,41,172,1,94,7,8,53,2,1,236,61,2,1, 2144,1,142,73,20,1,158,3,664,1,2,89,4,1,2,97, 16,101,206,1,428,109,2,113,8,1,2,11,4,1,254,1, 8384,1,2,137,556,1,2,1,8,149,302,1,4,157,2,1, 2608,1,334,13,4,173,2,1,1432,181,2,1,4,1,382,193, 32,197,398,1,4,1,2,1,1688,1,2,1,4,1,446,1, 3632,229,2,233,4,1,478,241,24,1,2,1,1004,1,2,257, 128,1,526,1,4,269,542,1,8,277,2,281,1132,1,2,17, 16,293,2,1,4,1,2,1,2456,1,622,313,4,317,2,1, 32,1,2,1,1324,1,2,337,8,1,14,1,1388,349,2,353, 16,1,718,19,4,1,734,1,8,373,10,1,1516,1,766,1, 64,389,2,1,4,397,2,401,8,1,2,409,4,1,2,1, 6704,421,2,1,4,1,862,433,8,1,878,1,1772,1,2,449, 32,1,2,457,4,461,926,1,3736,1,2,1,4,1,958,1, 16,1,974,1,1964,1,2,1,3992,1,1006,1,4,509,2,1, 256,1,2,521,2092,1,2,23,8,1,2,1,4,541,2,1, 8752,1,2,1,4,557,2,1,4504,1,2,569,2284,1,2,577, 32,1,2,1,2348,1,2,593,8,1,1198,601,4,1,1214,1, 16,613,2,617,2476,1,2,1,8,1,1262,1,4,1,2,641, 41152,1,1294,1,4,653,2,1,5272,661,2,1,4,1,2,673, 16,677,2,1,2732,1,2,1,5528,1,2,1,4,701,2,1, 32,709,2,1,4,1,1438,1,8,1,1454,3,4,733,2,1, 11824,1,1486,1,4,1,1502,1,8,757,2,761,4,1,2,769, 128,773,2,1,4,1,2,1,6296,1,2,1,4,797,2,1, 16,1,2,809,3244,1,2,1,8,821,1646,1,3308,829,2,1, 32,1,1678,29,4,1,2,1,8,853,2,857,3436,1,1726,1, 16,1,2,1,4,877,2,881,7064,1,1774,1,4,1,2,1, 64,1,2,1,3628,1,1822,1,8,1,1838,1,4,1,2,929, 16,1,2,937,4,941,2,1,7576,1,2,953,4,1,2,31, 32,1,1934,1,3884,1,2,977,8,1,1966,1,4,1,1982,1, 16,997,2,1,4,1,2,1009,8,1013,2,1,4076,1021,2,1 }; static __inline__ slong rj_fdiv(slong x, slong y) { if (x < 0) return -1; else return x / y; } void acb_elliptic_rj_taylor_sum(acb_t res, const acb_t E2, const acb_t E3, const acb_t E4, const acb_t E5, slong nterms, slong prec) { slong m2, m3, m4, m5, m2start, m3start, m4start, m5start, NMAX, N, M; slong m2dim, m3dim; acb_t s2, s3, s4, s5; acb_ptr powtab; fmpz_t c2, c3, c4, c5, den, t; acb_init(s2); acb_init(s3); acb_init(s4); acb_init(s5); fmpz_init(c2); fmpz_init(c3); fmpz_init(c4); fmpz_init(c5); fmpz_init(den); fmpz_init(t); NMAX = nterms - 1; m2dim = NMAX / 2 + 1; m3dim = NMAX / 3 + 1; powtab = _acb_vec_init(m2dim * m3dim); /* Compute universal denominator */ fmpz_one(den); for (N = 1; N <= NMAX; N++) fmpz_mul_ui(den, den, den_ratio_tab[N]); /* Precompute powers of E2 and E3 */ for (m2 = 0; m2 <= NMAX / 2; m2++) { for (m3 = 0; m3 <= rj_fdiv(NMAX - 2 * m2, 3); m3++) { slong i, j, k; i = m3 * m2dim + m2; if (m2 <= 1 && m3 <= 1) { if (m2 == 0 && m3 == 0) acb_one(powtab + i); else if (m2 == 0 && m3 == 1) acb_set(powtab + i, E3); else if (m2 == 1 && m3 == 0) acb_set(powtab + i, E2); else acb_mul(powtab + i, E2, E3, prec); } else { j = (m3 / 2) * m2dim + (m2 / 2); k = (m3 - (m3 / 2)) * m2dim + (m2 - (m2 / 2)); acb_mul(powtab + i, powtab + j, powtab + k, prec); } } } acb_zero(s5); m5start = NMAX / 5; fmpz_mul_ui(c5, den, 3); for (m5 = 0; m5 < m5start; m5++) { fmpz_mul_ui(c5, c5, 2 * m5 + 1); fmpz_divexact_ui(c5, c5, 2 * m5 + 2); } for (m5 = m5start; m5 >= 0; m5--) { acb_zero(s4); m4start = rj_fdiv(NMAX - 5 * m5, 4); if (m5 != m5start) { fmpz_mul_ui(c5, c5, 2 * m5 + 2); fmpz_divexact_ui(c5, c5, 2 * m5 + 1); } fmpz_set(c4, c5); for (m4 = 0; m4 < m4start; m4++) { fmpz_mul_ui(c4, c4, 2 * m5 + 2 * m4 + 1); fmpz_divexact_ui(c4, c4, 2 * m4 + 2); } for (m4 = m4start; m4 >= 0; m4--) { acb_zero(s3); m3start = rj_fdiv(NMAX - 5 * m5 - 4 * m4, 3); if (m4 != m4start) { fmpz_mul_ui(c4, c4, 2 * m4 + 2); fmpz_divexact_ui(c4, c4, 2 * m5 + 2 * m4 + 1); } fmpz_set(c3, c4); for (m3 = 0; m3 <= m3start; m3++) { m2start = rj_fdiv(NMAX - 5 * m5 - 4 * m4 - 3 * m3, 2); fmpz_set(c2, c3); for (m2 = 0; m2 <= m2start; m2++) { M = m5 + m4 + m3 + m2; N = 5 * m5 + 4 * m4 + 3 * m3 + 2 * m2; if (N > NMAX) flint_abort(); fmpz_divexact_ui(t, c2, 2 * N + 3); if ((M + N) % 2) fmpz_neg(t, t); acb_addmul_fmpz(s3, powtab + m3 * m2dim + m2, t, prec); if (m2 < m2start) { fmpz_mul_ui(c2, c2, 2 * m5 + 2 * m4 + 2 * m3 + 2 * m2 + 1); fmpz_divexact_ui(c2, c2, 2 * m2 + 2); } } if (m3 < m3start) { fmpz_mul_ui(c3, c3, 2 * m5 + 2 * m4 + 2 * m3 + 1); fmpz_divexact_ui(c3, c3, 2 * m3 + 2); } } /* Horner with respect to E4. */ acb_mul(s4, s4, E4, prec); acb_add(s4, s4, s3, prec); } /* Horner with respect to E5. */ acb_mul(s5, s5, E5, prec); acb_add(s5, s5, s4, prec); } acb_div_fmpz(res, s5, den, prec); _acb_vec_clear(powtab, m2dim * m3dim); acb_clear(s2); acb_clear(s3); acb_clear(s4); acb_clear(s5); fmpz_clear(c2); fmpz_clear(c3); fmpz_clear(c4); fmpz_clear(c5); fmpz_clear(den); fmpz_clear(t); } void acb_elliptic_rj_carlson(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec) { acb_t xx, yy, zz, pp, sx, sy, sz, sp, t, d, delta, S; acb_t A, AA, X, Y, Z, P, E2, E3, E4, E5; mag_t err, err2, prev_err; slong k, wp, accx, accy, accz, accp, order; int rd, real; /* printf("RJ carlson "); acb_printn(x, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(y, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(z, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(p, 6, ARB_STR_NO_RADIUS); printf(" "); printf("\n"); */ if (!acb_is_finite(x) || !acb_is_finite(y) || !acb_is_finite(z) || !acb_is_finite(p)) { acb_indeterminate(res); return; } if ((acb_contains_zero(x) + acb_contains_zero(y) + acb_contains_zero(z) > 1) || acb_contains_zero(p)) { acb_indeterminate(res); return; } /* Special case computing R_D(x,y,z) */ rd = (z == p) || acb_eq(z, p); acb_init(xx); acb_init(yy); acb_init(zz); acb_init(pp); acb_init(sx); acb_init(sy); acb_init(sz); acb_init(sp); acb_init(S); acb_init(A); acb_init(AA); acb_init(X); acb_init(Y); acb_init(Z); acb_init(P); acb_init(E2); acb_init(E3); acb_init(E4); acb_init(E5); acb_init(t); acb_init(d); acb_init(delta); mag_init(err); mag_init(err2); mag_init(prev_err); acb_set(xx, x); acb_set(yy, y); acb_set(zz, z); acb_set(pp, p); acb_zero(S); real = acb_is_real(x) && acb_is_real(y) && acb_is_real(z) && acb_is_real(p) && arb_is_nonnegative(acb_realref(x)) && arb_is_nonnegative(acb_realref(y)) && arb_is_nonnegative(acb_realref(z)) && arb_is_nonnegative(acb_realref(p)); order = 5; /* will be set later */ /* First guess precision based on the inputs. */ /* This does not account for mixing. */ accx = acb_rel_accuracy_bits(xx); accy = acb_rel_accuracy_bits(yy); accz = acb_rel_accuracy_bits(zz); accp = acb_rel_accuracy_bits(pp); accx = FLINT_MAX(accx, accy); accx = FLINT_MAX(accx, accz); accx = FLINT_MAX(accx, accp); if (accx < prec - 20) prec = FLINT_MAX(2, accx + 20); wp = prec + 4 + FLINT_BIT_COUNT(prec); if (!rd) { acb_mul_2exp_si(A, p, 1); acb_add(A, A, z, wp); } else { acb_mul_ui(A, z, 3, wp); } acb_add(A, A, x, wp); acb_add(A, A, y, wp); acb_div_ui(A, A, 5, wp); acb_set(AA, A); if (!rd) { acb_sub(delta, p, x, wp); acb_sub(t, p, y, wp); acb_mul(delta, delta, t, wp); acb_sub(t, p, z, wp); acb_mul(delta, delta, t, wp); } /* must do at least one iteration */ for (k = 0; k < prec; k++) { acb_sqrt(sx, xx, wp); acb_sqrt(sy, yy, wp); acb_sqrt(sz, zz, wp); if (!rd) acb_sqrt(sp, pp, wp); acb_add(t, sy, sz, wp); acb_mul(t, t, sx, wp); acb_addmul(t, sy, sz, wp); acb_add(xx, xx, t, wp); acb_add(yy, yy, t, wp); acb_add(zz, zz, t, wp); if (!rd) acb_add(pp, pp, t, wp); acb_add(AA, AA, t, wp); acb_mul_2exp_si(xx, xx, -2); acb_mul_2exp_si(yy, yy, -2); acb_mul_2exp_si(zz, zz, -2); if (!rd) acb_mul_2exp_si(pp, pp, -2); acb_mul_2exp_si(AA, AA, -2); if (!rd) { /* d = (sp+sx)(sp+sy)(sp+sz) */ /* e = 4^(-3k) delta / d^2 */ /* S += 4^(-k) RC(1, 1+e) / d */ acb_add(d, sp, sx, wp); acb_add(t, sp, sy, wp); acb_mul(d, d, t, wp); acb_add(t, sp, sz, wp); acb_mul(d, d, t, wp); /* E2 = e */ acb_mul(E2, d, d, wp); acb_div(E2, delta, E2, wp); acb_mul_2exp_si(E2, E2, -6 * k); acb_elliptic_rc1(E4, E2, wp); acb_div(E4, E4, d, wp); acb_mul_2exp_si(E4, E4, -2 * k); acb_add(S, S, E4, wp); } else { acb_mul(t, sz, zz, wp); acb_mul_2exp_si(t, t, 2); acb_inv(t, t, wp); acb_mul_2exp_si(t, t, -2 * k); acb_mul_2exp_si(t, t, -1); acb_add(S, S, t, wp); } /* Improve precision estimate and set expansion order. */ /* Should this done for other k also? */ if (k == 0) { accx = acb_rel_accuracy_bits(xx); accy = acb_rel_accuracy_bits(yy); accz = acb_rel_accuracy_bits(zz); accp = acb_rel_accuracy_bits(pp); accx = FLINT_MAX(accx, accy); accx = FLINT_MAX(accx, accz); accx = FLINT_MAX(accx, accp); if (accx < prec - 20) prec = FLINT_MAX(2, accx + 20); wp = prec + 4 + FLINT_BIT_COUNT(prec); if (!rd) if (real) order = 2.3 * pow(prec, 0.34); else order = 2.5 * pow(prec, 0.35); else if (real) order = 2.0 * pow(prec, 0.33); else order = 2.2 * pow(prec, 0.33); order = FLINT_MIN(order, 500); order = FLINT_MAX(order, 5); } /* Close enough? */ acb_sub(t, xx, yy, wp); acb_get_mag(err, t); acb_sub(t, xx, zz, wp); acb_get_mag(err2, t); mag_max(err, err, err2); if (!rd) { acb_sub(t, xx, pp, wp); acb_get_mag(err2, t); mag_max(err, err, err2); } acb_get_mag_lower(err2, xx); mag_div(err, err, err2); mag_pow_ui(err, err, order); if (mag_cmp_2exp_si(err, -prec) < 0 || (k > 2 && mag_cmp(err, prev_err) > 0)) { k++; break; } mag_set(prev_err, err); } /* X = (A-x)/(4^k AA) */ /* Y = (A-y)/(4^k AA) */ /* Z = (A-z)/(4^k AA) */ /* P = (-X-Y-Z)/2 */ acb_mul_2exp_si(t, AA, 2 * k); acb_inv(t, t, prec); acb_sub(X, A, x, prec); acb_mul(X, X, t, prec); acb_sub(Y, A, y, prec); acb_mul(Y, Y, t, prec); acb_sub(Z, A, z, prec); acb_mul(Z, Z, t, prec); acb_add(P, X, Y, prec); acb_add(P, P, Z, prec); acb_neg(P, P); acb_mul_2exp_si(P, P, -1); /* todo: improve for R_D */ /* E2 = XY + XZ + YZ - 3 P^2 */ /* E3 = XYZ + 2 E2 P + 4 P^3 */ /* E4 = (2 XYZ + E2 P + 3 P^3) P */ /* E5 = XYZP^2 */ acb_mul(t, P, P, prec); /* t = P^2 */ acb_mul(E2, X, Y, prec); acb_mul(E3, E2, Z, prec); acb_mul_2exp_si(E4, E3, 1); acb_mul(E5, E3, t, prec); acb_add(sx, X, Y, prec); acb_addmul(E2, sx, Z, prec); acb_submul_ui(E2, t, 3, prec); acb_mul(sx, E2, P, prec); acb_add(E4, E4, sx, prec); acb_mul_2exp_si(sx, sx, 1); acb_add(E3, E3, sx, prec); acb_mul(t, t, P, prec); /* t = P^3 */ acb_addmul_ui(E3, t, 4, prec); acb_addmul_ui(E4, t, 3, prec); acb_mul(E4, E4, P, prec); /* Error bound. */ acb_get_mag(err, X); acb_get_mag(err2, Y); mag_max(err, err, err2); acb_get_mag(err2, Z); mag_max(err, err, err2); acb_get_mag(err2, P); mag_max(err, err, err2); mag_mul_ui(err, err, 9); mag_mul_2exp_si(err, err, -3); mag_geom_series(err, err, order); mag_mul_2exp_si(err, err, 1); acb_elliptic_rj_taylor_sum(sx, E2, E3, E4, E5, order, wp); if (acb_is_real(X) && acb_is_real(Y) && acb_is_real(Z)) arb_add_error_mag(acb_realref(sx), err); else acb_add_error_mag(sx, err); acb_rsqrt(t, AA, wp); acb_div(t, t, AA, wp); acb_mul_2exp_si(t, t, -2 * k); acb_mul(t, t, sx, wp); acb_addmul_ui(t, S, 6, prec); acb_set(res, t); acb_clear(xx); acb_clear(yy); acb_clear(zz); acb_clear(pp); acb_clear(sx); acb_clear(sy); acb_clear(sz); acb_clear(sp); acb_clear(S); acb_clear(A); acb_clear(AA); acb_clear(X); acb_clear(Y); acb_clear(Z); acb_clear(P); acb_clear(E2); acb_clear(E3); acb_clear(E4); acb_clear(E5); acb_clear(t); acb_clear(d); acb_clear(delta); mag_clear(err); mag_clear(err2); mag_clear(prev_err); } static int acb_eq_conj(const acb_t x, const acb_t y) { int res; acb_t t; acb_init(t); acb_conj(t, y); res = acb_eq(x, t); acb_clear(t); return res; } /* todo: speed up this function -- early abort -- only compute single rsqrt or sqrt when evaluating precisely (but need to make sure branch is correct!) */ static int RJ_integrand(acb_ptr res, const acb_t t, void * param, slong order, slong prec) { acb_ptr x, y, z, p; acb_t xt, yt, zt, pt; int analytic, deflated; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ x = ((acb_ptr) param); y = ((acb_ptr) param) + 1; z = ((acb_ptr) param) + 2; p = ((acb_ptr) param) + 3; deflated = acb_is_zero(x); analytic = (order != 0); acb_init(xt); acb_init(yt); acb_init(zt); acb_init(pt); /* if x = 0, change of variables t -> t^2 to remove singularity at 0 */ if (deflated) { acb_sqr(xt, t, prec); acb_add(yt, y, xt, prec); acb_add(zt, z, xt, prec); acb_add(pt, p, xt, prec); if (acb_contains_zero(yt) || acb_contains_zero(zt) || acb_contains_zero(pt)) { acb_indeterminate(res); } else { acb_rsqrt_analytic(yt, yt, analytic, prec); acb_rsqrt_analytic(zt, zt, analytic, prec); acb_mul(xt, yt, zt, prec); acb_div(xt, xt, pt, prec); acb_mul_2exp_si(xt, xt, 1); acb_set(res, xt); } } else { acb_add(xt, x, t, prec); acb_add(yt, y, t, prec); acb_add(zt, z, t, prec); acb_add(pt, p, t, prec); if (acb_contains_zero(xt) || acb_contains_zero(yt) || acb_contains_zero(zt) || acb_contains_zero(pt)) { acb_indeterminate(res); } else { acb_rsqrt_analytic(xt, xt, analytic, prec); acb_rsqrt_analytic(yt, yt, analytic, prec); acb_rsqrt_analytic(zt, zt, analytic, prec); acb_mul(xt, xt, yt, prec); acb_mul(xt, xt, zt, prec); acb_div(xt, xt, pt, prec); acb_set(res, xt); } } acb_clear(xt); acb_clear(yt); acb_clear(zt); acb_clear(pt); return 0; } void acb_elliptic_rj_integration(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec) { acb_t a, b, N, I, J; arb_t A; acb_ptr xyzp; mag_t tol; int deflated; /* printf("RJ integration: "); acb_printn(x, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(y, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(z, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(p, 6, ARB_STR_NO_RADIUS); printf(" "); printf("\n"); */ acb_init(N); acb_init(a); acb_init(b); acb_init(I); acb_init(J); arb_init(A); xyzp = _acb_vec_init(4); mag_init(tol); /* compute shift that puts parameters in right half-plane */ arb_min(A, acb_realref(x), acb_realref(y), prec); arb_min(A, A, acb_realref(z), prec); arb_min(A, A, acb_realref(p), prec); arb_neg(A, A); arb_one(acb_realref(a)); arb_max(A, A, acb_realref(a), prec); arb_add_ui(A, A, 2, prec); arb_get_ubound_arf(arb_midref(A), A, prec); mag_zero(arb_radref(A)); acb_set(xyzp, x); acb_set(xyzp + 1, y); acb_set(xyzp + 2, z); acb_set(xyzp + 3, p); /* If there is a zero among x, y, z, put it first. */ if (acb_is_zero(y)) acb_swap(xyzp, xyzp + 1); if (acb_is_zero(z)) acb_swap(xyzp, xyzp + 2); deflated = acb_is_zero(xyzp); acb_set_arb(N, A); /* Path deformation to avoid 0 */ if ((arb_is_nonnegative(acb_imagref(x)) || arb_is_positive(acb_realref(x))) && (arb_is_nonnegative(acb_imagref(y)) || arb_is_positive(acb_realref(y))) && (arb_is_nonnegative(acb_imagref(z)) || arb_is_positive(acb_realref(z))) && (arb_is_nonnegative(acb_imagref(p)) || arb_is_positive(acb_realref(p)))) { arb_set_si(acb_imagref(N), 1); } else if ((arb_is_negative(acb_imagref(x)) || arb_is_positive(acb_realref(x))) && (arb_is_negative(acb_imagref(y)) || arb_is_positive(acb_realref(y))) && (arb_is_negative(acb_imagref(z)) || arb_is_positive(acb_realref(z))) && (arb_is_negative(acb_imagref(p)) || arb_is_positive(acb_realref(p)))) { arb_set_si(acb_imagref(N), -1); } else { int i; arb_set_si(acb_imagref(N), 2); /* Go through the upper half-plane, but low enough that any parameter starting in the lower plane doesn't cross the branch cut */ for (i = 0; i < 4; i++) { if (deflated && (i == 0)) continue; if (arb_is_nonnegative(acb_imagref(xyzp + i)) || arb_is_positive(acb_realref(xyzp + i))) continue; arb_zero(acb_realref(a)); /* use as tmp var */ arb_get_abs_lbound_arf(arb_midref(acb_realref(a)), acb_imagref(xyzp + i), prec); arb_min(acb_imagref(N), acb_imagref(N), acb_realref(a), prec); } arb_mul_2exp_si(acb_imagref(N), acb_imagref(N), -1); } mag_one(tol); mag_mul_2exp_si(tol, tol, -prec); acb_zero(a); if (deflated) acb_sqrt(b, N, prec); else acb_set(b, N); /* flint_printf("integrate "); flint_printf("%d\n", deflated); flint_printf("x = "); acb_printd(xyzp, 10); flint_printf("\n"); flint_printf("y = "); acb_printd(xyzp + 1, 10); flint_printf("\n"); flint_printf("z = "); acb_printd(xyzp + 2, 10); flint_printf("\n"); flint_printf("p = "); acb_printd(xyzp + 3, 10); flint_printf("\n"); flint_printf("a = "); acb_printd(a, 10); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 10); flint_printf("\n"); flint_printf("N = "); acb_printd(N, 10); flint_printf("\n"); */ acb_calc_integrate(I, RJ_integrand, xyzp, a, b, prec, tol, NULL, prec); acb_mul_ui(I, I, 3, prec); acb_mul_2exp_si(I, I, -1); /* flint_printf("I = "); acb_printd(I, 10); flint_printf("\n"); */ acb_add(xyzp, x, N, prec); acb_add(xyzp + 1, y, N, prec); acb_add(xyzp + 2, z, N, prec); acb_add(xyzp + 3, p, N, prec); acb_elliptic_rj_carlson(J, xyzp, xyzp + 1, xyzp + 2, xyzp + 3, 0, prec); acb_add(res, I, J, prec); acb_clear(N); acb_clear(a); acb_clear(b); acb_clear(I); acb_clear(J); arb_clear(A); _acb_vec_clear(xyzp, 4); mag_clear(tol); } void acb_elliptic_rj(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec) { /* printf("RJ: "); acb_printn(x, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(y, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(z, 6, ARB_STR_NO_RADIUS); printf(" "); acb_printn(p, 6, ARB_STR_NO_RADIUS); printf(" "); printf("\n"); */ if (!acb_is_finite(x) || !acb_is_finite(y) || !acb_is_finite(z) || !acb_is_finite(p)) { acb_indeterminate(res); return; } if ((acb_contains_zero(x) + acb_contains_zero(y) + acb_contains_zero(z) > 1) || acb_contains_zero(p)) { acb_indeterminate(res); return; } /* Carlson's algorithm is correct in the degenerate case computing R_D */ if (x == p || acb_eq(x, p)) { acb_elliptic_rj_carlson(res, y, z, x, p, flags, prec); return; } if (y == p || acb_eq(y, p)) { acb_elliptic_rj_carlson(res, x, z, y, p, flags, prec); return; } if (z == p || acb_eq(z, p)) { acb_elliptic_rj_carlson(res, x, y, z, p, flags, prec); return; } /* Sufficient condition for correctness */ if (arb_is_nonnegative(acb_realref(x)) && arb_is_nonnegative(acb_realref(y)) && arb_is_nonnegative(acb_realref(z)) && arb_is_positive(acb_realref(p))) { acb_elliptic_rj_carlson(res, x, y, z, p, flags, prec); return; } /* Sufficient condition for correctness */ if (acb_is_real(x) && acb_is_real(y) && acb_is_real(z) && acb_is_real(p)) { acb_elliptic_rj_carlson(res, x, y, z, p, flags, prec); return; } /* Also a sufficient condition */ if (arb_is_nonnegative(acb_realref(p)) || arb_is_nonzero(acb_imagref(p))) { if ((arb_is_zero(acb_imagref(x)) && arb_is_nonnegative(acb_realref(x)) && acb_eq_conj(y, z)) || (arb_is_zero(acb_imagref(y)) && arb_is_nonnegative(acb_realref(y)) && acb_eq_conj(x, z)) || (arb_is_zero(acb_imagref(z)) && arb_is_nonnegative(acb_realref(z)) && acb_eq_conj(x, y))) { acb_elliptic_rj_carlson(res, x, y, z, p, flags, prec); return; } } /* Fast abort for input straddling branch cuts */ if ((arb_contains_zero(acb_imagref(x)) && !(arb_is_nonnegative(acb_imagref(x)) || arb_is_nonnegative(acb_realref(x)))) || (arb_contains_zero(acb_imagref(y)) && !(arb_is_nonnegative(acb_imagref(y)) || arb_is_nonnegative(acb_realref(y)))) || (arb_contains_zero(acb_imagref(z)) && !(arb_is_nonnegative(acb_imagref(z)) || arb_is_nonnegative(acb_realref(z)))) || (arb_contains_zero(acb_imagref(p)) && !(arb_is_nonnegative(acb_imagref(p)) || arb_is_nonnegative(acb_realref(p))))) { acb_indeterminate(res); return; } /* Use integration as fallback */ acb_elliptic_rj_integration(res, x, y, z, p, flags, prec); } arb-2.22.1/acb_elliptic/roots.c000066400000000000000000000032531417376376500163140ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" void acb_elliptic_roots(acb_t e1, acb_t e2, acb_t e3, const acb_t tau, slong prec) { acb_t t1, t2, t3, t4; int e1r, e23r; if (!arb_is_positive(acb_imagref(tau)) || !arb_is_finite(acb_realref(tau))) { acb_indeterminate(e1); acb_indeterminate(e2); acb_indeterminate(e3); return; } acb_init(t1); acb_init(t2); acb_init(t3); acb_init(t4); e1r = e23r = 0; if (arb_is_int(acb_realref(tau))) e1r = e23r = 1; else if (arb_is_int_2exp_si(acb_realref(tau), -1)) e1r = 1; acb_modular_theta(t1, t2, t3, t4, t1, tau, prec); acb_pow_ui(t2, t2, 4, prec); acb_pow_ui(t4, t4, 4, prec); acb_sub(e2, t2, t4, prec); acb_mul_2exp_si(t3, t4, 1); acb_add(e1, t2, t3, prec); acb_mul_2exp_si(t3, t2, 1); acb_add(e3, t3, t4, prec); acb_const_pi(t3, prec); acb_mul(t3, t3, t3, prec); acb_div_ui(t3, t3, 3, prec); acb_mul(e1, e1, t3, prec); acb_mul(e2, e2, t3, prec); acb_mul(e3, e3, t3, prec); acb_neg(e3, e3); if (e1r) arb_zero(acb_imagref(e1)); if (e23r) { arb_zero(acb_imagref(e2)); arb_zero(acb_imagref(e3)); } acb_clear(t1); acb_clear(t2); acb_clear(t3); acb_clear(t4); } arb-2.22.1/acb_elliptic/test/000077500000000000000000000000001417376376500157565ustar00rootroot00000000000000arb-2.22.1/acb_elliptic/test/t-e_inc.c000066400000000000000000000070561417376376500174500ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("e_inc...."); fflush(stdout); flint_randinit(state); /* test E(z,m) = E(z+pi k, m) - 2 k E(m) */ for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t z1, z2, m, r1, r2, r3, t; arb_t pi; fmpz_t k; slong prec1, prec2; int times_pi; acb_init(z1); acb_init(z2); acb_init(m); acb_init(r1); acb_init(r2); acb_init(r3); acb_init(t); arb_init(pi); fmpz_init(k); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); times_pi = n_randint(state, 2); acb_randtest(z1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); acb_randtest(m, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); fmpz_randtest(k, state, 1 + n_randint(state, 100)); arb_const_pi(pi, FLINT_MAX(prec1, prec2)); if (n_randint(state, 2)) arb_set_d(acb_realref(z1), -4.5 + n_randint(state, 10)); if (times_pi) { if (n_randint(state, 2)) { acb_mul_arb(t, z1, pi, prec2); acb_elliptic_e_inc(r1, t, m, 0, prec1); } else { acb_elliptic_e_inc(r1, z1, m, 1, prec1); } if (n_randint(state, 2)) { acb_add_fmpz(z2, z1, k, prec2); acb_elliptic_e_inc(r2, z2, m, 1, prec2); } else { acb_mul_arb(z2, z1, pi, prec2); arb_addmul_fmpz(acb_realref(z2), pi, k, prec2); acb_elliptic_e_inc(r2, z2, m, 0, prec2); } } else { acb_elliptic_e_inc(r1, z1, m, 0, prec1); acb_set(z2, z1); arb_addmul_fmpz(acb_realref(z2), pi, k, prec2); acb_elliptic_e_inc(r2, z2, m, 0, prec2); } acb_set(r3, r2); acb_modular_elliptic_e(t, m, prec2); acb_mul_2exp_si(t, t, 1); acb_submul_fmpz(r3, t, k, prec2); if (!acb_overlaps(r1, r3)) { flint_printf("FAIL: overlap\n\n"); flint_printf("times_pi = %d\n\n", times_pi); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("k = "); fmpz_print(k); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_printf("r3 = "); acb_printd(r3, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z1); acb_clear(z2); acb_clear(m); acb_clear(r1); acb_clear(r2); acb_clear(r3); acb_clear(t); arb_clear(pi); fmpz_clear(k); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-f.c000066400000000000000000000070241417376376500166130ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("f...."); fflush(stdout); flint_randinit(state); /* test F(z,m) = F(z+pi k, m) - 2 k K(m) */ for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t z1, z2, m, r1, r2, r3, t; arb_t pi; fmpz_t k; slong prec1, prec2; int times_pi; acb_init(z1); acb_init(z2); acb_init(m); acb_init(r1); acb_init(r2); acb_init(r3); acb_init(t); arb_init(pi); fmpz_init(k); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); times_pi = n_randint(state, 2); acb_randtest(z1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest(m, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); fmpz_randtest(k, state, 1 + n_randint(state, 100)); arb_const_pi(pi, FLINT_MAX(prec1, prec2)); if (n_randint(state, 2)) arb_set_d(acb_realref(z1), -4.5 + n_randint(state, 10)); if (times_pi) { if (n_randint(state, 2)) { acb_mul_arb(t, z1, pi, prec2); acb_elliptic_f(r1, t, m, 0, prec1); } else { acb_elliptic_f(r1, z1, m, 1, prec1); } if (n_randint(state, 2)) { acb_add_fmpz(z2, z1, k, prec2); acb_elliptic_f(r2, z2, m, 1, prec2); } else { acb_mul_arb(z2, z1, pi, prec2); arb_addmul_fmpz(acb_realref(z2), pi, k, prec2); acb_elliptic_f(r2, z2, m, 0, prec2); } } else { acb_elliptic_f(r1, z1, m, 0, prec1); acb_set(z2, z1); arb_addmul_fmpz(acb_realref(z2), pi, k, prec2); acb_elliptic_f(r2, z2, m, 0, prec2); } acb_set(r3, r2); acb_modular_elliptic_k(t, m, prec2); acb_mul_2exp_si(t, t, 1); acb_submul_fmpz(r3, t, k, prec2); if (!acb_overlaps(r1, r3)) { flint_printf("FAIL: overlap\n\n"); flint_printf("times_pi = %d\n\n", times_pi); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("k = "); fmpz_print(k); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_printf("r3 = "); acb_printd(r3, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z1); acb_clear(z2); acb_clear(m); acb_clear(r1); acb_clear(r2); acb_clear(r3); acb_clear(t); arb_clear(pi); fmpz_clear(k); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-inv_p.c000066400000000000000000000035111417376376500174760ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" int main() { slong iter; flint_rand_t state; flint_printf("inv_p...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t tau, z, w, pw; slong prec; acb_init(tau); acb_init(z); acb_init(w); acb_init(pw); prec = 2 + n_randint(state, 400); acb_randtest(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); acb_randtest(w, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); acb_randtest(tau, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); if (arf_sgn(arb_midref(acb_imagref(tau))) < 0) acb_neg(tau, tau); acb_elliptic_inv_p(w, z, tau, prec); acb_elliptic_p(pw, w, tau, prec); if (!acb_contains(pw, z)) { flint_printf("FAIL (containment)\n"); flint_printf("tau = "); acb_printd(tau, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 30); flint_printf("\n\n"); flint_printf("pw = "); acb_printd(pw, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z); acb_clear(w); acb_clear(pw); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-invariants.c000066400000000000000000000043441417376376500205460ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" int main() { slong iter; flint_rand_t state; flint_printf("invariants...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t tau, e1, e2, e3, g2, g3, h2, h3; slong prec; acb_init(tau); acb_init(e1); acb_init(e2); acb_init(e3); acb_init(g2); acb_init(g3); acb_init(h2); acb_init(h3); prec = 2 + n_randint(state, 400); acb_randtest(tau, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); if (arf_sgn(arb_midref(acb_imagref(tau))) < 0) acb_neg(tau, tau); acb_elliptic_roots(e1, e2, e3, tau, prec); acb_elliptic_invariants(g2, g3, tau, prec); acb_mul(h2, e1, e1, prec); acb_addmul(h2, e2, e2, prec); acb_addmul(h2, e3, e3, prec); acb_mul_2exp_si(h2, h2, 1); acb_mul(h3, e1, e2, prec); acb_mul(h3, h3, e3, prec); acb_mul_2exp_si(h3, h3, 2); if (!acb_overlaps(g2, h2) || !acb_overlaps(g3, h3)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau = "); acb_printd(tau, 30); flint_printf("\n\n"); flint_printf("g2 = "); acb_printd(g2, 30); flint_printf("\n\n"); flint_printf("g3 = "); acb_printd(g3, 30); flint_printf("\n\n"); flint_printf("h2 = "); acb_printd(h2, 30); flint_printf("\n\n"); flint_printf("h3 = "); acb_printd(h3, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(e1); acb_clear(e2); acb_clear(e3); acb_clear(g2); acb_clear(g3); acb_clear(h2); acb_clear(h3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-p_p_prime.c000066400000000000000000000057521417376376500203460ustar00rootroot00000000000000/* Copyright (C) 2021 Daniel Schultz This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" int main() { slong iter; flint_rand_t state; flint_printf("p_p_prime...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_struct pj[2]; acb_t tau, z, p, pp, g2, g3, t; slong prec; acb_init(tau); acb_init(z); acb_init(p); acb_init(pp); acb_init(pj + 0); acb_init(pj + 1); acb_init(g2); acb_init(g3); acb_init(t); prec = 2 + n_randint(state, 400); acb_randtest(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); acb_randtest(tau, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); if (arf_sgn(arb_midref(acb_imagref(tau))) < 0) acb_neg(tau, tau); acb_elliptic_p(p, z, tau, prec); acb_elliptic_p_prime(pp, z, tau, prec); acb_elliptic_p_jet(pj, z, tau, 2, prec); if (!acb_overlaps(p, pj + 0) || !acb_overlaps(pp, pj + 1)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau = "); acb_printd(tau, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("p = "); acb_printd(p, 30); flint_printf("\n\n"); flint_printf("pp = "); acb_printd(pp, 30); flint_printf("\n\n"); flint_printf("pj0 = "); acb_printd(pj + 0, 30); flint_printf("\n\n"); flint_printf("pj1 = "); acb_printd(pj + 1, 30); flint_printf("\n\n"); flint_abort(); } acb_elliptic_invariants(g2, g3, tau, prec); acb_pow_ui(pj + 0, pp, 2, prec); acb_mul(t, p, g2, prec); acb_add(t, t, g3, prec); acb_pow_ui(pj + 1, p, 3, prec); acb_mul_ui(pj + 1, pj + 1, 4, prec); acb_sub(pj + 1, pj + 1, t, prec); if (!acb_overlaps(pj + 0, pj + 1)) { flint_printf("FAIL (check pp^2 = 4p^3-g2*p-g3)\n"); flint_printf("tau = "); acb_printd(tau, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("p = "); acb_printd(p, 30); flint_printf("\n\n"); flint_printf("pp = "); acb_printd(pp, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z); acb_clear(p); acb_clear(pp); acb_clear(pj + 0); acb_clear(pj + 1); acb_clear(g2); acb_clear(g3); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-pi.c000066400000000000000000000130471417376376500170000ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" static const double testdata_pi[17][6] = { {-2.0, 0.0, 0.0, 0.0, 0.9068996821171089253, 0.0}, {-2.0, 0.0, 2.0, 0.0, 0.90023699434287315449, -0.5446596026314193538}, {-2.0, 0.0, 0.0, 1.0, 0.84791174714919877248, 0.12945491185218067805}, {0.0, 0.0, -2.0, 0.0, 1.1714200841467698589, 0.0}, {0.0, 0.0, 2.0, 0.0, 1.3110287771460599052, -1.3110287771460599052}, {0.0, 0.0, 0.0, 1.0, 1.4212722810450360172, 0.29538028421477684284}, {2.0, 0.0, -2.0, 0.0, 0.30328372333566606144, -1.1107207345395915618}, {2.0, 0.0, 0.0, 0.0, 0.0, -1.5707963267948966192}, {2.0, 0.0, 0.0, 1.0, 0.53486323549280133642, -1.7002121907485779385}, {0.0, 1.0, -2.0, 0.0, 0.95136015191114896677, 0.33513918759114703301}, {0.0, 1.0, 0.0, 0.0, 1.2203312255379458475, 0.50547774420519745381}, {0.0, 1.0, 2.0, 0.0, 1.7987619218751253398, -0.55552744414075242238}, {2.0, -1.0, 2.0, 1.0, 1.8578723151271115, -1.18642180609983531}, {2.0, -0.5, 0.5, 1.0, 0.936761970766645807, -1.61876787838890786}, {2.0, 0.0, 1.0, 1.0, 0.999881420735506708, -2.4139272867045391}, {2.0, 1.0, 2.0, -1.0, 1.8578723151271115, 1.18642180609983531}, {2.0, 1.0, 2.0, 0.0, 2.78474654927885845, 2.02204728966993314}, }; int main() { slong iter; flint_rand_t state; flint_printf("pi...."); fflush(stdout); flint_randinit(state); /* Test self-consistency, and Pi(n,n) = E(n) / (1-n) */ for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_t n, m, r1, r2, t; slong prec1, prec2; prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); acb_init(n); acb_init(m); acb_init(r1); acb_init(r2); acb_init(t); if (iter == 0) { slong k; for (k = 0; k < 17; k++) { acb_set_d_d(n, testdata_pi[k][0], testdata_pi[k][1]); acb_set_d_d(m, testdata_pi[k][2], testdata_pi[k][3]); acb_set_d_d(r2, testdata_pi[k][4], testdata_pi[k][5]); mag_set_d(arb_radref(acb_realref(r2)), 1e-14 * fabs(testdata_pi[k][4])); mag_set_d(arb_radref(acb_imagref(r2)), 1e-14 * fabs(testdata_pi[k][5])); for (prec1 = 32; prec1 <= (arb_test_multiplier() < 1.0 ? 64 : 256); prec1 *= 2) { acb_elliptic_pi(r1, n, m, prec1 + 30); if (!acb_overlaps(r1, r2) || acb_rel_accuracy_bits(r1) < prec1) { flint_printf("FAIL: overlap (testdata)\n\n"); flint_printf("prec = %wd, accuracy = %wd\n\n", prec1, acb_rel_accuracy_bits(r1)); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } } } acb_randtest(n, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_randtest(m, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_one(t); if ((acb_is_real(n) && acb_is_real(m) && arb_le(acb_realref(n), acb_realref(t)) && arb_le(acb_realref(m), acb_realref(t))) || n_randint(state, 10) == 0) { acb_elliptic_pi(r1, n, n, prec1); acb_modular_elliptic_e(r2, n, prec1); acb_sub_ui(t, n, 1, prec1); acb_neg(t, t); acb_div(r2, r2, t, prec1); if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap (m=n)\n\n"); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } acb_elliptic_pi(r1, n, m, prec1); acb_randtest(t, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_add(n, n, t, prec2); acb_sub(n, n, t, prec2); acb_randtest(t, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_add(m, m, t, prec2); acb_sub(m, m, t, prec2); acb_elliptic_pi(r2, n, m, prec2); if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap (consistency)\n\n"); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } acb_clear(n); acb_clear(m); acb_clear(r1); acb_clear(r2); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-pi_inc.c000066400000000000000000000134011417376376500176230ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("pi_inc...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_t z1, z2, n, m, r1, r2, r3, t; arb_t pi; fmpz_t k; slong prec1, prec2; int times_pi; acb_init(z1); acb_init(z2); acb_init(n); acb_init(m); acb_init(r1); acb_init(r2); acb_init(r3); acb_init(t); arb_init(pi); fmpz_init(k); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); times_pi = n_randint(state, 2); acb_randtest(n, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); acb_randtest(z1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); acb_randtest(m, state, 1 + n_randint(state, 500), 1 + n_randint(state, 10)); fmpz_randtest(k, state, 1 + n_randint(state, 100)); arb_const_pi(pi, FLINT_MAX(prec1, prec2)); acb_one(t); if ((acb_is_real(n) && acb_is_real(z1) && acb_is_real(m) && arb_le(acb_realref(n), acb_realref(t)) && arb_le(acb_realref(m), acb_realref(t))) || n_randint(state, 10) == 0) { if (n_randint(state, 2)) arb_set_d(acb_realref(z1), -4.5 + n_randint(state, 10)); /* test Pi(n,z,m) = Pi(n, z+pi k, m) - 2 k Pi(n, m) */ if (times_pi) { if (n_randint(state, 2)) { acb_mul_arb(t, z1, pi, prec2); acb_elliptic_pi_inc(r1, n, t, m, 0, prec1); } else { acb_elliptic_pi_inc(r1, n, z1, m, 1, prec1); } if (n_randint(state, 2)) { acb_add_fmpz(z2, z1, k, prec2); acb_elliptic_pi_inc(r2, n, z2, m, 1, prec2); } else { acb_mul_arb(z2, z1, pi, prec2); arb_addmul_fmpz(acb_realref(z2), pi, k, prec2); acb_elliptic_pi_inc(r2, n, z2, m, 0, prec2); } } else { acb_elliptic_pi_inc(r1, n, z1, m, 0, prec1); acb_set(z2, z1); arb_addmul_fmpz(acb_realref(z2), pi, k, prec2); acb_elliptic_pi_inc(r2, n, z2, m, 0, prec2); } acb_set(r3, r2); acb_elliptic_pi(t, n, m, prec2); acb_mul_2exp_si(t, t, 1); acb_submul_fmpz(r3, t, k, prec2); if (!acb_overlaps(r1, r3)) { flint_printf("FAIL: overlap\n\n"); flint_printf("times_pi = %d\n\n", times_pi); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 30); flint_printf("\n\n"); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("k = "); fmpz_print(k); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_printf("r3 = "); acb_printd(r3, 30); flint_printf("\n\n"); flint_abort(); } /* test http://functions.wolfram.com/EllipticIntegrals/EllipticPi3/03/01/01/0006/ */ /* Pi(n,z,n) = (n sin(2z) / (2 sqrt(1-n sin(z)^2)) - E(z,n))/(n-1) */ acb_elliptic_pi_inc(r1, n, z1, n, times_pi, prec1); if (times_pi) acb_sin_pi(z2, z1, prec1); else acb_sin(z2, z1, prec1); acb_mul(z2, z2, z2, prec1); acb_mul(z2, z2, n, prec1); acb_sub_ui(z2, z2, 1, prec1); acb_neg(z2, z2); acb_rsqrt(z2, z2, prec1); acb_mul_2exp_si(z2, z2, -1); acb_mul_2exp_si(r3, z1, 1); if (times_pi) acb_sin_pi(r3, r3, prec1); else acb_sin(r3, r3, prec1); acb_mul(z2, z2, r3, prec1); acb_mul(z2, z2, n, prec1); acb_elliptic_e_inc(r3, z1, n, times_pi, prec1); acb_sub(z2, z2, r3, prec1); acb_sub_ui(r3, n, 1, prec1); acb_div(r2, z2, r3, prec1); if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap Pi(n,z,n)\n\n"); flint_printf("times_pi = %d\n\n", times_pi); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } acb_clear(z1); acb_clear(z2); acb_clear(n); acb_clear(m); acb_clear(r1); acb_clear(r2); acb_clear(r3); acb_clear(t); arb_clear(pi); fmpz_clear(k); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-rc1.c000066400000000000000000000035431417376376500170550ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("rc1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t x, r1, r2, a, b, c; acb_init(x); acb_init(r1); acb_init(r2); acb_init(a); acb_init(b); acb_init(c); acb_randtest(x, state, 1 + n_randint(state, 300), 10); acb_randtest(a, state, 1 + n_randint(state, 300), 10); acb_add(r2, x, a, 200); acb_sub(r2, r2, a, 200); acb_neg(r2, r2); if (n_randint(state, 2)) acb_swap(x, r2); acb_elliptic_rc1(r1, x, 2 + n_randint(state, 200)); acb_one(a); acb_set_d(b, 0.5); acb_set_d(c, 1.5); acb_hypgeom_2f1(r2, a, b, c, r2, 0, 20 + n_randint(state, 200)); if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(r1); acb_clear(r2); acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-rf.c000066400000000000000000000050261417376376500167750ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" int main() { slong iter; flint_rand_t state; flint_printf("rf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, y, z, r1, r2; slong prec1, prec2; prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); acb_init(x); acb_init(y); acb_init(z); acb_init(r1); acb_init(r2); acb_randtest_special(x, state, 1 + n_randint(state, 300), 1 + n_randint(state, 100)); acb_randtest_special(y, state, 1 + n_randint(state, 300), 1 + n_randint(state, 100)); acb_randtest_special(z, state, 1 + n_randint(state, 300), 1 + n_randint(state, 100)); acb_elliptic_rf(r1, x, y, z, 0, prec1); switch (n_randint(state, 6)) { case 0: acb_elliptic_rf(r2, x, y, z, 0, prec2); break; case 1: acb_elliptic_rf(r2, x, z, y, 0, prec2); break; case 2: acb_elliptic_rf(r2, y, x, z, 0, prec2); break; case 3: acb_elliptic_rf(r2, y, z, x, 0, prec2); break; case 4: acb_elliptic_rf(r2, z, x, y, 0, prec2); break; default: acb_elliptic_rf(r2, z, y, x, 0, prec2); break; } if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(z); acb_clear(r1); acb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-rg.c000066400000000000000000000111421417376376500167720ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" /* Test input from Carlson's paper and checked with mpmath. */ static const double testdata_rg[7][8] = { {0.0, 0.0, 16.0, 0.0, 16.0, 0.0, 3.1415926535897932385, 0.0}, {2.0, 0.0, 3.0, 0.0, 4.0, 0.0, 1.7255030280692277601, 0.0}, {0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.4236065423969895433, 0.0}, {-1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.44660591677018372657, 0.70768352357515390073}, {0.0, -1.0, -1.0, 1.0, 0.0, 1.0, 0.36023392184473309034, 0.40348623401722113741}, {0.0, 0.0, 0.0796, 0.0, 4.0, 0.0, 1.0284758090288040022, 0.0}, /* more tests */ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, }; int main() { slong iter; flint_rand_t state; flint_printf("rg...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, z, r1, r2; slong prec1, prec2; prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); acb_init(x); acb_init(y); acb_init(z); acb_init(r1); acb_init(r2); if (iter == 0) { slong k; for (k = 0; k < 7; k++) { acb_set_d_d(x, testdata_rg[k][0], testdata_rg[k][1]); acb_set_d_d(y, testdata_rg[k][2], testdata_rg[k][3]); acb_set_d_d(z, testdata_rg[k][4], testdata_rg[k][5]); acb_set_d_d(r2, testdata_rg[k][6], testdata_rg[k][7]); mag_set_d(arb_radref(acb_realref(r2)), 1e-14 * fabs(testdata_rg[k][6])); mag_set_d(arb_radref(acb_imagref(r2)), 1e-14 * fabs(testdata_rg[k][7])); for (prec1 = 16; prec1 <= 256; prec1 *= 2) { acb_elliptic_rg(r1, x, y, z, 0, prec1); if (!acb_overlaps(r1, r2) || acb_rel_accuracy_bits(r1) < prec1 * 0.9 - 10) { flint_printf("FAIL: overlap (testdata rg)\n\n"); flint_printf("prec = %wd, accuracy = %wd\n\n", prec1, acb_rel_accuracy_bits(r1)); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } } } acb_randtest(x, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_randtest(y, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_randtest(z, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_elliptic_rg(r1, x, y, z, 0, prec1); switch (n_randint(state, 6)) { case 0: acb_elliptic_rg(r2, x, y, z, 0, prec2); break; case 1: acb_elliptic_rg(r2, x, z, y, 0, prec2); break; case 2: acb_elliptic_rg(r2, y, x, z, 0, prec2); break; case 3: acb_elliptic_rg(r2, y, z, x, 0, prec2); break; case 4: acb_elliptic_rg(r2, z, x, y, 0, prec2); break; default: acb_elliptic_rg(r2, z, y, x, 0, prec2); break; } if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(y); acb_clear(z); acb_clear(r1); acb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-rj.c000066400000000000000000000227621417376376500170070ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" /* Test input from Carlson's paper and checked with mpmath. */ static const double testdata_rj[16][10] = { {0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 0.77688623778582332014, 0.0}, {2.0, 0.0, 3.0, 0.0, 4.0, 0.0, 5.0, 0.0, 0.14297579667156753833, 0.0}, {2.0, 0.0, 3.0, 0.0, 4.0, 0.0, -1.0, 1.0, 0.13613945827770535204, -0.3820756162442716425}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 2.0, 0.0, 1.6490011662710884518, 0.0}, {-1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 2.0, 0.0, 0.94148358841220238083, 0.0}, {0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.8260115229009316249, 1.22906619086434715}, {-1.0, 1.0, -1.0, -1.0, 1.0, 0.0, -3.0, 1.0, -0.61127970812028172124, -1.068403839000680788}, {-1.0, 1.0, -2.0, -1.0, 0.0, -1.0, -1.0, 1.0, 1.8249027393703805305, -1.2218475784827035855}, /* additional tests where Carlson's algorithm may not be valid */ {-1.0, -0.5, -10.0, -6.0, -10.0, -3.0, -5.0, 10.0, 0.128470516743927699, 0.102175950778504625}, {1.987, 0.0, 4.463, -1.614, 0.0, 0.0, -3.965, 0.0, -0.341575118513811305, -0.394703757004268486}, {0.3068, 0.0, -4.037, 0.632, 1.654, 0.0, -0.9609, 0.0, -1.14735199581485639, -0.134450158867472264}, {0.3068, 0.0, -4.037, -0.632, 1.654, 0.0, -0.9609, 0.0, 1.758765901861727, -0.161002343366626892}, {0.3068, 0.0, -4.037, 0.0632, 1.654, 0.0, -0.9609, 0.0, -1.17157627949475577, -0.069182614173988811}, {0.3068, 0.0, -4.037, -0.0632, 1.654, 0.0, -0.9609, 0.0, 1.77940452391261626, 0.0388711305592447234}, {0.3068, 0.0, -4.037, 0.00632, 1.654, 0.0, -0.9609, 0.0, -1.17337595670549633, -0.0623069224526925}, {0.3068, 0.0, -4.037, -0.00632, 1.654, 0.0, -0.9609, 0.0, 1.77806722756403055, 0.0592749824572262329}, }; static const double testdata_rd[6][8] = { {0.0, 0.0, 2.0, 0.0, 1.0, 0.0, 1.7972103521033883112, 0.0}, {2.0, 0.0, 3.0, 0.0, 4.0, 0.0, 0.16510527294261053349, 0.0}, {0.0, 1.0, 0.0, -1.0, 2.0, 0.0, 0.65933854154219768919, 0.0}, {0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 1.2708196271909686299, 2.7811120159520578776}, {0.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.8577235439239060056, -0.96193450888838559989}, {-2.0, -1.0, 0.0, -1.0, -1.0, 1.0, 1.8249027393703805305, -1.2218475784827035855}, }; int main() { slong iter; flint_rand_t state; flint_printf("rj...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, z, p, r1, r2; slong prec1, prec2; prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); acb_init(x); acb_init(y); acb_init(z); acb_init(p); acb_init(r1); acb_init(r2); if (iter == 0) { slong k; for (k = 0; k < 16; k++) { acb_set_d_d(x, testdata_rj[k][0], testdata_rj[k][1]); acb_set_d_d(y, testdata_rj[k][2], testdata_rj[k][3]); acb_set_d_d(z, testdata_rj[k][4], testdata_rj[k][5]); acb_set_d_d(p, testdata_rj[k][6], testdata_rj[k][7]); acb_set_d_d(r2, testdata_rj[k][8], testdata_rj[k][9]); mag_set_d(arb_radref(acb_realref(r2)), 1e-14 * fabs(testdata_rj[k][8])); mag_set_d(arb_radref(acb_imagref(r2)), 1e-14 * fabs(testdata_rj[k][9])); for (prec1 = 16; prec1 <= 256; prec1 *= 2) { acb_elliptic_rj(r1, x, y, z, p, 0, prec1); if (!acb_overlaps(r1, r2) || (k < 8 && acb_rel_accuracy_bits(r1) < prec1 - 12)) { flint_printf("FAIL: overlap (testdata rj)\n\n"); flint_printf("prec = %wd, accuracy = %wd\n\n", prec1, acb_rel_accuracy_bits(r1)); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("p = "); acb_printd(p, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } } for (k = 0; k < 6; k++) { acb_set_d_d(x, testdata_rd[k][0], testdata_rd[k][1]); acb_set_d_d(y, testdata_rd[k][2], testdata_rd[k][3]); acb_set_d_d(z, testdata_rd[k][4], testdata_rd[k][5]); acb_set_d_d(r2, testdata_rd[k][6], testdata_rd[k][7]); mag_set_d(arb_radref(acb_realref(r2)), 1e-14 * fabs(testdata_rd[k][6])); mag_set_d(arb_radref(acb_imagref(r2)), 1e-14 * fabs(testdata_rd[k][7])); for (prec1 = 16; prec1 <= 256; prec1 *= 2) { acb_elliptic_rj(r1, x, y, z, z, 0, prec1); if (!acb_overlaps(r1, r2) || acb_rel_accuracy_bits(r1) < prec1 - 12) { flint_printf("FAIL: overlap (testdata rd)\n\n"); flint_printf("prec = %wd, accuracy = %wd\n\n", prec1, acb_rel_accuracy_bits(r1)); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } } } acb_randtest(x, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_randtest(y, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_randtest(z, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); acb_set(p, z); /* Potentially slow general tests */ if ((arb_is_nonnegative(acb_realref(x)) && arb_is_nonnegative(acb_realref(y)) && arb_is_nonnegative(acb_realref(z)) && arb_is_positive(acb_realref(p))) || (n_randint(state, 10) == 0 && prec1 < 100 && prec2 < 100)) { acb_elliptic_rj(r1, x, y, z, z, 0, prec1); acb_elliptic_rj(r2, x, y, z, p, 0, prec2); if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap R_D\n\n"); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("p = "); acb_printd(p, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } acb_randtest(p, state, 1 + n_randint(state, 300), 1 + n_randint(state, 30)); /* Specialize */ if (n_randint(state, 2)) { if (arb_is_zero(acb_imagref(y))) arb_one(acb_imagref(y)); acb_conj(z, y); arb_zero(acb_imagref(x)); arb_abs(acb_realref(x), acb_realref(x)); } acb_elliptic_rj(r1, x, y, z, p, 0, prec1); switch (n_randint(state, 6)) { case 0: acb_elliptic_rj(r2, x, y, z, p, 0, prec2); break; case 1: acb_elliptic_rj(r2, x, z, y, p, 0, prec2); break; case 2: acb_elliptic_rj(r2, y, x, z, p, 0, prec2); break; case 3: acb_elliptic_rj(r2, y, z, x, p, 0, prec2); break; case 4: acb_elliptic_rj(r2, z, x, y, p, 0, prec2); break; default: acb_elliptic_rj(r2, z, y, x, p, 0, prec2); break; } if (!acb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("p = "); acb_printd(p, 30); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } acb_clear(x); acb_clear(y); acb_clear(z); acb_clear(p); acb_clear(r1); acb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-sigma.c000066400000000000000000000124031417376376500174630ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_elliptic.h" #define NUM_TESTS 6 #define EPS 1e-13 /* z, tau, sigma(z, tau) checked with Mathematica: N[{z, tau, WeierstrassSigma[z, WeierstrassInvariants[{1, tau}/2]]}, 20] */ const double testdata[NUM_TESTS][6] = { { 1.4142135623730950488, 1.7320508075688772935, 2.2360679774997896964, 2.6457513110645905905, 3.2497809387982239642, -6.2896427497987532326 }, { -1.0, -2.0, -1.0, 3.0, -0.17877885105742438172, 0.58508579024326876042 }, { 0.1, 0.0, 0.6, 0.2, 0.100055263033144515447, -0.000188998253739903104 }, { 0.0, 0.2, 0.2, 0.1, -0.05083547794781899013, 0.19409530512485630787 }, { 0.5, 0.0, 0.333333333333333333, 20.0, 0.48022700051193809297, 0.0 }, { 0.6666666666666667, 1.0, -3.1415926535897932385, 1.0, 1.3092907491438550394, 0.9063920053572463817 } }; static void acb_set_dddd(acb_t z, double a, double ar, double b, double br) { arf_set_d(arb_midref(acb_realref(z)), a); mag_set_d(arb_radref(acb_realref(z)), ar); arf_set_d(arb_midref(acb_imagref(z)), b); mag_set_d(arb_radref(acb_imagref(z)), br); } int main() { slong iter; flint_rand_t state; flint_printf("sigma...."); fflush(stdout); flint_randinit(state); /* check test values */ for (iter = 0; iter < 20 * arb_test_multiplier(); iter++) { slong i; acb_t z, tau, p1, p2; acb_init(z); acb_init(tau); acb_init(p1); acb_init(p2); for (i = 0; i < NUM_TESTS; i++) { acb_set_dddd(z, testdata[i][0], 0.0, testdata[i][1], 0.0); acb_set_dddd(tau, testdata[i][2], 0.0, testdata[i][3], 0.0); acb_set_dddd(p2, testdata[i][4], EPS, testdata[i][5], EPS); acb_elliptic_sigma(p1, z, tau, 2 + n_randint(state, 400)); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (test value)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(z); acb_clear(tau); acb_clear(p1); acb_clear(p2); } /* Test periods */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t tau, z1, z2, e1, e2, p1, p2, t, u; slong m, n, e0, prec0, prec1, prec2; acb_init(tau); acb_init(z1); acb_init(z2); acb_init(e1); acb_init(e2); acb_init(p1); acb_init(p2); acb_init(t); acb_init(u); e0 = 1 + n_randint(state, 10); prec0 = 2 + n_randint(state, 400); prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); acb_randtest(tau, state, prec0, e0); if (arf_sgn(arb_midref(acb_imagref(tau))) < 0) acb_neg(tau, tau); acb_one(e1); acb_mul_2exp_si(e1, e1, -1); acb_elliptic_zeta(e1, e1, tau, prec0); acb_mul_2exp_si(e2, tau, -1); acb_elliptic_zeta(e2, e2, tau, prec0); acb_randtest(z1, state, prec0, e0); acb_randtest(p1, state, prec0, e0); acb_randtest(p2, state, prec0, e0); /* z2 = z1 + m + n*tau */ m = n_randint(state, 10); n = n_randint(state, 10); acb_add_ui(z2, z1, m, prec0); acb_addmul_ui(z2, tau, n, prec0); /* sigma(z + m + n*tau) = (-1)^(m+n+mn) exp((m e1 + n e2)(m + n tau + 2z) sigma(z) */ acb_elliptic_sigma(p1, z1, tau, prec1); acb_elliptic_sigma(p2, z2, tau, prec2); acb_mul_ui(t, e1, m, prec2); acb_addmul_ui(t, e2, n, prec2); acb_mul_2exp_si(u, z1, 1); acb_addmul_ui(u, tau, n, prec2); acb_add_ui(u, u, m, prec2); acb_mul(t, t, u, prec2); acb_neg(t, t); acb_exp(t, t, prec2); if ((m + n + m*n) % 2 == 1) acb_neg(t, t); acb_mul(p2, p2, t, prec2); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z1); acb_clear(z2); acb_clear(e1); acb_clear(e2); acb_clear(p1); acb_clear(p2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/test/t-zeta.c000066400000000000000000000132451417376376500173330ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_elliptic.h" #define NUM_TESTS 6 #define EPS 1e-13 /* z, tau, zeta(z, tau) checked with Mathematica: N[{z, tau, WeierstrassZeta[z, WeierstrassInvariants[{1, tau}/2]]}, 20] */ const double testdata[NUM_TESTS][6] = { { 1.4142135623730950488, 1.7320508075688772935, 2.2360679774997896964, 2.6457513110645905905, 4.6708530542187465956, 2.5654839019069906619 }, { -3.0, -2.0, -7.0, 3.0, -9.8696028584909729616, -3.4498761151331612449 }, { 0.1, 0.0, 0.6, 0.2, 10.0222822996630537305, -0.0754856899565257555 }, { 0.0, 0.1, 0.6, 0.2, -0.0754856899565257555, -10.0222822996630537305 }, { 0.5, 0.0, 0.333333333333333333, 20.0, 1.6449340668482264365, 0.0 }, { 3.6666666666666667, 2014.0, -3.1415926535897932385, 0.1, -147965.49261828128352, -10426.83705290890375 } }; static void acb_set_dddd(acb_t z, double a, double ar, double b, double br) { arf_set_d(arb_midref(acb_realref(z)), a); mag_set_d(arb_radref(acb_realref(z)), ar); arf_set_d(arb_midref(acb_imagref(z)), b); mag_set_d(arb_radref(acb_imagref(z)), br); } int main() { slong iter; flint_rand_t state; flint_printf("zeta...."); fflush(stdout); flint_randinit(state); /* check test values */ for (iter = 0; iter < 20 * arb_test_multiplier(); iter++) { slong i; acb_t z, tau, p1, p2; acb_init(z); acb_init(tau); acb_init(p1); acb_init(p2); for (i = 0; i < NUM_TESTS; i++) { acb_set_dddd(z, testdata[i][0], 0.0, testdata[i][1], 0.0); acb_set_dddd(tau, testdata[i][2], 0.0, testdata[i][3], 0.0); if (i == NUM_TESTS - 1) /* sensitive to rounding errors in doubles */ acb_set_dddd(p2, testdata[i][4], 1e-6, testdata[i][5], 1e-6); else acb_set_dddd(p2, testdata[i][4], EPS, testdata[i][5], EPS); acb_elliptic_zeta(p1, z, tau, 2 + n_randint(state, 400)); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (test value)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } acb_elliptic_zeta(p2, z, tau, 2 + n_randint(state, 800)); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (test value 2)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(z); acb_clear(tau); acb_clear(p1); acb_clear(p2); } /* Test periods */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t tau, z1, z2, e1, e2, p1, p2; slong m, n, e0, prec0, prec1, prec2; acb_init(tau); acb_init(z1); acb_init(z2); acb_init(e1); acb_init(e2); acb_init(p1); acb_init(p2); e0 = 1 + n_randint(state, 10); prec0 = 2 + n_randint(state, 400); prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); acb_randtest(tau, state, prec0, e0); if (arf_sgn(arb_midref(acb_imagref(tau))) < 0) acb_neg(tau, tau); acb_one(e1); acb_mul_2exp_si(e1, e1, -1); acb_elliptic_zeta(e1, e1, tau, prec0); acb_mul_2exp_si(e2, tau, -1); acb_elliptic_zeta(e2, e2, tau, prec0); acb_mul_2exp_si(e1, e1, 1); acb_mul_2exp_si(e2, e2, 1); acb_randtest(z1, state, prec0, e0); acb_randtest(p1, state, prec0, e0); acb_randtest(p2, state, prec0, e0); /* z2 = z1 + m + n*tau */ m = n_randint(state, 10); n = n_randint(state, 10); acb_add_ui(z2, z1, m, prec0); acb_addmul_ui(z2, tau, n, prec0); /* zeta(z + 1) = zeta(z) + 2 zeta(1) */ /* zeta(z + tau) = zeta(z) + 2 zeta(tau) */ acb_elliptic_zeta(p1, z1, tau, prec1); acb_elliptic_zeta(p2, z2, tau, prec2); acb_submul_ui(p2, e1, m, prec2); acb_submul_ui(p2, e2, n, prec2); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z1); acb_clear(z2); acb_clear(e1); acb_clear(e2); acb_clear(p1); acb_clear(p2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_elliptic/zeta.c000066400000000000000000000042461417376376500161140ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_elliptic.h" #include "acb_modular.h" /* eta1 = (-1/6) theta1'''(0) / theta1'(0) */ static void eta1(acb_t res, acb_t theta1, const acb_t tau, slong prec) { acb_ptr theta; acb_t z; acb_init(z); theta = _acb_vec_init(16); acb_modular_theta_jet(theta, theta + 4, theta + 8, theta + 12, z, tau, 4, prec); if (theta1 != NULL) acb_set(theta1, theta + 1); acb_div(res, theta + 3, theta + 1, prec); acb_neg(res, res); _acb_vec_clear(theta, 16); acb_clear(z); } /* zeta(z) = 2 eta1 z + theta1'(z,q) / theta1(z,q) */ void acb_elliptic_zeta(acb_t res, const acb_t z, const acb_t tau, slong prec) { acb_ptr t; int real; real = acb_is_real(z) && arb_is_int_2exp_si(acb_realref(tau), -1) && arb_is_positive(acb_imagref(tau)); t = _acb_vec_init(8); acb_modular_theta_jet(t, t + 2, t + 4, t + 6, z, tau, 2, prec); eta1(t + 2, NULL, tau, prec); acb_mul_2exp_si(t + 2, t + 2, 1); acb_mul(t + 2, t + 2, z, prec); acb_div(t, t + 1, t, prec); acb_add(res, t, t + 2, prec); if (real) arb_zero(acb_imagref(res)); _acb_vec_clear(t, 8); } /* sigma(z) = exp(eta1 z^2) theta1(z) / theta1'(0) */ void acb_elliptic_sigma(acb_t res, const acb_t z, const acb_t tau, slong prec) { acb_ptr t; int real; real = acb_is_real(z) && arb_is_int_2exp_si(acb_realref(tau), -1) && arb_is_positive(acb_imagref(tau)); t = _acb_vec_init(8); acb_modular_theta_jet(t, t + 2, t + 4, t + 6, z, tau, 2, prec); eta1(t + 2, t + 3, tau, prec); acb_mul(t + 4, z, z, prec); acb_mul(t + 2, t + 2, t + 4, prec); acb_exp(t + 2, t + 2, prec); acb_div(t, t, t + 3, prec); acb_mul(res, t, t + 2, prec); if (real) arb_zero(acb_imagref(res)); _acb_vec_clear(t, 8); } arb-2.22.1/acb_hypgeom.h000066400000000000000000000402371417376376500150210ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_HYPGEOM_H #define ACB_HYPGEOM_H #include "acb.h" #include "acb_poly.h" #ifdef __cplusplus extern "C" { #endif void acb_hypgeom_rising_ui_forward(acb_t res, const acb_t x, ulong n, slong prec); void acb_hypgeom_rising_ui_rs(acb_t res, const acb_t x, ulong n, ulong m, slong prec); void acb_hypgeom_rising_ui_bs(acb_t res, const acb_t x, ulong n, slong prec); void acb_hypgeom_rising_ui_rec(acb_t res, const acb_t x, ulong n, slong prec); void acb_hypgeom_rising_ui(acb_t y, const acb_t x, ulong n, slong prec); void acb_hypgeom_rising(acb_t y, const acb_t x, const acb_t n, slong prec); void acb_hypgeom_rising_ui_jet_powsum(acb_ptr res, const acb_t x, ulong n, slong len, slong prec); void acb_hypgeom_rising_ui_jet_rs(acb_ptr res, const acb_t x, ulong n, ulong m, slong len, slong prec); void acb_hypgeom_rising_ui_jet_bs(acb_ptr res, const acb_t x, ulong n, slong len, slong prec); void acb_hypgeom_rising_ui_jet(acb_ptr res, const acb_t x, ulong n, slong len, slong prec); void acb_hypgeom_log_rising_ui_jet(acb_ptr res, const acb_t z, ulong r, slong len, slong prec); void acb_hypgeom_log_rising_ui(acb_ptr res, const acb_t z, ulong r, slong prec); void acb_hypgeom_gamma_stirling_sum_horner(acb_t s, const acb_t z, slong N, slong prec); void acb_hypgeom_gamma_stirling_sum_improved(acb_t s, const acb_t z, slong N, slong K, slong prec); void acb_hypgeom_gamma_stirling(acb_t res, const acb_t x, int reciprocal, slong prec); int acb_hypgeom_gamma_taylor(acb_t res, const acb_t x, int reciprocal, slong prec); void acb_hypgeom_gamma(acb_t y, const acb_t x, slong prec); void acb_hypgeom_rgamma(acb_t y, const acb_t x, slong prec); void acb_hypgeom_lgamma(acb_t y, const acb_t x, slong prec); void acb_hypgeom_pfq_bound_factor(mag_t C, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, ulong n); slong acb_hypgeom_pfq_choose_n(acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong prec); void acb_hypgeom_pfq_sum_forward(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec); void acb_hypgeom_pfq_sum_rs(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec); void acb_hypgeom_pfq_sum_bs(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec); void acb_hypgeom_pfq_sum_fme(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec); void acb_hypgeom_pfq_sum(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec); void acb_hypgeom_pfq_sum_bs_invz(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec); void acb_hypgeom_pfq_sum_invz(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, const acb_t zinv, slong n, slong prec); void acb_hypgeom_pfq_direct(acb_t res, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec); slong acb_hypgeom_pfq_series_choose_n(const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, slong len, slong prec); void acb_hypgeom_pfq_series_sum_forward(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec); void acb_hypgeom_pfq_series_sum_bs(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec); void acb_hypgeom_pfq_series_sum_rs(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec); void acb_hypgeom_pfq_series_sum(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec); void acb_hypgeom_pfq_series_direct(acb_poly_t res, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec); void acb_hypgeom_pfq(acb_t res, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, int regularized, slong prec); void acb_hypgeom_u_asymp(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong n, slong prec); void acb_hypgeom_u_1f1_series(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t z, slong len, slong prec); void acb_hypgeom_u_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec); void acb_hypgeom_u(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec); int acb_hypgeom_u_use_asymp(const acb_t z, slong prec); void acb_hypgeom_m_asymp(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec); void acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec); void acb_hypgeom_m(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec); void acb_hypgeom_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec); void acb_hypgeom_bessel_j_0f1(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_j_asymp(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_j(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_i_0f1(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec); void acb_hypgeom_bessel_i_asymp(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec); void acb_hypgeom_bessel_i(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_i_scaled(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_k_0f1(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec); void acb_hypgeom_bessel_k_0f1_series(acb_poly_t res, const acb_poly_t n, const acb_poly_t z, int scaled, slong len, slong prec); void acb_hypgeom_bessel_k_asymp(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec); void acb_hypgeom_bessel_k(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_k_scaled(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_y(acb_t res, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_bessel_jy(acb_t res1, acb_t res2, const acb_t nu, const acb_t z, slong prec); void acb_hypgeom_0f1_asymp(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec); void acb_hypgeom_0f1_direct(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec); void acb_hypgeom_0f1(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec); void acb_hypgeom_airy_bound(mag_t ai, mag_t aip, mag_t bi, mag_t bip, const acb_t z); void acb_hypgeom_airy_asymp(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong n, slong prec); void acb_hypgeom_airy_direct(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong n, slong prec); void acb_hypgeom_airy(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong prec); void acb_hypgeom_airy_jet(acb_ptr ai, acb_ptr bi, const acb_t z, slong len, slong prec); void _acb_hypgeom_airy_series(acb_ptr ai, acb_ptr ai_prime, acb_ptr bi, acb_ptr bi_prime, acb_srcptr z, slong zlen, slong len, slong prec); void acb_hypgeom_airy_series(acb_poly_t ai, acb_poly_t ai_prime, acb_poly_t bi, acb_poly_t bi_prime, const acb_poly_t z, slong len, slong prec); void acb_hypgeom_coulomb(acb_t F, acb_t G, acb_t Hpos, acb_t Hneg, const acb_t l, const acb_t eta, const acb_t z, slong prec); void acb_hypgeom_coulomb_jet(acb_ptr F, acb_ptr G, acb_ptr Hpos, acb_ptr Hneg, const acb_t l, const acb_t eta, const acb_t z, slong len, slong prec); void _acb_hypgeom_coulomb_series(acb_ptr F, acb_ptr G, acb_ptr Hpos, acb_ptr Hneg, const acb_t l, const acb_t eta, acb_srcptr z, slong zlen, slong len, slong prec); void acb_hypgeom_coulomb_series(acb_poly_t F, acb_poly_t G, acb_poly_t Hpos, acb_poly_t Hneg, const acb_t l, const acb_t eta, const acb_poly_t z, slong len, slong prec); void acb_hypgeom_gamma_upper_asymp(acb_t res, const acb_t s, const acb_t z, int modified, slong prec); void acb_hypgeom_gamma_upper_1f1a(acb_t res, const acb_t s, const acb_t z, int modified, slong prec); void acb_hypgeom_gamma_upper_1f1b(acb_t res, const acb_t s, const acb_t z, int modified, slong prec); void acb_hypgeom_gamma_upper_singular(acb_t res, slong s, const acb_t z, int modified, slong prec); void acb_hypgeom_gamma_upper(acb_t res, const acb_t s, const acb_t z, int modified, slong prec); void _acb_hypgeom_gamma_upper_series(acb_ptr g, const acb_t s, acb_srcptr h, slong hlen, int regularized, slong n, slong prec); void acb_hypgeom_gamma_upper_series(acb_poly_t g, const acb_t s, const acb_poly_t h, int regularized, slong n, slong prec); void acb_hypgeom_gamma_lower(acb_t res, const acb_t s, const acb_t z, int modified, slong prec); void _acb_hypgeom_gamma_lower_series(acb_ptr g, const acb_t s, acb_srcptr h, slong hlen, int regularized, slong n, slong prec); void acb_hypgeom_gamma_lower_series(acb_poly_t g, const acb_t s, const acb_poly_t h, int regularized, slong n, slong prec); void acb_hypgeom_beta_lower(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec); void _acb_hypgeom_beta_lower_series(acb_ptr res, const acb_t a, const acb_t b, acb_srcptr z, slong zlen, int regularized, slong len, slong prec); void acb_hypgeom_beta_lower_series(acb_poly_t res, const acb_t a, const acb_t b, const acb_poly_t z, int regularized, slong len, slong prec); void acb_hypgeom_expint(acb_t res, const acb_t s, const acb_t z, slong prec); void acb_hypgeom_erf_propagated_error(mag_t re, mag_t im, const acb_t z); void acb_hypgeom_erf_1f1a(acb_t res, const acb_t z, slong prec); void acb_hypgeom_erf_1f1b(acb_t res, const acb_t z, slong prec); void acb_hypgeom_erf_asymp(acb_t res, const acb_t z, int complementary, slong prec, slong prec2); void acb_hypgeom_erf(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_erf_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_erf_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_erfc(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_erfc_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_erfc_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_erfi(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_erfi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_erfi_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_fresnel(acb_t res1, acb_t res2, const acb_t z, int normalized, slong prec); void _acb_hypgeom_fresnel_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, int normalized, slong len, slong prec); void acb_hypgeom_fresnel_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, int normalized, slong len, slong prec); void acb_hypgeom_ei_asymp(acb_t res, const acb_t z, slong prec); void acb_hypgeom_ei_2f2(acb_t res, const acb_t z, slong prec); void acb_hypgeom_ei(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_ei_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_ei_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_si_asymp(acb_t res, const acb_t z, slong prec); void acb_hypgeom_si_1f2(acb_t res, const acb_t z, slong prec); void acb_hypgeom_si(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_si_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_si_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_ci_asymp(acb_t res, const acb_t z, slong prec); void acb_hypgeom_ci_2f3(acb_t res, const acb_t z, slong prec); void acb_hypgeom_ci(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_ci_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_ci_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_shi(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_shi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_shi_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_chi_asymp(acb_t res, const acb_t z, slong prec); void acb_hypgeom_chi_2f3(acb_t res, const acb_t z, slong prec); void acb_hypgeom_chi(acb_t res, const acb_t z, slong prec); void _acb_hypgeom_chi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_hypgeom_chi_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec); void acb_hypgeom_li(acb_t res, const acb_t z, int offset, slong prec); void _acb_hypgeom_li_series(acb_ptr g, acb_srcptr h, slong hlen, int offset, slong len, slong prec); void acb_hypgeom_li_series(acb_poly_t g, const acb_poly_t h, int offset, slong len, slong prec); void acb_hypgeom_2f1_continuation(acb_t res0, acb_t res1, const acb_t a, const acb_t b, const acb_t c, const acb_t z0, const acb_t z1, const acb_t f0, const acb_t f1, slong prec); void acb_hypgeom_2f1_series_direct(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t c, const acb_poly_t z, int regularized, slong len, slong prec); void acb_hypgeom_2f1_direct(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, slong prec); void acb_hypgeom_2f1_transform(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec); void acb_hypgeom_2f1_transform_limit(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec); void acb_hypgeom_2f1_corner(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, slong prec); int acb_hypgeom_2f1_choose(const acb_t z); void acb_hypgeom_2f1(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, slong prec); #define ACB_HYPGEOM_2F1_REGULARIZED 1 #define ACB_HYPGEOM_2F1_AB 2 /* a-b integer */ #define ACB_HYPGEOM_2F1_AC 4 /* a-c integer */ #define ACB_HYPGEOM_2F1_BC 8 /* b-c integer */ #define ACB_HYPGEOM_2F1_ABC 16 /* a+b-c integer */ void acb_hypgeom_legendre_p_uiui_rec(acb_t res, ulong n, ulong m, const acb_t z, slong prec); void acb_hypgeom_legendre_p(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec); void acb_hypgeom_legendre_q(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec); void acb_hypgeom_jacobi_p(acb_t res, const acb_t n, const acb_t a, const acb_t b, const acb_t z, slong prec); void acb_hypgeom_gegenbauer_c(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec); void acb_hypgeom_laguerre_l(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec); void acb_hypgeom_hermite_h(acb_t res, const acb_t n, const acb_t z, slong prec); void acb_hypgeom_chebyshev_t(acb_t res, const acb_t n, const acb_t z, slong prec); void acb_hypgeom_chebyshev_u(acb_t res, const acb_t n, const acb_t z, slong prec); void acb_hypgeom_spherical_y(acb_t res, slong n, slong m, const acb_t theta, const acb_t phi, slong prec); void acb_hypgeom_dilog_bernoulli(acb_t res, const acb_t z, slong prec); void acb_hypgeom_dilog_continuation(acb_t res, const acb_t a, const acb_t z, slong prec); void acb_hypgeom_dilog_bitburst(acb_t res, acb_t z0, const acb_t z, slong prec); void acb_hypgeom_dilog_transform(acb_t res, const acb_t z, int algorithm, slong prec); void acb_hypgeom_dilog_zero_taylor(acb_t res, const acb_t z, slong prec); void acb_hypgeom_dilog_zero(acb_t res, const acb_t z, slong prec); void acb_hypgeom_dilog(acb_t res, const acb_t z, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_hypgeom/000077500000000000000000000000001417376376500146425ustar00rootroot00000000000000arb-2.22.1/acb_hypgeom/0f1.c000066400000000000000000000065461417376376500154070ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_0f1_asymp(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec) { acb_t t, u, v; int neg; acb_init(t); acb_init(u); acb_init(v); /* both expansions are correct, but we want the one that works better on the real line */ neg = arf_sgn(arb_midref(acb_realref(z))) < 0; if (neg) acb_neg(t, z); else acb_set(t, z); acb_sqrt(t, t, prec); acb_mul_2exp_si(v, t, 1); acb_sub_ui(u, a, 1, prec); if (neg) acb_hypgeom_bessel_j_asymp(v, u, v, prec); else acb_hypgeom_bessel_i_asymp(v, u, v, 0, prec); acb_neg(u, u); acb_pow(t, t, u, prec); acb_mul(v, v, t, prec); if (!regularized) { acb_gamma(t, a, prec); acb_mul(v, v, t, prec); } acb_set(res, v); acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_0f1_direct(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec) { if (regularized) { if (acb_is_int(a) && arf_sgn(arb_midref(acb_realref(a))) <= 0) { acb_t t, u; acb_init(t); acb_init(u); acb_sub_ui(t, a, 2, prec); acb_neg(t, t); acb_sub_ui(u, a, 1, prec); acb_neg(u, u); acb_pow(u, z, u, prec); /* this cannot recurse infinitely, because t will either be an exact positive integer, or inexact */ acb_hypgeom_0f1_direct(res, t, z, regularized, prec); acb_mul(res, res, u, prec); acb_clear(t); acb_clear(u); } else /* todo: could skip when a=1 or a=2 */ { acb_t t; acb_init(t); acb_rgamma(t, a, prec); acb_hypgeom_0f1_direct(res, a, z, 0, prec); acb_mul(res, res, t, prec); acb_clear(t); } } else { acb_struct bb[2]; bb[0] = *a; acb_init(bb + 1); acb_one(bb + 1); acb_hypgeom_pfq_direct(res, NULL, 0, bb, 2, z, -1, prec); acb_clear(bb + 1); } } int acb_hypgeom_0f1_use_asymp(const acb_t z, slong prec) { double x, y, c; if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 0) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0)) { return 0; } if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 0) > 128 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) > 128)) { return 1; } x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); c = prec * 0.69314718055994530942; c = c * c; c = c * c; return x * x + y * y > c; } void acb_hypgeom_0f1(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec) { if (acb_hypgeom_0f1_use_asymp(z, prec)) acb_hypgeom_0f1_asymp(res, a, z, regularized, prec); else acb_hypgeom_0f1_direct(res, a, z, regularized, prec); } arb-2.22.1/acb_hypgeom/2f1.c000066400000000000000000000144301417376376500154000ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #include "arb_hypgeom.h" static void _acb_hypgeom_2f1r_reduced(acb_t res, const acb_t b, const acb_t c, const acb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_neg(u, b); acb_pow(t, t, u, prec); acb_rgamma(u, c, prec); acb_mul(t, t, u, prec); acb_set(res, t); acb_clear(t); acb_clear(u); return; } void acb_hypgeom_2f1_nointegration(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int flags, slong prec) { int algorithm, regularized; regularized = flags & ACB_HYPGEOM_2F1_REGULARIZED; if (!acb_is_finite(a) || !acb_is_finite(b) || !acb_is_finite(c) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (acb_is_zero(z)) { if (regularized) acb_rgamma(res, c, prec); else acb_one(res); return; } if (regularized && acb_is_int(c) && arb_is_nonpositive(acb_realref(c))) { if ((acb_is_int(a) && arb_is_nonpositive(acb_realref(a)) && arf_cmp(arb_midref(acb_realref(a)), arb_midref(acb_realref(c))) >= 0) || (acb_is_int(b) && arb_is_nonpositive(acb_realref(b)) && arf_cmp(arb_midref(acb_realref(b)), arb_midref(acb_realref(c))) >= 0)) { acb_zero(res); return; } } if (regularized && acb_eq(a, c)) { _acb_hypgeom_2f1r_reduced(res, b, c, z, prec); return; } if (regularized && acb_eq(b, c)) { _acb_hypgeom_2f1r_reduced(res, a, c, z, prec); return; } /* polynomial */ if (acb_is_int(a) && arf_sgn(arb_midref(acb_realref(a))) <= 0 && arf_cmpabs_ui(arb_midref(acb_realref(a)), prec) < 0) { acb_hypgeom_2f1_direct(res, a, b, c, z, regularized, prec); return; } /* polynomial */ if (acb_is_int(b) && arf_sgn(arb_midref(acb_realref(b))) <= 0 && arf_cmpabs_ui(arb_midref(acb_realref(b)), prec) < 0) { acb_hypgeom_2f1_direct(res, a, b, c, z, regularized, prec); return; } /* Try to reduce to a polynomial case using the Pfaff transformation */ /* TODO: look at flags for integer c-b, c-a here, even when c is nonexact */ if (acb_is_exact(c)) { acb_t t; acb_init(t); acb_sub(t, c, b, prec); if (acb_is_int(t) && arb_is_nonpositive(acb_realref(t))) { acb_hypgeom_2f1_transform(res, a, b, c, z, flags, 1, prec); acb_clear(t); return; } acb_sub(t, c, a, prec); if (acb_is_int(t) && arb_is_nonpositive(acb_realref(t))) { int f1, f2; /* When swapping a, b, also swap the flags. */ f1 = flags & ACB_HYPGEOM_2F1_AC; f2 = flags & ACB_HYPGEOM_2F1_BC; flags &= ~ACB_HYPGEOM_2F1_AC; flags &= ~ACB_HYPGEOM_2F1_BC; if (f1) flags |= ACB_HYPGEOM_2F1_BC; if (f2) flags |= ACB_HYPGEOM_2F1_AC; acb_hypgeom_2f1_transform(res, b, a, c, z, flags, 1, prec); acb_clear(t); return; } acb_clear(t); } /* special value at z = 1 */ if (acb_is_one(z)) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); acb_sub(t, c, a, prec); acb_sub(u, c, b, prec); acb_sub(v, t, b, prec); if (arb_is_positive(acb_realref(v))) { acb_rgamma(t, t, prec); acb_rgamma(u, u, prec); acb_mul(t, t, u, prec); acb_gamma(v, v, prec); acb_mul(t, t, v, prec); if (!regularized) { acb_gamma(v, c, prec); acb_mul(t, t, v, prec); } acb_set(res, t); } else { acb_indeterminate(res); } acb_clear(t); acb_clear(u); acb_clear(v); return; } algorithm = acb_hypgeom_2f1_choose(z); if (algorithm == 0) { acb_hypgeom_2f1_direct(res, a, b, c, z, regularized, prec); } else if (algorithm >= 1 && algorithm <= 5) { acb_hypgeom_2f1_transform(res, a, b, c, z, flags, algorithm, prec); } else { acb_hypgeom_2f1_corner(res, a, b, c, z, regularized, prec); } } void acb_hypgeom_2f1(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int flags, slong prec) { acb_t res2; slong acc, max, t; acb_init(res2); acb_hypgeom_2f1_nointegration(res2, a, b, c, z, flags, prec); acc = acb_rel_accuracy_bits(res2); if (acc < 0.5 * prec) { max = prec; t = acb_rel_accuracy_bits(z); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(a); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(b); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(c); max = FLINT_MIN(max, t); if (max > 2 && acc < 0.5 * max) { if (acb_is_real(a) && acb_is_real(b) && acb_is_real(c) && acb_is_real(z) && arf_cmpabs_2exp_si(arb_midref(acb_realref(a)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(c)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 60) < 0) { arb_hypgeom_2f1_integration(acb_realref(res), acb_realref(a), acb_realref(b), acb_realref(c), acb_realref(z), flags, prec); arb_zero(acb_imagref(res)); if (acb_rel_accuracy_bits(res) > acb_rel_accuracy_bits(res2) || (acb_is_finite(res) && !acb_is_finite(res2))) { acb_swap(res, res2); } } } } acb_swap(res, res2); acb_clear(res2); } arb-2.22.1/acb_hypgeom/2f1_choose.c000066400000000000000000000027631417376376500167460ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #define ALWAYS1 (0.25 * 0.25) #define ALWAYS2 (0.75 * 0.75) #define LIMIT (0.75 * 0.75) int acb_hypgeom_2f1_choose(const acb_t z) { double x, y; double mag[7]; int i, pick; x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); x = FLINT_MAX(FLINT_MIN(x, 1e10), -1e10); y = FLINT_MAX(FLINT_MIN(y, 1e10), -1e10); mag[0] = x*x + y*y; /* |z|^2 */ mag[4] = (1.0-x)*(1.0-x) + y*y; /* |1-z|^2 */ if (mag[0] <= ALWAYS1) return 0; mag[1] = mag[0] / FLINT_MAX(mag[4], 1e-10); /* |z/(z-1)|^2 */ if (mag[1] <= ALWAYS1) return 1; if (mag[0] <= ALWAYS2 || mag[1] <= ALWAYS2) return mag[0] <= mag[1] ? 0 : 1; mag[2] = 1.0 / mag[0]; /* |1/z|^2 */ mag[3] = 1.0 / FLINT_MAX(mag[4], 1e-10); /* 1/|1-z|^2 */ mag[5] = mag[4] / mag[0]; /* |1-1/z|^2 = |(1-z)/z|^2 */ pick = 0; for (i = 1; i < 6; i++) { if (mag[i] < mag[pick]) pick = i; } if (mag[pick] <= LIMIT) return pick; return 6; } arb-2.22.1/acb_hypgeom/2f1_continuation.c000066400000000000000000000134511417376376500201740ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* Differential equation for F(a,b,c,y+z): (y+z)(y-1+z) F''(z) + ((y+z)(a+b+1) - c) F'(z) + a b F(z) = 0 Coefficients in the Taylor series are bounded by A * binomial(N+k, k) * nu^k using the Cauchy-Kovalevskaya majorant method. See J. van der Hoeven, "Fast evaluation of holonomic functions near and in regular singularities" */ static void bound(mag_t A, mag_t nu, mag_t N, const acb_t a, const acb_t b, const acb_t c, const acb_t y, const acb_t f0, const acb_t f1) { mag_t M0, M1, t, u; acb_t d; acb_init(d); mag_init(M0); mag_init(M1); mag_init(t); mag_init(u); /* nu = max(1/|y-1|, 1/|y|) = 1/min(|y-1|, |y|) */ acb_get_mag_lower(t, y); acb_sub_ui(d, y, 1, MAG_BITS); acb_get_mag_lower(u, d); mag_min(t, t, u); mag_one(u); mag_div(nu, u, t); /* M0 = 2 nu |ab| */ acb_get_mag(t, a); acb_get_mag(u, b); mag_mul(M0, t, u); mag_mul(M0, M0, nu); mag_mul_2exp_si(M0, M0, 1); /* M1 = nu |a+b+1| + 2|c| */ acb_add(d, a, b, MAG_BITS); acb_add_ui(d, d, 1, MAG_BITS); acb_get_mag(t, d); mag_mul(t, t, nu); acb_get_mag(u, c); mag_mul_2exp_si(u, u, 1); mag_add(M1, t, u); /* N = max(sqrt(2 M0), 2 M1) / nu */ mag_mul_2exp_si(M0, M0, 1); mag_sqrt(M0, M0); mag_mul_2exp_si(M1, M1, 1); mag_max(N, M0, M1); mag_div(N, N, nu); /* A = max(|f0|, |f1| / (nu (N+1)) */ acb_get_mag(t, f0); acb_get_mag(u, f1); mag_div(u, u, nu); mag_div(u, u, N); /* upper bound for dividing by N+1 */ mag_max(A, t, u); acb_clear(d); mag_clear(M0); mag_clear(M1); mag_clear(t); mag_clear(u); } /* F(x) = c0 + c1 x + c2 x^2 + c3 x^3 + [...] F'(x) = c1 + 2 c2 x + 3 c3 x^2 + 4 c4 x^3 + [...] */ static void evaluate_sum(acb_t res, acb_t res1, const acb_t a, const acb_t b, const acb_t c, const acb_t y, const acb_t x, const acb_t f0, const acb_t f1, slong num, slong prec) { acb_t s, s2, w, d, e, xpow, ck, cknext; slong k; acb_init(s); acb_init(s2); acb_init(w); acb_init(d); acb_init(e); acb_init(xpow); acb_init(ck); acb_init(cknext); /* d = (y-1)*y */ acb_sub_ui(d, y, 1, prec); acb_mul(d, d, y, prec); acb_one(xpow); for (k = 0; k < num; k++) { if (k == 0) { acb_set(ck, f0); acb_set(cknext, f1); } else { acb_add_ui(w, b, k-1, prec); acb_mul(w, w, ck, prec); acb_add_ui(e, a, k-1, prec); acb_mul(w, w, e, prec); acb_add(e, a, b, prec); acb_add_ui(e, e, 2*(k+1)-3, prec); acb_mul(e, e, y, prec); acb_sub(e, e, c, prec); acb_sub_ui(e, e, k-1, prec); acb_mul_ui(e, e, k, prec); acb_addmul(w, e, cknext, prec); acb_mul_ui(e, d, k+1, prec); acb_mul_ui(e, e, k, prec); acb_div(w, w, e, prec); acb_neg(w, w); acb_set(ck, cknext); acb_set(cknext, w); } acb_addmul(s, ck, xpow, prec); acb_mul_ui(w, cknext, k+1, prec); acb_addmul(s2, w, xpow, prec); acb_mul(xpow, xpow, x, prec); } acb_set(res, s); acb_set(res1, s2); acb_clear(s); acb_clear(s2); acb_clear(w); acb_clear(d); acb_clear(e); acb_clear(xpow); acb_clear(ck); acb_clear(cknext); } void acb_hypgeom_2f1_continuation(acb_t res, acb_t res1, const acb_t a, const acb_t b, const acb_t c, const acb_t y, const acb_t z, const acb_t f0, const acb_t f1, slong prec) { mag_t A, nu, N, w, err, err1, R, T, goal; acb_t x; slong j, k; mag_init(A); mag_init(nu); mag_init(N); mag_init(err); mag_init(err1); mag_init(w); mag_init(R); mag_init(T); mag_init(goal); acb_init(x); bound(A, nu, N, a, b, c, y, f0, f1); acb_sub(x, z, y, prec); /* |T(k)| <= A * binomial(N+k, k) * nu^k * |x|^k */ acb_get_mag(w, x); mag_mul(w, w, nu); /* w = nu |x| */ mag_mul_2exp_si(goal, A, -prec-2); /* bound for T(0) */ mag_set(T, A); mag_inf(R); for (k = 1; k < 100 * prec; k++) { /* T(k) = T(k) * R(k), R(k) = (N+k)/k * w = (1 + N/k) w */ mag_div_ui(R, N, k); mag_add_ui(R, R, 1); mag_mul(R, R, w); /* T(k) */ mag_mul(T, T, R); if (mag_cmp(T, goal) <= 0 && mag_cmp_2exp_si(R, 0) < 0) break; } /* T(k) [1 + R + R^2 + R^3 + ...] */ mag_geom_series(err, R, 0); mag_mul(err, T, err); /* Now compute T, R for the derivative */ /* Coefficients are A * (k+1) * binomial(N+k+1, k+1) */ mag_add_ui(T, N, 1); mag_mul(T, T, A); mag_inf(R); for (j = 1; j <= k; j++) { mag_add_ui(R, N, k + 1); mag_div_ui(R, R, k); mag_mul(R, R, w); mag_mul(T, T, R); } mag_geom_series(err1, R, 0); mag_mul(err1, T, err1); if (mag_is_inf(err)) { acb_indeterminate(res); acb_indeterminate(res1); } else { evaluate_sum(res, res1, a, b, c, y, x, f0, f1, k, prec); acb_add_error_mag(res, err); acb_add_error_mag(res1, err1); } mag_clear(A); mag_clear(nu); mag_clear(N); mag_clear(err); mag_clear(err1); mag_clear(w); mag_clear(R); mag_clear(T); mag_clear(goal); acb_clear(x); } arb-2.22.1/acb_hypgeom/2f1_corner.c000066400000000000000000000032321417376376500167460ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_2f1_corner(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, slong prec) { acb_t aa, bb, cc, z1, z2, f1, f2; int upper; acb_init(aa); acb_init(bb); acb_init(cc); acb_init(z1); acb_init(z2); acb_init(f1); acb_init(f2); acb_add_ui(aa, a, 1, prec); acb_add_ui(bb, b, 1, prec); acb_add_ui(cc, c, 1, prec); upper = arb_is_positive(acb_imagref(z)); /* 0 -> 0.5 +/- 0.5i -> 0.5 +/- 0.75i -> z */ #if 0 acb_set_d_d(z1, 0.5, upper ? 0.5 : -0.5); acb_set_d_d(z2, 0.5, upper ? 0.75 : -0.75); #else acb_set_d_d(z1, 0.375, upper ? 0.625 : -0.625); acb_set_d_d(z2, 0.5, upper ? 0.8125 : -0.8125); #endif acb_hypgeom_2f1_direct(f1, a, b, c, z1, regularized, prec); acb_hypgeom_2f1_direct(f2, aa, bb, cc, z1, regularized, prec); acb_mul(f2, f2, a, prec); acb_mul(f2, f2, b, prec); if (!regularized) acb_div(f2, f2, c, prec); acb_hypgeom_2f1_continuation(f1, f2, a, b, c, z1, z2, f1, f2, prec); acb_set(z1, z2); acb_set(z2, z); acb_hypgeom_2f1_continuation(f1, f2, a, b, c, z1, z2, f1, f2, prec); acb_set(res, f1); acb_clear(aa); acb_clear(bb); acb_clear(cc); acb_clear(z1); acb_clear(z2); acb_clear(f1); acb_clear(f2); } arb-2.22.1/acb_hypgeom/2f1_direct.c000066400000000000000000000063611417376376500167360ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_2f1_direct(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, slong prec) { /* 2F1R(a,b,-n,z) = (a)_(n+1) * (b)_(n+1) * z^(n+1) / (n+1)! * 2F1(a+n+1, b+n+1, n+2, z) */ if (regularized && acb_is_int(c) && arf_sgn(arb_midref(acb_realref(c))) <= 0) { if ((acb_is_int(a) && arb_is_nonpositive(acb_realref(a)) && arf_cmp(arb_midref(acb_realref(a)), arb_midref(acb_realref(c))) >= 0) || (acb_is_int(b) && arb_is_nonpositive(acb_realref(b)) && arf_cmp(arb_midref(acb_realref(b)), arb_midref(acb_realref(c))) >= 0)) { acb_zero(res); } else { acb_t n, n1, t, u, v; acb_ptr aa; int p, q; acb_init(n); acb_init(n1); acb_init(t); acb_init(u); acb_init(v); aa = _acb_vec_init(4); acb_neg(n, c); acb_add_ui(n1, n, 1, prec); acb_add(aa, a, n1, prec); acb_add(aa + 1, b, n1, prec); acb_add_ui(aa + 2, n1, 1, prec); if (acb_is_one(aa)) { p = q = 1; acb_swap(aa, aa + 1); } else if (acb_is_one(aa + 1)) { p = q = 1; } else { p = q = 2; acb_one(aa + 3); } acb_hypgeom_pfq_direct(t, aa, p, aa + 2, q, z, -1, prec); /* z^(n+1) */ acb_pow(u, z, n1, prec); acb_mul(t, t, u, prec); acb_rising(u, a, n1, prec); acb_mul(t, t, u, prec); acb_rising(u, b, n1, prec); acb_mul(t, t, u, prec); /* 1/(n+1)! */ acb_rgamma(u, aa + 2, prec); acb_mul(t, t, u, prec); acb_set(res, t); acb_clear(n); acb_clear(n1); acb_clear(t); acb_clear(u); acb_clear(v); _acb_vec_clear(aa, 4); } } else { acb_ptr aa; int p, q; aa = _acb_vec_init(4); acb_set(aa + 2, c); if (acb_is_one(a)) { p = q = 1; acb_set(aa, b); } else if (acb_is_one(b)) { p = q = 1; acb_set(aa, a); } else { p = q = 2; acb_set(aa, a); acb_set(aa + 1, b); acb_one(aa + 3); } acb_hypgeom_pfq_direct(res, aa, p, aa + 2, q, z, -1, prec); if (regularized) { acb_rgamma(aa + 2, aa + 2, prec); acb_mul(res, res, aa + 2, prec); } _acb_vec_clear(aa, 4); } if (!acb_is_finite(res)) acb_indeterminate(res); } arb-2.22.1/acb_hypgeom/2f1_series_direct.c000066400000000000000000000015161417376376500203050ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_2f1_series_direct(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t c, const acb_poly_t z, int regularized, slong len, slong prec) { acb_poly_struct aa[4]; aa[0] = *a; aa[1] = *b; aa[2] = *c; acb_poly_init(&aa[3]); acb_poly_one(&aa[3]); acb_hypgeom_pfq_series_direct(res, aa, 2, aa + 2, 2, z, regularized, -1, len, prec); acb_poly_clear(&aa[3]); } arb-2.22.1/acb_hypgeom/2f1_transform.c000066400000000000000000000315751417376376500175040ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* which == 0 -- z which == 1 -- z/(z-1) which == 2 -- 1/z which == 3 -- 1/(1-z) which == 4 -- 1-z which == 5 -- 1-1/z */ void _acb_hypgeom_2f1_transform_limit(acb_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t c, const acb_poly_t z, int which, slong prec) { acb_poly_t ba, ca, cb, cab, ac1, bc1, ab1, ba1, w, t, u, v, s; acb_t tt; acb_poly_init(ba); acb_poly_init(ca); acb_poly_init(cb); acb_poly_init(cab); acb_poly_init(ac1); acb_poly_init(bc1); acb_poly_init(ab1); acb_poly_init(ba1); acb_poly_init(w); acb_poly_init(t); acb_poly_init(u); acb_poly_init(v); acb_poly_init(s); acb_init(tt); acb_poly_add_si(s, z, -1, prec); /* s = 1 - z */ acb_poly_neg(s, s); acb_poly_sub(ba, b, a, prec); /* ba = b - a */ acb_poly_sub(ca, c, a, prec); /* ca = c - a */ acb_poly_sub(cb, c, b, prec); /* cb = c - b */ acb_poly_sub(cab, ca, b, prec); /* cab = c - a - b */ acb_poly_add_si(ac1, ca, -1, prec); acb_poly_neg(ac1, ac1); /* ac1 = a - c + 1 */ acb_poly_add_si(bc1, cb, -1, prec); acb_poly_neg(bc1, bc1); /* bc1 = b - c + 1 */ acb_poly_add_si(ab1, ba, -1, prec); acb_poly_neg(ab1, ab1); /* ab1 = a - b + 1 */ acb_poly_add_si(ba1, ba, 1, prec); /* ba1 = b - a + 1 */ /* t = left term, u = right term (DLMF 15.8.1 - 15.8.5) */ if (which == 2) { acb_poly_inv_series(w, z, 2, prec); /* w = 1/z */ acb_hypgeom_2f1_series_direct(t, a, ac1, ab1, w, 1, 2, prec); acb_hypgeom_2f1_series_direct(u, b, bc1, ba1, w, 1, 2, prec); } else if (which == 3) { acb_poly_inv_series(w, s, 2, prec); /* w = 1/(1-z) */ acb_hypgeom_2f1_series_direct(t, a, cb, ab1, w, 1, 2, prec); acb_hypgeom_2f1_series_direct(u, b, ca, ba1, w, 1, 2, prec); } else if (which == 4) { acb_poly_set(w, s); /* w = 1-z */ acb_poly_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_series_direct(t, a, b, v, w, 1, 2, prec); acb_poly_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_hypgeom_2f1_series_direct(u, ca, cb, v, w, 1, 2, prec); } else if (which == 5) { acb_poly_inv_series(w, z, 2, prec); /* w = 1-1/z */ acb_poly_neg(w, w); acb_poly_add_si(w, w, 1, prec); acb_poly_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_series_direct(t, a, ac1, v, w, 1, 2, prec); acb_poly_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_poly_add_si(u, a, -1, prec); /* u = 1-a */ acb_poly_neg(u, u); acb_hypgeom_2f1_series_direct(u, ca, u, v, w, 1, 2, prec); } else { flint_printf("invalid transformation!\n"); flint_abort(); } /* gamma factors */ acb_poly_rgamma_series(v, a, 2, prec); acb_poly_mullow(u, u, v, 2, prec); acb_poly_rgamma_series(v, ca, 2, prec); acb_poly_mullow(t, t, v, 2, prec); acb_poly_rgamma_series(v, b, 2, prec); if (which == 2 || which == 3) acb_poly_mullow(t, t, v, 2, prec); else acb_poly_mullow(u, u, v, 2, prec); acb_poly_rgamma_series(v, cb, 2, prec); if (which == 2 || which == 3) acb_poly_mullow(u, u, v, 2, prec); else acb_poly_mullow(t, t, v, 2, prec); if (which == 2 || which == 3) { if (which == 2) acb_poly_neg(s, z); /* -z, otherwise 1-z since before */ acb_poly_neg(v, a); acb_poly_pow_series(v, s, v, 2, prec); acb_poly_mullow(t, t, v, 2, prec); acb_poly_neg(v, b); acb_poly_pow_series(v, s, v, 2, prec); acb_poly_mullow(u, u, v, 2, prec); } else { acb_poly_pow_series(v, s, cab, 2, prec); acb_poly_mullow(u, u, v, 2, prec); if (which == 5) { acb_poly_neg(v, a); acb_poly_pow_series(v, z, v, 2, prec); acb_poly_mullow(t, t, v, 2, prec); acb_poly_neg(v, ca); acb_poly_pow_series(v, z, v, 2, prec); acb_poly_mullow(u, u, v, 2, prec); } } acb_poly_sub(t, t, u, prec); if (which == 2 || which == 3) acb_poly_sin_pi_series(v, ba, 2, prec); else acb_poly_sin_pi_series(v, cab, 2, prec); acb_poly_get_coeff_acb(tt, t, 1); acb_poly_get_coeff_acb(res, v, 1); acb_div(res, tt, res, prec); acb_const_pi(tt, prec); acb_mul(res, res, tt, prec); acb_poly_clear(ba); acb_poly_clear(ca); acb_poly_clear(cb); acb_poly_clear(cab); acb_poly_clear(ac1); acb_poly_clear(bc1); acb_poly_clear(ab1); acb_poly_clear(ba1); acb_poly_clear(w); acb_poly_clear(t); acb_poly_clear(u); acb_poly_clear(v); acb_poly_clear(s); acb_clear(tt); } void acb_hypgeom_2f1_transform_limit(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec) { acb_poly_t aa, bb, cc, zz; acb_t t; if (acb_contains_zero(z) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (arb_contains_si(acb_realref(z), 1) && arb_contains_zero(acb_imagref(z))) { acb_indeterminate(res); return; } if (!regularized) { acb_init(t); acb_gamma(t, c, prec); acb_hypgeom_2f1_transform_limit(res, a, b, c, z, 1, which, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } acb_poly_init(aa); acb_poly_init(bb); acb_poly_init(cc); acb_poly_init(zz); acb_init(t); acb_poly_set_acb(aa, a); acb_poly_set_acb(bb, b); acb_poly_set_acb(cc, c); acb_poly_set_acb(zz, z); if (which == 2 || which == 3) { acb_sub(t, b, a, prec); acb_poly_set_coeff_si(aa, 1, 1); /* prefer b-a nonnegative (either is correct) to avoid expensive operations in the hypergeometric series */ if (arb_is_nonnegative(acb_realref(t))) _acb_hypgeom_2f1_transform_limit(res, aa, bb, cc, zz, which, prec); else _acb_hypgeom_2f1_transform_limit(res, bb, aa, cc, zz, which, prec); } else { acb_poly_set_coeff_si(aa, 1, 1); _acb_hypgeom_2f1_transform_limit(res, aa, bb, cc, zz, which, prec); } acb_poly_clear(aa); acb_poly_clear(bb); acb_poly_clear(cc); acb_poly_clear(zz); acb_clear(t); } void acb_hypgeom_2f1_transform_nolimit(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec) { acb_t ba, ca, cb, cab, ac1, bc1, ab1, ba1, w, t, u, v, s; if (acb_contains_zero(z) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (arb_contains_si(acb_realref(z), 1) && arb_contains_zero(acb_imagref(z))) { acb_indeterminate(res); return; } if (!regularized) { acb_init(t); acb_gamma(t, c, prec); acb_hypgeom_2f1_transform_nolimit(res, a, b, c, z, 1, which, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } acb_init(ba); acb_init(ca); acb_init(cb); acb_init(cab); acb_init(ac1); acb_init(bc1); acb_init(ab1); acb_init(ba1); acb_init(w); acb_init(t); acb_init(u); acb_init(v); acb_init(s); acb_add_si(s, z, -1, prec); /* s = 1 - z */ acb_neg(s, s); acb_sub(ba, b, a, prec); /* ba = b - a */ acb_sub(ca, c, a, prec); /* ca = c - a */ acb_sub(cb, c, b, prec); /* cb = c - b */ acb_sub(cab, ca, b, prec); /* cab = c - a - b */ acb_add_si(ac1, ca, -1, prec); acb_neg(ac1, ac1); /* ac1 = a - c + 1 */ acb_add_si(bc1, cb, -1, prec); acb_neg(bc1, bc1); /* bc1 = b - c + 1 */ acb_add_si(ab1, ba, -1, prec); acb_neg(ab1, ab1); /* ab1 = a - b + 1 */ acb_add_si(ba1, ba, 1, prec); /* ba1 = b - a + 1 */ /* t = left term, u = right term (DLMF 15.8.1 - 15.8.5) */ if (which == 2) { acb_inv(w, z, prec); /* w = 1/z */ acb_hypgeom_2f1_direct(t, a, ac1, ab1, w, 1, prec); acb_hypgeom_2f1_direct(u, b, bc1, ba1, w, 1, prec); } else if (which == 3) { acb_inv(w, s, prec); /* w = 1/(1-z) */ acb_hypgeom_2f1_direct(t, a, cb, ab1, w, 1, prec); acb_hypgeom_2f1_direct(u, b, ca, ba1, w, 1, prec); } else if (which == 4) { acb_set(w, s); /* w = 1-z */ acb_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_direct(t, a, b, v, w, 1, prec); acb_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_hypgeom_2f1_direct(u, ca, cb, v, w, 1, prec); } else if (which == 5) { acb_inv(w, z, prec); /* w = 1-1/z */ acb_neg(w, w); acb_add_si(w, w, 1, prec); acb_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_direct(t, a, ac1, v, w, 1, prec); acb_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_add_si(u, a, -1, prec); /* u = 1-a */ acb_neg(u, u); acb_hypgeom_2f1_direct(u, ca, u, v, w, 1, prec); } else { flint_printf("invalid transformation!\n"); flint_abort(); } /* gamma factors */ acb_rgamma(v, a, prec); acb_mul(u, u, v, prec); acb_rgamma(v, ca, prec); acb_mul(t, t, v, prec); acb_rgamma(v, b, prec); if (which == 2 || which == 3) acb_mul(t, t, v, prec); else acb_mul(u, u, v, prec); acb_rgamma(v, cb, prec); if (which == 2 || which == 3) acb_mul(u, u, v, prec); else acb_mul(t, t, v, prec); if (which == 2 || which == 3) { if (which == 2) acb_neg(s, z); /* -z, otherwise 1-z since before */ acb_neg(v, a); acb_pow(v, s, v, prec); acb_mul(t, t, v, prec); acb_neg(v, b); acb_pow(v, s, v, prec); acb_mul(u, u, v, prec); } else { acb_pow(v, s, cab, prec); acb_mul(u, u, v, prec); if (which == 5) { acb_neg(v, a); acb_pow(v, z, v, prec); acb_mul(t, t, v, prec); acb_neg(v, ca); acb_pow(v, z, v, prec); acb_mul(u, u, v, prec); } } acb_sub(t, t, u, prec); if (which == 2 || which == 3) acb_sin_pi(v, ba, prec); else acb_sin_pi(v, cab, prec); acb_div(t, t, v, prec); acb_const_pi(v, prec); acb_mul(t, t, v, prec); acb_set(res, t); acb_clear(ba); acb_clear(ca); acb_clear(cb); acb_clear(cab); acb_clear(ac1); acb_clear(bc1); acb_clear(ab1); acb_clear(ba1); acb_clear(w); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(s); } void acb_hypgeom_2f1_transform(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int flags, int which, slong prec) { int regularized; regularized = flags & ACB_HYPGEOM_2F1_REGULARIZED; if (which == 1) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); acb_sub_ui(t, z, 1, prec); /* t = z-1 */ acb_div(u, z, t, prec); /* u = z/(z-1) */ acb_neg(t, t); acb_neg(v, a); acb_pow(t, t, v, prec); /* t = (1-z)^-a */ acb_sub(v, c, b, prec); /* v = c-b */ /* We cannot use regularized=1 directly, since if c is a nonnegative integer, the transformation formula reads (lhs) * 0 = (rhs) * 0. */ acb_hypgeom_2f1_direct(u, a, v, c, u, 1, prec); if (!regularized) { acb_gamma(v, c, prec); acb_mul(u, u, v, prec); } acb_mul(res, u, t, prec); acb_clear(t); acb_clear(u); acb_clear(v); } else { acb_t d; int limit; acb_init(d); if (which == 2 || which == 3) { if (flags & ACB_HYPGEOM_2F1_AB) { limit = 1; } else { acb_sub(d, b, a, prec); limit = acb_is_int(d); } } else { if (flags & ACB_HYPGEOM_2F1_ABC) { limit = 1; } else { acb_sub(d, c, a, prec); acb_sub(d, d, b, prec); limit = acb_is_int(d); } } if (limit) acb_hypgeom_2f1_transform_limit(res, a, b, c, z, regularized, which, prec); else acb_hypgeom_2f1_transform_nolimit(res, a, b, c, z, regularized, which, prec); acb_clear(d); } if (!acb_is_finite(res)) acb_indeterminate(res); } arb-2.22.1/acb_hypgeom/airy.c000066400000000000000000000220161417376376500157530ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "acb_hypgeom.h" #define LOG2 0.69314718055994530942 #define EXP1 2.7182818284590452354 static const double small_log_tab[] = { 0.0, 0.0, 0.693147180559945309, 1.09861228866810969, 1.38629436111989062, 1.60943791243410037, 1.791759469228055, 1.94591014905531331, 2.07944154167983593, 2.19722457733621938, 2.30258509299404568, 2.39789527279837054, 2.48490664978800031, 2.56494935746153674, 2.63905732961525861, 2.70805020110221007, 2.77258872223978124, 2.83321334405621608, 2.89037175789616469, 2.94443897916644046, 2.99573227355399099, 3.044522437723423, 3.09104245335831585, 3.13549421592914969, 3.17805383034794562, 3.21887582486820075, 3.25809653802148205, 3.29583686600432907, 3.33220451017520392, 3.36729582998647403, 3.40119738166215538, 3.43398720448514625, 3.46573590279972655, 3.49650756146648024, 3.52636052461616139, 3.55534806148941368, 3.58351893845611, 3.61091791264422444, 3.63758615972638577, 3.66356164612964643, 3.6888794541139363, 3.7135720667043078, 3.73766961828336831, 3.76120011569356242, 3.78418963391826116, 3.80666248977031976, 3.828641396489095, 3.85014760171005859, 3.87120101090789093, 3.89182029811062661, 3.91202300542814606, 3.93182563272432577, 3.95124371858142735, 3.97029191355212183, 3.98898404656427438, 4.00733318523247092, 4.02535169073514923, 4.04305126783455015, 4.06044301054641934, 4.07753744390571945, 4.09434456222210068, 4.11087386417331125, 4.12713438504509156, 4.14313472639153269, }; static slong asymp_pick_terms(double prec, double logz) { double logk, log2term, log2term_prev; slong k; log2term_prev = 0.0; for (k = 1; ; k++) { logk = k < 64 ? small_log_tab[k] : log(k); log2term = -1.3257480647361593990 - 0.72134752044448170368*logk + k * (-1.8577325401678072259 + 1.4426950408889634074*logk - 2.1640425613334451110*logz); if (log2term > log2term_prev - 0.5) return -1; if (log2term < -prec) return k; } } /* Accurate estimate of log2(|Ai(z)|) or log2(|Bi(z)|), given z = x + yi. Should subtract 0.25*log2(|z| + log2(2*sqrt(pi)) from the output. */ static double estimate_airy(double x, double y, int ai) { double r, t, sgn; r = x; t = x * ((x * x) - 3.0 * (y * y)); y = y * (3.0 * (x * x) - (y * y)); x = t * (1.0 / 9.0); y = y * (1.0 / 9.0); sgn = 1.0; if (r > 0.0 && x > 0.0) { t = sqrt(x * x + y * y) + x; if (ai) sgn = -1.0; } else { x = -x; if (x > 0.0 && x > 1e6 * fabs(y)) t = y * y / (2.0 * x); else t = sqrt(x * x + y * y) - x; } return sgn * sqrt(0.5 * t) * 2.8853900817779268147; } /* error propagation based on derivatives */ void acb_hypgeom_airy_prop(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong n, int algo, slong prec) { mag_t aib, aipb, bib, bipb, zb, rad; acb_t zz; int real; mag_init(aib); mag_init(aipb); mag_init(bib); mag_init(bipb); mag_init(zb); mag_init(rad); acb_init(zz); real = acb_is_real(z); arf_set(arb_midref(acb_realref(zz)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zz)), arb_midref(acb_imagref(z))); mag_hypot(rad, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); acb_get_mag(zb, z); acb_hypgeom_airy_bound(aib, aipb, bib, bipb, z); if (algo == 0) acb_hypgeom_airy_direct(ai, aip, bi, bip, zz, n, prec); else acb_hypgeom_airy_asymp(ai, aip, bi, bip, zz, n, prec); if (ai != NULL) { mag_mul(aipb, aipb, rad); if (real) arb_add_error_mag(acb_realref(ai), aipb); else acb_add_error_mag(ai, aipb); } if (aip != NULL) { mag_mul(aib, aib, rad); mag_mul(aib, aib, zb); /* |Ai''(z)| = |z Ai(z)| */ if (real) arb_add_error_mag(acb_realref(aip), aib); else acb_add_error_mag(aip, aib); } if (bi != NULL) { mag_mul(bipb, bipb, rad); if (real) arb_add_error_mag(acb_realref(bi), bipb); else acb_add_error_mag(bi, bipb); } if (bip != NULL) { mag_mul(bib, bib, rad); mag_mul(bib, bib, zb); /* |Bi''(z)| = |z Bi(z)| */ if (real) arb_add_error_mag(acb_realref(bip), bib); else acb_add_error_mag(bip, bib); } mag_clear(aib); mag_clear(aipb); mag_clear(bib); mag_clear(bipb); mag_clear(zb); mag_clear(rad); acb_clear(zz); } void acb_hypgeom_airy_direct_prop(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong n, slong prec) { acb_hypgeom_airy_prop(ai, aip, bi, bip, z, n, 0, prec); } void acb_hypgeom_airy_asymp2(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong n, slong prec) { /* avoid singularity in asymptotic expansion near 0 */ if (acb_rel_accuracy_bits(z) > 3) acb_hypgeom_airy_asymp(ai, aip, bi, bip, z, n, prec); else acb_hypgeom_airy_prop(ai, aip, bi, bip, z, n, 1, prec); } void acb_hypgeom_airy(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong prec) { arf_srcptr re, im; double x, y, t, zmag, z15, term_est, airy_est, abstol; slong n, wp; if (!acb_is_finite(z)) { if (ai != NULL) acb_indeterminate(ai); if (aip != NULL) acb_indeterminate(aip); if (bi != NULL) acb_indeterminate(bi); if (bip != NULL) acb_indeterminate(bip); return; } re = arb_midref(acb_realref(z)); im = arb_midref(acb_imagref(z)); wp = prec * 1.03 + 15; /* tiny input -- use direct method and pick n without underflowing */ if (arf_cmpabs_2exp_si(re, -64) < 0 && arf_cmpabs_2exp_si(im, -64) < 0) { if (arf_cmpabs_2exp_si(re, -wp) < 0 && arf_cmpabs_2exp_si(im, -wp) < 0) { n = 1; /* very tiny input */ } else { if (arf_cmpabs(re, im) > 0) zmag = fmpz_get_d(ARF_EXPREF(re)); else zmag = fmpz_get_d(ARF_EXPREF(im)); zmag = 3.0 * zmag + 1; n = wp / (-zmag) + 1; } if (acb_is_exact(z)) acb_hypgeom_airy_direct(ai, aip, bi, bip, z, n, wp); else acb_hypgeom_airy_direct_prop(ai, aip, bi, bip, z, n, wp); } /* huge input -- use asymptotics and pick n without overflowing */ else if ((arf_cmpabs_2exp_si(re, 64) > 0 || arf_cmpabs_2exp_si(im, 64) > 0)) { if (arf_cmpabs_2exp_si(re, prec) > 0 || arf_cmpabs_2exp_si(im, prec) > 0) { n = 1; /* very huge input */ } else { x = fmpz_get_d(ARF_EXPREF(re)); y = fmpz_get_d(ARF_EXPREF(im)); zmag = (FLINT_MAX(x, y) - 2) * LOG2; n = asymp_pick_terms(wp, zmag); n = FLINT_MAX(n, 1); } acb_hypgeom_airy_asymp2(ai, aip, bi, bip, z, n, wp); } else /* moderate input */ { x = arf_get_d(re, ARF_RND_DOWN); y = arf_get_d(im, ARF_RND_DOWN); zmag = sqrt(x * x + y * y); z15 = zmag * sqrt(zmag); if (zmag >= 4.0 && (n = asymp_pick_terms(wp, log(zmag))) != -1) { acb_hypgeom_airy_asymp2(ai, aip, bi, bip, z, n, wp); } else if (zmag <= 1.5) { t = 3 * (wp * LOG2) / (2 * z15 * EXP1); t = (wp * LOG2) / (2 * d_lambertw(t)); n = FLINT_MAX(t + 1, 2); if (acb_is_exact(z)) acb_hypgeom_airy_direct(ai, aip, bi, bip, z, n, wp); else acb_hypgeom_airy_direct_prop(ai, aip, bi, bip, z, n, wp); } else { /* estimate largest term: log2(exp(2(z^3/9)^(1/2))) */ term_est = 0.96179669392597560491 * z15; /* estimate the smaller of Ai and Bi */ airy_est = estimate_airy(x, y, (ai != NULL || aip != NULL)); /* estimate absolute tolerance and necessary working precision */ abstol = airy_est - wp; wp = wp + term_est - airy_est; wp = FLINT_MAX(wp, 10); t = 3 * (-abstol * LOG2) / (2 * z15 * EXP1); t = (-abstol * LOG2) / (2 * d_lambertw(t)); n = FLINT_MAX(t + 1, 2); if (acb_is_exact(z)) acb_hypgeom_airy_direct(ai, aip, bi, bip, z, n, wp); else acb_hypgeom_airy_direct_prop(ai, aip, bi, bip, z, n, wp); } } if (ai != NULL) acb_set_round(ai, ai, prec); if (aip != NULL) acb_set_round(aip, aip, prec); if (bi != NULL) acb_set_round(bi, bi, prec); if (bip != NULL) acb_set_round(bip, bip, prec); } arb-2.22.1/acb_hypgeom/airy_asymp.c000066400000000000000000000374071417376376500171760ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_mag_chi(mag_t chi, ulong n); static int arg_lt_2pi3(const acb_t z, const acb_t zeta) { if (arb_is_nonnegative(acb_realref(z))) return 1; if (arb_is_positive(acb_imagref(z)) && arb_is_positive(acb_imagref(zeta))) return 1; if (arb_is_negative(acb_imagref(z)) && arb_is_negative(acb_imagref(zeta))) return 1; return 0; } /* assuming a >= b >= c >= d, e >= f */ void _acb_mul4div2_ui(acb_t x, ulong a, ulong b, ulong c, ulong d, ulong e, ulong f, slong prec) { if (a < (UWORD(1) << (FLINT_BITS / 4))) { acb_mul_ui(x, x, a * b * c * d, prec); } else if (a < (UWORD(1) << (FLINT_BITS / 2))) { acb_mul_ui(x, x, a * b, prec); acb_mul_ui(x, x, c * d, prec); } else { acb_mul_ui(x, x, a, prec); acb_mul_ui(x, x, b, prec); acb_mul_ui(x, x, c, prec); acb_mul_ui(x, x, d, prec); } if (e < (UWORD(1) << (FLINT_BITS / 2))) { acb_div_ui(x, x, e * f, prec); } else { acb_div_ui(x, x, e, prec); acb_div_ui(x, x, f, prec); } } void acb_hypgeom_airy_asymp_sum(acb_t s0even, acb_t s0odd, acb_t s1even, acb_t s1odd, mag_t t0n, mag_t t1n, const acb_t z, const acb_t z2, slong n, slong prec) { slong m, k, j; acb_ptr z2pow; acb_get_mag(t0n, z); mag_mul_ui(t0n, t0n, 72); mag_pow_ui(t0n, t0n, n); mag_one(t1n); for (k = 1; k <= n; k++) { mag_mul_ui(t0n, t0n, 6 * k - 1); mag_mul_ui(t0n, t0n, 6 * k - 5); mag_mul_ui_lower(t1n, t1n, 72 * k); } mag_div(t0n, t0n, t1n); mag_mul_ui(t1n, t0n, 6 * n + 1); mag_div_ui(t1n, t1n, 6 * n - 1); m = n_sqrt(n / 2); m = FLINT_MAX(m, 1); z2pow = _acb_vec_init(m + 1); _acb_vec_set_powers(z2pow, z2, m + 1, prec); if (s0even != NULL) { acb_zero(s0even); for (k = n + (n % 2); k >= 0; k -= 2) { j = (k / 2) % m; if (k < n) acb_add(s0even, s0even, z2pow + j, prec); if (k > 0) { _acb_mul4div2_ui(s0even, 6*k-1, 6*k-5, 6*k-7, 6*k-11, k, k-1, prec); if (j == 0 && k < n) acb_mul(s0even, s0even, z2pow + m, prec); } } } if (s0odd != NULL) { acb_zero(s0odd); for (k = n + 1 + (n % 2); k >= 1; k -= 2) { j = ((k - 1) / 2) % m; if (k < n) acb_add(s0odd, s0odd, z2pow + j, prec); if (k > 1) { _acb_mul4div2_ui(s0odd, 6*k-1, 6*k-5, 6*k-7, 6*k-11, k, k-1, prec); if (j == 0 && k < n) acb_mul(s0odd, s0odd, z2pow + m, prec); } else { acb_mul(s0odd, s0odd, z, prec); acb_mul_ui(s0odd, s0odd, 5, prec); } } } if (s1even != NULL) { acb_zero(s1even); for (k = n + (n % 2); k >= 0; k -= 2) { j = (k / 2) % m; if (k < n) acb_add(s1even, s1even, z2pow + j, prec); if (k > 0) { _acb_mul4div2_ui(s1even, 6*k+1, 6*k-5, 6*k-7, FLINT_ABS(6*k-13), k, k-1, prec); if (k == 2) acb_neg(s1even, s1even); if (j == 0 && k < n) acb_mul(s1even, s1even, z2pow + m, prec); } } } if (s1odd != NULL) { acb_zero(s1odd); for (k = n + 1 + (n % 2); k >= 1; k -= 2) { j = ((k - 1) / 2) % m; if (k < n) acb_add(s1odd, s1odd, z2pow + j, prec); if (k > 1) { _acb_mul4div2_ui(s1odd, 6*k+1, 6*k-5, 6*k-7, 6*k-13, k, k-1, prec); if (j == 0 && k < n) acb_mul(s1odd, s1odd, z2pow + m, prec); } else { acb_mul(s1odd, s1odd, z, prec); acb_mul_si(s1odd, s1odd, -7, prec); } } } _acb_vec_clear(z2pow, m + 1); } void acb_hypgeom_airy_asymp_bound_factor(mag_t bound, const acb_t z, const acb_t zeta, ulong n) { mag_t t, u, v; mag_init(t); mag_init(u); mag_init(v); if (arb_is_nonnegative(acb_realref(z)) && arb_is_nonnegative(acb_realref(zeta))) { /* 2 exp(7 / (36 |zeta|)) */ mag_set_ui_2exp_si(t, 50, -8); /* bound for 7/36 */ acb_get_mag_lower(u, zeta); mag_div(t, t, u); mag_exp(t, t); mag_mul_2exp_si(bound, t, 1); } else { /* 2 exp(7 pi / (72 |zeta|)) */ mag_set_ui_2exp_si(t, 79, -8); /* bound for 7 pi/72 */ acb_get_mag_lower(u, zeta); mag_div(t, t, u); mag_exp(t, t); mag_mul_2exp_si(bound, t, 1); /* 4 exp(7 pi / (36 |re(zeta)|)) / |cos(arg(zeta))|^n */ if (!arg_lt_2pi3(z, zeta)) { arb_get_mag_lower(u, acb_realref(zeta)); arb_get_mag(v, acb_imagref(zeta)); /* 4 exp(7 pi / (36 u)) < exp(157/(256 u)) */ mag_set_ui_2exp_si(t, 157, -8); mag_div(t, t, u); mag_exp(t, t); mag_mul_2exp_si(t, t, 2); /* |1/cos(arg(zeta))| = sqrt(1+(v/u)^2) */ mag_div(v, v, u); mag_mul(v, v, v); mag_one(u); mag_add(v, v, u); mag_sqrt(v, v); mag_pow_ui(v, v, n); mag_mul(t, t, v); mag_max(bound, bound, t); } /* chi(n) */ acb_hypgeom_mag_chi(t, n); mag_mul(bound, bound, t); } mag_clear(t); mag_clear(u); mag_clear(v); } void acb_hypgeom_airy_asymp(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong n, slong prec) { acb_t t, u, w, z_root, zeta; acb_t s0even, s0odd, s1even, s1odd, E1, E2; mag_t err1, err2, erru, errv, errtmp; int want_d0, want_d1, is_real, upper; acb_init(t); acb_init(u); acb_init(w); acb_init(z_root); acb_init(zeta); acb_init(s0even); acb_init(s0odd); acb_init(s1even); acb_init(s1odd); acb_init(E1); acb_init(E2); mag_init(err1); mag_init(err2); mag_init(errtmp); mag_init(erru); mag_init(errv); is_real = acb_is_real(z); want_d0 = (ai != NULL) || (bi != NULL); want_d1 = (aip != NULL) || (bip != NULL); /* required for some of the error bounds to be valid */ n = FLINT_MAX(n, 1); /* this is just a heuristic; the sectors are validated later */ if (arf_sgn(arb_midref(acb_realref(z))) >= 0) { /* z_root = z^(1/4), zeta = 2 z^(3/2) / 3 */ acb_sqrt(z_root, z, prec); acb_cube(zeta, z_root, prec); acb_sqrt(z_root, z_root, prec); acb_mul_2exp_si(zeta, zeta, 1); acb_div_ui(zeta, zeta, 3, prec); /* compute bound factor for z = t = z1, zeta = u = zeta1 */ acb_hypgeom_airy_asymp_bound_factor(err1, z, zeta, n); /* this is just a heuristic; the sectors are validated later */ upper = arf_sgn(arb_midref(acb_imagref(z))) >= 0; if (upper) { /* check -pi/3 < arg(z) < pi */ if (arb_is_positive(acb_imagref(z)) || (arb_is_positive(acb_realref(z)) && arb_is_positive(acb_realref(zeta)))) { arb_one(acb_realref(w)); arb_sqrt_ui(acb_imagref(w), 3, prec); acb_mul_2exp_si(w, w, -1); acb_neg(w, w); acb_mul(t, w, z, prec); acb_neg(u, zeta); acb_hypgeom_airy_asymp_bound_factor(err2, t, u, n); } else { mag_inf(err2); } } else { /* check -pi < arg(z) < pi/3 */ if (arb_is_negative(acb_imagref(z)) || (arb_is_positive(acb_realref(z)) && arb_is_positive(acb_realref(zeta)))) { arb_set_si(acb_realref(w), -1); arb_sqrt_ui(acb_imagref(w), 3, prec); acb_mul_2exp_si(w, w, -1); acb_mul(t, w, z, prec); acb_neg(u, zeta); acb_hypgeom_airy_asymp_bound_factor(err2, t, u, n); } else { mag_inf(err2); } } acb_mul_ui(t, zeta, 72, prec); acb_inv(t, t, prec); acb_mul(u, t, t, prec); acb_hypgeom_airy_asymp_sum(want_d0 ? s0even : NULL, want_d0 ? s0odd : NULL, want_d1 ? s1even : NULL, want_d1 ? s1odd : NULL, erru, errv, t, u, n, prec); /* exponentials */ acb_exp_invexp(E2, E1, zeta, prec); /* common prefactor */ acb_const_pi(w, prec); acb_sqrt(w, w, prec); acb_mul_2exp_si(w, w, 1); if (ai != NULL || bi != NULL) { /* t = sum (-1)^k u(k) / (zeta)^k + error */ acb_sub(t, s0even, s0odd, prec); mag_mul(errtmp, err1, erru); acb_add_error_mag(t, errtmp); /* u = sum (-1)^k u(k) / (-zeta)^k = sum u(k) / (zeta)^k + error */ acb_add(u, s0even, s0odd, prec); mag_mul(errtmp, err2, erru); acb_add_error_mag(u, errtmp); if (ai != NULL) { acb_mul(ai, t, E1, prec); } if (bi != NULL) { acb_mul(t, t, E1, prec); acb_mul(u, u, E2, prec); acb_mul_2exp_si(u, u, 1); if (upper) acb_mul_onei(t, t); else acb_div_onei(t, t); acb_add(bi, t, u, prec); } acb_mul(t, w, z_root, prec); acb_inv(t, t, prec); if (ai != NULL) acb_mul(ai, ai, t, prec); if (bi != NULL) acb_mul(bi, bi, t, prec); } if (aip != NULL || bip != NULL) { /* t = sum (-1)^k v(k) / (zeta)^k + error */ acb_sub(t, s1even, s1odd, prec); mag_mul(errtmp, err1, errv); acb_add_error_mag(t, errtmp); /* u = sum (-1)^k v(k) / (-zeta)^k = sum v(k) / (zeta)^k + error */ acb_add(u, s1even, s1odd, prec); mag_mul(errtmp, err2, errv); acb_add_error_mag(u, errtmp); if (aip != NULL) { acb_mul(aip, t, E1, prec); acb_neg(aip, aip); } if (bip != NULL) { acb_mul(t, t, E1, prec); acb_mul(u, u, E2, prec); acb_mul_2exp_si(u, u, 1); if (upper) acb_div_onei(t, t); else acb_mul_onei(t, t); acb_add(bip, t, u, prec); } acb_inv(t, w, prec); acb_mul(t, t, z_root, prec); if (aip != NULL) acb_mul(aip, aip, t, prec); if (bip != NULL) acb_mul(bip, bip, t, prec); } } else { /* z_root = (-z)^(1/4), zeta = 2 (-z)^(3/2) / 3 */ acb_neg(t, z); acb_sqrt(z_root, t, prec); acb_cube(zeta, z_root, prec); acb_sqrt(z_root, z_root, prec); acb_mul_2exp_si(zeta, zeta, 1); acb_div_ui(zeta, zeta, 3, prec); if (arg_lt_2pi3(t, zeta)) { /* compute bound factor for i zeta */ arb_one(acb_realref(w)); arb_sqrt_ui(acb_imagref(w), 3, prec); acb_mul_2exp_si(w, w, -1); acb_mul(t, z, w, prec); acb_neg(t, t); acb_mul_onei(u, zeta); acb_hypgeom_airy_asymp_bound_factor(err1, t, u, n); /* compute bound factor for -i zeta */ acb_conj(w, w); acb_mul(t, z, w, prec); acb_neg(t, t); acb_div_onei(u, zeta); acb_hypgeom_airy_asymp_bound_factor(err2, t, u, n); } else { mag_inf(err1); mag_inf(err2); } /* t = 1/(72 i zeta), u = (1/(72 i zeta))^2 */ acb_mul_onei(t, zeta); acb_mul_ui(t, t, 72, prec); acb_inv(t, t, prec); acb_mul(u, t, t, prec); acb_hypgeom_airy_asymp_sum(want_d0 ? s0even : NULL, want_d0 ? s0odd : NULL, want_d1 ? s1even : NULL, want_d1 ? s1odd : NULL, erru, errv, t, u, n, prec); /* exponentials */ acb_const_pi(t, prec); acb_mul_2exp_si(t, t, -2); acb_sub(t, zeta, t, prec); acb_mul_onei(t, t); acb_exp_invexp(E2, E1, t, prec); /* common prefactor */ acb_const_pi(w, prec); acb_sqrt(w, w, prec); acb_mul_2exp_si(w, w, 1); if (ai != NULL || bi != NULL) { /* t = sum (-1)^k u(k) / (i zeta)^k + error */ acb_sub(t, s0even, s0odd, prec); mag_mul(errtmp, err1, erru); acb_add_error_mag(t, errtmp); /* w = sum (-1)^k u(k) / (-i zeta)^k = sum u(k) / (i zeta)^k + error */ acb_add(u, s0even, s0odd, prec); mag_mul(errtmp, err2, erru); acb_add_error_mag(u, errtmp); if (ai != NULL) { acb_mul(ai, t, E1, prec); acb_addmul(ai, u, E2, prec); } if (bi != NULL) { /* (-i E1) t + (+i E2) u */ acb_mul(bi, u, E2, prec); acb_submul(bi, t, E1, prec); acb_mul_onei(bi, bi); } acb_mul(t, w, z_root, prec); acb_inv(t, t, prec); if (ai != NULL) acb_mul(ai, ai, t, prec); if (bi != NULL) acb_mul(bi, bi, t, prec); } if (aip != NULL || bip != NULL) { /* t = sum (-1)^k v(k) / (i zeta)^k + error */ acb_sub(t, s1even, s1odd, prec); mag_mul(errtmp, err1, errv); acb_add_error_mag(t, errtmp); /* u = sum (-1)^k v(k) / (-i zeta)^k = sum v(k) / (i zeta)^k + error */ acb_add(u, s1even, s1odd, prec); mag_mul(errtmp, err2, errv); acb_add_error_mag(u, errtmp); if (bip != NULL) { acb_mul(bip, t, E1, prec); acb_addmul(bip, u, E2, prec); } if (aip != NULL) { /* i E1 t - i E2 u */ acb_mul(aip, t, E1, prec); acb_submul(aip, u, E2, prec); acb_mul_onei(aip, aip); } acb_inv(t, w, prec); acb_mul(t, t, z_root, prec); if (aip != NULL) acb_mul(aip, aip, t, prec); if (bip != NULL) acb_mul(bip, bip, t, prec); } } if (is_real) { if (ai != NULL) arb_zero(acb_imagref(ai)); if (aip != NULL) arb_zero(acb_imagref(aip)); if (bi != NULL) arb_zero(acb_imagref(bi)); if (bip != NULL) arb_zero(acb_imagref(bip)); } acb_clear(t); acb_clear(u); acb_clear(w); acb_clear(z_root); acb_clear(zeta); acb_clear(s0even); acb_clear(s0odd); acb_clear(s1even); acb_clear(s1odd); acb_clear(E1); acb_clear(E2); mag_clear(err1); mag_clear(err2); mag_clear(errtmp); mag_clear(erru); mag_clear(errv); } arb-2.22.1/acb_hypgeom/airy_bound.c000066400000000000000000000232321417376376500171430ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void arb_bound_exp_neg(mag_t b, const arb_t x) { arb_t t; arb_init(t); arf_set_mag(arb_midref(t), arb_radref(x)); arf_sub(arb_midref(t), arb_midref(x), arb_midref(t), MAG_BITS, ARF_RND_FLOOR); arf_neg(arb_midref(t), arb_midref(t)); arb_exp(t, t, MAG_BITS); arb_get_mag(b, t); arb_clear(t); } /* Implements DLMF 9.7.17. We assume |zeta| >= 1/2 and |arg(z)| <= 2 pi/3 here, ignoring the smaller points which must be dealt with separately. */ void acb_hypgeom_airy_bound_9_7_17(mag_t bound, const acb_t z, const acb_t zeta) { mag_t D, t, u, v, zeta_lower, half; mag_init(D); mag_init(t); mag_init(u); mag_init(v); mag_init(zeta_lower); mag_init(half); mag_one(half); mag_mul_2exp_si(half, half, -1); acb_get_mag_lower(zeta_lower, zeta); mag_max(zeta_lower, zeta_lower, half); /* by assumption */ /* 2 chi(1) exp(7 pi / (72 |zeta|)) * c_1 */ /* simplified bound assuming |zeta| >= 1/2 */ mag_one(D); /* exp(-zeta) / (2 sqrt(pi)) * (1 + D / |zeta|) */ /* t = exp(-zeta) / (2 sqrt(pi)) < exp(-zeta) * (73/256) */ arb_bound_exp_neg(t, acb_realref(zeta)); mag_mul_ui(t, t, 73); mag_mul_2exp_si(t, t, -8); /* u = 1 + D / |zeta| */ mag_div(u, D, zeta_lower); mag_one(v); mag_add(u, u, v); mag_mul(bound, t, u); mag_clear(D); mag_clear(t); mag_clear(u); mag_clear(v); mag_clear(zeta_lower); } void acb_hypgeom_airy_bound_arg_le_2pi3(mag_t A, mag_t B, const acb_t z, slong wp) { acb_t zeta, z1; acb_init(zeta); acb_init(z1); acb_set_round(zeta, z, wp); acb_sqrt(zeta, zeta, wp); acb_cube(zeta, zeta, wp); acb_mul_2exp_si(zeta, zeta, 1); acb_div_ui(zeta, zeta, 3, wp); acb_hypgeom_airy_bound_9_7_17(A, z, zeta); /* Use Bi(z) = w_1 Ai(z) + 2 w_2 Ai(z exp(+/- 2pi i / 3)), where w_1, w_2 are roots of unity */ if (B != NULL) { arb_sqrt_ui(acb_imagref(z1), 3, wp); arb_set_si(acb_realref(z1), -1); acb_mul_2exp_si(z1, z1, -1); /* multiply by exp(-2 pi i / 3) in upper half plane and by exp(2 pi i / 3) in lower half plane, to stay close to positive reals */ /* in principle, we should be computing the union of both cases, but since Bi is conjugate symmetric with the maximum value attained on the positive real line, it's sufficient to consider the case centered on the midpoint */ if (arf_sgn(arb_midref(acb_imagref(z))) >= 0) acb_conj(z1, z1); acb_mul(z1, z1, z, wp); acb_neg(zeta, zeta); /* same effect regardless of exp(+/-2 pi i/3) */ acb_hypgeom_airy_bound_9_7_17(B, z1, zeta); mag_mul_2exp_si(B, B, 1); mag_add(B, B, A); } acb_clear(zeta); acb_clear(z1); } /* near the negative half line, use |Ai(-z)|, |Bi(-z)| <= |Ai(z exp(pi i/3))| + |Ai(z exp(-pi i/3))| */ void acb_hypgeom_airy_bound_arg_ge_2pi3(mag_t A, mag_t B, const acb_t z, slong wp) { acb_t zeta, z1, z2; acb_init(zeta); acb_init(z1); acb_init(z2); arb_sqrt_ui(acb_imagref(z1), 3, wp); arb_one(acb_realref(z1)); acb_mul_2exp_si(z1, z1, -1); acb_conj(z2, z1); acb_neg_round(zeta, z, wp); acb_mul(z1, z1, zeta, wp); acb_sqrt(zeta, zeta, wp); acb_cube(zeta, zeta, wp); acb_mul_2exp_si(zeta, zeta, 1); acb_div_ui(zeta, zeta, 3, wp); acb_mul_onei(zeta, zeta); acb_hypgeom_airy_bound_9_7_17(A, z1, zeta); /* conjugate symmetry */ if (arb_is_zero(acb_imagref(z))) { mag_mul_2exp_si(A, A, 1); } else { mag_t D; mag_init(D); acb_mul(z2, z2, zeta, wp); acb_neg(zeta, zeta); acb_hypgeom_airy_bound_9_7_17(D, z2, zeta); mag_add(A, A, D); mag_clear(D); } if (B != NULL) mag_set(B, A); acb_clear(zeta); acb_clear(z1); acb_clear(z2); } static int arg_lt_2pi3_fast(const acb_t z) { arf_t t; mag_t x, y, s; int res; if (arb_is_zero(acb_imagref(z)) && arb_is_nonnegative(acb_realref(z))) return 1; arf_init(t); mag_init(x); mag_init(y); mag_init(s); arf_set_mag(t, arb_radref(acb_realref(z))); arf_sub(t, arb_midref(acb_realref(z)), t, MAG_BITS, ARF_RND_FLOOR); if (arf_sgn(t) >= 0) { res = 1; } else { arf_get_mag(x, t); arb_get_mag_lower(y, acb_imagref(z)); mag_set_ui(s, 3); mag_sqrt(s, s); mag_mul(s, s, x); res = mag_cmp(s, y) <= 0; } arf_clear(t); mag_clear(x); mag_clear(y); mag_clear(s); return res; } static int arg_gt_2pi3_fast(const acb_t z) { arf_t t; mag_t x, y, s; int res; if (arb_is_zero(acb_imagref(z)) && arb_is_negative(acb_realref(z))) return 1; arf_init(t); mag_init(x); mag_init(y); mag_init(s); arf_set_mag(t, arb_radref(acb_realref(z))); arf_add(t, arb_midref(acb_realref(z)), t, MAG_BITS, ARF_RND_CEIL); if (arf_sgn(t) >= 0) { res = 0; } else { arf_get_mag_lower(x, t); arb_get_mag(y, acb_imagref(z)); mag_set_ui_lower(s, 3); mag_sqrt_lower(s, s); mag_mul_lower(s, s, x); res = mag_cmp(s, y) >= 0; } arf_clear(t); mag_clear(x); mag_clear(y); mag_clear(s); return res; } void acb_hypgeom_airy_bound(mag_t ai, mag_t aip, mag_t bi, mag_t bip, const acb_t z) { acb_t zeta; mag_t A, B, D, zlo, zhi; slong wp; int near_zero; /* Fast and slightly tighter bounds for real z <= 0 */ /* Todo: could implement bounds for z >= 0 too */ if (acb_is_real(z) && arb_is_nonpositive(acb_realref(z))) { mag_init(zlo); mag_init(zhi); mag_init(A); mag_init(B); mag_init(D); if (ai != NULL || bi != NULL) { acb_get_mag_lower(zlo, z); mag_rsqrt(A, zlo); mag_sqrt(A, A); mag_mul_ui(A, A, 150); mag_set_ui(D, 160); mag_min(A, A, D); mag_mul_2exp_si(A, A, -8); if (ai != NULL) mag_set(ai, A); if (bi != NULL) mag_set(bi, A); } if (aip != NULL || bip != NULL) { acb_get_mag(zhi, z); mag_sqrt(A, zhi); mag_sqrt(A, A); mag_mul_ui(A, A, 150); mag_set_ui(D, 160); mag_max(B, A, D); mag_mul_2exp_si(B, B, -8); mag_set_ui(D, 67); mag_max(A, A, D); mag_mul_2exp_si(A, A, -8); if (aip != NULL) mag_set(aip, A); if (bip != NULL) mag_set(bip, B); } mag_clear(zlo); mag_clear(zhi); mag_clear(A); mag_clear(B); mag_clear(D); return; } acb_init(zeta); mag_init(A); mag_init(B); mag_init(D); mag_init(zlo); mag_init(zhi); wp = MAG_BITS * 2; acb_get_mag_lower(zlo, z); acb_get_mag(zhi, z); if (mag_cmp_2exp_si(zhi, 0) <= 0) { /* inside unit circle -- don't look at asymptotics */ if (ai != NULL) mag_set_ui_2exp_si(ai, 159, -8); if (aip != NULL) mag_set_ui_2exp_si(aip, 125, -8); if (bi != NULL) mag_set_ui_2exp_si(bi, 310, -8); if (bip != NULL) mag_set_ui_2exp_si(bip, 239, -8); } else { /* look at asymptotics outside unit circle */ near_zero = mag_cmp_2exp_si(zlo, 0) <= 0; if (near_zero) mag_one(zlo); if (arg_lt_2pi3_fast(z)) { acb_hypgeom_airy_bound_arg_le_2pi3(A, (bi != NULL || bip != NULL) ? B : NULL, z, wp); } else if (arg_gt_2pi3_fast(z)) { acb_hypgeom_airy_bound_arg_ge_2pi3(A, (bi != NULL || bip != NULL) ? B : NULL, z, wp); } else { mag_t A2, B2; mag_init(A2); mag_init(B2); acb_hypgeom_airy_bound_arg_le_2pi3(A, (bi != NULL || bip != NULL) ? B : NULL, z, wp); acb_hypgeom_airy_bound_arg_ge_2pi3(A2, (bi != NULL || bip != NULL) ? B2 : NULL, z, wp); mag_max(A, A, A2); mag_max(B, B, A2); mag_clear(A2); mag_clear(B2); } /* bound |z|^(1/4) */ mag_sqrt(zhi, zhi); mag_sqrt(zhi, zhi); /* bound |z|^(-1/4) */ mag_rsqrt(zlo, zlo); mag_sqrt(zlo, zlo); if (ai != NULL) mag_mul(ai, A, zlo); if (aip != NULL) mag_mul(aip, A, zhi); if (bi != NULL) mag_mul(bi, B, zlo); if (bip != NULL) mag_mul(bip, B, zhi); if (near_zero) { /* max by bounds on the unit circle */ if (ai != NULL) { mag_set_ui_2exp_si(D, 159, -8); mag_max(ai, ai, D); } if (aip != NULL) { mag_set_ui_2exp_si(D, 125, -8); mag_max(aip, aip, D); } if (bi != NULL) { mag_set_ui_2exp_si(D, 310, -8); mag_max(bi, bi, D); } if (bip != NULL) { mag_set_ui_2exp_si(D, 239, -8); mag_max(bip, bip, D); } } } acb_clear(zeta); mag_clear(A); mag_clear(B); mag_clear(D); mag_clear(zlo); mag_clear(zhi); } arb-2.22.1/acb_hypgeom/airy_direct.c000066400000000000000000000154021417376376500173060ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void arb_const_airy_ai0_eval(arb_t y, slong prec) { arb_t t; fmpq_t v; arb_init(t); fmpq_init(v); arb_set_ui(y, 3); arb_root_ui(y, y, 3, prec + 5); arb_mul(y, y, y, prec + 5); fmpq_set_si(v, 2, 3); arb_gamma_fmpq(t, v, prec + 5); arb_mul(y, y, t, prec + 5); arb_inv(y, y, prec); arb_clear(t); fmpq_clear(v); } void arb_const_airy_ai1_eval(arb_t y, slong prec) { arb_t t; fmpq_t v; arb_init(t); fmpq_init(v); arb_set_ui(y, 3); arb_root_ui(y, y, 3, prec + 5); fmpq_set_si(v, 1, 3); arb_gamma_fmpq(t, v, prec + 5); arb_mul(y, y, t, prec + 5); arb_inv(y, y, prec); arb_neg(y, y); arb_clear(t); fmpq_clear(v); } void arb_const_airy_bi0_eval(arb_t y, slong prec) { arb_t t; fmpq_t v; arb_init(t); fmpq_init(v); arb_set_ui(y, 3); arb_root_ui(y, y, 6, prec + 5); fmpq_set_si(v, 2, 3); arb_gamma_fmpq(t, v, prec + 5); arb_mul(y, y, t, prec + 5); arb_inv(y, y, prec); arb_clear(t); fmpq_clear(v); } void arb_const_airy_bi1_eval(arb_t y, slong prec) { arb_t t; fmpq_t v; arb_init(t); fmpq_init(v); arb_set_ui(y, 3); arb_root_ui(y, y, 6, prec + 5); fmpq_set_si(v, 1, 3); arb_gamma_fmpq(t, v, prec + 5); arb_div(y, y, t, prec); arb_clear(t); fmpq_clear(v); } ARB_DEF_CACHED_CONSTANT(arb_const_airy_ai0, arb_const_airy_ai0_eval) ARB_DEF_CACHED_CONSTANT(arb_const_airy_ai1, arb_const_airy_ai1_eval) ARB_DEF_CACHED_CONSTANT(arb_const_airy_bi0, arb_const_airy_bi0_eval) ARB_DEF_CACHED_CONSTANT(arb_const_airy_bi1, arb_const_airy_bi1_eval) static void acb_hypgeom_airy_0f1_sum_inner(acb_t s, acb_srcptr t, slong m, slong n, slong alpha, int real, slong prec) { slong j, k; mp_limb_t c, chi, clo; acb_zero(s); /* not implemented (coefficient overflow) */ if (FLINT_BITS == 32 && n > 37000) { acb_indeterminate(s); return; } c = 1; j = (n - 1) % m; for (k = n - 1; k >= 0; k--) { if (k != 0) { umul_ppmm(chi, clo, c, 3 * k + alpha); if (chi == 0) umul_ppmm(chi, clo, clo, k); if (chi != 0) { acb_div_ui(s, s, c, prec); c = 1; } } if (real) arb_addmul_ui(acb_realref(s), acb_realref(t + j), c, prec); else acb_addmul_ui(s, t + j, c, prec); if (k != 0) { c = c * k * (3 * k + alpha); if (j == 0) { acb_mul(s, s, t + m, prec); j = m - 1; } else { j--; } } } acb_div_ui(s, s, c, prec); } /* s1 = 0F1(1/3, z/3) s2 = 0F1(2/3, z/3) s4 = 0F1(4/3, z/3) s5 = 0F1(5/3, z/3) */ static void acb_hypgeom_airy_0f1_sum(acb_t s1, acb_t s2, acb_t s4, acb_t s5, const acb_t z, slong n, int real, slong prec) { acb_ptr t; slong m; m = 2 * n_sqrt(n); m = FLINT_MAX(m, 1); t = _acb_vec_init(m + 1); _acb_vec_set_powers(t, z, m + 1, prec); if (s1 != NULL) acb_hypgeom_airy_0f1_sum_inner(s1, t, m, n, -2, real, prec); if (s2 != NULL) acb_hypgeom_airy_0f1_sum_inner(s2, t, m, n, -1, real, prec); if (s4 != NULL) acb_hypgeom_airy_0f1_sum_inner(s4, t, m, n, +1, real, prec); if (s5 != NULL) acb_hypgeom_airy_0f1_sum_inner(s5, t, m, n, +2, real, prec); _acb_vec_clear(t, m + 1); } void acb_hypgeom_airy_direct(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong n, slong prec) { mag_t err, wmag, tm; int is_real; acb_t s1, s2, s4, s5, t, u; arb_t ai0, ai1, bi0, bi1; mag_init(err); mag_init(wmag); mag_init(tm); acb_init(s1); acb_init(s2); acb_init(s4); acb_init(s5); acb_init(t); acb_init(u); arb_init(ai0); arb_init(ai1); arb_init(bi0); arb_init(bi1); n = FLINT_MAX(n, 2); is_real = acb_is_real(z); acb_get_mag(wmag, z); /* With w = z^3/9, the terms are bounded by 3 w^n / [(n-1)!]^2. 3 w^n w w^2 ---------- [ 1 + --- + ------- + ....] ((n-1)!)^2 n^2 (n+1)^2 */ mag_pow_ui(wmag, wmag, 3); mag_div_ui(wmag, wmag, 9); mag_pow_ui(err, wmag, n); mag_div_ui(tm, wmag, n); mag_div_ui(tm, tm, n); mag_geom_series(tm, tm, 0); mag_mul(err, err, tm); mag_rfac_ui(tm, n - 1); mag_mul(tm, tm, tm); mag_mul(err, err, tm); mag_mul_ui(err, err, 3); acb_cube(t, z, prec); acb_div_ui(t, t, 3, prec); acb_hypgeom_airy_0f1_sum( (aip != NULL || bip != NULL) ? s1 : NULL, (ai != NULL || bi != NULL) ? s2 : NULL, (ai != NULL || bi != NULL) ? s4 : NULL, (aip != NULL || bip != NULL) ? s5 : NULL, t, n, is_real, prec); if (is_real) { arb_add_error_mag(acb_realref(s1), err); arb_add_error_mag(acb_realref(s2), err); arb_add_error_mag(acb_realref(s4), err); arb_add_error_mag(acb_realref(s5), err); } else { acb_add_error_mag(s1, err); acb_add_error_mag(s2, err); acb_add_error_mag(s4, err); acb_add_error_mag(s5, err); } if (ai != NULL || aip != NULL) { arb_const_airy_ai0(ai0, prec); arb_const_airy_ai1(ai1, prec); } if (bi != NULL || bip != NULL) { arb_const_airy_bi0(bi0, prec); arb_const_airy_bi1(bi1, prec); } /* support aliasing with z */ acb_set(t, z); if (ai != NULL || bi != NULL) { acb_mul(u, s4, t, prec); if (ai != NULL) { acb_mul_arb(ai, s2, ai0, prec); acb_addmul_arb(ai, u, ai1, prec); } if (bi != NULL) { acb_mul_arb(bi, s2, bi0, prec); acb_addmul_arb(bi, u, bi1, prec); } } if (aip != NULL || bip != NULL) { acb_mul(u, t, t, prec); acb_mul_2exp_si(u, u, -1); acb_mul(u, u, s5, prec); if (aip != NULL) { acb_mul_arb(aip, s1, ai1, prec); acb_addmul_arb(aip, u, ai0, prec); } if (bip != NULL) { acb_mul_arb(bip, s1, bi1, prec); acb_addmul_arb(bip, u, bi0, prec); } } mag_clear(err); mag_clear(wmag); mag_clear(tm); acb_clear(s1); acb_clear(s2); acb_clear(s4); acb_clear(s5); acb_clear(t); acb_clear(u); arb_clear(ai0); arb_clear(ai1); arb_clear(bi0); arb_clear(bi1); } arb-2.22.1/acb_hypgeom/airy_jet.c000066400000000000000000000023231417376376500166140ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void airy_recurrence(acb_ptr ai, const acb_t z, slong len, slong prec) { slong k; if (len >= 3) { acb_mul(ai + 2, ai, z, prec); acb_mul_2exp_si(ai + 2, ai + 2, -1); } for (k = 3; k < len; k++) { acb_mul(ai + k, ai + k - 2, z, prec); acb_add(ai + k, ai + k, ai + k - 3, prec); acb_div_ui(ai + k, ai + k, k * (k - 1), prec); } } void acb_hypgeom_airy_jet(acb_ptr ai, acb_ptr bi, const acb_t z, slong len, slong prec) { if (len <= 0) return; if (len == 1) { acb_hypgeom_airy(ai, NULL, bi, NULL, z, prec); return; } acb_hypgeom_airy(ai, ai ? (ai + 1) : NULL, bi, bi ? (bi + 1) : NULL, z, prec); if (ai != NULL) airy_recurrence(ai, z, len, prec); if (bi != NULL) airy_recurrence(bi, z, len, prec); } arb-2.22.1/acb_hypgeom/airy_series.c000066400000000000000000000065611417376376500173340ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_airy_series(acb_ptr ai, acb_ptr ai_prime, acb_ptr bi, acb_ptr bi_prime, acb_srcptr z, slong zlen, slong len, slong prec) { acb_ptr t, u, v; slong tlen = len + ((ai_prime != NULL) || (bi_prime != NULL)); zlen = FLINT_MIN(zlen, len); if (zlen <= 0) return; if (zlen == 1) { acb_hypgeom_airy(ai, ai_prime, bi, bi_prime, z, prec); return; } t = _acb_vec_init(tlen); u = _acb_vec_init(tlen); v = _acb_vec_init(len); acb_hypgeom_airy_jet((ai || ai_prime) ? t : NULL, (bi || bi_prime) ? u : NULL, z, tlen, prec); /* compose with nonconstant part */ acb_zero(v); _acb_vec_set(v + 1, z + 1, zlen - 1); if (ai != NULL) _acb_poly_compose_series(ai, t, len, v, zlen, len, prec); if (bi != NULL) _acb_poly_compose_series(bi, u, len, v, zlen, len, prec); /* todo: use chain rule to avoid compositions for derivatives? */ if (ai_prime != NULL) { _acb_poly_derivative(t, t, len + 1, prec); _acb_poly_compose_series(ai_prime, t, len, v, zlen, len, prec); } if (bi_prime != NULL) { _acb_poly_derivative(u, u, len + 1, prec); _acb_poly_compose_series(bi_prime, u, len, v, zlen, len, prec); } _acb_vec_clear(t, tlen); _acb_vec_clear(u, tlen); _acb_vec_clear(v, len); } void acb_hypgeom_airy_series(acb_poly_t ai, acb_poly_t ai_prime, acb_poly_t bi, acb_poly_t bi_prime, const acb_poly_t z, slong len, slong prec) { if (len == 0) { if (ai != NULL) acb_poly_zero(ai); if (ai_prime != NULL) acb_poly_zero(ai_prime); if (bi != NULL) acb_poly_zero(bi); if (bi_prime != NULL) acb_poly_zero(bi_prime); return; } if (z->length <= 1) len = 1; if (ai != NULL) acb_poly_fit_length(ai, len); if (ai_prime != NULL) acb_poly_fit_length(ai_prime, len); if (bi != NULL) acb_poly_fit_length(bi, len); if (bi_prime != NULL) acb_poly_fit_length(bi_prime, len); if (z->length == 0) { acb_t t; acb_init(t); _acb_hypgeom_airy_series( ai ? ai->coeffs : NULL, ai_prime ? ai_prime->coeffs : NULL, bi ? bi->coeffs : NULL, bi_prime ? bi_prime->coeffs : NULL, t, 1, len, prec); acb_clear(t); } else { _acb_hypgeom_airy_series( ai ? ai->coeffs : NULL, ai_prime ? ai_prime->coeffs : NULL, bi ? bi->coeffs : NULL, bi_prime ? bi_prime->coeffs : NULL, z->coeffs, z->length, len, prec); } if (ai != NULL) { _acb_poly_set_length(ai, len); _acb_poly_normalise(ai); } if (ai_prime != NULL) { _acb_poly_set_length(ai_prime, len); _acb_poly_normalise(ai_prime); } if (bi != NULL) { _acb_poly_set_length(bi, len); _acb_poly_normalise(bi); } if (bi_prime != NULL) { _acb_poly_set_length(bi_prime, len); _acb_poly_normalise(bi_prime); } } arb-2.22.1/acb_hypgeom/bessel_i.c000066400000000000000000000147141417376376500166020ustar00rootroot00000000000000/* Copyright (C) 2014-2015, 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_bessel_i_asymp_prefactors(acb_t A, acb_t B, acb_t C, const acb_t nu, const acb_t z, int scaled, slong prec) { acb_t t, u; acb_init(t); acb_init(u); /* C = (2 pi z)^(-1/2) */ acb_const_pi(C, prec); acb_mul_2exp_si(C, C, 1); acb_mul(C, C, z, prec); acb_rsqrt(C, C, prec); if (arb_is_positive(acb_imagref(z)) || (arb_is_zero(acb_imagref(z)) && arb_is_negative(acb_realref(z)))) { acb_exp_pi_i(t, nu, prec); acb_mul_onei(t, t); } else if (arb_is_negative(acb_imagref(z)) || (arb_is_zero(acb_imagref(z)) && arb_is_positive(acb_realref(z)))) { acb_neg(t, nu); acb_exp_pi_i(t, t, prec); acb_mul_onei(t, t); acb_neg(t, t); } else { acb_exp_pi_i(t, nu, prec); acb_mul_onei(t, t); acb_neg(u, nu); acb_exp_pi_i(u, u, prec); acb_mul_onei(u, u); acb_neg(u, u); arb_union(acb_realref(t), acb_realref(t), acb_realref(u), prec); arb_union(acb_imagref(t), acb_imagref(t), acb_imagref(u), prec); } if (scaled) { acb_neg(u, z); acb_mul_2exp_si(u, u, 1); acb_exp(u, u, prec); acb_mul(A, t, u, prec); acb_one(B); } else { acb_exp_invexp(B, A, z, prec); acb_mul(A, A, t, prec); } acb_clear(t); acb_clear(u); } void acb_hypgeom_bessel_i_asymp(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { acb_t A1, A2, C, U1, U2, s, t, u; int is_real, is_imag; acb_init(A1); acb_init(A2); acb_init(C); acb_init(U1); acb_init(U2); acb_init(s); acb_init(t); acb_init(u); is_imag = 0; is_real = acb_is_real(nu) && acb_is_real(z) && (acb_is_int(nu) || arb_is_positive(acb_realref(z))); if (!is_real && !scaled && arb_is_zero(acb_realref(z)) && acb_is_int(nu)) { acb_mul_2exp_si(t, nu, -1); if (acb_is_int(t)) is_real = 1; else is_imag = 1; } if (scaled) is_imag = 0; acb_hypgeom_bessel_i_asymp_prefactors(A1, A2, C, nu, z, scaled, prec); /* todo: if Ap ~ 2^a and Am = 2^b and U1 ~ U2 ~ 1, change precision? */ if (!acb_is_finite(A1) || !acb_is_finite(A2) || !acb_is_finite(C)) { acb_indeterminate(res); } else { /* s = 1/2 + nu */ acb_one(s); acb_mul_2exp_si(s, s, -1); acb_add(s, s, nu, prec); /* t = 1 + 2 nu */ acb_mul_2exp_si(t, nu, 1); acb_add_ui(t, t, 1, prec); acb_mul_2exp_si(u, z, 1); acb_hypgeom_u_asymp(U1, s, t, u, -1, prec); acb_neg(u, u); acb_hypgeom_u_asymp(U2, s, t, u, -1, prec); acb_mul(res, A1, U1, prec); acb_addmul(res, A2, U2, prec); acb_mul(res, res, C, prec); if (is_real) arb_zero(acb_imagref(res)); if (is_imag) arb_zero(acb_realref(res)); } acb_clear(A1); acb_clear(A2); acb_clear(C); acb_clear(U1); acb_clear(U2); acb_clear(s); acb_clear(t); acb_clear(u); } void acb_hypgeom_bessel_i_0f1(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { acb_struct b[2]; acb_t w, c, t; if (acb_is_int(nu) && arb_is_negative(acb_realref(nu))) { acb_init(t); acb_neg(t, nu); acb_hypgeom_bessel_i_0f1(res, t, z, scaled, prec); acb_clear(t); return; } acb_init(b + 0); acb_init(b + 1); acb_init(w); acb_init(c); acb_init(t); acb_add_ui(b + 0, nu, 1, prec); acb_one(b + 1); /* (z/2)^nu / gamma(nu+1) */ acb_mul_2exp_si(c, z, -1); acb_pow(c, c, nu, prec); acb_rgamma(t, b + 0, prec); acb_mul(c, t, c, prec); /* z^2/4 */ acb_mul(w, z, z, prec); acb_mul_2exp_si(w, w, -2); acb_hypgeom_pfq_direct(t, NULL, 0, b, 2, w, -1, prec); if (scaled) { acb_neg(w, z); acb_exp(w, w, prec); acb_mul(t, t, w, prec); } acb_mul(res, t, c, prec); acb_clear(b + 0); acb_clear(b + 1); acb_clear(w); acb_clear(c); acb_clear(t); } void acb_hypgeom_bessel_i_nointegration(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { mag_t zmag; mag_init(zmag); acb_get_mag(zmag, z); if (mag_cmp_2exp_si(zmag, 4) < 0 || (mag_cmp_2exp_si(zmag, 64) < 0 && 2 * mag_get_d(zmag) < prec)) acb_hypgeom_bessel_i_0f1(res, nu, z, scaled, prec); else acb_hypgeom_bessel_i_asymp(res, nu, z, scaled, prec); mag_clear(zmag); } void _acb_hypgeom_bessel_i(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { acb_t res2; slong acc, max, t; acb_init(res2); acb_hypgeom_bessel_i_nointegration(res2, nu, z, scaled, prec); acc = acb_rel_accuracy_bits(res2); if (acc < 0.5 * prec) { max = prec; t = acb_rel_accuracy_bits(z); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(nu); max = FLINT_MIN(max, t); if (max > 2 && acc < 0.5 * max) { if (acb_is_real(nu) && acb_is_real(z) && arf_cmp_2exp_si(arb_midref(acb_realref(nu)), -1) > 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(nu)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 60) < 0) { arb_hypgeom_bessel_i_integration(acb_realref(res), acb_realref(nu), acb_realref(z), scaled, prec); arb_zero(acb_imagref(res)); if (acb_rel_accuracy_bits(res) > acb_rel_accuracy_bits(res2) || (acb_is_finite(res) && !acb_is_finite(res2))) { acb_swap(res, res2); } } } } acb_swap(res, res2); acb_clear(res2); } void acb_hypgeom_bessel_i(acb_t res, const acb_t nu, const acb_t z, slong prec) { _acb_hypgeom_bessel_i(res, nu, z, 0, prec); } void acb_hypgeom_bessel_i_scaled(acb_t res, const acb_t nu, const acb_t z, slong prec) { _acb_hypgeom_bessel_i(res, nu, z, 1, prec); } arb-2.22.1/acb_hypgeom/bessel_j.c000066400000000000000000000131301417376376500165720ustar00rootroot00000000000000/* Copyright (C) 2014-2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* assumes no aliasing */ /* (+/- iz)^(-1/2-v) * z^v * exp(+/- iz) */ void acb_hypgeom_bessel_j_asymp_prefactors_fallback(acb_t Ap, acb_t Am, acb_t C, const acb_t nu, const acb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); /* v = -1/2-nu */ acb_one(v); acb_mul_2exp_si(v, v, -1); acb_add(v, v, nu, prec); acb_neg(v, v); acb_mul_onei(t, z); /* t = iz */ acb_neg(u, t); /* u = -iz */ /* Ap, Am = (+/- iz)^(-1/2-nu) */ acb_pow(Ap, t, v, prec); acb_pow(Am, u, v, prec); /* Ap, Am *= exp(+/- iz) */ acb_exp_invexp(u, v, t, prec); acb_mul(Ap, Ap, u, prec); acb_mul(Am, Am, v, prec); /* z^nu */ acb_pow(t, z, nu, prec); acb_mul(Ap, Ap, t, prec); acb_mul(Am, Am, t, prec); /* (2 pi)^(-1/2) */ acb_const_pi(C, prec); acb_mul_2exp_si(C, C, 1); acb_rsqrt(C, C, prec); acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_bessel_j_asymp_prefactors(acb_t Ap, acb_t Am, acb_t C, const acb_t nu, const acb_t z, slong prec) { if (arb_is_positive(acb_realref(z))) { acb_t t, u; acb_init(t); acb_init(u); /* -(2nu+1)/4 * pi + z */ acb_mul_2exp_si(t, nu, 1); acb_add_ui(t, t, 1, prec); acb_mul_2exp_si(t, t, -2); acb_neg(t, t); acb_const_pi(u, prec); acb_mul(t, t, u, prec); acb_add(t, t, z, prec); acb_mul_onei(t, t); acb_exp_invexp(Ap, Am, t, prec); /* (2 pi z)^(-1/2) */ acb_const_pi(C, prec); acb_mul_2exp_si(C, C, 1); acb_mul(C, C, z, prec); acb_rsqrt(C, C, prec); acb_clear(t); acb_clear(u); return; } acb_hypgeom_bessel_j_asymp_prefactors_fallback(Ap, Am, C, nu, z, prec); } void acb_hypgeom_bessel_j_asymp(acb_t res, const acb_t nu, const acb_t z, slong prec) { acb_t A1, A2, C, U1, U2, s, t, u; int is_real, is_imag; /* zero at -inf and +inf when nu is finite */ if (acb_is_finite(nu) && !acb_is_finite(z) && acb_is_real(z) && !acb_contains_zero(z)) { acb_zero(res); return; } acb_init(A1); acb_init(A2); acb_init(C); acb_init(U1); acb_init(U2); acb_init(s); acb_init(t); acb_init(u); is_imag = 0; is_real = acb_is_real(nu) && acb_is_real(z) && (acb_is_int(nu) || arb_is_positive(acb_realref(z))); if (!is_real && arb_is_zero(acb_realref(z)) && acb_is_int(nu)) { acb_mul_2exp_si(t, nu, -1); if (acb_is_int(t)) is_real = 1; else is_imag = 1; } acb_hypgeom_bessel_j_asymp_prefactors(A1, A2, C, nu, z, prec); /* todo: if Ap ~ 2^a and Am = 2^b and U1 ~ U2 ~ 1, change precision? */ if (!acb_is_finite(A1) || !acb_is_finite(A2) || !acb_is_finite(C)) { acb_indeterminate(res); } else { /* s = 1/2 + nu */ acb_one(s); acb_mul_2exp_si(s, s, -1); acb_add(s, s, nu, prec); /* t = 1 + 2 nu */ acb_mul_2exp_si(t, nu, 1); acb_add_ui(t, t, 1, prec); acb_mul_onei(u, z); acb_mul_2exp_si(u, u, 1); acb_hypgeom_u_asymp(U2, s, t, u, -1, prec); acb_neg(u, u); acb_hypgeom_u_asymp(U1, s, t, u, -1, prec); acb_mul(res, A1, U1, prec); acb_addmul(res, A2, U2, prec); acb_mul(res, res, C, prec); if (is_real) arb_zero(acb_imagref(res)); if (is_imag) arb_zero(acb_realref(res)); } acb_clear(A1); acb_clear(A2); acb_clear(C); acb_clear(U1); acb_clear(U2); acb_clear(s); acb_clear(t); acb_clear(u); } void acb_hypgeom_bessel_j_0f1(acb_t res, const acb_t nu, const acb_t z, slong prec) { acb_struct b[2]; acb_t w, c, t; if (acb_is_int(nu) && arb_is_negative(acb_realref(nu))) { acb_init(t); acb_neg(t, nu); acb_hypgeom_bessel_j_0f1(res, t, z, prec); acb_mul_2exp_si(t, t, -1); if (!acb_is_int(t)) acb_neg(res, res); acb_clear(t); return; } acb_init(b + 0); acb_init(b + 1); acb_init(w); acb_init(c); acb_init(t); acb_add_ui(b + 0, nu, 1, prec); acb_one(b + 1); /* (z/2)^nu / gamma(nu+1) */ acb_mul_2exp_si(c, z, -1); acb_pow(c, c, nu, prec); acb_rgamma(t, b + 0, prec); acb_mul(c, t, c, prec); /* -z^2/4 */ acb_mul(w, z, z, prec); acb_mul_2exp_si(w, w, -2); acb_neg(w, w); acb_hypgeom_pfq_direct(t, NULL, 0, b, 2, w, -1, prec); acb_mul(res, t, c, prec); acb_clear(b + 0); acb_clear(b + 1); acb_clear(w); acb_clear(c); acb_clear(t); } /* The asymptotic series can be used roughly when [(1+log(2))/log(2) = 2.44269504088896] * z > p We are a bit more conservative and use the factor 2. */ void acb_hypgeom_bessel_j(acb_t res, const acb_t nu, const acb_t z, slong prec) { mag_t zmag; mag_init(zmag); acb_get_mag(zmag, z); if (mag_cmp_2exp_si(zmag, 4) < 0 || (mag_cmp_2exp_si(zmag, 64) < 0 && 2 * mag_get_d(zmag) < prec)) acb_hypgeom_bessel_j_0f1(res, nu, z, prec); else acb_hypgeom_bessel_j_asymp(res, nu, z, prec); mag_clear(zmag); } arb-2.22.1/acb_hypgeom/bessel_k.c000066400000000000000000000156351417376376500166070ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_bessel_k_asymp(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { acb_t t, a, b, w; acb_init(t); acb_init(a); acb_init(b); acb_init(w); acb_one(a); acb_mul_2exp_si(a, a, -1); acb_add(a, a, nu, prec); acb_mul_2exp_si(b, nu, 1); acb_add_ui(b, b, 1, prec); acb_mul_2exp_si(w, z, 1); acb_hypgeom_u_asymp(t, a, b, w, -1, prec); if (!scaled) { acb_neg(a, z); acb_exp(a, a, prec); acb_mul(t, t, a, prec); } acb_mul_2exp_si(w, z, 1); acb_rsqrt(w, w, prec); acb_mul(res, t, w, prec); arb_const_sqrt_pi(acb_realref(w), prec); acb_mul_arb(res, res, acb_realref(w), prec); acb_clear(t); acb_clear(a); acb_clear(b); acb_clear(w); } void acb_hypgeom_bessel_k_0f1_series(acb_poly_t res, const acb_poly_t nu, const acb_poly_t z, int scaled, slong len, slong prec) { acb_poly_t s, u, A, B; acb_poly_struct b[2]; arb_t c; slong wlen; int singular; acb_poly_init(s); acb_poly_init(u); acb_poly_init(A); acb_poly_init(B); acb_poly_init(b + 0); acb_poly_init(b + 1); arb_init(c); singular = (nu->length == 0) || acb_is_int(nu->coeffs); wlen = len + (singular != 0); /* A = (z/2)^nu, B = 1/A */ acb_poly_scalar_mul_2exp_si(A, z, -1); acb_poly_pow_series(A, A, nu, wlen, prec); acb_poly_inv_series(B, A, wlen, prec); acb_poly_mullow(u, z, z, wlen, prec); acb_poly_scalar_mul_2exp_si(u, u, -2); acb_poly_one(b + 1); acb_poly_add_si(b + 0, nu, 1, prec); acb_hypgeom_pfq_series_direct(s, NULL, 0, b, 2, u, 1, -1, wlen, prec); acb_poly_mullow(A, A, s, wlen, prec); acb_poly_add_si(b + 0, nu, -1, prec); acb_poly_neg(b + 0, b + 0); acb_hypgeom_pfq_series_direct(s, NULL, 0, b, 2, u, 1, -1, wlen, prec); acb_poly_mullow(B, B, s, wlen, prec); acb_poly_sub(A, B, A, prec); acb_poly_scalar_mul_2exp_si(A, A, -1); /* multiply by pi csc(pi nu) */ acb_poly_sin_pi_series(B, nu, wlen, prec); if (singular) { acb_poly_shift_right(A, A, 1); acb_poly_shift_right(B, B, 1); } if (scaled) { acb_poly_exp_series(u, z, len, prec); acb_poly_mullow(A, A, u, len, prec); } acb_poly_div_series(res, A, B, len, prec); arb_const_pi(c, prec); _acb_vec_scalar_mul_arb(res->coeffs, res->coeffs, res->length, c, prec); acb_poly_clear(s); acb_poly_clear(u); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(b + 0); acb_poly_clear(b + 1); arb_clear(c); } void acb_hypgeom_bessel_k_0f1(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { if (acb_is_int(nu)) { acb_poly_t nux, zx, rx; acb_poly_init(nux); acb_poly_init(zx); acb_poly_init(rx); acb_poly_set_coeff_acb(nux, 0, nu); acb_poly_set_coeff_si(nux, 1, 1); acb_poly_set_acb(zx, z); acb_hypgeom_bessel_k_0f1_series(rx, nux, zx, scaled, 1, prec); acb_poly_get_coeff_acb(res, rx, 0); acb_poly_clear(nux); acb_poly_clear(zx); acb_poly_clear(rx); } else { acb_t t, u, v, w; acb_struct b[2]; acb_init(t); acb_init(u); acb_init(v); acb_init(w); acb_init(b + 0); acb_init(b + 1); /* u = 0F1(1+nu), v = 0F1(1-nu) */ acb_mul(t, z, z, prec); acb_mul_2exp_si(t, t, -2); acb_add_ui(b, nu, 1, prec); acb_one(b + 1); acb_hypgeom_pfq_direct(u, NULL, 0, b, 2, t, -1, prec); acb_sub_ui(b, nu, 1, prec); acb_neg(b, b); acb_hypgeom_pfq_direct(v, NULL, 0, b, 2, t, -1, prec); /* v = v * gamma(nu) / (z/2)^nu */ acb_mul_2exp_si(t, z, -1); acb_pow(t, t, nu, prec); acb_gamma(w, nu, prec); acb_mul(v, v, w, prec); acb_div(v, v, t, prec); /* u = u * t * pi / (gamma(nu) * nu * sin(pi nu)) */ acb_mul(u, u, t, prec); acb_const_pi(t, prec); acb_mul(u, u, t, prec); acb_sin_pi(t, nu, prec); acb_mul(t, t, w, prec); acb_mul(t, t, nu, prec); acb_div(u, u, t, prec); acb_sub(v, v, u, prec); acb_mul_2exp_si(v, v, -1); if (scaled) { acb_exp(t, z, prec); acb_mul(v, v, t, prec); } acb_set(res, v); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(w); acb_clear(b + 0); acb_clear(b + 1); } } void acb_hypgeom_bessel_k_nointegration(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { mag_t zmag; mag_init(zmag); acb_get_mag(zmag, z); if (mag_cmp_2exp_si(zmag, 4) < 0 || (mag_cmp_2exp_si(zmag, 64) < 0 && 2 * mag_get_d(zmag) < prec)) acb_hypgeom_bessel_k_0f1(res, nu, z, scaled, prec); else acb_hypgeom_bessel_k_asymp(res, nu, z, scaled, prec); mag_clear(zmag); } void _acb_hypgeom_bessel_k(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) { acb_t res2; slong acc, max, t; acb_init(res2); acb_hypgeom_bessel_k_nointegration(res2, nu, z, scaled, prec); acc = acb_rel_accuracy_bits(res2); if (acc < 0.5 * prec) { max = prec; t = acb_rel_accuracy_bits(z); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(nu); max = FLINT_MIN(max, t); if (max > 2 && acc < 0.5 * max) { if (acb_is_real(nu) && acb_is_real(z) && arf_cmp_d(arb_midref(acb_realref(nu)), -0.5) > 0 && arf_cmp_2exp_si(arb_midref(acb_realref(z)), -16) > 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(nu)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 60) < 0) { arb_hypgeom_bessel_k_integration(acb_realref(res), acb_realref(nu), acb_realref(z), scaled, prec); arb_zero(acb_imagref(res)); if (acb_rel_accuracy_bits(res) > acb_rel_accuracy_bits(res2) || (acb_is_finite(res) && !acb_is_finite(res2))) { acb_swap(res, res2); } } } } acb_swap(res, res2); acb_clear(res2); } void acb_hypgeom_bessel_k(acb_t res, const acb_t nu, const acb_t z, slong prec) { _acb_hypgeom_bessel_k(res, nu, z, 0, prec); } void acb_hypgeom_bessel_k_scaled(acb_t res, const acb_t nu, const acb_t z, slong prec) { _acb_hypgeom_bessel_k(res, nu, z, 1, prec); } arb-2.22.1/acb_hypgeom/bessel_y.c000066400000000000000000000047761417376376500166310ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void phase(acb_t res, const arb_t re, const arb_t im) { if (arb_is_nonnegative(re) || arb_is_negative(im)) { acb_one(res); } else if (arb_is_negative(re) && arb_is_nonnegative(im)) { acb_set_si(res, -3); } else { arb_zero(acb_imagref(res)); /* -1 +/- 2 */ arf_set_si(arb_midref(acb_realref(res)), -1); mag_one(arb_radref(acb_realref(res))); mag_mul_2exp_si(arb_radref(acb_realref(res)), arb_radref(acb_realref(res)), 1); } } void acb_hypgeom_bessel_jy(acb_t res1, acb_t res2, const acb_t nu, const acb_t z, slong prec) { acb_t jnu, t, u, v; /* both j and y are zero at -inf and +inf when nu is finite */ if (acb_is_finite(nu) && !acb_is_finite(z) && acb_is_real(z) && !acb_contains_zero(z)) { if (res1 != NULL) acb_zero(res1); acb_zero(res2); return; } acb_init(jnu); acb_init(t); acb_init(u); acb_init(v); acb_hypgeom_bessel_j(jnu, nu, z, prec); if (acb_is_int(nu)) { int is_real = acb_is_real(nu) && acb_is_real(z) && arb_is_positive(acb_realref(z)); acb_mul_onei(t, z); acb_hypgeom_bessel_k(t, nu, t, prec); acb_onei(u); acb_pow(u, u, nu, prec); acb_mul(t, t, u, prec); acb_const_pi(u, prec); acb_div(t, t, u, prec); acb_mul_2exp_si(t, t, 1); acb_neg(t, t); phase(v, acb_realref(z), acb_imagref(z)); acb_mul(u, jnu, v, prec); acb_mul_onei(u, u); acb_sub(res2, t, u, prec); if (is_real) arb_zero(acb_imagref(res2)); } else { acb_sin_cos_pi(t, u, nu, prec); acb_mul(v, jnu, u, prec); acb_neg(u, nu); acb_hypgeom_bessel_j(u, u, z, prec); acb_sub(v, v, u, prec); acb_div(res2, v, t, prec); } if (res1 != NULL) acb_set(res1, jnu); acb_clear(jnu); acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_bessel_y(acb_t res, const acb_t nu, const acb_t z, slong prec) { acb_hypgeom_bessel_jy(NULL, res, nu, z, prec); } arb-2.22.1/acb_hypgeom/beta_lower.c000066400000000000000000000034261417376376500171360ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* todo: move this to the acb module? */ static void acb_beta(acb_t res, const acb_t a, const acb_t b, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_gamma(t, a, prec); acb_gamma(u, b, prec); acb_add(res, a, b, prec); acb_rgamma(res, res, prec); acb_mul(res, res, t, prec); acb_mul(res, res, u, prec); acb_clear(t); acb_clear(u); } void acb_hypgeom_beta_lower(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { acb_t t, u; if (acb_is_zero(z) && arb_is_positive(acb_realref(a))) { acb_zero(res); return; } if (acb_is_one(z) && arb_is_positive(acb_realref(b))) { if (regularized) acb_one(res); else acb_beta(res, a, b, prec); return; } acb_init(t); acb_init(u); acb_sub_ui(t, b, 1, prec); acb_neg(t, t); acb_add_ui(u, a, 1, prec); if (regularized) { acb_hypgeom_2f1(t, a, t, u, z, 1, prec); acb_add(u, a, b, prec); acb_gamma(u, u, prec); acb_mul(t, t, u, prec); acb_rgamma(u, b, prec); acb_mul(t, t, u, prec); } else { acb_hypgeom_2f1(t, a, t, u, z, 0, prec); acb_div(t, t, a, prec); } acb_pow(u, z, a, prec); acb_mul(t, t, u, prec); acb_set(res, t); acb_clear(t); acb_clear(u); } arb-2.22.1/acb_hypgeom/beta_lower_series.c000066400000000000000000000054701417376376500205110ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_beta_lower_series(acb_ptr res, const acb_t a, const acb_t b, acb_srcptr z, slong zlen, int regularized, slong len, slong prec) { acb_ptr t, u, v; acb_t c, d, e; zlen = FLINT_MIN(zlen, len); if (zlen == 1) { acb_hypgeom_beta_lower(res, a, b, z, regularized, prec); _acb_vec_zero(res + 1, len - 1); return; } t = _acb_vec_init(len); u = _acb_vec_init(len); v = _acb_vec_init(zlen - 1); acb_init(c); acb_init(d); acb_init(e); acb_hypgeom_beta_lower(d, a, b, z, regularized, prec); if (regularized) { /* todo: except in special cases, we already compute a bunch of gamma functions in beta_lower, so we could avoid recomputing them */ acb_add(e, a, b, prec); acb_gamma(e, e, prec); acb_rgamma(c, a, prec); acb_mul(e, e, c, prec); acb_rgamma(c, b, prec); acb_mul(e, e, c, prec); } /* u = (1-z)^(b-1) */ _acb_vec_neg(t, z, zlen); acb_add_ui(t, t, 1, prec); acb_sub_ui(c, b, 1, prec); _acb_poly_pow_acb_series(u, t, FLINT_MIN(zlen, len - 1), c, len - 1, prec); /* t = z^(a-1) */ acb_sub_ui(c, a, 1, prec); _acb_poly_pow_acb_series(t, z, FLINT_MIN(zlen, len - 1), c, len - 1, prec); /* v = z' */ _acb_poly_derivative(v, z, zlen, prec); _acb_poly_mullow(res, t, len - 1, u, len - 1, len - 1, prec); _acb_poly_mullow(t, res, len - 1, v, zlen - 1, len - 1, prec); _acb_poly_integral(res, t, len, prec); if (regularized) { _acb_vec_scalar_mul(res, res, len, e, prec); } acb_set(res, d); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(v, zlen - 1); acb_clear(c); acb_clear(d); acb_clear(e); } void acb_hypgeom_beta_lower_series(acb_poly_t res, const acb_t a, const acb_t b, const acb_poly_t z, int regularized, slong len, slong prec) { if (len == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, len); if (z->length == 0) { acb_t t; acb_init(t); _acb_hypgeom_beta_lower_series(res->coeffs, a, b, t, 1, regularized, len, prec); acb_clear(t); } else { _acb_hypgeom_beta_lower_series(res->coeffs, a, b, z->coeffs, z->length, regularized, len, prec); } _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_hypgeom/chebyshev_t.c000066400000000000000000000037121417376376500173140ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_chebyshev_t(acb_t res, const acb_t n, const acb_t z, slong prec) { acb_t t; if (acb_is_int(n) && arf_cmpabs_2exp_si(arb_midref(acb_realref(n)), FLINT_BITS - 1) < 0) { slong k = arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN); acb_chebyshev_t_ui(res, FLINT_ABS(k), z, prec); return; } if (acb_is_zero(z)) { acb_mul_2exp_si(res, n, -1); acb_cos_pi(res, res, prec); return; } if (acb_is_one(z)) { acb_one(res); return; } acb_init(t); acb_set_si(t, -1); if (acb_equal(t, z)) { acb_cos_pi(res, n, prec); } else { acb_sub_ui(t, z, 1, prec); if (arf_cmpabs_2exp_si(arb_midref(acb_realref(t)), -2 - prec / 10) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(t)), -2 - prec / 10) < 0) { acb_t a, c; acb_init(a); acb_init(c); acb_neg(a, n); acb_one(c); acb_mul_2exp_si(c, c, -1); acb_neg(t, t); acb_mul_2exp_si(t, t, -1); acb_hypgeom_2f1(res, a, n, c, t, 0, prec); acb_clear(a); acb_clear(c); } else if (arb_is_nonnegative(acb_realref(t))) { acb_acosh(t, z, prec); acb_mul(t, t, n, prec); acb_cosh(res, t, prec); } else { acb_acos(t, z, prec); acb_mul(t, t, n, prec); acb_cos(res, t, prec); } } acb_clear(t); } arb-2.22.1/acb_hypgeom/chebyshev_u.c000066400000000000000000000052631417376376500173200ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_chebyshev_u(acb_t res, const acb_t n, const acb_t z, slong prec) { acb_t t, u; if (acb_is_int(n) && arf_cmpabs_2exp_si(arb_midref(acb_realref(n)), FLINT_BITS - 1) < 0) { slong k = arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN); if (k >= 0) { acb_chebyshev_u_ui(res, k, z, prec); } else if (k == -1) { acb_zero(res); } else { acb_chebyshev_u_ui(res, -2-k, z, prec); acb_neg(res, res); } return; } if (acb_is_zero(z)) { acb_mul_2exp_si(res, n, -1); acb_cos_pi(res, res, prec); return; } if (acb_is_one(z)) { acb_add_ui(res, n, 1, prec); return; } acb_init(t); acb_init(u); acb_add_ui(u, n, 1, prec); acb_sub_ui(t, z, 1, prec); if (arf_cmpabs_2exp_si(arb_midref(acb_realref(t)), -2 - prec / 10) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(t)), -2 - prec / 10) < 0) { acb_t a, b, c; acb_init(a); acb_init(b); acb_init(c); acb_neg(a, n); acb_add_ui(b, n, 2, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_neg(t, t); acb_mul_2exp_si(t, t, -1); acb_hypgeom_2f1(t, a, b, c, t, 0, prec); acb_mul(res, t, u, prec); acb_clear(a); acb_clear(b); acb_clear(c); } else { if (arb_is_positive(acb_realref(t))) { /* sinh((n+1) acosh(z)) / (sqrt(z-1) sqrt(z+1)); can use one square root when strictly in the right half plane */ acb_mul(t, z, z, prec); acb_sub_ui(t, t, 1, prec); acb_acosh(res, z, prec); acb_mul(res, res, u, prec); acb_sinh(res, res, prec); acb_rsqrt(t, t, prec); acb_mul(res, res, t, prec); } else { acb_mul(t, z, z, prec); acb_sub_ui(t, t, 1, prec); acb_acos(res, z, prec); acb_mul(res, res, u, prec); acb_sin(res, res, prec); acb_neg(t, t); acb_rsqrt(t, t, prec); acb_mul(res, res, t, prec); } } acb_clear(t); acb_clear(u); } arb-2.22.1/acb_hypgeom/chi.c000066400000000000000000000067271417376376500155650ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_chi_asymp(acb_t res, const acb_t z, slong prec) { acb_t t, u, v, one; acb_init(t); acb_init(u); acb_init(v); acb_init(one); acb_one(one); /* u = U(1,1,z) */ acb_hypgeom_u_asymp(u, one, one, z, -1, prec); /* v = e^(-z) */ acb_neg(v, z); acb_exp(v, v, prec); acb_mul(t, u, v, prec); if (arb_is_zero(acb_realref(z))) { arb_div(acb_realref(t), acb_imagref(t), acb_imagref(z), prec); arb_zero(acb_imagref(t)); acb_neg(t, t); } else { /* u = U(1,1,-z) */ acb_neg(u, z); acb_hypgeom_u_asymp(u, one, one, u, -1, prec); acb_inv(v, v, prec); acb_submul(t, u, v, prec); acb_div(t, t, z, prec); acb_mul_2exp_si(t, t, -1); acb_neg(t, t); } if (acb_is_real(z)) { if (arb_is_positive(acb_realref(z))) { arb_zero(acb_imagref(t)); } else if (arb_is_negative(acb_realref(z))) { arb_const_pi(acb_imagref(t), prec); } else { /* add [-pi,pi]/2 i */ acb_const_pi(u, prec); arb_zero(acb_imagref(t)); arb_add_error(acb_imagref(t), acb_realref(u)); } } else { /* -pi/2 if positive real or in lower half plane pi/2 if negative real or in upper half plane */ if (arb_is_negative(acb_imagref(z))) { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_sub(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else if (arb_is_positive(acb_imagref(z))) { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_add(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else { /* add [-pi,pi]/2 i */ acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_add_error(acb_imagref(t), acb_realref(u)); } } acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(one); } void acb_hypgeom_chi_2f3(acb_t res, const acb_t z, slong prec) { acb_t a, t, u; acb_struct b[3]; acb_init(a); acb_init(b); acb_init(b + 1); acb_init(b + 2); acb_init(t); acb_init(u); acb_one(a); acb_set_ui(b, 2); acb_set(b + 1, b); acb_set_ui(b + 2, 3); acb_mul_2exp_si(b + 2, b + 2, -1); acb_mul(t, z, z, prec); acb_mul_2exp_si(t, t, -2); acb_hypgeom_pfq_direct(u, a, 1, b, 3, t, -1, prec); acb_mul(u, u, t, prec); acb_log(t, z, prec); acb_add(u, u, t, prec); arb_const_euler(acb_realref(t), prec); arb_add(acb_realref(u), acb_realref(u), acb_realref(t), prec); acb_swap(res, u); acb_clear(a); acb_clear(b); acb_clear(b + 1); acb_clear(b + 2); acb_clear(t); acb_clear(u); } void acb_hypgeom_chi(acb_t res, const acb_t z, slong prec) { if (acb_hypgeom_u_use_asymp(z, prec)) acb_hypgeom_chi_asymp(res, z, prec); else acb_hypgeom_chi_2f3(res, z, prec); } arb-2.22.1/acb_hypgeom/chi_series.c000066400000000000000000000034661417376376500171340ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_chi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { acb_t c; if (acb_contains_zero(h)) { _acb_vec_indeterminate(g, len); return; } acb_init(c); acb_hypgeom_chi(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else { acb_ptr t, u, v; t = _acb_vec_init(len); u = _acb_vec_init(len); v = _acb_vec_init(len); /* Chi(h(x)) = integral([h'(x) / h(x)] cosh(h(x)) */ _acb_poly_cosh_series(t, h, hlen, len - 1, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_mullow(v, t, len - 1, u, len - 1, len - 1, prec); _acb_poly_div_series(u, v, len - 1, h, hlen, len - 1, prec); _acb_poly_integral(g, u, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(v, len); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_chi_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_inv_series(g, h, len, prec); return; } acb_poly_fit_length(g, len); _acb_hypgeom_chi_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/ci.c000066400000000000000000000106531417376376500154060ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_ci_asymp(acb_t res, const acb_t z, slong prec) { acb_t t, u, w, v, one; acb_init(t); acb_init(u); acb_init(w); acb_init(v); acb_init(one); acb_one(one); acb_mul_onei(w, z); /* u = U(1,1,iz) */ acb_hypgeom_u_asymp(u, one, one, w, -1, prec); /* v = e^(-iz) */ acb_neg(v, w); acb_exp(v, v, prec); acb_mul(t, u, v, prec); if (acb_is_real(z)) { arb_div(acb_realref(t), acb_imagref(t), acb_realref(z), prec); arb_zero(acb_imagref(t)); acb_neg(t, t); } else { /* u = U(1,1,-iz) */ acb_neg(w, w); acb_hypgeom_u_asymp(u, one, one, w, -1, prec); acb_inv(v, v, prec); acb_submul(t, u, v, prec); acb_div(t, t, w, prec); acb_mul_2exp_si(t, t, -1); } if (arb_is_zero(acb_realref(z))) { if (arb_is_positive(acb_imagref(z))) { arb_const_pi(acb_imagref(t), prec); arb_mul_2exp_si(acb_imagref(t), acb_imagref(t), -1); } else if (arb_is_negative(acb_imagref(z))) { arb_const_pi(acb_imagref(t), prec); arb_mul_2exp_si(acb_imagref(t), acb_imagref(t), -1); arb_neg(acb_imagref(t), acb_imagref(t)); } else { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_zero(acb_imagref(t)); arb_add_error(acb_imagref(t), acb_realref(u)); } } else { /* 0 if positive or positive imaginary pi if upper left quadrant (including negative real axis) -pi if lower left quadrant (including negative imaginary axis) */ if (arb_is_positive(acb_realref(z))) { /* do nothing */ } else if (arb_is_negative(acb_realref(z)) && arb_is_nonnegative(acb_imagref(z))) { acb_const_pi(u, prec); arb_add(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else if (arb_is_nonpositive(acb_realref(z)) && arb_is_negative(acb_imagref(z))) { acb_const_pi(u, prec); arb_sub(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else { /* add [-pi,pi] */ acb_const_pi(u, prec); arb_add_error(acb_imagref(t), acb_realref(u)); } } acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(w); acb_clear(v); acb_clear(one); } void acb_hypgeom_ci_2f3(acb_t res, const acb_t z, slong prec) { acb_t a, t, u; acb_struct b[3]; acb_init(a); acb_init(b); acb_init(b + 1); acb_init(b + 2); acb_init(t); acb_init(u); acb_one(a); acb_set_ui(b, 2); acb_set(b + 1, b); acb_set_ui(b + 2, 3); acb_mul_2exp_si(b + 2, b + 2, -1); acb_mul(t, z, z, prec); acb_mul_2exp_si(t, t, -2); acb_neg(t, t); acb_hypgeom_pfq_direct(u, a, 1, b, 3, t, -1, prec); acb_mul(u, u, t, prec); acb_log(t, z, prec); acb_add(u, u, t, prec); arb_const_euler(acb_realref(t), prec); arb_add(acb_realref(u), acb_realref(u), acb_realref(t), prec); acb_swap(res, u); acb_clear(a); acb_clear(b); acb_clear(b + 1); acb_clear(b + 2); acb_clear(t); acb_clear(u); } void acb_hypgeom_ci(acb_t res, const acb_t z, slong prec) { if (acb_is_real(z) && arb_is_finite(acb_realref(z))) { if (arb_is_positive(acb_realref(z))) { arb_hypgeom_ci(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); } else if (arb_is_negative(acb_realref(z))) { arb_neg(acb_realref(res), acb_realref(z)); arb_hypgeom_ci(acb_realref(res), acb_realref(res), prec); arb_const_pi(acb_imagref(res), prec); } else { acb_indeterminate(res); } return; } if (acb_hypgeom_u_use_asymp(z, prec)) acb_hypgeom_ci_asymp(res, z, prec); else acb_hypgeom_ci_2f3(res, z, prec); } arb-2.22.1/acb_hypgeom/ci_series.c000066400000000000000000000034571417376376500167640ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_ci_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { acb_t c; if (acb_contains_zero(h)) { _acb_vec_indeterminate(g, len); return; } acb_init(c); acb_hypgeom_ci(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else { acb_ptr t, u, v; t = _acb_vec_init(len); u = _acb_vec_init(len); v = _acb_vec_init(len); /* Ci(h(x)) = integral([h'(x) / h(x)] cos(h(x)) */ _acb_poly_cos_series(t, h, hlen, len - 1, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_mullow(v, t, len - 1, u, len - 1, len - 1, prec); _acb_poly_div_series(u, v, len - 1, h, hlen, len - 1, prec); _acb_poly_integral(g, u, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(v, len); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_ci_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_inv_series(g, h, len, prec); return; } acb_poly_fit_length(g, len); _acb_hypgeom_ci_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/coulomb.c000066400000000000000000000230311417376376500164450ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void acb_hypgeom_coulomb_is_real(int * C, int * F, int * G, const acb_t l1, const acb_t eta, const acb_t z) { *C = *F = *G = 0; if (acb_is_real(l1) && acb_is_real(eta)) { if (arb_is_positive(acb_realref(l1)) || arb_is_nonzero(acb_realref(eta))) { *C = 1; } if (acb_is_real(z)) { if (arb_is_positive(acb_realref(z))) { *F = *G = 1; } if (acb_is_int(l1)) *F = 1; } } } void _acb_hypgeom_coulomb(acb_t F, acb_t G, acb_t Hpos, acb_t Hneg, const acb_t l, const acb_t eta, const acb_t z, int asymp, slong prec) { acb_t u, v, lu, lv, z1, z2, m, h, T1, T2, U1, U2, H1, H2, C, theta; int C_real, F_real, G_real; int want_U1, want_U2, cut; acb_init(u); acb_init(v); acb_init(lu); acb_init(lv); acb_init(z1); acb_init(z2); acb_init(m); acb_init(h); acb_init(T1); acb_init(T2); acb_init(U1); acb_init(U2); acb_init(H1); acb_init(H2); acb_init(C); acb_init(theta); acb_indeterminate(U1); acb_indeterminate(U2); /* z1 = 2iz, z2 = -2iz, */ acb_mul_onei(z1, z); acb_mul_2exp_si(z1, z1, 1); acb_neg(z2, z1); if (asymp == -1) asymp = acb_hypgeom_u_use_asymp(z1, prec); /* Need the union of both sides of the branch cut for G, H+, H-. */ if (arb_is_nonnegative(acb_imagref(z)) || arb_is_negative(acb_imagref(z)) || arb_is_positive(acb_realref(z))) cut = 0; else cut = 1; want_U1 = want_U2 = 0; if (asymp) { want_U1 = want_U2 = 1; } else { if (G != NULL || Hpos != NULL || Hneg != NULL) { if (arf_sgn(arb_midref(acb_imagref(z))) >= 0) want_U1 = 1; else want_U2 = 1; if (cut) want_U1 = want_U2 = 1; } } /* m = l+1 */ acb_add_ui(m, l, 1, prec); acb_hypgeom_coulomb_is_real(&C_real, &F_real, &G_real, m, eta, z); /* u = 1+l+i eta, v = 1+l-i eta */ acb_mul_onei(u, eta); acb_add(u, u, m, prec); acb_div_onei(v, eta); acb_add(v, v, m, prec); /* lu = lgamma(u), v = lgamma(v) */ acb_lgamma(lu, u, prec); if (C_real) acb_conj(lv, lu); else acb_lgamma(lv, v, prec); /* m = 2l+2 */ acb_mul_2exp_si(m, m, 1); if (asymp) { if (want_U1 && want_U2 && G_real) { acb_hypgeom_u_asymp(U1, u, m, z2, -1, prec); acb_conj(U2, U1); } else { if (want_U1) acb_hypgeom_u_asymp(U1, u, m, z2, -1, prec); if (want_U2) acb_hypgeom_u_asymp(U2, v, m, z1, -1, prec); } } else { if (want_U1 && want_U2 && G_real) { acb_hypgeom_u(U1, u, m, z2, prec); acb_pow(h, z2, u, prec); acb_mul(U1, U1, h, prec); acb_conj(U2, U1); } else { if (want_U1) { acb_hypgeom_u(U1, u, m, z2, prec); acb_pow(h, z2, u, prec); acb_mul(U1, U1, h, prec); } if (want_U2) { acb_hypgeom_u(U2, v, m, z1, prec); acb_pow(h, z1, v, prec); acb_mul(U2, U2, h, prec); } } } /* C = exp((-pi eta + lu + lv)/2) */ acb_const_pi(C, prec); acb_mul(C, C, eta, prec); acb_neg(C, C); if (C_real) { acb_mul_2exp_si(T1, lu, 1); arb_zero(acb_imagref(T1)); acb_add(C, C, T1, prec); } else { acb_add(C, C, lu, prec); acb_add(C, C, lv, prec); } acb_mul_2exp_si(C, C, -1); /* http://fungrim.org/entry/1976e1/ */ if (asymp) { /* T1 = exp(-(-iz + lv + u log(z1)) U1 */ /* T2 = exp(-(+iz + lu + v log(z2)) U2 */ acb_log(T1, z1, prec); acb_mul(T1, T1, u, prec); acb_add(T1, T1, lv, prec); acb_mul_2exp_si(z1, z1, -1); acb_sub(T1, T1, z1, prec); acb_mul_2exp_si(z1, z1, 1); acb_neg(T1, T1); acb_exp(T1, T1, prec); acb_mul(T1, T1, U1, prec); if (F_real) { acb_mul_2exp_si(F, T1, 1); arb_zero(acb_imagref(F)); } else { acb_log(T2, z2, prec); acb_mul(T2, T2, v, prec); acb_add(T2, T2, lu, prec); acb_mul_2exp_si(z2, z2, -1); acb_sub(T2, T2, z2, prec); acb_mul_2exp_si(z2, z2, 1); acb_neg(T2, T2); acb_exp(T2, T2, prec); acb_mul(T2, T2, U2, prec); /* F = (T1 + T2) z C */ acb_add(F, T1, T2, prec); } } else { /* C *= exp(-iz) */ acb_div_onei(F, z); acb_add(C, C, F, prec); /* http://fungrim.org/entry/2a2f18/ */ acb_hypgeom_m(F, v, m, z1, 1, prec); } if (acb_contains_zero(z)) { acb_exp(C, C, prec); /* (2z)^l without logarithm */ acb_mul_2exp_si(h, z, 1); acb_pow(h, h, l, prec); acb_mul(C, C, h, prec); /* h = log(2z) */ acb_indeterminate(h); } else { /* h = log(2z) */ acb_mul_2exp_si(h, z, 1); acb_log(h, h, prec); acb_addmul(C, h, l, prec); acb_exp(C, C, prec); } acb_mul(F, F, C, prec); if (F_real) arb_zero(acb_imagref(F)); acb_mul(F, F, z, prec); if (G != NULL || Hpos != NULL || Hneg != NULL) { /* theta = z - eta h - 0.5 l pi + (lu - lv) / (2i) */ acb_sub(theta, lu, lv, prec); acb_div_onei(theta, theta); acb_mul_2exp_si(theta, theta, -1); acb_const_pi(H1, prec); acb_mul_2exp_si(H1, H1, -1); acb_submul(theta, H1, l, prec); acb_submul(theta, eta, h, prec); acb_add(theta, theta, z, prec); /* H1 = exp(+i theta) U1, H2 = exp(-i theta) U2 */ acb_mul_onei(H1, theta); acb_exp_invexp(H1, H2, H1, prec); acb_mul(H1, H1, U1, prec); acb_mul(H2, H2, U2, prec); if (G != NULL) { /* http://fungrim.org/entry/e2efbf/ */ if (asymp && arb_is_positive(acb_realref(z))) { if (G_real) { if (arf_sgn(arb_midref(acb_imagref(z))) >= 0) acb_set(G, H1); else acb_set(G, H2); arb_zero(acb_imagref(G)); } else { acb_add(G, H1, H2, prec); acb_mul_2exp_si(G, G, -1); } } else { /* http://fungrim.org/entry/8027e8/ */ acb_div_onei(u, F); acb_add(u, H1, u, prec); /* http://fungrim.org/entry/69e5fb/ */ acb_mul_onei(v, F); acb_add(v, H2, v, prec); if (cut) acb_union(G, u, v, prec); else if (arf_sgn(arb_midref(acb_imagref(z))) >= 0) acb_set(G, u); else acb_set(G, v); if (G_real) arb_zero(acb_imagref(G)); } } if (Hpos != NULL) { /* http://fungrim.org/entry/bcdfc6/ */ acb_set(u, H1); /* http://fungrim.org/entry/f0414a/ */ acb_mul_onei(v, F); acb_mul_2exp_si(v, v, 1); acb_add(v, H2, v, prec); if (cut) acb_union(Hpos, u, v, prec); else if (arf_sgn(arb_midref(acb_imagref(z))) >= 0) acb_set(Hpos, u); else acb_set(Hpos, v); if (G_real) arb_set(acb_imagref(Hpos), acb_realref(F)); } if (Hneg != NULL) { /* http://fungrim.org/entry/0cc301/ */ acb_div_onei(u, F); acb_mul_2exp_si(u, u, 1); acb_add(u, H1, u, prec); /* http://fungrim.org/entry/781eae/ */ acb_set(v, H2); if (cut) acb_union(Hneg, u, v, prec); else if (arf_sgn(arb_midref(acb_imagref(z))) >= 0) acb_set(Hneg, u); else acb_set(Hneg, v); if (G_real) arb_neg(acb_imagref(Hneg), acb_realref(F)); } } acb_clear(u); acb_clear(v); acb_clear(lu); acb_clear(lv); acb_clear(z1); acb_clear(z2); acb_clear(m); acb_clear(h); acb_clear(T1); acb_clear(T2); acb_clear(U1); acb_clear(U2); acb_clear(H1); acb_clear(H2); acb_clear(C); acb_clear(theta); } void acb_hypgeom_coulomb(acb_t F, acb_t G, acb_t Hpos, acb_t Hneg, const acb_t l, const acb_t eta, const acb_t z, slong prec) { /* We always compute F. Also handle aliasing. */ acb_t F2, l2, eta2, z2; acb_init(F2); acb_init(l2); acb_init(eta2); acb_init(z2); acb_set(l2, l); acb_set(eta2, eta); acb_set(z2, z); _acb_hypgeom_coulomb(F2, G, Hpos, Hneg, l2, eta2, z2, -1, prec); if (F != NULL) acb_set(F, F2); acb_clear(F2); acb_clear(l2); acb_clear(eta2); acb_clear(z2); } arb-2.22.1/acb_hypgeom/coulomb_jet.c000066400000000000000000000242621417376376500173160ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* need special case for integer l and z = 0 since the recurrence relations break down */ static void _acb_hypgeom_coulomb_f_int_jet(acb_ptr F, const acb_t l, const acb_t eta, const acb_t z, slong len, slong prec) { acb_poly_struct a[1]; acb_poly_struct b[2]; acb_poly_t zx, M, zxi; acb_t t; slong k; int real; if (arf_cmp_si(arb_midref(acb_realref(l)), -1) < 0) { _acb_vec_indeterminate(F, len); return; } /* http://fungrim.org/entry/2a2f18/ */ /* F = C * (z+x)^(l+1) e^(-+ i (z+x)) M(l + 1 -+ i eta, 2l+2, +- 2 i (z+x)) */ acb_poly_init(a); acb_poly_init(b); acb_poly_init(b + 1); acb_poly_init(zx); acb_poly_init(M); acb_poly_init(zxi); acb_init(t); acb_poly_set_coeff_acb(zx, 0, z); acb_poly_set_coeff_si(zx, 1, 1); acb_div_onei(t, eta); acb_add(t, t, l, prec); acb_add_ui(t, t, 1, prec); acb_poly_set_acb(a, t); acb_add_ui(t, l, 1, prec); acb_mul_2exp_si(t, t, 1); acb_poly_set_acb(b, t); acb_poly_one(b + 1); acb_onei(t); acb_mul_2exp_si(t, t, 1); acb_poly_scalar_mul(zxi, zx, t, prec); acb_hypgeom_pfq_series_direct(M, a, 1, b, 2, zxi, 1, -1, len, prec); acb_poly_scalar_mul_2exp_si(zxi, zxi, -1); acb_poly_neg(zxi, zxi); acb_poly_exp_series(zxi, zxi, len, prec); acb_poly_mullow(M, M, zxi, len, prec); acb_add_ui(t, l, 1, prec); acb_poly_pow_acb_series(zxi, zx, t, len, prec); acb_poly_mullow(M, M, zxi, len, prec); { /* C = 2^l exp((-pi eta + lu + lv)/2) */ acb_t C, lu, lv; acb_init(C); acb_init(lu); acb_init(lv); acb_add_ui(lu, l, 1, prec); acb_mul_onei(t, eta); acb_add(lu, lu, t, prec); acb_add_ui(lv, l, 1, prec); acb_div_onei(t, eta); acb_add(lv, lv, t, prec); acb_lgamma(lu, lu, prec); acb_lgamma(lv, lv, prec); acb_const_pi(t, prec); acb_add(C, lu, lv, prec); acb_submul(C, t, eta, prec); acb_mul_2exp_si(C, C, -1); acb_exp(C, C, prec); acb_set_ui(t, 2); acb_pow(t, t, l, prec); acb_mul(C, C, t, prec); acb_poly_scalar_mul(M, M, C, prec); acb_clear(C); acb_clear(lu); acb_clear(lv); } real = acb_is_real(z) && acb_is_real(eta); for (k = 0; k < len; k++) { acb_poly_get_coeff_acb(F + k, M, k); if (real) arb_zero(acb_imagref(F + k)); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(b + 1); acb_poly_clear(zx); acb_poly_clear(M); acb_poly_clear(zxi); acb_clear(t); } static void _acb_hypgeom_coulomb_jet(acb_ptr F, acb_ptr G, acb_ptr Hpos, acb_ptr Hneg, const acb_t l, const acb_t eta, const acb_t z, slong len, slong prec) { acb_t l1, t, R, S; if (len <= 0) return; if (len == 1) { acb_hypgeom_coulomb(F, G, Hpos, Hneg, l, eta, z, prec); return; } if (acb_contains_zero(z)) { if (F != NULL) { if (acb_is_int(l)) _acb_hypgeom_coulomb_f_int_jet(F, l, eta, z, len, prec); else _acb_vec_indeterminate(F, len); } if (G != NULL) _acb_vec_indeterminate(G, len); if (Hpos != NULL) _acb_vec_indeterminate(Hpos, len); if (Hneg != NULL) _acb_vec_indeterminate(Hneg, len); return; } acb_init(l1); acb_init(t); acb_init(R); acb_init(S); acb_add_ui(l1, l, 1, prec); acb_hypgeom_coulomb(F, G, Hpos, Hneg, l, eta, z, prec); /* todo: somehow recycle the gamma function values for the two evaluations? */ acb_hypgeom_coulomb((F == NULL) ? NULL : (F + 1), (G == NULL) ? NULL : (G + 1), (Hpos == NULL) ? NULL : (Hpos + 1), (Hneg == NULL) ? NULL : (Hneg + 1), l1, eta, z, prec); /* First derivatives: http://fungrim.org/entry/a51a4b/, http://fungrim.org/entry/2fec14/ */ /* R_l = (2l+1) C_l / C_{l+1} = sqrt(l+i eta) sqrt(l-i eta) / l */ if (acb_is_real(l) && acb_is_real(eta) && arb_is_nonzero(acb_realref(eta))) { acb_mul(R, l1, l1, prec); acb_addmul(R, eta, eta, prec); acb_sqrt(R, R, prec); } else { acb_mul_onei(t, eta); acb_add(t, t, l1, prec); acb_sqrt(t, t, prec); acb_div_onei(R, eta); acb_add(R, R, l1, prec); acb_sqrt(R, R, prec); acb_mul(R, R, t, prec); } acb_div(R, R, l1, prec); acb_div(S, l1, z, prec); acb_div(t, eta, l1, prec); acb_add(S, S, t, prec); /* todo: fix regular F at origin */ if (F != NULL) { acb_mul(F + 1, F + 1, R, prec); acb_neg(F + 1, F + 1); acb_addmul(F + 1, F, S, prec); } if (G != NULL) { acb_mul(G + 1, G + 1, R, prec); acb_neg(G + 1, G + 1); acb_addmul(G + 1, G, S, prec); } if (Hpos != NULL) { acb_mul(Hpos + 1, Hpos + 1, R, prec); acb_neg(Hpos + 1, Hpos + 1); acb_addmul(Hpos + 1, Hpos, S, prec); } if (Hneg != NULL) { acb_mul(Hneg + 1, Hneg + 1, R, prec); acb_neg(Hneg + 1, Hneg + 1); acb_addmul(Hneg + 1, Hneg, S, prec); } if (len >= 3) { acb_t q, q2, w, w2; acb_init(q); acb_init(q2); acb_init(w); acb_init(w2); acb_inv(w, z, prec); acb_mul(w2, w, w, prec); /* http://fungrim.org/entry/07a654/ */ /* F''/2 = q F, q = (2eta/z + l(l+1)/z^2 - 1)/2 */ acb_mul(q, l, l1, prec); acb_mul(q, q, w2, prec); acb_mul_2exp_si(q2, eta, 1); acb_addmul(q, q2, w, prec); acb_sub_ui(q, q, 1, prec); acb_mul_2exp_si(q, q, -1); if (F != NULL) acb_mul(F + 2, F, q, prec); if (G != NULL) acb_mul(G + 2, G, q, prec); if (Hpos != NULL) acb_mul(Hpos + 2, Hpos, q, prec); if (Hneg != NULL) acb_mul(Hneg + 2, Hneg, q, prec); /* http://fungrim.org/entry/faa118/ */ /* F'''/6 = (2qF' - q2 F)/6, q2 = 2(eta + l(l+1)/z)/z^2 */ if (len >= 4) { acb_mul_2exp_si(q, q, 1); acb_mul(q2, l, l1, prec); acb_mul(q2, q2, w, prec); acb_add(q2, q2, eta, prec); acb_mul_2exp_si(q2, q2, 1); acb_mul(q2, q2, w2, prec); if (F != NULL) { acb_mul(F + 3, F + 1, q, prec); acb_submul(F + 3, F + 0, q2, prec); acb_div_ui(F + 3, F + 3, 6, prec); } if (G != NULL) { acb_mul(G + 3, G + 1, q, prec); acb_submul(G + 3, G, q2, prec); acb_div_ui(G + 3, G + 3, 6, prec); } if (Hpos != NULL) { acb_mul(Hpos + 3, Hpos + 1, q, prec); acb_submul(Hpos + 3, Hpos, q2, prec); acb_div_ui(Hpos + 3, Hpos + 3, 6, prec); } if (Hneg != NULL) { acb_mul(Hneg + 3, Hneg + 1, q, prec); acb_submul(Hneg + 3, Hneg, q2, prec); acb_div_ui(Hneg + 3, Hneg + 3, 6, prec); } } /* http://fungrim.org/entry/eca10b/ */ if (len >= 5) { slong k; acb_ptr s; s = _acb_vec_init(4); /* s4 = -(k(k+7) + 12) s3 = 2 (k(k+5) + 6) z s2 = (k(k+3) + z^2 - 2z*eta - l(l+1) + 2) s1 = 2(z-eta) s0 = 1 F[k+4] = (s0*F[k] + s1*F[k+1] + s2*F[k+2] + s3*F[k+3]) / s4 / z^2 */ acb_sub(s + 1, z, eta, prec); acb_mul_2exp_si(s + 1, s + 1, 1); acb_mul(q, z, z, prec); acb_mul(q2, eta, z, prec); acb_mul_2exp_si(q2, q2, 1); acb_sub(q, q, q2, prec); acb_submul(q, l, l1, prec); for (k = 0; k + 4 < len; k++) { acb_mul_si(s + 3, z, 2 * (k * (k + 5) + 6), prec); acb_add_si(s + 2, q, k * (k + 3) + 2, prec); if (F != NULL) { acb_dot(F + k + 4, F + k, 0, F + k + 1, 1, s + 1, 1, 3, prec); acb_div_si(F + k + 4, F + k + 4, -(k * (k + 7) + 12), prec); acb_mul(F + k + 4, F + k + 4, w2, prec); } if (G != NULL) { acb_dot(G + k + 4, G + k, 0, G + k + 1, 1, s + 1, 1, 3, prec); acb_div_si(G + k + 4, G + k + 4, -(k * (k + 7) + 12), prec); acb_mul(G + k + 4, G + k + 4, w2, prec); } if (Hpos != NULL) { acb_dot(Hpos + k + 4, Hpos + k, 0, Hpos + k + 1, 1, s + 1, 1, 3, prec); acb_div_si(Hpos + k + 4, Hpos + k + 4, -(k * (k + 7) + 12), prec); acb_mul(Hpos + k + 4, Hpos + k + 4, w2, prec); } if (Hneg != NULL) { acb_dot(Hneg + k + 4, Hneg + k, 0, Hneg + k + 1, 1, s + 1, 1, 3, prec); acb_div_si(Hneg + k + 4, Hneg + k + 4, -(k * (k + 7) + 12), prec); acb_mul(Hneg + k + 4, Hneg + k + 4, w2, prec); } } _acb_vec_clear(s, 4); } acb_clear(q); acb_clear(q2); acb_clear(w); acb_clear(w2); } acb_clear(l1); acb_clear(t); acb_clear(R); acb_clear(S); } void acb_hypgeom_coulomb_jet(acb_ptr F, acb_ptr G, acb_ptr Hpos, acb_ptr Hneg, const acb_t l, const acb_t eta, const acb_t z, slong len, slong prec) { acb_t t; /* to allow aliasing with z */ acb_init(t); acb_set(t, z); _acb_hypgeom_coulomb_jet(F, G, Hpos, Hneg, l, eta, t, len, prec); acb_clear(t); } arb-2.22.1/acb_hypgeom/coulomb_series.c000066400000000000000000000063651417376376500200320ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_coulomb_series(acb_ptr F, acb_ptr G, acb_ptr Hpos, acb_ptr Hneg, const acb_t l, const acb_t eta, acb_srcptr z, slong zlen, slong len, slong prec) { acb_ptr t, v; if (len == 0) return; zlen = FLINT_MIN(zlen, len); if (zlen == 1) { acb_hypgeom_coulomb(F, G, Hpos, Hneg, l, eta, z, prec); if (F != NULL) _acb_vec_zero(F + 1, len - 1); if (G != NULL) _acb_vec_zero(G + 1, len - 1); if (Hpos != NULL) _acb_vec_zero(Hpos + 1, len - 1); if (Hneg != NULL) _acb_vec_zero(Hneg + 1, len - 1); return; } t = _acb_vec_init(len); v = _acb_vec_init(zlen); /* copy nonconstant part first to allow aliasing */ acb_zero(v); _acb_vec_set(v + 1, z + 1, zlen - 1); acb_hypgeom_coulomb_jet(F, G, Hpos, Hneg, l, eta, z, len, prec); if (F != NULL) { _acb_vec_set(t, F, len); _acb_poly_compose_series(F, t, len, v, zlen, len, prec); } if (G != NULL) { _acb_vec_set(t, G, len); _acb_poly_compose_series(G, t, len, v, zlen, len, prec); } if (Hpos != NULL) { _acb_vec_set(t, Hpos, len); _acb_poly_compose_series(Hpos, t, len, v, zlen, len, prec); } if (Hneg != NULL) { _acb_vec_set(t, Hneg, len); _acb_poly_compose_series(Hneg, t, len, v, zlen, len, prec); } _acb_vec_clear(t, len); _acb_vec_clear(v, zlen); } void acb_hypgeom_coulomb_series(acb_poly_t F, acb_poly_t G, acb_poly_t Hpos, acb_poly_t Hneg, const acb_t l, const acb_t eta, const acb_poly_t z, slong len, slong prec) { acb_srcptr zptr; slong zlen; acb_t t; if (len == 0) { if (F != NULL) acb_poly_zero(F); if (G != NULL) acb_poly_zero(G); if (Hpos != NULL) acb_poly_zero(Hpos); if (Hneg != NULL) acb_poly_zero(Hneg); return; } zlen = z->length; if (zlen <= 1) len = 1; if (F != NULL) acb_poly_fit_length(F, len); if (G != NULL) acb_poly_fit_length(G, len); if (Hpos != NULL) acb_poly_fit_length(Hpos, len); if (Hneg != NULL) acb_poly_fit_length(Hneg, len); if (zlen == 0) { acb_init(t); zptr = t; zlen = 1; } else { zptr = z->coeffs; } _acb_hypgeom_coulomb_series( F ? F->coeffs : NULL, G ? G->coeffs : NULL, Hpos ? Hpos->coeffs : NULL, Hneg ? Hneg->coeffs : NULL, l, eta, zptr, zlen, len, prec); if (F != NULL) _acb_poly_set_length(F, len); if (G != NULL) _acb_poly_set_length(G, len); if (Hpos != NULL) _acb_poly_set_length(Hpos, len); if (Hneg != NULL) _acb_poly_set_length(Hneg, len); if (F != NULL) _acb_poly_normalise(F); if (G != NULL) _acb_poly_normalise(G); if (Hpos != NULL) _acb_poly_normalise(Hpos); if (Hneg != NULL) _acb_poly_normalise(Hneg); } arb-2.22.1/acb_hypgeom/dilog.c000066400000000000000000000102351417376376500161050ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_dilog(acb_t res, const acb_t z, slong prec) { double a, b, best, mz, mz1, t, u; int algorithm; slong acc, inprec; if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (acb_is_zero(z)) { acb_zero(res); return; } acc = acb_rel_accuracy_bits(z); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + 30); inprec = prec; /* first take care of exponents that may overflow doubles */ if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -20) <= 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -20) <= 0) { acb_hypgeom_dilog_zero(res, z, prec); return; } if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 20) >= 0 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 20) >= 0) { acb_hypgeom_dilog_transform(res, z, 1, prec); return; } prec = 1.005 * prec + 5; a = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); b = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); best = mz = a * a + b * b; algorithm = 0; /* if |z| > 0.25, consider expanding somewhere other than the origin */ if (best > 0.25 * 0.25) { if (1.0 / mz < best) /* use 1/z */ { best = 1.0 / mz; algorithm = 1; } mz1 = (a - 1.0) * (a - 1.0) + b * b; if (mz1 < best) /* use 1-z */ { best = mz1; algorithm = 2; } if (mz1 > 0.001 && mz / mz1 < best) /* use z/(z-1) */ { best = mz / mz1; algorithm = 3; } if (mz1 > 0.001 && 1.0 / mz1 < best) /* use 1/(1-z) */ { best = 1.0 / mz1; algorithm = 4; } } /* do we still have |z| > 0.25 after transforming? */ if (best > 0.25 * 0.25) { /* use series with bernoulli numbers (if not too many!) */ if (prec < 10000) { /* t = |log(a+bi)|^2 / (2 pi)^2 */ t = log(a * a + b * b); u = atan2(b, a); t = (t * t + u * u) * 0.02533029591; if (prec > 1000) t *= 4.0; /* penalty at high precision */ else t *= 1.1; /* small penalty... also helps avoid this method at negative reals where the log branch cut enters (todo: combine with 1-z formula?) */ if (t < best) { algorithm = 8; best = t; } } } /* fall back on expanding at another special point (this should only happen at high precision, where we will use the bit-burst algorithm) */ if (best > 0.75 * 0.75) { b = fabs(b); /* reduce to upper half plane */ /* expanding at z0 = i: effective radius |z-i|/sqrt(2) */ t = ((b - 1.0) * (b - 1.0) + a * a) * 0.5; if (t < best) { best = t; algorithm = 5; } /* expanding at z0 = (1+i)/2: effective radius |z-(1+i)/2|*sqrt(2) */ t = 1.0 + 2.0 * (a * (a - 1.0) + b * (b - 1.0)); if (t < best) { best = t; algorithm = 6; } /* expanding at z0 = 1+i: effective radius |z-(1+i)| */ t = 2.0 + (a - 2.0) * a + (b - 2.0) * b; if (t < best) { best = t; algorithm = 7; } } if (algorithm == 0) acb_hypgeom_dilog_zero(res, z, prec); else if (algorithm >= 1 && algorithm <= 7) acb_hypgeom_dilog_transform(res, z, algorithm, prec); else /* (algorithm == 8) */ acb_hypgeom_dilog_bernoulli(res, z, prec); acb_set_round(res, res, inprec); } arb-2.22.1/acb_hypgeom/dilog_bernoulli.c000066400000000000000000000050111417376376500201540ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #include "bernoulli.h" /* todo: use log(1-z) when this is better? would also need to adjust strategy in the main function */ void acb_hypgeom_dilog_bernoulli(acb_t res, const acb_t z, slong prec) { acb_t s, w, w2; slong n, k; fmpz_t c, d; mag_t m, err; double lm; int real; acb_init(s); acb_init(w); acb_init(w2); fmpz_init(c); fmpz_init(d); mag_init(m); mag_init(err); real = 0; if (acb_is_real(z)) { arb_sub_ui(acb_realref(w), acb_realref(z), 1, 30); real = arb_is_nonpositive(acb_realref(w)); } acb_log(w, z, prec); acb_get_mag(m, w); /* for k >= 4, the terms are bounded by (|w| / (2 pi))^k */ mag_set_ui_2exp_si(err, 2670177, -24); /* upper bound for 1/(2pi) */ mag_mul(err, err, m); lm = mag_get_d_log2_approx(err); if (lm < -0.25) { n = prec / (-lm) + 1; n = FLINT_MAX(n, 4); mag_geom_series(err, err, n); BERNOULLI_ENSURE_CACHED(n) acb_mul(w2, w, w, prec); for (k = n - (n % 2 == 0); k >= 3; k -= 2) { fmpz_mul_ui(c, fmpq_denref(bernoulli_cache + k - 1), k - 1); fmpz_mul_ui(d, c, (k + 1) * (k + 2)); acb_mul(s, s, w2, prec); acb_mul_fmpz(s, s, c, prec); fmpz_mul_ui(c, fmpq_numref(bernoulli_cache + k - 1), (k + 1) * (k + 2)); acb_sub_fmpz(s, s, c, prec); acb_div_fmpz(s, s, d, prec); } acb_mul(s, s, w, prec); acb_mul_2exp_si(s, s, 1); acb_sub_ui(s, s, 3, prec); acb_mul(s, s, w2, prec); acb_mul_2exp_si(s, s, -1); acb_const_pi(w2, prec); acb_addmul(s, w2, w2, prec); acb_div_ui(s, s, 6, prec); acb_neg(w2, w); acb_log(w2, w2, prec); acb_submul(s, w2, w, prec); acb_add(res, s, w, prec); acb_add_error_mag(res, err); if (real) arb_zero(acb_imagref(res)); } else { acb_indeterminate(res); } acb_clear(s); acb_clear(w); acb_clear(w2); fmpz_clear(c); fmpz_clear(d); mag_clear(m); mag_clear(err); } arb-2.22.1/acb_hypgeom/dilog_bitburst.c000066400000000000000000000041041417376376500200210ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #include "bernoulli.h" static void _arf_trunc(arf_t x) { if (arf_sgn(x) < 0) arf_ceil(x, x); else arf_floor(x, x); } static void acb_extract_bits(acb_t t, const acb_t z, slong b) { acb_mul_2exp_si(t, z, b); _arf_trunc(arb_midref(acb_realref(t))); _arf_trunc(arb_midref(acb_imagref(t))); mag_zero(arb_radref(acb_realref(t))); mag_zero(arb_radref(acb_imagref(t))); acb_mul_2exp_si(t, t, -b); } void acb_hypgeom_dilog_bitburst(acb_t res, acb_t z0, const acb_t z, slong prec) { acb_t s, t, tprev, u; slong w; slong start = 16; acb_init(s); acb_init(t); acb_init(tprev); acb_init(u); acb_sub_ui(t, z, 1, 30); arb_abs(acb_imagref(t), acb_imagref(t)); /* we don't want to end up on the branch cut */ if (arb_contains_nonnegative(acb_realref(t)) && !arb_gt(acb_imagref(t), acb_realref(t))) { acb_set(z0, z); acb_zero(res); } else { acb_extract_bits(t, z, start); acb_set(z0, t); acb_set(tprev, t); for (w = 2 * start; w < prec; w *= 2) { acb_extract_bits(t, z, w); acb_sub(u, t, z, 30); if (arf_cmpabs_2exp_si(arb_midref(acb_realref(u)), -prec / 8) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(u)), -prec / 8) < 0) break; acb_hypgeom_dilog_continuation(u, tprev, t, prec); acb_add(s, s, u, prec); acb_set(tprev, t); } acb_hypgeom_dilog_continuation(u, tprev, z, prec); acb_add(s, s, u, prec); acb_set(res, s); } acb_clear(s); acb_clear(t); acb_clear(tprev); acb_clear(u); } arb-2.22.1/acb_hypgeom/dilog_continuation.c000066400000000000000000000155731417376376500207110ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void bsplit(acb_ptr VA, const acb_t z, const acb_t z2, const acb_t a, const acb_t a1a, slong k, slong h, slong prec) { if (h - k == 1) { acb_zero(VA + 0); acb_mul_ui(VA + 1, a1a, (k+1)*(k+2), prec); acb_mul_si(VA + 2, z2, -k*k, prec); acb_mul_ui(VA + 3, a, (k+1)*(2*k+1), prec); acb_sub_ui(VA + 3, VA + 3, (k+1)*(k+1), prec); acb_mul(VA + 3, VA + 3, z, prec); acb_neg(VA + 3, VA + 3); acb_set(VA + 4, VA + 1); acb_zero(VA + 5); acb_set(VA + 6, VA + 1); } else { slong m; acb_ptr VB; if (h <= k) flint_abort(); m = k + (h - k) / 2; VB = _acb_vec_init(7); bsplit(VA, z, z2, a, a1a, k, m, prec); bsplit(VB, z, z2, a, a1a, m, h, prec); acb_mul(VA + 6, VA + 6, VB + 6, prec); acb_mul(VA + 4, VA + 4, VB + 6, prec); acb_addmul(VA + 4, VA + 0, VB + 4, prec); acb_addmul(VA + 4, VA + 2, VB + 5, prec); acb_mul(VA + 5, VA + 5, VB + 6, prec); acb_addmul(VA + 5, VA + 1, VB + 4, prec); acb_addmul(VA + 5, VA + 3, VB + 5, prec); acb_set(VB + 6, VA + 3); acb_mul(VA + 3, VA + 3, VB + 3, prec); acb_addmul(VA + 3, VA + 1, VB + 2, prec); acb_set(VB + 5, VA + 2); acb_mul(VA + 2, VA + 2, VB + 3, prec); acb_addmul(VA + 2, VA + 0, VB + 2, prec); acb_mul(VA + 1, VA + 1, VB + 0, prec); acb_addmul(VA + 1, VB + 6, VB + 1, prec); acb_mul(VA + 0, VA + 0, VB + 0, prec); acb_addmul(VA + 0, VB + 5, VB + 1, prec); _acb_vec_clear(VB, 7); } } /* Some possible approaches to bounding the Taylor coefficients c_k at the expansion point a: 1. Inspection of the symbolic derivatives gives the trivial bound |c_k| <= (1+|log(1-a)|) / min(|a|,|a-1|)^k which is good enough when not close to 0. 2. Using Cauchy's integral formula, some explicit computation gives |c_k| <= 4/|1-a|^k when |a| <= 1/2 or a = +/- i. The constant could certainly be improved. 3. For k >= 1, c_k = 2F1(k,k,k+1,a) / k^2. Can we use monotonicity to get good estimates here when a is complex? Note that 2F1(k,k,k,a) = (1-a)^-k. */ void acb_hypgeom_dilog_continuation(acb_t res, const acb_t a, const acb_t z, slong prec) { acb_t za, a1, a1a, za2, log1a; acb_ptr V; slong n; double tr; mag_t tm, err, am; int real; if (acb_is_zero(a)) { acb_hypgeom_dilog_zero_taylor(res, z, prec); return; } if (acb_eq(a, z)) { acb_zero(res); return; } acb_init(za); acb_init(a1); acb_init(a1a); acb_init(za2); acb_init(log1a); mag_init(tm); mag_init(err); mag_init(am); acb_sub(za, z, a, prec); /* z-a */ acb_sub_ui(a1, a, 1, prec); /* a-1 */ acb_mul(a1a, a1, a, prec); /* (a-1)a */ acb_mul(za2, za, za, prec); /* (z-a)^2 */ acb_neg(log1a, a1); acb_log(log1a, log1a, prec); /* log(1-a) */ acb_get_mag(am, a); if (mag_cmp_2exp_si(am, -1) <= 0 || (acb_is_exact(a) && arb_is_zero(acb_realref(a)) && arf_cmpabs_ui(arb_midref(acb_imagref(a)), 1) == 0)) { acb_get_mag_lower(am, a1); acb_get_mag(tm, za); mag_div(tm, tm, am); /* tm = ratio */ mag_set_ui(am, 4); /* am = prefactor */ } else { acb_get_mag_lower(am, a); acb_get_mag_lower(tm, a1); mag_min(am, am, tm); acb_get_mag(tm, za); mag_div(tm, tm, am); /* tm = ratio */ acb_get_mag(am, log1a); mag_add_ui(am, am, 1); /* am = prefactor */ } tr = mag_get_d_log2_approx(tm); if (tr < -0.1) { arf_srcptr rr, ii; rr = arb_midref(acb_realref(z)); ii = arb_midref(acb_imagref(z)); if (arf_cmpabs(ii, rr) > 0) rr = ii; /* target relative accuracy near 0 */ if (arf_cmpabs_2exp_si(rr, -2) < 0 && arf_cmpabs_2exp_si(rr, -prec) > 0) n = (prec - arf_abs_bound_lt_2exp_si(rr)) / (-tr) + 1; else n = prec / (-tr) + 1; n = FLINT_MAX(n, 2); } else { n = 2; } mag_geom_series(err, tm, n); mag_mul(err, err, am); real = acb_is_real(a) && acb_is_real(z) && arb_is_negative(acb_realref(a1)) && mag_is_finite(err); if (n < 10) { /* forward recurrence - faster for small n and/or low precision, but must be avoided for large n since complex intervals blow up */ acb_t s, t, u, v; slong k; acb_init(s); acb_init(t); acb_init(u); acb_init(v); acb_div(u, log1a, a, prec); acb_neg(u, u); if (n >= 3) { acb_inv(v, a1, prec); acb_add(v, v, u, prec); acb_div(v, v, a, prec); acb_mul_2exp_si(v, v, -1); acb_neg(v, v); acb_mul(v, v, za2, prec); } acb_mul(u, u, za, prec); acb_add(s, u, v, prec); for (k = 3; k < n; k++) { acb_mul_ui(u, u, (k - 2) * (k - 2), prec); acb_mul(u, u, za2, prec); acb_mul_ui(t, a, (k - 1) * (2 * k - 3), prec); acb_sub_ui(t, t, (k - 1) * (k - 1), prec); acb_mul(t, t, v, prec); acb_addmul(u, t, za, prec); acb_mul_ui(t, a1a, (k - 1) * k, prec); acb_neg(t, t); acb_div(u, u, t, prec); acb_add(s, s, u, prec); acb_swap(v, u); } acb_set(res, s); acb_clear(s); acb_clear(t); acb_clear(u); acb_clear(v); } else { /* binary splitting */ V = _acb_vec_init(7); bsplit(V, za, za2, a, a1a, 1, 1 + n, prec); acb_mul(V + 1, V + 4, log1a, prec); acb_neg(V + 1, V + 1); acb_mul(V + 2, V + 5, za2, prec); acb_mul_2exp_si(V + 2, V + 2, -1); acb_mul(V + 1, V + 1, za, prec); acb_div(V + 3, V + 2, a1, prec); acb_sub(V + 1, V + 1, V + 3, prec); acb_div(V + 0, log1a, a, prec); acb_addmul(V + 1, V + 2, V + 0, prec); acb_mul(V + 6, V + 6, a, prec); acb_div(V + 0, V + 1, V + 6, prec); acb_set(res, V + 0); _acb_vec_clear(V, 7); } if (real) arb_add_error_mag(acb_realref(res), err); else acb_add_error_mag(res, err); acb_clear(za); acb_clear(a1); acb_clear(a1a); acb_clear(za2); acb_clear(log1a); mag_clear(tm); mag_clear(err); mag_clear(am); } arb-2.22.1/acb_hypgeom/dilog_transform.c000066400000000000000000000132351417376376500202030ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_dilog_transform(acb_t res, const acb_t z, int algorithm, slong prec) { acb_t t, u; acb_init(t); acb_init(u); if (algorithm == 1) { /* Li_2(z) = -Li_2(1/z) - log(-z)^2/2 - pi^2/6, z not in (0,1) */ arf_set_ui_2exp_si(arb_midref(acb_realref(t)), 1, -1); mag_set_ui_2exp_si(arb_radref(acb_realref(t)), 1, -1); if (acb_overlaps(z, t)) { acb_indeterminate(res); } else { acb_inv(t, z, prec); acb_hypgeom_dilog_zero(t, t, prec); acb_neg(u, z); acb_log(u, u, prec); acb_mul(u, u, u, prec); acb_mul_2exp_si(u, u, -1); acb_add(t, t, u, prec); acb_const_pi(u, prec); acb_mul(u, u, u, prec); acb_div_ui(u, u, 6, prec); acb_add(t, t, u, prec); acb_neg(res, t); } } else if (algorithm == 2) { /* Li_2(z) = -Li_2(1-z) - log(1-z) log(z) + pi^2/6 */ if (acb_is_one(z)) { acb_zero(res); } else { acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_hypgeom_dilog_zero(u, t, prec); acb_log(t, t, prec); acb_log(res, z, prec); acb_mul(res, res, t, prec); acb_add(res, res, u, prec); } acb_const_pi(t, prec); acb_mul(t, t, t, prec); acb_div_ui(t, t, 6, prec); acb_sub(res, t, res, prec); } else if (algorithm == 3) { /* Li_2(z) = -Li_2(z/(z-1)) - log(1-z)^2/2, z not in (1,inf) */ acb_sub_ui(t, z, 1, prec); if (!arb_is_negative(acb_realref(t))) { acb_indeterminate(res); } else { acb_div(u, z, t, prec); acb_hypgeom_dilog_zero(u, u, prec); acb_neg(t, t); acb_log(t, t, prec); acb_mul(t, t, t, prec); acb_mul_2exp_si(t, t, -1); acb_add(t, t, u, prec); acb_neg(res, t); } } else if (algorithm == 4) { /* Li_2(z) = Li_2(1/(1-z)) + log(1-z) [log(1-z)/2 - log(-z)] - pi^2/6 */ acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_inv(u, t, prec); acb_hypgeom_dilog_zero(u, u, prec); acb_log(t, t, prec); acb_neg(res, z); acb_log(res, res, prec); acb_mul_2exp_si(res, res, 1); acb_sub(res, t, res, prec); acb_mul_2exp_si(res, res, -1); acb_addmul(u, res, t, prec); acb_const_pi(t, prec); acb_mul(t, t, t, prec); acb_div_ui(t, t, 6, prec); acb_sub(res, u, t, prec); } else if (algorithm >= 5 && algorithm <= 7) { if (arb_contains_zero(acb_imagref(z))) { acb_indeterminate(res); } else { acb_t a; acb_init(a); if (algorithm == 5) { acb_onei(a); /* Li_2(i) = -pi^2/48 + C i */ arb_const_catalan(acb_imagref(u), prec); arb_const_pi(acb_realref(u), prec); arb_mul(acb_realref(u), acb_realref(u), acb_realref(u), prec); arb_div_si(acb_realref(u), acb_realref(u), -48, prec); } else if (algorithm == 6) { /* Li_2((1+i)/2) = (5 pi^2 / 96 - log(2)^2/8) + (C - pi log(2) / 8) i */ arb_t t; arb_init(t); acb_set_d_d(a, 0.5, 0.5); arb_const_pi(t, prec); arb_const_log2(acb_imagref(u), prec); arb_mul(acb_realref(u), acb_imagref(u), acb_imagref(u), prec); arb_mul(acb_imagref(u), acb_imagref(u), t, prec); acb_mul_2exp_si(u, u, -3); arb_mul(t, t, t, prec); arb_mul_ui(t, t, 5, prec); arb_div_ui(t, t, 96, prec); arb_sub(acb_realref(u), t, acb_realref(u), prec); arb_const_catalan(t, prec); arb_sub(acb_imagref(u), t, acb_imagref(u), prec); arb_clear(t); } else { /* Li_2(1+i) = pi^2/16 + (C + pi log(2)/4) i */ arb_t t; arb_init(t); acb_set_d_d(a, 1.0, 1.0); arb_const_pi(acb_realref(u), prec); arb_mul_2exp_si(acb_realref(u), acb_realref(u), -2); arb_const_log2(t, prec); arb_mul(acb_imagref(u), acb_realref(u), t, prec); arb_const_catalan(t, prec); arb_add(acb_imagref(u), acb_imagref(u), t, prec); arb_mul(acb_realref(u), acb_realref(u), acb_realref(u), prec); arb_clear(t); } if (arf_sgn(arb_midref(acb_imagref(z))) < 0) { acb_conj(a, a); acb_conj(u, u); } acb_hypgeom_dilog_bitburst(res, t, z, prec); acb_add(res, res, u, prec); acb_hypgeom_dilog_continuation(t, a, t, prec); acb_add(res, res, t, prec); acb_clear(a); } } else { flint_printf("unknown algorithm\n"); flint_abort(); } acb_clear(t); acb_clear(u); } arb-2.22.1/acb_hypgeom/dilog_zero.c000066400000000000000000000016601417376376500171460ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_dilog_zero(acb_t res, const acb_t z, slong prec) { if (prec < 40000 || (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -prec / 1000) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -prec / 1000) < 0)) { acb_hypgeom_dilog_zero_taylor(res, z, prec); } else { acb_t z0; acb_init(z0); acb_hypgeom_dilog_bitburst(res, z0, z, prec); acb_hypgeom_dilog_zero_taylor(z0, z0, prec); acb_add(res, res, z0, prec); acb_clear(z0); } } arb-2.22.1/acb_hypgeom/dilog_zero_taylor.c000066400000000000000000000115421417376376500205400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void bsplit_zero(acb_t P, acb_t R, acb_t Q, const acb_t z, slong a, slong b, slong prec) { if (b - a == 1) { acb_mul_ui(P, z, a * a, prec); acb_set_ui(R, (a + 1) * (a + 1)); acb_set(Q, R); } else { acb_t P2, R2, Q2; slong m; acb_init(P2); acb_init(R2); acb_init(Q2); m = a + (b - a) / 2; bsplit_zero(P, R, Q, z, a, m, prec); bsplit_zero(P2, R2, Q2, z, m, b, prec); acb_mul(R, R, Q2, prec); acb_addmul(R, P, R2, prec); acb_mul(P, P, P2, prec); acb_mul(Q, Q, Q2, prec); acb_clear(P2); acb_clear(R2); acb_clear(Q2); } } #if FLINT_BITS == 64 #define DIVLIM 1625 /* just a tuning value */ #define DIVLIM2 1000000000 /* avoid overflow */ #else #define DIVLIM 40 #define DIVLIM2 30000 #endif void acb_hypgeom_dilog_taylor_sum(acb_t res, const acb_t z, slong n, slong prec) { slong k, qk, m, power; ulong q; acb_t s, t, u; acb_ptr zpow; int real; if (n <= 3) { if (n <= 1) acb_zero(res); else if (n == 2) acb_set_round(res, z, prec); else { acb_init(t); acb_mul(t, z, z, prec); acb_mul_2exp_si(t, t, -2); acb_add(res, z, t, prec); acb_clear(t); } return; } /* use binary splitting */ if (prec > 4000 && acb_bits(z) < prec * 0.02) { acb_init(s); acb_init(t); acb_init(u); bsplit_zero(s, t, u, z, 1, n, prec); acb_add(s, s, t, prec); acb_mul(s, s, z, prec); acb_div(res, s, u, prec); acb_clear(s); acb_clear(t); acb_clear(u); return; } real = acb_is_real(z); k = n - 1; m = n_sqrt(n); acb_init(s); acb_init(t); zpow = _acb_vec_init(m + 1); _acb_vec_set_powers(zpow, z, m + 1, prec); power = (n - 1) % m; while (k >= DIVLIM) { if (k < DIVLIM2) /* todo: write a div_uiui function? */ { acb_div_ui(t, zpow + power, k * k, prec); } else { acb_div_ui(t, zpow + power, k, prec); acb_div_ui(t, t, k, prec); } acb_add(s, s, t, prec); if (power == 0) { acb_mul(s, s, zpow + m, prec); power = m - 1; } else { power--; } k--; } qk = k; /* k at which to change denominator */ q = 1; while (k >= 2) { /* find next qk such that the consecutive denominators can be collected in a single word */ if (k == qk) { if (q != 1) acb_div_ui(s, s, q, prec); q = qk * qk; qk--; while (qk > 1) { ulong hi, lo; umul_ppmm(hi, lo, q, qk * qk); if (hi != 0) break; q *= qk * qk; qk--; } acb_mul_ui(s, s, q, prec); } if (power == 0) { acb_add_ui(s, s, q / (k * k), prec); acb_mul(s, s, zpow + m, prec); power = m - 1; } else { if (real) /* minor optimization */ arb_addmul_ui(acb_realref(s), acb_realref(zpow + power), q / (k * k), prec); else acb_addmul_ui(s, zpow + power, q / (k * k), prec); power--; } k--; } if (q != 1) acb_div_ui(s, s, q, prec); acb_add(s, s, z, prec); acb_swap(res, s); _acb_vec_clear(zpow, m + 1); acb_clear(s); acb_clear(t); } void acb_hypgeom_dilog_zero_taylor(acb_t res, const acb_t z, slong prec) { mag_t m; slong n; double x; int real; mag_init(m); acb_get_mag(m, z); real = acb_is_real(z); x = -mag_get_d_log2_approx(m); n = 2; if (x > 0.01) { n = prec / x + 1; n += (x > 2.0); /* relative error for very small |z| */ } n = FLINT_MAX(n, 2); mag_geom_series(m, m, n); mag_div_ui(m, m, n); mag_div_ui(m, m, n); if (mag_is_finite(m)) { acb_hypgeom_dilog_taylor_sum(res, z, n, prec); if (real) arb_add_error_mag(acb_realref(res), m); else acb_add_error_mag(res, m); } else { acb_indeterminate(res); } mag_clear(m); } arb-2.22.1/acb_hypgeom/ei.c000066400000000000000000000054771417376376500154200ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_ei_asymp(acb_t res, const acb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_one(t); acb_neg(u, z); acb_hypgeom_u_asymp(u, t, t, u, -1, prec); acb_div(u, u, z, prec); acb_exp(t, z, prec); acb_mul(u, u, t, prec); if (arb_is_zero(acb_imagref(z))) { arb_zero(acb_imagref(u)); } else if (arb_is_positive(acb_imagref(z))) { acb_const_pi(t, prec); arb_add(acb_imagref(u), acb_imagref(u), acb_realref(t), prec); } else if (arb_is_negative(acb_imagref(z))) { acb_const_pi(t, prec); arb_sub(acb_imagref(u), acb_imagref(u), acb_realref(t), prec); } else { /* add [-pi,pi] i */ acb_const_pi(t, prec); arb_add_error(acb_imagref(u), acb_realref(t)); } acb_swap(res, u); acb_clear(t); acb_clear(u); } /* Ei(z) = z 2F2(1,1,2,2,z) + 0.5[log(z)-log(1/z)] + gamma */ void acb_hypgeom_ei_2f2(acb_t res, const acb_t z, slong prec) { acb_t a, t; acb_struct b[2]; acb_init(a); acb_init(b); acb_init(b + 1); acb_init(t); acb_one(a); acb_set_ui(b, 2); acb_set_ui(b + 1, 2); acb_hypgeom_pfq_direct(t, a, 1, b, 2, z, -1, prec); acb_mul(t, t, z, prec); arb_const_euler(acb_realref(a), prec); arb_add(acb_realref(t), acb_realref(t), acb_realref(a), prec); if (arb_is_zero(acb_imagref(z))) { if (arb_is_positive(acb_realref(z))) { acb_log(a, z, prec); } else { /* ok if overlapping zero -- will be indeterminate either way */ acb_neg(a, z); acb_log(a, a, prec); arb_zero(acb_imagref(a)); } acb_add(t, t, a, prec); } else if (arb_is_nonzero(acb_imagref(z)) || arb_is_nonnegative(acb_realref(z))) /* not overlapping (-inf,0] */ { acb_log(a, z, prec); acb_add(t, t, a, prec); } else { acb_log(a, z, prec); arb_zero(acb_imagref(a)); acb_const_pi(b, prec); arb_add_error(acb_imagref(a), acb_realref(b)); acb_add(t, t, a, prec); } acb_swap(res, t); acb_clear(a); acb_clear(b); acb_clear(b + 1); acb_clear(t); } void acb_hypgeom_ei(acb_t res, const acb_t z, slong prec) { if (acb_hypgeom_u_use_asymp(z, prec)) acb_hypgeom_ei_asymp(res, z, prec); else acb_hypgeom_ei_2f2(res, z, prec); } arb-2.22.1/acb_hypgeom/ei_series.c000066400000000000000000000034571417376376500167660ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_ei_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { acb_t c; if (acb_contains_zero(h)) { _acb_vec_indeterminate(g, len); return; } acb_init(c); acb_hypgeom_ei(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else { acb_ptr t, u, v; t = _acb_vec_init(len); u = _acb_vec_init(len); v = _acb_vec_init(len); /* Ei(h(x)) = integral([h'(x) / h(x)] exp(h(x)) */ _acb_poly_exp_series(t, h, hlen, len - 1, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_mullow(v, t, len - 1, u, len - 1, len - 1, prec); _acb_poly_div_series(u, v, len - 1, h, hlen, len - 1, prec); _acb_poly_integral(g, u, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(v, len); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_ei_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_inv_series(g, h, len, prec); return; } acb_poly_fit_length(g, len); _acb_hypgeom_ei_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/erf.c000066400000000000000000000174401417376376500155700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" /* IMAG: erf(z) = 2z/sqrt(pi) * 1F1(1/2, 3/2, -z^2) */ void acb_hypgeom_erf_1f1a(acb_t res, const acb_t z, slong prec) { acb_t a, t, w; acb_struct b[2]; acb_init(a); acb_init(b); acb_init(b + 1); acb_init(t); acb_init(w); acb_one(a); acb_mul_2exp_si(a, a, -1); acb_set_ui(b, 3); acb_mul_2exp_si(b, b, -1); acb_one(b + 1); acb_mul(w, z, z, prec); acb_neg(w, w); acb_hypgeom_pfq_direct(t, a, 1, b, 2, w, -1, prec); acb_mul(t, t, z, prec); arb_const_sqrt_pi(acb_realref(w), prec); acb_div_arb(t, t, acb_realref(w), prec); acb_mul_2exp_si(res, t, 1); acb_clear(a); acb_clear(b); acb_clear(b + 1); acb_clear(t); acb_clear(w); } /* REAL: erf(x) = 2x/sqrt(pi) * exp(-x^2) 1F1(1, 3/2, x^2) */ void acb_hypgeom_erf_1f1b(acb_t res, const acb_t z, slong prec) { acb_t a, b, t, w; acb_init(a); acb_init(b); acb_init(t); acb_init(w); acb_set_ui(b, 3); acb_mul_2exp_si(b, b, -1); acb_mul(w, z, z, prec); acb_hypgeom_pfq_direct(t, a, 0, b, 1, w, -1, prec); acb_neg(w, w); acb_exp(w, w, prec); acb_mul(t, t, w, prec); acb_mul(t, t, z, prec); arb_const_sqrt_pi(acb_realref(w), prec); acb_div_arb(t, t, acb_realref(w), prec); acb_mul_2exp_si(res, t, 1); acb_clear(a); acb_clear(b); acb_clear(t); acb_clear(w); } void acb_hypgeom_erf_asymp(acb_t res, const acb_t z, int complementary, slong prec, slong prec2) { acb_t a, t, u; acb_init(a); acb_init(t); acb_init(u); if (!acb_is_exact(z) && (arf_cmpabs_ui(arb_midref(acb_realref(z)), prec) < 0) && (arf_cmpabs_ui(arb_midref(acb_imagref(z)), prec) < 0)) { acb_t zmid; mag_t re_err, im_err; acb_init(zmid); mag_init(re_err); mag_init(im_err); acb_hypgeom_erf_propagated_error(re_err, im_err, z); arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z))); acb_hypgeom_erf_asymp(res, zmid, complementary, prec, prec2); arb_add_error_mag(acb_realref(res), re_err); arb_add_error_mag(acb_imagref(res), im_err); acb_clear(zmid); mag_clear(re_err); mag_clear(im_err); return; } acb_one(a); acb_mul_2exp_si(a, a, -1); acb_mul(t, z, z, prec2); acb_hypgeom_u_asymp(u, a, a, t, -1, prec2); acb_neg(t, t); acb_exp(t, t, prec2); acb_mul(u, u, t, prec2); arb_const_sqrt_pi(acb_realref(t), prec2); arb_zero(acb_imagref(t)); acb_mul(t, t, z, prec2); acb_div(u, u, t, prec2); /* branch cut term: -1 or 1 */ acb_csgn(acb_realref(t), z); arb_zero(acb_imagref(t)); if (complementary) { /* erfc(z) = 1 - erf(z) = u - (sgn - 1) */ acb_sub_ui(t, t, 1, prec); acb_sub(t, u, t, prec); } else { /* erf(z) = sgn - u */ acb_sub(t, t, u, prec); } if (arb_is_zero(acb_imagref(z))) { arb_zero(acb_imagref(t)); } else if (arb_is_zero(acb_realref(z))) { if (complementary) arb_one(acb_realref(t)); else arb_zero(acb_realref(t)); } acb_set(res, t); acb_clear(a); acb_clear(t); acb_clear(u); } void acb_hypgeom_erf_propagated_error(mag_t re, mag_t im, const acb_t z) { mag_t x, y; mag_init(x); mag_init(y); /* |exp(-(x+y)^2)| = exp(y^2-x^2) */ arb_get_mag(y, acb_imagref(z)); mag_mul(y, y, y); arb_get_mag_lower(x, acb_realref(z)); mag_mul_lower(x, x, x); if (mag_cmp(y, x) >= 0) { mag_sub(re, y, x); mag_exp(re, re); } else { mag_sub_lower(re, x, y); mag_expinv(re, re); } /* Radius. */ mag_hypot(x, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); mag_mul(re, re, x); /* 2/sqrt(pi) < 289/256 */ mag_mul_ui(re, re, 289); mag_mul_2exp_si(re, re, -8); if (arb_is_zero(acb_imagref(z))) { /* todo: could bound magnitude even for complex numbers */ mag_set_ui(y, 2); mag_min(re, re, y); mag_zero(im); } else if (arb_is_zero(acb_realref(z))) { mag_swap(im, re); mag_zero(re); } else { mag_set(im, re); } mag_clear(x); mag_clear(y); } void acb_hypgeom_erf_1f1(acb_t res, const acb_t z, slong prec, slong wp, int more_imaginary) { if (acb_rel_accuracy_bits(z) >= wp) { if (more_imaginary) acb_hypgeom_erf_1f1a(res, z, wp); else acb_hypgeom_erf_1f1b(res, z, wp); } else { acb_t zmid; mag_t re_err, im_err; acb_init(zmid); mag_init(re_err); mag_init(im_err); acb_hypgeom_erf_propagated_error(re_err, im_err, z); arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z))); if (more_imaginary) acb_hypgeom_erf_1f1a(res, zmid, wp); else acb_hypgeom_erf_1f1b(res, zmid, wp); arb_add_error_mag(acb_realref(res), re_err); arb_add_error_mag(acb_imagref(res), im_err); acb_clear(zmid); mag_clear(re_err); mag_clear(im_err); } acb_set_round(res, res, prec); } void acb_hypgeom_erf(acb_t res, const acb_t z, slong prec) { double x, y, abs_z2, log_z, log_erf_z_asymp; slong prec2, wp; int more_imaginary; if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (acb_is_real(z)) { arb_hypgeom_erf(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); return; } if (acb_is_zero(z)) { acb_zero(res); return; } if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -64) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -64) < 0)) { acb_hypgeom_erf_1f1(res, z, prec, prec, 1); return; } if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 64) > 0 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 64) > 0)) { acb_hypgeom_erf_asymp(res, z, 0, prec, prec); return; } x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); abs_z2 = x * x + y * y; log_z = 0.5 * log(abs_z2); /* estimate of log(erf(z)), disregarding csgn term */ log_erf_z_asymp = y*y - x*x - log_z; if (log_z - abs_z2 < -(prec + 8) * 0.69314718055994530942) { /* If the asymptotic term is small, we can compute with reduced precision. */ prec2 = FLINT_MIN(prec + 4 + log_erf_z_asymp * 1.4426950408889634074, (double) prec); prec2 = FLINT_MAX(8, prec2); prec2 = FLINT_MIN(prec2, prec); acb_hypgeom_erf_asymp(res, z, 0, prec, prec2); } else { more_imaginary = arf_cmpabs(arb_midref(acb_imagref(z)), arb_midref(acb_realref(z))) > 0; /* Worst case: exp(|x|^2), computed: exp(x^2). (x^2+y^2) - (x^2-y^2) = 2y^2, etc. */ if (more_imaginary) wp = prec + FLINT_MAX(2 * x * x, 0.0) * 1.4426950408889634074 + 5; else wp = prec + FLINT_MAX(2 * y * y, 0.0) * 1.4426950408889634074 + 5; acb_hypgeom_erf_1f1(res, z, prec, wp, more_imaginary); } } arb-2.22.1/acb_hypgeom/erf_series.c000066400000000000000000000035751417376376500171460ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_erf_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { acb_t c; acb_init(c); acb_hypgeom_erf(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else { acb_ptr t, u; slong ulen; t = _acb_vec_init(len); u = _acb_vec_init(len); /* erf(h(x)) = integral(h'(x) exp(-h(x)^2)) * (2/sqrt(pi)) */ ulen = FLINT_MIN(len, 2 * hlen - 1); _acb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); _acb_vec_neg(u, u, ulen); _acb_poly_exp_series(u, u, ulen, len, prec); _acb_poly_derivative(t, h, hlen, prec); _acb_poly_mullow(g, u, len, t, hlen - 1, len, prec); _acb_poly_integral(g, g, len, prec); arb_const_sqrt_pi(acb_realref(t), prec); arb_inv(acb_realref(t), acb_realref(t), prec); arb_mul_2exp_si(acb_realref(t), acb_realref(t), 1); _acb_vec_scalar_mul_arb(g, g, len, acb_realref(t), prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_erf_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { acb_poly_zero(g); return; } acb_poly_fit_length(g, len); _acb_hypgeom_erf_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/erfc.c000066400000000000000000000053001417376376500157230ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_erfc(acb_t res, const acb_t z, slong prec) { double x, y, abs_z2, log_z, log_erfc_z_asymp; if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (acb_is_real(z)) { arb_hypgeom_erfc(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); return; } if (acb_is_zero(z)) { acb_one(res); return; } if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -64) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -64) < 0) || arf_sgn(arb_midref(acb_realref(z))) < 0) { acb_hypgeom_erf(res, z, prec); acb_sub_ui(res, res, 1, prec); acb_neg(res, res); return; } if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 64) > 0 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 64) > 0)) { acb_hypgeom_erf_asymp(res, z, 1, prec, prec); return; } x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); abs_z2 = x * x + y * y; if (abs_z2 > (prec + 8) * 0.69314718055994530942) { acb_hypgeom_erf_asymp(res, z, 1, prec, prec); } else { slong wp; log_z = 0.5 * log(abs_z2); log_erfc_z_asymp = y * y - x * x - log_z; wp = prec + 2; if (log_erfc_z_asymp < 0.0) wp += (-log_erfc_z_asymp) * 1.4426950408889634074; if (acb_rel_accuracy_bits(z) >= wp) { acb_hypgeom_erf(res, z, wp); } else { acb_t zmid; mag_t re_err, im_err; acb_init(zmid); mag_init(re_err); mag_init(im_err); acb_hypgeom_erf_propagated_error(re_err, im_err, z); arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z))); acb_hypgeom_erf(res, zmid, wp); arb_add_error_mag(acb_realref(res), re_err); arb_add_error_mag(acb_imagref(res), im_err); acb_clear(zmid); mag_clear(re_err); mag_clear(im_err); } acb_sub_ui(res, res, 1, prec); acb_neg(res, res); } } arb-2.22.1/acb_hypgeom/erfc_series.c000066400000000000000000000037401417376376500173030ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_erfc_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { acb_t c; acb_init(c); acb_hypgeom_erfc(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else { acb_ptr t, u; slong ulen; t = _acb_vec_init(len); u = _acb_vec_init(len); /* erfc(h(x)) = integral(-h'(x) exp(-h(x)^2)) * (2/sqrt(pi)) */ ulen = FLINT_MIN(len, 2 * hlen - 1); _acb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); _acb_vec_neg(u, u, ulen); _acb_poly_exp_series(u, u, ulen, len, prec); _acb_poly_derivative(t, h, hlen, prec); _acb_poly_mullow(g, u, len, t, hlen - 1, len, prec); _acb_poly_integral(g, g, len, prec); arb_const_sqrt_pi(acb_realref(t), prec); arb_inv(acb_realref(t), acb_realref(t), prec); arb_mul_2exp_si(acb_realref(t), acb_realref(t), 1); _acb_vec_scalar_mul_arb(g, g, len, acb_realref(t), prec); _acb_vec_neg(g, g, len); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_erfc_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_one(g); return; } acb_poly_fit_length(g, len); _acb_hypgeom_erfc_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/erfi.c000066400000000000000000000011111417376376500157250ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_erfi(acb_t res, const acb_t z, slong prec) { acb_mul_onei(res, z); acb_hypgeom_erf(res, res, prec); acb_mul_onei(res, res); acb_neg(res, res); } arb-2.22.1/acb_hypgeom/erfi_series.c000066400000000000000000000024621417376376500173110ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_erfi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_hypgeom_erfi(g, h, prec); _acb_vec_zero(g + 1, len - 1); } else { slong k; acb_ptr t = _acb_vec_init(hlen); for (k = 0; k < hlen; k++) acb_mul_onei(t + k, h + k); _acb_hypgeom_erf_series(g, t, hlen, len, prec); for (k = 0; k < len; k++) acb_div_onei(g + k, g + k); _acb_vec_clear(t, hlen); } } void acb_hypgeom_erfi_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { acb_poly_zero(g); return; } acb_poly_fit_length(g, len); _acb_hypgeom_erfi_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/expint.c000066400000000000000000000011731417376376500163170ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_expint(acb_t res, const acb_t s, const acb_t z, slong prec) { acb_t t; acb_init(t); acb_sub_ui(t, s, 1, prec); acb_neg(t, t); acb_hypgeom_gamma_upper(res, t, z, 2, prec); acb_clear(t); } arb-2.22.1/acb_hypgeom/fresnel.c000066400000000000000000000133721417376376500164520ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* We compute the following normalized versions internally: S(z) = (8/sqrt(pi)) int_0^z sin(2t^2) dt C(z) = (8/sqrt(pi)) int_0^z cos(2t^2) dt The benefit is that z^2 can be computed exactly inside erf when we have multiplied by 1+i instead of (1+i)/sqrt(2), so we get faster evaluation and better error bounds for Fresnel integrals on the real line (this is a bit of a hack, and it would be better to somehow pass z^2 directly to the erf evaluation code). */ void acb_hypgeom_fresnel_erf(acb_t res1, acb_t res2, const acb_t z, slong prec) { acb_t t, u, v, w1, w2; acb_init(t); acb_init(v); acb_init(w1); if (arb_is_zero(acb_imagref(z))) { acb_mul_onei(t, z); acb_add(w1, z, t, 2 * prec); acb_hypgeom_erf(t, w1, prec + 4); acb_mul_2exp_si(t, t, 1); acb_mul_onei(v, t); acb_add(t, t, v, prec); if (res1 != NULL) acb_set_arb(res1, acb_realref(t)); if (res2 != NULL) acb_set_arb(res2, acb_imagref(t)); } else if (arb_is_zero(acb_realref(z))) { acb_mul_onei(t, z); acb_sub(w1, t, z, 2 * prec); acb_hypgeom_erf(t, w1, prec + 4); acb_mul_2exp_si(t, t, 1); acb_mul_onei(v, t); acb_add(t, t, v, prec); if (res1 != NULL) acb_set_arb(res1, acb_realref(t)); if (res1 != NULL) acb_mul_onei(res1, res1); if (res2 != NULL) acb_set_arb(res2, acb_imagref(t)); if (res2 != NULL) acb_div_onei(res2, res2); } else { acb_init(u); acb_init(w2); /* w1 = (1+i)z, w2 = (1-i)z */ acb_mul_onei(t, z); acb_add(w1, z, t, 2 * prec); acb_sub(w2, z, t, 2 * prec); acb_hypgeom_erf(t, w1, prec + 4); acb_hypgeom_erf(u, w2, prec + 4); /* S = (1+i) (t - ui) = (1+i) t + (1-i) u */ /* C = (1-i) (t + ui) = (1-i) t + (1+i) u */ acb_mul_onei(v, t); if (res1 != NULL) acb_add(res1, t, v, prec); if (res2 != NULL) acb_sub(res2, t, v, prec); acb_mul_onei(v, u); if (res1 != NULL) acb_add(res1, res1, u, prec); if (res1 != NULL) acb_sub(res1, res1, v, prec); if (res2 != NULL) acb_add(res2, res2, u, prec); if (res2 != NULL) acb_add(res2, res2, v, prec); acb_clear(u); acb_clear(w2); } acb_clear(t); acb_clear(v); acb_clear(w1); } /* derivatives: |8/sqrt(pi) sin(2z^2)|, |8/sqrt(pi) cos(2z^2)| <= 5 exp(4|xy|) */ void acb_hypgeom_fresnel_erf_error(acb_t res1, acb_t res2, const acb_t z, slong prec) { mag_t re; mag_t im; acb_t zmid; mag_init(re); mag_init(im); acb_init(zmid); if (arf_cmpabs_ui(arb_midref(acb_realref(z)), 1000) < 0 && arf_cmpabs_ui(arb_midref(acb_imagref(z)), 1000) < 0) { arb_get_mag(re, acb_realref(z)); arb_get_mag(im, acb_imagref(z)); mag_mul(re, re, im); mag_mul_2exp_si(re, re, 2); mag_exp(re, re); mag_mul_ui(re, re, 5); } else { arb_t t; arb_init(t); arb_mul(t, acb_realref(z), acb_imagref(z), prec); arb_abs(t, t); arb_mul_2exp_si(t, t, 2); arb_exp(t, t, prec); arb_get_mag(re, t); mag_mul_ui(re, re, 5); arb_clear(t); } mag_hypot(im, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); mag_mul(re, re, im); if (arb_is_zero(acb_imagref(z))) { mag_set_ui(im, 8); /* For real x, |S(x)| < 4, |C(x)| < 4. */ mag_min(re, re, im); mag_zero(im); } else if (arb_is_zero(acb_realref(z))) { mag_set_ui(im, 8); mag_min(im, re, im); mag_zero(re); } else { mag_set(im, re); } arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z))); acb_hypgeom_fresnel_erf(res1, res2, zmid, prec); if (res1 != NULL) { arb_add_error_mag(acb_realref(res1), re); arb_add_error_mag(acb_imagref(res1), im); } if (res2 != NULL) { arb_add_error_mag(acb_realref(res2), re); arb_add_error_mag(acb_imagref(res2), im); } mag_clear(re); mag_clear(im); acb_clear(zmid); } void acb_hypgeom_fresnel(acb_t res1, acb_t res2, const acb_t z, int normalized, slong prec) { slong wp; acb_t w; arb_t c; if (!acb_is_finite(z)) { if (res1 != NULL) acb_indeterminate(res1); if (res2 != NULL) acb_indeterminate(res2); return; } acb_init(w); arb_init(c); wp = prec + 8; if (normalized) { arb_const_pi(c, wp); arb_sqrt(c, c, wp); arb_mul_2exp_si(c, c, -1); acb_mul_arb(w, z, c, wp); acb_hypgeom_fresnel_erf_error(res1, res2, w, wp); } else { arb_sqrt_ui(c, 2, wp); arb_mul_2exp_si(c, c, -1); acb_mul_arb(w, z, c, wp); acb_hypgeom_fresnel_erf_error(res1, res2, w, wp); arb_const_pi(c, wp); arb_mul_2exp_si(c, c, -1); arb_sqrt(c, c, wp); if (res1 != NULL) acb_mul_arb(res1, res1, c, wp); if (res2 != NULL) acb_mul_arb(res2, res2, c, wp); } if (res1 != NULL) { acb_mul_2exp_si(res1, res1, -2); acb_set_round(res1, res1, prec); } if (res2 != NULL) { acb_mul_2exp_si(res2, res2, -2); acb_set_round(res2, res2, prec); } acb_clear(w); arb_clear(c); } arb-2.22.1/acb_hypgeom/fresnel_series.c000066400000000000000000000057571417376376500200340ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_fresnel_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, int normalized, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_hypgeom_fresnel(s, c, h, normalized, prec); if (s != NULL) _acb_vec_zero(s + 1, len - 1); if (c != NULL) _acb_vec_zero(c + 1, len - 1); } else { acb_t s0, c0; acb_ptr t, u, v; slong ulen; acb_init(s0); acb_init(c0); acb_hypgeom_fresnel((s != NULL) ? s0 : NULL, (c != NULL) ? c0 : NULL, h, normalized, prec); t = _acb_vec_init(len); u = _acb_vec_init(len); v = _acb_vec_init(len); /* normalized: */ /* C(h(x)) = integral(h'(x) cos(-(pi/2) h(x)^2)) */ /* S(h(x)) = -integral(h'(x) sin(-(pi/2) h(x)^2)) */ ulen = FLINT_MIN(len, 2 * hlen - 1); _acb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); _acb_vec_neg(u, u, ulen); if (normalized) { _acb_vec_scalar_mul_2exp_si(u, u, ulen, -1); _acb_poly_sin_cos_pi_series(u, v, u, ulen, len, prec); } else { _acb_poly_sin_cos_series(u, v, u, ulen, len, prec); } _acb_poly_derivative(t, h, hlen, prec); if (s != NULL) { _acb_poly_mullow(s, u, len, t, hlen - 1, len, prec); _acb_poly_integral(s, s, len, prec); _acb_vec_neg(s, s, len); acb_swap(s, s0); } if (c != NULL) { _acb_poly_mullow(c, v, len, t, hlen - 1, len, prec); _acb_poly_integral(c, c, len, prec); acb_swap(c, c0); } _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(v, len); acb_clear(s0); acb_clear(c0); } } void acb_hypgeom_fresnel_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, int normalized, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { if (s != NULL) acb_poly_zero(s); if (c != NULL) acb_poly_zero(c); return; } if (s != NULL) acb_poly_fit_length(s, len); if (c != NULL) acb_poly_fit_length(c, len); _acb_hypgeom_fresnel_series((s != NULL) ? s->coeffs : NULL, (c != NULL) ? c->coeffs : NULL, h->coeffs, hlen, normalized, len, prec); if (s != NULL) _acb_poly_set_length(s, len); if (c != NULL) _acb_poly_set_length(c, len); if (s != NULL) _acb_poly_normalise(s); if (c != NULL) _acb_poly_normalise(c); } arb-2.22.1/acb_hypgeom/gamma.c000066400000000000000000000131061417376376500160710ustar00rootroot00000000000000/* Copyright (C) 2014, 2015, 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #include "arb_hypgeom.h" void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t z, int use_reflect, int digamma, slong prec); void acb_gamma_stirling_bound(mag_ptr err, const acb_t x, slong k0, slong knum, slong n); void acb_hypgeom_gamma_stirling_inner(acb_t s, const acb_t z, slong N, slong prec) { acb_t logz, t; mag_t err; mag_init(err); acb_init(t); acb_init(logz); acb_gamma_stirling_bound(err, z, 0, 1, N); /* t = (z-0.5)*log(z) - z + log(2*pi)/2 */ acb_log(logz, z, prec); arb_one(acb_realref(t)); arb_mul_2exp_si(acb_realref(t), acb_realref(t), -1); acb_sub(t, z, t, prec); acb_mul(t, logz, t, prec); acb_sub(t, t, z, prec); arb_const_log_sqrt2pi(acb_realref(logz), prec); arb_add(acb_realref(t), acb_realref(t), acb_realref(logz), prec); /* sum part */ if (prec <= 128 || (prec <= 1024 && N <= 40) || (prec <= 2048 && N <= 16)) acb_hypgeom_gamma_stirling_sum_horner(s, z, N, prec); else acb_hypgeom_gamma_stirling_sum_improved(s, z, N, 0, prec); acb_add(s, s, t, prec); acb_add_error_mag(s, err); acb_clear(t); acb_clear(logz); mag_clear(err); } void acb_hypgeom_gamma_stirling(acb_t y, const acb_t x, int reciprocal, slong prec) { int reflect; slong r, n, wp; acb_t t, u, v; double acc; wp = prec + FLINT_BIT_COUNT(prec); /* todo: for large x (if exact or accurate enough), increase precision */ acc = acb_rel_accuracy_bits(x); acc = FLINT_MAX(acc, 0); wp = FLINT_MIN(prec, acc + 20); wp = FLINT_MAX(wp, 2); wp = wp + FLINT_BIT_COUNT(wp); if (acc < 3) /* try to avoid divisions blowing up */ { if (arf_cmp_d(arb_midref(acb_realref(x)), -0.5) < 0) { reflect = 1; r = 0; } else if (arf_cmp_si(arb_midref(acb_realref(x)), 1) < 0) { reflect = 0; r = 1; } else { reflect = 0; r = 0; } n = 1; } else { acb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 0, wp); } acb_init(t); acb_init(u); acb_init(v); if (reflect) { acb_sub_ui(t, x, 1, wp); acb_neg(t, t); acb_hypgeom_rising_ui_rec(u, t, r, wp); arb_const_pi(acb_realref(v), wp); acb_mul_arb(u, u, acb_realref(v), wp); acb_add_ui(t, t, r, wp); acb_hypgeom_gamma_stirling_inner(v, t, n, wp); if (reciprocal) { /* rgamma(x) = gamma(1-x+r) sin(pi x) / ((rf(1-x, r) * pi) */ acb_exp(v, v, wp); acb_sin_pi(t, x, wp); acb_mul(v, v, t, wp); acb_mul(y, u, v, wp); acb_div(y, v, u, prec); } else { /* gamma(x) = (rf(1-x, r) * pi) rgamma(1-x+r) csc(pi x) */ acb_neg(v, v); acb_exp(v, v, wp); acb_csc_pi(t, x, wp); acb_mul(v, v, t, wp); acb_mul(y, v, u, prec); } } else { acb_add_ui(t, x, r, wp); acb_hypgeom_gamma_stirling_inner(u, t, n, wp); if (reciprocal) { /* rgamma(x) = rf(x,r) rgamma(x+r) */ acb_neg(u, u); acb_exp(u, u, prec); acb_hypgeom_rising_ui_rec(v, x, r, wp); acb_mul(y, v, u, prec); } else { /* gamma(x) = gamma(x+r) / rf(x,r) */ acb_exp(u, u, prec); acb_hypgeom_rising_ui_rec(v, x, r, wp); acb_div(y, u, v, prec); } } acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_gamma(acb_t y, const acb_t x, slong prec) { if (acb_is_real(x)) { arb_hypgeom_gamma(acb_realref(y), acb_realref(x), prec); arb_zero(acb_imagref(y)); return; } if (acb_hypgeom_gamma_taylor(y, x, 0, prec)) return; acb_hypgeom_gamma_stirling(y, x, 0, prec); } void acb_hypgeom_rgamma(acb_t y, const acb_t x, slong prec) { mag_t magz; if (acb_is_real(x)) { arb_hypgeom_rgamma(acb_realref(y), acb_realref(x), prec); arb_zero(acb_imagref(y)); return; } if (acb_hypgeom_gamma_taylor(y, x, 1, prec)) return; mag_init(magz); acb_get_mag(magz, x); if (mag_is_inf(magz)) { acb_indeterminate(y); } else { acb_hypgeom_gamma_stirling(y, x, 1, prec); /* Todo: improved bounds computation */ if (!acb_is_finite(y)) { arb_t t, u, R; arb_init(R); arb_init(t); arb_init(u); arf_set_mag(arb_midref(R), magz); arb_set_d(u, 0.5); arb_add(u, u, R, MAG_BITS); arb_pow(u, R, u, MAG_BITS); arb_const_pi(t, MAG_BITS); arb_mul(t, t, R, MAG_BITS); arb_mul_2exp_si(t, t, -1); arb_exp(t, t, MAG_BITS); arb_mul(t, t, u, MAG_BITS); arb_get_mag(magz, t); acb_zero(y); acb_add_error_mag(y, magz); arb_clear(R); arb_clear(t); arb_clear(u); } } mag_clear(magz); } arb-2.22.1/acb_hypgeom/gamma_lower.c000066400000000000000000000025631417376376500173060ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_gamma_lower(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) { acb_t s1, nz, t, u; if (!acb_is_finite(s) || !acb_is_finite(z)) { acb_indeterminate(res); return; } acb_init(s1); acb_init(nz); acb_init(t); acb_init(u); acb_add_ui(s1, s, 1, prec); acb_neg(nz, z); if (regularized == 0) { /* \gamma(s, z) = s^-1 z^s 1F1(s, 1+s, -z) */ acb_hypgeom_m(u, s, s1, nz, 0, prec); acb_pow(t, z, s, prec); acb_mul(u, u, t, prec); acb_div(res, u, s, prec); } else if (regularized == 1) { /* P(s, z) = z^s \gamma^{*}(s, z) */ acb_hypgeom_m(u, s, s1, nz, 1, prec); acb_pow(t, z, s, prec); acb_mul(res, u, t, prec); } else if (regularized == 2) { /* \gamma^{*}(s, z) */ acb_hypgeom_m(res, s, s1, nz, 1, prec); } acb_clear(s1); acb_clear(nz); acb_clear(t); acb_clear(u); } arb-2.22.1/acb_hypgeom/gamma_lower_series.c000066400000000000000000000062111417376376500206520ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_hypgeom.h" void _acb_hypgeom_gamma_lower_series(acb_ptr g, const acb_t s, acb_srcptr h, slong hlen, int regularized, slong n, slong prec) { acb_t c; hlen = FLINT_MIN(hlen, n); if (regularized == 2 && acb_is_int(s) && arb_is_nonpositive(acb_realref(s))) { acb_t ns; acb_init(ns); acb_neg(ns, s); if (g == h) { acb_ptr t = _acb_vec_init(hlen); _acb_vec_set(t, h, hlen); _acb_poly_pow_acb_series(g, t, hlen, ns, n, prec); _acb_vec_clear(t, hlen); } else { _acb_poly_pow_acb_series(g, h, hlen, ns, n, prec); } acb_clear(ns); return; } acb_init(c); acb_hypgeom_gamma_lower(c, s, h, regularized, prec); if (hlen == 1) { _acb_vec_zero(g + 1, n - 1); } else { acb_ptr t, u, v; acb_ptr w = NULL; t = _acb_vec_init(n); u = _acb_vec_init(n); v = _acb_vec_init(n); if (regularized == 2) { w = _acb_vec_init(n); acb_neg(t, s); _acb_poly_pow_acb_series(w, h, hlen, t, n, prec); } /* gamma(s, h(x)) = integral(h'(x) h(x)^(s-1) exp(-h(x)) */ acb_sub_ui(u, s, 1, prec); _acb_poly_pow_acb_series(t, h, hlen, u, n, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_mullow(v, t, n, u, hlen - 1, n, prec); _acb_vec_neg(t, h, hlen); _acb_poly_exp_series(t, t, hlen, n, prec); _acb_poly_mullow(g, v, n, t, n, n, prec); _acb_poly_integral(g, g, n, prec); if (regularized == 1) { acb_rgamma(t, s, prec); _acb_vec_scalar_mul(g, g, n, t, prec); } else if (regularized == 2) { acb_rgamma(t, s, prec); _acb_vec_scalar_mul(g, g, n, t, prec); _acb_vec_set(u, g, n); _acb_poly_mullow(g, u, n, w, n, n, prec); _acb_vec_clear(w, n); } _acb_vec_clear(t, n); _acb_vec_clear(u, n); _acb_vec_clear(v, n); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_gamma_lower_series(acb_poly_t g, const acb_t s, const acb_poly_t h, int regularized, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(g); return; } acb_poly_fit_length(g, n); if (hlen == 0) { acb_t t; acb_init(t); _acb_hypgeom_gamma_lower_series(g->coeffs, s, t, 1, regularized, n, prec); acb_clear(t); } else { _acb_hypgeom_gamma_lower_series( g->coeffs, s, h->coeffs, hlen, regularized, n, prec); } _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/gamma_stirling_sum_horner.c000066400000000000000000000033341417376376500222470ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void arb_gamma_stirling_coeff(acb_t b, ulong k, int digamma, slong prec); void acb_hypgeom_gamma_stirling_sum_horner(acb_t s, const acb_t z, slong N, slong prec) { acb_t b, t, zinv, w; mag_t zinv_mag; slong n, term_mag, term_prec; slong * term_mags; if (N <= 1) { acb_zero(s); return; } acb_init(b); acb_init(t); acb_init(zinv); acb_init(w); mag_init(zinv_mag); acb_inv(zinv, z, prec); acb_mul(w, zinv, zinv, prec); acb_get_mag(zinv_mag, zinv); term_mags = flint_malloc(sizeof(ulong) * N); _arb_hypgeom_gamma_stirling_term_bounds(term_mags, zinv_mag, N); acb_zero(s); for (n = N - 1; n >= 1; n--) { term_mag = term_mags[n]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); if (prec - term_prec > 200) { acb_set_round(t, w, term_prec); acb_mul(s, s, t, term_prec); } else acb_mul(s, s, w, term_prec); arb_gamma_stirling_coeff(b, n, 0, term_prec); acb_add(s, s, b, term_prec); } acb_mul(s, s, zinv, prec); flint_free(term_mags); acb_clear(t); acb_clear(b); acb_clear(zinv); acb_clear(w); mag_clear(zinv_mag); } arb-2.22.1/acb_hypgeom/gamma_stirling_sum_improved.c000066400000000000000000000311451417376376500226000ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" #include "bernoulli.h" /* todo: move to acb module */ static void acb_fma_ui(acb_t res, const acb_t x, ulong y, const acb_t z, slong prec) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ arb_fma_arf(acb_realref(res), acb_realref(x), t, acb_realref(z), prec); arb_fma_arf(acb_imagref(res), acb_imagref(x), t, acb_imagref(z), prec); } void acb_hypgeom_gamma_stirling_sum_improved(acb_t s, const acb_t z, slong N, slong K, slong prec) { acb_t b, t, zinv, w, u, S2, S3, S4; mag_t zinv_mag, err; slong n, term_mag, term_prec; slong * term_mags; slong i, j, k, M; slong * Mk; acb_ptr upow, ukpow; slong kodd, kpow_exp, wp; fmpz_t kpow; slong m; if (N <= 1) { acb_zero(s); return; } if (N == 2) { acb_mul_ui(s, z, 12, prec); acb_inv(s, s, prec); return; } if (K == 0) { if (prec <= 128) K = 1; else if (prec <= 1024) K = 2; else { K = 4 + 0.1 * sqrt(FLINT_MAX(prec - 4096, 0)); K = FLINT_MIN(K, 100); } } acb_init(b); acb_init(t); acb_init(zinv); acb_init(w); acb_init(u); acb_init(S2); acb_init(S3); acb_init(S4); mag_init(zinv_mag); mag_init(err); acb_inv(zinv, z, prec); acb_mul(w, zinv, zinv, prec); acb_get_mag(zinv_mag, zinv); term_mags = flint_malloc(sizeof(ulong) * (N + 1)); /* Avoid possible overflow. (This case is not interesting to handle well, but we need to handle it.) */ if (mag_cmp_2exp_si(zinv_mag, 10) > 0) K = 1; /* Avoid possible underflow. */ if (mag_cmp_2exp_si(zinv_mag, -100000) < 0) mag_set_ui_2exp_si(zinv_mag, 1, -100000); _arb_hypgeom_gamma_stirling_term_bounds(term_mags, zinv_mag, N + 1); /* We will assume below that term_mags is nonincreasing */ for (n = N - 2; n >= 1; n--) { if (term_mags[n] < term_mags[n + 1]) term_mags[n] = term_mags[n + 1]; } Mk = NULL; if (K > 1) { Mk = flint_malloc(sizeof(slong) * (K + 1)); Mk[0] = Mk[1] = N; for (k = 2; k <= K; k++) { double log2_k; Mk[k] = N; log2_k = log(k) * (1.0 / 0.693147180559945309); while (Mk[k] > 2) { slong err, Mnew; Mnew = Mk[k] - 1; err = term_mags[Mnew] - log2_k * (2 * Mnew) + FLINT_BIT_COUNT(N - Mnew); if (err < -prec) Mk[k] = Mnew; else break; } } /* We will assume that Mk is nonincreasing. */ for (k = 2; k <= K; k++) { if (Mk[k] > Mk[k - 1]) Mk[k] = Mk[k - 1]; } while (K >= 2 && Mk[K] == Mk[K - 1]) K--; M = Mk[K]; mag_hurwitz_zeta_uiui(err, 2 * M, K); mag_mul_ui(err, err, N - M); mag_mul_2exp_si(err, err, term_mags[M]); for (k = 1; k < K; k++) { mag_t t; mag_init(t); mag_set_ui_lower(t, k); mag_inv(t, t); mag_pow_ui(t, t, 2 * Mk[k]); mag_mul_ui(t, t, N - Mk[k]); mag_mul_2exp_si(t, t, term_mags[Mk[k]]); mag_add(err, err, t); mag_clear(t); } } else { M = N; } m = sqrt(N - M); m = FLINT_MAX(m, 1); /* S3 precision */ wp = prec + term_mags[M]; wp = FLINT_MIN(wp, prec); wp = FLINT_MAX(wp, 10); acb_zero(S3); /* todo: could avoid one mul + div with precomputation here */ /* u = -1 / (2 pi z)^2 */ acb_const_pi(u, wp); acb_mul(u, u, z, wp); acb_mul_2exp_si(u, u, 1); acb_mul(u, u, u, wp); acb_inv(u, u, wp); acb_neg(u, u); fmpz_init(kpow); upow = _acb_vec_init(m + 1); ukpow = _acb_vec_init(m + 1); _acb_vec_set_powers(upow, u, m + 1, wp); for (kodd = 1; kodd < K; kodd += 2) { for (k = kodd; k < K; k *= 2) { if (k == 1) { _acb_vec_set(ukpow, upow, m + 1); fmpz_one(kpow); kpow_exp = 0; } else if (k == kodd) { acb_set(ukpow + 0, upow + 0); for (j = 1; j <= FLINT_MIN(Mk[k] - M - 1, m); j++) { if (j == 1) fmpz_set_ui(kpow, k * k); else fmpz_mul_ui(kpow, kpow, k * k); acb_div_fmpz(ukpow + j, upow + j, kpow, wp); } /* set kpow = k^(2M) */ fmpz_ui_pow_ui(kpow, k * k, M); kpow_exp = 0; } else { /* compute x / k^(2j) given x / (k/2)^(2j) */ for (j = 1; j <= FLINT_MIN(Mk[k] - M - 1, m); j++) acb_mul_2exp_si(ukpow + j, ukpow + j, -2 * j); kpow_exp += 2 * M; } acb_zero(S4); for (n = Mk[k] - 1; n >= M; n--) { i = n - M; term_prec = prec + term_mags[n]; term_prec = FLINT_MIN(wp, prec); term_prec = FLINT_MAX(term_prec, 10); /* note: set_round makes small difference here */ acb_fma_ui(S4, S4, (2 * n) * (2 * n - 1), ukpow + i % m, term_prec); if (i != 0 && i % m == 0) { /* note: set_round makes small difference here */ acb_mul(S4, S4, ukpow + m, term_prec); } } /* divide by k^(2M) */ if (k != 1) { if (!fmpz_is_one(kpow)) acb_div_fmpz(S4, S4, kpow, wp); acb_mul_2exp_si(S4, S4, -kpow_exp); } acb_add(S3, S3, S4, wp); } } /* multiply by -2 (2M-2)! u^M z */ fmpz_fac_ui(kpow, 2 * M - 2); acb_mul_fmpz(S3, S3, kpow, wp); acb_pow_ui(u, u, M, wp); acb_mul(S3, S3, u, wp); acb_set_round(t, z, wp); acb_mul(S3, S3, t, wp); acb_mul_2exp_si(S3, S3, 1); acb_neg(S3, S3); acb_add_error_mag(S3, err); _acb_vec_clear(upow, m + 1); _acb_vec_clear(ukpow, m + 1); fmpz_clear(kpow); acb_zero(S2); m = sqrt(M); upow = _acb_vec_init(m + 1); _acb_vec_set_powers(upow, w, m + 1, prec); BERNOULLI_ENSURE_CACHED(2 * M - 2); { fmpz_t d, e, f, g, h; fmpz q[4]; fmpz_init(d); fmpz_init(e); fmpz_init(f); fmpz_init(g); fmpz_init(h); fmpz_init(q); fmpz_init(q + 1); fmpz_init(q + 2); fmpz_init(q + 3); for (n = M - 1; n >= 1; n--) { i = n - 1; if (i >= 4 && i % m >= 3 && prec >= 512 && prec <= 4096) { term_mag = term_mags[n - 3]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * (n - 0)), 2 * (n - 0) * (2 * (n - 0) - 1)); fmpz_mul_ui(e, fmpq_denref(bernoulli_cache + 2 * (n - 1)), 2 * (n - 1) * (2 * (n - 1) - 1)); fmpz_mul_ui(g, fmpq_denref(bernoulli_cache + 2 * (n - 2)), 2 * (n - 2) * (2 * (n - 2) - 1)); fmpz_mul_ui(h, fmpq_denref(bernoulli_cache + 2 * (n - 3)), 2 * (n - 3) * (2 * (n - 3) - 1)); /* q3 = egh q2 = dgh q1 = deh q0 = deg d = degh */ fmpz_mul(q + 3, e, g); fmpz_mul(q + 0, q + 3, d); fmpz_mul(q + 3, q + 3, h); fmpz_mul(q + 2, d, h); fmpz_mul(q + 1, q + 2, e); fmpz_mul(q + 2, q + 2, g); fmpz_mul(d, q + 3, d); fmpz_mul(q + 3, q + 3, fmpq_numref(bernoulli_cache + 2 * (n - 0))); fmpz_mul(q + 2, q + 2, fmpq_numref(bernoulli_cache + 2 * (n - 1))); fmpz_mul(q + 1, q + 1, fmpq_numref(bernoulli_cache + 2 * (n - 2))); fmpz_mul(q + 0, q + 0, fmpq_numref(bernoulli_cache + 2 * (n - 3))); acb_dot_fmpz(t, NULL, 0, upow + i % m - 3, 1, q, 1, 4, term_prec); acb_div_fmpz(t, t, d, term_prec); acb_add(S2, S2, t, term_prec); n -= 3; i -= 3; } else if (i >= 3 && i % m >= 2) { term_mag = term_mags[n - 2]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * (n - 0)), 2 * (n - 0) * (2 * (n - 0) - 1)); fmpz_mul_ui(e, fmpq_denref(bernoulli_cache + 2 * (n - 1)), 2 * (n - 1) * (2 * (n - 1) - 1)); fmpz_mul_ui(g, fmpq_denref(bernoulli_cache + 2 * (n - 2)), 2 * (n - 2) * (2 * (n - 2) - 1)); fmpz_mul(q + 2, e, g); fmpz_mul(q + 2, q + 2, fmpq_numref(bernoulli_cache + 2 * (n - 0))); fmpz_mul(q + 1, d, g); fmpz_mul(q + 1, q + 1, fmpq_numref(bernoulli_cache + 2 * (n - 1))); fmpz_mul(q + 0, d, e); fmpz_mul(d, q + 0, g); fmpz_mul(q + 0, q + 0, fmpq_numref(bernoulli_cache + 2 * (n - 2))); acb_dot_fmpz(t, NULL, 0, upow + i % m - 2, 1, q, 1, 3, term_prec); acb_div_fmpz(t, t, d, term_prec); acb_add(S2, S2, t, term_prec); n -= 2; i -= 2; } else if (i >= 1 && i % m >= 1) { term_mag = term_mags[n - 1]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * (n - 0)), 2 * (n - 0) * (2 * (n - 0) - 1)); fmpz_mul_ui(e, fmpq_denref(bernoulli_cache + 2 * (n - 1)), 2 * (n - 1) * (2 * (n - 1) - 1)); fmpz_mul(f, fmpq_numref(bernoulli_cache + 2 * (n - 0)), e); acb_set_round(u, upow + i % m, term_prec); acb_mul_fmpz(t, u, f, term_prec); /* todo: output-sensitive mul */ fmpz_mul(f, fmpq_numref(bernoulli_cache + 2 * (n - 1)), d); acb_set_round(u, upow + i % m - 1, term_prec); acb_mul_fmpz(u, u, f, term_prec); /* todo: output-sensitive mul */ acb_add(t, t, u, term_prec); fmpz_mul(d, d, e); acb_div_fmpz(t, t, d, term_prec); acb_add(S2, S2, t, term_prec); n--; i--; } else { term_mag = term_mags[n]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); acb_set_round(u, upow + i % m, term_prec); acb_mul_fmpz(t, u, fmpq_numref(bernoulli_cache + 2 * n), term_prec); /* todo: output-sensitive mul */ fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * n), 2 * n * (2 * n - 1)); acb_div_fmpz(t, t, d, term_prec); acb_add(S2, S2, t, term_prec); } if (i != 0 && i % m == 0) { acb_set_round(u, upow + m, term_prec); /* todo: output-sensitive mul */ acb_mul(S2, S2, u, term_prec); } } fmpz_clear(q); fmpz_clear(q + 1); fmpz_clear(q + 2); fmpz_clear(q + 3); fmpz_clear(d); fmpz_clear(e); fmpz_clear(f); fmpz_clear(g); fmpz_clear(h); } _acb_vec_clear(upow, m + 1); acb_mul(S2, S2, zinv, prec); acb_add(s, S2, S3, prec); flint_free(term_mags); if (Mk != NULL) flint_free(Mk); acb_clear(b); acb_clear(t); acb_clear(zinv); acb_clear(w); acb_clear(u); acb_clear(S2); acb_clear(S3); acb_clear(S4); mag_clear(zinv_mag); mag_clear(err); } arb-2.22.1/acb_hypgeom/gamma_taylor.c000066400000000000000000000146441417376376500174730ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" static void evaluate_rect(acb_t res, const short * term_prec, slong len, const acb_t x, slong prec) { slong i, j, m, r, n1, n2; acb_ptr xs; acb_t s, t; arb_struct c[17]; m = n_sqrt(len) + 1; m = FLINT_MIN(m, 16); r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); _acb_vec_set_powers(xs, x, m + 1, prec); acb_zero(res); for (i = r - 1; i >= 0; i--) { n1 = m * i; n2 = FLINT_MIN(len, n1 + m); for (j = n1; j < n2; j++) { if (j == 0) { arb_init(c); arb_one(c); } else { if (!_arb_hypgeom_gamma_coeff_shallow(arb_midref(c + j - n1), arb_radref(c + j - n1), j, term_prec[j])) flint_abort(); } } arb_dot(acb_realref(s), NULL, 0, acb_realref(xs), 2, c, 1, n2 - n1, prec); arb_dot(acb_imagref(s), NULL, 0, acb_imagref(xs), 2, c, 1, n2 - n1, prec); #if 0 acb_set_round(t, xs + m, term_prec[n1]); acb_mul(res, res, t, term_prec[n1]); acb_add(res, res, s, term_prec[n1]); #else acb_mul(res, res, xs + m, term_prec[n1]); acb_add(res, res, s, term_prec[n1]); #endif } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); } /* Bound requires: |u| <= 20, N <= 10000, N != (1443, 2005, 9891). */ static void error_bound(mag_t err, const acb_t u, slong N) { mag_t t; mag_init(t); acb_get_mag(t, u); if (N >= 1443 || mag_cmp_2exp_si(t, 4) > 0) { mag_inf(err); } else { mag_pow_ui(err, t, N); mag_mul_2exp_si(err, err, arb_hypgeom_gamma_coeffs[N].exp); if (mag_cmp_2exp_si(t, -1) > 0) mag_mul(err, err, t); else mag_mul_2exp_si(err, err, -1); mag_mul_2exp_si(err, err, 3); if (mag_cmp_2exp_si(err, -8) > 0) mag_inf(err); } mag_clear(t); } static double want_taylor(double x, double y, slong prec) { if (y < 0.0) y = -y; if (x < 0.0) x = -x; if ((prec < 128 && y > 4.0) || (prec < 256 && y > 5.0) || (prec < 512 && y > 8.0) || (prec < 1024 && y > 9.0) || y > 10.0) { return 0; } if (x * (1.0 + 0.75 * y) > 8 + 0.15 * prec) { return 0; } return 1; } int acb_hypgeom_gamma_taylor(acb_t res, const acb_t z, int reciprocal, slong prec) { acb_t s, u; int success; double dua, dub, du2, log2u; slong i, r, n, wp, tail_bound, goal; short term_prec[ARB_HYPGEOM_GAMMA_TAB_NUM]; mag_t err; if (!acb_is_finite(z) || arf_cmp_2exp_si(arb_midref(acb_imagref(z)), 4) >= 0 || arf_cmp_2exp_si(arb_midref(acb_realref(z)), 10) >= 0) { return 0; } dua = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_UP); dub = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_UP); dub = fabs(dub); if (!want_taylor(dua, dub, prec)) return 0; if (dua >= 0.0) r = (slong) (dua + 0.5); else r = -(slong) (-dua + 0.5); acb_init(s); acb_init(u); mag_init(err); success = 0; /* Argument reduction: u = z - r */ acb_sub_si(u, z, r, 2 * prec + 10); dua -= r; goal = acb_rel_accuracy_bits(u); /* not designed for wide intervals (yet) */ if (goal < 8) { success = 0; goto cleanup; } goal = FLINT_MIN(goal, prec - MAG_BITS) + MAG_BITS; goal = FLINT_MAX(goal, 5); goal = goal + 5; wp = goal + 4 + FLINT_BIT_COUNT(FLINT_ABS(r)); if (wp > ARB_HYPGEOM_GAMMA_TAB_PREC) { success = 0; goto cleanup; } if (!want_taylor(r, dub, goal)) { success = 0; goto cleanup; } du2 = dua * dua + dub * dub; if (du2 > 1e-8) { log2u = 0.5 * mag_d_log_upper_bound(du2) * 1.4426950408889634074 * (1 + 1e-14); } else { slong aexp, bexp; aexp = arf_cmpabs_2exp_si(arb_midref(acb_realref(u)), -wp) >= 0 ? ARF_EXP(arb_midref(acb_realref(u))) : -wp; bexp = arf_cmpabs_2exp_si(arb_midref(acb_imagref(u)), -wp) >= 0 ? ARF_EXP(arb_midref(acb_imagref(u))) : -wp; log2u = FLINT_MAX(aexp, bexp) + 1; } term_prec[0] = wp; n = 0; for (i = 1; i < ARB_HYPGEOM_GAMMA_TAB_NUM; i++) { tail_bound = arb_hypgeom_gamma_coeffs[i].exp + i * log2u + 5; if (tail_bound <= -goal) { n = i; break; } term_prec[i] = FLINT_MIN(FLINT_MAX(wp + tail_bound, 2), wp); if (term_prec[i] > arb_hypgeom_gamma_coeffs[i].nlimbs * FLINT_BITS) { success = 0; goto cleanup; } } if (n != 0) error_bound(err, u, n); if (n == 0 || mag_is_inf(err)) { success = 0; goto cleanup; } evaluate_rect(s, term_prec, n, u, wp); acb_add_error_mag(s, err); if (r == 0 || r == 1) { if (r == 0) acb_mul(s, s, u, wp); if (reciprocal) { acb_set_round(res, s, prec); } else { acb_one(u); acb_div(res, u, s, prec); } } else if (r >= 2) { acb_add_ui(u, u, 1, wp); acb_hypgeom_rising_ui_rec(u, u, r - 1, wp); if (reciprocal) acb_div(res, s, u, prec); else acb_div(res, u, s, prec); } else { /* gamma(x) = (-1)^r / (rgamma(1+x-r)*rf(1+r-x,-r)*(x-r)) */ /* 1/gamma(x) = (-1)^r * rgamma(1+x-r) * rf(1+r-x,-r) * (x-r) */ acb_neg(res, z); acb_add_si(res, res, 1 + r, wp); acb_hypgeom_rising_ui_rec(res, res, -r, wp); acb_mul(u, res, u, wp); if (reciprocal) { acb_mul(res, s, u, prec); } else { acb_mul(u, s, u, wp); acb_inv(res, u, prec); } if (r % 2) acb_neg(res, res); } success = 1; cleanup: acb_clear(s); acb_clear(u); mag_clear(err); return success; } arb-2.22.1/acb_hypgeom/gamma_upper.c000066400000000000000000000314051417376376500173060ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" int acb_hypgeom_u_asymp_determine_region(const mag_t r, const mag_t zlo, const acb_t z); void acb_hypgeom_gamma_upper_asymp(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_sub_ui(t, s, 1, prec); acb_neg(t, t); acb_hypgeom_u_asymp(u, t, t, z, -1, prec); if (regularized == 2) { acb_div(u, u, z, prec); } else { acb_neg(t, t); acb_pow(t, z, t, prec); acb_mul(u, u, t, prec); if (regularized == 1) { acb_rgamma(t, s, prec); acb_mul(u, u, t, prec); } } acb_neg(t, z); acb_exp(t, t, prec); acb_mul(res, t, u, prec); acb_clear(t); acb_clear(u); } void acb_hypgeom_gamma_upper_1f1a(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) { acb_t a, t, w; acb_struct b[2]; acb_init(a); acb_init(b); acb_init(b + 1); acb_init(t); acb_init(w); acb_set(a, s); acb_add_ui(b, s, 1, prec); acb_one(b + 1); acb_neg(w, z); /* t = 1F1(s, s+1, -z) / s */ acb_hypgeom_pfq_direct(t, a, 1, b, 2, w, -1, prec); acb_div(t, t, s, prec); if (regularized == 2) { acb_neg(a, s); acb_pow(a, z, a, prec); acb_gamma(b, s, prec); acb_mul(b, b, a, prec); acb_sub(res, b, t, prec); } else { acb_pow(a, z, s, prec); acb_mul(t, t, a, prec); if (regularized == 1) { acb_rgamma(a, s, prec); acb_mul(t, t, a, prec); acb_sub_ui(res, t, 1, prec); acb_neg(res, res); } else { acb_gamma(a, s, prec); acb_sub(res, a, t, prec); } } acb_clear(a); acb_clear(b); acb_clear(b + 1); acb_clear(t); acb_clear(w); } void acb_hypgeom_gamma_upper_1f1b(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) { acb_t a, b, t; acb_init(a); acb_init(b); acb_init(t); acb_add_ui(b, s, 1, prec); acb_hypgeom_pfq_direct(t, NULL, 0, b, 1, z, -1, prec); acb_div(t, t, s, prec); acb_neg(a, z); acb_exp(a, a, prec); acb_mul(t, t, a, prec); if (regularized == 2) { acb_neg(a, s); acb_pow(a, z, a, prec); acb_gamma(b, s, prec); acb_mul(b, b, a, prec); acb_sub(res, b, t, prec); } else { acb_pow(a, z, s, prec); acb_mul(t, t, a, prec); if (regularized == 1) { acb_rgamma(a, s, prec); acb_mul(t, t, a, prec); acb_sub_ui(res, t, 1, prec); acb_neg(res, res); } else { acb_gamma(a, s, prec); acb_sub(res, a, t, prec); } } acb_clear(a); acb_clear(b); acb_clear(t); } /* requires n <= 0 */ void acb_hypgeom_gamma_upper_singular(acb_t res, slong s, const acb_t z, int regularized, slong prec) { acb_t A, B, C, t, u; acb_struct a[2]; acb_struct b[2]; arb_t f; slong n; if (regularized == 1) { acb_zero(res); return; } n = -s; acb_init(A); acb_init(B); acb_init(C); acb_init(t); acb_init(u); arb_init(f); acb_init(a + 0); acb_init(a + 1); acb_init(b + 0); acb_init(b + 1); arb_fac_ui(f, n, prec); /* (-1)^n (psi(n+1) - log(z)) / n! */ acb_set_ui(A, n + 1); acb_digamma(A, A, prec); acb_log(t, z, prec); acb_sub(A, A, t, prec); acb_div_arb(A, A, f, prec); if (n % 2) acb_neg(A, A); /* (-1)^n z 2F2(1,1;2,2+n;-z) / (n+1)! */ acb_set_si(a, 1); acb_set_si(b, 2); acb_set_si(b + 1, 2 + n); acb_neg(t, z); acb_hypgeom_pfq_direct(B, a, 1, b, 2, t, -1, prec); acb_mul(B, B, z, prec); arb_mul_ui(f, f, n + 1, prec); acb_div_arb(B, B, f, prec); if (n % 2) acb_neg(B, B); /* -sum((-z)^k / ((k-n) k!), k=0...n-1) */ acb_set_si(a, -n); acb_set_si(b, 1 - n); acb_set_si(b + 1, 1); acb_neg(t, z); if (n == 0) { acb_zero(C); } else { acb_hypgeom_pfq_sum(C, u, a, 1, b, 2, t, n, prec); acb_div_ui(C, C, n, prec); } if (regularized == 2) { acb_pow_si(t, z, n, prec); acb_mul(A, A, t, prec); acb_mul(B, B, t, prec); } else { acb_pow_si(t, z, -n, prec); acb_mul(C, C, t, prec); } acb_add(res, A, B, prec); acb_add(res, res, C, prec); acb_clear(A); acb_clear(B); acb_clear(C); acb_clear(t); acb_clear(u); arb_clear(f); acb_clear(a + 0); acb_clear(a + 1); acb_clear(b + 0); acb_clear(b + 1); } static int _determine_region(const acb_t s, const acb_t z) { int R; mag_t r, zlo; acb_t t; mag_init(r); mag_init(zlo); acb_init(t); /* lower bound for |z| */ acb_get_mag_lower(zlo, z); /* upper bound for r = |s - 1| */ acb_sub_ui(t, s, 1, MAG_BITS); acb_get_mag(r, t); R = acb_hypgeom_u_asymp_determine_region(r, zlo, z); mag_clear(r); mag_clear(zlo); acb_clear(t); return R; } /* Returns 1 if it can be determined that a^n > b^n + c^n. * Requires 1 <= n <= WORD_MAX. * If n == WORD_MAX, the infinity norm a > max(b, c) is compared instead. */ int _mag_gt_norm_ui(const mag_t a, const mag_t b, const mag_t c, ulong n) { int result; result = 0; if (n < 1) { flint_abort(); } else if (mag_is_zero(a)) { result = 0; } else if (mag_is_zero(b)) { result = mag_cmp(a, c) > 0; } else if (mag_is_zero(c)) { result = mag_cmp(a, b) > 0; } else if (n == WORD_MAX) { result = mag_cmp(a, b) > 0 && mag_cmp(a, c) > 0; } else if (n == 1) { mag_t sum; mag_init(sum); mag_add(sum, b, c); result = mag_cmp(a, sum) > 0; mag_clear(sum); } else if (_mag_gt_norm_ui(a, b, c, 1)) { result = 1; } else if (!_mag_gt_norm_ui(a, b, c, WORD_MAX)) { result = 0; } else { mag_t u, v, w, sum; mag_init(u); mag_init(v); mag_init(w); mag_init(sum); mag_pow_ui_lower(u, a, n); mag_pow_ui(v, b, n); mag_pow_ui(w, c, n); mag_add(sum, v, w); result = mag_cmp(u, sum) > 0; mag_clear(u); mag_clear(v); mag_clear(w); mag_clear(sum); } return result; } /* Given nonnegative real s, x, and prec, * returns 1 if the asymptotic expansion of the * hypergeometric U function should be used for upper incomplete gamma. * It returns 1 if x > 4 and (x-c)^8 > (a*s)^8 + (b*prec)^8. * Careful mag rounding is not used because this is just a heuristic. */ static int _nonnegative_real_use_asymp(const mag_t s, const mag_t x, slong prec) { int result; result = 0; if (mag_cmp_2exp_si(x, 2) > 0) { mag_t a, b, c, u, v, w; mag_init(a); mag_init(b); mag_init(c); mag_init(u); mag_init(v); mag_init(w); mag_set_d(a, 1.029287542); mag_set_d(b, 0.3319411658); mag_set_d(c, 2.391097143); mag_sub(u, x, c); mag_mul(v, a, s); mag_mul_ui(w, b, FLINT_MAX(0, prec)); result = _mag_gt_norm_ui(u, v, w, 8); mag_clear(a); mag_clear(b); mag_clear(c); mag_clear(u); mag_clear(v); mag_clear(w); } return result; } static int _acb_is_nonnegative_real(const acb_t z) { return arb_is_zero(acb_imagref(z)) && arb_is_nonnegative(acb_realref(z)); } void acb_hypgeom_gamma_upper_nointegration(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) { if (!acb_is_finite(s) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (acb_is_zero(z)) { if (regularized == 2) { if (arb_is_negative(acb_realref(s))) { acb_inv(res, s, prec); acb_neg(res, res); } else { acb_indeterminate(res); } } else { if (arb_is_positive(acb_realref(s))) { if (regularized == 1) acb_one(res); else acb_gamma(res, s, prec); } else { acb_indeterminate(res); } } } else { slong n = WORD_MAX; if (acb_is_int(s)) { if (regularized == 1 && arf_sgn(arb_midref(acb_realref(s))) <= 0) { acb_zero(res); return; } if (arf_cmpabs_2exp_si(arb_midref(acb_realref(s)), 30) < 0) { n = arf_get_si(arb_midref(acb_realref(s)), ARF_RND_DOWN); } } if (n >= 1 && n <= 3) { acb_t t, u; acb_init(t); acb_init(u); if (regularized == 2) acb_pow_si(u, z, n, prec); if (n == 1) { acb_neg(res, z); acb_exp(res, res, prec); } else if (n == 2) { acb_add_ui(t, z, 1, prec); acb_neg(res, z); acb_exp(res, res, prec); acb_mul(res, res, t, prec); } else if (n == 3) { acb_add_ui(t, z, 2, prec); acb_mul(t, t, z, prec); acb_add_ui(t, t, 2, prec); acb_neg(res, z); acb_exp(res, res, prec); acb_mul(res, res, t, prec); } if (regularized == 2) acb_div(res, res, u, prec); else if (regularized == 1 && n == 3) acb_mul_2exp_si(res, res, -1); acb_clear(t); acb_clear(u); return; } if (_acb_is_nonnegative_real(s) && _acb_is_nonnegative_real(z)) { int result; mag_t ms, mx; mag_init(ms); mag_init(mx); arb_get_mag(ms, acb_realref(s)); arb_get_mag(mx, acb_realref(z)); result = _nonnegative_real_use_asymp(ms, mx, prec); mag_clear(ms); mag_clear(mx); if (result) { acb_hypgeom_gamma_upper_asymp(res, s, z, regularized, prec); return; } } else if (acb_hypgeom_u_use_asymp(z, prec) && ((0 < n && n < WORD_MAX) || _determine_region(s, z))) { acb_hypgeom_gamma_upper_asymp(res, s, z, regularized, prec); return; } if (n <= 0 && n > -10 * prec) { acb_hypgeom_gamma_upper_singular(res, n, z, regularized, prec); return; } if (arf_sgn(arb_midref(acb_realref(z))) > 0) acb_hypgeom_gamma_upper_1f1b(res, s, z, regularized, prec); else acb_hypgeom_gamma_upper_1f1a(res, s, z, regularized, prec); } } void acb_hypgeom_gamma_upper(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) { acb_t res2; slong acc, max, t; acb_init(res2); acb_hypgeom_gamma_upper_nointegration(res2, s, z, regularized, prec); acc = acb_rel_accuracy_bits(res2); if (acc < 0.5 * prec) { max = prec; t = acb_rel_accuracy_bits(z); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(s); max = FLINT_MIN(max, t); if (max > 2 && acc < 0.5 * max) { if (acb_is_real(s) && acb_is_real(z) && arf_cmp_2exp_si(arb_midref(acb_realref(z)), -16) > 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(s)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 60) < 0) { arb_hypgeom_gamma_upper_integration(acb_realref(res), acb_realref(s), acb_realref(z), regularized, prec); arb_zero(acb_imagref(res)); if (acb_rel_accuracy_bits(res) > acb_rel_accuracy_bits(res2) || (acb_is_finite(res) && !acb_is_finite(res2))) { acb_swap(res, res2); } } } } acb_swap(res, res2); acb_clear(res2); } arb-2.22.1/acb_hypgeom/gamma_upper_series.c000066400000000000000000000051231417376376500206560ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_hypgeom.h" void _acb_hypgeom_gamma_upper_series(acb_ptr g, const acb_t s, acb_srcptr h, slong hlen, int regularized, slong n, slong prec) { acb_t c; acb_init(c); acb_hypgeom_gamma_upper(c, s, h, regularized, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _acb_vec_zero(g + 1, n - 1); } else { acb_ptr t, u, v; acb_ptr w = NULL; t = _acb_vec_init(n); u = _acb_vec_init(n); v = _acb_vec_init(n); if (regularized == 2) { w = _acb_vec_init(n); acb_neg(t, s); _acb_poly_pow_acb_series(w, h, hlen, t, n, prec); } /* Gamma(s, h(x)) = -integral(h'(x) h(x)^(s-1) exp(-h(x)) */ acb_sub_ui(u, s, 1, prec); _acb_poly_pow_acb_series(t, h, hlen, u, n, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_mullow(v, t, n, u, hlen - 1, n, prec); _acb_vec_neg(t, h, hlen); _acb_poly_exp_series(t, t, hlen, n, prec); _acb_poly_mullow(g, v, n, t, n, n, prec); _acb_poly_integral(g, g, n, prec); _acb_vec_neg(g, g, n); if (regularized == 1) { acb_rgamma(t, s, prec); _acb_vec_scalar_mul(g, g, n, t, prec); } else if (regularized == 2) { _acb_vec_set(u, g, n); _acb_poly_mullow(g, u, n, w, n, n, prec); _acb_vec_clear(w, n); } _acb_vec_clear(t, n); _acb_vec_clear(u, n); _acb_vec_clear(v, n); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_gamma_upper_series(acb_poly_t g, const acb_t s, const acb_poly_t h, int regularized, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(g); return; } acb_poly_fit_length(g, n); if (hlen == 0) { acb_t t; acb_init(t); _acb_hypgeom_gamma_upper_series(g->coeffs, s, t, 1, regularized, n, prec); acb_clear(t); } else { _acb_hypgeom_gamma_upper_series( g->coeffs, s, h->coeffs, hlen, regularized, n, prec); } _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/gegenbauer_c.c000066400000000000000000000050551417376376500174210ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* this can be improved */ static int use_recurrence(const acb_t n, const acb_t m, slong prec) { if (!acb_is_int(n) || !arb_is_nonnegative(acb_realref(n))) return 0; if (arf_cmpabs_ui(arb_midref(acb_realref(n)), prec) > 0) return 0; if (arb_is_nonnegative(acb_realref(m))) return 0; return 1; } void acb_hypgeom_gegenbauer_c_ui_recurrence(acb_t res, ulong n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; ulong k; if (n == 0) { acb_one(res); return; } if (n == 1) { acb_mul(res, m, z, prec); acb_mul_2exp_si(res, res, 1); return; } acb_init(t); acb_init(u); acb_init(v); acb_one(t); acb_mul(u, m, z, prec); acb_mul_2exp_si(u, u, 1); for (k = 2; k <= n; k++) { acb_mul_2exp_si(v, m, 1); acb_add_ui(v, v, k - 2, prec); acb_mul(t, t, v, prec); acb_add_ui(v, m, k - 1, prec); acb_mul(v, v, z, prec); acb_mul_2exp_si(v, v, 1); acb_mul(v, v, u, prec); acb_sub(t, v, t, prec); acb_div_ui(t, t, k, prec); acb_swap(t, u); } acb_set(res, u); acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_gegenbauer_c(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t a, b, c, t; if (use_recurrence(n, m, prec)) { acb_hypgeom_gegenbauer_c_ui_recurrence(res, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), m, z, prec); return; } acb_init(a); acb_init(b); acb_init(c); acb_init(t); acb_neg(a, n); acb_mul_2exp_si(b, m, 1); acb_add(b, b, n, prec); acb_one(c); acb_mul_2exp_si(c, c, -1); acb_add(c, c, m, prec); acb_sub_ui(t, z, 1, prec); acb_mul_2exp_si(t, t, -1); acb_neg(t, t); acb_hypgeom_2f1(t, a, b, c, t, 0, prec); acb_mul_2exp_si(b, m, 1); acb_rising(b, b, n, prec); acb_mul(t, t, b, prec); acb_add_ui(b, n, 1, prec); acb_rgamma(b, b, prec); acb_mul(t, t, b, prec); acb_set(res, t); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(t); } arb-2.22.1/acb_hypgeom/hermite_h.c000066400000000000000000000060771417376376500167640ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_hermite_h_ui_recurrence(acb_t res, ulong n, const acb_t z, slong prec) { acb_t t, u, v; ulong k; if (n == 0) { acb_one(res); return; } if (n == 1) { acb_set_round(res, z, prec); acb_mul_2exp_si(res, res, 1); return; } acb_init(t); acb_init(u); acb_init(v); acb_one(t); acb_mul_2exp_si(u, z, 1); for (k = 2; k <= n; k++) { acb_mul(v, u, z, prec); acb_submul_ui(v, t, k - 1, prec); acb_mul_2exp_si(v, v, 1); acb_swap(t, u); acb_swap(u, v); } acb_set(res, u); acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_hermite_h(acb_t res, const acb_t n, const acb_t z, slong prec) { acb_t a, b, c, t, u, v; int use_asymp; if (acb_is_int(n) && arb_is_nonnegative(acb_realref(n)) && (arf_cmpabs_ui(arb_midref(acb_realref(n)), 30) < 0)) { acb_hypgeom_hermite_h_ui_recurrence(res, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), z, prec); return; } acb_init(a); acb_init(b); acb_init(c); acb_init(t); acb_init(u); acb_init(v); acb_mul(t, z, z, prec); use_asymp = arb_is_positive(acb_realref(z)) && acb_hypgeom_u_use_asymp(t, prec); if (use_asymp) { acb_mul_2exp_si(a, n, -1); acb_neg(a, a); acb_one(b); acb_mul_2exp_si(b, b, -1); acb_hypgeom_u_asymp(u, a, b, t, -1, prec); acb_mul_2exp_si(t, z, 1); acb_pow(t, t, n, prec); acb_mul(u, u, t, prec); acb_set(res, u); } else { /* a = (1-n)/2 */ acb_sub_ui(a, n, 1, prec); acb_neg(a, a); acb_mul_2exp_si(a, a, -1); /* c = -n/2 */ acb_mul_2exp_si(c, n, -1); acb_neg(c, c); acb_rgamma(u, a, prec); if (!acb_is_zero(u)) { acb_one(b); acb_mul_2exp_si(b, b, -1); acb_hypgeom_m(v, c, b, t, 0, prec); acb_mul(u, u, v, prec); } acb_rgamma(v, c, prec); if (!acb_is_zero(v)) { acb_set_ui(b, 3); acb_mul_2exp_si(b, b, -1); acb_hypgeom_m(t, a, b, t, 0, prec); acb_mul_2exp_si(t, t, 1); acb_mul(t, t, z, prec); acb_submul(u, v, t, prec); } acb_set_ui(t, 2); acb_pow(t, t, n, prec); acb_mul(u, u, t, prec); arb_const_sqrt_pi(acb_realref(t), prec); acb_mul_arb(u, u, acb_realref(t), prec); acb_set(res, u); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(t); acb_clear(u); acb_clear(v); } arb-2.22.1/acb_hypgeom/jacobi_p.c000066400000000000000000000052251417376376500165600ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* this can be improved */ static int use_recurrence(const acb_t n, const acb_t a, const acb_t b, slong prec) { if (!acb_is_int(n) || !arb_is_nonnegative(acb_realref(n))) return 0; if (arf_cmpabs_ui(arb_midref(acb_realref(n)), prec) > 0) return 0; if (arb_is_nonnegative(acb_realref(a)) || arf_get_d(arb_midref(acb_realref(a)), ARF_RND_DOWN) > -0.9) return 0; return 1; } void acb_hypgeom_jacobi_p_ui_direct(acb_t res, ulong n, const acb_t a, const acb_t b, const acb_t z, slong prec) { acb_ptr terms; acb_t t, u, v; slong k; terms = _acb_vec_init(n + 1); acb_init(t); acb_init(u); acb_init(v); acb_one(terms); acb_add_ui(u, z, 1, prec); for (k = 1; k <= n; k++) { acb_add_ui(t, a, n + 1 - k, prec); acb_mul(t, t, u, prec); acb_div_ui(t, t, 2 * k, prec); acb_mul(terms + k, terms + k - 1, t, prec); } acb_sub_ui(u, z, 1, prec); acb_one(v); for (k = 1; k <= n; k++) { acb_add_ui(t, b, n + 1 - k, prec); acb_mul(t, t, u, prec); acb_div_ui(t, t, 2 * k, prec); acb_mul(v, v, t, prec); acb_mul(terms + n - k, terms + n - k, v, prec); } acb_set(res, terms); for (k = 1; k <= n; k++) acb_add(res, res, terms + k, prec); _acb_vec_clear(terms, n + 1); acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_jacobi_p(acb_t res, const acb_t n, const acb_t a, const acb_t b, const acb_t z, slong prec) { acb_t t, u, v, w; if (use_recurrence(n, a, b, prec)) { acb_hypgeom_jacobi_p_ui_direct(res, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), a, b, z, prec); return; } acb_init(t); acb_init(u); acb_init(v); acb_init(w); acb_neg(t, n); acb_add_ui(v, a, 1, prec); acb_add(u, n, v, prec); acb_add(u, u, b, prec); acb_sub_ui(w, z, 1, prec); acb_mul_2exp_si(w, w, -1); acb_neg(w, w); acb_hypgeom_2f1(w, t, u, v, w, 0, prec); acb_rising(t, v, n, prec); acb_mul(w, w, t, prec); acb_add_ui(t, n, 1, prec); acb_rgamma(t, t, prec); acb_mul(w, w, t, prec); acb_set(res, w); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(w); } arb-2.22.1/acb_hypgeom/laguerre_l.c000066400000000000000000000046101417376376500171300ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* this can be improved */ static int use_recurrence(const acb_t n, const acb_t m, slong prec) { if (!acb_is_int(n) || !arb_is_nonnegative(acb_realref(n))) return 0; if (arf_cmpabs_ui(arb_midref(acb_realref(n)), prec) > 0) return 0; if (arf_cmpabs(arb_midref(acb_realref(n)), arb_midref(acb_realref(m))) >= 0) return 0; return 1; } void acb_hypgeom_laguerre_l_ui_recurrence(acb_t res, ulong n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; ulong k; if (n == 0) { acb_one(res); return; } if (n == 1) { acb_sub(res, m, z, prec); acb_add_ui(res, res, 1, prec); return; } acb_init(t); acb_init(u); acb_init(v); acb_one(t); acb_sub(u, m, z, prec); acb_add_ui(u, u, 1, prec); for (k = 2; k <= n; k++) { acb_add_ui(v, m, k - 1, prec); acb_mul(t, t, v, prec); acb_add_ui(v, m, 2 * k - 1, prec); acb_sub(v, v, z, prec); acb_mul(v, v, u, prec); acb_sub(t, v, t, prec); acb_div_ui(t, t, k, prec); acb_swap(t, u); } acb_set(res, u); acb_clear(t); acb_clear(u); acb_clear(v); } void acb_hypgeom_laguerre_l(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; if (use_recurrence(n, m, prec)) { acb_hypgeom_laguerre_l_ui_recurrence(res, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), m, z, prec); return; } /* todo: should be a test of whether n contains any negative integer */ if (acb_contains_int(n) && !arb_is_nonnegative(acb_realref(n))) { acb_indeterminate(res); return; } acb_init(t); acb_init(u); acb_init(v); acb_neg(t, n); acb_add_ui(u, m, 1, prec); acb_hypgeom_m(t, t, u, z, 1, prec); acb_add_ui(u, n, 1, prec); acb_rising(u, u, m, prec); acb_mul(res, t, u, prec); acb_clear(t); acb_clear(u); acb_clear(v); } arb-2.22.1/acb_hypgeom/legendre_p.c000066400000000000000000000074761417376376500171300ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #include "arb_hypgeom.h" void acb_hypgeom_legendre_p(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec) { acb_t a, b, c, w; int flag; if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (acb_is_real(z) && acb_is_zero(m) && acb_is_int(n) && arf_sgn(arb_midref(acb_realref(n))) >= 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(n)), FLINT_BITS - 1) < 0) { arb_hypgeom_legendre_p_ui(acb_realref(res), NULL, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), acb_realref(z), prec); arb_zero(acb_imagref(res)); return; } if (acb_is_int(n) && acb_is_int(m) && arb_is_nonnegative(acb_realref(n)) && arb_is_nonnegative(acb_realref(m)) && type == 0) { arf_srcptr nn = arb_midref(acb_realref(n)); arf_srcptr mm = arb_midref(acb_realref(m)); if (arf_cmpabs(mm, nn) > 0) { acb_zero(res); return; } if (arf_cmpabs_2exp_si(nn, FLINT_BITS - 1) < 0 && arf_cmpabs_2exp_si(mm, FLINT_BITS - 1) < 0) { slong nnn, mmm; nnn = arf_get_si(nn, ARF_RND_DOWN); mmm = arf_get_si(mm, ARF_RND_DOWN); /* we will probably lose all accuracy... */ if (nnn - mmm > 2 * prec) { acb_indeterminate(res); } /* hypergeometric series is faster at high precision, but avoid at 1 */ else if (prec < 500 + nnn * 10.0 || (nnn - mmm) < 10 || (arb_contains_si(acb_realref(z), 1) && arb_contains_zero(acb_imagref(z)))) { if (mmm == 0) { acb_hypgeom_legendre_p_uiui_rec(res, nnn, mmm, z, prec); } else { acb_init(a); acb_init(b); acb_mul(a, z, z, prec); acb_sub_ui(a, a, 1, prec); acb_neg(a, a); acb_mul_2exp_si(b, m, -1); acb_pow(a, a, b, prec); acb_hypgeom_legendre_p_uiui_rec(res, nnn, mmm, z, prec); acb_mul(res, res, a, prec); acb_clear(a); acb_clear(b); } return; } } } acb_init(a); acb_init(b); acb_init(c); acb_init(w); acb_neg(a, n); acb_add_ui(b, n, 1, prec); acb_sub_ui(c, m, 1, prec); acb_neg(c, c); acb_sub_ui(w, z, 1, prec); acb_neg(w, w); acb_mul_2exp_si(w, w, -1); /* a + b - c (which could be inexact) is integer iff c is integer */ flag = 1; if (acb_is_int(c)) { flag |= ACB_HYPGEOM_2F1_ABC; } acb_hypgeom_2f1(w, a, b, c, w, flag, prec); if (!acb_is_zero(m)) { acb_add_ui(a, z, 1, prec); acb_sub_ui(b, z, 1, prec); if (type == 0) { acb_neg(b, b); } else if (type != 1) { flint_printf("unsupported 'type' %d for legendre p\n", type); flint_abort(); } acb_mul_2exp_si(c, m, -1); acb_pow(a, a, c, prec); acb_neg(c, c); acb_pow(b, b, c, prec); acb_mul(w, w, a, prec); acb_mul(w, w, b, prec); } acb_set(res, w); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(w); } arb-2.22.1/acb_hypgeom/legendre_p_uiui_rec.c000066400000000000000000000031451417376376500210010ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_legendre_p_uiui_rec(acb_t res, ulong n, ulong m, const acb_t z, slong prec) { acb_t t, u, v; slong k; if (!acb_is_finite(z)) { acb_indeterminate(res); return; } if (m > n) { acb_zero(res); return; } if ((n - m) / 4 > prec) { acb_indeterminate(res); return; } acb_init(t); acb_init(u); acb_init(v); /* t = p(m,m) = (-1)^m (2m-1)!! */ if (m == 0) arb_one(acb_realref(t)); else arb_doublefac_ui(acb_realref(t), 2 * m - 1, prec); if (m % 2) arb_neg(acb_realref(t), acb_realref(t)); if (n > m) { /* t = p(m+1,m) = z(2m+1)p(m,m), u = p(m,m) */ acb_mul_ui(u, t, 2 * m + 1, prec); acb_mul(u, u, z, prec); acb_swap(t, u); for (k = m + 2; k <= n; k++) { /* t, u = ((2*k-1)*z*t - (k+m-1)*u) / (k-m), t */ acb_mul(v, t, z, prec); acb_mul_ui(v, v, 2 * k - 1, prec); acb_submul_ui(v, u, k + m - 1, prec); acb_div_ui(u, v, k - m, prec); acb_swap(t, u); } } acb_set(res, t); acb_clear(t); acb_clear(u); acb_clear(v); } arb-2.22.1/acb_hypgeom/legendre_q.c000066400000000000000000000170411417376376500171160ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* invalid in (-1,0) */ int _acb_hypgeom_legendre_q_single_valid(const acb_t z) { arb_t t; int ok; if (!arb_contains_zero(acb_imagref(z))) return 1; if (arb_is_positive(acb_imagref(z))) return 1; arb_init(t); arb_one(t); arb_neg(t, t); ok = arb_lt(acb_realref(z), t); arb_clear(t); return ok; } void _acb_hypgeom_legendre_q_double(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); if (acb_is_int(m)) { acb_sub_ui(t, z, 1, prec); acb_mul_2exp_si(u, m, -1); acb_pow(v, t, u, prec); acb_neg(t, t); acb_neg(u, u); acb_pow(t, t, u, prec); acb_mul(t, t, v, prec); acb_hypgeom_legendre_q(u, n, m, z, 0, prec); acb_mul(t, t, u, prec); acb_mul_2exp_si(u, m, -1); if (!acb_is_int(u)) acb_neg(t, t); acb_sub_ui(u, z, 1, prec); acb_sqrt(u, u, prec); acb_sub_ui(v, z, 1, prec); acb_neg(v, v); acb_rsqrt(v, v, prec); acb_mul(u, u, v, prec); acb_hypgeom_legendre_p(v, n, m, z, 1, prec); acb_mul(u, u, v, prec); acb_const_pi(v, prec); acb_mul(u, u, v, prec); acb_mul_2exp_si(u, u, -1); acb_sub(res, t, u, prec); } else { acb_sub(t, n, m, prec); acb_add_ui(t, t, 1, prec); acb_mul_2exp_si(u, m, 1); acb_rising(t, t, u, prec); acb_neg(u, m); acb_hypgeom_legendre_p(u, n, u, z, 1, prec); acb_mul(t, t, u, prec); acb_hypgeom_legendre_p(u, n, m, z, 1, prec); acb_sub(t, u, t, prec); acb_exp_pi_i(u, m, prec); acb_mul(t, t, u, prec); acb_sin_pi(u, m, prec); acb_div(t, t, u, prec); acb_const_pi(u, prec); acb_mul(t, t, u, prec); acb_mul_2exp_si(t, t, -1); acb_set(res, t); } acb_clear(t); acb_clear(u); acb_clear(v); } void _acb_hypgeom_legendre_q_single(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t a, b, c, z2, t, u; acb_init(a); acb_init(b); acb_init(c); acb_init(z2); acb_init(t); acb_init(u); /* invalid in (-1,0) */ if (!_acb_hypgeom_legendre_q_single_valid(z)) { acb_indeterminate(res); return; } acb_pow_si(z2, z, -2, prec); /* z2 = 1/z^2 */ /* t = 2F1r((m+n+1)/2, (m+n)/2+1, n+3/2, 1/z^2) */ acb_add(b, m, n, prec); acb_add_ui(a, b, 1, prec); acb_mul_2exp_si(a, a, -1); acb_mul_2exp_si(b, b, -1); acb_add_ui(b, b, 1, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_add(c, c, n, prec); acb_hypgeom_2f1(t, a, b, c, z2, 1, prec); /* prefactor sqrt(pi) 2^-n (z+1)^(m/2) (z-1)^(m/2) exp(i pi m) */ /* (1/2) gamma(m+n+1) z^(-m-n-1) */ if (!acb_is_zero(m)) { acb_add_ui(z2, z, 1, prec); acb_mul_2exp_si(c, m, -1); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_sub_ui(z2, z, 1, prec); acb_mul_2exp_si(c, m, -1); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_exp_pi_i(z2, m, prec); acb_mul(t, t, z2, prec); } acb_set_ui(z2, 2); acb_neg(c, n); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_add(c, m, n, prec); acb_add_ui(c, c, 1, prec); acb_gamma(z2, c, prec); acb_mul(t, t, z2, prec); acb_neg(c, c); acb_pow(z2, z, c, prec); acb_mul(t, t, z2, prec); acb_mul_2exp_si(t, t, -1); arb_const_sqrt_pi(acb_realref(u), prec); acb_mul_arb(t, t, acb_realref(u), prec); acb_set(res, t); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z2); acb_clear(t); acb_clear(u); } void acb_hypgeom_legendre_q(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec) { if (type == 0) { /* http://functions.wolfram.com/07.11.26.0033.01 */ /* todo: simplify the gamma quotients and the sqrt pi factor... */ acb_t a, b, c, z2, mn, nm, t, u; acb_init(a); acb_init(b); acb_init(c); acb_init(z2); acb_init(mn); acb_init(nm); acb_init(t); acb_init(u); acb_add(mn, m, n, prec); /* mn = m + n */ acb_sub(nm, n, m, prec); /* nm = n - m */ acb_mul(z2, z, z, prec); /* z2 = z^2 */ /* t = 2F1((1-m-n)/2, (n-m)/2+1, 3/2, z^2) */ acb_sub_ui(a, mn, 1, prec); acb_neg(a, a); acb_mul_2exp_si(a, a, -1); acb_mul_2exp_si(b, nm, -1); acb_add_ui(b, b, 1, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_hypgeom_2f1(t, a, b, c, z2, 0, prec); /* u = 2F1(-(m+n)/2, (n-m+1)/2, 1/2, z^2) */ acb_neg(a, mn); acb_mul_2exp_si(a, a, -1); acb_add_ui(b, nm, 1, prec); acb_mul_2exp_si(b, b, -1); acb_one(c); acb_mul_2exp_si(c, c, -1); acb_hypgeom_2f1(u, a, b, c, z2, 0, prec); /* a = cospi((m+n)/2) gamma((m+n)/2+1) rgamma((n-m+1)/2) z */ /* b = sinpi((m+n)/2) gamma((m+n+1)/2) rgamma((n-m)/2+1) / 2 */ acb_mul_2exp_si(a, mn, -1); acb_sin_cos_pi(b, a, a, prec); acb_mul_2exp_si(c, mn, -1); acb_add_ui(c, c, 1, prec); acb_gamma(c, c, prec); acb_mul(a, a, c, prec); acb_add_ui(c, nm, 1, prec); acb_mul_2exp_si(c, c, -1); acb_rgamma(c, c, prec); acb_mul(a, a, c, prec); acb_mul(a, a, z, prec); acb_add_ui(c, mn, 1, prec); acb_mul_2exp_si(c, c, -1); acb_gamma(c, c, prec); acb_mul(b, b, c, prec); acb_mul_2exp_si(c, nm, -1); acb_add_ui(c, c, 1, prec); acb_rgamma(c, c, prec); acb_mul(b, b, c, prec); acb_mul_2exp_si(b, b, -1); /* at - bu */ acb_mul(t, t, a, prec); acb_mul(u, u, b, prec); acb_sub(t, t, u, prec); /* prefactor sqrt(pi) 2^m (1-z^2)^(-m/2) */ if (!acb_is_zero(m)) { acb_sub_ui(u, z2, 1, prec); acb_neg(u, u); acb_neg(c, m); acb_mul_2exp_si(c, c, -1); acb_pow(u, u, c, prec); acb_set_ui(c, 2); acb_pow(c, c, m, prec); acb_mul(u, u, c, prec); acb_mul(t, t, u, prec); } arb_const_sqrt_pi(acb_realref(u), prec); acb_mul_arb(t, t, acb_realref(u), prec); acb_set(res, t); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z2); acb_clear(mn); acb_clear(nm); acb_clear(t); acb_clear(u); } else if (type == 1) { if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -2) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -2) < 0) || !_acb_hypgeom_legendre_q_single_valid(z)) { _acb_hypgeom_legendre_q_double(res, n, m, z, prec); } else { _acb_hypgeom_legendre_q_single(res, n, m, z, prec); } } else { flint_printf("unsupported 'type' %d for legendre q\n", type); flint_abort(); } } arb-2.22.1/acb_hypgeom/lgamma.c000066400000000000000000000142771417376376500162570ustar00rootroot00000000000000/* Copyright (C) 2014, 2015, 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #include "arb_hypgeom.h" void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t z, int use_reflect, int digamma, slong prec); void acb_hypgeom_gamma_stirling_inner(acb_t s, const acb_t z, slong N, slong prec); static double want_taylor(double x, double y, slong prec) { if (y < 0.0) y = -y; if (x < 0.0) x = -2.0 * x; if ((prec < 128 && y > 4.0) || (prec < 256 && y > 5.0) || (prec < 512 && y > 8.0) || (prec < 1024 && y > 9.0) || y > 10.0) { return 0; } if (x * (1.0 + 0.75 * y) > 8 + 0.15 * prec) { return 0; } return 1; } /* Linear fit on [0.5, 1.5] for lambda x: findroot(lambda y: im(loggamma(x+1j*y)) - (n+0.5)*pi */ static const double Atab[] = { 4.5835631239879990091, 6.4037921417161376741, 7.9938623618272375768, 9.4449131928216797873, 10.802608819487725856, 12.0918817314347272, }; static const double Btab[] = { -1.1432582881376479127, -0.86248117216701645437, -0.75778990135448922722, -0.69734688055939976228, -0.65626499937495627271, -0.62578331900739100617, }; void _arb_const_log_pi(arb_t t, slong prec) { arb_const_pi(t, prec + 2); arb_log(t, t, prec); } ARB_DEF_CACHED_CONSTANT(arb_const_log_pi, _arb_const_log_pi) int acb_hypgeom_lgamma_taylor(acb_t res, const acb_t z, slong prec) { double x, y, acc; slong k, r, wp; acb_t t, u; int reflect; /* Assume xerr, yerr <= 1/16 */ if (mag_cmp_2exp_si(arb_radref(acb_realref(z)), -4) > 0) return 0; if (mag_cmp_2exp_si(arb_radref(acb_imagref(z)), -4) > 0) return 0; acc = acb_rel_accuracy_bits(z); acc = FLINT_MAX(acc, 0); wp = FLINT_MIN(prec, acc + 20); wp = FLINT_MAX(wp, 2); /* x, y plus eventual rounding error */ x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_NEAR); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_NEAR); if (!want_taylor(x, y, wp)) return 0; acb_init(t); acb_init(u); /* Reduce real part to (approximately) [0.5, 1.5]. */ r = floor(x - 0.5); /* Reflection formula is slower but improves accuracy. */ reflect = (x < -3.0); if (reflect) { acb_neg(u, z); acb_add_si(u, u, 2 + r, 2 * prec + 10); x = 2.0 + r - x; y = -y; } else { acb_sub_si(u, z, r, 2 * prec + 10); x = x - r; } for (k = 0; k < 6; k++) { if (fabs(y) <= Atab[k] + Btab[k] * x) { if (!acb_hypgeom_gamma_taylor(t, u, 1, wp)) { acb_clear(t); acb_clear(u); return 0; } if (k % 2 == 0) { acb_log(t, t, wp); acb_neg(t, t); } else { acb_neg(t, t); acb_log(t, t, wp); acb_neg(t, t); } if (k != 0) { arb_t pi; arb_init(pi); arb_const_pi(pi, wp); arb_addmul_si(acb_imagref(t), pi, (y > 0) ? k : -k, wp); arb_clear(pi); } if (reflect) { acb_t v; acb_init(v); /* loggamma(x) = log(pi) - lsin(x) - loggamma(2+r-x) - logrf(2+r-x, -r-1) */ acb_hypgeom_log_rising_ui(v, u, -r-1, wp); acb_log_sin_pi(res, z, wp); acb_add(res, res, v, wp); acb_add(res, res, t, wp); acb_neg(res, res); arb_const_log_pi(acb_realref(t), wp); arb_zero(acb_imagref(t)); acb_add(res, res, t, prec); acb_clear(v); } else if (r == 0) { acb_set_round(res, t, prec); } else if (r > 0) { acb_hypgeom_log_rising_ui(res, u, r, wp); acb_add(res, res, t, prec); } else { acb_hypgeom_log_rising_ui(res, z, -r, wp); acb_sub(res, t, res, prec); } acb_clear(t); acb_clear(u); return 1; } } acb_clear(t); acb_clear(u); return 0; } void acb_hypgeom_lgamma(acb_t y, const acb_t x, slong prec) { int reflect; slong r, n, wp; acb_t t, u, v; double acc; if (acb_is_real(x) && arb_is_positive(acb_realref(x))) { arb_hypgeom_lgamma(acb_realref(y), acb_realref(x), prec); arb_zero(acb_imagref(y)); return; } if (acb_hypgeom_lgamma_taylor(y, x, prec)) return; acc = acb_rel_accuracy_bits(x); acc = FLINT_MAX(acc, 0); wp = FLINT_MIN(prec, acc + 20); wp = FLINT_MAX(wp, 2); wp = wp + FLINT_BIT_COUNT(wp); acb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 0, wp); acb_init(t); acb_init(u); acb_init(v); if (reflect) { /* log gamma(x) = log rf(1-x, r) - log gamma(1-x+r) - log sin(pi x) + log(pi) */ acb_sub_ui(u, x, 1, wp); acb_neg(u, u); acb_hypgeom_log_rising_ui(t, u, r, wp); acb_add_ui(u, u, r, wp); acb_hypgeom_gamma_stirling_inner(v, u, n, wp); acb_sub(t, t, v, wp); acb_log_sin_pi(u, x, wp); acb_sub(t, t, u, wp); arb_const_log_pi(acb_realref(u), wp); arb_zero(acb_imagref(u)); acb_add(y, t, u, wp); } else { /* log gamma(x) = log gamma(x+r) - log rf(x,r) */ acb_add_ui(t, x, r, wp); acb_hypgeom_gamma_stirling_inner(u, t, n, wp); acb_hypgeom_log_rising_ui(t, x, r, wp); acb_sub(y, u, t, prec); } if (!acb_is_finite(y)) acb_indeterminate(y); acb_clear(t); acb_clear(u); acb_clear(v); } arb-2.22.1/acb_hypgeom/li.c000066400000000000000000000027331417376376500154170ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void _acb_hypgeom_li(acb_t res, const acb_t z, slong prec) { if (acb_is_zero(z)) { acb_zero(res); } else { acb_log(res, z, prec); acb_hypgeom_ei(res, res, prec); } } void _acb_hypgeom_const_li2_eval(arb_t s, slong prec) { acb_t t; acb_init(t); acb_set_ui(t, 2); _acb_hypgeom_li(t, t, prec); arb_set(s, acb_realref(t)); acb_clear(t); } ARB_DEF_CACHED_CONSTANT(_acb_hypgeom_const_li2, _acb_hypgeom_const_li2_eval) static void _acb_hypgeom_li_offset(acb_t res, const acb_t z, slong prec) { if (acb_is_int(z) && arf_cmp_2exp_si(arb_midref(acb_realref(z)), 1) == 0) { acb_zero(res); } else { arb_t t; arb_init(t); _acb_hypgeom_const_li2(t, prec); _acb_hypgeom_li(res, z, prec); arb_sub(acb_realref(res), acb_realref(res), t, prec); arb_clear(t); } } void acb_hypgeom_li(acb_t res, const acb_t z, int offset, slong prec) { if (offset) _acb_hypgeom_li_offset(res, z, prec); else _acb_hypgeom_li(res, z, prec); } arb-2.22.1/acb_hypgeom/li_series.c000066400000000000000000000034701417376376500167700ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_li_series(acb_ptr g, acb_srcptr h, slong hlen, int offset, slong len, slong prec) { acb_t c; if (acb_contains_zero(h)) { _acb_vec_indeterminate(g, len); return; } acb_init(c); acb_hypgeom_li(c, h, offset, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else if (len == 2) { acb_log(g, h, prec); acb_div(g + 1, h + 1, g, prec); } else { acb_ptr t, u; t = _acb_vec_init(len); u = _acb_vec_init(hlen); /* li(h(x)) = integral(h'(x) / log(h(x))) */ _acb_poly_log_series(t, h, hlen, len - 1, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_div_series(g, u, hlen - 1, t, len - 1, len - 1, prec); _acb_poly_integral(g, g, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, hlen); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_li_series(acb_poly_t g, const acb_poly_t h, int offset, slong len, slong prec) { slong hlen = h->length; if (len == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_inv_series(g, h, len, prec); return; } acb_poly_fit_length(g, len); _acb_hypgeom_li_series(g->coeffs, h->coeffs, hlen, offset, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/log_rising_ui_jet.c000066400000000000000000000145071417376376500205100ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #include "arb_hypgeom.h" static void _acb_log_rising_correct_branch(acb_t res, const acb_t t_wrong, const acb_t z, ulong r, slong prec) { acb_t f; arb_t pi, u, v; fmpz_t pi_mult; slong i, argprec; acb_init(f); arb_init(u); arb_init(pi); arb_init(v); fmpz_init(pi_mult); argprec = FLINT_MIN(prec, 40); arb_zero(u); for (i = 0; i < r; i++) { acb_add_ui(f, z, i, argprec); acb_arg(v, f, argprec); arb_add(u, u, v, argprec); } if (argprec == prec) { arb_set(acb_imagref(res), u); } else { arb_sub(v, u, acb_imagref(t_wrong), argprec); arb_const_pi(pi, argprec); arb_div(v, v, pi, argprec); if (arb_get_unique_fmpz(pi_mult, v)) { arb_const_pi(v, prec); arb_mul_fmpz(v, v, pi_mult, prec); arb_add(acb_imagref(res), acb_imagref(t_wrong), v, prec); } else { arb_zero(u); for (i = 0; i < r; i++) { acb_add_ui(f, z, i, prec); acb_arg(v, f, prec); arb_add(u, u, v, prec); } arb_set(acb_imagref(res), u); } } arb_set(acb_realref(res), acb_realref(t_wrong)); acb_clear(f); arb_clear(u); arb_clear(v); arb_clear(pi); fmpz_clear(pi_mult); } void acb_hypgeom_log_rising_ui_jet_fallback(acb_ptr res, const acb_t z, slong r, slong len, slong prec) { acb_t t; acb_init(t); acb_set(t, z); if (len == 1) { acb_hypgeom_rising_ui_rec(res, t, r, prec); acb_log(res, res, prec); } else { acb_hypgeom_rising_ui_jet(res, t, r, len, prec); _acb_poly_log_series(res, res, FLINT_MIN(len, r + 1), len, prec); } _acb_log_rising_correct_branch(res, res, t, r, prec); acb_clear(t); } void acb_hypgeom_log_rising_ui_jet(acb_ptr res, const acb_t z, ulong r, slong len, slong prec) { double za, zb, sa, sb, ta, tb, ma, mb, zak; slong k, correction; int neg; if (r == 0 || len == 0) { _acb_vec_zero(res, len); return; } if (r == 1) { if (len == 1) { acb_log(res, z, prec); } else { acb_set(res, z); acb_one(res + 1); _acb_poly_log_series(res, res, 2, len, prec); } return; } if (arb_is_zero(acb_imagref(z))) { if (arb_is_positive(acb_realref(z))) { acb_hypgeom_rising_ui_jet(res, z, r, len, prec); _acb_poly_log_series(res, res, FLINT_MIN(len, r + 1), len, prec); } else if (arb_contains_int(acb_realref(z))) { _acb_vec_indeterminate(res, len); } else { arb_t t, u; arb_init(t); arb_init(u); arb_floor(u, acb_realref(z), prec); arb_neg(u, u); arb_set_ui(t, r); arb_min(u, u, t, prec); arb_const_pi(t, prec); arb_mul(t, u, t, prec); acb_hypgeom_rising_ui_jet(res, z, r, len, prec); _acb_vec_neg(res, res, FLINT_MIN(len, r + 1)); _acb_poly_log_series(res, res, FLINT_MIN(len, r + 1), len, prec); arb_swap(acb_imagref(res), t); arb_clear(t); arb_clear(u); } return; } /* We use doubles if it is safe. - No overflow/underflow possible. - Input is accurate enough (and not too close to the real line). Note: the relative error for a complex floating-point multiplication is bounded by sqrt(5) * eps, and we basically only need to determine the result to within one quadrant. */ /* todo: wide */ if (prec <= 20 || acb_rel_accuracy_bits(z) < 30 || arb_rel_accuracy_bits(acb_imagref(z)) < 30) { acb_hypgeom_log_rising_ui_jet_fallback(res, z, r, len, prec); return; } za = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_NEAR); zb = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_NEAR); if (!(r <= 1e6 && za <= 1e6 && za >= -1e6 && zb <= 1e6 && zb >= -1e6 && (zb > 1e-6 || zb < -1e-6))) { acb_hypgeom_log_rising_ui_jet_fallback(res, z, r, len, prec); return; } sa = za; sb = zb; correction = 0; neg = 0; for (k = 1; k < r; k++) { zak = za + k; ta = sa * zak - sb * zb; tb = sb * zak + sa * zb; if (zb > 0.0) { if (sb >= 0.0 && tb < 0.0) correction += 2; } else { if (sb < 0.0 && tb >= 0.0) correction += 2; } sa = ta; sb = tb; if (k % 4 == 0) { ma = fabs(sa); mb = fabs(sb); /* Rescale to protect against overflow. */ if (ma > mb) ma = 1.0 / ma; else ma = 1.0 / mb; sa *= ma; sb *= ma; } } if (sa < 0.0) { neg = 1; if ((zb > 0.0 && sb >= 0.0) || (zb < 0.0 && sb < 0.0)) correction += 1; else correction -= 1; } if (len == 1) { acb_hypgeom_rising_ui_rec(res, z, r, prec); if (neg) acb_neg(res, res); acb_log(res, res, prec); } else { acb_hypgeom_rising_ui_jet(res, z, r, len, prec); if (neg) _acb_vec_neg(res, res, FLINT_MIN(len, r + 1)); _acb_poly_log_series(res, res, FLINT_MIN(len, r + 1), len, prec); } if (zb < 0.0) correction = -correction; if (correction != 0) { arb_t t; arb_init(t); arb_const_pi(t, prec); arb_addmul_si(acb_imagref(res), t, correction, prec); arb_clear(t); } } void acb_hypgeom_log_rising_ui(acb_ptr res, const acb_t z, ulong r, slong prec) { acb_hypgeom_log_rising_ui_jet(res, z, r, 1, prec); } arb-2.22.1/acb_hypgeom/m.c000066400000000000000000000222131417376376500152420ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_m_asymp(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { acb_t t, u, v, c; acb_init(t); acb_init(u); acb_init(v); acb_init(c); acb_sub(c, b, a, prec); acb_neg(v, z); acb_hypgeom_u_asymp(t, a, b, z, -1, prec); acb_hypgeom_u_asymp(u, c, b, v, -1, prec); /* gamma(b-a) */ acb_rgamma(v, c, prec); acb_mul(t, t, v, prec); /* z^(a-b) */ acb_neg(c, c); acb_pow(v, z, c, prec); acb_mul(u, u, v, prec); /* gamma(a) */ acb_rgamma(v, a, prec); acb_mul(u, u, v, prec); /* exp(z) */ acb_exp(v, z, prec); acb_mul(u, u, v, prec); /* (-z)^(-a) */ acb_neg(c, a); acb_neg(v, z); acb_pow(v, v, c, prec); acb_mul(t, t, v, prec); acb_add(t, t, u, prec); if (!regularized) { acb_gamma(v, b, prec); if (acb_is_finite(v)) acb_mul(t, t, v, prec); else acb_indeterminate(t); } if (acb_is_real(a) && acb_is_real(b) && acb_is_real(z)) { arb_zero(acb_imagref(t)); } acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(c); } void _acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec, slong gamma_prec, int kummer) { if (regularized) { /* Remove singularity */ if (acb_is_int(b) && arb_is_nonpositive(acb_realref(b)) && arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 30) < 0) { acb_t c, d, t, u; slong n; n = arf_get_si(arb_midref(acb_realref(b)), ARF_RND_DOWN); acb_init(c); acb_init(d); acb_init(t); acb_init(u); acb_sub(c, a, b, prec); acb_add_ui(c, c, 1, prec); acb_neg(d, b); acb_add_ui(d, d, 2, prec); _acb_hypgeom_m_1f1(t, c, d, z, 0, prec, gamma_prec, kummer); acb_pow_ui(u, z, 1 - n, prec); acb_mul(t, t, u, prec); acb_rising_ui(u, a, 1 - n, prec); acb_mul(t, t, u, prec); arb_fac_ui(acb_realref(u), 1 - n, prec); acb_div_arb(res, t, acb_realref(u), prec); acb_clear(c); acb_clear(d); acb_clear(t); acb_clear(u); } else { acb_t t; acb_init(t); acb_rgamma(t, b, gamma_prec); _acb_hypgeom_m_1f1(res, a, b, z, 0, prec, gamma_prec, kummer); acb_mul(res, res, t, prec); acb_clear(t); } return; } /* Kummer's transformation */ if (kummer) { acb_t u, v; acb_init(u); acb_init(v); acb_sub(u, b, a, prec); acb_neg(v, z); _acb_hypgeom_m_1f1(u, u, b, v, regularized, prec, gamma_prec, 0); acb_exp(v, z, prec); acb_mul(res, u, v, prec); acb_clear(u); acb_clear(v); return; } if (acb_is_one(a)) { acb_hypgeom_pfq_direct(res, NULL, 0, b, 1, z, -1, prec); } else { acb_struct c[3]; c[0] = *a; c[1] = *b; acb_init(c + 2); acb_one(c + 2); acb_hypgeom_pfq_direct(res, c, 1, c + 1, 2, z, -1, prec); acb_clear(c + 2); } } void acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { if (arf_sgn(arb_midref(acb_realref(z))) >= 0 || (acb_is_int(a) && arb_is_nonpositive(acb_realref(a)))) { _acb_hypgeom_m_1f1(res, a, b, z, regularized, prec, prec, 0); } else { _acb_hypgeom_m_1f1(res, a, b, z, regularized, prec, prec, 1); } } static double hypotmx(double x, double y) { if (x > 0.0 && x > 1e6 * fabs(y)) return y * y / (2.0 * x); else return sqrt(x * x + y * y) - x; } void acb_hypgeom_m_choose(int * asymp, int * kummer, slong * wp, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { double x, y, t, cancellation; double input_accuracy, direct_accuracy, asymp_accuracy; slong m = WORD_MAX; slong n = WORD_MAX; if (acb_is_int(a) && arf_cmpabs_2exp_si(arb_midref(acb_realref(a)), 30) < 0) { m = arf_get_si(arb_midref(acb_realref(a)), ARF_RND_DOWN); } if (acb_is_int(b) && arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 30) < 0) { n = arf_get_si(arb_midref(acb_realref(b)), ARF_RND_DOWN); } *asymp = 0; *kummer = 0; *wp = prec; /* The 1F1 series terminates. */ /* TODO: for large m, estimate extra precision here. */ if (m <= 0 && m < n && m > -10 * prec && (n > 0 || !regularized)) { *asymp = 0; return; } /* The 1F1 series terminates with the Kummer transform. */ /* TODO: for large m, estimate extra precision here. */ if (m >= 1 && n >= 1 && m < 0.1 * prec && n < 0.1 * prec && n <= m) { *asymp = 0; *kummer = 1; return; } input_accuracy = acb_rel_one_accuracy_bits(z); t = acb_rel_one_accuracy_bits(a); input_accuracy = FLINT_MIN(input_accuracy, t); t = acb_rel_one_accuracy_bits(b); input_accuracy = FLINT_MIN(input_accuracy, t); input_accuracy = FLINT_MAX(input_accuracy, 0.0); /* From here we ignore the values of a, b. Taking them into account is a possible future improvement... */ /* Tiny |z|. */ if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 2) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 2) < 0)) { *asymp = 0; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); return; } /* Huge |z|. */ if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 64) > 0 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 64) > 0)) { *asymp = 1; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); return; } x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); asymp_accuracy = sqrt(x * x + y * y) * 1.44269504088896 - 5.0; /* The Kummer transformation gives less cancellation with the 1F1 series. */ if (x < 0.0) { *kummer = 1; x = -x; } if (asymp_accuracy >= prec) { *asymp = 1; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); return; } cancellation = hypotmx(x, y) * 1.44269504088896; direct_accuracy = input_accuracy - cancellation; if (direct_accuracy > asymp_accuracy) { *asymp = 0; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec + cancellation)); } else { *asymp = 1; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); } } void acb_hypgeom_m_nointegration(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { int asymp, kummer; slong wp; acb_hypgeom_m_choose(&asymp, &kummer, &wp, a, b, z, regularized, prec); if (asymp) { acb_hypgeom_m_asymp(res, a, b, z, regularized, wp); } else { _acb_hypgeom_m_1f1(res, a, b, z, regularized, wp, FLINT_MIN(wp, prec), kummer); } acb_set_round(res, res, prec); } void acb_hypgeom_m(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { acb_t res2; slong acc, max, t; acb_init(res2); acb_hypgeom_m_nointegration(res2, a, b, z, regularized, prec); acc = acb_rel_accuracy_bits(res2); if (acc < 0.5 * prec) { max = prec; t = acb_rel_accuracy_bits(z); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(a); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(b); max = FLINT_MIN(max, t); if (max > 2 && acc < 0.5 * max) { if (acb_is_real(a) && acb_is_real(b) && acb_is_real(z) && arf_cmpabs_2exp_si(arb_midref(acb_realref(a)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 60) < 0) { arb_hypgeom_1f1_integration(acb_realref(res), acb_realref(a), acb_realref(b), acb_realref(z), regularized, prec); arb_zero(acb_imagref(res)); if (acb_rel_accuracy_bits(res) > acb_rel_accuracy_bits(res2) || (acb_is_finite(res) && !acb_is_finite(res2))) { acb_swap(res, res2); } } } } acb_swap(res, res2); acb_clear(res2); } void acb_hypgeom_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { acb_hypgeom_m(res, a, b, z, regularized, prec); } arb-2.22.1/acb_hypgeom/pfq.c000066400000000000000000000070411417376376500155760ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static int _acb_vec_maybe_nonpositive_int(acb_srcptr b, slong q) { slong i; for (i = 0; i < q; i++) if (!arb_is_positive(acb_realref(b + i)) && acb_contains_int(b + i)) return 1; return 0; } void acb_hypgeom_pfq(acb_t res, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, int regularized, slong prec) { if (p == 0 && q == 0) { acb_exp(res, z, prec); } else if (p == 1 && q == 0) { acb_t t; acb_init(t); acb_neg(t, a); acb_sub_ui(res, z, 1, prec); acb_neg(res, res); acb_pow(res, res, t, prec); acb_clear(t); } else if (p == 0 && q == 1) { acb_hypgeom_0f1(res, b, z, regularized, prec); } else if (p == 1 && q == 1) { acb_hypgeom_m(res, a, b, z, regularized, prec); } else if (p == 2 && q == 1) { acb_hypgeom_2f1(res, a, a + 1, b, z, regularized, prec); } else if (regularized && _acb_vec_maybe_nonpositive_int(b, q)) { /* todo: implement regularized sum without using polynomials */ acb_poly_struct * tmp; slong i; tmp = flint_malloc(sizeof(acb_poly_struct) * (p + q + 2)); for (i = 0; i < p + q + 2; i++) acb_poly_init(tmp + i); for (i = 0; i < p; i++) acb_poly_set_acb(tmp + i, a + i); for (i = 0; i < q; i++) acb_poly_set_acb(tmp + p + i, b + i); acb_poly_one(tmp + p + q); acb_poly_set_acb(tmp + p + q + 1, z); acb_hypgeom_pfq_series_direct(tmp, tmp, p, tmp + p, q + 1, tmp + p + q + 1, regularized, -1, 1, prec); acb_poly_get_coeff_acb(res, tmp, 0); for (i = 0; i < p + q + 2; i++) acb_poly_clear(tmp + i); flint_free(tmp); } else { acb_ptr tmp; slong i, j, alloc = 0; /* check if we can remove a '1' from the upper parameters */ for (i = 0; i < p; i++) { if (acb_is_one(a + i)) { alloc = p; tmp = _acb_vec_init(alloc); for (j = 0; j < p - 1; j++) acb_set(tmp + 1 + j, a + j + (j >= i)); acb_hypgeom_pfq_direct(tmp, tmp + 1, p - 1, b, q, z, -1, prec); break; } } if (alloc == 0) { alloc = q + 2; tmp = _acb_vec_init(alloc); for (j = 0; j < q; j++) acb_set(tmp + 1 + j, b + j); acb_one(tmp + 1 + q); acb_hypgeom_pfq_direct(tmp, a, p, tmp + 1, q + 1, z, -1, prec); } if (regularized && q > 0) { acb_t c, t; acb_init(c); acb_init(t); acb_rgamma(c, b, prec); for (i = 1; i < q; i++) { acb_rgamma(t, b + i, prec); acb_mul(c, c, t, prec); } acb_mul(tmp, tmp, c, prec); acb_clear(c); acb_clear(t); } acb_set(res, tmp); _acb_vec_clear(tmp, alloc); } if (!acb_is_finite(res)) acb_indeterminate(res); } arb-2.22.1/acb_hypgeom/pfq_bound_factor.c000066400000000000000000000027121417376376500203230ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_pfq_bound_factor(mag_t C, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, ulong n) { mag_t t, u; acb_t w; slong i; if (p > q) { mag_inf(C); return; } mag_init(t); mag_init(u); acb_init(w); acb_get_mag(C, z); for (i = 0; i < q; i++) { acb_add_ui(w, b + i, n, MAG_BITS); if (arb_is_positive(acb_realref(w))) { acb_get_mag_lower(u, w); if (i < p) { acb_sub(w, a + i, b + i, MAG_BITS); acb_get_mag(t, w); mag_div(t, t, u); mag_one(u); mag_add(t, t, u); mag_mul(C, C, t); } else { mag_div(C, C, u); } } else { mag_inf(C); } } mag_one(t); mag_sub_lower(u, t, C); if (mag_is_zero(u)) mag_inf(C); else mag_div(C, t, u); mag_clear(t); mag_clear(u); acb_clear(w); } arb-2.22.1/acb_hypgeom/pfq_choose_n.c000066400000000000000000000200341417376376500174500ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #define D_ABS(x) ((x) < 0.0 ? (-(x)) : (x)) int acb_hypgeom_pfq_choose_n_double(slong * nn, const double * are, const double * aim, slong p, const double * bre, const double * bim, slong q, double log2_z, slong n_skip, slong n_min, slong n_max, slong prec) { double increase, term, term_max, accuracy, accuracy_best, t, u; double required_decrease; slong k, n, n_best; int success; if (p < q) required_decrease = 0.01; else if (p == q) required_decrease = 0.0001; else required_decrease = 0.01; term = term_max = accuracy = accuracy_best = 0.0; success = 0; for (n = n_best = n_skip; n < n_max; n++) { t = 1.0; for (k = 0; k < FLINT_MAX(p, q); k++) { if (k < p) { u = (are[k]+n-1)*(are[k]+n-1) + (aim[k]*aim[k]); t *= D_ABS(u); } if (k < q) { u = (bre[k]+n-1)*(bre[k]+n-1) + (bim[k]*bim[k]); u = D_ABS(u); if (u > 1e-100) t /= u; } } increase = 0.5 * log(t) * 1.4426950408889634074 + log2_z; term += increase; term_max = FLINT_MAX(term_max, term); accuracy = term_max - term; if (accuracy > accuracy_best && n >= n_min && increase < -required_decrease) { n_best = n; accuracy_best = accuracy; } if (accuracy_best > prec + 4) { success = 1; break; } } *nn = n_best; return success; } slong acb_hypgeom_pfq_choose_n_max(acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong prec, slong n_max) { slong n_skip, n_min, n_terminating, nint; slong k, n; double log2_z; double * are; double * aim; double * bre; double * bim; mag_t zmag; int success; if (acb_is_zero(z) || !acb_is_finite(z)) return 1; mag_init(zmag); are = flint_malloc(sizeof(double) * 2 * (p + q)); aim = are + p; bre = aim + p; bim = bre + q; acb_get_mag(zmag, z); log2_z = mag_get_d_log2_approx(zmag); n_skip = 1; n_min = 1; n_terminating = WORD_MAX; for (k = 0; k < p; k++) { are[k] = arf_get_d(arb_midref(acb_realref(a + k)), ARF_RND_DOWN); aim[k] = arf_get_d(arb_midref(acb_imagref(a + k)), ARF_RND_DOWN); /* If the series is terminating, stop at this n. */ if (acb_is_int(a + k) && are[k] <= 0.0) { n_terminating = FLINT_MIN(n_terminating, (slong) (-are[k] + 1)); n_terminating = FLINT_MAX(n_terminating, 1); } else if (are[k] <= 0.01 && D_ABS(aim[k]) < 0.01) { /* If very close to an integer, we don't want to deal with it using doubles, so fast forward (todo: could work with the log2 of the difference instead when this happens). */ nint = floor(are[k] + 0.5); if (D_ABS(nint - are[k]) < 0.01) n_skip = FLINT_MAX(n_skip, 2 - nint); } } n_max = FLINT_MIN(n_max, n_terminating); for (k = 0; k < q; k++) { bre[k] = arf_get_d(arb_midref(acb_realref(b + k)), ARF_RND_DOWN); bim[k] = arf_get_d(arb_midref(acb_imagref(b + k)), ARF_RND_DOWN); if (bre[k] <= 0.25) { n_min = FLINT_MAX(n_min, 2 - bre[k]); /* Also avoid near-integers here (can even allow exact integers when computing regularized hypergeometric functions). */ if (bre[k] <= 0.01 && D_ABS(bim[k]) < 0.01) { nint = floor(bre[k] + 0.5); if (D_ABS(nint - bre[k]) < 0.01) n_skip = FLINT_MAX(n_skip, 2 - nint); } } } success = acb_hypgeom_pfq_choose_n_double(&n, are, aim, p, bre, bim, q, log2_z, n_skip, n_min, n_max, prec); if (!success) { if (n_terminating <= n_max) { n = n_terminating; } else { n = FLINT_MAX(n_min, n); n = FLINT_MIN(n_max, n); } } flint_free(are); mag_clear(zmag); return n; } slong acb_hypgeom_pfq_choose_n(acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong prec) { return acb_hypgeom_pfq_choose_n_max(a, p, b, q, z, prec, FLINT_MIN(WORD_MAX / 2, 50 + 10.0 * prec)); } slong acb_hypgeom_pfq_series_choose_n(const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, slong len, slong prec) { slong n_skip, n_min, n_max, n_terminating, nint; slong k, n; double log2_z; double * are; double * aim; double * bre; double * bim; acb_t t; mag_t zmag; int success; if (z->length == 0) /* todo: check finite */ return 1; mag_init(zmag); acb_init(t); are = flint_malloc(sizeof(double) * 2 * (p + q)); aim = are + p; bre = aim + p; bim = bre + q; acb_get_mag(zmag, z->coeffs); log2_z = mag_get_d_log2_approx(zmag); n_skip = 1; n_min = 1; n_max = FLINT_MIN(WORD_MAX / 2, 50 + 10.0 * prec); n_terminating = WORD_MAX; /* e.g. for exp(x + O(x^100)), make sure that we actually run the recurrence up to order 100. todo: compute correctly based on degrees of inputs */ n_min = FLINT_MAX(n_min, len); n_max = FLINT_MAX(n_max, n_min); for (k = 0; k < p; k++) { acb_poly_get_coeff_acb(t, a + k, 0); are[k] = arf_get_d(arb_midref(acb_realref(t)), ARF_RND_DOWN); aim[k] = arf_get_d(arb_midref(acb_imagref(t)), ARF_RND_DOWN); /* If the series is terminating, stop at this n. */ if (acb_is_int(t) && are[k] <= 0.0 && acb_poly_length(a + k) <= 1) { n_terminating = FLINT_MIN(n_terminating, (slong) (-are[k] + 1)); n_terminating = FLINT_MAX(n_terminating, 1); } else if (are[k] <= 0.01 && D_ABS(aim[k]) < 0.01) { /* If very close to an integer, we don't want to deal with it using doubles, so fast forward (todo: could work with the log2 of the difference instead when this happens). */ nint = floor(are[k] + 0.5); if (D_ABS(nint - are[k]) < 0.01) n_skip = FLINT_MAX(n_skip, 2 - nint); } } n_max = FLINT_MIN(n_max, n_terminating); for (k = 0; k < q; k++) { acb_poly_get_coeff_acb(t, b + k, 0); bre[k] = arf_get_d(arb_midref(acb_realref(t)), ARF_RND_DOWN); bim[k] = arf_get_d(arb_midref(acb_imagref(t)), ARF_RND_DOWN); if (bre[k] <= 0.25) { n_min = FLINT_MAX(n_min, 2 - bre[k]); /* Also avoid near-integers here (can even allow exact integers when computing regularized hypergeometric functions). */ if (bre[k] <= 0.01 && D_ABS(bim[k]) < 0.01) { nint = floor(bre[k] + 0.5); if (D_ABS(nint - bre[k]) < 0.01) n_skip = FLINT_MAX(n_skip, 2 - nint); } } } success = acb_hypgeom_pfq_choose_n_double(&n, are, aim, p, bre, bim, q, log2_z, n_skip, n_min, n_max, prec); if (!success) { if (n_terminating <= n_max) { n = n_terminating; } else { n = FLINT_MAX(n_min, n); n = FLINT_MIN(n_max, n); } } flint_free(are); acb_clear(t); mag_clear(zmag); return n; } arb-2.22.1/acb_hypgeom/pfq_direct.c000066400000000000000000000022721417376376500171310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_pfq_direct(acb_t res, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_t s, t; mag_t err, C; acb_init(s); acb_init(t); mag_init(err); mag_init(C); if (n < 0) n = acb_hypgeom_pfq_choose_n(a, p, b, q, z, prec); acb_hypgeom_pfq_sum(s, t, a, p, b, q, z, n, prec); if (!acb_is_zero(t)) { acb_hypgeom_pfq_bound_factor(C, a, p, b, q, z, n); acb_get_mag(err, t); mag_mul(err, err, C); if (_acb_vec_is_real(a, p) && _acb_vec_is_real(b, q) && acb_is_real(z)) arb_add_error_mag(acb_realref(s), err); else acb_add_error_mag(s, err); } acb_set(res, s); acb_clear(s); acb_clear(t); mag_clear(err); mag_clear(C); } arb-2.22.1/acb_hypgeom/pfq_series_direct.c000066400000000000000000000153541417376376500205100ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_poly_reciprocal_majorant(arb_ptr res, acb_srcptr vec, slong len, slong prec) { slong i; for (i = 0; i < len; i++) { if (i == 0) { acb_get_abs_lbound_arf(arb_midref(res + i), vec + i, prec); mag_zero(arb_radref(res + i)); } else { acb_get_abs_ubound_arf(arb_midref(res + i), vec + i, prec); arf_neg(arb_midref(res + i), arb_midref(res + i)); mag_zero(arb_radref(res + i)); } } } void acb_poly_reciprocal_majorant(arb_poly_t res, const acb_poly_t poly, slong prec) { arb_poly_fit_length(res, poly->length); _acb_poly_reciprocal_majorant(res->coeffs, poly->coeffs, poly->length, prec); _arb_poly_set_length(res, poly->length); } /* F = 1 + U + U^2 + ... = 1/(1-U) assuming that U[0] is positive; indeterminate if not convergent */ static void arb_poly_geometric_sum(arb_poly_t F, const arb_poly_t U, slong len, slong prec) { if (U->length == 0) { arb_poly_one(F); return; } arb_poly_add_si(F, U, -1, prec); arb_poly_neg(F, F); if (F->length > 0 && arb_is_positive(F->coeffs)) { arb_poly_inv_series(F, F, len, prec); } else { arb_poly_fit_length(F, len); _arb_vec_indeterminate(F->coeffs, len); _arb_poly_set_length(F, len); } } /* F = 1 + U + U^2 + U^3 + ... = 1/(1-U) U = product of (1 + |A-B|/(|B[0] - |B[1:]|) product of (1 / (|B[0] - |B[1:]|)) * |Z| */ void acb_hypgeom_pfq_series_bound_factor(arb_poly_t F, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, slong n, slong len, slong prec) { slong i; arb_poly_t T, U, V; acb_poly_t BN, AB; /* not convergent */ if (p > q) { arb_poly_fit_length(F, len); _arb_vec_indeterminate(F->coeffs, len); _arb_poly_set_length(F, len); return; } arb_poly_init(T); arb_poly_init(U); arb_poly_init(V); acb_poly_init(BN); acb_poly_init(AB); acb_poly_majorant(U, z, prec); for (i = 0; i < q; i++) { acb_poly_add_si(BN, b + i, n, prec); if (acb_poly_length(BN) != 0 && arb_is_positive(acb_realref(BN->coeffs))) { if (i < p) { /* 1 + |a-b|/reciprocal_majorant(b + n) */ acb_poly_sub(AB, a + i, b + i, prec); acb_poly_majorant(T, AB, prec); acb_poly_reciprocal_majorant(V, BN, prec); arb_poly_div_series(T, T, V, len, prec); arb_poly_add_si(T, T, 1, prec); arb_poly_mullow(U, U, T, len, prec); } else { acb_poly_reciprocal_majorant(T, BN, prec); arb_poly_div_series(U, U, T, len, prec); } } else { arb_poly_fit_length(U, len); _arb_vec_indeterminate(U->coeffs, len); _arb_poly_set_length(U, len); break; } } /* F = 1/(1-U) */ arb_poly_geometric_sum(F, U, len, prec); arb_poly_clear(T); arb_poly_clear(U); arb_poly_clear(V); acb_poly_clear(BN); acb_poly_clear(AB); } void acb_hypgeom_pfq_series_direct(acb_poly_t res, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) { acb_poly_t s, t, err; arb_poly_t C, T; slong i; int is_real; int terminating; /* default algorithm to choose number of terms */ if (n < 0) { n = acb_hypgeom_pfq_series_choose_n(a, p, b, q, z, len, prec); } terminating = 0; /* check if it terminates due to a root of the numerator */ for (i = 0; i < p; i++) { if (acb_poly_length(a + i) == 0 && n > 0) { terminating = 1; } else if (acb_poly_length(a + i) == 1) { acb_srcptr c = acb_poly_get_coeff_ptr(a + i, 0); if (acb_is_int(c) && arb_is_negative(acb_realref(c)) && arf_cmpabs_ui(arb_midref(acb_realref(c)), n) < 0) { terminating = 1; } } } /* check if it terminates (to order n) due to z */ /* the following tests could be made stronger... */ if (z->length == 0 && n >= 1) { terminating = 1; } else if (!terminating && z->length > 0 && acb_is_zero(z->coeffs) && n >= len) { if (regularized) { terminating = 1; } else { terminating = 1; for (i = 0; i < q; i++) { acb_srcptr c = acb_poly_get_coeff_ptr(b + i, 0); if (!arb_is_positive(acb_realref(c)) && acb_contains_int(c)) terminating = 0; } } } acb_poly_init(s); acb_poly_init(t); acb_poly_init(err); arb_poly_init(C); arb_poly_init(T); acb_hypgeom_pfq_series_sum(s, t, a, p, b, q, z, regularized, n, len, prec); if (!terminating) { is_real = acb_poly_is_real(z); for (i = 0; i < p; i++) is_real = is_real && acb_poly_is_real(a + i); for (i = 0; i < q; i++) is_real = is_real && acb_poly_is_real(b + i); acb_poly_majorant(T, t, MAG_BITS); acb_hypgeom_pfq_series_bound_factor(C, a, p, b, q, z, n, len, MAG_BITS); if (!_arb_vec_is_finite(T->coeffs, T->length) || !_arb_vec_is_finite(C->coeffs, C->length)) { arb_poly_fit_length(T, len); _arb_vec_indeterminate(T->coeffs, len); _arb_poly_set_length(T, len); } else { arb_poly_mullow(T, T, C, len, MAG_BITS); } /* create polynomial of errors */ acb_poly_fit_length(err, len); for (i = 0; i < FLINT_MIN(len, T->length); i++) { arb_add_error(acb_realref(err->coeffs + i), T->coeffs + i); if (!is_real) arb_add_error(acb_imagref(err->coeffs + i), T->coeffs + i); } _acb_poly_set_length(err, len); _acb_poly_normalise(err); acb_poly_add(s, s, err, prec); } acb_poly_set(res, s); acb_poly_clear(s); acb_poly_clear(t); acb_poly_clear(err); arb_poly_clear(C); arb_poly_clear(T); } arb-2.22.1/acb_hypgeom/pfq_series_sum.c000066400000000000000000000043271417376376500200400ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_pfq_series_sum(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) { slong abits, zbits, i, j, cb; if (n < 4) { acb_hypgeom_pfq_series_sum_forward(s, t, a, p, b, q, z, regularized, n, len, prec); return; } abits = 0; zbits = 0; for (i = 0; i < p; i++) { for (j = 0; j < FLINT_MIN(acb_poly_length(a + i), n); j++) { cb = acb_bits((a + i)->coeffs + j); abits = FLINT_MAX(abits, cb); } } for (i = 0; i < q; i++) { for (j = 0; j < FLINT_MIN(acb_poly_length(b + i), n); j++) { cb = acb_bits((b + i)->coeffs + j); abits = FLINT_MAX(abits, cb); } } for (j = 0; j < FLINT_MIN(acb_poly_length(z), n); j++) { cb = acb_bits(z->coeffs + j); zbits = FLINT_MAX(zbits, cb); } /* Prefer RS with small coefficients in parameters, large coefficients in z. TODO: tune for larger len? */ if (len <= 5 && prec > 900 && abits < prec * 0.1 && zbits > prec * 0.1) { acb_hypgeom_pfq_series_sum_rs(s, t, a, p, b, q, z, regularized, n, len, prec); return; } /* Prefer BS with small coefficients and high precision, or when computing derivatives of high order. */ if ((abits < prec * 0.1 && zbits < prec * 0.1 && prec > 600) || len > 20) { acb_hypgeom_pfq_series_sum_bs(s, t, a, p, b, q, z, regularized, n, len, prec); return; } /* TODO: also use bs here when n is large enough, for better numerical stability? */ acb_hypgeom_pfq_series_sum_forward(s, t, a, p, b, q, z, regularized, n, len, prec); } arb-2.22.1/acb_hypgeom/pfq_series_sum_bs.c000066400000000000000000000121151417376376500205160ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void factor(acb_poly_t A, acb_poly_t tmp, const acb_poly_struct * a, slong p, const acb_poly_t z, slong k, slong len, slong prec) { slong i; if (p == 0) { if (z == NULL) acb_poly_one(A); else acb_poly_set(A, z); } else { acb_poly_add_si(A, a, k, prec); for (i = 1; i < p; i++) { acb_poly_add_si(tmp, a + i, k, prec); acb_poly_mullow(A, A, tmp, len, prec); } if (z != NULL) { acb_poly_mullow(A, A, z, len, prec); } } } static void bsplit(acb_poly_t A1, acb_poly_t B1, acb_poly_t C1, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, slong aa, slong bb, slong len, slong prec) { if (bb - aa == 1) { factor(A1, B1, a, p, z, aa, len, prec); factor(C1, B1, b, q, NULL, aa, len, prec); /* acb_poly_set(B1, C1); but we skip this */ } else { slong m; acb_poly_t A2, B2, C2, tmp; acb_poly_init(A2); acb_poly_init(B2); acb_poly_init(C2); acb_poly_init(tmp); m = aa + (bb - aa) / 2; bsplit(A1, B1, C1, a, p, b, q, z, aa, m, len, prec); bsplit(A2, B2, C2, a, p, b, q, z, m, bb, len, prec); if (bb - m == 1) /* B2 = C2 */ { if (m - aa == 1) acb_poly_add(B2, A1, C1, prec); else acb_poly_add(B2, A1, B1, prec); acb_poly_mullow(B1, B2, C2, len, prec); } else { if (m - aa == 1) { acb_poly_mullow(B1, C1, C2, len, prec); } else { acb_poly_mullow(tmp, B1, C2, len, prec); acb_poly_swap(B1, tmp); } acb_poly_mullow(tmp, A1, B2, len, prec); acb_poly_add(B1, B1, tmp, prec); } acb_poly_mullow(tmp, A1, A2, len, prec); acb_poly_swap(A1, tmp); acb_poly_mullow(tmp, C1, C2, len, prec); acb_poly_swap(C1, tmp); acb_poly_clear(A2); acb_poly_clear(B2); acb_poly_clear(C2); acb_poly_clear(tmp); } } void acb_hypgeom_pfq_series_sum_bs(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) { acb_poly_t u, v, w; slong i, start; if (n == 0) { acb_hypgeom_pfq_series_sum_forward(s, t, a, p, b, q, z, regularized, n, len, prec); return; } start = 0; if (regularized) { /* Use basecase algorithm to get past any poles. G(x) = 1/Gamma(x) n = 1: s = 0; t = G(b); b = 0 requires skipping n = 2: s = G(b); t = G(b) G(b+1); b = 0, -1 require skipping... TODO: when pole is near the end, do the *start* (or middle segment) using fast algorithm; use basecase algorithm for the end. */ for (i = 0; i < q; i++) { if (acb_poly_is_zero(b + i)) { start = FLINT_MAX(start, 1); } else { /* todo: use a fuzzier test? */ if (acb_contains_int((b + i)->coeffs) && !arb_is_positive(acb_realref((b + i)->coeffs)) && arf_cmpabs_2exp_si(arb_midref(acb_realref((b + i)->coeffs)), FLINT_BITS - 2) < 0) { slong c = -arf_get_si(arb_midref(acb_realref((b + i)->coeffs)), ARF_RND_NEAR); /* if c >= n, terminates earlier, so no problem */ if (c < n) { start = FLINT_MAX(start, c + 1); } } } } /* We should now have start <= n. */ if (start > n) flint_abort(); acb_hypgeom_pfq_series_sum_forward(s, t, a, p, b, q, z, regularized, start, len, prec); } else { acb_poly_zero(s); acb_poly_one(t); } if (start == n) return; acb_poly_init(u); acb_poly_init(v); acb_poly_init(w); bsplit(u, v, w, a, p, b, q, z, start, n, len, prec); if (n - start == 1) acb_poly_set(v, w); /* B1 not set */ acb_poly_mullow(v, v, t, len, prec); acb_poly_div_series(v, v, w, len, prec); acb_poly_add(s, s, v, prec); acb_poly_mullow(t, t, u, len, prec); acb_poly_div_series(t, t, w, len, prec); acb_poly_clear(u); acb_poly_clear(v); acb_poly_clear(w); } arb-2.22.1/acb_hypgeom/pfq_series_sum_forward.c000066400000000000000000000102521417376376500215560ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_pfq_series_sum_forward(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) { acb_poly_t u, v; acb_poly_t tmp; slong k, i; acb_poly_init(u); acb_poly_init(v); acb_poly_init(tmp); if (!regularized) { acb_poly_zero(s); acb_poly_one(t); for (k = 0; k < n && acb_poly_length(t) != 0; k++) { acb_poly_add(s, s, t, prec); if (p > 0) { acb_poly_add_si(u, a, k, prec); for (i = 1; i < p; i++) { acb_poly_add_si(v, a + i, k, prec); acb_poly_mullow(u, u, v, len, prec); } acb_poly_mullow(t, t, u, len, prec); } if (q > 0) { acb_poly_add_si(u, b, k, prec); for (i = 1; i < q; i++) { acb_poly_add_si(v, b + i, k, prec); acb_poly_mullow(u, u, v, len, prec); } acb_poly_div_series(t, t, u, len, prec); } acb_poly_mullow(t, t, z, len, prec); } } else { acb_poly_zero(s); if (q == 0) acb_poly_one(t); for (i = 0; i < q; i++) { if (i == 0) { acb_poly_rgamma_series(t, b + i, len, prec); } else { acb_poly_rgamma_series(u, b + i, len, prec); acb_poly_mullow(tmp, t, u, len, prec); acb_poly_swap(tmp, t); } } for (k = 0; k < n; k++) { acb_poly_add(s, s, t, prec); if (p > 0) { acb_poly_add_si(u, a, k, prec); for (i = 1; i < p; i++) { acb_poly_add_si(v, a + i, k, prec); acb_poly_mullow(tmp, u, v, len, prec); acb_poly_swap(tmp, u); } acb_poly_mullow(tmp, t, u, len, prec); acb_poly_swap(tmp, t); } if (q > 0) { acb_poly_add_si(u, b, k, prec); for (i = 1; i < q; i++) { acb_poly_add_si(v, b + i, k, prec); acb_poly_mullow(tmp, u, v, len, prec); acb_poly_swap(tmp, u); } if (acb_poly_length(u) > 0 && !acb_contains_zero(u->coeffs)) { acb_poly_div_series(tmp, t, u, len, prec); acb_poly_mullow(t, tmp, z, len, prec); } else { /* compute term from scratch */ acb_poly_one(t); for (i = 0; i < p; i++) { acb_poly_rising_ui_series(v, a + i, k + 1, len, prec); acb_poly_mullow(t, t, v, len, prec); } for (i = 0; i < q; i++) { acb_poly_add_si(v, b + i, k + 1, prec); acb_poly_rgamma_series(v, v, len, prec); acb_poly_mullow(t, t, v, len, prec); } acb_poly_pow_ui_trunc_binexp(v, z, k + 1, len, prec); acb_poly_mullow(t, t, v, len, prec); } } else { acb_poly_mullow(tmp, t, z, len, prec); acb_poly_swap(tmp, t); } } } acb_poly_clear(u); acb_poly_clear(v); acb_poly_clear(tmp); } arb-2.22.1/acb_hypgeom/pfq_series_sum_rs.c000066400000000000000000000157571417376376500205550ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" #define FAST_T 0 void acb_poly_reciprocal_majorant(arb_poly_t res, const acb_poly_t poly, slong prec); static void rsplit(acb_poly_t res, acb_poly_t term, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, slong offset, slong n, slong len, slong prec) { acb_poly_struct * zpow; acb_poly_t s, t, u; slong i, j, k, m, tprec; int is_real; #if FAST_T arb_poly_t B, C, D; #else acb_poly_t B, C, D; #endif if (n == 0) { acb_poly_zero(res); acb_poly_one(term); return; } if (n < 0) flint_abort(); m = n_sqrt(n); m = FLINT_MIN(m, 150); acb_poly_init(s); acb_poly_init(t); acb_poly_init(u); #if FAST_T tprec = MAG_BITS; arb_poly_init(B); arb_poly_init(C); arb_poly_init(D); arb_poly_one(B); arb_poly_one(D); is_real = 1; for (i = 0; i < p; i++) for (j = 0; j < FLINT_MIN(acb_poly_length(a + i), len); j++) is_real = is_real && acb_is_real((a + i)->coeffs + j); for (i = 0; i < q; i++) for (j = 0; j < FLINT_MIN(acb_poly_length(b + i), len); j++) is_real = is_real && acb_is_real((b + i)->coeffs + j); for (j = 0; j < FLINT_MIN(acb_poly_length(z), len); j++) is_real = is_real && acb_is_real(z->coeffs + j); #else tprec = 2 * MAG_BITS; is_real = 0; (void) is_real; acb_poly_init(B); acb_poly_init(C); acb_poly_init(D); acb_poly_one(B); acb_poly_one(D); #endif zpow = flint_malloc(sizeof(acb_poly_struct) * (m + 1)); for (i = 0; i <= m; i++) acb_poly_init(zpow + i); for (i = 0; i <= m; i++) { if (i == 0) acb_poly_one(zpow + i); else if (i == 1) acb_poly_set_round(zpow + i, z, prec); else if (i % 2 == 0) acb_poly_mullow(zpow + i, zpow + i / 2, zpow + i / 2, len, prec); else acb_poly_mullow(zpow + i, zpow + i - 1, zpow + 1, len, prec); } for (k = n; k >= 0; k--) { j = k % m; if (k < n) acb_poly_add(s, s, zpow + j, prec); if (k > 0) { if (p > 0) { acb_poly_add_si(u, a, offset + k - 1, prec); for (i = 1; i < p; i++) { acb_poly_add_si(t, a + i, offset + k - 1, prec); acb_poly_mullow(u, u, t, len, prec); } if (k < n) acb_poly_mullow(s, s, u, len, prec); #if FAST_T acb_poly_majorant(C, u, tprec); arb_poly_mullow(B, B, C, len, tprec); #else acb_poly_set_round(C, u, tprec); acb_poly_mullow(B, B, C, len, tprec); #endif } if (q > 0) { acb_poly_add_si(u, b, offset + k - 1, prec); for (i = 1; i < q; i++) { acb_poly_add_si(t, b + i, offset + k - 1, prec); acb_poly_mullow(u, u, t, len, prec); } if (k < n) acb_poly_div_series(s, s, u, len, prec); #if FAST_T acb_poly_reciprocal_majorant(C, u, tprec); arb_poly_mullow(D, D, C, len, tprec); #else acb_poly_set_round(C, u, tprec); acb_poly_mullow(D, D, C, len, tprec); #endif } if (j == 0 && k < n) { acb_poly_mullow(s, s, zpow + m, len, prec); } } } #if FAST_T arb_poly_div_series(B, B, D, len, tprec); acb_poly_majorant(C, z, tprec); arb_poly_pow_ui_trunc_binexp(C, C, n, len, tprec); arb_poly_mullow(C, B, C, len, tprec); acb_poly_fit_length(term, arb_poly_length(C)); for (i = 0; i < arb_poly_length(C); i++) { arb_get_mag(arb_radref(acb_realref(term->coeffs + i)), C->coeffs + i); arf_zero(arb_midref(acb_realref(term->coeffs + i))); if (is_real) arb_zero(acb_imagref(term->coeffs + i)); else arb_set(acb_imagref(term->coeffs + i), acb_realref(term->coeffs + i)); } _acb_poly_set_length(term, arb_poly_length(C)); _acb_poly_normalise(term); #else acb_poly_div_series(B, B, D, len, tprec); acb_poly_set_round(C, z, tprec); acb_poly_pow_ui_trunc_binexp(C, C, n, len, tprec); acb_poly_mullow(term, B, C, len, tprec); #endif acb_poly_set(res, s); #if FAST_T arb_poly_clear(B); arb_poly_clear(C); arb_poly_clear(D); #else acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(D); #endif acb_poly_clear(s); acb_poly_clear(t); acb_poly_clear(u); for (i = 0; i <= m; i++) acb_poly_clear(zpow + i); flint_free(zpow); } void acb_hypgeom_pfq_series_sum_rs(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) { acb_poly_t u, v; slong i, start; if (n == 0) { acb_hypgeom_pfq_series_sum_forward(s, t, a, p, b, q, z, regularized, n, len, prec); return; } start = 0; if (regularized) { for (i = 0; i < q; i++) { if (acb_poly_is_zero(b + i)) { start = FLINT_MAX(start, 1); } else { /* todo: use a fuzzier test? */ if (acb_contains_int((b + i)->coeffs) && !arb_is_positive(acb_realref((b + i)->coeffs)) && arf_cmpabs_2exp_si(arb_midref(acb_realref((b + i)->coeffs)), FLINT_BITS - 2) < 0) { slong c = -arf_get_si(arb_midref(acb_realref((b + i)->coeffs)), ARF_RND_NEAR); /* if c >= n, terminates earlier, so no problem */ if (c < n) { start = FLINT_MAX(start, c + 1); } } } } /* We should now have start <= n. */ if (start > n) flint_abort(); acb_hypgeom_pfq_series_sum_forward(s, t, a, p, b, q, z, regularized, start, len, prec); } else { acb_poly_zero(s); acb_poly_one(t); } if (start == n) return; acb_poly_init(u); acb_poly_init(v); rsplit(u, v, a, p, b, q, z, start, n - start, len, prec); acb_poly_mullow(u, u, t, len, prec); acb_poly_add(s, s, u, prec); acb_poly_mullow(t, t, v, len, prec); acb_poly_clear(u); acb_poly_clear(v); } arb-2.22.1/acb_hypgeom/pfq_sum.c000066400000000000000000000042651417376376500164670ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_pfq_sum(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { if (n > 4 && prec >= 128 && _acb_vec_bits(a, p) * p + _acb_vec_bits(b, q) * q + 10 < prec / 2) { if (prec >= 256 && acb_bits(z) < prec * 0.01) acb_hypgeom_pfq_sum_bs(s, t, a, p, b, q, z, n, prec); else acb_hypgeom_pfq_sum_rs(s, t, a, p, b, q, z, n, prec); } else if (prec >= 1500 && n >= 30 + 100000 / (prec - 1000)) { acb_hypgeom_pfq_sum_fme(s, t, a, p, b, q, z, n, prec); } else { /* With inexact complex numbers, prefer binary splitting as it reduces the wrapping effect. */ if (n > 8) acb_hypgeom_pfq_sum_bs(s, t, a, p, b, q, z, n, prec); else acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, z, n, prec); } } void acb_hypgeom_pfq_sum_invz(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, const acb_t zinv, slong n, slong prec) { if (n > 4 && prec >= 128 && _acb_vec_bits(a, p) * p + _acb_vec_bits(b, q) * q + 10 < prec / 2) { if (prec >= 256 && acb_bits(zinv) < prec * 0.01) acb_hypgeom_pfq_sum_bs_invz(s, t, a, p, b, q, zinv, n, prec); else acb_hypgeom_pfq_sum_rs(s, t, a, p, b, q, z, n, prec); } else if (prec >= 1500 && n >= 30 + 100000 / (prec - 1000)) { acb_hypgeom_pfq_sum_fme(s, t, a, p, b, q, z, n, prec); } else { /* With inexact complex numbers, binary splitting as it reduces the wrapping effect. */ if (n > 8) acb_hypgeom_pfq_sum_bs_invz(s, t, a, p, b, q, zinv, n, prec); else acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, z, n, prec); } } arb-2.22.1/acb_hypgeom/pfq_sum_bs.c000066400000000000000000000105411417376376500171450ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* [S(k+1)] = [ R(k) 0 ] [S(k)] [T(k+1)] [ 1 1 ] [T(k)] [S(k+1)] = [ P(k) / Q(k) 0 ] [S(k)] [T(k+1)] [ 1 1 ] [T(k)] 1 [ P(k) ] ---- [ ] Q(k) [ Q(k) Q(k) ] [[A2 0] [B2 C2]] . [[A1 0] [B1 C1]] = [[A1 A2 0] [A1 B2 + B1 C2 C1 C2] A1 B2 + B1 B2 = B2 (A1 + B1) -- use to save time? */ static void factor(acb_t A, acb_t tmp, acb_srcptr a, slong p, const acb_t z, slong k, slong prec) { slong i; if (p == 0) { if (z == NULL) acb_one(A); else acb_set(A, z); } else { acb_add_ui(A, a, k, prec); for (i = 1; i < p; i++) { acb_add_ui(tmp, a + i, k, prec); acb_mul(A, A, tmp, prec); } if (z != NULL) acb_mul(A, A, z, prec); } } static void bsplit(acb_t A1, acb_t B1, acb_t C1, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong aa, slong bb, slong prec, int invz) { if (bb - aa == 1) { factor(A1, B1, a, p, invz ? NULL : z, aa, prec); factor(C1, B1, b, q, invz ? z : NULL, aa, prec); /* acb_set(B1, C1); but we skip this */ } else { slong m; acb_t A2, B2, C2; acb_init(A2); acb_init(B2); acb_init(C2); m = aa + (bb - aa) / 2; bsplit(A1, B1, C1, a, p, b, q, z, aa, m, prec, invz); bsplit(A2, B2, C2, a, p, b, q, z, m, bb, prec, invz); if (bb - m == 1) /* B2 = C2 */ { if (m - aa == 1) acb_add(B2, A1, C1, prec); else acb_add(B2, A1, B1, prec); acb_mul(B1, B2, C2, prec); } else { if (m - aa == 1) acb_mul(B1, C1, C2, prec); else acb_mul(B1, B1, C2, prec); acb_addmul(B1, A1, B2, prec); } acb_mul(A1, A1, A2, prec); acb_mul(C1, C1, C2, prec); acb_clear(A2); acb_clear(B2); acb_clear(C2); } } void acb_hypgeom_pfq_sum_bs(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_t u, v, w, tmp; if (n < 4) { acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, z, n, prec); return; } acb_init(u); acb_init(v); acb_init(w); acb_init(tmp); /* we compute to n-1 instead of n to avoid dividing by 0 in the denominator when computing a hypergeometric polynomial that terminates right before a pole */ bsplit(u, v, w, a, p, b, q, z, 0, n - 1, prec, 0); acb_add(s, u, v, prec); /* s = s + t */ acb_div(s, s, w, prec); /* split off last factor */ factor(t, tmp, a, p, z, n - 1, prec); acb_mul(u, u, t, prec); factor(t, tmp, b, q, NULL, n - 1, prec); acb_mul(w, w, t, prec); acb_div(t, u, w, prec); acb_clear(u); acb_clear(v); acb_clear(w); acb_clear(tmp); } void acb_hypgeom_pfq_sum_bs_invz(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_t u, v, w, tmp; if (n < 4) { acb_init(u); acb_inv(u, z, prec); acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, u, n, prec); acb_clear(u); return; } acb_init(u); acb_init(v); acb_init(w); acb_init(tmp); /* we compute to n-1 instead of n to avoid dividing by 0 in the denominator when computing a hypergeometric polynomial that terminates right before a pole */ bsplit(u, v, w, a, p, b, q, z, 0, n - 1, prec, 1); acb_add(s, u, v, prec); /* s = s + t */ acb_div(s, s, w, prec); /* split off last factor */ factor(t, tmp, a, p, NULL, n - 1, prec); acb_mul(u, u, t, prec); factor(t, tmp, b, q, z, n - 1, prec); acb_mul(w, w, t, prec); acb_div(t, u, w, prec); acb_clear(u); acb_clear(v); acb_clear(w); acb_clear(tmp); } arb-2.22.1/acb_hypgeom/pfq_sum_fme.c000066400000000000000000000152141417376376500173120ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void evaluate(acb_poly_t A, acb_srcptr a, slong p, const acb_t z, slong n, slong prec) { acb_poly_fit_length(A, p + 1); if (p == 1) { acb_add_ui(A->coeffs, a, n, prec); if (z != NULL) acb_mul(A->coeffs, A->coeffs, z, prec); } else if (p == 2) { acb_add(A->coeffs, a + 0, a + 1, prec); acb_add_ui(A->coeffs + 1, A->coeffs, 2 * n, prec); acb_add_ui(A->coeffs, A->coeffs, n, prec); acb_mul_ui(A->coeffs, A->coeffs, n, prec); acb_addmul(A->coeffs, a + 0, a + 1, prec); if (z != NULL) { acb_mul(A->coeffs, A->coeffs, z, prec); acb_mul(A->coeffs + 1, A->coeffs + 1, z, prec); } } else if (p == 3) { acb_t t, u; acb_init(t); acb_init(u); acb_add(t, a + 0, a + 1, prec); acb_add(t, t, a + 2, prec); acb_mul(u, a + 0, a + 1, prec); acb_mul(A->coeffs, u, a + 2, prec); acb_addmul(u, a + 0, a + 2, prec); acb_addmul(u, a + 1, a + 2, prec); /* (a0 + n)(a1 + n)(a2 + n) = a0 a1 a2 + (a0 a1 + a0 a2 + a1 a2) n + (a0 + a1 + a2) n^2 + n^3 (a0 a1 + a0 a2 + a1 a2) + 2 (a0 + a1 + a2) n + 3 n^2 (a0 + a1 + a2) + 3n 1 */ acb_addmul_ui(A->coeffs, u, n, prec); acb_addmul_ui(A->coeffs, t, n * n, prec); acb_add_ui(A->coeffs, A->coeffs, n * n * n, prec); acb_set(A->coeffs + 1, u); acb_addmul_ui(A->coeffs + 1, t, 2 * n, prec); acb_add_ui(A->coeffs + 1, A->coeffs + 1, 3 * n * n, prec); acb_add_ui(A->coeffs + 2, t, 3 * n, prec); if (z != NULL) { acb_mul(A->coeffs + 0, A->coeffs + 0, z, prec); acb_mul(A->coeffs + 1, A->coeffs + 1, z, prec); acb_mul(A->coeffs + 2, A->coeffs + 2, z, prec); } acb_clear(t); acb_clear(u); } else if (p != 0) { flint_abort(); } if (z != NULL) acb_set(A->coeffs + p, z); else acb_one(A->coeffs + p); _acb_poly_set_length(A, p + 1); _acb_poly_normalise(A); } /* todo: do this using underscore methods */ static void bsplit(acb_poly_t A, acb_poly_t B, acb_poly_t C, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong an, slong bn, slong prec) { if (bn - an == 1) { evaluate(A, a, p, z, an, prec); evaluate(B, b, q, NULL, an, prec); acb_poly_set(C, B); } else if (bn - an == 2) /* inlined */ { acb_poly_t A2, B2; acb_poly_init(A2); acb_poly_init(B2); evaluate(A, a, p, z, an, prec); evaluate(A2, a, p, z, an + 1, prec); evaluate(B, b, q, NULL, an, prec); evaluate(B2, b, q, NULL, an + 1, prec); acb_poly_mul(C, B, B2, prec); acb_poly_set(B, C); acb_poly_mul(C, A, B2, prec); acb_poly_add(C, C, B, prec); acb_poly_mul(A2, A, A2, prec); acb_poly_swap(A, A2); acb_poly_clear(A2); acb_poly_clear(B2); } else { slong m = an + (bn - an) / 2; acb_poly_t A2, B2, C2, T; acb_poly_init(A2); acb_poly_init(B2); acb_poly_init(C2); acb_poly_init(T); bsplit(A, B, C, a, p, b, q, z, an, m, prec); bsplit(A2, B2, C2, a, p, b, q, z, m, bn, prec); acb_poly_mul(T, B2, C, prec); acb_poly_mul(C, A, C2, prec); acb_poly_add(C, C, T, prec); acb_poly_mul(C2, B, B2, prec); acb_poly_swap(B, C2); acb_poly_mul(B2, A, A2, prec); acb_poly_swap(A, B2); acb_poly_clear(A2); acb_poly_clear(B2); acb_poly_clear(C2); acb_poly_clear(T); } } void acb_hypgeom_pfq_sum_fme(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_poly_t A, B, C; acb_ptr ks, As, Bs, Cs; acb_t u, v; acb_ptr * tree; slong i, k, m, w; /* we compute to n-1 instead of n to avoid dividing by 0 in the denominator when computing a hypergeometric polynomial that terminates right before a pole */ if (n > 4) { m = n_sqrt(n - 1) / 4; /* tuning parameter */ w = (n - 1) / FLINT_MAX(m, 1); } else { m = w = 0; } if (m < 1 || w < 1 || p > 3 || q > 3) { acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, z, n, prec); return; } acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(u); acb_init(v); ks = _acb_vec_init(w); As = _acb_vec_init(w); Bs = _acb_vec_init(w); Cs = _acb_vec_init(w); bsplit(A, B, C, a, p, b, q, z, 0, m, prec); for (i = 0; i < w; i++) acb_set_ui(ks + i, i * m); tree = _acb_poly_tree_alloc(w); _acb_poly_tree_build(tree, ks, w, prec); _acb_poly_evaluate_vec_fast_precomp(As, A->coeffs, A->length, tree, w, prec); _acb_poly_evaluate_vec_fast_precomp(Bs, B->coeffs, B->length, tree, w, prec); _acb_poly_evaluate_vec_fast_precomp(Cs, C->coeffs, C->length, tree, w, prec); _acb_poly_tree_free(tree, w); /* todo: use binary splitting here for improved numerical stability */ for (i = 1; i < w; i++) { acb_mul(Cs, Cs, Bs + i, prec); acb_addmul(Cs, As, Cs + i, prec); acb_mul(As, As, As + i, prec); acb_mul(Bs, Bs, Bs + i, prec); } acb_div(s, Cs, Bs, prec); acb_div(t, As, Bs, prec); for (k = w * m; k < n && !acb_is_zero(t); k++) { acb_add(s, s, t, prec); if (p > 0) { acb_add_ui(u, a, k, prec); for (i = 1; i < p; i++) { acb_add_ui(v, a + i, k, prec); acb_mul(u, u, v, prec); } acb_mul(t, t, u, prec); } if (q > 0) { acb_add_ui(u, b, k, prec); for (i = 1; i < q; i++) { acb_add_ui(v, b + i, k, prec); acb_mul(u, u, v, prec); } acb_div(t, t, u, prec); } acb_mul(t, t, z, prec); } acb_clear(u); acb_clear(v); _acb_vec_clear(ks, w); _acb_vec_clear(As, w); _acb_vec_clear(Bs, w); _acb_vec_clear(Cs, w); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } arb-2.22.1/acb_hypgeom/pfq_sum_forward.c000066400000000000000000000025031417376376500202040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_pfq_sum_forward(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_t u, v; slong k, i; acb_init(u); acb_init(v); acb_zero(s); acb_one(t); for (k = 0; k < n && !acb_is_zero(t); k++) { acb_add(s, s, t, prec); if (p > 0) { acb_add_ui(u, a, k, prec); for (i = 1; i < p; i++) { acb_add_ui(v, a + i, k, prec); acb_mul(u, u, v, prec); } acb_mul(t, t, u, prec); } if (q > 0) { acb_add_ui(u, b, k, prec); for (i = 1; i < q; i++) { acb_add_ui(v, b + i, k, prec); acb_mul(u, u, v, prec); } acb_div(t, t, u, prec); } acb_mul(t, t, z, prec); } acb_clear(u); acb_clear(v); } arb-2.22.1/acb_hypgeom/pfq_sum_rs.c000066400000000000000000000047621417376376500171750ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_pfq_sum_rs(acb_t res, acb_t term, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_ptr zpow; acb_t s, t, u; slong i, j, k, m; mag_t B, C; if (n == 0) { acb_zero(res); acb_one(term); return; } if (n < 0) flint_abort(); m = n_sqrt(n); m = FLINT_MIN(m, 150); mag_init(B); mag_init(C); acb_init(s); acb_init(t); acb_init(u); zpow = _acb_vec_init(m + 1); _acb_vec_set_powers(zpow, z, m + 1, prec); mag_one(B); for (k = n; k >= 0; k--) { j = k % m; if (k < n) acb_add(s, s, zpow + j, prec); if (k > 0) { if (p > 0) { acb_add_ui(u, a, k - 1, prec); for (i = 1; i < p; i++) { acb_add_ui(t, a + i, k - 1, prec); acb_mul(u, u, t, prec); } if (k < n) acb_mul(s, s, u, prec); acb_get_mag(C, u); mag_mul(B, B, C); } if (q > 0) { acb_add_ui(u, b, k - 1, prec); for (i = 1; i < q; i++) { acb_add_ui(t, b + i, k - 1, prec); acb_mul(u, u, t, prec); } if (k < n) acb_div(s, s, u, prec); acb_get_mag_lower(C, u); mag_div(B, B, C); } if (j == 0 && k < n) { acb_mul(s, s, zpow + m, prec); } } } acb_get_mag(C, z); mag_pow_ui(C, C, n); mag_mul(B, B, C); acb_zero(term); if (_acb_vec_is_real(a, p) && _acb_vec_is_real(b, q) && acb_is_real(z)) arb_add_error_mag(acb_realref(term), B); else acb_add_error_mag(term, B); acb_set(res, s); mag_clear(B); mag_clear(C); acb_clear(s); acb_clear(t); acb_clear(u); _acb_vec_clear(zpow, m + 1); } arb-2.22.1/acb_hypgeom/rising_ui.c000066400000000000000000000025051417376376500170000ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_rising_ui(acb_t y, const acb_t x, ulong n, slong prec) { if (n < FLINT_MAX(prec, 100)) { acb_hypgeom_rising_ui_rec(y, x, n, prec); } else { acb_t t; acb_init(t); acb_add_ui(t, x, n, prec); acb_gamma(t, t, prec); acb_rgamma(y, x, prec); acb_mul(y, y, t, prec); acb_clear(t); } } void acb_hypgeom_rising(acb_t y, const acb_t x, const acb_t n, slong prec) { if (acb_is_int(n) && arf_sgn(arb_midref(acb_realref(n))) >= 0 && arf_cmpabs_ui(arb_midref(acb_realref(n)), FLINT_MAX(prec, 100)) < 0) { acb_hypgeom_rising_ui_rec(y, x, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), prec); } else { acb_t t; acb_init(t); acb_add(t, x, n, prec); acb_gamma(t, t, prec); acb_rgamma(y, x, prec); acb_mul(y, y, t, prec); acb_clear(t); } } arb-2.22.1/acb_hypgeom/rising_ui_bs.c000066400000000000000000000026421417376376500174660ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void bsplit(acb_t y, const acb_t x, ulong a, ulong b, slong prec) { if (b - a <= 4) { if (a == 0) { acb_hypgeom_rising_ui_forward(y, x, b, prec); } else { acb_add_ui(y, x, a, prec); acb_hypgeom_rising_ui_forward(y, y, b - a, prec); } } else { acb_t t, u; ulong m = a + (b - a) / 2; acb_init(t); acb_init(u); bsplit(t, x, a, m, prec); bsplit(u, x, m, b, prec); acb_mul(y, t, u, prec); acb_clear(t); acb_clear(u); } } void acb_hypgeom_rising_ui_bs(acb_t res, const acb_t x, ulong n, slong prec) { if (n <= 1) { if (n == 0) acb_one(res); else acb_set_round(res, x, prec); return; } { acb_t t; slong wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); acb_init(t); bsplit(t, x, 0, n, wp); acb_set_round(res, t, prec); acb_clear(t); } } arb-2.22.1/acb_hypgeom/rising_ui_forward.c000066400000000000000000000017761417376376500205350ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _arb_increment_fast(arb_t x, slong prec); void acb_hypgeom_rising_ui_forward(acb_t res, const acb_t x, ulong n, slong prec) { acb_t t; ulong k; slong wp; if (n <= 1) { if (n == 0) acb_one(res); else acb_set_round(res, x, prec); return; } wp = prec + FLINT_BIT_COUNT(n); acb_init(t); acb_add_ui(t, x, 1, wp); acb_mul(res, x, t, (n == 2) ? prec : wp); for (k = 2; k < n; k++) { _arb_increment_fast(acb_realref(t), wp); acb_mul(res, res, t, k == (n - 1) ? prec : wp); } acb_clear(t); } arb-2.22.1/acb_hypgeom/rising_ui_jet.c000066400000000000000000000025151417376376500176430ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_rising_ui_jet(acb_ptr res, const acb_t x, ulong n, slong len, slong prec) { if (len == 1) { acb_hypgeom_rising_ui_rec(res, x, n, prec); } else if (n <= 7) { acb_hypgeom_rising_ui_jet_powsum(res, x, n, len, prec); } else if (len == 2) { if (n <= 30 || acb_bits(x) >= prec / 128) acb_hypgeom_rising_ui_jet_rs(res, x, n, 0, len, prec); else acb_hypgeom_rising_ui_jet_bs(res, x, n, len, prec); } else { if (n <= 20 || (n <= 200 && prec > 400 * n && acb_bits(x) >= prec / 4)) { acb_hypgeom_rising_ui_jet_powsum(res, x, n, len, prec); } else if (len >= 64 || (acb_bits(x) + 1 < prec / 1024 && n >= 32)) { acb_hypgeom_rising_ui_jet_bs(res, x, n, len, prec); } else { acb_hypgeom_rising_ui_jet_rs(res, x, n, 0, len, prec); } } } arb-2.22.1/acb_hypgeom/rising_ui_jet_bs.c000066400000000000000000000035611417376376500203310ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" static void bsplit(acb_ptr res, const acb_t x, ulong a, ulong b, slong trunc, slong prec) { trunc = FLINT_MIN(trunc, b - a + 1); if (b - a <= 12) { if (a == 0) { acb_hypgeom_rising_ui_jet_powsum(res, x, b - a, FLINT_MIN(trunc, b - a + 1), prec); } else { acb_t t; acb_init(t); acb_add_ui(t, x, a, prec); acb_hypgeom_rising_ui_jet_powsum(res, t, b - a, FLINT_MIN(trunc, b - a + 1), prec); acb_clear(t); } } else { acb_ptr L, R; slong len1, len2; slong m = a + (b - a) / 2; len1 = poly_pow_length(2, m - a, trunc); len2 = poly_pow_length(2, b - m, trunc); L = _acb_vec_init(len1 + len2); R = L + len1; bsplit(L, x, a, m, trunc, prec); bsplit(R, x, m, b, trunc, prec); _acb_poly_mullow(res, L, len1, R, len2, FLINT_MIN(trunc, len1 + len2 - 1), prec); _acb_vec_clear(L, len1 + len2); } } void acb_hypgeom_rising_ui_jet_bs(acb_ptr res, const acb_t x, ulong n, slong len, slong prec) { if (len == 0) return; if (len > n + 1) { _acb_vec_zero(res + n + 1, len - n - 1); len = n + 1; } if (len == n + 1) { acb_one(res + n); len = n; } if (n <= 1) { if (n == 1) acb_set_round(res, x, prec); return; } bsplit(res, x, 0, n, len, prec); } arb-2.22.1/acb_hypgeom/rising_ui_jet_powsum.c000066400000000000000000000100231417376376500212460ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_rising_ui_jet_powsum(acb_ptr res, const acb_t x, ulong n, slong len, slong prec) { slong i, j, k, wp; acb_ptr xpow; TMP_INIT; if (len == 0) return; if (len > n + 1) { _acb_vec_zero(res + n + 1, len - n - 1); len = n + 1; } if (len == n + 1) { acb_one(res + n); len = n; } if (n <= 1) { if (n == 1) acb_set_round(res, x, prec); return; } if (len == 1) { acb_hypgeom_rising_ui_rs(res, x, n, 0, prec); return; } if (n == 2) { acb_mul_2exp_si(res + 1, x, 1); acb_add_ui(res + 1, res + 1, 1, prec); acb_mul(res, x, x, prec + 4); acb_add(res, res, x, prec); return; } if (n <= 12 || (FLINT_BITS == 64 && n <= 20)) { mp_ptr c; TMP_START; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); c = TMP_ALLOC(sizeof(mp_limb_t) * (n + 1) * len); _nmod_vec_zero(c, (n + 1) * len); c[0] = 0; c[1] = 1; c[(n + 1) + 0] = 1; for (i = 2; i <= n; i++) { for (j = FLINT_MIN(len - 1, i); j >= 0; j--) { slong ln, pos; ln = i + 1 - j; pos = (n + 1) * j; if (i == j) { c[pos] = 1; } else { c[pos + ln - 1] = c[pos + ln - 2]; for (k = ln - 2; k >= 1; k--) c[pos + k] = c[pos + k] * (i - 1) + c[pos + k - 1]; c[pos + 0] *= (i - 1); if (j != 0) for (k = ln - 1; k >= 0; k--) c[pos + k] += c[pos - (n + 1) + k]; } } } xpow = _acb_vec_init(n + 1); _acb_vec_set_powers(xpow, x, n + 1, wp); acb_dot_ui(res, NULL, 0, xpow + 1, 1, c + 1, 1, n, prec); for (i = 1; i < len; i++) acb_dot_ui(res + i, NULL, 0, xpow, 1, c + (n + 1) * i, 1, n + 1 - i, prec); _acb_vec_clear(xpow, n + 1); TMP_END; } else { fmpz * c; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); c = _fmpz_vec_init((n + 1) * len); fmpz_one(c + 1); fmpz_one(c + (n + 1) + 0); for (i = 2; i <= n; i++) { for (j = FLINT_MIN(len - 1, i); j >= 0; j--) { slong ln, pos; ln = i + 1 - j; pos = (n + 1) * j; if (i == j) { fmpz_one(c + pos); } else { fmpz_set(c + pos + ln - 1, c + pos + ln - 2); for (k = ln - 2; k >= 1; k--) { fmpz_mul_ui(c + pos + k, c + pos + k, i - 1); fmpz_add(c + pos + k, c + pos + k, c + pos + k - 1); } fmpz_mul_ui(c + pos + 0, c + pos + 0, i - 1); if (j != 0) for (k = ln - 1; k >= 0; k--) fmpz_add(c + pos + k, c + pos + k, c + pos - (n + 1) + k); } } } xpow = _acb_vec_init(n + 1); _acb_vec_set_powers(xpow, x, n + 1, wp); acb_dot_fmpz(res, NULL, 0, xpow + 1, 1, c + 1, 1, n, prec); for (i = 1; i < len; i++) acb_dot_fmpz(res + i, NULL, 0, xpow, 1, c + (n + 1) * i, 1, n + 1 - i, prec); _acb_vec_clear(xpow, n + 1); _fmpz_vec_clear(c, (n + 1) * len); } } arb-2.22.1/acb_hypgeom/rising_ui_jet_rs.c000066400000000000000000000102721417376376500203460ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_rising_ui_jet_rs(acb_ptr res, const acb_t x, ulong n, ulong m, slong len, slong prec) { slong i, j, k, l, m0, xmlen, tlen, ulen, climbs, climbs_max, wp; acb_ptr tmp, xpow; acb_ptr t, u; mp_ptr c; TMP_INIT; if (len == 0) return; if (len > n + 1) { _acb_vec_zero(res + n + 1, len - n - 1); len = n + 1; } if (len == n + 1) { acb_one(res + n); len = n; } if (n <= 1) { if (n == 1) acb_set_round(res, x, prec); return; } if (len == 1) { acb_hypgeom_rising_ui_rs(res, x, n, m, prec); return; } TMP_START; if (m == 0) { if (n <= 7) m = n; else if (n <= 12) m = (n + 1) / 2; else if (n <= 32) m = (n + 2) / 3; else { m0 = n_sqrt(n); m = 8 + 0.5 * pow(prec, 0.4); m = FLINT_MIN(m, m0); m = FLINT_MIN(m, 64); } } wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); climbs_max = FLINT_BIT_COUNT(n - 1) * m; c = TMP_ALLOC(sizeof(mp_limb_t) * climbs_max * m); /* length of (x+t)^m */ xmlen = FLINT_MIN(len, m + 1); tmp = _acb_vec_init(2 * len + (m + 1) * xmlen); t = tmp; u = tmp + len; xpow = tmp + 2 * len; _acb_vec_set_powers(xpow, x, m + 1, wp); tlen = 1; /* First derivatives */ for (i = 1; i <= m; i++) acb_mul_ui(xpow + (m + 1) + i, xpow + i - 1, i, wp); /* Higher derivatives if we need them */ if (len >= 3) { fmpz * f = _fmpz_vec_init(len); fmpz_one(f + 0); fmpz_one(f + 1); for (i = 2; i <= m; i++) { for (j = FLINT_MIN(xmlen - 1, i + 1); j >= 1; j--) fmpz_add(f + j, f + j, f + j - 1); for (j = 2; j < FLINT_MIN(xmlen, i + 1); j++) acb_mul_fmpz(xpow + (m + 1) * j + i, xpow + i - j, f + j, wp); } _fmpz_vec_clear(f, len); } for (k = 0; k < n; k += m) { l = FLINT_MIN(m, n - k); climbs = FLINT_BIT_COUNT(k + l - 1) * l; climbs = (climbs + FLINT_BITS - 1) / FLINT_BITS; ulen = FLINT_MIN(len, l + 1); if (l == 1) { acb_add_ui(u, x, k, wp); acb_one(u + 1); } else { if (climbs == 1) { _arb_hypgeom_rising_coeffs_1(c, k, l); for (j = 0; j < ulen; j++) acb_dot_ui(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, c + j, 1, l - j, wp); } else if (climbs == 2) { _arb_hypgeom_rising_coeffs_2(c, k, l); for (j = 0; j < ulen; j++) acb_dot_uiui(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, c + 2 * j, 1, l - j, wp); } else { fmpz * f = (fmpz *) c; for (i = 0; i < l; i++) fmpz_init(f + i); _arb_hypgeom_rising_coeffs_fmpz(f, k, l); for (j = 0; j < ulen; j++) acb_dot_fmpz(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, f + j, 1, l - j, wp); for (i = 0; i < l; i++) fmpz_clear(f + i); } } if (k == 0) { tlen = ulen; _acb_vec_swap(t, u, ulen); } else { _acb_poly_mullow(res, t, tlen, u, ulen, FLINT_MIN(len, tlen + ulen - 1), wp); tlen = FLINT_MIN(len, tlen + ulen - 1); _acb_vec_swap(t, res, tlen); } } _acb_vec_set_round(res, t, len, prec); _acb_vec_clear(tmp, 2 * len + (m + 1) * xmlen); TMP_END; } arb-2.22.1/acb_hypgeom/rising_ui_rec.c000066400000000000000000000024011417376376500176240ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_rising_ui_rec(acb_t res, const acb_t x, ulong n, slong prec) { if (n <= 1) { if (n == 0) acb_one(res); else acb_set_round(res, x, prec); return; } if (arb_is_zero(acb_imagref(x))) { arb_hypgeom_rising_ui_rec(acb_realref(res), acb_realref(x), n, prec); arb_zero(acb_imagref(res)); return; } if (n == 2 && prec <= 1024) { if (res != x) acb_set(res, x); acb_addmul(res, x, x, prec); return; } if (n <= 5 && prec <= 512) { acb_hypgeom_rising_ui_forward(res, x, n, prec); } else { if (n >= 20 && acb_bits(x) < prec / 8) acb_hypgeom_rising_ui_bs(res, x, n, prec); else acb_hypgeom_rising_ui_rs(res, x, n, 0, prec); } } arb-2.22.1/acb_hypgeom/rising_ui_rs.c000066400000000000000000000052061417376376500175050ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_rising_ui_rs(acb_t res, const acb_t x, ulong n, ulong m, slong prec) { slong i, k, l, m0, climbs, climbs_max, wp; acb_ptr xpow; acb_t t, u; mp_ptr c; TMP_INIT; if (n <= 1) { if (n == 0) acb_one(res); else acb_set_round(res, x, prec); return; } TMP_START; if (m == 0 || m == -1) { if (n <= 6) m = 2; else if (n <= 16) m = 4; else if (n <= 40) m = 6; else { m0 = n_sqrt(n); m = 8 + 0.27 * pow(1.5 * FLINT_MAX(0, prec - 1024), 0.4); m = FLINT_MIN(m, m0); m = FLINT_MIN(m, 64); } } wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); climbs_max = FLINT_BIT_COUNT(n - 1) * m; c = TMP_ALLOC(sizeof(mp_limb_t) * climbs_max * m); xpow = _acb_vec_init(m + 1); _acb_vec_set_powers(xpow, x, m + 1, wp); acb_init(t); acb_init(u); for (k = 0; k < n; k += m) { l = FLINT_MIN(m, n - k); climbs = FLINT_BIT_COUNT(k + l - 1) * l; climbs = (climbs + FLINT_BITS - 1) / FLINT_BITS; /* assumes l >= 2 */ if (l == 1) { acb_add_ui(u, x, k, wp); } else { if (climbs == 1) { _arb_hypgeom_rising_coeffs_1(c, k, l); acb_dot_ui(u, xpow + l, 0, xpow, 1, c, 1, l, wp); } else if (climbs == 2) { _arb_hypgeom_rising_coeffs_2(c, k, l); acb_dot_uiui(u, xpow + l, 0, xpow, 1, c, 1, l, wp); } else { fmpz * f = (fmpz *) c; for (i = 0; i < l; i++) fmpz_init(f + i); _arb_hypgeom_rising_coeffs_fmpz(f, k, l); acb_dot_fmpz(u, xpow + l, 0, xpow, 1, f, 1, l, wp); for (i = 0; i < l; i++) fmpz_clear(f + i); } } if (k == 0) acb_swap(t, u); else acb_mul(t, t, u, wp); } acb_set_round(res, t, prec); acb_clear(t); acb_clear(u); _acb_vec_clear(xpow, m + 1); TMP_END; } arb-2.22.1/acb_hypgeom/shi.c000066400000000000000000000011071417376376500155700ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_shi(acb_t res, const acb_t z, slong prec) { acb_mul_onei(res, z); acb_hypgeom_si(res, res, prec); acb_mul_onei(res, res); acb_neg(res, res); } arb-2.22.1/acb_hypgeom/shi_series.c000066400000000000000000000033401417376376500171430ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_shi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { acb_t c; acb_init(c); acb_hypgeom_shi(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else if (len == 2) { acb_mul_onei(g, h); acb_sinc(g, g, prec); acb_mul(g + 1, g, h + 1, prec); } else { acb_ptr t, u; slong i; t = _acb_vec_init(len - 1); u = _acb_vec_init(hlen); /* Shi(h(x)) = integral(h'(x) sinc(i h(x))) */ for (i = 0; i < hlen; i++) acb_mul_onei(u + i, h + i); _acb_poly_sinc_series(t, u, hlen, len - 1, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_mullow(g, t, len - 1, u, hlen - 1, len - 1, prec); _acb_poly_integral(g, g, len, prec); _acb_vec_clear(t, len - 1); _acb_vec_clear(u, hlen); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_shi_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { acb_poly_zero(g); return; } acb_poly_fit_length(g, len); _acb_hypgeom_shi_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/si.c000066400000000000000000000060211417376376500154200ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void acb_hypgeom_si_asymp(acb_t res, const acb_t z, slong prec) { acb_t t, u, w, v, one; acb_init(t); acb_init(u); acb_init(w); acb_init(v); acb_init(one); acb_one(one); acb_mul_onei(w, z); /* u = U(1,1,iz) */ acb_hypgeom_u_asymp(u, one, one, w, -1, prec); /* v = e^(-iz) */ acb_neg(v, w); acb_exp(v, v, prec); acb_mul(t, u, v, prec); if (acb_is_real(z)) { arb_div(acb_realref(t), acb_realref(t), acb_realref(z), prec); arb_zero(acb_imagref(t)); acb_neg(t, t); } else { /* u = U(1,1,-iz) */ acb_neg(w, w); acb_hypgeom_u_asymp(u, one, one, w, -1, prec); acb_inv(v, v, prec); acb_addmul(t, u, v, prec); acb_div(t, t, z, prec); acb_mul_2exp_si(t, t, -1); acb_neg(t, t); } if (arb_is_zero(acb_realref(z))) { /* the function is imaginary */ arb_zero(acb_realref(t)); } else if (arb_is_positive(acb_realref(z))) { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_add(acb_realref(t), acb_realref(t), acb_realref(u), prec); } else if (arb_is_negative(acb_realref(z))) { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_sub(acb_realref(t), acb_realref(t), acb_realref(u), prec); } else { /* add [-pi,pi]/2 */ acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_add_error(acb_imagref(t), acb_realref(u)); } acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(w); acb_clear(v); acb_clear(one); } void acb_hypgeom_si_1f2(acb_t res, const acb_t z, slong prec) { acb_t a, t; acb_struct b[3]; acb_init(a); acb_init(b); acb_init(b + 1); acb_init(b + 2); acb_init(t); acb_one(a); acb_mul_2exp_si(a, a, -1); acb_set_ui(b, 3); acb_mul_2exp_si(b, b, -1); acb_set(b + 1, b); acb_one(b + 2); acb_mul(t, z, z, prec); acb_mul_2exp_si(t, t, -2); acb_neg(t, t); acb_hypgeom_pfq_direct(t, a, 1, b, 3, t, -1, prec); acb_mul(t, t, z, prec); acb_swap(res, t); acb_clear(a); acb_clear(b); acb_clear(b + 1); acb_clear(b + 2); acb_clear(t); } void acb_hypgeom_si(acb_t res, const acb_t z, slong prec) { if (acb_is_real(z) && arb_is_finite(acb_realref(z))) { arb_hypgeom_si(acb_realref(res), acb_realref(z), prec); arb_zero(acb_imagref(res)); return; } if (acb_hypgeom_u_use_asymp(z, prec)) acb_hypgeom_si_asymp(res, z, prec); else acb_hypgeom_si_1f2(res, z, prec); } arb-2.22.1/acb_hypgeom/si_series.c000066400000000000000000000031511417376376500167730ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void _acb_hypgeom_si_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { acb_t c; acb_init(c); acb_hypgeom_si(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _acb_vec_zero(g + 1, len - 1); } else if (len == 2) { acb_sinc(g, h, prec); acb_mul(g + 1, g, h + 1, prec); } else { acb_ptr t, u; t = _acb_vec_init(len - 1); u = _acb_vec_init(hlen - 1); /* Si(h(x)) = integral(h'(x) sinc(h(x))) */ _acb_poly_sinc_series(t, h, hlen, len - 1, prec); _acb_poly_derivative(u, h, hlen, prec); _acb_poly_mullow(g, t, len - 1, u, hlen - 1, len - 1, prec); _acb_poly_integral(g, g, len, prec); _acb_vec_clear(t, len - 1); _acb_vec_clear(u, hlen - 1); } acb_swap(g, c); acb_clear(c); } void acb_hypgeom_si_series(acb_poly_t g, const acb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { acb_poly_zero(g); return; } acb_poly_fit_length(g, len); _acb_hypgeom_si_series(g->coeffs, h->coeffs, hlen, len, prec); _acb_poly_set_length(g, len); _acb_poly_normalise(g); } arb-2.22.1/acb_hypgeom/spherical_y.c000066400000000000000000000035071417376376500173150ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_spherical_y(acb_t res, slong n, slong m, const acb_t theta, const acb_t phi, slong prec) { acb_t t, u; if (n < 0) { if (m <= n) { acb_zero(res); return; } n = -1-n; } if (m > n || m < -n) { acb_zero(res); return; } if (n > WORD_MAX / 4) { acb_indeterminate(res); return; } acb_init(t); acb_init(u); acb_sin_cos(t, u, theta, prec); /* P_n^m(cos(theta)) */ acb_hypgeom_legendre_p_uiui_rec(u, n, FLINT_ABS(m), u, prec); acb_pow_ui(t, t, FLINT_ABS(m), prec); acb_mul(t, t, u, prec); /* exp(i m phi) */ acb_mul_onei(u, phi); acb_mul_si(u, u, m, prec); acb_exp(u, u, prec); if (m < 0 && m % 2) acb_neg(u, u); acb_mul(t, t, u, prec); /* sqrt((2n+1)/(4pi) (n-m)!/(n+m)!) */ arb_fac_ui(acb_realref(u), n - FLINT_ABS(m), prec); arb_fac_ui(acb_imagref(u), n + FLINT_ABS(m), prec); arb_mul_ui(acb_realref(u), acb_realref(u), 2 * n + 1, prec); arb_div(acb_realref(u), acb_realref(u), acb_imagref(u), prec); arb_const_pi(acb_imagref(u), prec); arb_div(acb_realref(u), acb_realref(u), acb_imagref(u), prec); arb_mul_2exp_si(acb_realref(u), acb_realref(u), -2); arb_sqrt(acb_realref(u), acb_realref(u), prec); acb_mul_arb(t, t, acb_realref(u), prec); acb_set(res, t); acb_clear(t); acb_clear(u); } arb-2.22.1/acb_hypgeom/test/000077500000000000000000000000001417376376500156215ustar00rootroot00000000000000arb-2.22.1/acb_hypgeom/test/t-0f1.c000066400000000000000000000054071417376376500166220ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("0f1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t a, z, w1, w2; slong prec1, prec2; int regularized, ebits; acb_init(a); acb_init(z); acb_init(w1); acb_init(w2); prec1 = 2 + n_randint(state, 700); prec2 = 2 + n_randint(state, 700); if (n_randint(state, 5) == 0) ebits = 100; else ebits = 10; acb_randtest_param(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest_param(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); regularized = n_randint(state, 2); switch (n_randint(state, 3)) { case 0: acb_hypgeom_0f1_asymp(w1, a, z, regularized, prec1); break; case 1: acb_hypgeom_0f1_direct(w1, a, z, regularized, prec1); break; default: acb_hypgeom_0f1(w1, a, z, regularized, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_0f1_asymp(w2, a, z, regularized, prec2); break; case 1: acb_hypgeom_0f1_direct(w2, a, z, regularized, prec2); break; default: acb_hypgeom_0f1(w2, a, z, regularized, prec2); } if (!acb_overlaps(w1, w2)) { flint_printf("FAIL: consistency\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(z); acb_clear(w1); acb_clear(w2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-2f1.c000066400000000000000000000127641417376376500166300ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("2f1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t a, b, c, z, w1, w2, t; slong prec1, prec2; int reg1, reg2, ebits; int alg1, alg2; int flags1, flags2; acb_init(a); acb_init(b); acb_init(c); acb_init(z); acb_init(w1); acb_init(w2); acb_init(t); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); if (n_randint(state, 20) == 0) ebits = 30; else ebits = 5; flags1 = flags2 = 0; switch (n_randint(state, 3)) { case 0: acb_set_si(a, n_randint(state, 500)); acb_set_si(b, n_randint(state, 500)); acb_set_si(c, n_randint(state, 10)); break; case 1: acb_set_si(a, n_randint(state, 200) - 100); acb_set_si(b, n_randint(state, 200) - 100); acb_set_si(c, n_randint(state, 200) - 100); break; default: acb_randtest_param(a, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); acb_randtest_param(b, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); acb_randtest_param(c, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); } /* TODO: test other cases (a-c, b-c), once implemented. */ if (n_randint(state, 10) == 0) { acb_add_si(a, b, n_randint(state, 20) - 10, prec1); flags1 |= ACB_HYPGEOM_2F1_AB; if (n_randint(state, 2)) flags2 |= ACB_HYPGEOM_2F1_AB; } if (n_randint(state, 10) == 0) { acb_add(c, a, b, prec1); acb_add_si(c, c, n_randint(state, 20) - 10, prec1); flags1 |= ACB_HYPGEOM_2F1_ABC; if (n_randint(state, 2)) flags2 |= ACB_HYPGEOM_2F1_ABC; } acb_randtest_param(z, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); acb_randtest(w1, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); acb_randtest(w2, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); if (n_randint(state, 2)) arb_zero(acb_imagref(z)); reg1 = n_randint(state, 2); reg2 = n_randint(state, 2); alg1 = n_randint(state, 10); alg2 = n_randint(state, 10); if (reg1) flags1 |= ACB_HYPGEOM_2F1_REGULARIZED; if (reg2) flags2 |= ACB_HYPGEOM_2F1_REGULARIZED; switch (alg1) { case 0: acb_hypgeom_2f1_direct(w1, a, b, c, z, reg1, prec1); break; case 1: case 2: case 3: case 4: case 5: acb_hypgeom_2f1_transform(w1, a, b, c, z, flags1, alg1, prec1); break; case 6: acb_hypgeom_2f1_corner(w1, a, b, c, z, reg1, prec1); break; default: acb_hypgeom_2f1(w1, a, b, c, z, flags1, prec1); } switch (alg2) { case 0: acb_hypgeom_2f1_direct(w2, a, b, c, z, reg2, prec2); break; case 1: case 2: case 3: case 4: case 5: acb_hypgeom_2f1_transform(w2, a, b, c, z, flags2, alg2, prec2); break; case 6: acb_hypgeom_2f1_corner(w2, a, b, c, z, reg2, prec2); break; default: acb_hypgeom_2f1(w2, a, b, c, z, flags2, prec2); } if (reg1 != reg2) { acb_rgamma(t, c, prec2); if (reg1) acb_mul(w2, w2, t, prec2); else acb_mul(w1, w1, t, prec2); } if (!acb_overlaps(w1, w2)) { flint_printf("FAIL: consistency\n\n"); flint_printf("iter = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, prec1, prec2); flint_printf("alg1 = %d, alg2 = %d\n\n", alg1, alg2); flint_printf("reg1 = %d, reg2 = %d\n\n", reg1, reg2); flint_printf("flags1 = %d, flags2 = %d\n\n", flags1, flags2); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z); acb_clear(w1); acb_clear(w2); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-2f1_continuation.c000066400000000000000000000125121417376376500214110ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("2f1_continuation...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, b, c, z1, z2, f1, f2, g1, g2, h1, h2, aa, bb, cc; mag_t d0, d1, dt; slong prec; int regularized, ebits; acb_init(a); acb_init(b); acb_init(c); acb_init(aa); acb_init(bb); acb_init(cc); acb_init(z1); acb_init(z2); acb_init(f1); acb_init(f2); acb_init(g1); acb_init(g2); acb_init(h1); acb_init(h2); mag_init(d0); mag_init(d1); mag_init(dt); prec = 2 + n_randint(state, 300); ebits = 10; regularized = n_randint(state, 2); acb_randtest_param(a, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits / 2)); acb_randtest_param(b, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits / 2)); acb_randtest_param(c, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits / 2)); acb_randtest(h1, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); acb_randtest(h2, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); do { int left, upper, lower; acb_randtest_param(z1, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); acb_randtest_param(z2, state, 1 + n_randint(state, 400), 1 + n_randint(state, ebits)); /* we test both convergent and non-convergent cases, but try to be more efficient by generating more convergent cases */ if (n_randint(state, 2)) { acb_sub_ui(aa, z1, 1, prec); acb_get_mag(d0, z1); acb_get_mag(d1, aa); acb_get_mag(dt, z2); if (mag_cmp(dt, d0) >= 0 || mag_cmp(dt, d1) >= 0) continue; } acb_add(z2, z1, z2, prec); /* for the test, don't cross the branch cut */ acb_sub_ui(aa, z1, 1, prec); acb_sub_ui(bb, z2, 1, prec); left = arb_is_negative(acb_realref(aa)) && arb_is_negative(acb_realref(bb)); upper = arb_is_positive(acb_imagref(aa)) && arb_is_positive(acb_imagref(bb)); lower = arb_is_nonpositive(acb_imagref(aa)) && arb_is_nonpositive(acb_imagref(bb)); if (left || upper || lower) break; } while (1); acb_add_ui(aa, a, 1, prec); acb_add_ui(bb, b, 1, prec); acb_add_ui(cc, c, 1, prec); acb_hypgeom_2f1(f1, a, b, c, z1, regularized, prec); acb_hypgeom_2f1(f2, aa, bb, cc, z1, regularized, prec); acb_mul(f2, f2, a, prec); acb_mul(f2, f2, b, prec); if (!regularized) acb_div(f2, f2, c, prec); acb_hypgeom_2f1_continuation(h1, h2, a, b, c, z1, z2, f1, f2, prec); if (acb_is_finite(h1) || acb_is_finite(h2)) { acb_hypgeom_2f1(g1, a, b, c, z2, regularized, prec); acb_hypgeom_2f1(g2, aa, bb, cc, z2, regularized, prec); acb_mul(g2, g2, a, prec); acb_mul(g2, g2, b, prec); if (!regularized) acb_div(g2, g2, c, prec); if (!acb_overlaps(g1, h1) || !acb_overlaps(g2, h2)) { flint_printf("FAIL: consistency\n\n"); flint_printf("regularized = %d, prec = %wd\n\n", regularized, prec); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 30); flint_printf("\n\n"); flint_printf("F(a,b,c,z1) and F'(a,b,c,z1):\n"); flint_printf("f1 = "); acb_printd(f1, 30); flint_printf("\n\n"); flint_printf("f2 = "); acb_printd(f2, 30); flint_printf("\n\n"); flint_printf("F(a,b,c,z2) and F'(a,b,c,z2):\n"); flint_printf("g1 = "); acb_printd(g1, 30); flint_printf("\n\n"); flint_printf("g2 = "); acb_printd(g2, 30); flint_printf("\n\n"); flint_printf("Computed F and F':\n"); flint_printf("h1 = "); acb_printd(h1, 30); flint_printf("\n\n"); flint_printf("h2 = "); acb_printd(h2, 30); flint_printf("\n\n"); flint_abort(); } } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(aa); acb_clear(bb); acb_clear(cc); acb_clear(z1); acb_clear(z2); acb_clear(f1); acb_clear(f2); acb_clear(g1); acb_clear(g2); acb_clear(h1); acb_clear(h2); mag_clear(d0); mag_clear(d1); mag_clear(dt); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-airy.c000066400000000000000000000135621417376376500172010ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("airy...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z, t, w; acb_t ai1, aip1, bi1, bip1; acb_t ai2, aip2, bi2, bip2; slong n1, n2, prec1, prec2; unsigned int mask; acb_init(z); acb_init(t); acb_init(w); acb_init(ai1); acb_init(aip1); acb_init(bi1); acb_init(bip1); acb_init(ai2); acb_init(aip2); acb_init(bi2); acb_init(bip2); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); n1 = n_randint(state, 300); n2 = n_randint(state, 300); acb_randtest_param(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest_param(t, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_add(z, z, t, 1000); acb_sub(z, z, t, 1000); switch (n_randint(state, 3)) { case 0: acb_hypgeom_airy_direct(ai1, aip1, bi1, bip1, z, n1, prec1); break; case 1: acb_hypgeom_airy_asymp(ai1, aip1, bi1, bip1, z, n1, prec1); break; default: acb_hypgeom_airy(ai1, aip1, bi1, bip1, z, prec1); break; } switch (n_randint(state, 3)) { case 0: acb_hypgeom_airy_direct(ai2, aip2, bi2, bip2, z, n2, prec2); break; case 1: acb_hypgeom_airy_asymp(ai2, aip2, bi2, bip2, z, n2, prec2); break; default: acb_hypgeom_airy(ai2, aip2, bi2, bip2, z, prec2); break; } if (!acb_overlaps(ai1, ai2)) { flint_printf("FAIL: consistency (Ai)\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("ai1 = "); acb_printd(ai1, 30); flint_printf("\n\n"); flint_printf("ai2 = "); acb_printd(ai2, 30); flint_printf("\n\n"); flint_abort(); } if (!acb_overlaps(aip1, aip2)) { flint_printf("FAIL: consistency (Ai')\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("aip1 = "); acb_printd(aip1, 30); flint_printf("\n\n"); flint_printf("aip2 = "); acb_printd(aip2, 30); flint_printf("\n\n"); flint_abort(); } if (!acb_overlaps(bi1, bi2)) { flint_printf("FAIL: consistency (Bi)\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("bi1 = "); acb_printd(bi1, 30); flint_printf("\n\n"); flint_printf("bi2 = "); acb_printd(bi2, 30); flint_printf("\n\n"); flint_abort(); } if (!acb_overlaps(bip1, bip2)) { flint_printf("FAIL: consistency (Bi')\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("bip1 = "); acb_printd(bip1, 30); flint_printf("\n\n"); flint_printf("bip2 = "); acb_printd(bip2, 30); flint_printf("\n\n"); flint_abort(); } acb_mul(w, ai1, bip1, prec1); acb_submul(w, bi1, aip1, prec1); acb_const_pi(t, prec1); acb_inv(t, t, prec1); if (!acb_overlaps(w, t)) { flint_printf("FAIL: wronskian\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("ai1 = "); acb_printd(ai1, 30); flint_printf("\n\n"); flint_printf("aip1 = "); acb_printd(aip1, 30); flint_printf("\n\n"); flint_printf("bi1 = "); acb_printd(bi1, 30); flint_printf("\n\n"); flint_printf("bip1 = "); acb_printd(bip1, 30); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 30); flint_printf("\n\n"); flint_abort(); } mask = n_randlimb(state); acb_hypgeom_airy((mask & 1) ? ai2 : NULL, (mask & 2) ? aip2 : NULL, (mask & 4) ? bi2 : NULL, (mask & 8) ? bip2 : NULL, z, prec2); if (!acb_overlaps(ai1, ai2) || !acb_overlaps(aip1, aip2) || !acb_overlaps(bi1, bi2) || !acb_overlaps(bip1, bip2)) { flint_printf("FAIL: consistency (mask)\n\n"); flint_printf("mask = %u\n\n", mask); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("ai1 = "); acb_printd(ai1, 30); flint_printf("\n\n"); flint_printf("ai2 = "); acb_printd(ai2, 30); flint_printf("\n\n"); flint_printf("aip1 = "); acb_printd(aip1, 30); flint_printf("\n\n"); flint_printf("aip2 = "); acb_printd(aip2, 30); flint_printf("\n\n"); flint_printf("bi1 = "); acb_printd(bi1, 30); flint_printf("\n\n"); flint_printf("bi2 = "); acb_printd(bi2, 30); flint_printf("\n\n"); flint_printf("bip1 = "); acb_printd(bip1, 30); flint_printf("\n\n"); flint_printf("bip2 = "); acb_printd(bip2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z); acb_clear(t); acb_clear(w); acb_clear(ai1); acb_clear(aip1); acb_clear(bi1); acb_clear(bip1); acb_clear(ai2); acb_clear(aip2); acb_clear(bi2); acb_clear(bip2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-airy_bound.c000066400000000000000000000123731417376376500203670ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("airy_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t ai, aip, bi, bip, z1, z2; slong prec; mag_t aib, aipb, bib, bipb, aim, aipm, bim, bipm; acb_init(ai); acb_init(aip); acb_init(bi); acb_init(bip); acb_init(z1); acb_init(z2); mag_init(aib); mag_init(aipb); mag_init(bib); mag_init(bipb); mag_init(aim); mag_init(aipm); mag_init(bim); mag_init(bipm); acb_randtest(z1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); arb_mul_ui(acb_realref(z1), acb_realref(z1), n_randint(state, 300), 1 + n_randint(state, 200)); arb_mul_ui(acb_imagref(z1), acb_imagref(z1), n_randint(state, 300), 1 + n_randint(state, 200)); acb_zero(z2); arf_set_mag(arb_midref(acb_realref(z2)), arb_radref(acb_realref(z1))); arf_set_mag(arb_midref(acb_imagref(z2)), arb_radref(acb_imagref(z1))); switch (n_randint(state, 5)) { case 0: arf_add(arb_midref(acb_realref(z2)), arb_midref(acb_realref(z1)), arb_midref(acb_realref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); arf_add(arb_midref(acb_imagref(z2)), arb_midref(acb_imagref(z1)), arb_midref(acb_imagref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); break; case 1: arf_add(arb_midref(acb_realref(z2)), arb_midref(acb_realref(z1)), arb_midref(acb_realref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); arf_sub(arb_midref(acb_imagref(z2)), arb_midref(acb_imagref(z1)), arb_midref(acb_imagref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); break; case 2: arf_sub(arb_midref(acb_realref(z2)), arb_midref(acb_realref(z1)), arb_midref(acb_realref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); arf_add(arb_midref(acb_imagref(z2)), arb_midref(acb_imagref(z1)), arb_midref(acb_imagref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); break; case 3: arf_sub(arb_midref(acb_realref(z2)), arb_midref(acb_realref(z1)), arb_midref(acb_realref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); arf_sub(arb_midref(acb_imagref(z2)), arb_midref(acb_imagref(z1)), arb_midref(acb_imagref(z2)), ARF_PREC_EXACT, ARF_RND_DOWN); break; default: arf_set(arb_midref(acb_realref(z2)), arb_midref(acb_realref(z1))); arf_set(arb_midref(acb_imagref(z2)), arb_midref(acb_imagref(z1))); } acb_hypgeom_airy_bound(aib, aipb, bib, bipb, z1); prec = MAG_BITS + 10; do { acb_hypgeom_airy(ai, aip, bi, bip, z2, prec); if (acb_rel_accuracy_bits(ai) >= MAG_BITS && acb_rel_accuracy_bits(aip) >= MAG_BITS && acb_rel_accuracy_bits(bi) >= MAG_BITS && acb_rel_accuracy_bits(bip) >= MAG_BITS) break; prec *= 2; } while (1); acb_get_mag(aim, ai); acb_get_mag(aipm, aip); acb_get_mag(bim, bi); acb_get_mag(bipm, bip); if (mag_cmp(aim, aib) > 0 || mag_cmp(aipm, aipb) > 0 || mag_cmp(bim, bib) > 0 || mag_cmp(aipm, bipb) > 0) { printf("FAIL\n"); flint_printf("z1 = "); acb_printd(z1, 20); flint_printf("\n"); flint_printf("z2 = "); acb_printd(z2, 20); flint_printf("\n\n"); flint_printf("ai = "); acb_printd(ai, 20); flint_printf("\n"); flint_printf("aim = "); mag_printd(aim, 10); printf("\n"); flint_printf("aib = "); mag_printd(aib, 10); printf("\n\n"); flint_printf("api = "); acb_printd(aip, 20); flint_printf("\n"); flint_printf("aipm = "); mag_printd(aipm, 10); printf("\n"); flint_printf("aipb = "); mag_printd(aipb, 10); printf("\n\n"); flint_printf("bi = "); acb_printd(bi, 20); flint_printf("\n"); flint_printf("bim = "); mag_printd(bim, 10); printf("\n"); flint_printf("bib = "); mag_printd(bib, 10); printf("\n\n"); flint_printf("bpi = "); acb_printd(bip, 20); flint_printf("\n"); flint_printf("bipm = "); mag_printd(bipm, 10); printf("\n"); flint_printf("bipb = "); mag_printd(bipb, 10); printf("\n\n"); flint_abort(); } acb_clear(ai); acb_clear(aip); acb_clear(bi); acb_clear(bip); acb_clear(z1); acb_clear(z2); mag_clear(aib); mag_clear(aipb); mag_clear(bib); mag_clear(bipb); mag_clear(aim); mag_clear(aipm); mag_clear(bim); mag_clear(bipm); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-airy_series.c000066400000000000000000000112141417376376500205430ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("airy_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t ai, aip, bi, bip, ai2, aip2, bi2, bip2, z, w, t; acb_t c; slong n1, n2, prec1, prec2; unsigned int mask; acb_poly_init(ai); acb_poly_init(aip); acb_poly_init(bi); acb_poly_init(bip); acb_poly_init(ai2); acb_poly_init(aip2); acb_poly_init(bi2); acb_poly_init(bip2); acb_poly_init(z); acb_poly_init(w); acb_poly_init(t); acb_init(c); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); n1 = n_randint(state, 6); n2 = n_randint(state, 6); acb_poly_randtest(ai, state, 10, prec1, 10); acb_poly_randtest(aip, state, 10, prec1, 10); acb_poly_randtest(bi, state, 10, prec1, 10); acb_poly_randtest(bip, state, 10, prec1, 10); acb_poly_randtest(z, state, 1 + n_randint(state, 10), prec1, 10); acb_hypgeom_airy_series(ai, aip, bi, bip, z, n1, prec1); acb_poly_mullow(w, ai, bip, n1, prec1); acb_poly_mullow(t, bi, aip, n1, prec1); acb_poly_sub(w, w, t, prec1); acb_const_pi(c, prec1); acb_inv(c, c, prec1); acb_poly_set_acb(t, c); acb_poly_truncate(t, n1); if (!acb_poly_overlaps(w, t)) { flint_printf("FAIL: wronskian\n\n"); flint_printf("z = "); acb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("ai = "); acb_poly_printd(ai, 30); flint_printf("\n\n"); flint_printf("aip = "); acb_poly_printd(aip, 30); flint_printf("\n\n"); flint_printf("bi = "); acb_poly_printd(bi, 30); flint_printf("\n\n"); flint_printf("bip = "); acb_poly_printd(bip, 30); flint_printf("\n\n"); flint_printf("w = "); acb_poly_printd(w, 30); flint_printf("\n\n"); flint_abort(); } mask = n_randlimb(state); acb_hypgeom_airy_series((mask & 1) ? ai2 : NULL, (mask & 2) ? aip2 : NULL, (mask & 4) ? bi2 : NULL, (mask & 8) ? bip2 : NULL, z, n2, prec2); acb_poly_truncate(ai, FLINT_MIN(n1, n2)); acb_poly_truncate(aip, FLINT_MIN(n1, n2)); acb_poly_truncate(bi, FLINT_MIN(n1, n2)); acb_poly_truncate(bip, FLINT_MIN(n1, n2)); acb_poly_truncate(ai2, FLINT_MIN(n1, n2)); acb_poly_truncate(aip2, FLINT_MIN(n1, n2)); acb_poly_truncate(bi2, FLINT_MIN(n1, n2)); acb_poly_truncate(bip2, FLINT_MIN(n1, n2)); if (((mask & 1) && (!acb_poly_overlaps(ai, ai2))) || ((mask & 2) && (!acb_poly_overlaps(aip, aip2))) || ((mask & 4) && (!acb_poly_overlaps(bi, bi2))) || ((mask & 8) && (!acb_poly_overlaps(bip, bip2)))) { flint_printf("FAIL: consistency (mask)\n\n"); flint_printf("mask = %u\n\n", mask); flint_printf("len1 = %wd, len2 = %wd\n\n", n1, n2); flint_printf("z = "); acb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("ai = "); acb_poly_printd(ai, 30); flint_printf("\n\n"); flint_printf("ai2 = "); acb_poly_printd(ai2, 30); flint_printf("\n\n"); flint_printf("aip = "); acb_poly_printd(aip, 30); flint_printf("\n\n"); flint_printf("aip2 = "); acb_poly_printd(aip2, 30); flint_printf("\n\n"); flint_printf("bi = "); acb_poly_printd(bi, 30); flint_printf("\n\n"); flint_printf("bi2 = "); acb_poly_printd(bi2, 30); flint_printf("\n\n"); flint_printf("bip = "); acb_poly_printd(bip, 30); flint_printf("\n\n"); flint_printf("bip2 = "); acb_poly_printd(bip2, 30); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(ai); acb_poly_clear(aip); acb_poly_clear(bi); acb_poly_clear(bip); acb_poly_clear(ai2); acb_poly_clear(aip2); acb_poly_clear(bi2); acb_poly_clear(bip2); acb_poly_clear(z); acb_poly_clear(w); acb_poly_clear(t); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-bessel_i.c000066400000000000000000000203451417376376500200170ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_i...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t nu, z, jv, iv, t; slong prec; int scaled; acb_init(nu); acb_init(z); acb_init(jv); acb_init(iv); acb_init(t); prec = 2 + n_randint(state, 500); scaled = n_randint(state, 2); acb_randtest_param(nu, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 20)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); if (n_randint(state, 2) && prec <= 200) { arb_zero(acb_imagref(nu)); arb_zero(acb_imagref(z)); arb_abs(acb_realref(nu), acb_realref(nu)); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(iv, nu, z, scaled, prec); break; case 1: acb_hypgeom_bessel_i_0f1(iv, nu, z, scaled, prec); break; default: if (scaled) acb_hypgeom_bessel_i_scaled(iv, nu, z, prec); else acb_hypgeom_bessel_i(iv, nu, z, prec); } acb_mul_onei(t, z); acb_hypgeom_bessel_j(jv, nu, t, prec); acb_pow(t, z, nu, prec); acb_mul(jv, jv, t, prec); acb_mul_onei(t, z); acb_pow(t, t, nu, prec); acb_div(jv, jv, t, prec); if (scaled) { acb_neg(t, z); acb_exp(t, t, prec); acb_mul(jv, jv, t, prec); } if (!acb_overlaps(iv, jv)) { flint_printf("FAIL: consistency with bessel_j\n\n"); flint_printf("scaled = %d\n\n", scaled); flint_printf("nu = "); acb_printd(nu, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("iv = "); acb_printd(iv, 30); flint_printf("\n\n"); flint_printf("jv = "); acb_printd(jv, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(nu); acb_clear(z); acb_clear(jv); acb_clear(iv); acb_clear(t); } for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t nu0, nu1, nu2, z, w0, w1, w2, t, u; slong prec0, prec1, prec2; acb_init(nu0); acb_init(nu1); acb_init(nu2); acb_init(z); acb_init(w0); acb_init(w1); acb_init(w2); acb_init(t); acb_init(u); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest_param(nu0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_sub_ui(nu1, nu0, 1, prec0); acb_sub_ui(nu2, nu0, 2, prec0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w0, nu0, z, 0, prec0); break; case 1: acb_hypgeom_bessel_i_0f1(w0, nu0, z, 0, prec0); break; default: acb_hypgeom_bessel_i(w0, nu0, z, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w1, nu0, z, 0, prec1); break; case 1: acb_hypgeom_bessel_i_0f1(w1, nu0, z, 0, prec1); break; default: acb_hypgeom_bessel_i(w1, nu0, z, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w1, nu1, z, 0, prec1); break; case 1: acb_hypgeom_bessel_i_0f1(w1, nu1, z, 0, prec1); break; default: acb_hypgeom_bessel_i(w1, nu1, z, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w2, nu2, z, 0, prec2); break; case 1: acb_hypgeom_bessel_i_0f1(w2, nu2, z, 0, prec2); break; default: if (n_randint(state, 2)) { acb_hypgeom_bessel_i(w2, nu2, z, prec2); } else { acb_hypgeom_bessel_i_scaled(w2, nu2, z, prec2); acb_exp(t, z, prec2); acb_mul(w2, w2, t, prec2); } } acb_mul(t, w1, nu1, prec0); acb_mul_2exp_si(t, t, 1); acb_submul(t, w2, z, prec0); acb_addmul(t, w0, z, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_neg(t, nu0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w2, t, z, 0, prec2); break; case 1: acb_hypgeom_bessel_i_0f1(w2, t, z, 0, prec2); break; default: acb_hypgeom_bessel_i(w2, t, z, prec2); } acb_mul(w1, w1, w2, prec2); acb_neg(t, nu1); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w2, t, z, 0, prec2); break; case 1: acb_hypgeom_bessel_i_0f1(w2, t, z, 0, prec2); break; default: acb_hypgeom_bessel_i(w2, t, z, prec2); } acb_mul(w0, w0, w2, prec2); acb_sub(w0, w1, w0, prec2); acb_sin_pi(t, nu0, prec2); acb_const_pi(u, prec2); acb_mul(u, u, z, prec2); acb_div(t, t, u, prec2); acb_mul_2exp_si(t, t, 1); if (!acb_overlaps(w0, t)) { flint_printf("FAIL: wronskian\n\n"); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(nu0); acb_clear(nu1); acb_clear(nu2); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(w2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-bessel_j.c000066400000000000000000000134101417376376500200130ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_j...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t nu0, nu1, nu2, z, w0, w1, w2, t, u; slong prec0, prec1, prec2; acb_init(nu0); acb_init(nu1); acb_init(nu2); acb_init(z); acb_init(w0); acb_init(w1); acb_init(w2); acb_init(t); acb_init(u); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest_param(nu0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_sub_ui(nu1, nu0, 1, prec0); acb_sub_ui(nu2, nu0, 2, prec0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_j_asymp(w0, nu0, z, prec0); break; case 1: acb_hypgeom_bessel_j_0f1(w0, nu0, z, prec0); break; default: acb_hypgeom_bessel_j(w0, nu0, z, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_j_asymp(w1, nu0, z, prec1); break; case 1: acb_hypgeom_bessel_j_0f1(w1, nu0, z, prec1); break; default: acb_hypgeom_bessel_j(w1, nu0, z, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_j_asymp(w1, nu1, z, prec1); break; case 1: acb_hypgeom_bessel_j_0f1(w1, nu1, z, prec1); break; default: acb_hypgeom_bessel_j(w1, nu1, z, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_j_asymp(w2, nu2, z, prec2); break; case 1: acb_hypgeom_bessel_j_0f1(w2, nu2, z, prec2); break; default: acb_hypgeom_bessel_j(w2, nu2, z, prec2); } acb_mul(t, w1, nu1, prec0); acb_mul_2exp_si(t, t, 1); acb_submul(t, w2, z, prec0); acb_submul(t, w0, z, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_neg(t, nu0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_j_asymp(w2, t, z, prec2); break; case 1: acb_hypgeom_bessel_j_0f1(w2, t, z, prec2); break; default: acb_hypgeom_bessel_j(w2, t, z, prec2); } acb_mul(w1, w1, w2, prec2); acb_neg(t, nu1); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_j_asymp(w2, t, z, prec2); break; case 1: acb_hypgeom_bessel_j_0f1(w2, t, z, prec2); break; default: acb_hypgeom_bessel_j(w2, t, z, prec2); } acb_mul(w0, w0, w2, prec2); acb_add(w0, w0, w1, prec2); acb_sin_pi(t, nu0, prec2); acb_const_pi(u, prec2); acb_mul(u, u, z, prec2); acb_div(t, t, u, prec2); acb_mul_2exp_si(t, t, 1); if (!acb_overlaps(w0, t)) { flint_printf("FAIL: wronskian\n\n"); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(nu0); acb_clear(nu1); acb_clear(nu2); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(w2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-bessel_k.c000066400000000000000000000131111417376376500200120ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_k...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t nu0, nu1, nu2, z, w0, w1, w2, t, u; slong prec0, prec1, prec2; int scaled; acb_init(nu0); acb_init(nu1); acb_init(nu2); acb_init(z); acb_init(w0); acb_init(w1); acb_init(w2); acb_init(t); acb_init(u); prec0 = 2 + n_randint(state, 700); prec1 = 2 + n_randint(state, 700); prec2 = 2 + n_randint(state, 700); scaled = n_randint(state, 2); acb_randtest_param(nu0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); if (n_randint(state, 4) == 0) arb_zero(acb_imagref(z)); if (n_randint(state, 2) && prec0 <= 200 && prec1 <= 200 && prec2 <= 200) { arb_zero(acb_imagref(nu0)); arb_zero(acb_imagref(z)); arb_abs(acb_realref(nu0), acb_realref(nu0)); } acb_sub_ui(nu1, nu0, 1, prec0); acb_sub_ui(nu2, nu0, 2, prec0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_k_asymp(w0, nu0, z, scaled, prec0); break; case 1: acb_hypgeom_bessel_k_0f1(w0, nu0, z, scaled, prec0); break; default: if (scaled) acb_hypgeom_bessel_k_scaled(w0, nu0, z, prec0); else acb_hypgeom_bessel_k(w0, nu0, z, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_k_asymp(w1, nu0, z, scaled, prec1); break; case 1: acb_hypgeom_bessel_k_0f1(w1, nu0, z, scaled, prec1); break; default: if (scaled) acb_hypgeom_bessel_k_scaled(w1, nu0, z, prec1); else acb_hypgeom_bessel_k(w1, nu0, z, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("scaled = %d\n\n", scaled); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_k_asymp(w1, nu1, z, scaled, prec1); break; case 1: acb_hypgeom_bessel_k_0f1(w1, nu1, z, scaled, prec1); break; default: if (scaled) acb_hypgeom_bessel_k_scaled(w1, nu1, z, prec1); else acb_hypgeom_bessel_k(w1, nu1, z, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_k_asymp(w2, nu2, z, scaled, prec2); break; case 1: acb_hypgeom_bessel_k_0f1(w2, nu2, z, scaled, prec2); break; default: if (scaled) { acb_hypgeom_bessel_k(w2, nu2, z, prec2); acb_exp(t, z, prec2); acb_mul(w2, w2, t, prec2); } else { acb_hypgeom_bessel_k_scaled(w2, nu2, z, prec2); acb_neg(t, z); acb_exp(t, t, prec2); acb_mul(w2, w2, t, prec2); } } acb_mul(t, w1, nu1, prec0); acb_mul_2exp_si(t, t, 1); acb_addmul(t, w2, z, prec0); acb_submul(t, w0, z, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("nu = "); acb_printd(nu0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(nu0); acb_clear(nu1); acb_clear(nu2); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(w2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-bessel_y.c000066400000000000000000000101001417376376500200230ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_y...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t nu, nu1, z, jv, jv1, yv, yv1, r, s; slong prec, n; acb_init(nu); acb_init(nu1); acb_init(z); acb_init(jv); acb_init(jv1); acb_init(yv); acb_init(yv1); acb_init(r); acb_init(s); prec = 2 + n_randint(state, 500); acb_randtest_param(nu, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); if (n_randint(state, 4) == 0) arb_zero(acb_imagref(z)); acb_add_ui(nu1, nu, 1, prec); if (n_randint(state, 2)) { acb_hypgeom_bessel_j(jv, nu, z, prec); acb_hypgeom_bessel_y(yv, nu, z, prec); } else { acb_hypgeom_bessel_jy(jv, yv, nu, z, prec); } if (n_randint(state, 2)) { acb_hypgeom_bessel_j(jv1, nu1, z, prec); acb_hypgeom_bessel_y(yv1, nu1, z, prec); } else { acb_hypgeom_bessel_jy(jv1, yv1, nu1, z, prec); } acb_mul(r, jv1, yv, prec); acb_submul(r, jv, yv1, prec); acb_mul(r, r, z, prec); acb_const_pi(s, prec); acb_mul(r, r, s, prec); acb_sub_ui(r, r, 2, prec); if (!acb_contains_zero(r)) { flint_printf("FAIL: wronskian\n\n"); flint_printf("nu = "); acb_printd(nu, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("yv = "); acb_printd(yv, 30); flint_printf("\n\n"); flint_printf("yv1 = "); acb_printd(yv1, 30); flint_printf("\n\n"); flint_printf("jv = "); acb_printd(jv, 30); flint_printf("\n\n"); flint_printf("jv1 = "); acb_printd(jv1, 30); flint_printf("\n\n"); flint_printf("r = "); acb_printd(r, 30); flint_printf("\n\n"); flint_abort(); } /* Y_n(-z) = (-1)^n [Y_n(z) - (2/pi) [log(z) - log(-z)] J_v(z)] */ n = n_randint(state, 20) - 10; acb_set_si(nu, n); acb_hypgeom_bessel_y(yv, nu, z, prec); acb_hypgeom_bessel_j(jv, nu, z, prec); acb_log(r, z, prec); acb_neg(s, z); acb_log(s, s, prec); acb_sub(r, r, s, prec); acb_mul(jv, jv, r, prec); acb_const_pi(r, prec); acb_div(jv, jv, r, prec); acb_mul_2exp_si(jv, jv, 1); acb_sub(r, yv, jv, prec); if (n % 2) acb_neg(r, r); acb_neg(yv1, z); acb_hypgeom_bessel_y(yv1, nu, yv1, prec); if (!acb_overlaps(r, yv1)) { flint_printf("FAIL: reflection formula\n\n"); flint_printf("nu = "); acb_printd(nu, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("yv = "); acb_printd(yv, 30); flint_printf("\n\n"); flint_printf("yv1 = "); acb_printd(yv1, 30); flint_printf("\n\n"); flint_printf("jv = "); acb_printd(jv, 30); flint_printf("\n\n"); flint_printf("r = "); acb_printd(r, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(nu); acb_clear(nu1); acb_clear(z); acb_clear(jv); acb_clear(jv1); acb_clear(yv); acb_clear(yv1); acb_clear(r); acb_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-beta_lower.c000066400000000000000000000142011417376376500203470ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("beta_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, a1, b, b1, z, w, wa1, wb1, t, u; slong prec; int regularized; acb_init(a); acb_init(a1); acb_init(b); acb_init(b1); acb_init(z); acb_init(w); acb_init(wa1); acb_init(wb1); acb_init(t); acb_init(u); regularized = n_randint(state, 2); prec = 2 + n_randint(state, 100); acb_randtest_param(a, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_randtest_param(b, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_randtest_param(z, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_add_ui(a1, a, 1, prec); acb_add_ui(b1, b, 1, prec); acb_hypgeom_beta_lower(w, a, b, z, regularized, prec); acb_hypgeom_beta_lower(wa1, a1, b, z, regularized, prec); acb_hypgeom_beta_lower(wb1, a, b1, z, regularized, prec); if (regularized) { acb_mul(t, wa1, a, prec); acb_addmul(t, wb1, b, prec); acb_add(u, a, b, prec); acb_div(t, t, u, prec); } else { acb_add(t, wa1, wb1, prec); } if (!acb_overlaps(w, t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 30); flint_printf("\n\n"); flint_printf("wa1 = "); acb_printd(wa1, 30); flint_printf("\n\n"); flint_printf("wb1 = "); acb_printd(wb1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } /* test I(a,b;z) = 1-I(b,a,1-z) */ if (!regularized) { acb_add(t, a, b, prec); acb_gamma(t, t, prec); acb_mul(w, w, t, prec); acb_rgamma(t, a, prec); acb_mul(w, w, t, prec); acb_rgamma(t, b, prec); acb_mul(w, w, t, prec); } acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_hypgeom_beta_lower(t, b, a, t, 1, prec); acb_sub_ui(t, t, 1, prec); acb_neg(t, t); if (!acb_overlaps(w, t)) { flint_printf("FAIL: symmetry\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(a1); acb_clear(b); acb_clear(b1); acb_clear(z); acb_clear(w); acb_clear(wa1); acb_clear(wb1); acb_clear(t); acb_clear(u); } /* see issue 359 */ { slong prec; acb_t z, a, b, res, res2; acb_init(z); acb_init(a); acb_init(b); acb_init(res); acb_init(res2); prec = 64; acb_set_d(a, 1e5); acb_set_d(b, 1e5); acb_set_ui(z, 4999); acb_div_ui(z, z, 10000, prec); acb_hypgeom_beta_lower(res, a, b, z, 1, prec); arb_set_str(acb_realref(res2), "0.4643650813520 +/- 5.17e-14", prec); if (!acb_overlaps(res, res2) || acb_rel_accuracy_bits(res) < acb_rel_accuracy_bits(res2) - 10) { flint_printf("FAIL: test case (1)\n\n"); flint_printf("res = "); acb_printd(res, 100); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 100); flint_printf("\n\n"); flint_abort(); } prec = 128; acb_set_d(a, 1e10); acb_set_d(b, 1e10); acb_set_ui(z, 4999); acb_div_ui(z, z, 10000, prec); acb_hypgeom_beta_lower(res, a, b, z, 1, prec); arb_set_str(acb_realref(res2), "2.69791122252793228610950163e-176 +/- 2.47e-203", prec); if (!acb_overlaps(res, res2) || acb_rel_accuracy_bits(res) < acb_rel_accuracy_bits(res2) - 10) { flint_printf("FAIL: test case (2)\n\n"); flint_printf("res = "); acb_printd(res, 100); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 100); flint_printf("\n\n"); flint_abort(); } prec = 128; acb_set_d(a, 1e15); acb_set_d(b, 1e15); acb_set_ui(z, 4999); acb_div_ui(z, z, 10000, prec); acb_hypgeom_beta_lower(res, a, b, z, 1, prec); arb_set_str(acb_realref(res2), "1.0612052723416047758478e-17371784 +/- 7.21e-17371807", prec); if (!acb_overlaps(res, res2) || acb_rel_accuracy_bits(res) < acb_rel_accuracy_bits(res2) - 10) { flint_printf("FAIL: test case (3\n\n"); flint_printf("res = "); acb_printd(res, 100); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 100); flint_printf("\n\n"); flint_abort(); } acb_clear(z); acb_clear(a); acb_clear(b); acb_clear(res); acb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-beta_lower_series.c000066400000000000000000000123141417376376500217240ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("beta_lower_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, a1, b, b1, t, u; acb_poly_t z, w, wa1, wb1, pt, pu; slong prec, len, lena1, lenb1; int regularized; acb_init(a); acb_init(a1); acb_init(b); acb_init(b1); acb_init(t); acb_init(u); acb_poly_init(z); acb_poly_init(w); acb_poly_init(wa1); acb_poly_init(wb1); acb_poly_init(pt); acb_poly_init(pu); regularized = n_randint(state, 2); prec = 2 + n_randint(state, 100); acb_randtest_param(a, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_randtest_param(b, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_poly_randtest(z, state, 10, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_poly_randtest(w, state, 10, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_poly_randtest(wa1, state, 10, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_poly_randtest(wb1, state, 10, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); len = n_randint(state, 10); lena1 = n_randint(state, 10); lenb1 = n_randint(state, 10); acb_add_ui(a1, a, 1, prec); acb_add_ui(b1, b, 1, prec); acb_hypgeom_beta_lower_series(w, a, b, z, regularized, len, prec); acb_hypgeom_beta_lower_series(wa1, a1, b, z, regularized, lena1, prec); acb_hypgeom_beta_lower_series(wb1, a, b1, z, regularized, lenb1, prec); if (regularized) { acb_poly_scalar_mul(pt, wa1, a, prec); acb_poly_scalar_mul(pu, wb1, b, prec); acb_poly_add(pt, pt, pu, prec); acb_add(u, a, b, prec); acb_poly_scalar_div(pt, pt, u, prec); } else { acb_poly_add(pt, wa1, wb1, prec); } acb_poly_set(pu, w); acb_poly_truncate(pu, FLINT_MIN(FLINT_MIN(len, lena1), lenb1)); acb_poly_truncate(pt, FLINT_MIN(FLINT_MIN(len, lena1), lenb1)); if (!acb_poly_overlaps(pu, pt)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("len = %wd, lena1 = %wd, lenb1 = %wd\n\n", len, lena1, lenb1); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("w = "); acb_poly_printd(w, 30); flint_printf("\n\n"); flint_printf("wa1 = "); acb_poly_printd(wa1, 30); flint_printf("\n\n"); flint_printf("wb1 = "); acb_poly_printd(wb1, 30); flint_printf("\n\n"); flint_printf("pt = "); acb_poly_printd(pt, 30); flint_printf("\n\n"); flint_abort(); } /* test I(a,b;z) = 1-I(b,a,1-z) */ if (!regularized) { acb_add(t, a, b, prec); acb_gamma(t, t, prec); acb_poly_scalar_mul(w, w, t, prec); acb_rgamma(t, a, prec); acb_poly_scalar_mul(w, w, t, prec); acb_rgamma(t, b, prec); acb_poly_scalar_mul(w, w, t, prec); } acb_poly_add_si(pt, z, -1, prec); acb_poly_neg(pt, pt); acb_hypgeom_beta_lower_series(pt, b, a, pt, 1, lena1, prec); acb_poly_add_si(pt, pt, -1, prec); acb_poly_neg(pt, pt); acb_poly_set(pu, w); acb_poly_truncate(pu, FLINT_MIN(len, lena1)); acb_poly_truncate(pt, FLINT_MIN(len, lena1)); if (!acb_poly_overlaps(pu, pt)) { flint_printf("FAIL: symmetry\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("len = %wd, lena1 = %wd\n\n", len, lena1); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("w = "); acb_poly_printd(w, 30); flint_printf("\n\n"); flint_printf("pt = "); acb_poly_printd(pt, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(a1); acb_clear(b); acb_clear(b1); acb_clear(t); acb_clear(u); acb_poly_clear(z); acb_poly_clear(w); acb_poly_clear(wa1); acb_poly_clear(wb1); acb_poly_clear(pt); acb_poly_clear(pu); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-chebyshev_t.c000066400000000000000000000045201417376376500205320ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("chebyshev_t...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t n, z, a, b, c, t, res1, res2; slong prec; acb_init(n); acb_init(z); acb_init(a); acb_init(b); acb_init(c); acb_init(t); acb_init(res1); acb_init(res2); prec = 2 + n_randint(state, 300); acb_randtest_param(n, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_randtest_param(z, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_randtest_param(res1, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_randtest_param(res2, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_hypgeom_chebyshev_t(res1, n, z, prec); acb_neg(a, n); acb_set(b, n); acb_one(c); acb_mul_2exp_si(c, c, -1); acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_mul_2exp_si(t, t, -1); acb_hypgeom_2f1(res2, a, b, c, t, 0, 2 + n_randint(state, 300)); if (!acb_overlaps(res1, res2)) { flint_printf("FAIL: consistency\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(z); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(t); acb_clear(res1); acb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-chebyshev_u.c000066400000000000000000000046531417376376500205420ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("chebyshev_u...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t n, z, a, b, c, t, res1, res2; slong prec; acb_init(n); acb_init(z); acb_init(a); acb_init(b); acb_init(c); acb_init(t); acb_init(res1); acb_init(res2); prec = 2 + n_randint(state, 300); acb_randtest_param(n, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_randtest_param(z, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_randtest_param(res1, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_randtest_param(res2, state, 1 + n_randint(state, 400), 1 + n_randint(state, 10)); acb_hypgeom_chebyshev_u(res1, n, z, prec); acb_neg(a, n); acb_add_ui(b, n, 2, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_mul_2exp_si(t, t, -1); acb_hypgeom_2f1(res2, a, b, c, t, 0, 2 + n_randint(state, 300)); acb_add_ui(t, n, 1, prec); acb_mul(res2, res2, t, prec); if (!acb_overlaps(res1, res2)) { flint_printf("FAIL: consistency\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(z); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(t); acb_clear(res1); acb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-chi.c000066400000000000000000000047671417376376500170070ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("chi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z0, z1, w0, w1; slong prec0, prec1; acb_init(z0); acb_init(z1); acb_init(w0); acb_init(w1); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest(z0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_set(z1, z0); if (n_randint(state, 2)) { acb_add(z1, z1, w0, prec0); acb_sub(z1, z1, w0, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_chi_2f3(w0, z0, prec0); break; case 1: acb_hypgeom_chi_asymp(w0, z0, prec0); break; default: acb_hypgeom_chi(w0, z0, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_chi_2f3(w1, z1, prec1); break; case 1: acb_hypgeom_chi_asymp(w1, z1, prec1); break; default: acb_hypgeom_chi(w1, z1, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("z0 = "); acb_printd(z0, 30); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z0); acb_clear(z1); acb_clear(w0); acb_clear(w1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-chi_series.c000066400000000000000000000053651417376376500203540ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("chi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, n3, bits1, bits2, bits3; acb_poly_t S, A, B, C, T, U; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); n3 = FLINT_MIN(n1, n2); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_init(T); acb_poly_init(U); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_chi_series(A, S, n1, bits2); acb_hypgeom_chi_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, n3); acb_poly_truncate(B, n3); /* [Chi(h(x))]' h(x) = cosh(h(x)) h'(x) */ acb_poly_cosh_series(U, S, n3, bits2); acb_poly_derivative(T, S, bits2); acb_poly_mullow(U, U, T, FLINT_MAX(0, n3 - 1), bits2); acb_poly_derivative(T, A, bits2); acb_poly_mullow(T, T, S, FLINT_MAX(0, n3 - 1), bits2); if (!acb_poly_overlaps(B, C) || !acb_poly_overlaps(T, U)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("T = "); acb_poly_printd(T, 15); flint_printf("\n\n"); flint_printf("U = "); acb_poly_printd(U, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_chi_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(T); acb_poly_clear(U); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-ci.c000066400000000000000000000047631417376376500166330ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("ci...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z0, z1, w0, w1; slong prec0, prec1; acb_init(z0); acb_init(z1); acb_init(w0); acb_init(w1); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest(z0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_set(z1, z0); if (n_randint(state, 2)) { acb_add(z1, z1, w0, prec0); acb_sub(z1, z1, w0, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_ci_2f3(w0, z0, prec0); break; case 1: acb_hypgeom_ci_asymp(w0, z0, prec0); break; default: acb_hypgeom_ci(w0, z0, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_ci_2f3(w1, z1, prec1); break; case 1: acb_hypgeom_ci_asymp(w1, z1, prec1); break; default: acb_hypgeom_ci(w1, z1, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("z0 = "); acb_printd(z0, 30); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z0); acb_clear(z1); acb_clear(w0); acb_clear(w1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-ci_series.c000066400000000000000000000053561417376376500202040ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("ci_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, n3, bits1, bits2, bits3; acb_poly_t S, A, B, C, T, U; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); n3 = FLINT_MIN(n1, n2); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_init(T); acb_poly_init(U); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_ci_series(A, S, n1, bits2); acb_hypgeom_ci_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, n3); acb_poly_truncate(B, n3); /* [Ci(h(x))]' h(x) = cos(h(x)) h'(x) */ acb_poly_cos_series(U, S, n3, bits2); acb_poly_derivative(T, S, bits2); acb_poly_mullow(U, U, T, FLINT_MAX(0, n3 - 1), bits2); acb_poly_derivative(T, A, bits2); acb_poly_mullow(T, T, S, FLINT_MAX(0, n3 - 1), bits2); if (!acb_poly_overlaps(B, C) || !acb_poly_overlaps(T, U)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("T = "); acb_poly_printd(T, 15); flint_printf("\n\n"); flint_printf("U = "); acb_poly_printd(U, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_ci_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(T); acb_poly_clear(U); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-coulomb.c000066400000000000000000000163221417376376500176720ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("coulomb...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t z, t, u, eta, l; acb_t F1, G1, Hpos1, Hneg1; acb_t F2, G2, Hpos2, Hneg2; slong prec1, prec2; unsigned int mask; acb_init(z); acb_init(t); acb_init(u); acb_init(eta); acb_init(l); acb_init(F1); acb_init(G1); acb_init(Hpos1); acb_init(Hneg1); acb_init(F2); acb_init(G2); acb_init(Hpos2); acb_init(Hneg2); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); acb_randtest_param(eta, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); acb_randtest_param(l, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); acb_randtest_param(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); acb_randtest_param(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); acb_randtest_param(t, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); acb_add(z, z, t, 1000); acb_sub(z, z, t, 1000); acb_hypgeom_coulomb(F1, G1, Hpos1, Hneg1, l, eta, z, prec1); acb_hypgeom_coulomb(F2, G2, Hpos2, Hneg2, l, eta, z, prec2); if (!acb_overlaps(F1, F2) || !acb_overlaps(G1, G2) || !acb_overlaps(Hpos1, Hpos2) || !acb_overlaps(Hneg1, Hneg2)) { flint_printf("FAIL: consistency\n\n"); flint_printf("l = "); acb_printn(l, 30, 0); flint_printf("\n\n"); flint_printf("eta = "); acb_printn(eta, 30, 0); flint_printf("\n\n"); flint_printf("z = "); acb_printn(z, 30, 0); flint_printf("\n\n"); flint_printf("F1 = "); acb_printn(F1, 30, 0); flint_printf("\n"); flint_printf("F2 = "); acb_printn(F2, 30, 0); flint_printf("\n\n"); flint_printf("G1 = "); acb_printn(G1, 30, 0); flint_printf("\n"); flint_printf("G2 = "); acb_printn(G2, 30, 0); flint_printf("\n\n"); flint_printf("Hpos1 = "); acb_printn(Hpos1, 30, 0); flint_printf("\n"); flint_printf("Hpos2 = "); acb_printn(Hpos2, 30, 0); flint_printf("\n\n"); flint_printf("Hneg1 = "); acb_printn(Hneg1, 30, 0); flint_printf("\n"); flint_printf("Hneg2 = "); acb_printn(Hneg2, 30, 0); flint_printf("\n\n"); flint_abort(); } acb_mul_onei(t, F1); acb_add(t, t, G1, prec1); acb_div_onei(u, F1); acb_add(u, u, G1, prec1); if (!acb_overlaps(t, Hpos1) || !acb_overlaps(u, Hneg1)) { flint_printf("FAIL: complex\n\n"); flint_printf("l = "); acb_printn(l, 30, 0); flint_printf("\n\n"); flint_printf("eta = "); acb_printn(eta, 30, 0); flint_printf("\n\n"); flint_printf("z = "); acb_printn(z, 30, 0); flint_printf("\n\n"); flint_printf("F1 = "); acb_printn(F1, 30, 0); flint_printf("\n"); flint_printf("G1 = "); acb_printn(G1, 30, 0); flint_printf("\n"); flint_printf("Hpos1 = "); acb_printn(Hpos1, 30, 0); flint_printf("\n"); flint_printf("Hneg1 = "); acb_printn(Hneg1, 30, 0); flint_printf("\n"); flint_printf("t = "); acb_printn(t, 30, 0); flint_printf("\n"); flint_printf("u = "); acb_printn(u, 30, 0); flint_printf("\n"); flint_abort(); } mask = n_randlimb(state); if (n_randint(state, 2) == 0) { acb_randtest_param(t, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); acb_add(z, z, t, prec2); acb_sub(z, z, t, prec2); } /* also test aliasing */ acb_set(G2, z); acb_hypgeom_coulomb((mask & 1) ? F2 : NULL, (mask & 2) ? G2 : NULL, (mask & 4) ? Hpos2 : NULL, (mask & 8) ? Hneg2 : NULL, l, eta, G2, prec2); if (((mask & 1) && !acb_overlaps(F1, F2)) || ((mask & 2) && !acb_overlaps(G1, G2)) || ((mask & 4) && !acb_overlaps(Hpos1, Hpos2)) || ((mask & 8) && !acb_overlaps(Hneg1, Hneg2))) { flint_printf("FAIL: consistency (mask)\n\n"); flint_printf("mask = %u\n\n", mask); flint_printf("l = "); acb_printn(l, 30, 0); flint_printf("\n\n"); flint_printf("eta = "); acb_printn(eta, 30, 0); flint_printf("\n\n"); flint_printf("z = "); acb_printn(z, 30, 0); flint_printf("\n\n"); flint_printf("F1 = "); acb_printn(F1, 30, 0); flint_printf("\n"); flint_printf("F2 = "); acb_printn(F2, 30, 0); flint_printf("\n\n"); flint_printf("G1 = "); acb_printn(G1, 30, 0); flint_printf("\n"); flint_printf("G2 = "); acb_printn(G2, 30, 0); flint_printf("\n\n"); flint_printf("Hpos1 = "); acb_printn(Hpos1, 30, 0); flint_printf("\n"); flint_printf("Hpos2 = "); acb_printn(Hpos2, 30, 0); flint_printf("\n\n"); flint_printf("Hneg1 = "); acb_printn(Hneg1, 30, 0); flint_printf("\n"); flint_printf("Hneg2 = "); acb_printn(Hneg2, 30, 0); flint_printf("\n\n"); flint_abort(); } /* Check F_{l-1} G_{l} - F_{l} G_{l-1} = l (l^2 + eta^2)^(1/2) */ acb_sub_ui(t, l, 1, prec2); acb_hypgeom_coulomb(F2, G2, NULL, NULL, t, eta, z, prec2); acb_mul_onei(t, eta); acb_add(t, t, l, prec2); acb_rsqrt(t, t, prec2); acb_div_onei(u, eta); acb_add(u, u, l, prec2); acb_rsqrt(u, u, prec2); acb_mul(u, t, u, prec2); acb_mul(u, u, l, prec2); acb_mul(t, F2, G1, prec2); acb_submul(t, F1, G2, prec2); if (!acb_overlaps(t, u)) { flint_printf("FAIL: cross-product\n\n"); flint_printf("l = "); acb_printn(l, 30, 0); flint_printf("\n\n"); flint_printf("eta = "); acb_printn(eta, 30, 0); flint_printf("\n\n"); flint_printf("z = "); acb_printn(z, 30, 0); flint_printf("\n\n"); flint_printf("F1 = "); acb_printn(F1, 30, 0); flint_printf("\n"); flint_printf("G1 = "); acb_printn(G1, 30, 0); flint_printf("\n"); flint_printf("F2 = "); acb_printn(F2, 30, 0); flint_printf("\n"); flint_printf("G2 = "); acb_printn(G2, 30, 0); flint_printf("\n"); flint_printf("t = "); acb_printn(t, 30, 0); flint_printf("\n"); flint_printf("u = "); acb_printn(u, 30, 0); flint_printf("\n"); flint_abort(); } acb_clear(z); acb_clear(t); acb_clear(u); acb_clear(eta); acb_clear(l); acb_clear(F1); acb_clear(G1); acb_clear(Hpos1); acb_clear(Hneg1); acb_clear(F2); acb_clear(G2); acb_clear(Hpos2); acb_clear(Hneg2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-coulomb_series.c000066400000000000000000000141751417376376500212500ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("coulomb_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_poly_t F, G, Hpos, Hneg, F2, G2, Hpos2, Hneg2, z, w, t, u; acb_t c, l, eta, z0; slong n1, n2, prec1, prec2; unsigned int mask; acb_poly_init(F); acb_poly_init(G); acb_poly_init(Hpos); acb_poly_init(Hneg); acb_poly_init(F2); acb_poly_init(G2); acb_poly_init(Hpos2); acb_poly_init(Hneg2); acb_poly_init(z); acb_poly_init(w); acb_poly_init(t); acb_poly_init(u); acb_init(c); acb_init(l); acb_init(eta); acb_init(z0); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); n1 = n_randint(state, 8); n2 = n_randint(state, 8); acb_poly_randtest(F, state, 10, prec1, 10); acb_poly_randtest(G, state, 10, prec1, 10); acb_poly_randtest(Hpos, state, 10, prec1, 10); acb_poly_randtest(Hneg, state, 10, prec1, 10); acb_randtest_param(l, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); acb_randtest_param(eta, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); acb_poly_randtest(z, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); acb_hypgeom_coulomb_series(F, G, Hpos, Hneg, l, eta, z, n1, prec1); acb_poly_derivative(t, F, prec1); if (n_randint(state, 2)) acb_poly_set(u, G); else if (n_randint(state, 2)) acb_poly_set(u, Hpos); else acb_poly_set(u, Hneg); /* F' G - F G' = 1 */ acb_poly_mullow(w, t, u, FLINT_MAX(n1 - 1, 0), prec1); acb_poly_derivative(u, u, prec1); acb_poly_mullow(t, F, u, FLINT_MAX(n1 - 1, 0), prec1); acb_poly_sub(w, w, t, prec1); acb_poly_derivative(t, z, prec1); acb_poly_truncate(t, FLINT_MAX(n1 - 1, 0)); /* hack: work around mullow(nan, 0) = 0 */ acb_poly_get_coeff_acb(z0, z, 0); if (!acb_contains_zero(z0) && !acb_poly_overlaps(w, t)) { flint_printf("FAIL: wronskian, n1 = %wd\n\n", n1); flint_printf("l = "); acb_printd(l, 30); flint_printf("\n\n"); flint_printf("eta = "); acb_printd(eta, 30); flint_printf("\n\n"); flint_printf("z = "); acb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("F = "); acb_poly_printd(F, 30); flint_printf("\n\n"); flint_printf("G = "); acb_poly_printd(G, 30); flint_printf("\n\n"); flint_printf("Hpos = "); acb_poly_printd(Hpos, 30); flint_printf("\n\n"); flint_printf("Hneg = "); acb_poly_printd(Hneg, 30); flint_printf("\n\n"); flint_printf("w = "); acb_poly_printd(w, 30); flint_printf("\n\n"); flint_printf("t = "); acb_poly_printd(t, 30); flint_printf("\n\n"); flint_abort(); } mask = n_randlimb(state); acb_poly_set(G2, z); /* for aliasing */ if (n_randint(state, 2)) { acb_poly_randtest(u, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); acb_poly_add(G2, G2, u, prec2); acb_poly_sub(G2, G2, u, prec2); } acb_hypgeom_coulomb_series((mask & 1) ? F2 : NULL, (mask & 2) ? G2 : NULL, (mask & 4) ? Hpos2 : NULL, (mask & 8) ? Hneg2 : NULL, l, eta, G2, n2, prec2); acb_poly_truncate(F, FLINT_MIN(n1, n2)); acb_poly_truncate(G, FLINT_MIN(n1, n2)); acb_poly_truncate(Hpos, FLINT_MIN(n1, n2)); acb_poly_truncate(Hneg, FLINT_MIN(n1, n2)); acb_poly_truncate(F2, FLINT_MIN(n1, n2)); acb_poly_truncate(G2, FLINT_MIN(n1, n2)); acb_poly_truncate(Hpos2, FLINT_MIN(n1, n2)); acb_poly_truncate(Hneg2, FLINT_MIN(n1, n2)); if (((mask & 1) && (!acb_poly_overlaps(F, F2))) || ((mask & 2) && (!acb_poly_overlaps(G, G2))) || ((mask & 4) && (!acb_poly_overlaps(Hpos, Hpos2))) || ((mask & 8) && (!acb_poly_overlaps(Hneg, Hneg2)))) { flint_printf("FAIL: consistency (mask)\n\n"); flint_printf("mask = %u\n\n", mask); flint_printf("len1 = %wd, len2 = %wd\n\n", n1, n2); flint_printf("l = "); acb_printd(l, 30); flint_printf("\n\n"); flint_printf("eta = "); acb_printd(eta, 30); flint_printf("\n\n"); flint_printf("z = "); acb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("F = "); acb_poly_printd(F, 30); flint_printf("\n\n"); flint_printf("F2 = "); acb_poly_printd(F2, 30); flint_printf("\n\n"); flint_printf("G = "); acb_poly_printd(G, 30); flint_printf("\n\n"); flint_printf("G2 = "); acb_poly_printd(G2, 30); flint_printf("\n\n"); flint_printf("Hpos = "); acb_poly_printd(Hpos, 30); flint_printf("\n\n"); flint_printf("Hpos2 = "); acb_poly_printd(Hpos2, 30); flint_printf("\n\n"); flint_printf("Hneg = "); acb_poly_printd(Hneg, 30); flint_printf("\n\n"); flint_printf("Hneg2 = "); acb_poly_printd(Hneg2, 30); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(F); acb_poly_clear(G); acb_poly_clear(Hpos); acb_poly_clear(Hneg); acb_poly_clear(F2); acb_poly_clear(G2); acb_poly_clear(Hpos2); acb_poly_clear(Hneg2); acb_poly_clear(z); acb_poly_clear(w); acb_poly_clear(t); acb_poly_clear(u); acb_clear(c); acb_clear(l); acb_clear(eta); acb_clear(z0); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-dilog.c000066400000000000000000000071701417376376500173310ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("dilog...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z0, z1, w0, w1, a; slong prec0, prec1; int alg0, alg1; acb_init(z0); acb_init(z1); acb_init(w0); acb_init(w1); acb_init(a); prec0 = 2 + n_randint(state, 500); prec1 = 2 + n_randint(state, 500); acb_randtest(z0, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_set(z1, z0); if (n_randint(state, 2)) { acb_add(z1, z1, w0, prec0); acb_sub(z1, z1, w0, prec0); } switch ((alg0 = n_randint(state, 15))) { case 0: acb_hypgeom_dilog_zero(w0, z0, prec0); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: acb_hypgeom_dilog_transform(w0, z0, alg0, prec0); break; case 8: acb_hypgeom_dilog_bernoulli(w0, z0, prec0); break; case 9: acb_hypgeom_dilog_bitburst(w0, a, z0, prec0); acb_hypgeom_dilog(a, a, prec0); acb_add(w0, w0, a, prec0); break; default: acb_hypgeom_dilog(w0, z0, prec0); } acb_set(w1, z1); /* also test aliasing */ switch ((alg1 = n_randint(state, 15))) { case 0: acb_hypgeom_dilog_zero(w1, w1, prec1); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: acb_hypgeom_dilog_transform(w1, w1, alg1, prec1); break; case 8: acb_hypgeom_dilog_bernoulli(w1, z1, prec1); break; case 9: acb_hypgeom_dilog_bitburst(w1, a, z1, prec1); acb_hypgeom_dilog(a, a, prec1); acb_add(w1, w1, a, prec1); break; default: acb_hypgeom_dilog(w1, z1, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("alg0 = %d, alg1 = %d\n\n", alg0, alg1); flint_printf("prec0 = %wd, prec1 = %wd\n\n", prec0, prec1); flint_printf("z0 = "); acb_printd(z0, 30); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z0); acb_clear(z1); acb_clear(w0); acb_clear(w1); acb_clear(a); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-ei.c000066400000000000000000000063421417376376500166300ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_ei_fallback(acb_t res, const acb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_zero(t); acb_neg(u, z); acb_hypgeom_gamma_upper(u, t, u, 0, prec); acb_neg(u, u); acb_log(t, z, prec); acb_mul_2exp_si(t, t, -1); acb_add(u, u, t, prec); acb_inv(t, z, prec); acb_log(t, t, prec); acb_mul_2exp_si(t, t, -1); acb_sub(u, u, t, prec); acb_neg(t, z); acb_log(t, t, prec); acb_sub(u, u, t, prec); acb_swap(res, u); acb_clear(t); acb_clear(u); } int main() { slong iter; flint_rand_t state; flint_printf("ei...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t z0, z1, w0, w1; slong prec0, prec1; acb_init(z0); acb_init(z1); acb_init(w0); acb_init(w1); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest(z0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_set(z1, z0); if (n_randint(state, 2)) { acb_add(z1, z1, w0, prec0); acb_sub(z1, z1, w0, prec0); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_ei_2f2(w0, z0, prec0); break; case 1: acb_hypgeom_ei_asymp(w0, z0, prec0); break; case 2: acb_hypgeom_ei(w0, z0, prec0); break; default: acb_hypgeom_ei_fallback(w0, z0, prec0); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_ei_2f2(w1, z1, prec1); break; case 1: acb_hypgeom_ei_asymp(w1, z1, prec1); break; case 2: acb_hypgeom_ei(w1, z1, prec1); break; default: acb_hypgeom_ei_fallback(w1, z1, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("z0 = "); acb_printd(z0, 30); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z0); acb_clear(z1); acb_clear(w0); acb_clear(w1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-ei_series.c000066400000000000000000000052561417376376500202050ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("ei_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, n3, bits1, bits2, bits3; acb_poly_t S, A, B, C, T, U; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); n3 = FLINT_MIN(n1, n2); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_init(T); acb_poly_init(U); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_ei_series(A, S, n1, bits2); acb_hypgeom_ei_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, n3); acb_poly_truncate(B, n3); /* [Ei(h(x))]' h(x) = exp(h(x)) h'(x) */ acb_poly_derivative(T, A, bits2); acb_poly_mullow(T, T, S, FLINT_MAX(0, n3 - 1), bits2); acb_poly_exp_series(U, S, n3, bits2); acb_poly_derivative(U, U, bits2); if (!acb_poly_overlaps(B, C) || !acb_poly_overlaps(T, U)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("T = "); acb_poly_printd(T, 15); flint_printf("\n\n"); flint_printf("U = "); acb_poly_printd(U, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_ei_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(T); acb_poly_clear(U); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-erf.c000066400000000000000000000047711417376376500170130ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("erf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2, prec3, prec4; prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); prec3 = 2 + n_randint(state, 1000); prec4 = 2 + n_randint(state, 1000); acb_init(a); acb_init(b); acb_init(c); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest_special(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); switch (n_randint(state, 4)) { case 0: acb_hypgeom_erf_asymp(b, a, 0, prec1, prec3); break; case 1: acb_hypgeom_erf_1f1a(b, a, prec1); break; case 2: acb_hypgeom_erf_1f1b(b, a, prec1); break; default: acb_hypgeom_erf(b, a, prec1); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_erf_asymp(c, a, 0, prec2, prec4); break; case 1: acb_hypgeom_erf_1f1a(c, a, prec2); break; case 2: acb_hypgeom_erf_1f1b(c, a, prec2); break; default: acb_hypgeom_erf(c, a, prec2); } if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-erf_series.c000066400000000000000000000042151417376376500203560ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("erf_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_erf_series(A, S, n1, bits2); acb_hypgeom_erf_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_erf_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-erfc.c000066400000000000000000000047331417376376500171540ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("erfc...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2, prec3, prec4; prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); prec3 = 2 + n_randint(state, 1000); prec4 = 2 + n_randint(state, 1000); acb_init(a); acb_init(b); acb_init(c); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest_special(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); switch (n_randint(state, 4)) { case 0: acb_hypgeom_erf_asymp(b, a, 1, prec1, prec3); break; case 1: acb_hypgeom_erf(b, a, prec1); acb_sub_ui(b, b, 1, prec1); acb_neg(b, b); break; default: acb_hypgeom_erfc(b, a, prec1); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_erf_asymp(c, a, 1, prec2, prec4); break; case 1: acb_hypgeom_erf(c, a, prec2); acb_sub_ui(c, c, 1, prec2); acb_neg(c, c); break; default: acb_hypgeom_erfc(c, a, prec2); } if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-erfc_series.c000066400000000000000000000043261417376376500205240ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("erfc_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_erfc_series(A, S, n1, bits2); acb_hypgeom_erf_series(B, S, n2, bits3); acb_poly_add_si(B, B, -1, bits3); acb_poly_neg(B, B); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_erfc_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-erfi_series.c000066400000000000000000000045511417376376500205320ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("erfi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t I; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(I); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_erfi_series(A, S, n1, bits2); acb_onei(I); acb_poly_set_acb(C, I); acb_poly_mul(B, S, C, bits3); acb_hypgeom_erf_series(B, B, n2, bits3); acb_poly_neg(C, C); acb_poly_mul(B, B, C, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_erfi_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(I); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-fresnel.c000066400000000000000000000070031417376376500176640ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("fresnel...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z, z2, s, c, u, v; slong prec1, prec2; int normalized; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_init(z); acb_init(z2); acb_init(s); acb_init(c); acb_init(u); acb_init(v); acb_randtest_special(z, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(s, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); normalized = n_randint(state, 2); /* test S(z) + i C(z) = sqrt(pi/2) (1+i)/2 erf((1+i)/sqrt(2) z) */ /* u = rhs */ acb_onei(u); acb_sqrt(u, u, prec1); acb_mul(u, u, z, prec1); acb_hypgeom_erf(u, u, prec1); acb_mul_onei(v, u); acb_add(u, u, v, prec1); acb_mul_2exp_si(u, u, -1); acb_const_pi(v, prec1); acb_mul_2exp_si(v, v, -1); acb_sqrt(v, v, prec1); acb_mul(u, u, v, prec1); if (normalized) { acb_const_pi(v, prec2); acb_mul_2exp_si(v, v, -1); acb_sqrt(v, v, prec2); acb_div(z2, z, v, prec2); } else { acb_set(z2, z); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_fresnel(s, c, z2, normalized, prec2); break; case 1: acb_hypgeom_fresnel(s, NULL, z2, normalized, prec2); acb_hypgeom_fresnel(NULL, c, z2, normalized, prec2); break; case 2: acb_set(s, z2); acb_hypgeom_fresnel(s, c, s, normalized, prec2); break; case 3: acb_set(c, z2); acb_hypgeom_fresnel(s, c, c, normalized, prec2); break; default: acb_hypgeom_fresnel(s, c, z2, normalized, prec2); } if (normalized) { acb_mul(s, s, v, prec2); acb_mul(c, c, v, prec2); } acb_mul_onei(v, c); acb_add(v, v, s, prec2); if (!acb_overlaps(u, v)) { flint_printf("FAIL: overlap\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 30); flint_printf("\n\n"); flint_printf("v = "); acb_printd(v, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z); acb_clear(z2); acb_clear(s); acb_clear(c); acb_clear(u); acb_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-fresnel_series.c000066400000000000000000000104751417376376500212450ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("fresnel_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t X, S1, S2, C1, C2, T; acb_t c; int normalized; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); normalized = n_randint(state, 2); acb_poly_init(X); acb_poly_init(S1); acb_poly_init(S2); acb_poly_init(C1); acb_poly_init(C2); acb_poly_init(T); acb_init(c); acb_poly_randtest(X, state, m, bits1, 3); acb_poly_randtest(S1, state, 10, bits1, 3); acb_poly_randtest(S2, state, 10, bits1, 3); acb_poly_randtest(C1, state, 10, bits1, 3); acb_poly_randtest(C2, state, 10, bits1, 3); acb_hypgeom_fresnel_series(S1, C1, X, normalized, n1, bits2); switch (n_randint(state, 8)) { case 0: acb_hypgeom_fresnel_series(S2, C2, X, normalized, n2, bits3); break; case 1: acb_hypgeom_fresnel_series(S2, NULL, X, normalized, n2, bits3); acb_hypgeom_fresnel_series(NULL, C2, X, normalized, n2, bits3); break; case 2: acb_poly_set(S2, X); acb_hypgeom_fresnel_series(NULL, C2, S2, normalized, n2, bits3); acb_hypgeom_fresnel_series(S2, NULL, S2, normalized, n2, bits3); break; case 3: acb_poly_set(C2, X); acb_hypgeom_fresnel_series(S2, NULL, C2, normalized, n2, bits3); acb_hypgeom_fresnel_series(NULL, C2, C2, normalized, n2, bits3); break; case 4: acb_poly_set(S2, X); acb_hypgeom_fresnel_series(S2, C2, S2, normalized, n2, bits3); break; case 5: acb_poly_set(C2, X); acb_hypgeom_fresnel_series(S2, C2, C2, normalized, n2, bits3); break; default: acb_const_pi(c, bits3); acb_mul_2exp_si(c, c, -1); acb_sqrt(c, c, bits3); if (normalized == 0) acb_inv(c, c, bits3); acb_poly_set_acb(T, c); acb_poly_mul(T, T, X, bits3); acb_hypgeom_fresnel_series(S2, C2, T, !normalized, n2, bits3); acb_inv(c, c, bits3); acb_poly_set_acb(T, c); acb_poly_mul(S2, S2, T, bits3); acb_poly_mul(C2, C2, T, bits3); } acb_poly_truncate(S1, FLINT_MIN(n1, n2)); acb_poly_truncate(C1, FLINT_MIN(n1, n2)); acb_poly_truncate(S2, FLINT_MIN(n1, n2)); acb_poly_truncate(C2, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(S1, S2) || !acb_poly_overlaps(C1, C2)) { flint_printf("FAIL (n1 = %wd, n2 = %wd, norm = %d)\n\n", n1, n2, normalized); flint_printf("X = "); acb_poly_printd(X, 15); flint_printf("\n\n"); flint_printf("S1 = "); acb_poly_printd(S1, 15); flint_printf("\n\n"); flint_printf("S2 = "); acb_poly_printd(S2, 15); flint_printf("\n\n"); flint_printf("C1 = "); acb_poly_printd(C1, 15); flint_printf("\n\n"); flint_printf("C2 = "); acb_poly_printd(C2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(X); acb_poly_clear(S1); acb_poly_clear(S2); acb_poly_clear(C1); acb_poly_clear(C2); acb_poly_clear(T); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-gamma_lower.c000066400000000000000000000121301417376376500205150ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t a0, a1, b, z, w0, w1, t, u, enz; slong prec0, prec1; int regularized; acb_init(a0); acb_init(a1); acb_init(b); acb_init(z); acb_init(w0); acb_init(w1); acb_init(t); acb_init(u); acb_init(enz); regularized = n_randint(state, 3); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest_param(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_add_ui(a1, a0, 1, prec0); acb_hypgeom_gamma_lower(w0, a0, z, regularized, prec0); acb_hypgeom_gamma_lower(w1, a1, z, regularized, prec1); acb_neg(enz, z); acb_exp(enz, enz, prec0); /* recurrence relations */ if (regularized == 2) { /* gamma^{*}(a,z) - exp(-z)/Gamma(a+1) - z gamma^{*}(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E4 */ acb_set(t, w0); acb_rgamma(u, a1, prec0); acb_submul(t, enz, u, prec0); acb_submul(t, z, w1, prec0); } else if (regularized == 1) { /* P(a,z) - exp(-z) z^a / Gamma(a+1) - P(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E5 */ acb_pow(u, z, a0, prec0); acb_rgamma(b, a1, prec0); acb_mul(u, u, b, prec0); acb_sub(t, w0, w1, prec0); acb_submul(t, enz, u, prec0); } else { /* a gamma(a,z) - exp(-z) z^a - gamma(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E1 */ acb_pow(u, z, a0, prec0); acb_mul(t, a0, w0, prec0); acb_submul(t, enz, u, prec0); acb_sub(t, t, w1, prec0); } if (!acb_contains_zero(t)) { flint_printf("FAIL: recurrence relation\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } /* identities relating lower and upper incomplete gamma functions */ if (regularized == 0 || regularized == 1) { acb_t u0; acb_init(u0); acb_hypgeom_gamma_upper(u0, a0, z, regularized, prec0); acb_zero(t); if (regularized == 1) { /* P(s,z) + Q(s,z) - 1 = 0 */ /* http://dlmf.nist.gov/8.2.E5 */ acb_add(t, w0, u0, prec0); acb_sub_ui(t, t, 1, prec0); } else { /* gamma(s,z) + Gamma(s,z) - Gamma(s) = 0 */ /* excludes non-positive integer values of s */ /* http://dlmf.nist.gov/8.2.E3 */ if (!acb_is_int(a0) || arb_is_positive(acb_realref(a0))) { acb_gamma(b, a0, prec0); acb_add(t, w0, u0, prec0); acb_sub(t, t, b, prec0); } } if (!acb_contains_zero(t)) { flint_printf("FAIL: lower plus upper\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(u0); } acb_clear(a0); acb_clear(a1); acb_clear(b); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(t); acb_clear(u); acb_clear(enz); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-gamma_lower_series.c000066400000000000000000000142341417376376500220760ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_lower_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t s, t, c; int regularized; regularized = n_randint(state, 3); bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(s); acb_init(t); acb_init(c); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); if (n_randint(state, 10)) { acb_randtest(s, state, bits1, 3); } else { fmpz_t k; fmpz_init(k); fmpz_randtest(k, state, 100); acb_set_fmpz(s, k); fmpz_clear(k); } acb_hypgeom_gamma_lower_series(A, s, S, regularized, n1, bits2); acb_hypgeom_gamma_lower_series(B, s, S, regularized, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL (consistency)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("C = "); acb_poly_printd(C, 15); flint_printf("\n\n"); flint_abort(); } /* f(h(x)) = exp(-h(x)) h(x)^(s-1) */ acb_poly_neg(C, S); acb_poly_exp_series(C, C, n1, bits2); acb_sub_ui(t, s, 1, bits2); acb_poly_pow_acb_series(B, S, t, n1, bits2); acb_poly_mullow(C, C, B, n1, bits2); if (regularized == 0) { /* integral(f(h(x)) h'(x))' = f(h(x)) h'(x) */ acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_truncate(C, n1 - 1); } else if (regularized == 1) { /* (integral(f(h(x)) h'(x)) / c)' = (f(h(x)) h'(x)) / c */ acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_gamma(c, s, bits2); acb_poly_scalar_div(C, C, c, bits2); acb_poly_truncate(C, n1 - 1); } else if (regularized == 2) { if (acb_is_int(s) && arf_sgn(arb_midref(acb_realref(s))) <= 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(s)), 30) < 0) { /* (h(x)^-s)' = -s h(x)^-(s+1) h'(x) */ acb_poly_derivative(C, S, bits2); acb_add_ui(t, s, 1, bits2); acb_neg(t, t); acb_poly_pow_acb_series(B, S, t, n1, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_scalar_mul(C, C, s, bits2); acb_poly_neg(C, C); acb_poly_truncate(C, n1 - 1); } else { /* (h(x)^-s integral(f(h(x)) h'(x)) / c)' = * h(x)^-(s+1) (h(x) f(h(x)) - s integral(f(h(x)) h'(x))) h'(x) / c */ acb_poly_t D; acb_poly_init(D); acb_poly_derivative(B, S, bits2); acb_poly_mullow(D, C, B, n1, bits2); acb_poly_integral(D, D, bits2); acb_poly_scalar_mul(D, D, s, bits2); acb_poly_mullow(C, C, S, n1, bits2); acb_poly_sub(D, C, D, bits2); acb_add_ui(t, s, 1, bits2); acb_neg(t, t); acb_poly_pow_acb_series(B, S, t, n1, bits2); acb_poly_mullow(C, D, B, n1, bits2); acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_gamma(c, s, bits2); acb_poly_scalar_div(C, C, c, bits2); acb_poly_truncate(C, n1 - 1); acb_poly_clear(D); } } acb_poly_derivative(B, A, bits2); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL (derivative)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("C = "); acb_poly_printd(C, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_gamma_lower_series(S, s, S, regularized, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(s); acb_clear(t); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-gamma_stirling_sum.c000066400000000000000000000032101417376376500221030ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_stirling_sum...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z, s1, s2; slong prec, N, K; prec = 2 + n_randint(state, 800); N = n_randint(state, 200); K = n_randint(state, 20); acb_init(z); acb_init(s1); acb_init(s2); acb_randtest(z, state, prec, 10 + n_randint(state, 200)); acb_hypgeom_gamma_stirling_sum_horner(s1, z, N, prec); acb_hypgeom_gamma_stirling_sum_improved(s2, z, N, K, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("N = %wd, K = %wd, prec = %wd\n\n", N, K, prec); flint_printf("z = "); acb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(z); acb_clear(s1); acb_clear(s2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-gamma_taylor.c000066400000000000000000000106151417376376500207050ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_taylor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, s1, s2, a, b; slong prec, ebits, prec2; int success, success2, alias, reciprocal; if (n_randint(state, 10) == 0) prec = 2 + n_randint(state, 4000); else prec = 2 + n_randint(state, 300); if (n_randint(state, 10) == 0) ebits = 100; else ebits = 10; prec2 = prec + 1 + n_randint(state, 30); acb_init(x); acb_init(s1); acb_init(s2); acb_init(a); acb_init(b); acb_randtest(x, state, prec, ebits); acb_randtest(s1, state, prec, 10); acb_randtest(s2, state, prec, 10); alias = n_randint(state, 2); reciprocal = n_randint(state, 2); if (alias) { success = acb_hypgeom_gamma_taylor(s1, x, reciprocal, prec); } else { acb_set(s1, x); success = acb_hypgeom_gamma_taylor(s1, s1, reciprocal, prec); } if (success) { /* printf("%ld\n", iter); */ /* Compare with Stirling series algorithm. */ acb_hypgeom_gamma_stirling(s2, x, reciprocal, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); acb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); acb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); acb_printd(s1, 1000); flint_printf("\n\n"); flint_abort(); } /* Compare with different level of precision. */ success2 = acb_hypgeom_gamma_taylor(s2, x, reciprocal, prec2); if (success2 && !acb_overlaps(s1, s2)) { flint_printf("FAIL (2)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); acb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); acb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_abort(); } acb_get_mid(a, x); if (n_randint(state, 2)) { arf_set_mag(arb_midref(acb_realref(b)), arb_radref(acb_realref(x))); arf_set_mag(arb_midref(acb_imagref(b)), arb_radref(acb_imagref(x))); if (n_randint(state, 2)) acb_neg(b, b); if (n_randint(state, 2)) acb_conj(b, b); acb_add(a, a, b, prec2); } success2 = acb_hypgeom_gamma_taylor(s2, a, reciprocal, prec2); if (success2 && !acb_overlaps(s1, s2)) { flint_printf("FAIL (3)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); acb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); acb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_abort(); } } acb_clear(x); acb_clear(s1); acb_clear(s2); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-gamma_upper.c000066400000000000000000000256111417376376500205300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int _mag_gt_norm_ui(const mag_t a, const mag_t b, const mag_t c, ulong n); static void _accuracy_regression_test(const acb_t s, const acb_t z, int regularized, slong prec, slong issue, slong accuracy) { acb_t g; acb_init(g); acb_hypgeom_gamma_upper(g, s, z, regularized, prec); if (acb_rel_accuracy_bits(g) < accuracy) { flint_printf("FAIL: accuracy regression in issue #%wd\n\n", issue); flint_printf("prec = %wd\n\n", prec); flint_printf("regularized = %d\n\n", regularized); flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("g = "); acb_printd(g, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(g); } int main() { slong iter; flint_rand_t state; flint_printf("gamma_upper...."); fflush(stdout); flint_randinit(state); /* special accuracy test -- see nemo #38 */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t a, z, res; slong prec, goal; int regularized; acb_init(a); acb_init(z); acb_init(res); acb_set_si(a, n_randint(state, 100) - 50); do { acb_set_si(z, n_randint(state, 100) - 50); } while (acb_is_zero(z)); regularized = n_randint(state, 3); goal = 2 + n_randint(state, 4000); for (prec = 2 + n_randint(state, 1000); ; prec *= 2) { acb_hypgeom_gamma_upper(res, a, z, regularized, prec); if (acb_rel_accuracy_bits(res) > goal) break; if (prec > 10000) { printf("FAIL (convergence)\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res = "); acb_printd(res, 30); flint_printf("\n\n"); flint_abort(); } } acb_clear(a); acb_clear(z); acb_clear(res); } for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t a0, a1, b, z, w0, w1, t, u; slong prec0, prec1; int regularized; acb_init(a0); acb_init(a1); acb_init(b); acb_init(z); acb_init(w0); acb_init(w1); acb_init(t); acb_init(u); regularized = n_randint(state, 3); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest_param(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_add_ui(a1, a0, 1, prec0); switch (n_randint(state, 4)) { case 0: acb_hypgeom_gamma_upper_asymp(w0, a0, z, regularized, prec0); break; case 1: acb_hypgeom_gamma_upper_1f1a(w0, a0, z, regularized, prec0); break; case 2: acb_hypgeom_gamma_upper_1f1b(w0, a0, z, regularized, prec0); break; default: acb_hypgeom_gamma_upper(w0, a0, z, regularized, prec0); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_gamma_upper_asymp(w1, a0, z, regularized, prec1); break; case 1: acb_hypgeom_gamma_upper_1f1a(w1, a0, z, regularized, prec1); break; case 2: acb_hypgeom_gamma_upper_1f1b(w1, a0, z, regularized, prec1); break; default: acb_hypgeom_gamma_upper(w1, a0, z, regularized, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_gamma_upper_asymp(w1, a1, z, regularized, prec1); break; case 1: acb_hypgeom_gamma_upper_1f1a(w1, a1, z, regularized, prec1); break; case 2: acb_hypgeom_gamma_upper_1f1b(w1, a1, z, regularized, prec1); break; default: acb_hypgeom_gamma_upper(w1, a1, z, regularized, prec1); } if (regularized == 2) { /* a R(a,z) + exp(-z) - z R(a+1,z) = 0 */ acb_one(t); acb_neg(u, z); acb_exp(u, u, prec0); acb_mul(t, t, u, prec0); acb_mul(b, w1, z, prec0); acb_addmul(t, a0, w0, prec0); acb_sub(t, t, b, prec0); } else if (regularized == 1) { /* Q(a,z) + exp(-z) z^a / Gamma(a+1) - Q(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E6 */ acb_pow(t, z, a0, prec0); acb_rgamma(u, a1, prec0); acb_mul(t, t, u, prec0); acb_neg(u, z); acb_exp(u, u, prec0); acb_mul(t, t, u, prec0); acb_add(t, t, w0, prec0); acb_sub(t, t, w1, prec0); } else { /* a Gamma(a,z) + exp(-z) z^a - Gamma(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E2 */ acb_pow(t, z, a0, prec0); acb_neg(u, z); acb_exp(u, u, prec0); acb_mul(t, t, u, prec0); acb_addmul(t, a0, w0, prec0); acb_sub(t, t, w1, prec0); } if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a0); acb_clear(a1); acb_clear(b); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(t); acb_clear(u); } /* Accuracy regression tests. */ { acb_t s, z; slong prec, issue, accuracy; acb_init(s); acb_init(z); issue = 166; prec = 165; accuracy = 100; acb_zero(s); acb_set_si(z, 110); _accuracy_regression_test(s, z, 2, prec, issue, accuracy); issue = 276; prec = 300; accuracy = 100; acb_set_ui(s, 357); acb_set_ui(z, 356); _accuracy_regression_test(s, z, 0, prec, issue, accuracy); arb_set_str(acb_realref(s), "356.123", prec); arb_set_str(acb_realref(z), "356.456", prec); _accuracy_regression_test(s, z, 0, prec, issue, accuracy); arb_set_str(acb_realref(s), "357.123", prec); arb_set_str(acb_realref(z), "356.456", prec); _accuracy_regression_test(s, z, 0, prec, issue, accuracy); arb_set_str(acb_realref(s), "357.456", prec); arb_set_str(acb_realref(z), "356.123", prec); _accuracy_regression_test(s, z, 0, prec, issue, accuracy); acb_clear(s); acb_clear(z); } /* Norm comparison tests (compare a^n to b^n + c^n). */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong prec; ulong n; arb_t a, b, c, u, v, w, rhs; arb_init(a); arb_init(b); arb_init(c); arb_init(u); arb_init(v); arb_init(w); arb_init(rhs); prec = n_randint(state, 1000) + 1; while (!arb_is_positive(a)) { arb_randtest(a, state, n_randint(state, 1000)+1, n_randint(state, 100)+1); } while (!arb_is_positive(b)) { arb_randtest(b, state, n_randint(state, 1000)+1, n_randint(state, 100)+1); } while (!arb_is_positive(c)) { arb_randtest(c, state, n_randint(state, 1000)+1, n_randint(state, 100)+1); } if (n_randint(state, 20)) arb_zero(a); if (n_randint(state, 20)) arb_zero(b); if (n_randint(state, 20)) arb_zero(c); if (n_randint(state, 20)) arb_set(b, a); if (n_randint(state, 20)) arb_set(c, b); if (n_randint(state, 20)) arb_set(c, a); n = n_randint(state, 10); if (!n) n = WORD_MAX; if (n == WORD_MAX) { arb_set(u, a); arb_max(rhs, b, c, prec); } else { arb_pow_ui(u, a, n, prec); arb_pow_ui(v, b, n, prec); arb_pow_ui(w, c, n, prec); arb_add(rhs, v, w, prec); } if (arb_lt(u, rhs) || (arb_is_exact(u) && arb_equal(u, rhs))) { mag_t ma, mb, mc; mag_init(ma); mag_init(mb); mag_init(mc); arb_get_mag_lower(ma, a); arb_get_mag(mb, b); arb_get_mag(mc, c); if (_mag_gt_norm_ui(ma, mb, mc, n)) { flint_printf("FAIL: _mag_gt_norm_ui\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 30); flint_printf("\n\n"); flint_printf("n = %ld\n\n", n); flint_abort(); } mag_clear(ma); mag_clear(mb); mag_clear(mc); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(u); arb_clear(v); arb_clear(w); arb_clear(rhs); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-gamma_upper_series.c000066400000000000000000000122001417376376500220700ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_upper_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t s, t, c; int regularized; regularized = n_randint(state, 3); bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(s); acb_init(t); acb_init(c); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_randtest(s, state, bits1, 3); acb_hypgeom_gamma_upper_series(A, s, S, regularized, n1, bits2); acb_hypgeom_gamma_upper_series(B, s, S, regularized, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL (consistency)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("C = "); acb_poly_printd(C, 15); flint_printf("\n\n"); flint_abort(); } /* f(h(x)) = -exp(-h(x)) h(x)^(s-1) */ acb_poly_neg(C, S); acb_poly_exp_series(C, C, n1, bits2); acb_sub_ui(t, s, 1, bits2); acb_poly_pow_acb_series(B, S, t, n1, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_neg(C, C); if (regularized == 0) { /* integral(f(h(x)) h'(x))' = f(h(x)) h'(x) */ acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_truncate(C, n1 - 1); } else if (regularized == 1) { /* (integral(f(h(x)) h'(x)) / c)' = (f(h(x)) h'(x)) / c */ acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_gamma(c, s, bits2); acb_poly_scalar_div(C, C, c, bits2); acb_poly_truncate(C, n1 - 1); } else if (regularized == 2) { /* (h(x)^-s integral(f(h(x)) h'(x)))' = * h(x)^-(s+1) (h(x) f(h(x)) - s integral(f(h(x)) h'(x))) h'(x) */ acb_poly_t D; acb_poly_init(D); acb_poly_derivative(B, S, bits2); acb_poly_mullow(D, C, B, n1, bits2); acb_poly_integral(D, D, bits2); acb_poly_scalar_mul(D, D, s, bits2); acb_poly_mullow(C, C, S, n1, bits2); acb_poly_sub(D, C, D, bits2); acb_add_ui(t, s, 1, bits2); acb_neg(t, t); acb_poly_pow_acb_series(B, S, t, n1, bits2); acb_poly_mullow(C, D, B, n1, bits2); acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_truncate(C, n1 - 1); acb_poly_clear(D); } acb_poly_derivative(B, A, bits2); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL (derivative)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("C = "); acb_poly_printd(C, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_gamma_upper_series(S, s, S, regularized, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(s); acb_clear(t); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-gegenbauer_c.c000066400000000000000000000051311417376376500206340ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gegenbauer_c...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t n, m, z, t, u, res1, res2; slong prec1, prec2; acb_init(n); acb_init(m); acb_init(z); acb_init(t); acb_init(u); acb_init(res1); acb_init(res2); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); if (n_randint(state, 2)) { acb_set_si(m, n_randint(state, 20) - 10); acb_set_si(n, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), 10); acb_randtest_param(m, state, 1 + n_randint(state, 400), 10); } acb_randtest_param(z, state, 1 + n_randint(state, 400), 10); acb_hypgeom_gegenbauer_c(res1, n, m, z, prec1); acb_one(t); acb_mul_2exp_si(t, t, -1); acb_sub(t, m, t, prec2); acb_hypgeom_jacobi_p(res2, n, t, t, z, prec2); acb_add_ui(t, t, 1, prec2); acb_rising(t, t, n, prec2); acb_div(res2, res2, t, prec2); acb_mul_2exp_si(t, m, 1); acb_rising(t, t, n, prec2); acb_mul(res2, res2, t, prec2); if (!acb_overlaps(res1, res2)) { flint_printf("FAIL: consistency 1\n\n"); flint_printf("iter = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, prec1, prec2); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(m); acb_clear(z); acb_clear(t); acb_clear(u); acb_clear(res1); acb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-hermite_h.c000066400000000000000000000047161417376376500202020ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("hermite_h...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t n, n1, n2, z, res1, res2, res3, s; slong prec1, prec2, prec3; acb_init(n); acb_init(n1); acb_init(n2); acb_init(z); acb_init(res1); acb_init(res2); acb_init(res3); acb_init(s); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); prec3 = 2 + n_randint(state, 300); acb_randtest_param(n, state, 1 + n_randint(state, 400), 10); acb_sub_ui(n1, n, 1, prec1); acb_sub_ui(n2, n, 2, prec1); acb_randtest_param(z, state, 1 + n_randint(state, 400), 10); acb_randtest_param(res1, state, 1 + n_randint(state, 400), 10); acb_hypgeom_hermite_h(res1, n, z, prec1); acb_hypgeom_hermite_h(res2, n1, z, prec2); acb_hypgeom_hermite_h(res3, n2, z, prec3); acb_mul(s, res2, z, prec1); acb_submul(s, res3, n1, prec1); acb_mul_2exp_si(s, s, 1); if (!acb_overlaps(res1, s)) { flint_printf("FAIL: consistency\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_printf("res3 = "); acb_printd(res3, 30); flint_printf("\n\n"); flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(n1); acb_clear(n2); acb_clear(z); acb_clear(res1); acb_clear(res2); acb_clear(res3); acb_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-jacobi_p.c000066400000000000000000000057431417376376500200050ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("jacobi_p...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t n, a, b, n1, a1, b1, z, res1, res2, res3, s; slong prec; acb_init(n); acb_init(a); acb_init(b); acb_init(n1); acb_init(a1); acb_init(b1); acb_init(z); acb_init(res1); acb_init(res2); acb_init(res3); acb_init(s); prec = 2 + n_randint(state, 300); if (n_randint(state, 2)) { acb_set_si(n, n_randint(state, 20) - 10); acb_set_si(a, n_randint(state, 20) - 10); acb_set_si(b, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), 10); acb_randtest_param(a, state, 1 + n_randint(state, 400), 10); acb_randtest_param(b, state, 1 + n_randint(state, 400), 10); } acb_randtest_param(z, state, 1 + n_randint(state, 400), 10); acb_sub_ui(n1, n, 1, prec); acb_sub_ui(a1, a, 1, prec); acb_sub_ui(b1, b, 1, prec); acb_hypgeom_jacobi_p(res1, n, a, b1, z, prec); acb_hypgeom_jacobi_p(res2, n, a1, b, z, 2 + n_randint(state, 300)); acb_hypgeom_jacobi_p(res3, n1, a, b, z, 2 + n_randint(state, 300)); acb_sub(s, res1, res2, prec); if (!acb_overlaps(s, res3)) { flint_printf("FAIL: consistency\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_printf("res3 = "); acb_printd(res3, 30); flint_printf("\n\n"); flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(a); acb_clear(b); acb_clear(n1); acb_clear(a1); acb_clear(b1); acb_clear(z); acb_clear(res1); acb_clear(res2); acb_clear(res3); acb_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-laguerre_l.c000066400000000000000000000052771417376376500203620ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("laguerre_l...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t n, m, n1, m1, z, res1, res2, res3, s; slong prec; acb_init(n); acb_init(m); acb_init(n1); acb_init(m1); acb_init(z); acb_init(res1); acb_init(res2); acb_init(res3); acb_init(s); prec = 2 + n_randint(state, 200); if (n_randint(state, 2)) { acb_set_si(n, n_randint(state, 20) - 10); acb_set_si(m, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), 10); acb_randtest_param(m, state, 1 + n_randint(state, 400), 10); } acb_randtest_param(z, state, 1 + n_randint(state, 400), 10); acb_sub_ui(n1, n, 1, prec); acb_sub_ui(m1, m, 1, prec); acb_hypgeom_laguerre_l(res1, n, m, z, prec); acb_hypgeom_laguerre_l(res2, n1, m, z, 2 + n_randint(state, 200)); acb_hypgeom_laguerre_l(res3, n, m1, z, 2 + n_randint(state, 200)); acb_add(s, res2, res3, prec); if (acb_is_finite(res1) && acb_is_finite(s) && !acb_overlaps(res1, s)) { flint_printf("FAIL: consistency\n\n"); flint_printf("iter = %wd\n\n", iter); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_printf("res3 = "); acb_printd(res3, 30); flint_printf("\n\n"); flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(m); acb_clear(n1); acb_clear(m1); acb_clear(z); acb_clear(res1); acb_clear(res2); acb_clear(res3); acb_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-legendre_p.c000066400000000000000000000064521417376376500203410ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t n, na, nb, m, z, res1, res2, res3, t, u; slong prec1, prec2, ebits; int type; acb_init(n); acb_init(na); acb_init(nb); acb_init(m); acb_init(z); acb_init(res1); acb_init(res2); acb_init(res3); acb_init(t); acb_init(u); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 10); if (n_randint(state, 2)) { acb_set_si(m, n_randint(state, 20) - 10); acb_set_si(n, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), ebits); acb_randtest_param(m, state, 1 + n_randint(state, 400), ebits); } acb_randtest_param(z, state, 1 + n_randint(state, 400), ebits); acb_sub_ui(na, n, 1, prec2); acb_add_ui(nb, n, 1, prec2); type = n_randint(state, 2); acb_hypgeom_legendre_p(res1, n, m, z, type, prec1); acb_hypgeom_legendre_p(res2, na, m, z, type, prec2); acb_hypgeom_legendre_p(res3, nb, m, z, type, prec2); acb_add(t, n, m, prec2); acb_mul(t, t, res2, prec2); acb_sub(u, n, m, prec2); acb_add_ui(u, u, 1, prec2); acb_mul(u, u, res3, prec2); acb_add(t, t, u, prec2); acb_mul_2exp_si(u, n, 1); acb_add_ui(u, u, 1, prec2); acb_mul(u, u, z, prec2); acb_mul(u, u, res1, prec2); if (!acb_overlaps(t, u)) { flint_printf("FAIL: consistency\n\n"); flint_printf("iter = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, prec1, prec2); flint_printf("type = %d\n\n", type); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_printf("res3 = "); acb_printd(res3, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(na); acb_clear(nb); acb_clear(m); acb_clear(z); acb_clear(res1); acb_clear(res2); acb_clear(res3); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-legendre_q.c000066400000000000000000000123611417376376500203360ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* these functions are not public for now */ void _acb_hypgeom_legendre_q_single(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec); void _acb_hypgeom_legendre_q_double(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec); int main() { slong iter; flint_rand_t state; flint_printf("legendre_q...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t n, m, z, res1, res2; slong prec1, prec2, ebits; acb_init(n); acb_init(m); acb_init(z); acb_init(res1); acb_init(res2); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 10); if (n_randint(state, 2)) { acb_set_si(m, n_randint(state, 20) - 10); acb_set_si(n, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), ebits); acb_randtest_param(m, state, 1 + n_randint(state, 400), ebits); } acb_randtest_param(z, state, 1 + n_randint(state, 400), ebits); _acb_hypgeom_legendre_q_single(res1, n, m, z, prec1); _acb_hypgeom_legendre_q_double(res2, n, m, z, prec2); if (!acb_overlaps(res1, res2)) { flint_printf("FAIL: consistency 1\n\n"); flint_printf("iter = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, prec1, prec2); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(m); acb_clear(z); acb_clear(res1); acb_clear(res2); } for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t n, m, z, res1, res2, t, u; slong prec1, prec2, ebits; int type; acb_init(n); acb_init(m); acb_init(z); acb_init(res1); acb_init(res2); acb_init(t); acb_init(u); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 10); if (n_randint(state, 2)) { acb_set_si(m, n_randint(state, 20) - 10); acb_set_si(n, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), ebits); acb_randtest_param(m, state, 1 + n_randint(state, 400), ebits); } acb_randtest_param(z, state, 1 + n_randint(state, 400), ebits); type = n_randint(state, 2); acb_hypgeom_legendre_q(res1, n, m, z, type, prec1); acb_neg(t, m); acb_hypgeom_legendre_p(res2, n, t, z, type, prec2); acb_add(u, m, n, prec2); acb_add_ui(u, u, 1, prec2); acb_gamma(u, u, prec2); acb_mul(res2, res2, u, prec2); acb_sub(u, n, m, prec2); acb_add_ui(u, u, 1, prec2); acb_rgamma(u, u, prec2); acb_mul(res2, res2, u, prec2); acb_hypgeom_legendre_p(t, n, m, z, type, prec2); if (type == 0) { acb_cos_pi(u, m, prec2); acb_mul(t, t, u, prec2); } acb_sub(res2, t, res2, prec2); if (type == 1) { acb_exp_pi_i(t, m, prec2); acb_mul(res2, res2, t, prec2); } acb_sin_pi(t, m, prec2); if (acb_contains_zero(t)) acb_indeterminate(res2); else acb_div(res2, res2, t, prec2); acb_const_pi(t, prec2); acb_mul(res2, res2, t, prec2); acb_mul_2exp_si(res2, res2, -1); if (!acb_overlaps(res1, res2)) { flint_printf("FAIL: consistency 2\n\n"); flint_printf("iter = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, prec1, prec2); flint_printf("type = %d\n\n", type); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("n = "); acb_printd(n, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(n); acb_clear(m); acb_clear(z); acb_clear(res1); acb_clear(res2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-lgamma.c000066400000000000000000000065231417376376500174720ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("lgamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z, s1, s2, a, b; slong prec, ebits, prec2; prec = 2 + n_randint(state, 200); if (n_randint(state, 10) == 0) prec = 2 + n_randint(state, 1000); if (n_randint(state, 10) == 0) ebits = 100; else ebits = 10; ebits = 2; prec2 = 2 + n_randint(state, 200); acb_init(z); acb_init(s1); acb_init(s2); acb_init(a); acb_init(b); acb_randtest(z, state, prec, ebits); acb_randtest(s1, state, prec, 10); acb_randtest(s2, state, prec, 10); if (n_randint(state, 2)) { acb_hypgeom_lgamma(s1, z, prec); } else { acb_set(s1, z); acb_hypgeom_lgamma(s1, s1, prec); } acb_add_ui(s2, z, 1, prec2); acb_hypgeom_lgamma(s2, s2, prec2); acb_log(a, z, prec2); acb_sub(s2, s2, a, prec2); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("z = "); acb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); acb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); acb_printd(s1, 1000); flint_printf("\n\n"); flint_abort(); } acb_get_mid(a, z); if (n_randint(state, 2)) { arf_set_mag(arb_midref(acb_realref(b)), arb_radref(acb_realref(z))); arf_set_mag(arb_midref(acb_imagref(b)), arb_radref(acb_imagref(z))); if (n_randint(state, 2)) acb_neg(b, b); if (n_randint(state, 2)) acb_conj(b, b); acb_add(a, a, b, prec); } acb_hypgeom_lgamma(s2, a, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL (2)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("z = "); acb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); acb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); acb_printd(s1, 1000); flint_printf("\n\n"); flint_abort(); } acb_clear(z); acb_clear(s1); acb_clear(s2); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-li_series.c000066400000000000000000000054571417376376500202170ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("li_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, n3, bits1, bits2, bits3; acb_poly_t S, A, B, C, T, U; int offset; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); n3 = FLINT_MIN(n1, n2); offset = n_randint(state, 2); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_init(T); acb_poly_init(U); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_li_series(A, S, offset, n1, bits2); acb_hypgeom_li_series(B, S, offset, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, n3); acb_poly_truncate(B, n3); /* [li(h(x))]' log(h(x)) = h'(x) */ acb_poly_derivative(T, A, bits2); acb_poly_log_series(U, S, n3, bits2); acb_poly_mullow(T, T, U, FLINT_MAX(0, n3 - 1), bits2); acb_poly_derivative(U, S, bits2); acb_poly_truncate(U, FLINT_MAX(0, n3 - 1)); if (!acb_poly_overlaps(B, C) || !acb_poly_overlaps(T, U)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("T = "); acb_poly_printd(T, 15); flint_printf("\n\n"); flint_printf("U = "); acb_poly_printd(U, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_li_series(S, S, offset, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(T); acb_poly_clear(U); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-log_rising_ui.c000066400000000000000000000074071417376376500210670ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_log_rising_ui_naive(acb_t res, const acb_t z, ulong r, slong prec) { acb_t t, u; slong k; acb_init(t); acb_init(u); for (k = 0; k < r; k++) { acb_add_ui(t, z, k, prec); acb_log(t, t, prec); acb_add(u, u, t, prec); } acb_swap(res, u); acb_clear(t); acb_clear(u); } int main() { slong iter; flint_rand_t state; flint_printf("log_rising_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z, s1, s2, a, b; slong prec, ebits, prec2; ulong n; prec = 2 + n_randint(state, 100); if (n_randint(state, 10) == 0) ebits = 100; else ebits = 10; ebits = 2; prec2 = prec + 1 + n_randint(state, 30); acb_init(z); acb_init(s1); acb_init(s2); acb_init(a); acb_init(b); acb_randtest(z, state, prec, ebits); acb_randtest(s1, state, prec, 10); acb_randtest(s2, state, prec, 10); n = n_randint(state, 20); if (n_randint(state, 20) == 0) n = n_randint(state, 200); if (n_randint(state, 2)) { acb_hypgeom_log_rising_ui(s1, z, n, prec); } else { acb_set(s1, z); acb_hypgeom_log_rising_ui(s1, s1, n, prec); } acb_hypgeom_log_rising_ui_naive(s2, z, n, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("n = %wu\n\n", n); flint_printf("z = "); acb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); acb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); acb_printd(s1, 1000); flint_printf("\n\n"); flint_abort(); } acb_get_mid(a, z); if (n_randint(state, 2)) { arf_set_mag(arb_midref(acb_realref(b)), arb_radref(acb_realref(z))); arf_set_mag(arb_midref(acb_imagref(b)), arb_radref(acb_imagref(z))); if (n_randint(state, 2)) acb_neg(b, b); if (n_randint(state, 2)) acb_conj(b, b); acb_add(a, a, b, prec); } acb_hypgeom_log_rising_ui(s2, a, n, prec); if (!acb_overlaps(s1, s2)) { flint_printf("FAIL (2)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("n = %wu\n\n", n); flint_printf("z = "); acb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("a = "); acb_printn(a, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); acb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); acb_printn(s2, 1000, 0); flint_printf("\n\n"); acb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); acb_printd(s1, 1000); flint_printf("\n\n"); flint_abort(); } acb_clear(z); acb_clear(s1); acb_clear(s2); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-log_rising_ui_jet.c000066400000000000000000000053661417376376500217330ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("log_rising_ui_jet...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z; acb_ptr s1, s2, s3, s4; slong prec, ebits, len, len1, len2, len3, len4; ulong n, m; prec = 2 + n_randint(state, 100); len = n_randint(state, 5); len1 = len + n_randint(state, 2); len2 = len + n_randint(state, 2); len3 = len + n_randint(state, 2); len4 = len + n_randint(state, 2); if (n_randint(state, 10) == 0) ebits = 100; else ebits = 10; ebits = 2; acb_init(z); s1 = _acb_vec_init(FLINT_MAX(1, len1)); s2 = _acb_vec_init(FLINT_MAX(1, len2)); s3 = _acb_vec_init(FLINT_MAX(1, len3)); s4 = _acb_vec_init(FLINT_MAX(1, len4)); acb_randtest(z, state, prec, ebits); acb_randtest(s1, state, prec, 10); acb_randtest(s2, state, prec, 10); n = n_randint(state, 8); m = n_randint(state, 8); acb_hypgeom_log_rising_ui_jet(s1, z, n + m, len1, prec); acb_hypgeom_log_rising_ui_jet(s2, z, n, len2, prec); acb_add_ui(s4, z, n, prec); acb_hypgeom_log_rising_ui_jet(s3, s4, m, len3, prec); _acb_vec_add(s4, s2, s3, len, prec); if (!_acb_poly_overlaps(s1, len, s4, len)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("n = %wu, m = %lu\n\n", n, m); flint_printf("z = "); acb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); _acb_vec_printn(s1, len, 30, 0); flint_printf("\n\n"); flint_printf("s2 = "); _acb_vec_printn(s2, len, 30, 0); flint_printf("\n\n"); flint_printf("s3 = "); _acb_vec_printn(s3, len, 30, 0); flint_printf("\n\n"); flint_printf("s4 = "); _acb_vec_printn(s4, len, 30, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(z); _acb_vec_clear(s1, FLINT_MAX(1, len1)); _acb_vec_clear(s2, FLINT_MAX(1, len2)); _acb_vec_clear(s3, FLINT_MAX(1, len3)); _acb_vec_clear(s4, FLINT_MAX(1, len4)); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-m.c000066400000000000000000000206341417376376500164670ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("m...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t a0, a1, a2, b, z, w0, w1, w2, t, u; slong prec0, prec1, prec2; int regularized, ebits; acb_init(a0); acb_init(a1); acb_init(a2); acb_init(b); acb_init(z); acb_init(w0); acb_init(w1); acb_init(w2); acb_init(t); acb_init(u); prec0 = 2 + n_randint(state, 700); prec1 = 2 + n_randint(state, 700); prec2 = 2 + n_randint(state, 700); if (n_randint(state, 5) == 0) ebits = 100; else ebits = 10; acb_randtest_param(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest_param(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); regularized = n_randint(state, 2); if (prec0 <= 300 && prec1 <= 300 && prec2 <= 300 && n_randint(state, 2)) { arb_zero(acb_imagref(a0)); arb_zero(acb_imagref(b)); arb_zero(acb_imagref(z)); } acb_add_ui(a1, a0, 1, prec0); acb_add_ui(a2, a0, 2, prec0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_m_asymp(w0, a0, b, z, regularized, prec0); break; case 1: acb_hypgeom_m_1f1(w0, a0, b, z, regularized, prec0); break; default: acb_hypgeom_m(w0, a0, b, z, regularized, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_m_asymp(w1, a0, b, z, regularized, prec1); break; case 1: acb_hypgeom_m_1f1(w1, a0, b, z, regularized, prec1); break; default: acb_hypgeom_m(w1, a0, b, z, regularized, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_m_asymp(w1, a1, b, z, regularized, prec1); break; case 1: acb_hypgeom_m_1f1(w1, a1, b, z, regularized, prec1); break; default: acb_hypgeom_m(w1, a1, b, z, regularized, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_m_asymp(w2, a2, b, z, regularized, prec2); break; case 1: acb_hypgeom_m_1f1(w2, a2, b, z, regularized, prec2); break; default: acb_hypgeom_m(w2, a2, b, z, regularized, prec2); } /* 1F1(a,b,z) * (a-b+1) */ acb_sub(u, a1, b, prec0); acb_mul(t, w0, u, prec0); /* 1F1(a+1,b,z) * (2a - b + z + 2) */ acb_mul_2exp_si(u, a0, 1); acb_sub(u, u, b, prec0); acb_add(u, u, z, prec0); acb_add_ui(u, u, 2, prec0); acb_submul(t, w1, u, prec0); /* 1F1(a+2,b,z) * -(a+1) */ acb_addmul(t, w2, a1, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("a = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_add_ui(a1, b, 1, prec0); acb_add_ui(a2, b, 2, prec0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_m_asymp(w1, a0, a1, z, regularized, prec1); break; case 1: acb_hypgeom_m_1f1(w1, a0, a1, z, regularized, prec1); break; default: acb_hypgeom_m(w1, a0, a1, z, regularized, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_m_asymp(w2, a0, a2, z, regularized, prec2); break; case 1: acb_hypgeom_m_1f1(w2, a0, a2, z, regularized, prec2); break; default: acb_hypgeom_m(w2, a0, a2, z, regularized, prec2); } if (regularized) { acb_set(t, w0); acb_add(u, b, z, prec0); acb_submul(t, w1, u, prec0); acb_sub(u, a0, a1, prec0); acb_mul(u, u, z, prec0); acb_submul(t, w2, u, prec0); } else { acb_mul(t, w0, b, prec0); acb_mul(t, t, a1, prec0); acb_add(u, b, z, prec0); acb_mul(u, u, a1, prec0); acb_submul(t, w1, u, prec0); acb_sub(u, a0, a1, prec0); acb_mul(u, u, z, prec0); acb_submul(t, w2, u, prec0); } if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation 2\n\n"); flint_printf("a = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_m(a0, a0, b, z, regularized, prec0); acb_set(t, a0); break; case 1: acb_hypgeom_m(b, a0, b, z, regularized, prec0); acb_set(t, b); break; default: acb_hypgeom_m(z, a0, b, z, regularized, prec2); acb_set(t, z); } if (!acb_overlaps(t, w0)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a0); acb_clear(a1); acb_clear(a2); acb_clear(b); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(w2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq.c000066400000000000000000000073141417376376500170210ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_ptr a, b; acb_t z, t, res1, res2; slong i, p, q, extend, prec1, prec2; int regularized1, regularized2; p = n_randint(state, 3); q = n_randint(state, 3); extend = n_randint(state, 3); a = _acb_vec_init(p + extend); b = _acb_vec_init(q + extend); acb_init(z); acb_init(t); acb_init(res1); acb_init(res2); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); regularized1 = n_randint(state, 2); regularized2 = n_randint(state, 2); for (i = 0; i < p; i++) { if (n_randint(state, 2)) acb_one(a + i); else acb_randtest_param(a + i, state, 1 + n_randint(state, 200), 3); } for (i = 0; i < q; i++) acb_randtest_param(b + i, state, 1 + n_randint(state, 200), 3); for (i = 0; i < extend; i++) { acb_randtest_param(a + p + i, state, 1 + n_randint(state, 200), 3); acb_set(b + q + i, a + p + i); } acb_randtest_param(z, state, 1 + n_randint(state, 200), 3); acb_hypgeom_pfq(res1, a, p, b, q, z, regularized1, prec1); acb_hypgeom_pfq(res2, a, p + extend, b, q + extend, z, regularized2, prec2); if (regularized1 && !regularized2) { for (i = 0; i < q; i++) { acb_rgamma(t, b + i, prec2); acb_mul(res2, res2, t, prec2); } } else if (regularized2) { if (!regularized1) { for (i = 0; i < q; i++) { acb_rgamma(t, b + i, prec2); acb_mul(res1, res1, t, prec2); } } for (i = 0; i < extend; i++) { acb_rgamma(t, b + q + i, prec2); acb_mul(res1, res1, t, prec2); } } if (!acb_overlaps(res1, res2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("p = %wd, q = %wd, regularized1 = %d, regularized2 = %d\n\n", p, q, regularized1, regularized2); for (i = 0; i < p + extend; i++) { flint_printf("a[%wd] = ", i); acb_printd(a + i, 30); flint_printf("\n\n"); } for (i = 0; i < q + extend; i++) { flint_printf("b[%wd] = ", i); acb_printd(b + i, 30); flint_printf("\n\n"); } flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); acb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); acb_printd(res2, 30); flint_printf("\n\n"); flint_abort(); } _acb_vec_clear(a, p + extend); _acb_vec_clear(b, q + extend); acb_clear(z); acb_clear(t); acb_clear(res1); acb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq_series_direct.c000066400000000000000000000066331417376376500217300ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq_series_direct...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_struct a[4], b[4]; acb_poly_t z, s1, s2; slong i, p, q, len1, len2, n1, n2, prec1, prec2; int regularized; p = n_randint(state, 3); q = n_randint(state, 3); len1 = n_randint(state, 8); len2 = n_randint(state, 8); prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); if (n_randint(state, 2)) n1 = -1; else n1 = n_randint(state, 50); if (n_randint(state, 2)) n2 = -1; else n2 = n_randint(state, 50); regularized = n_randint(state, 2); acb_poly_init(z); acb_poly_init(s1); acb_poly_init(s2); for (i = 0; i < p; i++) acb_poly_init(a + i); for (i = 0; i < q; i++) acb_poly_init(b + i); acb_poly_randtest(z, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 10); for (i = 0; i < p; i++) acb_poly_randtest(a + i, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 3); for (i = 0; i < q; i++) acb_poly_randtest(b + i, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 3); acb_hypgeom_pfq_series_direct(s1, a, p, b, q, z, regularized, n1, len1, prec1); acb_hypgeom_pfq_series_direct(s2, a, p, b, q, z, regularized, n2, len2, prec2); acb_poly_truncate(s1, FLINT_MIN(len1, len2)); acb_poly_truncate(s2, FLINT_MIN(len1, len2)); if (!acb_poly_overlaps(s1, s2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("n1 = %wd, n2 = %wd prec1 = %wd, prec2 = %wd\n\n", n1, n2, prec1, prec2); flint_printf("p = %wd, q = %wd\n\n", p, q); flint_printf("z = "); acb_poly_printd(z, 15); flint_printf("\n\n"); for (i = 0; i < p; i++) { flint_printf("a[%wd] = ", i); acb_poly_printd(a + i, 15); flint_printf("\n\n"); } for (i = 0; i < q; i++) { flint_printf("b[%wd] = ", i); acb_poly_printd(b + i, 15); flint_printf("\n\n"); } flint_printf("s1 = "); acb_poly_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); acb_poly_printd(s2, 15); flint_printf("\n\n"); acb_poly_sub(s1, s1, s2, prec1); flint_printf("diff = "); acb_poly_printd(s1, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(z); acb_poly_clear(s1); acb_poly_clear(s2); for (i = 0; i < p; i++) acb_poly_clear(a + i); for (i = 0; i < q; i++) acb_poly_clear(b + i); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq_series_sum_bs.c000066400000000000000000000074471417376376500217520ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq_series_sum_bs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_struct a[4], b[4]; acb_poly_t z, s1, s2, t1, t2; slong i, p, q, len1, len2, n, prec1, prec2; int regularized; p = n_randint(state, 3); q = n_randint(state, 3); len1 = n_randint(state, 8); len2 = n_randint(state, 8); prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); n = n_randint(state, 50); regularized = n_randint(state, 2); acb_poly_init(z); acb_poly_init(s1); acb_poly_init(s2); acb_poly_init(t1); acb_poly_init(t2); for (i = 0; i < p; i++) acb_poly_init(a + i); for (i = 0; i < q; i++) acb_poly_init(b + i); acb_poly_randtest(z, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 10); for (i = 0; i < p; i++) acb_poly_randtest(a + i, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 3); for (i = 0; i < q; i++) acb_poly_randtest(b + i, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 3); acb_hypgeom_pfq_series_sum_forward(s1, t1, a, p, b, q, z, regularized, n, len1, prec1); acb_hypgeom_pfq_series_sum_bs(s2, t2, a, p, b, q, z, regularized, n, len2, prec2); acb_poly_truncate(s1, FLINT_MIN(len1, len2)); acb_poly_truncate(s2, FLINT_MIN(len1, len2)); acb_poly_truncate(t1, FLINT_MIN(len1, len2)); acb_poly_truncate(t2, FLINT_MIN(len1, len2)); if (!acb_poly_overlaps(s1, s2) || !acb_poly_overlaps(t1, t2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("n = %wd, len1 = %wd, len2 = %wd, prec1 = %wd, prec2 = %wd\n\n", n, len1, len2, prec1, prec2); flint_printf("p = %wd, q = %wd\n\n", p, q); flint_printf("z = "); acb_poly_printd(z, 15); flint_printf("\n\n"); for (i = 0; i < p; i++) { flint_printf("a[%wd] = ", i); acb_poly_printd(a + i, 15); flint_printf("\n\n"); } for (i = 0; i < q; i++) { flint_printf("b[%wd] = ", i); acb_poly_printd(b + i, 15); flint_printf("\n\n"); } flint_printf("s1 = "); acb_poly_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); acb_poly_printd(s2, 15); flint_printf("\n\n"); acb_poly_sub(s1, s1, s2, prec1); flint_printf("diff = "); acb_poly_printd(s1, 15); flint_printf("\n\n"); flint_printf("t1 = "); acb_poly_printd(t1, 15); flint_printf("\n\n"); flint_printf("t2 = "); acb_poly_printd(t2, 15); flint_printf("\n\n"); acb_poly_sub(t1, t1, t2, prec1); flint_printf("diff = "); acb_poly_printd(t1, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(z); acb_poly_clear(s1); acb_poly_clear(s2); for (i = 0; i < p; i++) acb_poly_clear(a + i); for (i = 0; i < q; i++) acb_poly_clear(b + i); acb_poly_clear(t1); acb_poly_clear(t2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq_series_sum_rs.c000066400000000000000000000074471417376376500217720ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq_series_sum_rs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_struct a[4], b[4]; acb_poly_t z, s1, s2, t1, t2; slong i, p, q, len1, len2, n, prec1, prec2; int regularized; p = n_randint(state, 3); q = n_randint(state, 3); len1 = n_randint(state, 8); len2 = n_randint(state, 8); prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); n = n_randint(state, 50); regularized = n_randint(state, 2); acb_poly_init(z); acb_poly_init(s1); acb_poly_init(s2); acb_poly_init(t1); acb_poly_init(t2); for (i = 0; i < p; i++) acb_poly_init(a + i); for (i = 0; i < q; i++) acb_poly_init(b + i); acb_poly_randtest(z, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 10); for (i = 0; i < p; i++) acb_poly_randtest(a + i, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 3); for (i = 0; i < q; i++) acb_poly_randtest(b + i, state, 1 + n_randint(state, 10), 1 + n_randint(state, 500), 3); acb_hypgeom_pfq_series_sum_forward(s1, t1, a, p, b, q, z, regularized, n, len1, prec1); acb_hypgeom_pfq_series_sum_rs(s2, t2, a, p, b, q, z, regularized, n, len2, prec2); acb_poly_truncate(s1, FLINT_MIN(len1, len2)); acb_poly_truncate(s2, FLINT_MIN(len1, len2)); acb_poly_truncate(t1, FLINT_MIN(len1, len2)); acb_poly_truncate(t2, FLINT_MIN(len1, len2)); if (!acb_poly_overlaps(s1, s2) || !acb_poly_overlaps(t1, t2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("n = %wd, len1 = %wd, len2 = %wd, prec1 = %wd, prec2 = %wd\n\n", n, len1, len2, prec1, prec2); flint_printf("p = %wd, q = %wd\n\n", p, q); flint_printf("z = "); acb_poly_printd(z, 15); flint_printf("\n\n"); for (i = 0; i < p; i++) { flint_printf("a[%wd] = ", i); acb_poly_printd(a + i, 15); flint_printf("\n\n"); } for (i = 0; i < q; i++) { flint_printf("b[%wd] = ", i); acb_poly_printd(b + i, 15); flint_printf("\n\n"); } flint_printf("s1 = "); acb_poly_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); acb_poly_printd(s2, 15); flint_printf("\n\n"); acb_poly_sub(s1, s1, s2, prec1); flint_printf("diff = "); acb_poly_printd(s1, 15); flint_printf("\n\n"); flint_printf("t1 = "); acb_poly_printd(t1, 15); flint_printf("\n\n"); flint_printf("t2 = "); acb_poly_printd(t2, 15); flint_printf("\n\n"); acb_poly_sub(t1, t1, t2, prec1); flint_printf("diff = "); acb_poly_printd(t1, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(z); acb_poly_clear(s1); acb_poly_clear(s2); for (i = 0; i < p; i++) acb_poly_clear(a + i); for (i = 0; i < q; i++) acb_poly_clear(b + i); acb_poly_clear(t1); acb_poly_clear(t2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq_sum_bs.c000066400000000000000000000052541417376376500203720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq_sum_bs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_ptr a, b; acb_t z, s1, s2, t1, t2; slong i, p, q, n, prec1, prec2; p = n_randint(state, 5); q = n_randint(state, 5); n = n_randint(state, 300); prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_init(z); acb_init(s1); acb_init(s2); acb_init(t1); acb_init(t2); acb_randtest_special(z, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(s1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(t1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(s2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(t2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); a = _acb_vec_init(p); b = _acb_vec_init(q); for (i = 0; i < p; i++) acb_randtest(a + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); for (i = 0; i < q; i++) acb_randtest(b + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_hypgeom_pfq_sum_forward(s1, t1, a, p, b, q, z, n, prec1); acb_hypgeom_pfq_sum_bs(s2, t2, a, p, b, q, z, n, prec2); if (!acb_overlaps(s1, s2) || !acb_overlaps(t1, t2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("z = "); acb_print(a); flint_printf("\n\n"); flint_printf("s1 = "); acb_print(s1); flint_printf("\n\n"); flint_printf("s2 = "); acb_print(s2); flint_printf("\n\n"); flint_printf("t1 = "); acb_print(t1); flint_printf("\n\n"); flint_printf("t2 = "); acb_print(t2); flint_printf("\n\n"); flint_abort(); } _acb_vec_clear(a, p); _acb_vec_clear(b, q); acb_clear(z); acb_clear(s1); acb_clear(s2); acb_clear(t1); acb_clear(t2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq_sum_fme.c000066400000000000000000000051711417376376500205330ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq_sum_fme...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_ptr a, b; acb_t z, s1, s2, t1, t2; slong i, p, q, n, prec1, prec2; p = n_randint(state, 4); q = n_randint(state, 4); n = n_randint(state, 100); prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_init(z); acb_init(s1); acb_init(s2); acb_init(t1); acb_init(t2); acb_randtest(z, state, 1 + n_randint(state, 500), 1 + n_randint(state, 5)); acb_randtest(s1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 5)); acb_randtest(t1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 5)); acb_randtest(s2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 5)); acb_randtest(t2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 5)); a = _acb_vec_init(p); b = _acb_vec_init(q); for (i = 0; i < p; i++) acb_randtest(a + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 5)); for (i = 0; i < q; i++) acb_randtest(b + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 5)); acb_hypgeom_pfq_sum_forward(s1, t1, a, p, b, q, z, n, prec1); acb_hypgeom_pfq_sum_fme(s2, t2, a, p, b, q, z, n, prec2); if (!acb_overlaps(s1, s2) || !acb_overlaps(t1, t2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("z = "); acb_print(a); flint_printf("\n\n"); flint_printf("s1 = "); acb_print(s1); flint_printf("\n\n"); flint_printf("s2 = "); acb_print(s2); flint_printf("\n\n"); flint_printf("t1 = "); acb_print(t1); flint_printf("\n\n"); flint_printf("t2 = "); acb_print(t2); flint_printf("\n\n"); flint_abort(); } _acb_vec_clear(a, p); _acb_vec_clear(b, q); acb_clear(z); acb_clear(s1); acb_clear(s2); acb_clear(t1); acb_clear(t2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq_sum_invz.c000066400000000000000000000057371417376376500207620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq_sum_invz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_ptr a, b; acb_t z, zinv, s1, s2, t1, t2; slong i, p, q, n, prec1, prec2; p = n_randint(state, 5); q = n_randint(state, 5); n = n_randint(state, 300); prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_init(z); acb_init(zinv); acb_init(s1); acb_init(s2); acb_init(t1); acb_init(t2); acb_randtest_special(z, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(s1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(t1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(s2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(t2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_inv(zinv, z, 1 + n_randint(state, 500)); a = _acb_vec_init(p); b = _acb_vec_init(q); for (i = 0; i < p; i++) acb_randtest(a + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); for (i = 0; i < q; i++) acb_randtest(b + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); if (n_randint(state, 2)) acb_hypgeom_pfq_sum_invz(s1, t1, a, p, b, q, zinv, z, n, prec1); else acb_hypgeom_pfq_sum_bs_invz(s1, t1, a, p, b, q, z, n, prec1); acb_hypgeom_pfq_sum(s2, t2, a, p, b, q, zinv, n, prec2); if (!acb_overlaps(s1, s2) || !acb_overlaps(t1, t2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wd\n\n", n); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("s1 = "); acb_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); acb_printd(s2, 15); flint_printf("\n\n"); flint_printf("t1 = "); acb_printd(t1, 15); flint_printf("\n\n"); flint_printf("t2 = "); acb_printd(t2, 15); flint_printf("\n\n"); flint_abort(); } _acb_vec_clear(a, p); _acb_vec_clear(b, q); acb_clear(z); acb_clear(zinv); acb_clear(s1); acb_clear(s2); acb_clear(t1); acb_clear(t2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-pfq_sum_rs.c000066400000000000000000000052541417376376500204120ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("pfq_sum_rs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_ptr a, b; acb_t z, s1, s2, t1, t2; slong i, p, q, n, prec1, prec2; p = n_randint(state, 5); q = n_randint(state, 5); n = n_randint(state, 300); prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_init(z); acb_init(s1); acb_init(s2); acb_init(t1); acb_init(t2); acb_randtest_special(z, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(s1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(t1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(s2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_randtest_special(t2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); a = _acb_vec_init(p); b = _acb_vec_init(q); for (i = 0; i < p; i++) acb_randtest(a + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); for (i = 0; i < q; i++) acb_randtest(b + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10)); acb_hypgeom_pfq_sum_forward(s1, t1, a, p, b, q, z, n, prec1); acb_hypgeom_pfq_sum_rs(s2, t2, a, p, b, q, z, n, prec2); if (!acb_overlaps(s1, s2) || !acb_overlaps(t1, t2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("z = "); acb_print(a); flint_printf("\n\n"); flint_printf("s1 = "); acb_print(s1); flint_printf("\n\n"); flint_printf("s2 = "); acb_print(s2); flint_printf("\n\n"); flint_printf("t1 = "); acb_print(t1); flint_printf("\n\n"); flint_printf("t2 = "); acb_print(t2); flint_printf("\n\n"); flint_abort(); } _acb_vec_clear(a, p); _acb_vec_clear(b, q); acb_clear(z); acb_clear(s1); acb_clear(s2); acb_clear(t1); acb_clear(t2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-rising_ui.c000066400000000000000000000063571417376376500202310ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void rising_algorithm(acb_t res, const acb_t x, ulong n, ulong m, slong prec, int alg, int alias) { if (alias) { acb_set(res, x); rising_algorithm(res, res, n, m, prec, alg, 0); return; } if (alg == 0) acb_hypgeom_rising_ui_rs(res, x, n, m, prec); else if (alg == 1) acb_hypgeom_rising_ui_forward(res, x, n, prec); else if (alg == 2) acb_hypgeom_rising_ui_bs(res, x, n, prec); else if (alg == 3) acb_hypgeom_rising_ui_rec(res, x, n, prec); else acb_hypgeom_rising_ui(res, x, n, prec); } int main() { slong iter; flint_rand_t state; flint_printf("rising_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, xk, y, ya, yb, yayb; ulong k, n, m1, m2, m3; slong prec; int alg1, alg2, alg3, alias1, alias2, alias3; prec = 2 + n_randint(state, 200); k = n_randint(state, 10); n = n_randint(state, 50); m1 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n + k, 1)); m2 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(k, 1)); m3 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n, 1)); alg1 = n_randint(state, 5); alg2 = n_randint(state, 5); alg3 = n_randint(state, 5); alias1 = n_randint(state, 2); alias2 = n_randint(state, 2); alias3 = n_randint(state, 2); if (n_randint(state, 100) == 0) n += 100; acb_init(x); acb_init(xk); acb_init(y); acb_init(ya); acb_init(yb); acb_init(yayb); acb_randtest(x, state, prec, 10 + n_randint(state, 200)); acb_add_ui(xk, x, k, prec); rising_algorithm(y, x, n + k, m1, prec, alg1, alias1); rising_algorithm(ya, x, k, m2, prec, alg2, alias2); rising_algorithm(yb, xk, n, m3, prec, alg3, alias3); acb_mul(yayb, ya, yb, prec); if (!acb_overlaps(y, yayb)) { flint_printf("FAIL\n\n"); flint_printf("k = %wu, n = %wu, m1 = %wu, m2 = %wu, m3 = %wu\n\n", k, n, m1, m2, m3); flint_printf("x = "); acb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); acb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("ya = "); acb_printn(ya, 100, 0); flint_printf("\n\n"); flint_printf("yb = "); acb_printn(yb, 100, 0); flint_printf("\n\n"); flint_printf("yayb = "); acb_printn(yayb, 100, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(xk); acb_clear(y); acb_clear(ya); acb_clear(yb); acb_clear(yayb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-rising_ui_jet.c000066400000000000000000000061261417376376500210650ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void rising_algorithm(acb_ptr res, const acb_t x, ulong n, ulong m, slong len, slong prec, int alg) { if (alg == 0) acb_hypgeom_rising_ui_jet_powsum(res, x, n, len, prec); else if (alg == 1) acb_hypgeom_rising_ui_jet_rs(res, x, n, m, len, prec); else if (alg == 2) acb_hypgeom_rising_ui_jet_bs(res, x, n, len, prec); else acb_hypgeom_rising_ui_jet(res, x, n, len, prec); } int main() { slong iter; flint_rand_t state; flint_printf("rising_ui_jet...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t x, xk; acb_ptr y, ya, yb, yayb; ulong k, n, m1, m2, m3, len; slong prec; int alg1, alg2, alg3; prec = 2 + n_randint(state, 200); len = 1 + n_randint(state, 6); k = n_randint(state, 10); n = n_randint(state, 50); m1 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n + k, 1)); m2 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(k, 1)); m3 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n, 1)); alg1 = n_randint(state, 4); alg2 = n_randint(state, 4); alg3 = n_randint(state, 4); acb_init(x); acb_init(xk); y = _acb_vec_init(len); ya = _acb_vec_init(len); yb = _acb_vec_init(len); yayb = _acb_vec_init(len); acb_randtest(x, state, prec, 10); acb_add_ui(xk, x, k, prec); rising_algorithm(y, x, n + k, m1, len, prec, alg1); rising_algorithm(ya, x, k, m2, len, prec, alg2); rising_algorithm(yb, xk, n, m3, len, prec, alg3); _acb_poly_mullow(yayb, ya, len, yb, len, len, prec); if (!_acb_poly_overlaps(y, len, yayb, len)) { flint_printf("FAIL\n\n"); flint_printf("len = %wd, k = %wu, n = %wu, m1 = %wu, m2 = %wu, m3 = %wu\n\n", len, k, n, m1, m2, m3); flint_printf("x = "); acb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); _acb_vec_printn(y, len, 100, 0); flint_printf("\n\n"); flint_printf("ya = "); _acb_vec_printn(ya, len, 100, 0); flint_printf("\n\n"); flint_printf("yb = "); _acb_vec_printn(yb, len, 100, 0); flint_printf("\n\n"); flint_printf("yayb = "); _acb_vec_printn(yayb, len, 100, 0); flint_printf("\n\n"); flint_abort(); } acb_clear(x); acb_clear(xk); _acb_vec_clear(y, len); _acb_vec_clear(ya, len); _acb_vec_clear(yb, len); _acb_vec_clear(yayb, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-shi_series.c000066400000000000000000000053651417376376500203740ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("shi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, n3, bits1, bits2, bits3; acb_poly_t S, A, B, C, T, U; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); n3 = FLINT_MIN(n1, n2); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_init(T); acb_poly_init(U); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_shi_series(A, S, n1, bits2); acb_hypgeom_shi_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, n3); acb_poly_truncate(B, n3); /* [Shi(h(x))]' h(x) = sinh(h(x)) h'(x) */ acb_poly_sinh_series(U, S, n3, bits2); acb_poly_derivative(T, S, bits2); acb_poly_mullow(U, U, T, FLINT_MAX(0, n3 - 1), bits2); acb_poly_derivative(T, A, bits2); acb_poly_mullow(T, T, S, FLINT_MAX(0, n3 - 1), bits2); if (!acb_poly_overlaps(B, C) || !acb_poly_overlaps(T, U)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("T = "); acb_poly_printd(T, 15); flint_printf("\n\n"); flint_printf("U = "); acb_poly_printd(U, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_shi_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(T); acb_poly_clear(U); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-si.c000066400000000000000000000047631417376376500166530ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t z0, z1, w0, w1; slong prec0, prec1; acb_init(z0); acb_init(z1); acb_init(w0); acb_init(w1); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest(z0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_set(z1, z0); if (n_randint(state, 2)) { acb_add(z1, z1, w0, prec0); acb_sub(z1, z1, w0, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_si_1f2(w0, z0, prec0); break; case 1: acb_hypgeom_si_asymp(w0, z0, prec0); break; default: acb_hypgeom_si(w0, z0, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_si_1f2(w1, z1, prec1); break; case 1: acb_hypgeom_si_asymp(w1, z1, prec1); break; default: acb_hypgeom_si(w1, z1, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("z0 = "); acb_printd(z0, 30); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(z0); acb_clear(z1); acb_clear(w0); acb_clear(w1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-si_series.c000066400000000000000000000053561417376376500202240ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("si_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, n3, bits1, bits2, bits3; acb_poly_t S, A, B, C, T, U; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); n3 = FLINT_MIN(n1, n2); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_init(T); acb_poly_init(U); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_si_series(A, S, n1, bits2); acb_hypgeom_si_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, n3); acb_poly_truncate(B, n3); /* [Si(h(x))]' h(x) = sin(h(x)) h'(x) */ acb_poly_sin_series(U, S, n3, bits2); acb_poly_derivative(T, S, bits2); acb_poly_mullow(U, U, T, FLINT_MAX(0, n3 - 1), bits2); acb_poly_derivative(T, A, bits2); acb_poly_mullow(T, T, S, FLINT_MAX(0, n3 - 1), bits2); if (!acb_poly_overlaps(B, C) || !acb_poly_overlaps(T, U)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_printf("T = "); acb_poly_printd(T, 15); flint_printf("\n\n"); flint_printf("U = "); acb_poly_printd(U, 15); flint_printf("\n\n"); flint_abort(); } acb_hypgeom_si_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(T); acb_poly_clear(U); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-spherical_y.c000066400000000000000000000107421417376376500205340ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" /* generated with mpmath */ static const double testdata[] = { 0.0, 0.0, -0.02701626593453869896, 0.06085851132589568114, 0.092391418427377575111, 0.29443833672801130076, 0.65131374739365937388, 0.37063665572827331764, 0.83847032733386007862, -0.28730577566514336534, -0.14750357092078405673, -0.30269451746476217073, -0.048646822931479694311, 0.038926542608778397121, 0.0048197328091099892156, 0.003641138129582944611, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.027574808444335508972, 0.11025410152651193448, 0.35400136349600893569, 0.24420566191536183849, 0.67425312681608106523, -0.11728998324910652574, -0.069322941709900597259, -0.18037674817459565026, -0.018729775699827662658, 0.013254956213452933465, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14771800806690767222, 0.11532328561497280466, 0.50057392828327004059, -0.029559886614345590592, -0.02552211332726607337, -0.080244885187214384683, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.28209479177387814347, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.28209479177387814347, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14771800806690767222, 0.11532328561497280466, 0.50057392828327004059, -0.029559886614345590592, -0.02552211332726607337, -0.080244885187214384683, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.027574808444335508972, 0.11025410152651193448, 0.35400136349600893569, 0.24420566191536183849, 0.67425312681608106523, -0.11728998324910652574, -0.069322941709900597259, -0.18037674817459565026, -0.018729775699827662658, 0.013254956213452933465, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.02701626593453869896, 0.06085851132589568114, 0.092391418427377575111, 0.29443833672801130076, 0.65131374739365937388, 0.37063665572827331764, 0.83847032733386007862, -0.28730577566514336534, -0.14750357092078405673, -0.30269451746476217073, -0.048646822931479694311, 0.038926542608778397121, 0.0048197328091099892156, 0.003641138129582944611, 0.0, 0.0, -0.033798002071615353821, 0.018033964330683617275, -0.071988993423855434033, 0.19195223773954952294, 0.23381678888295549361, 0.58288246446413288682, 1.0666048448920927459, 0.45816450098677839043, 0.99160821344691798668, -0.56670953266315770842, -0.27930640165163989333, -0.44051756827083040505, -0.092578419347396006256, 0.086641542063743427664, 0.015474322098595795308, 0.010316287906840124695, 0.00051935757617903067671, -0.0014726339944978705874, }; int main() { flint_printf("spherical_y...."); fflush(stdout); { slong i, n, m; acb_t z, w, x, y; acb_init(z); acb_init(w); acb_init(x); acb_init(y); i = 0; arb_set_str(acb_realref(x), "0.2", 64); arb_set_str(acb_imagref(x), "0.3", 64); arb_set_str(acb_realref(y), "0.3", 64); arb_set_str(acb_imagref(y), "0.4", 64); for (n = -4; n <= 4; n++) { for (m = -4; m <= 4; m++) { acb_hypgeom_spherical_y(z, n, m, x, y, 64); acb_set_d_d(w, testdata[2 * i], testdata[2 * i + 1]); mag_set_d(arb_radref(acb_realref(w)), 1e-13); mag_set_d(arb_radref(acb_imagref(w)), 1e-13); if (!acb_overlaps(z, w)) { flint_printf("FAIL: value\n\n"); flint_printf("n = %wd, m = %wd\n", n, m); flint_printf("z = "); acb_printd(z, 20); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 20); flint_printf("\n\n"); flint_abort(); } i++; } } acb_clear(z); acb_clear(w); acb_clear(x); acb_clear(y); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-u.c000066400000000000000000000123101417376376500164670ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" void acb_hypgeom_u_asymp_proper(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec) { acb_t t; acb_init(t); acb_pow(t, z, a, prec); acb_hypgeom_u_asymp(res, a, b, z, -1, prec); acb_div(res, res, t, prec); acb_clear(t); } int main() { slong iter; flint_rand_t state; flint_printf("u...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t a0, a1, a2, b, z, w0, w1, w2, t, u; slong prec0, prec1, prec2; acb_init(a0); acb_init(a1); acb_init(a2); acb_init(b); acb_init(z); acb_init(w0); acb_init(w1); acb_init(w2); acb_init(t); acb_init(u); prec0 = 2 + n_randint(state, 700); prec1 = 2 + n_randint(state, 700); prec2 = 2 + n_randint(state, 700); acb_randtest_param(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest_param(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); if (prec0 <= 300 && prec1 <= 300 && prec2 <= 300 && n_randint(state, 2)) { arb_zero(acb_imagref(a0)); arb_zero(acb_imagref(b)); arb_zero(acb_imagref(z)); } acb_add_ui(a1, a0, 1, prec0); acb_add_ui(a2, a0, 2, prec0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_u_asymp_proper(w0, a0, b, z, prec0); break; case 1: acb_hypgeom_u_1f1(w0, a0, b, z, prec0); break; default: acb_hypgeom_u(w0, a0, b, z, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_u_asymp_proper(w1, a0, b, z, prec1); break; case 1: acb_hypgeom_u_1f1(w1, a0, b, z, prec1); break; default: acb_hypgeom_u(w1, a0, b, z, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("a = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_abort(); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_u_asymp_proper(w1, a1, b, z, prec1); break; case 1: acb_hypgeom_u_1f1(w1, a1, b, z, prec1); break; default: acb_hypgeom_u(w1, a1, b, z, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_u_asymp_proper(w2, a2, b, z, prec2); break; case 1: acb_hypgeom_u_1f1(w2, a2, b, z, prec2); break; default: acb_hypgeom_u(w2, a2, b, z, prec2); } acb_set(t, w0); acb_mul_2exp_si(u, a0, 1); acb_sub(u, u, b, prec0); acb_add(u, u, z, prec0); acb_add_ui(u, u, 2, prec0); acb_submul(t, w1, u, prec0); acb_sub(u, a2, b, prec0); acb_mul(u, u, a1, prec0); acb_addmul(t, w2, u, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("a = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(a0); acb_clear(a1); acb_clear(a2); acb_clear(b); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(w2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/test/t-u_asymp.c000066400000000000000000000160311417376376500177040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("u_asymp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, a2, b2, z, U1, U2, t, u, M1, M2, am; acb_struct bm[2]; ulong n1, n2; slong prec0, prec1, prec2; acb_init(a); acb_init(b); acb_init(a2); acb_init(b2); acb_init(z); acb_init(U1); acb_init(U2); acb_init(t); acb_init(u); acb_init(M1); acb_init(M2); acb_init(am); acb_init(bm); acb_init(bm + 1); if (n_randint(state, 4) == 0) { n1 = n_randint(state, 200); n2 = n_randint(state, 200); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); } else { n1 = n_randint(state, 40); n2 = n_randint(state, 40); prec0 = 2 + n_randint(state, 300); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); } acb_randtest_param(a, state, prec0, 1 + n_randint(state, 20)); if (n_randint(state, 4) == 0) acb_add_ui(b, a, n_randint(state, 10), prec0); else acb_randtest_param(b, state, prec0, 1 + n_randint(state, 20)); acb_randtest(z, state, prec0, 1 + n_randint(state, 20)); /* Test Kummer's transformation */ acb_sub(a2, a, b, prec0); acb_add_ui(a2, a2, 1, prec0); acb_sub_ui(b2, b, 2, prec0); acb_neg(b2, b2); acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1); acb_hypgeom_u_asymp(U2, a2, b2, z, n2, prec2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (Kummer transformation)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); flint_abort(); } /* Check contiguous relation (b-a-1)U(a,b-1,z) + z U(a,b+1,z) + (1-b-z) U(a,b,z) = 0 */ acb_one(t); acb_sub(t, t, b, prec0); acb_sub(t, t, z, prec0); acb_mul(u, U1, t, prec1); acb_add_ui(b2, b, 1, prec0); acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2); acb_addmul(u, U2, z, prec1); acb_sub_ui(b2, b, 1, prec0); acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2); acb_sub(t, b, a, prec0); acb_sub_ui(t, t, 1, prec0); acb_mul(t, t, U2, prec0); acb_add(t, t, u, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL (contiguous relation)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("t = "); acb_printd(t, 100); flint_printf("\n"); flint_abort(); } /* Test U(a,b,z) = gamma(1-b)/gamma(a-b+1) M(a,b,z) + gamma(b-1)/gamma(a) z^(1-b) M(a-b+1,2-b,z) */ acb_set(am, a); acb_set(bm, b); acb_one(bm + 1); acb_hypgeom_pfq_direct(M1, am, 1, bm, 2, z, n2, prec2); acb_sub(am, a, b, prec2); acb_add_ui(am, am, 1, prec2); acb_sub_ui(bm, b, 2, prec2); acb_neg(bm, bm); acb_one(bm + 1); acb_hypgeom_pfq_direct(M2, am, 1, bm, 2, z, n2, prec2); acb_sub(am, a, b, prec2); acb_add_ui(am, am, 1, prec2); acb_rgamma(am, am, prec2); acb_mul(M1, M1, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_neg(am, am); acb_gamma(am, am, prec2); acb_mul(M1, M1, am, prec2); acb_rgamma(am, a, prec2); acb_mul(M2, M2, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_gamma(am, am, prec2); acb_mul(M2, M2, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_neg(am, am); acb_pow(am, z, am, prec2); acb_mul(M2, M2, am, prec2); acb_add(U2, M1, M2, prec2); acb_pow(am, z, a, prec2); acb_mul(U2, U2, am, prec2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (U in terms of M)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); flint_abort(); } /* Test special value: b = a+1 */ acb_add_ui(b, a, 1, prec0); acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1); acb_one(U2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (special value)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(a2); acb_clear(b2); acb_clear(z); acb_clear(U1); acb_clear(U2); acb_clear(t); acb_clear(u); acb_clear(M1); acb_clear(M2); acb_clear(am); acb_clear(bm); acb_clear(bm + 1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_hypgeom/u.c000066400000000000000000000273741417376376500152670ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" static void bsplit(acb_t A, acb_t B, acb_t C, acb_t D, const acb_t b, const acb_t z, slong n0, slong n1, slong prec) { if (n1 - n0 == 1) { acb_zero(A); acb_one(B); acb_neg(C, b); acb_add_si(C, C, 2 - n0, prec); acb_mul_si(C, C, n0 - 1, prec); acb_sub(D, z, b, prec); acb_add_si(D, D, 2 - 2 * n0, prec); } else { slong m; acb_t T, A2, B2, C2, D2; acb_init(T); acb_init(A2); acb_init(B2); acb_init(C2); acb_init(D2); m = n0 + (n1 - n0) / 2; bsplit(A, B, C, D, b, z, n0, m, prec); bsplit(A2, B2, C2, D2, b, z, m, n1, prec); acb_set(T, A); acb_mul(A, A, A2, prec); acb_addmul(A, B2, C, prec); acb_mul(C, C, D2, prec); acb_addmul(C, C2, T, prec); acb_set(T, B); acb_mul(B, B, A2, prec); acb_addmul(B, B2, D, prec); acb_mul(D, D, D2, prec); acb_addmul(D, C2, T, prec); acb_clear(T); acb_clear(A2); acb_clear(B2); acb_clear(C2); acb_clear(D2); } } void acb_hypgeom_u_si_rec(acb_t res, slong a, const acb_t b, const acb_t z, slong prec) { slong k; acb_t u0, u1, t; if (a > 0) flint_abort(); if (a == 0) { acb_one(res); return; } else if (a == -1) { acb_sub(res, z, b, prec); return; } /* special-case U(-n, -n+1, z) = z^n */ if (acb_equal_si(b, a + 1)) { acb_pow_si(res, z, -a, prec); return; } acb_init(u0); acb_init(u1); acb_init(t); acb_one(u0); acb_sub(u1, z, b, prec); if (-a < 20) { for (k = 2; k <= -a; k++) { acb_neg(t, b); acb_add_si(t, t, 2 - k, prec); acb_mul_si(t, t, k - 1, prec); acb_mul(u0, u0, t, prec); acb_sub(t, z, b, prec); acb_add_si(t, t, 2 - 2 * k, prec); acb_addmul(u0, u1, t, prec); acb_swap(u0, u1); } acb_set(res, u1); } else { acb_t A, B, C, D; acb_init(A); acb_init(B); acb_init(C); acb_init(D); bsplit(A, B, C, D, b, z, 2, -a + 1, prec); acb_sub(A, z, b, prec); acb_mul(D, D, A, prec); acb_add(res, C, D, prec); acb_clear(A); acb_clear(B); acb_clear(C); acb_clear(D); } acb_clear(u0); acb_clear(u1); acb_clear(t); } void acb_hypgeom_u_1f1_series(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t z, slong len, slong prec) { acb_poly_t s, u, A, B; acb_poly_struct aa[3]; arb_t c; slong wlen; int singular; acb_poly_init(s); acb_poly_init(u); acb_poly_init(A); acb_poly_init(B); acb_poly_init(aa + 0); acb_poly_init(aa + 1); acb_poly_init(aa + 2); arb_init(c); singular = (b->length == 0) || acb_is_int(b->coeffs); wlen = len + (singular != 0); /* A = rgamma(a-b+1) * 1F~1(a,b,z) */ acb_poly_sub(u, a, b, prec); acb_poly_add_si(u, u, 1, prec); acb_poly_rgamma_series(A, u, wlen, prec); /* todo: handle a = 1 efficiently */ acb_poly_set(aa, a); acb_poly_set(aa + 1, b); acb_poly_one(aa + 2); acb_hypgeom_pfq_series_direct(s, aa, 1, aa + 1, 2, z, 1, -1, wlen, prec); acb_poly_mullow(A, A, s, wlen, prec); /* B = rgamma(a) * 1F~1(a-b+1,2-b,z) * z^(1-b) */ acb_poly_set(aa, u); acb_poly_add_si(aa + 1, b, -2, prec); acb_poly_neg(aa + 1, aa + 1); acb_hypgeom_pfq_series_direct(s, aa, 1, aa + 1, 2, z, 1, -1, wlen, prec); acb_poly_rgamma_series(B, a, wlen, prec); acb_poly_mullow(B, B, s, wlen, prec); acb_poly_add_si(u, b, -1, prec); acb_poly_neg(u, u); acb_poly_pow_series(s, z, u, wlen, prec); acb_poly_mullow(B, B, s, wlen, prec); acb_poly_sub(A, A, B, prec); /* multiply by pi csc(pi b) */ acb_poly_sin_pi_series(B, b, wlen, prec); if (singular) { acb_poly_shift_right(A, A, 1); acb_poly_shift_right(B, B, 1); } acb_poly_div_series(res, A, B, len, prec); arb_const_pi(c, prec); _acb_vec_scalar_mul_arb(res->coeffs, res->coeffs, res->length, c, prec); acb_poly_clear(s); acb_poly_clear(u); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(aa + 0); acb_poly_clear(aa + 1); acb_poly_clear(aa + 2); arb_clear(c); } void acb_hypgeom_u_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec) { if (acb_is_int(b)) { acb_poly_t aa, bb, zz; acb_poly_init(aa); acb_poly_init(bb); acb_poly_init(zz); acb_poly_set_acb(aa, a); acb_poly_set_coeff_acb(bb, 0, b); acb_poly_set_coeff_si(bb, 1, 1); acb_poly_set_acb(zz, z); acb_hypgeom_u_1f1_series(zz, aa, bb, zz, 1, prec); acb_poly_get_coeff_acb(res, zz, 0); acb_poly_clear(aa); acb_poly_clear(bb); acb_poly_clear(zz); } else { acb_t t, u, v; acb_struct aa[3]; acb_init(t); acb_init(u); acb_init(v); acb_init(aa + 0); acb_init(aa + 1); acb_init(aa + 2); acb_set(aa, a); acb_set(aa + 1, b); acb_one(aa + 2); acb_hypgeom_pfq_direct(u, aa, 1, aa + 1, 2, z, -1, prec); acb_sub(aa, a, b, prec); acb_add_ui(aa, aa, 1, prec); acb_sub_ui(aa + 1, b, 2, prec); acb_neg(aa + 1, aa + 1); acb_hypgeom_pfq_direct(v, aa, 1, aa + 1, 2, z, -1, prec); acb_sub_ui(aa + 1, b, 1, prec); /* rgamma(a-b+1) * gamma(1-b) * u */ acb_rgamma(t, aa, prec); acb_mul(u, u, t, prec); acb_neg(t, aa + 1); acb_gamma(t, t, prec); acb_mul(u, u, t, prec); /* rgamma(a) * gamma(b-1) * z^(1-b) * v */ acb_rgamma(t, a, prec); acb_mul(v, v, t, prec); acb_gamma(t, aa + 1, prec); acb_mul(v, v, t, prec); acb_neg(t, aa + 1); acb_pow(t, z, t, prec); acb_mul(v, v, t, prec); acb_add(res, u, v, prec); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(aa + 0); acb_clear(aa + 1); acb_clear(aa + 2); } } void acb_hypgeom_u_choose(int * asymp, slong * wp, const acb_t a, const acb_t b, const acb_t z, slong prec) { double x, y, t, cancellation; double input_accuracy, direct_accuracy, asymp_accuracy; *asymp = 0; *wp = prec; input_accuracy = acb_rel_one_accuracy_bits(z); t = acb_rel_one_accuracy_bits(a); input_accuracy = FLINT_MIN(input_accuracy, t); t = acb_rel_one_accuracy_bits(b); input_accuracy = FLINT_MIN(input_accuracy, t); input_accuracy = FLINT_MAX(input_accuracy, 0.0); /* From here we ignore the values of a, b. Taking them into account is a possible future improvement... */ /* Tiny |z|. */ if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 2) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 2) < 0)) { *asymp = 0; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); return; } /* Huge |z|. */ if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 64) > 0 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 64) > 0)) { *asymp = 1; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); return; } x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); asymp_accuracy = sqrt(x * x + y * y) * 1.44269504088896; /* The Kummer transformation gives less cancellation with the 1F1 series. if (x < 0.0) { *kummer = 1; x = -x; } */ if (asymp_accuracy >= prec) { *asymp = 1; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); return; } /* Assume U ~ 1, M ~ exp(|z|) (there is cancellation both in the evaluation of M and in the linear combination) -- a better estimate would account for a, b. */ cancellation = sqrt(x * x + y * y) * 1.44269504088896 + 5; direct_accuracy = input_accuracy - cancellation; if (direct_accuracy > asymp_accuracy) { *asymp = 0; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec + cancellation)); } else { *asymp = 1; *wp = FLINT_MAX(2, FLINT_MIN(input_accuracy + 20, prec)); } } void acb_hypgeom_u_nointegration(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec) { acb_t t; arf_srcptr av, tv; av = arb_midref(acb_realref(a)); /* Handle small polynomial cases without divisions. */ /* todo: should incorporate a -> 1+a-b transformation, also... */ if (acb_is_int(a) && arf_sgn(av) <= 0) { if (arf_cmpabs_ui(av, 30) < 0 || (arf_cmpabs_ui(av, prec) < 0 && ((acb_bits(b) < 0.1 * prec && acb_bits(z) < 0.1 * prec) || acb_contains_zero(z)))) { acb_hypgeom_u_si_rec(res, arf_get_si(av, ARF_RND_DOWN), b, z, prec); return; } } acb_init(t); acb_sub(t, a, b, prec); acb_add_ui(t, t, 1, prec); tv = arb_midref(acb_realref(t)); /* todo: combine these conditions with the code below */ if ((acb_is_int(a) && arf_sgn(av) <= 0) || (acb_is_int(t) && arf_sgn(tv) <= 0) || acb_hypgeom_u_use_asymp(z, prec)) { acb_neg(t, a); acb_pow(t, z, t, prec); acb_hypgeom_u_asymp(res, a, b, z, -1, prec); acb_mul(res, res, t, prec); } else { slong wp; int asymp; acb_hypgeom_u_choose(&asymp, &wp, a, b, z, prec); if (asymp) { acb_neg(t, a); acb_pow(t, z, t, prec); acb_hypgeom_u_asymp(res, a, b, z, -1, wp); acb_mul(res, res, t, prec); } else { acb_hypgeom_u_1f1(res, a, b, z, wp); acb_set_round(res, res, prec); } } acb_clear(t); } void acb_hypgeom_u(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec) { acb_t res2; slong acc, max, t; acb_init(res2); acb_hypgeom_u_nointegration(res2, a, b, z, prec); acc = acb_rel_accuracy_bits(res2); if (acc < 0.5 * prec) { max = prec; t = acb_rel_accuracy_bits(z); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(a); max = FLINT_MIN(max, t); t = acb_rel_accuracy_bits(b); max = FLINT_MIN(max, t); if (max > 2 && acc < 0.5 * max) { if (acb_is_real(a) && acb_is_real(b) && acb_is_real(z) && arb_is_positive(acb_realref(z)) && arf_cmpabs_2exp_si(arb_midref(acb_realref(a)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 60) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 60) < 0) { arb_hypgeom_u_integration(acb_realref(res), acb_realref(a), acb_realref(b), acb_realref(z), prec); arb_zero(acb_imagref(res)); if (acb_rel_accuracy_bits(res) > acb_rel_accuracy_bits(res2) || (acb_is_finite(res) && !acb_is_finite(res2))) { acb_swap(res, res2); } } } } acb_swap(res, res2); acb_clear(res2); } arb-2.22.1/acb_hypgeom/u_asymp.c000066400000000000000000000227141417376376500164710ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" slong acb_hypgeom_pfq_choose_n_max(acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong prec, slong n_max); int acb_hypgeom_u_asymp_determine_region(const mag_t r, const mag_t zlo, const acb_t z) { int R; mag_t u, zre, zim; mag_init(u); mag_init(zre); mag_init(zim); /* lower bounds for |re(z)|, |im(z)|, |z| */ arb_get_mag_lower(zre, acb_realref(z)); arb_get_mag_lower(zim, acb_imagref(z)); R = 0; if (mag_cmp(zlo, r) >= 0) { int znonneg = arb_is_nonnegative(acb_realref(z)); if (znonneg && mag_cmp(zre, r) >= 0) { R = 1; } else if (mag_cmp(zim, r) >= 0 || znonneg) { R = 2; } else { mag_mul_2exp_si(u, r, 1); if (mag_cmp(zlo, u) >= 0) R = 3; } } mag_clear(u); mag_clear(zre); mag_clear(zim); return R; } /* computes the factors that are independent of n (all are upper bounds) */ void acb_hypgeom_u_asymp_bound_factors(int * R, mag_t alpha, mag_t nu, mag_t sigma, mag_t rho, mag_t zinv, const acb_t a, const acb_t b, const acb_t z) { mag_t r, u, zlo, sigma_prime; acb_t t; mag_init(r); mag_init(u); mag_init(zlo); mag_init(sigma_prime); acb_init(t); /* upper bound for 1/|z| */ acb_get_mag_lower(zlo, z); mag_inv(zinv, zlo); /* upper bound for r = |b - 2a| */ acb_mul_2exp_si(t, a, 1); acb_sub(t, b, t, MAG_BITS); acb_get_mag(r, t); /* determine region */ *R = acb_hypgeom_u_asymp_determine_region(r, zlo, z); if (*R == 0) { mag_inf(alpha); mag_inf(nu); mag_inf(sigma); mag_inf(rho); } else { /* sigma = |(b-2a)/z| */ mag_mul(sigma, r, zinv); /* nu = (1/2 + 1/2 sqrt(1-4 sigma^2))^(-1/2) <= 1 + 2 sigma^2 */ if (mag_cmp_2exp_si(sigma, -1) <= 0) { mag_mul(nu, sigma, sigma); mag_mul_2exp_si(nu, nu, 1); mag_one(u); mag_add(nu, nu, u); } else { mag_inf(nu); } /* modified sigma for alpha, beta, rho when in R3 */ if (*R == 3) mag_mul(sigma_prime, sigma, nu); else mag_set(sigma_prime, sigma); /* alpha = 1/(1-sigma') */ mag_one(alpha); mag_sub_lower(alpha, alpha, sigma_prime); mag_one(u); mag_div(alpha, u, alpha); /* rho = |2a^2-2ab+b|/2 + sigma'*(1+sigma'/4)/(1-sigma')^2 */ mag_mul_2exp_si(rho, sigma_prime, -2); mag_one(u); mag_add(rho, rho, u); mag_mul(rho, rho, sigma_prime); mag_mul(rho, rho, alpha); mag_mul(rho, rho, alpha); acb_sub(t, a, b, MAG_BITS); acb_mul(t, t, a, MAG_BITS); acb_mul_2exp_si(t, t, 1); acb_add(t, t, b, MAG_BITS); acb_get_mag(u, t); mag_mul_2exp_si(u, u, -1); mag_add(rho, rho, u); } mag_clear(r); mag_clear(u); mag_clear(zlo); mag_clear(sigma_prime); acb_clear(t); } void acb_hypgeom_mag_chi(mag_t chi, ulong n) { mag_t p, q; ulong k; mag_init(p); mag_init(q); if (n % 2 == 0) { mag_one(p); mag_one(q); } else { /* upper bound for pi/2 */ mag_set_ui_2exp_si(p, 843314857, -28); mag_one(q); } for (k = n; k >= 2; k -= 2) { mag_mul_ui(p, p, k); mag_mul_ui_lower(q, q, k - 1); } mag_div(chi, p, q); mag_clear(p); mag_clear(q); } static void acb_hypgeom_mag_Cn(mag_t Cn, int R, const mag_t nu, const mag_t sigma, ulong n) { if (R == 1) { mag_one(Cn); } else { acb_hypgeom_mag_chi(Cn, n); if (R == 3) { mag_t tmp; mag_init(tmp); mag_mul(tmp, nu, nu); mag_mul(tmp, tmp, sigma); if (n != 1) mag_mul_ui(tmp, tmp, n); mag_add(Cn, Cn, tmp); mag_pow_ui(tmp, nu, n); mag_mul(Cn, Cn, tmp); mag_clear(tmp); } } } static int acb_is_nonpositive_int(const acb_t x) { return acb_is_int(x) && arf_sgn(arb_midref(acb_realref(x))) <= 0; } void acb_hypgeom_u_asymp(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong n, slong prec) { acb_struct aa[3]; acb_t s, t, w, winv; int R, p, q, is_real, is_terminating; slong n_terminating; if (!acb_is_finite(a) || !acb_is_finite(b) || !acb_is_finite(z)) { acb_indeterminate(res); return; } acb_init(aa); acb_init(aa + 1); acb_init(aa + 2); acb_init(s); acb_init(t); acb_init(w); acb_init(winv); is_terminating = 0; n_terminating = WORD_MAX; /* special case, for incomplete gamma [todo: also when they happen to be exact and with difference 1...] */ if (a == b) { acb_set(aa, a); p = 1; q = 0; } else { acb_set(aa, a); acb_sub(aa + 1, a, b, prec); acb_add_ui(aa + 1, aa + 1, 1, prec); acb_one(aa + 2); p = 2; q = 1; } if (acb_is_nonpositive_int(aa)) { is_terminating = 1; if (arf_cmpabs_ui(arb_midref(acb_realref(aa)), prec) < 0) n_terminating = 1 - arf_get_si(arb_midref(acb_realref(aa)), ARF_RND_DOWN); } if (p == 2 && acb_is_nonpositive_int(aa + 1)) { is_terminating = 1; if (arf_cmpabs_ui(arb_midref(acb_realref(aa + 1)), n_terminating) < 0) n_terminating = 1 - arf_get_si(arb_midref(acb_realref(aa + 1)), ARF_RND_DOWN); } acb_neg(w, z); acb_inv(w, w, prec); acb_neg(winv, z); /* low degree polynomial -- no need to try to terminate sooner */ if (is_terminating && n_terminating < 8) { acb_hypgeom_pfq_sum_invz(s, t, aa, p, aa + p, q, w, winv, n_terminating, prec); acb_set(res, s); } else { mag_t C1, Cn, alpha, nu, sigma, rho, zinv, tmp, err; mag_init(C1); mag_init(Cn); mag_init(alpha); mag_init(nu); mag_init(sigma); mag_init(rho); mag_init(zinv); mag_init(tmp); mag_init(err); acb_hypgeom_u_asymp_bound_factors(&R, alpha, nu, sigma, rho, zinv, a, b, z); is_real = acb_is_real(a) && acb_is_real(b) && acb_is_real(z) && (is_terminating || arb_is_positive(acb_realref(z))); if (R == 0) { /* if R == 0, the error bound is infinite unless terminating */ if (is_terminating && n_terminating < prec) { acb_hypgeom_pfq_sum_invz(s, t, aa, p, aa + p, q, w, winv, n_terminating, prec); acb_set(res, s); } else { acb_indeterminate(res); } } else { /* C1 */ acb_hypgeom_mag_Cn(C1, R, nu, sigma, 1); /* err = 2 * alpha * exp(...) */ mag_mul(tmp, C1, rho); mag_mul(tmp, tmp, alpha); mag_mul(tmp, tmp, zinv); mag_mul_2exp_si(tmp, tmp, 1); mag_exp(err, tmp); mag_mul(err, err, alpha); mag_mul_2exp_si(err, err, 1); /* choose n automatically */ if (n < 0) { slong moreprec; /* take err into account when finding truncation point */ /* we should take Cn into account as well, but this depends on n which is to be determined; it's easier to look only at exp(...) which should be larger anyway */ if (mag_cmp_2exp_si(err, 10 * prec) > 0) moreprec = 10 * prec; else if (mag_cmp_2exp_si(err, 0) < 0) moreprec = 0; else moreprec = MAG_EXP(err); n = acb_hypgeom_pfq_choose_n_max(aa, p, aa + p, q, w, prec + moreprec, FLINT_MIN(WORD_MAX / 2, 50 + 10.0 * prec)); } acb_hypgeom_pfq_sum_invz(s, t, aa, p, aa + p, q, w, winv, n, prec); /* add error bound, if not terminating */ if (!(is_terminating && n == n_terminating)) { acb_hypgeom_mag_Cn(Cn, R, nu, sigma, n); mag_mul(err, err, Cn); /* nth term * factor */ acb_get_mag(tmp, t); mag_mul(err, err, tmp); if (is_real) arb_add_error_mag(acb_realref(s), err); else acb_add_error_mag(s, err); } acb_set(res, s); } mag_clear(C1); mag_clear(Cn); mag_clear(alpha); mag_clear(nu); mag_clear(sigma); mag_clear(rho); mag_clear(zinv); mag_clear(tmp); mag_clear(err); } acb_clear(aa); acb_clear(aa + 1); acb_clear(aa + 2); acb_clear(s); acb_clear(t); acb_clear(w); acb_clear(winv); } arb-2.22.1/acb_hypgeom/u_use_asymp.c000066400000000000000000000017451417376376500173460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_hypgeom.h" int acb_hypgeom_u_use_asymp(const acb_t z, slong prec) { double x, y; if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 0) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0)) { return 0; } if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 64) > 0 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 64) > 0)) { return 1; } x = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); y = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); return sqrt(x * x + y * y) > prec * 0.69314718055994530942; } arb-2.22.1/acb_mat.h000066400000000000000000000345201417376376500141300ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_MAT_H #define ACB_MAT_H #ifdef ACB_MAT_INLINES_C #define ACB_MAT_INLINE #else #define ACB_MAT_INLINE static __inline__ #endif #include #include "flint/fmpz_mat.h" #include "flint/fmpq_mat.h" #include "arb.h" #include "acb.h" #include "arb_mat.h" #include "acb_poly.h" #ifdef __cplusplus extern "C" { #endif typedef struct { acb_ptr entries; slong r; slong c; acb_ptr * rows; } acb_mat_struct; typedef acb_mat_struct acb_mat_t[1]; #define acb_mat_entry(mat,i,j) ((mat)->rows[i] + (j)) #define acb_mat_nrows(mat) ((mat)->r) #define acb_mat_ncols(mat) ((mat)->c) ACB_MAT_INLINE acb_ptr acb_mat_entry_ptr(acb_mat_t mat, slong i, slong j) { return acb_mat_entry(mat, i, j); } /* Memory management */ void acb_mat_init(acb_mat_t mat, slong r, slong c); void acb_mat_clear(acb_mat_t mat); ACB_MAT_INLINE void acb_mat_swap(acb_mat_t mat1, acb_mat_t mat2) { acb_mat_struct t = *mat1; *mat1 = *mat2; *mat2 = t; } ACB_MAT_INLINE void acb_mat_swap_entrywise(acb_mat_t mat1, acb_mat_t mat2) { slong i, j; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) acb_swap(acb_mat_entry(mat2, i, j), acb_mat_entry(mat1, i, j)); } /* Window matrices */ void acb_mat_window_init(acb_mat_t window, const acb_mat_t mat, slong r1, slong c1, slong r2, slong c2); ARB_MAT_INLINE void acb_mat_window_clear(acb_mat_t window) { flint_free(window->rows); } /* Conversions */ void acb_mat_set(acb_mat_t dest, const acb_mat_t src); void acb_mat_set_fmpz_mat(acb_mat_t dest, const fmpz_mat_t src); void acb_mat_set_round_fmpz_mat(acb_mat_t dest, const fmpz_mat_t src, slong prec); void acb_mat_set_fmpq_mat(acb_mat_t dest, const fmpq_mat_t src, slong prec); void acb_mat_set_arb_mat(acb_mat_t dest, const arb_mat_t src); void acb_mat_set_round_arb_mat(acb_mat_t dest, const arb_mat_t src, slong prec); /* Random generation */ void acb_mat_randtest(acb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits); void acb_mat_randtest_eig(acb_mat_t A, flint_rand_t state, acb_srcptr E, slong prec); /* I/O */ void acb_mat_fprintd(FILE * file, const acb_mat_t mat, slong digits); ACB_MAT_INLINE void acb_mat_printd(const acb_mat_t mat, slong digits) { acb_mat_fprintd(stdout, mat, digits); } /* Comparisons */ int acb_mat_eq(const acb_mat_t mat1, const acb_mat_t mat2); int acb_mat_ne(const acb_mat_t mat1, const acb_mat_t mat2); int acb_mat_equal(const acb_mat_t mat1, const acb_mat_t mat2); int acb_mat_overlaps(const acb_mat_t mat1, const acb_mat_t mat2); int acb_mat_contains(const acb_mat_t mat1, const acb_mat_t mat2); int acb_mat_contains_fmpq_mat(const acb_mat_t mat1, const fmpq_mat_t mat2); int acb_mat_contains_fmpz_mat(const acb_mat_t mat1, const fmpz_mat_t mat2); int acb_mat_is_real(const acb_mat_t mat); ACB_MAT_INLINE int acb_mat_is_empty(const acb_mat_t mat) { return (mat->r == 0) || (mat->c == 0); } ACB_MAT_INLINE int acb_mat_is_square(const acb_mat_t mat) { return (mat->r == mat->c); } int acb_mat_is_exact(const acb_mat_t mat); int acb_mat_is_zero(const acb_mat_t mat); int acb_mat_is_finite(const acb_mat_t mat); int acb_mat_is_triu(const acb_mat_t mat); int acb_mat_is_tril(const acb_mat_t mat); ACB_MAT_INLINE int acb_mat_is_diag(const acb_mat_t mat) { return acb_mat_is_tril(mat) && acb_mat_is_triu(mat); } /* Radius and interval operations */ ACB_MAT_INLINE void acb_mat_get_mid(acb_mat_t B, const acb_mat_t A) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) { for (j = 0; j < acb_mat_ncols(A); j++) { arb_get_mid_arb(acb_realref(acb_mat_entry(B, i, j)), acb_realref(acb_mat_entry(A, i, j))); arb_get_mid_arb(acb_imagref(acb_mat_entry(B, i, j)), acb_imagref(acb_mat_entry(A, i, j))); } } } ACB_MAT_INLINE void acb_mat_add_error_mag(acb_mat_t mat, const mag_t err) { slong i, j; for (i = 0; i < acb_mat_nrows(mat); i++) for (j = 0; j < acb_mat_ncols(mat); j++) acb_add_error_mag(acb_mat_entry(mat, i, j), err); } /* Special matrices */ void acb_mat_zero(acb_mat_t mat); void acb_mat_one(acb_mat_t mat); void acb_mat_ones(acb_mat_t mat); void acb_mat_indeterminate(acb_mat_t mat); void acb_mat_dft(acb_mat_t res, int kind, slong prec); void acb_mat_transpose(acb_mat_t mat1, const acb_mat_t mat2); void acb_mat_conjugate(acb_mat_t mat1, const acb_mat_t mat2); ACB_MAT_INLINE void acb_mat_conjugate_transpose(acb_mat_t mat1, const acb_mat_t mat2) { acb_mat_transpose(mat1, mat2); acb_mat_conjugate(mat1, mat1); } /* Norms */ void acb_mat_bound_inf_norm(mag_t b, const acb_mat_t A); void acb_mat_frobenius_norm(arb_t res, const acb_mat_t A, slong prec); void acb_mat_bound_frobenius_norm(mag_t b, const acb_mat_t A); /* Arithmetic */ void acb_mat_neg(acb_mat_t dest, const acb_mat_t src); void acb_mat_add(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec); void acb_mat_sub(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec); void acb_mat_mul_classical(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec); void acb_mat_mul_threaded(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec); void acb_mat_mul_reorder(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec); void acb_mat_mul(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec); void acb_mat_mul_entrywise(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec); void acb_mat_sqr_classical(acb_mat_t res, const acb_mat_t mat, slong prec); void acb_mat_sqr(acb_mat_t res, const acb_mat_t mat, slong prec); void acb_mat_pow_ui(acb_mat_t B, const acb_mat_t A, ulong exp, slong prec); /* Scalar arithmetic */ ACB_MAT_INLINE void acb_mat_scalar_mul_2exp_si(acb_mat_t B, const acb_mat_t A, slong c) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_mul_2exp_si(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c); } ACB_MAT_INLINE void acb_mat_scalar_addmul_si(acb_mat_t B, const acb_mat_t A, slong c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_addmul_si(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_mul_si(acb_mat_t B, const acb_mat_t A, slong c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_mul_si(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_div_si(acb_mat_t B, const acb_mat_t A, slong c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_div_si(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_addmul_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_addmul_fmpz(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_mul_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_mul_fmpz(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_div_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_div_fmpz(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_addmul_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_addmul(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_mul_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_mul(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_div_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_div(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_addmul_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_addmul_arb(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_mul_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_mul_arb(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } ACB_MAT_INLINE void acb_mat_scalar_div_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_div_arb(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), c, prec); } /* Solving */ ACB_MAT_INLINE void acb_mat_swap_rows(acb_mat_t mat, slong * perm, slong r, slong s) { if (r != s) { acb_ptr u; slong t; if (perm != NULL) { t = perm[s]; perm[s] = perm[r]; perm[r] = t; } u = mat->rows[s]; mat->rows[s] = mat->rows[r]; mat->rows[r] = u; } } slong acb_mat_find_pivot_partial(const acb_mat_t mat, slong start_row, slong end_row, slong c); void acb_mat_solve_tril_classical(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec); void acb_mat_solve_tril_recursive(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec); void acb_mat_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec); void acb_mat_solve_triu_classical(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec); void acb_mat_solve_triu_recursive(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec); void acb_mat_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec); int acb_mat_lu_classical(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec); int acb_mat_lu_recursive(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec); int acb_mat_lu(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec); void acb_mat_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t A, const acb_mat_t B, slong prec); int acb_mat_solve_lu(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec); int acb_mat_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec); int acb_mat_solve_precond(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec); void acb_mat_approx_mul(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec); void acb_mat_approx_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec); void acb_mat_approx_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec); int acb_mat_approx_lu(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec); void acb_mat_approx_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t A, const acb_mat_t B, slong prec); int acb_mat_approx_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec); int acb_mat_approx_inv(acb_mat_t X, const acb_mat_t A, slong prec); int acb_mat_inv(acb_mat_t X, const acb_mat_t A, slong prec); void acb_mat_det_lu(acb_t det, const acb_mat_t A, slong prec); void acb_mat_det_precond(acb_t det, const acb_mat_t A, slong prec); void acb_mat_det(acb_t det, const acb_mat_t A, slong prec); /* Eigenvalues and eigenvectors */ int acb_mat_approx_eig_qr(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, const mag_t tol, slong maxiter, slong prec); void acb_mat_eig_global_enclosure(mag_t eps, const acb_mat_t A, acb_srcptr E, const acb_mat_t R, slong prec); void acb_mat_eig_enclosure_rump(acb_t lambda, acb_mat_t J, acb_mat_t X, const acb_mat_t A, const acb_t lambda_approx, const acb_mat_t X_approx, slong prec); int acb_mat_eig_simple_rump(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec); int acb_mat_eig_simple_vdhoeven_mourrain(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec); int acb_mat_eig_simple(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec); int acb_mat_eig_multiple_rump(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec); int acb_mat_eig_multiple(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec); /* Special functions */ void acb_mat_exp_taylor_sum(acb_mat_t S, const acb_mat_t A, slong N, slong prec); void acb_mat_exp(acb_mat_t B, const acb_mat_t A, slong prec); void _acb_mat_charpoly(acb_ptr poly, const acb_mat_t mat, slong prec); void acb_mat_charpoly(acb_poly_t poly, const acb_mat_t mat, slong prec); void _acb_mat_companion(acb_mat_t mat, acb_srcptr poly, slong prec); void acb_mat_companion(acb_mat_t mat, const acb_poly_t poly, slong prec); void acb_mat_trace(acb_t trace, const acb_mat_t mat, slong prec); void _acb_mat_diag_prod(acb_t res, const acb_mat_t A, slong a, slong b, slong prec); void acb_mat_diag_prod(acb_t res, const acb_mat_t A, slong prec); ACB_MAT_INLINE slong acb_mat_allocated_bytes(const acb_mat_t x) { return _acb_vec_allocated_bytes(x->entries, x->r * x->c) + x->r * sizeof(acb_ptr); } #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_mat/000077500000000000000000000000001417376376500137535ustar00rootroot00000000000000arb-2.22.1/acb_mat/add.c000066400000000000000000000013621417376376500146510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_add(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) acb_add(acb_mat_entry(res, i, j), acb_mat_entry(mat1, i, j), acb_mat_entry(mat2, i, j), prec); } arb-2.22.1/acb_mat/approx_eig_qr.c000066400000000000000000000714711417376376500167700ustar00rootroot00000000000000/* Copyright 2013 Timo Hartmann Copyright 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ /* Adapted from eigen.py in mpmath (written by Timo Hartmann) Todo items present in the original code: - Implement balancing - Aggressive early deflation */ #include "acb_mat.h" static void acb_approx_mag(mag_t res, const acb_t x) { mag_t t; mag_init(t); arf_get_mag(res, arb_midref(acb_realref(x))); arf_get_mag(t, arb_midref(acb_imagref(x))); mag_hypot(res, res, t); mag_clear(t); } static void acb_approx_mul(acb_t res, const acb_t x, const acb_t y, slong prec) { arf_complex_mul(arb_midref(acb_realref(res)), arb_midref(acb_imagref(res)), arb_midref(acb_realref(x)), arb_midref(acb_imagref(x)), arb_midref(acb_realref(y)), arb_midref(acb_imagref(y)), prec, ARF_RND_DOWN); } static void acb_approx_add(acb_t res, const acb_t x, const acb_t y, slong prec) { arf_add(arb_midref(acb_realref(res)), arb_midref(acb_realref(x)), arb_midref(acb_realref(y)), prec, ARF_RND_DOWN); arf_add(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(x)), arb_midref(acb_imagref(y)), prec, ARF_RND_DOWN); } static void acb_approx_sub(acb_t res, const acb_t x, const acb_t y, slong prec) { arf_sub(arb_midref(acb_realref(res)), arb_midref(acb_realref(x)), arb_midref(acb_realref(y)), prec, ARF_RND_DOWN); arf_sub(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(x)), arb_midref(acb_imagref(y)), prec, ARF_RND_DOWN); } static void acb_approx_set(acb_t res, const acb_t x) { arf_set(arb_midref(acb_realref(res)), arb_midref(acb_realref(x))); arf_set(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(x))); } static void acb_approx_div_arb(acb_t res, const acb_t x, const arb_t y, slong prec) { arf_div(arb_midref(acb_realref(res)), arb_midref(acb_realref(x)), arb_midref(y), prec, ARF_RND_DOWN); arf_div(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(x)), arb_midref(y), prec, ARF_RND_DOWN); } static void acb_approx_inv(acb_t z, const acb_t x, slong prec) { arf_set(arb_midref(acb_realref(z)), arb_midref(acb_realref(x))); arf_set(arb_midref(acb_imagref(z)), arb_midref(acb_imagref(x))); mag_zero(arb_radref(acb_realref(z))); mag_zero(arb_radref(acb_imagref(z))); acb_inv(z, z, prec); mag_zero(arb_radref(acb_realref(z))); mag_zero(arb_radref(acb_imagref(z))); } static void acb_approx_div(acb_t z, const acb_t x, const acb_t y, slong prec) { acb_t t; acb_init(t); acb_approx_inv(t, y, prec); acb_approx_mul(z, x, t, prec); acb_clear(t); } void acb_mat_approx_qr_step(acb_mat_t A, acb_mat_t Q, slong n0, slong n1, const acb_t shift, slong prec) { slong j, k, n; acb_t c, s, negs, cc, cs, negcs, t; acb_struct v1[2]; acb_struct v1neg[2]; acb_struct v2[2]; acb_struct v2neg[2]; acb_struct v3[2]; arb_t v, u; n = acb_mat_nrows(A); acb_init(c); acb_init(s); acb_init(negs); acb_init(cc); acb_init(cs); acb_init(negcs); acb_init(t); arb_init(v); arb_init(u); /* Calculate Givens rotation */ acb_approx_sub(c, acb_mat_entry(A, n0, n0), shift, prec); acb_approx_set(s, acb_mat_entry(A, n0 + 1, n0)); arf_sosq(arb_midref(v), arb_midref(acb_realref(c)), arb_midref(acb_imagref(c)), prec, ARF_RND_DOWN); arf_sosq(arb_midref(u), arb_midref(acb_realref(s)), arb_midref(acb_imagref(s)), prec, ARF_RND_DOWN); arf_add(arb_midref(v), arb_midref(v), arb_midref(u), prec, ARF_RND_DOWN); arf_sqrt(arb_midref(v), arb_midref(v), prec, ARF_RND_DOWN); if (arb_is_zero(v)) { arb_one(v); acb_one(c); acb_zero(s); } else { acb_approx_div_arb(c, c, v, prec); acb_approx_div_arb(s, s, v, prec); } acb_conj(cc, c); acb_conj(cs, s); acb_neg(negs, s); acb_neg(negcs, cs); v1[0] = *c; v1[1] = *s; v1neg[0] = *c; v1neg[1] = *negs; v2[0] = *cc; v2[1] = *cs; v2neg[0] = *cc; v2neg[1] = *negcs; /* Apply Givens rotation from the left */ for (k = n0; k < n; k++) { v3[0] = *acb_mat_entry(A, n0, k); v3[1] = *acb_mat_entry(A, n0 + 1, k); /* x = A[n0 ,k] */ /* y = A[n0+1,k] */ /* A[n0, k] = cc * x + cs * y */ /* A[n0 + 1, k] = c * y - s * x */ acb_approx_dot(t, NULL, 0, v2, 1, v3, 1, 2, prec); acb_approx_dot(acb_mat_entry(A, n0 + 1, k), NULL, 0, v1neg, 1, v3 + 1, -1, 2, prec); acb_swap(t, acb_mat_entry(A, n0, k)); } /* Apply Givens rotation from the right */ for (k = 0; k < FLINT_MIN(n1, n0 + 3); k++) { /* x = A[k,n0 ] */ /* y = A[k,n0+1] */ /* A[k,n0 ] = c * x + s * y */ /* A[k,n0+1] = cc * y - cs * x */ v3[0] = *acb_mat_entry(A, k, n0); v3[1] = *acb_mat_entry(A, k, n0 + 1); acb_approx_dot(t, NULL, 0, v1, 1, v3, 1, 2, prec); acb_approx_dot(acb_mat_entry(A, k, n0 + 1), NULL, 0, v2neg, 1, v3 + 1, -1, 2, prec); acb_swap(t, acb_mat_entry(A, k, n0)); } if (Q != NULL) { for (k = 0; k < n; k++) { /* x = Q[k,n0 ] */ /* y = Q[k,n0+1] */ /* Q[k,n0 ] = c * x + s * y */ /* Q[k,n0+1] = cc * y - cs * x */ v3[0] = *acb_mat_entry(Q, k, n0); v3[1] = *acb_mat_entry(Q, k, n0 + 1); acb_approx_dot(t, NULL, 0, v1, 1, v3, 1, 2, prec); acb_approx_dot(acb_mat_entry(Q, k, n0 + 1), NULL, 0, v2neg, 1, v3 + 1, -1, 2, prec); acb_swap(t, acb_mat_entry(Q, k, n0)); } } for (j = n0; j < n1 - 2; j++) { /* Calculate Givens rotation */ acb_set(c, acb_mat_entry(A, j + 1, j)); acb_set(s, acb_mat_entry(A, j + 2, j)); arf_sosq(arb_midref(v), arb_midref(acb_realref(c)), arb_midref(acb_imagref(c)), prec, ARF_RND_DOWN); arf_sosq(arb_midref(u), arb_midref(acb_realref(s)), arb_midref(acb_imagref(s)), prec, ARF_RND_DOWN); arf_add(arb_midref(v), arb_midref(v), arb_midref(u), prec, ARF_RND_DOWN); arf_sqrt(arb_midref(v), arb_midref(v), prec, ARF_RND_DOWN); if (arb_is_zero(v)) { acb_zero(acb_mat_entry(A, j + 1, j)); arb_one(v); acb_one(c); acb_zero(s); } else { acb_set_arb(acb_mat_entry(A, j + 1, j), v); acb_approx_div_arb(c, c, v, prec); acb_approx_div_arb(s, s, v, prec); } acb_zero(acb_mat_entry(A, j + 2, j)); acb_conj(cc, c); acb_conj(cs, s); acb_neg(negs, s); acb_neg(negcs, cs); v1[0] = *c; v1[1] = *s; v1neg[0] = *c; v1neg[1] = *negs; v2[0] = *cc; v2[1] = *cs; v2neg[0] = *cc; v2neg[1] = *negcs; /* Apply Givens rotation from the left */ for (k = j + 1; k < n; k++) { v3[0] = *acb_mat_entry(A, j + 1, k); v3[1] = *acb_mat_entry(A, j + 2, k); /* x = A[j+1, k] */ /* y = A[j+2, k] */ /* A[j + 1, k] = cc * x + cs * y */ /* A[j + 2, k] = c * y - s * x */ acb_approx_dot(t, NULL, 0, v2, 1, v3, 1, 2, prec); acb_approx_dot(acb_mat_entry(A, j + 2, k), NULL, 0, v1neg, 1, v3 + 1, -1, 2, prec); acb_swap(t, acb_mat_entry(A, j + 1, k)); } /* Apply Givens rotation from the right */ for (k = 0; k < FLINT_MIN(n1, j + 4); k++) { /* x = A[k,j+1] */ /* y = A[k,j+2] */ /* A[k,j+1] = c * x + s * y */ /* A[k,j+2] = cc * y - cs * x */ v3[0] = *acb_mat_entry(A, k, j + 1); v3[1] = *acb_mat_entry(A, k, j + 2); acb_approx_dot(t, NULL, 0, v1, 1, v3, 1, 2, prec); acb_approx_dot(acb_mat_entry(A, k, j + 2), NULL, 0, v2neg, 1, v3 + 1, -1, 2, prec); acb_swap(t, acb_mat_entry(A, k, j + 1)); } if (Q != NULL) { for (k = 0; k < n; k++) { /* x = Q[k,j+1] */ /* y = Q[k,j+2] */ /* Q[k,j+1] = c * x + s * y */ /* Q[k,j+2] = cc * y - cs * x */ v3[0] = *acb_mat_entry(Q, k, j + 1); v3[1] = *acb_mat_entry(Q, k, j + 2); acb_approx_dot(t, NULL, 0, v1, 1, v3, 1, 2, prec); acb_approx_dot(acb_mat_entry(Q, k, j + 2), NULL, 0, v2neg, 1, v3 + 1, -1, 2, prec); acb_swap(t, acb_mat_entry(Q, k, j + 1)); } } } acb_clear(c); acb_clear(s); acb_clear(negs); acb_clear(cc); acb_clear(cs); acb_clear(negcs); acb_clear(t); arb_clear(v); arb_clear(u); } void acb_mat_approx_hessenberg_reduce_0(acb_mat_t A, acb_ptr T, slong prec) { slong i, j, k, n; arf_t scale, scale_inv, tt, H, G, f; acb_ptr V1, V2; acb_t ff, GG, TT; acb_t F; n = acb_mat_nrows(A); if (n <= 2) return; arf_init(scale); arf_init(scale_inv); arf_init(tt); arf_init(H); arf_init(G); arf_init(f); acb_init(F); V1 = _acb_vec_init(n + 1); V2 = _acb_vec_init(n + 1); acb_init(ff); acb_init(GG); acb_init(TT); for (i = n - 1; i >= 2; i--) { /* Scale the vector (todo: is this needed?) */ arf_zero(scale); for (k = 0; k < i; k++) { arf_abs(tt, arb_midref(acb_realref(acb_mat_entry(A, i, k)))); arf_add(scale, scale, tt, prec, ARF_RND_DOWN); arf_abs(tt, arb_midref(acb_imagref(acb_mat_entry(A, i, k)))); arf_add(scale, scale, tt, prec, ARF_RND_DOWN); } arf_ui_div(scale_inv, 1, scale, prec, ARF_RND_DOWN); if (arf_is_zero(scale)) { acb_zero(T + i); acb_zero(acb_mat_entry(A, i, i - 1)); continue; } /* Calculate parameters for Householder transformation. */ arf_zero(H); for (k = 0; k < i; k++) { arf_ptr Aikr, Aiki; Aikr = arb_midref(acb_realref(acb_mat_entry(A, i, k))); Aiki = arb_midref(acb_imagref(acb_mat_entry(A, i, k))); arf_mul(Aikr, Aikr, scale_inv, prec, ARF_RND_DOWN); arf_mul(Aiki, Aiki, scale_inv, prec, ARF_RND_DOWN); arf_addmul(H, Aikr, Aikr, prec, ARF_RND_DOWN); arf_addmul(H, Aiki, Aiki, prec, ARF_RND_DOWN); } acb_set(F, acb_mat_entry(A, i, i - 1)); /* f = abs(F) */ arf_mul(f, arb_midref(acb_realref(F)), arb_midref(acb_realref(F)), prec, ARF_RND_DOWN); arf_addmul(f, arb_midref(acb_imagref(F)), arb_midref(acb_imagref(F)), prec, ARF_RND_DOWN); arf_sqrt(f, f, prec, ARF_RND_DOWN); arf_sqrt(G, H, prec, ARF_RND_DOWN); /* A[i,i-1] = -G scale */ arf_mul(arb_midref(acb_realref(acb_mat_entry(A, i, i - 1))), G, scale, prec, ARF_RND_DOWN); arf_neg(arb_midref(acb_realref(acb_mat_entry(A, i, i - 1))), arb_midref(acb_realref(acb_mat_entry(A, i, i - 1)))); arf_zero(arb_midref(acb_imagref(acb_mat_entry(A, i, i - 1)))); if (arf_is_zero(f)) { arb_set_arf(acb_realref(T + i), G); arb_zero(acb_imagref(T + i)); } else { /* ff = F / f */ arf_div(arb_midref(acb_realref(ff)), arb_midref(acb_realref(F)), f, prec, ARF_RND_DOWN); arf_div(arb_midref(acb_imagref(ff)), arb_midref(acb_imagref(F)), f, prec, ARF_RND_DOWN); /* T[i] = F + G ff */ acb_set(T + i, F); arf_addmul(arb_midref(acb_realref(T + i)), arb_midref(acb_realref(ff)), G, prec, ARF_RND_DOWN); arf_addmul(arb_midref(acb_imagref(T + i)), arb_midref(acb_imagref(ff)), G, prec, ARF_RND_DOWN); /* A[i,i-1] *= ff */ acb_approx_mul(acb_mat_entry(A, i, i - 1), acb_mat_entry(A, i, i - 1), ff, prec); } arf_addmul(H, G, f, prec, ARF_RND_DOWN); arf_rsqrt(H, H, prec, ARF_RND_DOWN); arf_mul(arb_midref(acb_realref(T + i)), arb_midref(acb_realref(T + i)), H, prec, ARF_RND_DOWN); arf_mul(arb_midref(acb_imagref(T + i)), arb_midref(acb_imagref(T + i)), H, prec, ARF_RND_DOWN); for (k = 0; k < i - 1; k++) { arf_mul(arb_midref(acb_realref(acb_mat_entry(A, i, k))), arb_midref(acb_realref(acb_mat_entry(A, i, k))), H, prec, ARF_RND_DOWN); arf_mul(arb_midref(acb_imagref(acb_mat_entry(A, i, k))), arb_midref(acb_imagref(acb_mat_entry(A, i, k))), H, prec, ARF_RND_DOWN); } /* todo: optimize copies below */ /* todo: conj mid etc... */ /* Apply Householder transformation (from the right). */ for (j = 0; j < i; j++) { acb_conj(V1, T + i); acb_set(V2, acb_mat_entry(A, j, i - 1)); for (k = 0; k < i - 1; k++) { acb_conj(V1 + k + 1, acb_mat_entry(A, i, k)); acb_set(V2 + k + 1, acb_mat_entry(A, j, k)); } acb_approx_dot(GG, NULL, 0, V1, 1, V2, 1, i, prec); acb_approx_mul(TT, GG, T + i, prec); acb_approx_sub(acb_mat_entry(A, j, i - 1), acb_mat_entry(A, j, i - 1), TT, prec); for (k = 0; k < i - 1; k++) { acb_approx_mul(TT, GG, acb_mat_entry(A, i, k), prec); acb_approx_sub(acb_mat_entry(A, j, k), acb_mat_entry(A, j, k), TT, prec); } } for (j = 0; j < n; j++) { acb_set(V1, T + i); acb_set(V2, acb_mat_entry(A, i - 1, j)); for (k = 0; k < i - 1; k++) { acb_set(V1 + k + 1, acb_mat_entry(A, i, k)); acb_set(V2 + k + 1, acb_mat_entry(A, k, j)); } acb_approx_dot(GG, NULL, 0, V1, 1, V2, 1, i, prec); acb_conj(TT, T + i); acb_approx_mul(TT, GG, TT, prec); acb_approx_sub(acb_mat_entry(A, i - 1, j), acb_mat_entry(A, i - 1, j), TT, prec); for (k = 0; k < i - 1; k++) { acb_conj(TT, acb_mat_entry(A, i, k)); acb_approx_mul(TT, GG, TT, prec); acb_approx_sub(acb_mat_entry(A, k, j), acb_mat_entry(A, k, j), TT, prec); } } } arf_clear(scale); arf_clear(scale_inv); arf_clear(tt); arf_clear(H); arf_clear(G); arf_clear(f); acb_clear(F); _acb_vec_clear(V1, n + 1); _acb_vec_clear(V2, n + 1); acb_clear(ff); acb_clear(GG); acb_clear(TT); } void acb_mat_approx_hessenberg_reduce_1(acb_mat_t A, acb_srcptr T, slong prec) { slong i, j, k, n; acb_t G, t; n = acb_mat_nrows(A); if (n <= 1) { if (n == 1) acb_one(acb_mat_entry(A, 0, 0)); return; } acb_one(acb_mat_entry(A, 0, 0)); acb_one(acb_mat_entry(A, 1, 1)); acb_zero(acb_mat_entry(A, 0, 1)); acb_zero(acb_mat_entry(A, 1, 0)); acb_init(G); acb_init(t); for (i = 2; i < n; i++) { if (!acb_is_zero(T + i)) { /* todo: rewrite using approx_dot */ for (j = 0; j < i; j++) { acb_approx_mul(G, T + i, acb_mat_entry(A, i - 1, j), prec); for (k = 0; k < i - 1; k++) { acb_approx_mul(t, acb_mat_entry(A, i, k), acb_mat_entry(A, k, j), prec); acb_approx_add(G, G, t, prec); } acb_conj(t, T + i); acb_approx_mul(t, G, t, prec); acb_approx_sub(acb_mat_entry(A, i - 1, j), acb_mat_entry(A, i - 1, j), t, prec); for (k = 0; k < i - 1; k++) { acb_conj(t, acb_mat_entry(A, i, k)); acb_approx_mul(t, G, t, prec); acb_approx_sub(acb_mat_entry(A, k, j), acb_mat_entry(A, k, j), t, prec); } } } acb_one(acb_mat_entry(A, i, i)); for (j = 0; j < i; j++) { acb_zero(acb_mat_entry(A, j, i)); acb_zero(acb_mat_entry(A, i, j)); } } acb_clear(G); acb_clear(t); } /* Right eigenvectors of a triu matrix. No aliasing. */ void acb_mat_approx_eig_triu_r(acb_mat_t ER, const acb_mat_t A, slong prec) { slong i, j, k, n; mag_t tm, smin, unfl, simin, smlnum, rmax; acb_t r, s, t; n = acb_mat_nrows(A); acb_mat_one(ER); acb_init(r); acb_init(s); acb_init(t); mag_init(tm); mag_init(smin); mag_init(smlnum); mag_init(unfl); mag_init(simin); mag_init(rmax); mag_set_ui_2exp_si(unfl, 1, -30 * prec); mag_mul_ui(smlnum, unfl, n); mag_mul_2exp_si(smlnum, smlnum, prec); mag_set_ui_2exp_si(simin, 1, prec / 2); mag_one(rmax); for (i = 1; i < n; i++) { acb_set(s, acb_mat_entry(A, i, i)); /* smin = max(eps * abs(s), smlnum) */ acb_approx_mag(smin, s); mag_mul_2exp_si(smin, smin, -prec); mag_max(smin, smin, smlnum); for (j = i - 1; j >= 0; j--) { acb_approx_dot(r, NULL, 0, A->rows[j] + j + 1, 1, ER->rows[i] + j + 1, 1, i - j, prec); acb_approx_sub(t, acb_mat_entry(A, j, j), s, prec); /* if abs(t) < smin: t = smin */ acb_approx_mag(tm, t); if (mag_cmp(tm, smin) < 0) { acb_zero(t); arf_set_mag(arb_midref(acb_realref(t)), smin); } acb_approx_div(acb_mat_entry(ER, i, j), r, t, prec); acb_neg(acb_mat_entry(ER, i, j), acb_mat_entry(ER, i, j)); acb_approx_mag(tm, r); mag_max(rmax, rmax, tm); if (mag_cmp(rmax, simin) > 0) { arb_t b; arb_init(b); arf_set_mag(arb_midref(b), rmax); for (k = j; k < i + 1; k++) { acb_approx_div_arb(acb_mat_entry(ER, i, k), acb_mat_entry(ER, i, k), b, prec); } mag_one(rmax); arb_clear(b); } } if (mag_cmp_2exp_si(rmax, 0) != 0) { arb_t b; arb_init(b); arf_set_mag(arb_midref(b), rmax); for (k = 0; k < i + 1; k++) { acb_approx_div_arb(acb_mat_entry(ER, i, k), acb_mat_entry(ER, i, k), b, prec); } arb_clear(b); } } acb_mat_transpose(ER, ER); acb_clear(r); acb_clear(s); acb_clear(t); mag_clear(tm); mag_clear(smin); mag_clear(smlnum); mag_clear(unfl); mag_clear(simin); mag_clear(rmax); } /* Left eigenvectors of a triu matrix. No aliasing. */ void acb_mat_approx_eig_triu_l(acb_mat_t EL, const acb_mat_t A, slong prec) { slong i, j, k, n; mag_t tm, smin, unfl, simin, smlnum, rmax; acb_t r, s, t; acb_mat_t AT; n = acb_mat_nrows(A); acb_mat_init(AT, n, n); acb_mat_one(EL); acb_mat_transpose(AT, A); acb_init(r); acb_init(s); acb_init(t); mag_init(tm); mag_init(smin); mag_init(smlnum); mag_init(unfl); mag_init(simin); mag_init(rmax); mag_set_ui_2exp_si(unfl, 1, -30 * prec); mag_mul_ui(smlnum, unfl, n); mag_mul_2exp_si(smlnum, smlnum, prec); mag_set_ui_2exp_si(simin, 1, prec / 2); mag_one(rmax); for (i = 0; i < n - 1; i++) { acb_set(s, acb_mat_entry(AT, i, i)); /* smin = max(eps * abs(s), smlnum) */ acb_approx_mag(smin, s); mag_mul_2exp_si(smin, smin, -prec); mag_max(smin, smin, smlnum); for (j = i + 1; j < n; j++) { acb_approx_dot(r, NULL, 0, EL->rows[i] + i, 1, AT->rows[j] + i, 1, j - i, prec); acb_approx_sub(t, acb_mat_entry(AT, j, j), s, prec); /* if abs(t) < smin: t = smin */ acb_approx_mag(tm, t); if (mag_cmp(tm, smin) < 0) { acb_zero(t); arf_set_mag(arb_midref(acb_realref(t)), smin); } acb_approx_div(acb_mat_entry(EL, i, j), r, t, prec); acb_neg(acb_mat_entry(EL, i, j), acb_mat_entry(EL, i, j)); acb_approx_mag(tm, r); mag_max(rmax, rmax, tm); if (mag_cmp(rmax, simin) > 0) { arb_t b; arb_init(b); arf_set_mag(arb_midref(b), rmax); for (k = i; k < j + 1; k++) { acb_approx_div_arb(acb_mat_entry(EL, i, k), acb_mat_entry(EL, i, k), b, prec); } mag_one(rmax); arb_clear(b); } } if (mag_cmp_2exp_si(rmax, 0) != 0) { arb_t b; arb_init(b); arf_set_mag(arb_midref(b), rmax); for (k = i; k < n; k++) { acb_approx_div_arb(acb_mat_entry(EL, i, k), acb_mat_entry(EL, i, k), b, prec); } arb_clear(b); } } acb_clear(r); acb_clear(s); acb_clear(t); mag_clear(tm); mag_clear(smin); mag_clear(smlnum); mag_clear(unfl); mag_clear(simin); mag_clear(rmax); } int acb_mat_approx_hessenberg_qr(acb_mat_t A, acb_mat_t Q, const mag_t tol, slong maxiter, slong prec) { slong n, i, j, k, n0, n1, iter, total_iter; mag_t norm, tm, um, eps, ts; acb_t shift, s, t, a, b; int result; n = acb_mat_nrows(A); if (n <= 1) return 1; mag_init(norm); mag_init(tm); mag_init(um); mag_init(eps); mag_init(ts); acb_init(shift); acb_init(s); acb_init(t); acb_init(a); acb_init(b); for (i = 0; i < n; i++) { for (j = 0; j < FLINT_MIN(i + 2, n); j++) { arf_get_mag(tm, arb_midref(acb_realref(acb_mat_entry(A, j, i)))); arf_get_mag(um, arb_midref(acb_imagref(acb_mat_entry(A, j, i)))); mag_addmul(norm, tm, tm); mag_addmul(norm, um, um); } } mag_sqrt(norm, norm); mag_div_ui(norm, norm, n); if (mag_is_zero(norm)) return 1; if (mag_is_inf(norm)) return 0; if (tol == NULL) { mag_one(eps); mag_mul_2exp_si(eps, eps, -prec); mag_div_ui(eps, eps, 100 * n); } else { mag_set(eps, tol); } if (maxiter <= 0) { maxiter = 14 * n; maxiter += prec / 10; } /* The active submatrix is A[n0:n1,n0:n1]. */ n0 = 0; n1 = n; iter = total_iter = 0; result = 0; while (1) { k = n0; /* flint_printf("total_iter %wd active %wd\n", total_iter, n1 - n0); */ while (k + 1 < n1) { mag_zero(ts); arf_get_mag(tm, arb_midref(acb_realref(acb_mat_entry(A, k, k)))); mag_add(ts, ts, tm); arf_get_mag(tm, arb_midref(acb_imagref(acb_mat_entry(A, k, k)))); mag_add(ts, ts, tm); arf_get_mag(tm, arb_midref(acb_realref(acb_mat_entry(A, k + 1, k + 1)))); mag_add(ts, ts, tm); arf_get_mag(tm, arb_midref(acb_imagref(acb_mat_entry(A, k + 1, k + 1)))); mag_add(ts, ts, tm); /* if s < eps * norm, s = norm */ mag_mul(tm, eps, norm); if (mag_cmp(ts, tm) < 0) mag_set(ts, norm); /* if abs(A[k+1,k]) < eps * s, break */ arf_get_mag(tm, arb_midref(acb_realref(acb_mat_entry(A, k + 1, k)))); arf_get_mag(um, arb_midref(acb_imagref(acb_mat_entry(A, k + 1, k)))); mag_hypot(tm, tm, um); mag_mul(um, eps, ts); if (mag_cmp(tm, um) < 0) break; k++; } /* Deflation found at position (k+1, k). */ if (k + 1 < n1) { acb_zero(acb_mat_entry(A, k + 1, k)); n0 = k + 1; iter = 0; if (n0 + 1 >= n1) { /* Block of size at most two has converged. */ n0 = 0; n1 = k + 1; if (n1 < 2) { /* QR algorithm has converged. */ result = 1; goto cleanup; } } } else { if (iter % 30 == 10) { /* Exceptional shift */ acb_set(shift, acb_mat_entry(A, n1 - 1, n1 - 2)); } else if (iter % 30 == 20) { /* Exceptional shift */ acb_abs(acb_realref(shift), acb_mat_entry(A, n1 - 1, n1 - 2), prec); arb_zero(acb_imagref(shift)); } else if (iter % 30 == 29) { /* Exceptional shift */ acb_zero(shift); arf_set_mag(arb_midref(acb_realref(shift)), norm); } else { acb_approx_add(t, acb_mat_entry(A, n1 - 2, n1 - 2), acb_mat_entry(A, n1 - 1, n1 - 1), prec); acb_approx_sub(a, acb_mat_entry(A, n1 - 1, n1 - 1), acb_mat_entry(A, n1 - 2, n1 - 2), prec); acb_approx_mul(a, a, a, prec); acb_approx_mul(b, acb_mat_entry(A, n1 - 1, n1 - 2), acb_mat_entry(A, n1 - 2, n1 - 1), prec); acb_mul_2exp_si(b, b, 2); acb_approx_add(s, a, b, prec); if (arb_is_positive(acb_realref(s))) { acb_sqrt(s, s, prec); acb_get_mid(s, s); } else { acb_neg(s, s); acb_sqrt(s, s, prec); acb_get_mid(s, s); acb_mul_onei(s, s); } acb_approx_add(a, t, s, prec); acb_approx_sub(b, t, s, prec); acb_mul_2exp_si(a, a, -1); acb_mul_2exp_si(b, b, -1); acb_approx_sub(s, acb_mat_entry(A, n1 - 1, n1 - 1), a, prec); acb_approx_sub(t, acb_mat_entry(A, n1 - 1, n1 - 1), b, prec); acb_get_mag(tm, s); acb_get_mag(um, t); if (mag_cmp(tm, um) > 0) acb_set(shift, b); else acb_set(shift, a); } mag_zero(arb_radref(acb_realref(shift))); mag_zero(arb_radref(acb_imagref(shift))); iter++; total_iter++; acb_mat_approx_qr_step(A, Q, n0, n1, shift, prec); if (iter > maxiter) { result = 0; goto cleanup; } } } cleanup: mag_clear(norm); mag_clear(tm); mag_clear(um); mag_clear(ts); mag_clear(eps); acb_clear(shift); acb_clear(s); acb_clear(t); acb_clear(a); acb_clear(b); return result; } int acb_mat_approx_eig_qr(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, const mag_t tol, slong maxiter, slong prec) { slong n, i, j; acb_ptr T; acb_mat_t Acopy, Q; int result; n = acb_mat_nrows(A); T = _acb_vec_init(n); acb_mat_init(Acopy, n, n); acb_mat_get_mid(Acopy, A); acb_mat_approx_hessenberg_reduce_0(Acopy, T, prec); if (L != NULL || R != NULL) { acb_mat_init(Q, n, n); acb_mat_set(Q, Acopy); acb_mat_approx_hessenberg_reduce_1(Q, T, prec); } for (i = 0; i < n; i++) for (j = i + 2; j < n; j++) acb_zero(acb_mat_entry(Acopy, j, i)); result = acb_mat_approx_hessenberg_qr(Acopy, (L != NULL || R != NULL) ? Q : NULL, tol, maxiter, prec); for (i = 0; i < n; i++) acb_get_mid(E + i, acb_mat_entry(Acopy, i, i)); if (R != NULL) { acb_mat_t ER; acb_mat_init(ER, n, n); acb_mat_approx_eig_triu_r(ER, Acopy, prec); acb_mat_approx_mul(R, Q, ER, prec); acb_mat_get_mid(R, R); /* zero radii */ acb_mat_clear(ER); } if (L != NULL) { acb_mat_t EL; acb_mat_init(EL, n, n); acb_mat_approx_eig_triu_l(EL, Acopy, prec); acb_mat_conjugate_transpose(Q, Q); acb_mat_approx_mul(L, EL, Q, prec); acb_mat_get_mid(L, L); /* zero radii */ acb_mat_clear(EL); } if (L != NULL || R != NULL) acb_mat_clear(Q); _acb_vec_clear(T, n); acb_mat_clear(Acopy); return result; } arb-2.22.1/acb_mat/approx_inv.c000066400000000000000000000014171417376376500163070ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_approx_inv(acb_mat_t X, const acb_mat_t A, slong prec) { if (X == A) { int r; acb_mat_t T; acb_mat_init(T, acb_mat_nrows(A), acb_mat_ncols(A)); r = acb_mat_approx_inv(T, A, prec); acb_mat_swap(T, X); acb_mat_clear(T); return r; } acb_mat_one(X); return acb_mat_approx_solve(X, A, X, prec); } arb-2.22.1/acb_mat/approx_lu.c000066400000000000000000000124451417376376500161360ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void _apply_permutation(slong * AP, acb_mat_t A, slong * P, slong n, slong offset) { if (n != 0) { acb_ptr * Atmp; slong * APtmp; slong i; Atmp = flint_malloc(sizeof(acb_ptr) * n); APtmp = flint_malloc(sizeof(slong) * n); for (i = 0; i < n; i++) Atmp[i] = A->rows[P[i] + offset]; for (i = 0; i < n; i++) A->rows[i + offset] = Atmp[i]; for (i = 0; i < n; i++) APtmp[i] = AP[P[i] + offset]; for (i = 0; i < n; i++) AP[i + offset] = APtmp[i]; flint_free(Atmp); flint_free(APtmp); } } static void _acb_approx_mul(acb_t res, const acb_t x, const acb_t y, slong prec) { arf_complex_mul(arb_midref(acb_realref(res)), arb_midref(acb_imagref(res)), arb_midref(acb_realref(x)), arb_midref(acb_imagref(x)), arb_midref(acb_realref(y)), arb_midref(acb_imagref(y)), prec, ARB_RND); } static void _acb_approx_inv(acb_t z, const acb_t x, slong prec) { arf_set(arb_midref(acb_realref(z)), arb_midref(acb_realref(x))); arf_set(arb_midref(acb_imagref(z)), arb_midref(acb_imagref(x))); mag_zero(arb_radref(acb_realref(z))); mag_zero(arb_radref(acb_imagref(z))); acb_inv(z, z, prec); mag_zero(arb_radref(acb_realref(z))); mag_zero(arb_radref(acb_imagref(z))); } static void _acb_vec_approx_scalar_addmul(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) { acb_t t; slong i; acb_init(t); for (i = 0; i < len; i++) { _acb_approx_mul(t, vec + i, c, prec); arf_add(arb_midref(acb_realref(res + i)), arb_midref(acb_realref(res + i)), arb_midref(acb_realref(t)), prec, ARB_RND); arf_add(arb_midref(acb_imagref(res + i)), arb_midref(acb_imagref(res + i)), arb_midref(acb_imagref(t)), prec, ARB_RND); } acb_clear(t); } int acb_mat_approx_lu_classical(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec) { acb_t d, e; acb_ptr * a; slong i, j, m, n, r, row, col; int result; if (acb_mat_is_empty(A)) return 1; m = acb_mat_nrows(A); n = acb_mat_ncols(A); acb_mat_get_mid(LU, A); a = LU->rows; row = col = 0; for (i = 0; i < m; i++) P[i] = i; acb_init(d); acb_init(e); result = 1; while (row < m && col < n) { r = acb_mat_find_pivot_partial(LU, row, m, col); if (r == -1) { result = 0; break; } else if (r != row) acb_mat_swap_rows(LU, P, row, r); _acb_approx_inv(d, a[row] + col, prec); for (j = row + 1; j < m; j++) { _acb_approx_mul(e, a[j] + col, d, prec); acb_neg(e, e); _acb_vec_approx_scalar_addmul(a[j] + col, a[row] + col, n - col, e, prec); acb_zero(a[j] + col); acb_neg(a[j] + row, e); } row++; col++; } acb_clear(d); acb_clear(e); return result; } int acb_mat_approx_lu_recursive(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec) { slong i, m, n, r1, r2, n1; acb_mat_t A0, A1, A00, A01, A10, A11; slong * P1; m = A->r; n = A->c; if (m <= 1 || n <= 1) { return acb_mat_approx_lu_classical(P, LU, A, prec); } acb_mat_get_mid(LU, A); n1 = n / 2; for (i = 0; i < m; i++) P[i] = i; P1 = flint_malloc(sizeof(slong) * m); acb_mat_window_init(A0, LU, 0, 0, m, n1); acb_mat_window_init(A1, LU, 0, n1, m, n); r1 = acb_mat_approx_lu(P1, A0, A0, prec); if (!r1) { flint_free(P1); acb_mat_window_clear(A0); acb_mat_window_clear(A1); return 0; } /* r1 = rank of A0 */ r1 = FLINT_MIN(m, n1); _apply_permutation(P, LU, P1, m, 0); acb_mat_window_init(A00, LU, 0, 0, r1, r1); acb_mat_window_init(A10, LU, r1, 0, m, r1); acb_mat_window_init(A01, LU, 0, n1, r1, n); acb_mat_window_init(A11, LU, r1, n1, m, n); acb_mat_approx_solve_tril(A01, A00, A01, 1, prec); { /* acb_mat_submul(A11, A11, A10, A01, prec); */ acb_mat_t T; acb_mat_init(T, A10->r, A01->c); acb_mat_approx_mul(T, A10, A01, prec); acb_mat_sub(A11, A11, T, prec); acb_mat_get_mid(A11, A11); acb_mat_clear(T); } r2 = acb_mat_approx_lu(P1, A11, A11, prec); if (!r2) r1 = r2 = 0; else _apply_permutation(P, LU, P1, m - r1, r1); flint_free(P1); acb_mat_window_clear(A00); acb_mat_window_clear(A01); acb_mat_window_clear(A10); acb_mat_window_clear(A11); acb_mat_window_clear(A0); acb_mat_window_clear(A1); return r1 && r2; } int acb_mat_approx_lu(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec) { if (acb_mat_nrows(A) < 8 || acb_mat_ncols(A) < 8) return acb_mat_approx_lu_classical(P, LU, A, prec); else return acb_mat_approx_lu_recursive(P, LU, A, prec); } arb-2.22.1/acb_mat/approx_mul.c000066400000000000000000000074641417376376500163200ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_approx_mul_classical(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec) { slong ar, br, bc, i, j; ar = acb_mat_nrows(A); br = acb_mat_nrows(B); bc = acb_mat_ncols(B); if (br == 0) { for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { arf_zero(arb_midref(acb_realref(acb_mat_entry(C, i, j)))); arf_zero(arb_midref(acb_imagref(acb_mat_entry(C, i, j)))); } } return; } if (A == C || B == C) { acb_mat_t T; acb_mat_init(T, ar, bc); acb_mat_approx_mul_classical(T, A, B, prec); acb_mat_swap_entrywise(T, C); acb_mat_clear(T); return; } if (br == 1) { for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { arf_complex_mul( arb_midref(acb_realref(acb_mat_entry(C, i, j))), arb_midref(acb_imagref(acb_mat_entry(C, i, j))), arb_midref(acb_realref(acb_mat_entry(A, i, 0))), arb_midref(acb_imagref(acb_mat_entry(A, i, 0))), arb_midref(acb_realref(acb_mat_entry(B, 0, j))), arb_midref(acb_imagref(acb_mat_entry(B, 0, j))), prec, ARB_RND); } } } else { acb_ptr tmp; TMP_INIT; TMP_START; tmp = TMP_ALLOC(sizeof(acb_struct) * br * bc); for (i = 0; i < br; i++) for (j = 0; j < bc; j++) tmp[j * br + i] = *acb_mat_entry(B, i, j); for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { acb_approx_dot(acb_mat_entry(C, i, j), NULL, 0, A->rows[i], 1, tmp + j * br, 1, br, prec); } } TMP_END; } } void acb_mat_approx_mul(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec) { slong cutoff; /* todo: detect small-integer matrices */ if (prec <= 2 * FLINT_BITS) cutoff = 120; else if (prec <= 16 * FLINT_BITS) cutoff = 60; else cutoff = 40; if (acb_mat_nrows(A) <= cutoff || acb_mat_ncols(A) <= cutoff || acb_mat_ncols(B) <= cutoff) { acb_mat_approx_mul_classical(C, A, B, prec); } else { if (acb_mat_is_exact(A) && acb_mat_is_exact(B)) { acb_mat_mul(C, A, B, prec); } else { acb_mat_t AM, BM; if (acb_mat_is_exact(A)) { acb_mat_init(BM, acb_mat_nrows(B), acb_mat_ncols(B)); acb_mat_get_mid(BM, B); acb_mat_mul(C, A, BM, prec); acb_mat_clear(BM); } else if (acb_mat_is_exact(B)) { acb_mat_init(AM, acb_mat_nrows(A), acb_mat_ncols(A)); acb_mat_get_mid(AM, A); acb_mat_mul(C, AM, B, prec); acb_mat_clear(AM); } else { acb_mat_init(BM, acb_mat_nrows(B), acb_mat_ncols(B)); acb_mat_get_mid(BM, B); acb_mat_init(AM, acb_mat_nrows(A), acb_mat_ncols(A)); acb_mat_get_mid(AM, A); acb_mat_mul(C, AM, BM, prec); acb_mat_clear(AM); acb_mat_clear(BM); } } acb_mat_get_mid(C, C); } } arb-2.22.1/acb_mat/approx_solve.c000066400000000000000000000015761417376376500166510ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_approx_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) { int result; slong n, m, *perm; acb_mat_t LU; n = acb_mat_nrows(A); m = acb_mat_ncols(X); if (n == 0 || m == 0) return 1; perm = _perm_init(n); acb_mat_init(LU, n, n); result = acb_mat_approx_lu(perm, LU, A, prec); if (result) acb_mat_approx_solve_lu_precomp(X, perm, LU, B, prec); acb_mat_clear(LU); _perm_clear(perm); return result; } arb-2.22.1/acb_mat/approx_solve_lu_precomp.c000066400000000000000000000024041417376376500210650ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_approx_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t A, const acb_mat_t B, slong prec) { slong i, c, n, m; n = acb_mat_nrows(X); m = acb_mat_ncols(X); if (X == B) { acb_ptr tmp = flint_malloc(sizeof(acb_struct) * n); for (c = 0; c < m; c++) { for (i = 0; i < n; i++) tmp[i] = B->rows[perm[i]][c]; for (i = 0; i < n; i++) X->rows[i][c] = tmp[i]; } flint_free(tmp); } else { for (c = 0; c < m; c++) { for (i = 0; i < n; i++) { acb_set(acb_mat_entry(X, i, c), acb_mat_entry(B, perm[i], c)); } } } acb_mat_get_mid(X, X); acb_mat_approx_solve_tril(X, A, X, 1, prec); acb_mat_approx_solve_triu(X, A, X, 0, prec); } arb-2.22.1/acb_mat/approx_solve_tril.c000066400000000000000000000070101417376376500176700ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void acb_approx_mul(acb_t res, const acb_t x, const acb_t y, slong prec) { arf_complex_mul(arb_midref(acb_realref(res)), arb_midref(acb_imagref(res)), arb_midref(acb_realref(x)), arb_midref(acb_imagref(x)), arb_midref(acb_realref(y)), arb_midref(acb_imagref(y)), prec, ARB_RND); } /* note: the tmp variable t should have zero radius */ static void acb_approx_div(acb_t z, const acb_t x, const acb_t y, acb_t t, slong prec) { arf_set(arb_midref(acb_realref(t)), arb_midref(acb_realref(y))); arf_set(arb_midref(acb_imagref(t)), arb_midref(acb_imagref(y))); acb_inv(t, t, prec); mag_zero(arb_radref(acb_realref(t))); mag_zero(arb_radref(acb_imagref(t))); acb_approx_mul(z, x, t, prec); } void acb_mat_approx_solve_tril_classical(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) { slong i, j, n, m; acb_ptr tmp; acb_t s, t; n = L->r; m = B->c; acb_init(s); acb_init(t); tmp = flint_malloc(sizeof(acb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *acb_mat_entry(X, j, i); for (j = 0; j < n; j++) { acb_approx_dot(s, acb_mat_entry(B, j, i), 1, L->rows[j], 1, tmp, 1, j, prec); if (!unit) acb_approx_div(tmp + j, s, acb_mat_entry(L, j, j), t, prec); else acb_swap(tmp + j, s); } for (j = 0; j < n; j++) *acb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); acb_clear(s); acb_clear(t); } void acb_mat_approx_solve_tril_recursive(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) { acb_mat_t LA, LC, LD, XX, XY, BX, BY, T; slong r, n, m; n = L->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A 0]^ [X] == [A^ 0 ] [X] == [A^ X] [C D] [Y] == [-D^ C A^ D^] [Y] == [D^ (Y - C A^ X)] */ acb_mat_window_init(LA, L, 0, 0, r, r); acb_mat_window_init(LC, L, r, 0, n, r); acb_mat_window_init(LD, L, r, r, n, n); acb_mat_window_init(BX, B, 0, 0, r, m); acb_mat_window_init(BY, B, r, 0, n, m); acb_mat_window_init(XX, X, 0, 0, r, m); acb_mat_window_init(XY, X, r, 0, n, m); acb_mat_approx_solve_tril(XX, LA, BX, unit, prec); /* acb_mat_submul(XY, BY, LC, XX); */ acb_mat_init(T, LC->r, BX->c); acb_mat_approx_mul(T, LC, XX, prec); acb_mat_sub(XY, BY, T, prec); acb_mat_get_mid(XY, XY); acb_mat_clear(T); acb_mat_approx_solve_tril(XY, LD, XY, unit, prec); acb_mat_window_clear(LA); acb_mat_window_clear(LC); acb_mat_window_clear(LD); acb_mat_window_clear(BX); acb_mat_window_clear(BY); acb_mat_window_clear(XX); acb_mat_window_clear(XY); } void acb_mat_approx_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) acb_mat_approx_solve_tril_classical(X, L, B, unit, prec); else acb_mat_approx_solve_tril_recursive(X, L, B, unit, prec); } arb-2.22.1/acb_mat/approx_solve_triu.c000066400000000000000000000067161417376376500177150ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void acb_approx_mul(acb_t res, const acb_t x, const acb_t y, slong prec) { arf_complex_mul(arb_midref(acb_realref(res)), arb_midref(acb_imagref(res)), arb_midref(acb_realref(x)), arb_midref(acb_imagref(x)), arb_midref(acb_realref(y)), arb_midref(acb_imagref(y)), prec, ARB_RND); } /* note: the tmp variable t should have zero radius */ static void acb_approx_div(acb_t z, const acb_t x, const acb_t y, acb_t t, slong prec) { arf_set(arb_midref(acb_realref(t)), arb_midref(acb_realref(y))); arf_set(arb_midref(acb_imagref(t)), arb_midref(acb_imagref(y))); acb_inv(t, t, prec); mag_zero(arb_radref(acb_realref(t))); mag_zero(arb_radref(acb_imagref(t))); acb_approx_mul(z, x, t, prec); } void acb_mat_approx_solve_triu_classical(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) { slong i, j, n, m; acb_ptr tmp; acb_t s, t; n = U->r; m = B->c; acb_init(s); acb_init(t); tmp = flint_malloc(sizeof(acb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *acb_mat_entry(X, j, i); for (j = n - 1; j >= 0; j--) { acb_approx_dot(s, acb_mat_entry(B, j, i), 1, U->rows[j] + j + 1, 1, tmp + j + 1, 1, n - j - 1, prec); if (!unit) acb_approx_div(tmp + j, s, arb_mat_entry(U, j, j), t, prec); else acb_swap(tmp + j, s); } for (j = 0; j < n; j++) *acb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); acb_clear(s); acb_clear(t); } void acb_mat_approx_solve_triu_recursive(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) { acb_mat_t UA, UB, UD, XX, XY, BX, BY, T; slong r, n, m; n = U->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A B]^ [X] == [A^ (X - B D^ Y)] [0 D] [Y] == [ D^ Y ] */ acb_mat_window_init(UA, U, 0, 0, r, r); acb_mat_window_init(UB, U, 0, r, r, n); acb_mat_window_init(UD, U, r, r, n, n); acb_mat_window_init(BX, B, 0, 0, r, m); acb_mat_window_init(BY, B, r, 0, n, m); acb_mat_window_init(XX, X, 0, 0, r, m); acb_mat_window_init(XY, X, r, 0, n, m); acb_mat_approx_solve_triu(XY, UD, BY, unit, prec); acb_mat_init(T, UB->r, XY->c); acb_mat_approx_mul(T, UB, XY, prec); acb_mat_sub(XX, BX, T, prec); acb_mat_get_mid(XX, XX); acb_mat_clear(T); acb_mat_approx_solve_triu(XX, UA, XX, unit, prec); acb_mat_window_clear(UA); acb_mat_window_clear(UB); acb_mat_window_clear(UD); acb_mat_window_clear(BX); acb_mat_window_clear(BY); acb_mat_window_clear(XX); acb_mat_window_clear(XY); } void acb_mat_approx_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) acb_mat_approx_solve_triu_classical(X, U, B, unit, prec); else acb_mat_approx_solve_triu_recursive(X, U, B, unit, prec); } arb-2.22.1/acb_mat/bound_frobenius_norm.c000066400000000000000000000017071417376376500203420ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_bound_frobenius_norm(mag_t b, const acb_mat_t A) { slong i, j, r, c; mag_t t; r = acb_mat_nrows(A); c = acb_mat_ncols(A); mag_zero(b); if (r == 0 || c == 0) return; mag_init(t); for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { acb_srcptr z = acb_mat_entry(A, i, j); arb_get_mag(t, acb_realref(z)); mag_addmul(b, t, t); arb_get_mag(t, acb_imagref(z)); mag_addmul(b, t, t); } } mag_sqrt(b, b); mag_clear(t); } arb-2.22.1/acb_mat/bound_inf_norm.c000066400000000000000000000016201417376376500171140ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_bound_inf_norm(mag_t b, const acb_mat_t A) { slong i, j, r, c; mag_t s, t; r = acb_mat_nrows(A); c = acb_mat_ncols(A); mag_zero(b); if (r == 0 || c == 0) return; mag_init(s); mag_init(t); for (i = 0; i < r; i++) { mag_zero(s); for (j = 0; j < c; j++) { acb_get_mag(t, acb_mat_entry(A, i, j)); mag_add(s, s, t); } mag_max(b, b, s); } mag_clear(s); mag_clear(t); } arb-2.22.1/acb_mat/charpoly.c000066400000000000000000000043731417376376500157470ustar00rootroot00000000000000/* Copyright (C) 2012 Sebastian Pancratz This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void _acb_mat_charpoly(acb_ptr cp, const acb_mat_t mat, slong prec) { const slong n = mat->r; if (n == 0) { acb_one(cp); } else if (n == 1) { acb_neg(cp + 0, acb_mat_entry(mat, 0, 0)); acb_one(cp + 1); } else { slong i, k, t; acb_ptr a, A, s; a = _acb_vec_init(n * n); A = a + (n - 1) * n; _acb_vec_zero(cp, n + 1); acb_neg(cp + 0, acb_mat_entry(mat, 0, 0)); for (t = 1; t < n; t++) { for (i = 0; i <= t; i++) { acb_set(a + 0 * n + i, acb_mat_entry(mat, i, t)); } acb_set(A + 0, acb_mat_entry(mat, t, t)); for (k = 1; k < t; k++) { for (i = 0; i <= t; i++) { s = a + k * n + i; acb_dot(s, NULL, 0, mat->rows[i], 1, a + (k - 1) * n, 1, t + 1, prec); } acb_set(A + k, a + k * n + t); } acb_dot(A + t, NULL, 0, mat->rows[t], 1, a + (t - 1) * n, 1, t + 1, prec); for (k = 0; k <= t; k++) { acb_dot(cp + k, cp + k, 1, A, 1, cp + k - 1, -1, k, prec); acb_sub(cp + k, cp + k, A + k, prec); } } /* Shift all coefficients up by one */ for (i = n; i > 0; i--) acb_swap(cp + i, cp + (i - 1)); acb_one(cp + 0); _acb_poly_reverse(cp, cp, n + 1, n + 1); _acb_vec_clear(a, n * n); } } void acb_mat_charpoly(acb_poly_t cp, const acb_mat_t mat, slong prec) { if (mat->r != mat->c) { flint_printf("Exception (acb_mat_charpoly). Non-square matrix.\n"); flint_abort(); } acb_poly_fit_length(cp, mat->r + 1); _acb_poly_set_length(cp, mat->r + 1); _acb_mat_charpoly(cp->coeffs, mat, prec); } arb-2.22.1/acb_mat/clear.c000066400000000000000000000010701417376376500152030ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_clear(acb_mat_t mat) { if (mat->entries != NULL) { _acb_vec_clear(mat->entries, mat->r * mat->c); flint_free(mat->rows); } } arb-2.22.1/acb_mat/companion.c000066400000000000000000000022521417376376500161030ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void _acb_mat_companion(acb_mat_t A, acb_srcptr poly, slong prec) { slong i, j, n; acb_t c; n = acb_mat_nrows(A); if (n == 0) return; for (i = 0; i < n - 1; i++) for (j = 0; j < n; j++) acb_set_ui(acb_mat_entry(A, i, j), (i + 1) == j); acb_init(c); acb_inv(c, poly + n, prec); acb_neg(c, c); for (j = 0; j < n; j++) acb_mul(acb_mat_entry(A, n - 1, j), poly + j, c, prec); acb_clear(c); } void acb_mat_companion(acb_mat_t A, const acb_poly_t poly, slong prec) { slong n = acb_mat_nrows(A); if (n != acb_poly_degree(poly) || n != acb_mat_ncols(A)) { flint_printf("acb_mat_companion: incompatible dimensions!\n"); flint_abort(); } _acb_mat_companion(A, poly->coeffs, prec); } arb-2.22.1/acb_mat/conjugate.c000066400000000000000000000015141417376376500160770ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_conjugate(acb_mat_t B, const acb_mat_t A) { slong i, j; if ((acb_mat_nrows(B) != acb_mat_nrows(A)) || (acb_mat_ncols(B) != acb_mat_ncols(A))) { flint_printf("acb_mat_conjugate: incompatible dimensions.\n"); flint_abort(); } for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_conj(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j)); } arb-2.22.1/acb_mat/contains.c000066400000000000000000000015071417376376500157400ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_contains(const acb_mat_t mat1, const acb_mat_t mat2) { slong i, j; if ((acb_mat_nrows(mat1) != acb_mat_nrows(mat2)) || (acb_mat_ncols(mat1) != acb_mat_ncols(mat2))) return 0; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) if (!acb_contains(acb_mat_entry(mat1, i, j), acb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/contains_fmpq_mat.c000066400000000000000000000015471417376376500176300ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_contains_fmpq_mat(const acb_mat_t mat1, const fmpq_mat_t mat2) { slong i, j; if ((acb_mat_nrows(mat1) != acb_mat_nrows(mat2)) || (acb_mat_ncols(mat1) != acb_mat_ncols(mat2))) return 0; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) if (!acb_contains_fmpq(acb_mat_entry(mat1, i, j), fmpq_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/contains_fmpz_mat.c000066400000000000000000000015471417376376500176410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_contains_fmpz_mat(const acb_mat_t mat1, const fmpz_mat_t mat2) { slong i, j; if ((acb_mat_nrows(mat1) != acb_mat_nrows(mat2)) || (acb_mat_ncols(mat1) != acb_mat_ncols(mat2))) return 0; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) if (!acb_contains_fmpz(acb_mat_entry(mat1, i, j), fmpz_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/det.c000066400000000000000000000043771417376376500147060ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void _acb_mat_det_cofactor_2x2(acb_t t, const acb_mat_t A, slong prec) { acb_mul (t, acb_mat_entry(A, 0, 0), acb_mat_entry(A, 1, 1), prec); acb_submul(t, acb_mat_entry(A, 0, 1), acb_mat_entry(A, 1, 0), prec); } static void _acb_mat_det_cofactor_3x3(acb_t t, const acb_mat_t A, slong prec) { acb_t a; acb_init(a); acb_mul (a, acb_mat_entry(A, 1, 0), acb_mat_entry(A, 2, 1), prec); acb_submul(a, acb_mat_entry(A, 1, 1), acb_mat_entry(A, 2, 0), prec); acb_mul (t, a, acb_mat_entry(A, 0, 2), prec); acb_mul (a, acb_mat_entry(A, 1, 2), acb_mat_entry(A, 2, 0), prec); acb_submul(a, acb_mat_entry(A, 1, 0), acb_mat_entry(A, 2, 2), prec); acb_addmul(t, a, acb_mat_entry(A, 0, 1), prec); acb_mul (a, acb_mat_entry(A, 1, 1), acb_mat_entry(A, 2, 2), prec); acb_submul(a, acb_mat_entry(A, 1, 2), acb_mat_entry(A, 2, 1), prec); acb_addmul(t, a, acb_mat_entry(A, 0, 0), prec); acb_clear(a); } void acb_mat_det(acb_t det, const acb_mat_t A, slong prec) { slong n; if (!acb_mat_is_square(A)) { flint_printf("acb_mat_det: a square matrix is required!\n"); flint_abort(); } n = acb_mat_nrows(A); if (n == 0) { acb_one(det); } else if (n == 1) { acb_set_round(det, acb_mat_entry(A, 0, 0), prec); } else if (n == 2) { _acb_mat_det_cofactor_2x2(det, A, prec); } else if (!acb_mat_is_finite(A)) { acb_indeterminate(det); } else if (acb_mat_is_tril(A) || acb_mat_is_triu(A)) { acb_mat_diag_prod(det, A, prec); } else if (n == 3) { _acb_mat_det_cofactor_3x3(det, A, prec); /* note: 4x4 performs worse than LU */ } else { if (n <= 14 || prec > 10.0 * n) acb_mat_det_lu(det, A, prec); else acb_mat_det_precond(det, A, prec); } } arb-2.22.1/acb_mat/det_lu.c000066400000000000000000000063741417376376500154050ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" slong acb_mat_gauss_partial(acb_mat_t A, slong prec) { acb_t e; acb_ptr * a; slong j, m, n, r, rank, row, col, sign; m = A->r; n = A->c; a = A->rows; rank = row = col = 0; sign = 1; acb_init(e); while (row < m && col < n) { r = acb_mat_find_pivot_partial(A, row, m, col); if (r == -1) { break; } else if (r != row) { acb_mat_swap_rows(A, NULL, row, r); sign *= -1; } rank++; for (j = row + 1; j < m; j++) { acb_div(e, a[j] + col, a[row] + col, prec); acb_neg(e, e); _acb_vec_scalar_addmul(a[j] + col + 1, a[row] + col + 1, n - col - 1, e, prec); } row++; col++; } acb_clear(e); return rank * sign; } void acb_vec_get_arf_2norm_squared_bound(arf_t s, acb_srcptr vec, slong len, slong prec) { slong i; arf_t t; arf_init(t); arf_zero(s); for (i = 0; i < len; i++) { arb_get_abs_ubound_arf(t, acb_realref(vec + i), prec); arf_addmul(s, t, t, prec, ARF_RND_UP); arb_get_abs_ubound_arf(t, acb_imagref(vec + i), prec); arf_addmul(s, t, t, prec, ARF_RND_UP); } arf_clear(t); } void acb_mat_det_lu_inplace(acb_t det, acb_mat_t A, slong prec) { slong i, n, sign, rank; int is_real; n = acb_mat_nrows(A); rank = acb_mat_gauss_partial(A, prec); sign = (rank < 0) ? -1 : 1; rank = FLINT_ABS(rank); _acb_mat_diag_prod(det, A, 0, rank, prec); acb_mul_si(det, det, sign, prec); /* bound unreduced part using Hadamard's inequality */ if (rank < n) { arf_t t; arf_t d; acb_t e; arf_init(t); arf_init(d); acb_init(e); arf_one(d); is_real = acb_mat_is_real(A); for (i = rank; i < n; i++) { acb_vec_get_arf_2norm_squared_bound(t, A->rows[i] + rank, n - rank, MAG_BITS); arf_mul(d, d, t, MAG_BITS, ARF_RND_UP); } /* now d contains the absolute value of the determinant */ arf_sqrt(d, d, MAG_BITS, ARF_RND_UP); /* multiply by disc with radius d */ if (is_real) { arb_add_error_arf(acb_realref(e), d); } else { arb_add_error_arf(acb_realref(e), d); arb_add_error_arf(acb_imagref(e), d); } acb_mul(det, det, e, prec); acb_clear(e); arf_clear(d); arf_clear(t); } } void acb_mat_det_lu(acb_t det, const acb_mat_t A, slong prec) { slong n; n = acb_mat_nrows(A); if (n == 0) { acb_one(det); } else { acb_mat_t T; acb_mat_init(T, acb_mat_nrows(A), acb_mat_ncols(A)); acb_mat_set(T, A); acb_mat_det_lu_inplace(det, T, prec); acb_mat_clear(T); } } arb-2.22.1/acb_mat/det_precond.c000066400000000000000000000070221417376376500164060ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void _apply_permutation(acb_mat_t A, slong * P, slong n) { acb_ptr * Atmp; slong i; Atmp = flint_malloc(sizeof(acb_ptr) * n); for (i = 0; i < n; i++) Atmp[i] = A->rows[P[i]]; for (i = 0; i < n; i++) A->rows[i] = Atmp[i]; flint_free(Atmp); } /* Enclosure of det(I + eps) using Gershgorin circles. Can be improved. */ void acb_mat_det_one_gershgorin(acb_t det, const acb_mat_t A) { slong n, i, j; acb_t t; mag_t r, e, f; n = acb_mat_nrows(A); acb_init(t); mag_init(r); mag_init(e); mag_init(f); for (i = 0; i < n; i++) { mag_zero(e); for (j = 0; j < n; j++) { if (i == j) { acb_sub_ui(t, acb_mat_entry(A, i, j), 1, MAG_BITS); acb_get_mag(f, t); } else { acb_get_mag(f, acb_mat_entry(A, i, j)); } mag_add(e, e, f); } mag_max(r, r, e); } /* (1 + eps)^n - 1 <= expm1(n*eps) */ mag_mul_ui(r, r, n); mag_expm1(r, r); acb_one(det); mag_set(arb_radref(acb_realref(det)), r); mag_set(arb_radref(acb_imagref(det)), r); acb_clear(t); mag_clear(r); mag_clear(e); mag_clear(f); } void acb_mat_det_precond(acb_t det, const acb_mat_t A, slong prec) { acb_mat_t LU, Linv, Uinv; acb_t detU; slong n; slong *P; n = acb_mat_nrows(A); if (n == 0) { acb_one(det); return; } P = _perm_init(n); acb_mat_init(LU, n, n); if (!acb_mat_approx_lu(P, LU, A, prec)) { /* Fallback. */ acb_mat_det_lu(det, A, prec); } else { acb_mat_init(Linv, n, n); acb_mat_init(Uinv, n, n); acb_init(detU); acb_mat_one(Linv); acb_mat_approx_solve_tril(Linv, LU, Linv, 1, prec); acb_mat_one(Uinv); acb_mat_approx_solve_triu(Uinv, LU, Uinv, 0, prec); acb_mat_diag_prod(detU, Uinv, prec); acb_mat_mul(LU, A, Uinv, prec); _apply_permutation(LU, P, n); acb_mat_mul(Uinv, Linv, LU, prec); acb_mat_det_one_gershgorin(det, Uinv); if (acb_mat_is_real(A)) arb_zero(acb_imagref(det)); if (_perm_parity(P, n)) acb_neg(det, det); acb_div(det, det, detU, prec); if (acb_contains_zero(det)) { mag_t rad1, rad2; /* Run the interval LU algorithm. This can give a much better bound if the Gaussian elimination manages to work through several rows, and it is not that expensive. */ acb_mat_det_lu(detU, A, prec); mag_init(rad1); mag_init(rad2); mag_hypot(rad1, arb_radref(acb_realref(detU)), arb_radref(acb_imagref(detU))); mag_hypot(rad2, arb_radref(acb_realref(det)), arb_radref(acb_imagref(det))); if (mag_cmp(rad1, rad2) < 0) acb_set(det, detU); mag_clear(rad1); mag_clear(rad2); } acb_mat_clear(Linv); acb_mat_clear(Uinv); acb_clear(detU); } _perm_clear(P); acb_mat_clear(LU); } arb-2.22.1/acb_mat/dft.c000066400000000000000000000021651417376376500147000ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" #include "acb_dirichlet.h" void acb_mat_dft(acb_mat_t res, int kind, slong prec) { acb_dirichlet_roots_t roots; acb_t t; acb_t v; slong n, r, c, i, j; r = arb_mat_nrows(res); c = arb_mat_ncols(res); n = FLINT_MIN(r, c); if (n == 0) return; acb_dirichlet_roots_init(roots, n, (r - 1) * c, prec); acb_init(t); acb_init(v); acb_set_ui(v, n); acb_rsqrt(v, v, prec); for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { acb_dirichlet_root(t, roots, i * j, prec); acb_conj(t, t); acb_mul(acb_mat_entry(res, i, j), t, v, prec); } } acb_dirichlet_roots_clear(roots); acb_clear(t); acb_clear(v); } arb-2.22.1/acb_mat/diag_prod.c000066400000000000000000000025031417376376500160470ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void _acb_mat_diag_prod(acb_t res, const acb_mat_t A, slong a, slong b, slong prec) { if (b - a == 0) acb_one(res); else if (b - a == 1) acb_set_round(res, acb_mat_entry(A, a, a), prec); else if (b - a == 2) acb_mul(res, acb_mat_entry(A, a, a), acb_mat_entry(A, a + 1, a + 1), prec); else if (b - a == 3) { acb_mul(res, acb_mat_entry(A, a, a), acb_mat_entry(A, a + 1, a + 1), prec); acb_mul(res, res, acb_mat_entry(A, a + 2, a + 2), prec); } else { acb_t t; acb_init(t); _acb_mat_diag_prod(t, A, a, a + (b - a) / 2, prec); _acb_mat_diag_prod(res, A, a + (b - a) / 2, b, prec); acb_mul(res, res, t, prec); acb_clear(t); } } void acb_mat_diag_prod(acb_t res, const acb_mat_t A, slong prec) { slong m, n; m = acb_mat_nrows(A); n = acb_mat_nrows(A); _acb_mat_diag_prod(res, A, 0, FLINT_MIN(m, n), prec); } arb-2.22.1/acb_mat/eig_enclosure_rump.c000066400000000000000000000271421417376376500200130ustar00rootroot00000000000000/* Copyright 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" /* Follows section 13.4 of Siegfried M. Rump, "Veriï€cation methods: Rigorous results using floating-point arithmetic", Acta Numerica 19 (2010), pp. 287 - 449, implemented as verifyeig() in INTLAB. Cheat sheet for the formulas in Rump's paper. Assuming U = first n-k indices, V = last k indices. U U^T M = selects first n-k rows from M, zeroing rest V V^T M = selects last k rows from M, zeroing rest M U U^T = selects first n-k columns from M, zeroing rest M V V^T = selects last k columns from M, zeroing rest U^T M = selects first n-k rows from M, truncating matrix V^T M = selects last k rows from M, truncating matrix M U = selects first n-k columns from M, truncating matrix M V = selects last k columns from M, truncating matrix X V^T = extends X to n x n matrix (placing X on right) */ static void acb_approx_neg(acb_t res, const acb_t x) { arf_neg(arb_midref(acb_realref(res)), arb_midref(acb_realref(x))); arf_neg(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(x))); } static void acb_approx_sub(acb_t res, const acb_t x, const acb_t y, slong prec) { arf_sub(arb_midref(acb_realref(res)), arb_midref(acb_realref(x)), arb_midref(acb_realref(y)), prec, ARF_RND_DOWN); arf_sub(arb_midref(acb_imagref(res)), arb_midref(acb_imagref(x)), arb_midref(acb_imagref(y)), prec, ARF_RND_DOWN); } /* todo: separate out */ void acb_mat_bound_max_norm(mag_t res, const acb_mat_t A) { mag_t t; slong i, j; mag_init(t); mag_zero(res); for (i = 0; i < acb_mat_nrows(A); i++) { for (j = 0; j < acb_mat_ncols(A); j++) { acb_get_mag(t, acb_mat_entry(A, i, j)); mag_max(res, res, t); } } mag_clear(t); } static void arb_mat_nonnegative_eig_bound(mag_t eps, const arb_mat_t M, slong prec) { /* Cheap, but poor for defective eigenvalues */ arb_mat_bound_frobenius_norm(eps, M); /* Use Perron root bound. TODO: do something direct for k = 2. */ if (1) { acb_mat_t A, R, E; arb_mat_t V, MV; mag_t tm, um, vbound; slong i, j, k; k = arb_mat_nrows(M); acb_mat_init(A, k, k); acb_mat_init(R, k, k); acb_mat_init(E, 1, k); arb_mat_init(V, k, k); arb_mat_init(MV, k, k); mag_init(tm); mag_init(um); mag_init(vbound); acb_mat_set_arb_mat(A, M); /* TODO: could probably lower precision if precision is very high? */ acb_mat_approx_eig_qr(acb_mat_entry(E, 0, 0), NULL, R, A, NULL, 0, prec); for (i = 0; i < k; i++) { for (j = 0; j < k; j++) { acb_get_mag(tm, acb_mat_entry(R, i, j)); arf_set_mag(arb_midref(arb_mat_entry(V, i, j)), tm); } } arb_mat_mul(MV, M, V, MAG_BITS); for (j = 0; j < k; j++) { mag_zero(vbound); for (i = 0; i < k; i++) { arb_get_mag(tm, arb_mat_entry(MV, i, j)); arb_get_mag_lower(um, arb_mat_entry(V, i, j)); mag_div(tm, tm, um); mag_max(vbound, vbound, tm); } mag_min(eps, eps, vbound); } acb_mat_clear(A); acb_mat_clear(R); acb_mat_clear(E); arb_mat_clear(V); arb_mat_clear(MV); mag_clear(tm); mag_clear(um); mag_clear(vbound); } } static void acb_approx_mag(mag_t res, const acb_t x) { mag_t t; mag_init(t); arf_get_mag(res, arb_midref(acb_realref(x))); arf_get_mag(t, arb_midref(acb_imagref(x))); mag_hypot(res, res, t); mag_clear(t); } /* Extract k largest rows to freeze */ static void partition_X_sorted(slong * u, slong * v, const acb_mat_t X, slong prec) { slong i, j, n, k, c; slong * row_idx; mag_ptr row_mag; mag_t t; n = acb_mat_nrows(X); k = acb_mat_ncols(X); row_mag = _mag_vec_init(n); row_idx = flint_malloc(sizeof(slong) * n); mag_init(t); for (i = 0; i < n; i++) { row_idx[i] = i; for (j = 0; j < k; j++) { acb_approx_mag(t, acb_mat_entry(X, i, j)); mag_add(row_mag + i, row_mag + i, t); } } /* Bubble sort... */ for (i = 0; i < n - 1; i++) { for (j = 0; j < n - i - 1; j++) { if (mag_cmp(row_mag + j, row_mag + j + 1) > 0) { mag_swap(row_mag + j, row_mag + j + 1); c = row_idx[j]; row_idx[j] = row_idx[j + 1]; row_idx[j + 1] = c; } } } /* Not frozen rows of the approximation. */ for (i = 0; i < n - k; i++) u[i] = row_idx[i]; /* Frozen rows of the approximation. */ for (i = 0; i < k; i++) v[i] = row_idx[n - k + i]; _mag_vec_clear(row_mag, n); flint_free(row_idx); mag_clear(t); } static void partition_X_trivial(slong * u, slong * v, const acb_mat_t X, slong prec) { slong n, k, i; n = acb_mat_nrows(X); k = acb_mat_ncols(X); /* Not frozen rows of the approximation. */ for (i = 0; i < n - k; i++) u[i] = i; /* Frozen rows of the approximation. */ for (i = 0; i < k; i++) v[i] = n - k + i; } void acb_mat_eig_enclosure_rump(acb_t lambda, acb_mat_t J, acb_mat_t X, const acb_mat_t A, const acb_t lambda_approx, const acb_mat_t X_approx, slong prec) { slong n, k, i, j, iter, maxiter; slong *u, *v; acb_mat_t R, I, T, Y, Y0, UY, VY, Yeps; mag_t eps; n = acb_mat_nrows(A); k = acb_mat_ncols(X_approx); if (k < 1 || k > n || n != acb_mat_nrows(X_approx) || n != acb_mat_ncols(A)) { flint_printf("bad matrix dimensions in acb_mat_eig_enclosure_rump\n"); flint_abort(); } /* Not frozen rows of the approximation. */ u = flint_malloc(sizeof(slong) * (n - k)); /* Frozen rows of the approximation. */ v = flint_malloc(sizeof(slong) * k); if (k == 1) partition_X_sorted(u, v, X_approx, prec); else partition_X_trivial(u, v, X_approx, prec); mag_init(eps); acb_mat_init(R, n, n); acb_mat_init(UY, n, k); acb_mat_init(VY, k, k); acb_mat_init(T, n, n); acb_mat_init(Y, n, k); acb_mat_init(Y0, n, k); acb_mat_init(Yeps, n, k); /* Preconditioner: R ~= ((A - lambda_approx I) U U^T - X_approx V^T)^(-1) */ acb_mat_get_mid(R, A); for (i = 0; i < n; i++) acb_approx_sub(acb_mat_entry(R, i, i), acb_mat_entry(R, i, i), lambda_approx, prec); for (i = 0; i < n; i++) for (j = 0; j < k; j++) acb_approx_neg(acb_mat_entry(R, i, v[j]), acb_mat_entry(X_approx, i, j)); acb_mat_init(I, n, n); acb_mat_one(I); acb_mat_approx_solve(R, R, I, prec); acb_mat_clear(I); /* T = I - R * ((A - lambda_approx I) U U^T - X_approx V^T) */ /* Y = Y_0 = -R * ((A - lambda_approx I) X_approx) */ acb_mat_set(T, A); for (i = 0; i < n; i++) acb_sub(acb_mat_entry(T, i, i), acb_mat_entry(T, i, i), lambda_approx, prec); acb_mat_mul(Y0, T, X_approx, prec); acb_mat_mul(Y0, R, Y0, prec); acb_mat_neg(Y0, Y0); acb_mat_set(Y, Y0); for (i = 0; i < n; i++) for (j = 0; j < k; j++) acb_neg(acb_mat_entry(T, i, v[j]), acb_mat_entry(X_approx, i, j)); acb_mat_mul(T, R, T, prec); acb_mat_neg(T, T); for (i = 0; i < n; i++) acb_add_ui(acb_mat_entry(T, i, i), acb_mat_entry(T, i, i), 1, prec); /* Iteration with epsilon-inflation */ /* Y represents the error with respect to lambda_approx and X_approx */ /* TODO: what number of iterations is actually reasonable? */ /* TODO: what size of epsilon is actually reasonable? */ maxiter = 5 + FLINT_BIT_COUNT(prec); for (iter = 0; iter < maxiter; iter++) { /* Inflate Y. TODO: make it elementwise? */ acb_mat_bound_max_norm(eps, Y); if (mag_is_zero(eps)) mag_set_ui_2exp_si(eps, 1, -20 * prec); mag_mul_2exp_si(eps, eps, -3 + 2 * iter); /* if (iter > 3) mag_mul_2exp_si(eps, eps, (prec / 2) * (iter - 3) / (maxiter - 3)); */ acb_mat_add_error_mag(Y, eps); acb_mat_set(Yeps, Y); /* Y = Y0 + T Y + R ((U U^T Y) V^T Y) */ acb_mat_zero(UY); acb_mat_zero(VY); /* U U^T Y -- zero the rows at indices v. */ acb_mat_set(UY, Y); for (i = 0; i < k; i++) for (j = 0; j < k; j++) acb_zero(acb_mat_entry(UY, v[i], j)); /* V^T Y -- extract rows at indices v */ for (i = 0; i < k; i++) for (j = 0; j < k; j++) acb_set(acb_mat_entry(VY, i, j), acb_mat_entry(Y, v[i], j)); acb_mat_mul(UY, UY, VY, prec); acb_mat_mul(UY, R, UY, prec); acb_mat_mul(Y, T, Y, prec); acb_mat_add(Y, Y, UY, prec); acb_mat_add(Y, Y, Y0, prec); if (acb_mat_contains(Yeps, Y)) { acb_get_mid(lambda, lambda_approx); if (J != NULL) { /* J = lambda_approx I_k + V^T Y */ for (i = 0; i < k; i++) for (j = 0; j < k; j++) acb_set(acb_mat_entry(J, i, j), acb_mat_entry(Y, v[i], j)); for (i = 0; i < k; i++) acb_add(acb_mat_entry(J, i, i), acb_mat_entry(J, i, i), lambda, prec); } /* The correction for the frozen rows corresponds to the eigenvalue. */ if (k == 1) { /* Just one eigenvalue. */ acb_get_mag(eps, acb_mat_entry(Y, v[0], 0)); } else { /* Inclusion of eigenvalues of lambda_approx I_k + V^T Y. */ arb_mat_t M; arb_mat_init(M, k, k); /* Extract rows of Y corresponding to the eigenvalue correction. */ for (i = 0; i < k; i++) { for (j = 0; j < k; j++) { acb_get_mag(eps, acb_mat_entry(Y, v[i], j)); arf_set_mag(arb_midref(arb_mat_entry(M, i, j)), eps); } } arb_mat_nonnegative_eig_bound(eps, M, prec); arb_mat_clear(M); } /* Error bound for eigenvalues. */ acb_add_error_mag(lambda, eps); acb_mat_get_mid(X, X_approx); /* Error bounds for eigenvectors. */ /* Update the not frozen rows of the eigenvectors. */ for (i = 0; i < n - k; i++) { for (j = 0; j < k; j++) acb_add(acb_mat_entry(X, u[i], j), acb_mat_entry(X, u[i], j), acb_mat_entry(Y, u[i], j), prec); } goto cleanup; } } /* We failed to find an enclosure. */ acb_indeterminate(lambda); acb_mat_indeterminate(X); if (J != NULL) acb_mat_indeterminate(J); cleanup: acb_mat_clear(R); acb_mat_clear(T); acb_mat_clear(Y); acb_mat_clear(Y0); acb_mat_clear(Yeps); acb_mat_clear(UY); acb_mat_clear(VY); mag_clear(eps); flint_free(u); flint_free(v); } arb-2.22.1/acb_mat/eig_global_enclosure.c000066400000000000000000000030511417376376500202610ustar00rootroot00000000000000/* Copyright 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_eig_global_enclosure(mag_t eps, const acb_mat_t A, acb_srcptr E, const acb_mat_t R, slong prec) { acb_mat_t Y, R1, R2; slong i, j, n; mag_t r1, r2; n = acb_mat_nrows(A); acb_mat_init(Y, n, n); acb_mat_init(R1, n, n); acb_mat_init(R2, n, n); mag_init(r1); mag_init(r2); /* Y ~= inv(R) */ acb_mat_one(R1); acb_mat_approx_solve(Y, R, R1, prec); /* R2 = Y*R - I */ acb_mat_mul(R2, Y, R, prec); for (i = 0; i < n; i++) acb_sub_ui(acb_mat_entry(R2, i, i), acb_mat_entry(R2, i, i), 1, prec); acb_mat_bound_inf_norm(r2, R2); if (mag_cmp_2exp_si(r2, 0) < 0) { /* R1 = Y*(AR - RD) */ acb_mat_mul(R2, A, R, prec); for (i = 0; i < n; i++) for (j = 0; j < n; j++) acb_submul(acb_mat_entry(R2, i, j), acb_mat_entry(R, i, j), E + j, prec); acb_mat_mul(R1, Y, R2, prec); acb_mat_bound_inf_norm(r1, R1); mag_geom_series(r2, r2, 0); mag_mul(eps, r1, r2); } else { mag_inf(eps); } acb_mat_clear(R1); acb_mat_clear(R2); acb_mat_clear(Y); mag_clear(r1); mag_clear(r2); } arb-2.22.1/acb_mat/eig_multiple.c000066400000000000000000000015661417376376500166060ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_eig_multiple(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) { slong n; acb_ptr F; int success; n = arb_mat_nrows(A); F = _acb_vec_init(n); success = acb_mat_eig_simple_vdhoeven_mourrain(F, NULL, NULL, A, E_approx, R_approx, prec); if (!success) success = acb_mat_eig_multiple_rump(F, A, E_approx, R_approx, prec); _acb_vec_set(E, F, n); _acb_vec_clear(F, n); return success; } arb-2.22.1/acb_mat/eig_multiple_rump.c000066400000000000000000000104371417376376500176460ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void acb_approx_mag(mag_t res, const acb_t x) { mag_t t; mag_init(t); arf_get_mag(res, arb_midref(acb_realref(x))); arf_get_mag(t, arb_midref(acb_imagref(x))); mag_hypot(res, res, t); mag_clear(t); } static int close(const acb_t x, const acb_t y, const mag_t eps) { arf_t t; mag_t a, b; int result; mag_init(a); mag_init(b); arf_init(t); arf_sub(t, arb_midref(acb_realref(x)), arb_midref(acb_realref(y)), MAG_BITS, ARF_RND_UP); arf_get_mag(a, t); arf_sub(t, arb_midref(acb_imagref(x)), arb_midref(acb_imagref(y)), MAG_BITS, ARF_RND_UP); arf_get_mag(b, t); mag_hypot(a, a, b); result = (mag_cmp(a, eps) <= 0); mag_clear(a); mag_clear(b); arf_clear(t); return result; } int acb_mat_eig_multiple_rump(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) { slong c, i, j, k, n; acb_mat_t X; acb_ptr F; int result; slong iter; mag_t escale, eps, tm, um; slong ** cluster; slong * cluster_size; slong num_clusters; n = acb_mat_nrows(A); if (n == 0) return 1; cluster = flint_malloc(sizeof(slong *) * n); for (i = 0; i < n; i++) cluster[i] = flint_malloc(sizeof(slong) * n); cluster_size = flint_malloc(sizeof(slong) * n); mag_init(eps); mag_init(escale); mag_init(tm); mag_init(um); mag_zero(escale); for (i = 0; i < n; i++) { acb_approx_mag(tm, E_approx + i); mag_max(escale, escale, tm); } /* todo: when num_clusters = 1, could use fallback global enclosure */ /* todo: initial clustering could be allowed to be zero */ /* M 2^(-0.75p), M 2^(-0.5p), M 2^(-0.25p), ... */ for (iter = 0; iter < 2; iter++) { mag_mul_2exp_si(eps, escale, -prec + (iter + 1) * prec/4); /* Group the eigenvalue approximations. */ num_clusters = 0; for (i = 0; i < n; i++) { int new_cluster = 1; for (j = 0; j < num_clusters && new_cluster; j++) { if (close(E_approx + i, E_approx + cluster[j][0], eps)) { cluster[j][cluster_size[j]] = i; cluster_size[j]++; new_cluster = 0; } } if (new_cluster) { cluster[num_clusters][0] = i; cluster_size[num_clusters] = 1; num_clusters++; } } result = 1; F = _acb_vec_init(num_clusters); for (c = 0; c < num_clusters && result; c++) { k = cluster_size[c]; acb_mat_init(X, n, k); for (i = 0; i < n; i++) for (j = 0; j < k; j++) acb_set(acb_mat_entry(X, i, j), acb_mat_entry(R_approx, i, cluster[c][j])); acb_mat_eig_enclosure_rump(F + c, NULL, X, A, E_approx + cluster[c][0], X, prec); if (!acb_is_finite(F + c)) result = 0; acb_mat_clear(X); } for (i = 0; i < num_clusters; i++) { for (j = i + 1; j < num_clusters; j++) { if (acb_overlaps(F + i, F + j)) result = 0; } } if (result) { i = 0; for (c = 0; c < num_clusters; c++) { for (j = 0; j < cluster_size[c]; j++) { acb_set(E + i, F + c); i++; } } } _acb_vec_clear(F, num_clusters); if (result) break; } if (!result) _acb_vec_indeterminate(E, n); for (i = 0; i < n; i++) flint_free(cluster[i]); flint_free(cluster); flint_free(cluster_size); mag_clear(eps); mag_clear(escale); mag_clear(tm); mag_clear(um); return result; } arb-2.22.1/acb_mat/eig_simple.c000066400000000000000000000011731417376376500162360ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_eig_simple(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) { return acb_mat_eig_simple_vdhoeven_mourrain(E, L, R, A, E_approx, R_approx, prec); } arb-2.22.1/acb_mat/eig_simple_rump.c000066400000000000000000000035121417376376500173000ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_eig_simple_rump(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) { slong i, j, n; acb_mat_t X, R2; int result; n = acb_mat_nrows(A); if (n == 0) return 1; if (n == 1) { acb_set_round(E, acb_mat_entry(A, 0, 0), prec); if (L != NULL) acb_one(acb_mat_entry(L, 0, 0)); if (R != NULL) acb_one(acb_mat_entry(R, 0, 0)); return 1; } acb_mat_init(X, n, 1); acb_mat_init(R2, n, n); result = 1; for (i = 0; i < n && result; i++) { for (j = 0; j < n; j++) acb_set(acb_mat_entry(X, j, 0), acb_mat_entry(R_approx, j, i)); acb_mat_eig_enclosure_rump(E + i, NULL, X, A, E_approx + i, X, prec); if (!acb_is_finite(E + i)) result = 0; for (j = 0; j < i; j++) if (acb_overlaps(E + i, E + j)) result = 0; for (j = 0; j < n; j++) acb_set(acb_mat_entry(R2, j, i), acb_mat_entry(X, j, 0)); } if (R != NULL) { if (result) acb_mat_set(R, R2); else acb_mat_indeterminate(R); } if (L != NULL) { if (!result || !acb_mat_inv(L, R2, prec)) acb_mat_indeterminate(L); } if (!result) _acb_vec_indeterminate(E, n); acb_mat_clear(X); acb_mat_clear(R2); return result; } arb-2.22.1/acb_mat/eig_simple_vdhoeven_mourrain.c000066400000000000000000000135011417376376500220460ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" /* todo: move out */ void acb_mat_inf_norm(arb_t res, const acb_mat_t A, slong prec) { slong i, j, m, n; arb_t s, t; m = acb_mat_nrows(A); n = acb_mat_nrows(A); if (m == 0 || n == 0) { arb_zero(res); return; } arb_init(s); arb_init(t); arb_zero(res); for (i = 0; i < m; i++) { acb_abs(s, acb_mat_entry(A, i, 0), prec); for (j = 1; j < n; j++) { acb_abs(t, acb_mat_entry(A, i, j), prec); arb_add(s, s, t, prec); } arb_max(res, res, s, prec); } arb_clear(s); arb_clear(t); } static void diagonal_certify(arb_t epsilon, arb_t eta1, arb_t eta2, const acb_mat_t D, const acb_mat_t H, slong prec) { arb_t mu, sigma, alpha, t, u, v; acb_t d; slong i, j, n; arb_init(mu); arb_init(sigma); arb_init(alpha); arb_init(t); arb_init(u); arb_init(v); acb_init(d); n = acb_mat_nrows(D); /* D = diagonal matrix; H = off diagonal matrix */ /* mu = ||D|| */ acb_mat_inf_norm(mu, D, prec); /* sigma = sigma(D) = separation number */ arb_pos_inf(sigma); for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { acb_sub(d, acb_mat_entry(D, i, i), acb_mat_entry(D, j, j), prec); acb_abs(t, d, prec); arb_min(sigma, sigma, t, prec); } } /* eta1 = ||Delta(H)|| Delta = diagonal projection */ arb_zero(eta1); /* eta2 = ||Omega(H)|| Omega = off-diagonal projection */ acb_mat_inf_norm(eta2, H, prec); /* alpha = min(sigma / (6 mu), 1/4) */ arb_div(t, sigma, mu, prec); arb_div_ui(t, t, 6, prec); arb_set_d(u, 0.25); arb_min(alpha, t, u, prec); arb_add(t, eta1, eta2, prec); arb_mul(u, alpha, mu, prec); arb_mul_2exp_si(u, u, -3); arb_mul(v, alpha, sigma, prec); arb_mul_2exp_si(v, v, -3); if (arb_le(t, u) && arb_le(eta2, v)) { arb_div(epsilon, eta2, sigma, prec); arb_mul_ui(epsilon, epsilon, 3, prec); } else { arb_indeterminate(epsilon); } arb_clear(mu); arb_clear(sigma); arb_clear(alpha); arb_clear(t); arb_clear(u); arb_clear(v); acb_clear(d); } int acb_mat_eig_simple_vdhoeven_mourrain(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) { acb_mat_t D, T, AT; int result; slong i, j, n; result = 0; n = acb_mat_nrows(A); if (n == 0) return 1; if (n == 1) { acb_set_round(E, acb_mat_entry(A, 0, 0), prec); if (L != NULL) acb_one(acb_mat_entry(L, 0, 0)); if (R != NULL) acb_one(acb_mat_entry(R, 0, 0)); return 1; } acb_mat_init(D, n, n); acb_mat_init(T, n, n); acb_mat_init(AT, n, n); /* T D = A T */ acb_mat_get_mid(T, R_approx); acb_mat_mul(AT, A, T, prec); if (acb_mat_solve(D, T, AT, prec)) { acb_mat_t DD, DH; arb_t epsilon, eta1, eta2; arb_init(epsilon); arb_init(eta1); arb_init(eta2); acb_mat_init(DD, n, n); acb_mat_init(DH, n, n); for (i = 0; i < n; i++) acb_set(acb_mat_entry(DD, i, i), acb_mat_entry(D, i, i)); for (i = 0; i < n; i++) for (j = 0; j < n; j++) if (i != j) acb_set(acb_mat_entry(DH, i, j), acb_mat_entry(D, i, j)); diagonal_certify(epsilon, eta1, eta2, DD, DH, 2 * MAG_BITS); if (arb_is_finite(epsilon)) { for (i = 0; i < n; i++) { /* note: paper actually uses D_c which would be better? */ acb_set(E + i, acb_mat_entry(D, i, i)); arb_add_error(acb_realref(E + i), eta2); arb_add_error(acb_imagref(E + i), eta2); } result = 1; /* unlikely */ for (i = 0; i < n; i++) for (j = i + 1; j < n; j++) if (acb_overlaps(E + i, E + j)) result = 0; if (result && (R != NULL || L != NULL)) { mag_t ep, em; mag_init(ep); mag_init(em); arb_get_mag(ep, epsilon); acb_mat_zero(D); acb_mat_add_error_mag(D, ep); acb_mat_mul(D, T, D, MAG_BITS); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { acb_get_mag(ep, acb_mat_entry(D, i, j)); acb_add_error_mag(acb_mat_entry(T, i, j), ep); } } if (R != NULL) acb_mat_set(R, T); if (L != NULL) { if (!acb_mat_inv(L, T, prec)) acb_mat_indeterminate(L); } mag_clear(ep); mag_clear(em); } } acb_mat_clear(DD); acb_mat_clear(DH); arb_clear(epsilon); arb_clear(eta1); arb_clear(eta2); } if (!result) { for (i = 0; i < n; i++) acb_indeterminate(E + i); if (L != NULL) acb_mat_indeterminate(L); if (R != NULL) acb_mat_indeterminate(R); } acb_mat_clear(D); acb_mat_clear(T); acb_mat_clear(AT); return result; } arb-2.22.1/acb_mat/eq.c000066400000000000000000000015071417376376500145270ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_eq(const acb_mat_t mat1, const acb_mat_t mat2) { slong i, j; if ((acb_mat_nrows(mat1) != acb_mat_nrows(mat2)) || (acb_mat_ncols(mat1) != acb_mat_ncols(mat2))) return 0; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) if (!acb_eq(acb_mat_entry(mat1, i, j), acb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/equal.c000066400000000000000000000015211417376376500152250ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_equal(const acb_mat_t mat1, const acb_mat_t mat2) { slong i, j; if ((acb_mat_nrows(mat1) != acb_mat_nrows(mat2)) || (acb_mat_ncols(mat1) != acb_mat_ncols(mat2))) return 0; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) if (!acb_equal(acb_mat_entry(mat1, i, j), acb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/exp.c000066400000000000000000000114711417376376500147170ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "acb_mat.h" #include "bool_mat.h" slong _arb_mat_exp_choose_N(const mag_t norm, slong prec); static slong _acb_mat_count_is_zero(const acb_mat_t A) { slong nz, i, j; for (nz = 0, i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) nz += acb_is_zero(acb_mat_entry(A, i, j)); return nz; } static void _acb_mat_exp_diagonal(acb_mat_t B, const acb_mat_t A, slong prec) { slong n, i; n = acb_mat_nrows(A); if (B != A) { acb_mat_zero(B); } for (i = 0; i < n; i++) { acb_exp(acb_mat_entry(B, i, i), acb_mat_entry(A, i, i), prec); } } void acb_mat_exp(acb_mat_t B, const acb_mat_t A, slong prec) { slong i, j, dim, nz; bool_mat_t S; slong nildegree; if (!acb_mat_is_square(A)) { flint_printf("acb_mat_exp: a square matrix is required!\n"); flint_abort(); } if (acb_mat_is_empty(A)) return; dim = acb_mat_nrows(A); if (dim == 1) { acb_exp(acb_mat_entry(B, 0, 0), acb_mat_entry(A, 0, 0), prec); return; } if (acb_mat_is_real(A)) { arb_mat_t R; arb_mat_init(R, dim, dim); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) arb_set(arb_mat_entry(R, i, j), acb_realref(acb_mat_entry(A, i, j))); arb_mat_exp(R, R, prec); acb_mat_set_arb_mat(B, R); arb_mat_clear(R); return; } nz = _acb_mat_count_is_zero(A); if (nz == dim * dim) { acb_mat_one(B); return; } bool_mat_init(S, dim, dim); if (nz == 0) { nildegree = -1; bool_mat_complement(S, S); } else { for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) bool_mat_set_entry(S, i, j, !acb_is_zero(acb_mat_entry(A, i, j))); if (bool_mat_is_diagonal(S)) { _acb_mat_exp_diagonal(B, A, prec); bool_mat_clear(S); return; } else { nildegree = bool_mat_nilpotency_degree(S); } } /* evaluate using scaling and squaring of truncated taylor series */ { slong wp, N, q, r; mag_t norm, err; acb_mat_t T; wp = prec + 3 * FLINT_BIT_COUNT(prec); mag_init(norm); mag_init(err); acb_mat_init(T, dim, dim); acb_mat_bound_inf_norm(norm, A); q = pow(wp, 0.25); /* wanted magnitude */ if (mag_cmp_2exp_si(norm, 2 * wp) > 0) /* too big */ r = 2 * wp; else if (mag_cmp_2exp_si(norm, -q) < 0) /* tiny, no need to reduce */ r = 0; else r = FLINT_MAX(0, q + MAG_EXP(norm)); /* reduce to magnitude 2^(-r) */ acb_mat_scalar_mul_2exp_si(T, A, -r); mag_mul_2exp_si(norm, norm, -r); N = _arb_mat_exp_choose_N(norm, wp); /* if positive, nildegree is an upper bound on nilpotency degree */ if (nildegree > 0) N = FLINT_MIN(N, nildegree); mag_exp_tail(err, norm, N); acb_mat_exp_taylor_sum(B, T, N, wp); /* add truncation error to entries for which it is not ruled out */ if (nz == 0) { for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) acb_add_error_mag(acb_mat_entry(B, i, j), err); } else if (nildegree < 0 || N < nildegree) { slong w; fmpz_mat_t W; fmpz_mat_init(W, dim, dim); w = bool_mat_all_pairs_longest_walk(W, S); if (w + 1 != nildegree) flint_abort(); /* assert */ for (i = 0; i < dim; i++) { for (j = 0; j < dim; j++) { slong d = fmpz_get_si(fmpz_mat_entry(W, i, j)) + 1; if (d < 0 || N < d) { acb_add_error_mag(acb_mat_entry(B, i, j), err); } } } fmpz_mat_clear(W); } for (i = 0; i < r; i++) { acb_mat_sqr(T, B, wp); acb_mat_swap(T, B); } for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) acb_set_round(acb_mat_entry(B, i, j), acb_mat_entry(B, i, j), prec); mag_clear(norm); mag_clear(err); acb_mat_clear(T); } bool_mat_clear(S); } arb-2.22.1/acb_mat/exp_taylor_sum.c000066400000000000000000000053541417376376500172000ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_exp_taylor_sum(acb_mat_t S, const acb_mat_t A, slong N, slong prec) { if (A == S) { acb_mat_t t; acb_mat_init(t, acb_mat_nrows(A), acb_mat_nrows(A)); acb_mat_set(t, A); acb_mat_exp_taylor_sum(S, t, N, prec); acb_mat_clear(t); } else if (N <= 0) { acb_mat_zero(S); } else if (N == 1) { acb_mat_one(S); } else if (N == 2) { acb_mat_one(S); acb_mat_add(S, S, A, prec); } else if (N == 3) { acb_mat_t T; acb_mat_init(T, acb_mat_nrows(A), acb_mat_nrows(A)); acb_mat_sqr(T, A, prec); acb_mat_scalar_mul_2exp_si(T, T, -1); acb_mat_add(S, A, T, prec); acb_mat_one(T); acb_mat_add(S, S, T, prec); acb_mat_clear(T); } else { slong i, lo, hi, m, w, dim; acb_mat_struct * pows; acb_mat_t T, U; fmpz_t c, f; dim = acb_mat_nrows(A); m = n_sqrt(N); w = (N + m - 1) / m; fmpz_init(c); fmpz_init(f); pows = flint_malloc(sizeof(acb_mat_t) * (m + 1)); acb_mat_init(T, dim, dim); acb_mat_init(U, dim, dim); for (i = 0; i <= m; i++) { acb_mat_init(pows + i, dim, dim); if (i == 0) acb_mat_one(pows + i); else if (i == 1) acb_mat_set(pows + i, A); else acb_mat_mul(pows + i, pows + i - 1, A, prec); } acb_mat_zero(S); fmpz_one(f); for (i = w - 1; i >= 0; i--) { lo = i * m; hi = FLINT_MIN(N - 1, lo + m - 1); acb_mat_zero(T); fmpz_one(c); while (hi >= lo) { acb_mat_scalar_addmul_fmpz(T, pows + hi - lo, c, prec); if (hi != 0) fmpz_mul_ui(c, c, hi); hi--; } acb_mat_mul(U, pows + m, S, prec); acb_mat_scalar_mul_fmpz(S, T, f, prec); acb_mat_add(S, S, U, prec); fmpz_mul(f, f, c); } acb_mat_scalar_div_fmpz(S, S, f, prec); fmpz_clear(c); fmpz_clear(f); for (i = 0; i <= m; i++) acb_mat_clear(pows + i); flint_free(pows); acb_mat_clear(T); acb_mat_clear(U); } } arb-2.22.1/acb_mat/find_pivot_partial.c000066400000000000000000000027501417376376500200000ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_cmpabs_approx(const acb_t x, const acb_t y) { const arf_struct *xm, *ym; if (arf_cmpabs(arb_midref(acb_realref(x)), arb_midref(acb_imagref(x))) >= 0) xm = arb_midref(acb_realref(x)); else xm = arb_midref(acb_imagref(x)); if (arf_cmpabs(arb_midref(acb_realref(y)), arb_midref(acb_imagref(y))) >= 0) ym = arb_midref(acb_realref(y)); else ym = arb_midref(acb_imagref(y)); return arf_cmpabs(xm, ym); } slong acb_mat_find_pivot_partial(const acb_mat_t mat, slong start_row, slong end_row, slong c) { slong best_row, i; best_row = -1; for (i = start_row; i < end_row; i++) { if (!acb_contains_zero(acb_mat_entry(mat, i, c))) { if (best_row == -1) { best_row = i; } /* todo: should take the radius into account */ else if (acb_cmpabs_approx(acb_mat_entry(mat, i, c), acb_mat_entry(mat, best_row, c)) > 0) { best_row = i; } } } return best_row; } arb-2.22.1/acb_mat/fprintd.c000066400000000000000000000015561417376376500155740ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_fprintd(FILE * file, const acb_mat_t mat, slong digits) { slong i, j; for (i = 0; i < acb_mat_nrows(mat); i++) { flint_fprintf(file, "["); for (j = 0; j < acb_mat_ncols(mat); j++) { acb_fprintd(file, acb_mat_entry(mat, i, j), digits); if (j < acb_mat_ncols(mat) - 1) flint_fprintf(file, ", "); } flint_fprintf(file, "]\n"); } } arb-2.22.1/acb_mat/frobenius_norm.c000066400000000000000000000016301417376376500171460ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_frobenius_norm(arb_t res, const acb_mat_t A, slong prec) { slong i, j, r, c; r = acb_mat_nrows(A); c = acb_mat_ncols(A); arb_zero(res); if (r == 0 || c == 0) return; for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { acb_srcptr z = acb_mat_entry(A, i, j); arb_addmul(res, acb_realref(z), acb_realref(z), prec); arb_addmul(res, acb_imagref(z), acb_imagref(z), prec); } } arb_sqrtpos(res, res, prec); } arb-2.22.1/acb_mat/indeterminate.c000066400000000000000000000011401417376376500167430ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_indeterminate(acb_mat_t A) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) acb_indeterminate(acb_mat_entry(A, i, j)); } arb-2.22.1/acb_mat/init.c000066400000000000000000000014121417376376500150600ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_init(acb_mat_t mat, slong r, slong c) { if (r != 0 && c != 0) { slong i; mat->entries = _acb_vec_init(r * c); mat->rows = (acb_ptr *) flint_malloc(r * sizeof(acb_ptr)); for (i = 0; i < r; i++) mat->rows[i] = mat->entries + i * c; } else mat->entries = NULL; mat->r = r; mat->c = c; } arb-2.22.1/acb_mat/inlines.c000066400000000000000000000006541417376376500155650ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ACB_MAT_INLINES_C #include "acb_mat.h" arb-2.22.1/acb_mat/inv.c000066400000000000000000000013721417376376500147160ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_inv(acb_mat_t X, const acb_mat_t A, slong prec) { if (X == A) { int r; acb_mat_t T; acb_mat_init(T, acb_mat_nrows(A), acb_mat_ncols(A)); r = acb_mat_inv(T, A, prec); acb_mat_swap(T, X); acb_mat_clear(T); return r; } acb_mat_one(X); return acb_mat_solve(X, A, X, prec); } arb-2.22.1/acb_mat/is_exact.c000066400000000000000000000013621417376376500157200ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_is_exact(const acb_mat_t A) { slong i, j; for (i = 0; i < acb_mat_nrows(A); i++) for (j = 0; j < acb_mat_ncols(A); j++) if (!mag_is_zero(arb_radref(acb_realref(acb_mat_entry(A, i, j)))) || !mag_is_zero(arb_radref(acb_imagref(acb_mat_entry(A, i, j))))) return 0; return 1; } arb-2.22.1/acb_mat/is_finite.c000066400000000000000000000012501417376376500160660ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_is_finite(const acb_mat_t A) { slong i, j, n, m; n = acb_mat_nrows(A); m = acb_mat_ncols(A); for (i = 0; i < n; i++) for (j = 0; j < m; j++) if (!acb_is_finite(acb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/is_real.c000066400000000000000000000012171417376376500155360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_is_real(const acb_mat_t mat) { slong i, j; for (i = 0; i < acb_mat_nrows(mat); i++) for (j = 0; j < acb_mat_ncols(mat); j++) if (!acb_is_real(acb_mat_entry(mat, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/is_tril.c000066400000000000000000000012501417376376500155620ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_is_tril(const acb_mat_t A) { slong i, j, n, m; n = acb_mat_nrows(A); m = acb_mat_ncols(A); for (i = 0; i < n; i++) for (j = i + 1; j < m; j++) if (!acb_is_zero(acb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/is_triu.c000066400000000000000000000012621417376376500155760ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_is_triu(const acb_mat_t A) { slong i, j, n, m; n = acb_mat_nrows(A); m = acb_mat_ncols(A); for (i = 1; i < n; i++) for (j = 0; j < FLINT_MIN(i, m); j++) if (!acb_is_zero(acb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/is_zero.c000066400000000000000000000012441417376376500155720ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_is_zero(const acb_mat_t A) { slong i, j, n, m; n = acb_mat_nrows(A); m = acb_mat_ncols(A); for (i = 0; i < n; i++) for (j = 0; j < m; j++) if (!acb_is_zero(acb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/lu.c000066400000000000000000000012071417376376500145370ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_lu(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec) { if (acb_mat_nrows(A) < 8 || acb_mat_ncols(A) < 8) return acb_mat_lu_classical(P, LU, A, prec); else return acb_mat_lu_recursive(P, LU, A, prec); } arb-2.22.1/acb_mat/lu_classical.c000066400000000000000000000027521417376376500165630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_lu_classical(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec) { acb_t d, e; acb_ptr * a; slong i, j, m, n, r, row, col; int result; if (acb_mat_is_empty(A)) return 1; m = acb_mat_nrows(A); n = acb_mat_ncols(A); acb_mat_set(LU, A); a = LU->rows; row = col = 0; for (i = 0; i < m; i++) P[i] = i; acb_init(d); acb_init(e); result = 1; while (row < m && col < n) { r = acb_mat_find_pivot_partial(LU, row, m, col); if (r == -1) { result = 0; break; } else if (r != row) acb_mat_swap_rows(LU, P, row, r); acb_set(d, a[row] + col); for (j = row + 1; j < m; j++) { acb_div(e, a[j] + col, d, prec); acb_neg(e, e); _acb_vec_scalar_addmul(a[j] + col, a[row] + col, n - col, e, prec); acb_zero(a[j] + col); acb_neg(a[j] + row, e); } row++; col++; } acb_clear(d); acb_clear(e); return result; } arb-2.22.1/acb_mat/lu_recursive.c000066400000000000000000000051371417376376500166340ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void _apply_permutation(slong * AP, acb_mat_t A, slong * P, slong n, slong offset) { if (n != 0) { acb_ptr * Atmp; slong * APtmp; slong i; Atmp = flint_malloc(sizeof(acb_ptr) * n); APtmp = flint_malloc(sizeof(slong) * n); for (i = 0; i < n; i++) Atmp[i] = A->rows[P[i] + offset]; for (i = 0; i < n; i++) A->rows[i + offset] = Atmp[i]; for (i = 0; i < n; i++) APtmp[i] = AP[P[i] + offset]; for (i = 0; i < n; i++) AP[i + offset] = APtmp[i]; flint_free(Atmp); flint_free(APtmp); } } int acb_mat_lu_recursive(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec) { slong i, m, n, r1, r2, n1; acb_mat_t A0, A1, A00, A01, A10, A11; slong * P1; m = A->r; n = A->c; if (m <= 1 || n <= 1) { return acb_mat_lu_classical(P, LU, A, prec); } if (LU != A) acb_mat_set(LU, A); n1 = n / 2; for (i = 0; i < m; i++) P[i] = i; P1 = flint_malloc(sizeof(slong) * m); acb_mat_window_init(A0, LU, 0, 0, m, n1); acb_mat_window_init(A1, LU, 0, n1, m, n); r1 = acb_mat_lu(P1, A0, A0, prec); if (!r1) { flint_free(P1); acb_mat_window_clear(A0); acb_mat_window_clear(A1); return 0; } /* r1 = rank of A0 */ r1 = FLINT_MIN(m, n1); _apply_permutation(P, LU, P1, m, 0); acb_mat_window_init(A00, LU, 0, 0, r1, r1); acb_mat_window_init(A10, LU, r1, 0, m, r1); acb_mat_window_init(A01, LU, 0, n1, r1, n); acb_mat_window_init(A11, LU, r1, n1, m, n); acb_mat_solve_tril(A01, A00, A01, 1, prec); { /* acb_mat_submul(A11, A11, A10, A01, prec); */ acb_mat_t T; acb_mat_init(T, A10->r, A01->c); acb_mat_mul(T, A10, A01, prec); acb_mat_sub(A11, A11, T, prec); acb_mat_clear(T); } r2 = acb_mat_lu(P1, A11, A11, prec); if (!r2) r1 = r2 = 0; else _apply_permutation(P, LU, P1, m - r1, r1); flint_free(P1); acb_mat_window_clear(A00); acb_mat_window_clear(A01); acb_mat_window_clear(A10); acb_mat_window_clear(A11); acb_mat_window_clear(A0); acb_mat_window_clear(A1); return r1 && r2; } arb-2.22.1/acb_mat/mul.c000066400000000000000000000040411417376376500147130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static slong acb_mat_bits(const acb_mat_t A) { slong b, t, i, ar, ac; ar = acb_mat_nrows(A); ac = acb_mat_ncols(A); b = 0; for (i = 0; i < ar; i++) { t = _arb_vec_bits((arb_srcptr) A->rows[i], 2 * ac); b = FLINT_MAX(b, t); } return b; } int acb_mat_is_lagom(const acb_mat_t A) { slong i, j, M, N; M = acb_mat_nrows(A); N = acb_mat_ncols(A); for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (!ARB_IS_LAGOM(acb_realref(acb_mat_entry(A, i, j))) || !ARB_IS_LAGOM(acb_imagref(acb_mat_entry(A, i, j)))) return 0; } } return 1; } void acb_mat_mul(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec) { slong ar, ac, br, bc, n, abits, bbits, bits; ar = acb_mat_nrows(A); ac = acb_mat_ncols(A); br = acb_mat_nrows(B); bc = acb_mat_ncols(B); if (ac != br || ar != acb_mat_nrows(C) || bc != acb_mat_ncols(C)) { flint_printf("acb_mat_mul: incompatible dimensions\n"); flint_abort(); } n = FLINT_MIN(ar, ac); n = FLINT_MIN(ac, bc); if (n >= 20) { abits = acb_mat_bits(A); bbits = acb_mat_bits(B); bits = FLINT_MIN(prec, FLINT_MAX(abits, bbits)); if (bits < 8000 && n >= 5 + bits / 64) { acb_mat_mul_reorder(C, A, B, prec); return; } } if (flint_get_num_threads() > 1 && ((double) ar * (double) ac * (double) bc * (double) prec > 100000)) { acb_mat_mul_threaded(C, A, B, prec); } else { acb_mat_mul_classical(C, A, B, prec); } } arb-2.22.1/acb_mat/mul_classical.c000066400000000000000000000045361417376376500167420ustar00rootroot00000000000000/* Copyright (C) 2012, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_mul_classical(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec) { slong ar, ac, br, bc, i, j, k; if (A == B && (acb_mat_nrows(A) <= 2 || (prec >= 1024 && acb_mat_nrows(A) < 8))) { acb_mat_sqr_classical(C, A, prec); return; } ar = acb_mat_nrows(A); ac = acb_mat_ncols(A); br = acb_mat_nrows(B); bc = acb_mat_ncols(B); if (ac != br || ar != acb_mat_nrows(C) || bc != acb_mat_ncols(C)) { flint_printf("acb_mat_mul: incompatible dimensions\n"); flint_abort(); } if (br == 0) { acb_mat_zero(C); return; } if (A == C || B == C) { acb_mat_t T; acb_mat_init(T, ar, bc); acb_mat_mul_classical(T, A, B, prec); acb_mat_swap_entrywise(T, C); acb_mat_clear(T); return; } if (br <= 2) { for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { /* todo: efficient fmma code */ acb_mul(acb_mat_entry(C, i, j), acb_mat_entry(A, i, 0), acb_mat_entry(B, 0, j), prec); for (k = 1; k < br; k++) { acb_addmul(acb_mat_entry(C, i, j), acb_mat_entry(A, i, k), acb_mat_entry(B, k, j), prec); } } } } else { acb_ptr tmp; TMP_INIT; TMP_START; tmp = TMP_ALLOC(sizeof(acb_struct) * br * bc); for (i = 0; i < br; i++) for (j = 0; j < bc; j++) tmp[j * br + i] = *acb_mat_entry(B, i, j); for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { acb_dot(acb_mat_entry(C, i, j), NULL, 0, A->rows[i], 1, tmp + j * br, 1, br, prec); } } TMP_END; } } arb-2.22.1/acb_mat/mul_entrywise.c000066400000000000000000000017141417376376500170300ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_mul_entrywise(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec) { slong i, j; if (acb_mat_nrows(A) != acb_mat_nrows(B) || acb_mat_ncols(A) != acb_mat_ncols(B)) { flint_printf("acb_mat_mul_entrywise: incompatible dimensions\n"); flint_abort(); } for (i = 0; i < acb_mat_nrows(A); i++) { for (j = 0; j < acb_mat_ncols(A); j++) { acb_mul(acb_mat_entry(C, i, j), acb_mat_entry(A, i, j), acb_mat_entry(B, i, j), prec); } } } arb-2.22.1/acb_mat/mul_reorder.c000066400000000000000000000171621417376376500164450ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void copy_re_shallow(arb_mat_t X, const acb_mat_t A) { slong M, N, i, j; M = arb_mat_nrows(X); N = arb_mat_ncols(X); for (i = 0; i < M; i++) for (j = 0; j < N; j++) *arb_mat_entry(X, i, j) = *acb_realref(acb_mat_entry(A, i, j)); } static void copy_im_shallow(arb_mat_t X, const acb_mat_t A) { slong M, N, i, j; M = arb_mat_nrows(X); N = arb_mat_ncols(X); for (i = 0; i < M; i++) for (j = 0; j < N; j++) *arb_mat_entry(X, i, j) = *acb_imagref(acb_mat_entry(A, i, j)); } static void clear_shallow(arb_mat_t X) { slong M, N, i, j; M = arb_mat_nrows(X); N = arb_mat_ncols(X); for (i = 0; i < M; i++) for (j = 0; j < N; j++) arb_init(arb_mat_entry(X, i, j)); } /* todo: squaring optimizations */ void acb_mat_mul_reorder(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec) { arb_mat_t X, Y, Z, W; slong M, N, P; slong i, j; M = acb_mat_nrows(A); N = acb_mat_ncols(A); P = acb_mat_ncols(B); if (acb_mat_is_real(A)) { if (acb_mat_is_real(B)) { arb_mat_init(X, M, N); arb_mat_init(Y, N, P); arb_mat_init(Z, M, P); copy_re_shallow(X, A); copy_re_shallow(Y, B); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_zero(acb_imagref(acb_mat_entry(C, i, j))); if (A == C || B == C) { arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_swap(acb_realref(acb_mat_entry(C, i, j)), acb_mat_entry(Z, i, j)); } else { copy_re_shallow(Z, C); arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) *acb_realref(acb_mat_entry(C, i, j)) = *arb_mat_entry(Z, i, j); clear_shallow(Z); } clear_shallow(X); clear_shallow(Y); arb_mat_clear(X); arb_mat_clear(Y); arb_mat_clear(Z); } else { arb_mat_init(X, M, N); arb_mat_init(Y, N, P); arb_mat_init(Z, M, P); /* (reA*reB, reA*imB) */ copy_re_shallow(X, A); copy_re_shallow(Y, B); if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, M, P); arb_mat_mul(T, X, Y, prec); copy_im_shallow(Y, B); arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_swap(acb_realref(acb_mat_entry(C, i, j)), acb_mat_entry(T, i, j)); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_swap(acb_imagref(acb_mat_entry(C, i, j)), acb_mat_entry(Z, i, j)); arb_mat_clear(T); } else { copy_re_shallow(Z, C); arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) *acb_realref(acb_mat_entry(C, i, j)) = *arb_mat_entry(Z, i, j); copy_im_shallow(Z, C); copy_im_shallow(Y, B); arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) *acb_imagref(acb_mat_entry(C, i, j)) = *arb_mat_entry(Z, i, j); clear_shallow(Z); } clear_shallow(X); clear_shallow(Y); arb_mat_clear(X); arb_mat_clear(Y); arb_mat_clear(Z); } } else if (acb_mat_is_real(B)) { arb_mat_init(X, M, N); arb_mat_init(Y, N, P); arb_mat_init(Z, M, P); /* (reA*reB, imA*reB) */ copy_re_shallow(X, A); copy_re_shallow(Y, B); if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, M, P); arb_mat_mul(T, X, Y, prec); copy_im_shallow(X, A); arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_swap(acb_realref(acb_mat_entry(C, i, j)), acb_mat_entry(T, i, j)); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_swap(acb_imagref(acb_mat_entry(C, i, j)), acb_mat_entry(Z, i, j)); arb_mat_clear(T); } else { copy_re_shallow(Z, C); arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) *acb_realref(acb_mat_entry(C, i, j)) = *arb_mat_entry(Z, i, j); copy_im_shallow(Z, C); copy_im_shallow(X, A); arb_mat_mul(Z, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) *acb_imagref(acb_mat_entry(C, i, j)) = *arb_mat_entry(Z, i, j); clear_shallow(Z); } clear_shallow(X); clear_shallow(Y); arb_mat_clear(X); arb_mat_clear(Y); arb_mat_clear(Z); } else { arb_mat_init(X, M, N); arb_mat_init(Y, N, P); arb_mat_init(Z, M, P); arb_mat_init(W, M, P); copy_re_shallow(X, A); copy_re_shallow(Y, B); arb_mat_mul(Z, X, Y, prec); copy_im_shallow(X, A); copy_im_shallow(Y, B); arb_mat_mul(W, X, Y, prec); if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, M, P); arb_mat_sub(T, Z, W, prec); copy_re_shallow(X, A); arb_mat_mul(Z, X, Y, prec); copy_im_shallow(X, A); copy_re_shallow(Y, B); arb_mat_mul(W, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_swap(acb_realref(acb_mat_entry(C, i, j)), arb_mat_entry(T, i, j)); arb_mat_clear(T); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_add(acb_imagref(acb_mat_entry(C, i, j)), arb_mat_entry(Z, i, j), arb_mat_entry(W, i, j), prec); } else { for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_sub(acb_realref(acb_mat_entry(C, i, j)), arb_mat_entry(Z, i, j), arb_mat_entry(W, i, j), prec); copy_re_shallow(X, A); arb_mat_mul(Z, X, Y, prec); copy_im_shallow(X, A); copy_re_shallow(Y, B); arb_mat_mul(W, X, Y, prec); for (i = 0; i < M; i++) for (j = 0; j < P; j++) arb_add(acb_imagref(acb_mat_entry(C, i, j)), arb_mat_entry(Z, i, j), arb_mat_entry(W, i, j), prec); } clear_shallow(X); clear_shallow(Y); arb_mat_clear(X); arb_mat_clear(Y); arb_mat_clear(Z); arb_mat_clear(W); } } arb-2.22.1/acb_mat/mul_threaded.c000066400000000000000000000057451417376376500165670ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" #include "pthread.h" typedef struct { acb_ptr * C; const acb_ptr * A; const acb_ptr * B; slong ar0; slong ar1; slong bc0; slong bc1; slong br; slong prec; } acb_mat_mul_arg_t; void * _acb_mat_mul_thread(void * arg_ptr) { acb_mat_mul_arg_t arg = *((acb_mat_mul_arg_t *) arg_ptr); slong i, j, br, bc; acb_ptr tmp; TMP_INIT; br = arg.br; bc = arg.bc1 - arg.bc0; TMP_START; tmp = TMP_ALLOC(sizeof(acb_struct) * br * bc); for (i = 0; i < br; i++) for (j = 0; j < bc; j++) tmp[j * br + i] = arg.B[i][arg.bc0 + j]; for (i = arg.ar0; i < arg.ar1; i++) { for (j = arg.bc0; j < arg.bc1; j++) { acb_dot(arg.C[i] + j, NULL, 0, arg.A[i], 1, tmp + (j - arg.bc0) * br, 1, br, arg.prec); } } TMP_END; flint_cleanup(); return NULL; } void acb_mat_mul_threaded(acb_mat_t C, const acb_mat_t A, const acb_mat_t B, slong prec) { slong ar, ac, br, bc, i, num_threads; pthread_t * threads; acb_mat_mul_arg_t * args; ar = acb_mat_nrows(A); ac = acb_mat_ncols(A); br = acb_mat_nrows(B); bc = acb_mat_ncols(B); if (ac != br || ar != acb_mat_nrows(C) || bc != acb_mat_ncols(C)) { flint_printf("acb_mat_mul_threaded: incompatible dimensions\n"); flint_abort(); } if (br == 0) { acb_mat_zero(C); return; } if (A == C || B == C) { acb_mat_t T; acb_mat_init(T, ar, bc); acb_mat_mul_threaded(T, A, B, prec); acb_mat_swap_entrywise(T, C); acb_mat_clear(T); return; } num_threads = flint_get_num_threads(); threads = flint_malloc(sizeof(pthread_t) * num_threads); args = flint_malloc(sizeof(acb_mat_mul_arg_t) * num_threads); for (i = 0; i < num_threads; i++) { args[i].C = C->rows; args[i].A = A->rows; args[i].B = B->rows; if (ar >= bc) { args[i].ar0 = (ar * i) / num_threads; args[i].ar1 = (ar * (i + 1)) / num_threads; args[i].bc0 = 0; args[i].bc1 = bc; } else { args[i].ar0 = 0; args[i].ar1 = ar; args[i].bc0 = (bc * i) / num_threads; args[i].bc1 = (bc * (i + 1)) / num_threads; } args[i].br = br; args[i].prec = prec; pthread_create(&threads[i], NULL, _acb_mat_mul_thread, &args[i]); } for (i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); } flint_free(threads); flint_free(args); } arb-2.22.1/acb_mat/ne.c000066400000000000000000000015061417376376500145230ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_ne(const acb_mat_t mat1, const acb_mat_t mat2) { slong i, j; if ((acb_mat_nrows(mat1) != acb_mat_nrows(mat2)) || (acb_mat_ncols(mat1) != acb_mat_ncols(mat2))) return 1; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) if (acb_ne(acb_mat_entry(mat1, i, j), acb_mat_entry(mat2, i, j))) return 1; return 0; } arb-2.22.1/acb_mat/neg.c000066400000000000000000000012251417376376500146700ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_neg(acb_mat_t dest, const acb_mat_t src) { slong i, j; for (i = 0; i < acb_mat_nrows(src); i++) for (j = 0; j < acb_mat_ncols(src); j++) acb_neg(acb_mat_entry(dest, i, j), acb_mat_entry(src, i, j)); } arb-2.22.1/acb_mat/one.c000066400000000000000000000012651417376376500147040ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_one(acb_mat_t mat) { slong i, j; for (i = 0; i < acb_mat_nrows(mat); i++) for (j = 0; j < acb_mat_ncols(mat); j++) if (i == j) acb_one(acb_mat_entry(mat, i, j)); else acb_zero(acb_mat_entry(mat, i, j)); } arb-2.22.1/acb_mat/ones.c000066400000000000000000000011631417376376500150640ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_ones(acb_mat_t mat) { slong R, C, i, j; R = acb_mat_nrows(mat); C = acb_mat_ncols(mat); for (i = 0; i < R; i++) for (j = 0; j < C; j++) acb_one(acb_mat_entry(mat, i, j)); } arb-2.22.1/acb_mat/overlaps.c000066400000000000000000000015071417376376500157550ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_overlaps(const acb_mat_t mat1, const acb_mat_t mat2) { slong i, j; if ((acb_mat_nrows(mat1) != acb_mat_nrows(mat2)) || (acb_mat_ncols(mat1) != acb_mat_ncols(mat2))) return 0; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) if (!acb_overlaps(acb_mat_entry(mat1, i, j), acb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/acb_mat/pow_ui.c000066400000000000000000000026331417376376500154250ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_pow_ui(acb_mat_t B, const acb_mat_t A, ulong exp, slong prec) { slong d = acb_mat_nrows(A); if (exp <= 2 || d <= 1) { if (exp == 0 || d == 0) { acb_mat_one(B); } else if (d == 1) { acb_pow_ui(acb_mat_entry(B, 0, 0), acb_mat_entry(A, 0, 0), exp, prec); } else if (exp == 1) { acb_mat_set(B, A); } else if (exp == 2) { acb_mat_sqr(B, A, prec); } } else { acb_mat_t T, U; slong i; acb_mat_init(T, d, d); acb_mat_set(T, A); acb_mat_init(U, d, d); for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--) { acb_mat_sqr(U, T, prec); if (exp & (WORD(1) << i)) acb_mat_mul(T, U, A, prec); else acb_mat_swap(T, U); } acb_mat_swap(B, T); acb_mat_clear(T); acb_mat_clear(U); } } arb-2.22.1/acb_mat/randtest.c000066400000000000000000000023201417376376500157400ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_randtest(acb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits) { slong i, j, density; density = n_randint(state, 100); if (n_randint(state, 2)) for (i = 0; i < acb_mat_nrows(mat); i++) for (j = 0; j < acb_mat_ncols(mat); j++) if (n_randint(state, 100) < density) acb_randtest(acb_mat_entry(mat, i, j), state, prec, mag_bits); else acb_zero(acb_mat_entry(mat, i, j)); else for (i = 0; i < acb_mat_nrows(mat); i++) for (j = 0; j < acb_mat_ncols(mat); j++) if (n_randint(state, 100) < density) acb_randtest_precise(acb_mat_entry(mat, i, j), state, prec, mag_bits); else acb_zero(acb_mat_entry(mat, i, j)); } arb-2.22.1/acb_mat/randtest_eig.c000066400000000000000000000030141417376376500165650ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_randtest_eig(acb_mat_t A, flint_rand_t state, acb_srcptr E, slong prec) { slong n, i, j, ebits; acb_mat_t U, Q; n = acb_mat_nrows(A); ebits = 1 + n_randint(state, 5); acb_mat_init(U, n, n); acb_mat_init(Q, n, n); /* Skew-Hermitian matrix */ acb_mat_randtest(Q, state, prec, 1); if (n_randint(state, 2)) acb_mat_get_mid(Q, Q); for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { acb_neg(acb_mat_entry(Q, i, j), acb_mat_entry(Q, j, i)); acb_conj(acb_mat_entry(Q, i, j), acb_mat_entry(Q, i, j)); } arb_zero(acb_realref(acb_mat_entry(Q, i, i))); } acb_mat_exp(Q, Q, prec); acb_mat_randtest(U, state, prec, ebits); if (n_randint(state, 2)) acb_mat_get_mid(U, U); for (i = 0; i < n; i++) for (j = 0; j < i; j++) acb_zero(acb_mat_entry(U, i, j)); for (i = 0; i < n; i++) acb_set(acb_mat_entry(U, i, i), E + i); acb_mat_mul(U, Q, U, prec); acb_mat_conjugate_transpose(Q, Q); acb_mat_mul(A, U, Q, prec); acb_mat_clear(U); acb_mat_clear(Q); } arb-2.22.1/acb_mat/set.c000066400000000000000000000013411417376376500147110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_set(acb_mat_t dest, const acb_mat_t src) { slong i, j; if (dest != src && acb_mat_ncols(src) != 0) { for (i = 0; i < acb_mat_nrows(src); i++) for (j = 0; j < acb_mat_ncols(src); j++) acb_set(acb_mat_entry(dest, i, j), acb_mat_entry(src, i, j)); } } arb-2.22.1/acb_mat/set_arb_mat.c000066400000000000000000000013351417376376500164010ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_set_arb_mat(acb_mat_t dest, const arb_mat_t src) { slong i, j; if (acb_mat_ncols(dest) != 0) { for (i = 0; i < acb_mat_nrows(dest); i++) for (j = 0; j < acb_mat_ncols(dest); j++) acb_set_arb(acb_mat_entry(dest, i, j), arb_mat_entry(src, i, j)); } } arb-2.22.1/acb_mat/set_fmpq_mat.c000066400000000000000000000013671417376376500166050ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_set_fmpq_mat(acb_mat_t dest, const fmpq_mat_t src, slong prec) { slong i, j; if (acb_mat_ncols(dest) != 0) { for (i = 0; i < acb_mat_nrows(dest); i++) for (j = 0; j < acb_mat_ncols(dest); j++) acb_set_fmpq(acb_mat_entry(dest, i, j), fmpq_mat_entry(src, i, j), prec); } } arb-2.22.1/acb_mat/set_fmpz_mat.c000066400000000000000000000013451417376376500166120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_set_fmpz_mat(acb_mat_t dest, const fmpz_mat_t src) { slong i, j; if (acb_mat_ncols(dest) != 0) { for (i = 0; i < acb_mat_nrows(dest); i++) for (j = 0; j < acb_mat_ncols(dest); j++) acb_set_fmpz(acb_mat_entry(dest, i, j), fmpz_mat_entry(src, i, j)); } } arb-2.22.1/acb_mat/set_round_arb_mat.c000066400000000000000000000013731417376376500176120ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_set_round_arb_mat(acb_mat_t dest, const arb_mat_t src, slong prec) { slong i, j; if (acb_mat_ncols(dest) != 0) { for (i = 0; i < acb_mat_nrows(dest); i++) for (j = 0; j < acb_mat_ncols(dest); j++) acb_set_round_arb(acb_mat_entry(dest, i, j), arb_mat_entry(src, i, j), prec); } } arb-2.22.1/acb_mat/set_round_fmpz_mat.c000066400000000000000000000013771417376376500200260ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_set_round_fmpz_mat(acb_mat_t dest, const fmpz_mat_t src, slong prec) { slong i, j; if (acb_mat_ncols(dest) != 0) { for (i = 0; i < acb_mat_nrows(dest); i++) for (j = 0; j < acb_mat_ncols(dest); j++) acb_set_round_fmpz(acb_mat_entry(dest, i, j), fmpz_mat_entry(src, i, j), prec); } } arb-2.22.1/acb_mat/solve.c000066400000000000000000000012311417376376500152440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) { slong n = acb_mat_nrows(A); if (n <= 4 || prec > 10.0 * n) return acb_mat_solve_lu(X, A, B, prec); else return acb_mat_solve_precond(X, A, B, prec); } arb-2.22.1/acb_mat/solve_lu.c000066400000000000000000000015651417376376500157560ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int acb_mat_solve_lu(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) { int result; slong n, m, *perm; acb_mat_t LU; n = acb_mat_nrows(A); m = acb_mat_ncols(X); if (n == 0 || m == 0) return 1; perm = _perm_init(n); acb_mat_init(LU, n, n); result = acb_mat_lu(perm, LU, A, prec); if (result) acb_mat_solve_lu_precomp(X, perm, LU, B, prec); acb_mat_clear(LU); _perm_clear(perm); return result; } arb-2.22.1/acb_mat/solve_lu_precomp.c000066400000000000000000000040211417376376500174710ustar00rootroot00000000000000/* Copyright (C) 2012,2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t A, const acb_mat_t B, slong prec) { slong i, j, c, n, m; n = acb_mat_nrows(X); m = acb_mat_ncols(X); if (X == B) { acb_ptr tmp = flint_malloc(sizeof(acb_struct) * n); for (c = 0; c < m; c++) { for (i = 0; i < n; i++) tmp[i] = B->rows[perm[i]][c]; for (i = 0; i < n; i++) X->rows[i][c] = tmp[i]; } flint_free(tmp); } else { for (c = 0; c < m; c++) { for (i = 0; i < n; i++) { acb_set(acb_mat_entry(X, i, c), acb_mat_entry(B, perm[i], c)); } } } /* solve_tril and solve_triu have some overhead */ if (n >= 4) { acb_mat_solve_tril(X, A, X, 1, prec); acb_mat_solve_triu(X, A, X, 0, prec); return; } for (c = 0; c < m; c++) { /* solve Ly = b */ for (i = 1; i < n; i++) { for (j = 0; j < i; j++) { acb_submul(acb_mat_entry(X, i, c), acb_mat_entry(A, i, j), acb_mat_entry(X, j, c), prec); } } /* solve Ux = y */ for (i = n - 1; i >= 0; i--) { for (j = i + 1; j < n; j++) { acb_submul(acb_mat_entry(X, i, c), acb_mat_entry(A, i, j), acb_mat_entry(X, j, c), prec); } acb_div(acb_mat_entry(X, i, c), acb_mat_entry(X, i, c), acb_mat_entry(A, i, i), prec); } } } arb-2.22.1/acb_mat/solve_precond.c000066400000000000000000000064001417376376500167610ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int _acb_mat_solve_c(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) { int result; slong m, n; acb_mat_t I, R; n = acb_mat_nrows(A); m = acb_mat_ncols(X); if (n == 0 || m == 0) return 1; acb_mat_init(I, n, n); acb_mat_init(R, n, n); acb_mat_one(I); result = acb_mat_approx_solve(R, A, I, prec); if (result) { acb_mat_t RA, RB; acb_mat_init(RA, n, n); acb_mat_init(RB, n, m); acb_mat_mul(RA, R, A, prec); acb_mat_mul(RB, R, B, prec); result = acb_mat_solve_lu(X, RA, RB, prec); acb_mat_clear(RA); acb_mat_clear(RB); } acb_mat_clear(I); acb_mat_clear(R); return result; } int _acb_mat_solve_d(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) { int result, real; slong m, n; acb_mat_t I, R; n = acb_mat_nrows(A); m = acb_mat_ncols(X); if (n == 0 || m == 0) return 1; real = acb_mat_is_real(A) && acb_mat_is_real(B); acb_mat_init(I, n, n); acb_mat_init(R, n, n); acb_mat_one(I); result = acb_mat_approx_solve(R, A, I, prec); if (result) { acb_mat_t RA, RB, E; mag_t d; acb_mat_init(RA, n, n); acb_mat_init(RB, n, m); acb_mat_init(E, n, n); mag_init(d); acb_mat_mul(RA, R, A, prec); acb_mat_mul(RB, R, B, prec); acb_mat_sub(E, I, RA, prec); acb_mat_bound_inf_norm(d, E); if (mag_cmp_2exp_si(d, 0) < 0) { slong i, j; mag_t e, err; mag_init(e); mag_init(err); mag_geom_series(d, d, 1); acb_mat_set(X, RB); for (j = 0; j < m; j++) { mag_zero(err); for (i = 0; i < n; i++) { acb_get_mag(e, acb_mat_entry(RB, i, j)); mag_max(err, err, e); } mag_mul(err, err, d); for (i = 0; i < n; i++) { if (real) arb_add_error_mag(acb_realref(acb_mat_entry(X, i, j)), err); else acb_add_error_mag(acb_mat_entry(X, i, j), err); } } mag_clear(e); mag_clear(err); } else { result = acb_mat_solve_lu(X, RA, RB, prec); } acb_mat_clear(RA); acb_mat_clear(RB); acb_mat_clear(E); mag_clear(d); } acb_mat_clear(I); acb_mat_clear(R); return result; } int acb_mat_solve_precond(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) { slong n = acb_mat_nrows(A); slong m = acb_mat_ncols(B); if (m < 0.1 * n + 1) return _acb_mat_solve_c(X, A, B, prec); else return _acb_mat_solve_d(X, A, B, prec); } arb-2.22.1/acb_mat/solve_tril.c000066400000000000000000000052261417376376500163060ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_solve_tril_classical(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) { slong i, j, n, m; acb_ptr tmp; acb_t s; n = L->r; m = B->c; acb_init(s); tmp = flint_malloc(sizeof(acb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *acb_mat_entry(X, j, i); for (j = 0; j < n; j++) { acb_dot(s, acb_mat_entry(B, j, i), 1, L->rows[j], 1, tmp, 1, j, prec); if (!unit) acb_div(tmp + j, s, acb_mat_entry(L, j, j), prec); else acb_swap(tmp + j, s); } for (j = 0; j < n; j++) *acb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); acb_clear(s); } void acb_mat_solve_tril_recursive(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) { acb_mat_t LA, LC, LD, XX, XY, BX, BY, T; slong r, n, m; n = L->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A 0]^ [X] == [A^ 0 ] [X] == [A^ X] [C D] [Y] == [-D^ C A^ D^] [Y] == [D^ (Y - C A^ X)] */ acb_mat_window_init(LA, L, 0, 0, r, r); acb_mat_window_init(LC, L, r, 0, n, r); acb_mat_window_init(LD, L, r, r, n, n); acb_mat_window_init(BX, B, 0, 0, r, m); acb_mat_window_init(BY, B, r, 0, n, m); acb_mat_window_init(XX, X, 0, 0, r, m); acb_mat_window_init(XY, X, r, 0, n, m); acb_mat_solve_tril(XX, LA, BX, unit, prec); /* acb_mat_submul(XY, BY, LC, XX); */ acb_mat_init(T, LC->r, BX->c); acb_mat_mul(T, LC, XX, prec); acb_mat_sub(XY, BY, T, prec); acb_mat_clear(T); acb_mat_solve_tril(XY, LD, XY, unit, prec); acb_mat_window_clear(LA); acb_mat_window_clear(LC); acb_mat_window_clear(LD); acb_mat_window_clear(BX); acb_mat_window_clear(BY); acb_mat_window_clear(XX); acb_mat_window_clear(XY); } void acb_mat_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) acb_mat_solve_tril_classical(X, L, B, unit, prec); else acb_mat_solve_tril_recursive(X, L, B, unit, prec); } arb-2.22.1/acb_mat/solve_triu.c000066400000000000000000000052061417376376500163150ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_solve_triu_classical(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) { slong i, j, n, m; acb_ptr tmp; acb_t s; n = U->r; m = B->c; acb_init(s); tmp = flint_malloc(sizeof(acb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *acb_mat_entry(X, j, i); for (j = n - 1; j >= 0; j--) { acb_dot(s, acb_mat_entry(B, j, i), 1, U->rows[j] + j + 1, 1, tmp + j + 1, 1, n - j - 1, prec); if (!unit) acb_div(tmp + j, s, acb_mat_entry(U, j, j), prec); else acb_swap(tmp + j, s); } for (j = 0; j < n; j++) *acb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); acb_clear(s); } void acb_mat_solve_triu_recursive(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) { acb_mat_t UA, UB, UD, XX, XY, BX, BY, T; slong r, n, m; n = U->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A B]^ [X] == [A^ (X - B D^ Y)] [0 D] [Y] == [ D^ Y ] */ acb_mat_window_init(UA, U, 0, 0, r, r); acb_mat_window_init(UB, U, 0, r, r, n); acb_mat_window_init(UD, U, r, r, n, n); acb_mat_window_init(BX, B, 0, 0, r, m); acb_mat_window_init(BY, B, r, 0, n, m); acb_mat_window_init(XX, X, 0, 0, r, m); acb_mat_window_init(XY, X, r, 0, n, m); acb_mat_solve_triu(XY, UD, BY, unit, prec); /* acb_mat_submul(XX, BX, UB, XY); */ acb_mat_init(T, UB->r, XY->c); acb_mat_mul(T, UB, XY, prec); acb_mat_sub(XX, BX, T, prec); acb_mat_clear(T); acb_mat_solve_triu(XX, UA, XX, unit, prec); acb_mat_window_clear(UA); acb_mat_window_clear(UB); acb_mat_window_clear(UD); acb_mat_window_clear(BX); acb_mat_window_clear(BY); acb_mat_window_clear(XX); acb_mat_window_clear(XY); } void acb_mat_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) acb_mat_solve_triu_classical(X, U, B, unit, prec); else acb_mat_solve_triu_recursive(X, U, B, unit, prec); } arb-2.22.1/acb_mat/sqr.c000066400000000000000000000007561417376376500147340ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_sqr(acb_mat_t B, const acb_mat_t A, slong prec) { acb_mat_mul(B, A, A, prec); } arb-2.22.1/acb_mat/sqr_classical.c000066400000000000000000000052031417376376500167420ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_sqr_classical(acb_mat_t B, const acb_mat_t A, slong prec) { slong n, i, j, k; acb_t p, s; n = acb_mat_nrows(A); if (acb_mat_ncols(A) != n || acb_mat_nrows(B) != n || acb_mat_ncols(B) != n) { flint_printf("acb_mat_sqr: incompatible dimensions\n"); flint_abort(); } if (n == 0) return; if (n == 1) { acb_mul(acb_mat_entry(B, 0, 0), acb_mat_entry(A, 0, 0), acb_mat_entry(A, 0, 0), prec); return; } if (A == B) { acb_mat_t T; acb_mat_init(T, n, n); acb_mat_sqr_classical(T, A, prec); acb_mat_swap(T, B); acb_mat_clear(T); return; } acb_init(p); acb_init(s); /* contribution of diagonal of A to diagonal of B */ for (i = 0; i < n; i++) { acb_mul(acb_mat_entry(B, i, i), acb_mat_entry(A, i, i), acb_mat_entry(A, i, i), prec); } for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { /* contribution of off-diagonal of A to diagonal of B */ acb_mul(p, acb_mat_entry(A, i, j), acb_mat_entry(A, j, i), prec); acb_add(acb_mat_entry(B, i, i), acb_mat_entry(B, i, i), p, prec); acb_add(acb_mat_entry(B, j, j), acb_mat_entry(B, j, j), p, prec); /* contribution of diagonal of A to off-diagonal of B */ acb_add(s, acb_mat_entry(A, i, i), acb_mat_entry(A, j, j), prec); acb_mul(acb_mat_entry(B, i, j), acb_mat_entry(A, i, j), s, prec); acb_mul(acb_mat_entry(B, j, i), acb_mat_entry(A, j, i), s, prec); } } /* contribution of off-diagonal of A to off-diagonal of B */ if (n > 2) { for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { for (k = 0; k < n; k++) { if (i != j && j != k && k != i) { acb_addmul(acb_mat_entry(B, i, j), acb_mat_entry(A, i, k), acb_mat_entry(A, k, j), prec); } } } } } acb_clear(p); acb_clear(s); } arb-2.22.1/acb_mat/sub.c000066400000000000000000000013621417376376500147120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_sub(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(mat1); i++) for (j = 0; j < acb_mat_ncols(mat1); j++) acb_sub(acb_mat_entry(res, i, j), acb_mat_entry(mat1, i, j), acb_mat_entry(mat2, i, j), prec); } arb-2.22.1/acb_mat/test/000077500000000000000000000000001417376376500147325ustar00rootroot00000000000000arb-2.22.1/acb_mat/test/t-approx_eig_qr.c000066400000000000000000000131041417376376500201750ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("approx_eig_qr...."); fflush(stdout); flint_randinit(state); /* Test random & DFT matrices */ for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { acb_mat_t A, L, R; acb_ptr E; acb_t t; mag_t b; slong i, j, n, prec, goal, c0, c1, c2, c3; int wantL, wantR, result, dft; dft = n_randint(state, 2); if (dft) n = n_randint(state, 30); else n = n_randint(state, 15); goal = 2 + n_randint(state, 100); wantL = n_randint(state, 2); wantR = n_randint(state, 2); acb_mat_init(A, n, n); acb_mat_init(L, n, n); acb_mat_init(R, n, n); acb_init(t); mag_init(b); E = _acb_vec_init(n); for (prec = 32; ; prec *= 2) { if (dft) { acb_mat_dft(A, 0, prec); } else { acb_mat_randtest(A, state, 2 + n_randint(state, 200), 5); acb_mat_get_mid(A, A); } acb_mat_approx_eig_qr(E, wantL ? L : NULL, wantR ? R : NULL, A, NULL, 0, prec); if (dft) { /* Verify the known eigenvalues + multiplicities */ c0 = c1 = c2 = c3 = 0; for (i = 0; i < n; i++) { acb_set_d_d(t, 1.0, 0.0); acb_sub(t, t, E + i, prec); acb_get_mag(b, t); c0 += (mag_cmp_2exp_si(b, -goal) < 0); acb_set_d_d(t, -1.0, 0.0); acb_sub(t, t, E + i, prec); acb_get_mag(b, t); c1 += (mag_cmp_2exp_si(b, -goal) < 0); acb_set_d_d(t, 0.0, 1.0); acb_sub(t, t, E + i, prec); acb_get_mag(b, t); c2 += (mag_cmp_2exp_si(b, -goal) < 0); acb_set_d_d(t, 0.0, -1.0); acb_sub(t, t, E + i, prec); acb_get_mag(b, t); c3 += (mag_cmp_2exp_si(b, -goal) < 0); } result = (n == 0 || (c0 == (n+4)/4 && c1 == (n+2)/4 && c2 == (n-1)/4 && c3 == (n+1)/4)); } else { result = 1; } if (result && wantL) { acb_mat_t LA, D; acb_mat_init(LA, n, n); acb_mat_init(D, n, n); /* Check LA - lambda L = 0 */ acb_mat_approx_mul(LA, L, A, prec); for (i = 0; i < n; i++) acb_set(acb_mat_entry(D, i, i), E + i); acb_mat_approx_mul(D, D, L, prec); acb_mat_sub(LA, LA, D, prec); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { acb_get_mag(b, acb_mat_entry(LA, i, j)); result = result && (mag_cmp_2exp_si(b, -goal) < 0); } } acb_mat_clear(LA); acb_mat_clear(D); } if (result && wantR) { acb_mat_t AR, D; acb_mat_init(AR, n, n); acb_mat_init(D, n, n); /* Check AR - R lambda = 0 */ acb_mat_approx_mul(AR, A, R, prec); for (i = 0; i < n; i++) acb_set(acb_mat_entry(D, i, i), E + i); acb_mat_approx_mul(D, R, D, prec); acb_mat_sub(AR, AR, D, prec); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { acb_get_mag(b, acb_mat_entry(AR, i, j)); result = result && (mag_cmp_2exp_si(b, -goal) < 0); } } acb_mat_clear(AR); acb_mat_clear(D); } if (result) break; if (prec > 2000) { flint_printf("FAIL (convergence, dft = %d)\n\n", dft); flint_printf("n = %wd\n\n", n); acb_mat_printd(A, 10); flint_printf("\n\n"); for (i = 0; i < n; i++) { acb_printn(E + i, 50, 0); flint_printf("\n"); } flint_printf("\n"); if (wantL) { flint_printf("L = \n"); acb_mat_printd(L, 10); flint_printf("\n\n"); } if (wantR) { flint_printf("R = \n"); acb_mat_printd(R, 10); flint_printf("\n\n"); } flint_abort(); } } acb_mat_clear(A); acb_mat_clear(L); acb_mat_clear(R); _acb_vec_clear(E, n); acb_clear(t); mag_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-charpoly.c000066400000000000000000000037641417376376500171720ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main(void) { slong iter; flint_rand_t state; flint_printf("charpoly...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_mat_t A, B, C, D; acb_poly_t f, g; slong m, n; m = n_randint(state, 8); n = m; acb_mat_init(A, m, n); acb_mat_init(B, m, n); acb_mat_init(C, m, m); acb_mat_init(D, n, n); acb_poly_init(f); acb_poly_init(g); acb_mat_randtest(A, state, 1 + n_randint(state, 1000), 10); acb_mat_randtest(B, state, 1 + n_randint(state, 1000), 10); acb_mat_mul(C, A, B, 2 + n_randint(state, 1000)); acb_mat_mul(D, B, A, 2 + n_randint(state, 1000)); acb_mat_charpoly(f, C, 2 + n_randint(state, 1000)); acb_mat_charpoly(g, D, 2 + n_randint(state, 1000)); if (!acb_poly_overlaps(f, g)) { flint_printf("FAIL: charpoly(AB) != charpoly(BA).\n"); flint_printf("Matrix A:\n"), acb_mat_printd(A, 15), flint_printf("\n"); flint_printf("Matrix B:\n"), acb_mat_printd(B, 15), flint_printf("\n"); flint_printf("cp(AB) = "), acb_poly_printd(f, 15), flint_printf("\n"); flint_printf("cp(BA) = "), acb_poly_printd(g, 15), flint_printf("\n"); flint_abort(); } acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(C); acb_mat_clear(D); acb_poly_clear(f); acb_poly_clear(g); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/acb_mat/test/t-companion.c000066400000000000000000000033241417376376500173240ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main(void) { slong iter; flint_rand_t state; flint_printf("companion...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { acb_mat_t A; acb_poly_t f, g; slong n, prec; acb_poly_init(f); acb_poly_init(g); do { acb_poly_randtest(f, state, 1 + n_randint(state, 8), 1 + n_randint(state, 1000), 10); } while (acb_poly_degree(f) < 0); n = acb_poly_degree(f); prec = 2 + n_randint(state, 200); acb_mat_init(A, n, n); acb_mat_randtest(A, state, 1 + n_randint(state, 1000), 10); acb_mat_companion(A, f, prec); acb_mat_charpoly(g, A, prec); acb_poly_scalar_mul(g, g, acb_poly_get_coeff_ptr(f, n), prec); if (!acb_poly_contains(g, f)) { flint_printf("FAIL\n"); flint_printf("A:\n"), acb_mat_printd(A, 15), flint_printf("\n"); flint_printf("f:\n"), acb_poly_printd(f, 15), flint_printf("\n"); flint_printf("g:\n"), acb_poly_printd(g, 15), flint_printf("\n"); flint_abort(); } acb_mat_clear(A); acb_poly_clear(f); acb_poly_clear(g); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/acb_mat/test/t-det.c000066400000000000000000000075511417376376500161230ustar00rootroot00000000000000/* Copyright (C) 2012, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("det...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; fmpq_t Qdet; acb_mat_t A; acb_t Adet; slong n, qbits, prec; n = n_randint(state, 12); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_init(Qdet); acb_mat_init(A, n, n); acb_init(Adet); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_det(Qdet, Q); acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_det(Adet, A, prec); if (!acb_contains_fmpq(Adet, Qdet)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qdet = \n"); fmpq_print(Qdet); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Adet = \n"); acb_printd(Adet, 15); flint_printf("\n\n"); flint_printf("Adet = \n"); acb_print(Adet); flint_printf("\n\n"); flint_abort(); } fmpq_mat_clear(Q); fmpq_clear(Qdet); acb_mat_clear(A); acb_clear(Adet); } for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_mat_t A, B, AB; acb_t detA, detB, detAB, t; slong n, prec1, prec2, prec3; n = n_randint(state, 12); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); prec3 = 2 + n_randint(state, 200); acb_mat_init(A, n, n); acb_mat_init(B, n, n); acb_mat_init(AB, n, n); acb_init(detA); acb_init(detB); acb_init(detAB); acb_init(t); acb_mat_randtest(A, state, 2 + n_randint(state, 200), 2 + n_randint(state, 100)); acb_mat_randtest(B, state, 2 + n_randint(state, 200), 2 + n_randint(state, 100)); acb_mat_mul(AB, A, B, prec3); acb_mat_det(detA, A, prec1); acb_mat_det(detB, B, prec2); acb_mat_det(detAB, AB, prec3); acb_mul(t, detA, detB, 1000); if (!acb_overlaps(t, detAB)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("n = %wd, prec1 = %wd, prec2 = %wd, prec3 = %wd\n", n, prec1, prec2, prec3); flint_printf("\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("detA = \n"); acb_printn(detA, 50, 0); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("detB = \n"); acb_printn(detB, 50, 0); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(AB, 15); flint_printf("\n\n"); flint_printf("detAB = \n"); acb_printn(detAB, 50, 0); flint_printf("\n\n"); flint_printf("detA*detB = \n"); acb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(AB); acb_clear(detA); acb_clear(detB); acb_clear(detAB); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-det_precond.c000066400000000000000000000124321417376376500176270ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("det_precond...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; fmpq_t Qdet; acb_mat_t A; acb_t Adet; slong n, qbits, prec; n = n_randint(state, 12); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_init(Qdet); acb_mat_init(A, n, n); acb_init(Adet); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_det(Qdet, Q); acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_det_precond(Adet, A, prec); if (!acb_contains_fmpq(Adet, Qdet)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qdet = \n"); fmpq_print(Qdet); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Adet = \n"); acb_printd(Adet, 15); flint_printf("\n\n"); flint_printf("Adet = \n"); acb_print(Adet); flint_printf("\n\n"); flint_abort(); } fmpq_mat_clear(Q); fmpq_clear(Qdet); acb_mat_clear(A); acb_clear(Adet); } for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_mat_t A, B, AB; acb_t detA, detB, detAB, detAb, detBb, detABb, t; slong n, prec1, prec2, prec3; n = n_randint(state, 12); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); prec3 = 2 + n_randint(state, 200); acb_mat_init(A, n, n); acb_mat_init(B, n, n); acb_mat_init(AB, n, n); acb_init(detA); acb_init(detB); acb_init(detAB); acb_init(t); acb_init(detAb); acb_init(detBb); acb_init(detABb); acb_mat_randtest(A, state, 2 + n_randint(state, 200), 2 + n_randint(state, 20)); acb_mat_randtest(B, state, 2 + n_randint(state, 200), 2 + n_randint(state, 20)); acb_mat_mul(AB, A, B, prec3); acb_mat_det_precond(detA, A, prec1); acb_mat_det_precond(detB, B, prec2); acb_mat_det_precond(detAB, AB, prec3); acb_mul(t, detA, detB, 1000); if (!acb_overlaps(t, detAB)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("n = %wd, prec1 = %wd, prec2 = %wd, prec3 = %wd\n", n, prec1, prec2, prec3); flint_printf("\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("detA = \n"); acb_printn(detA, 50, 0); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("detB = \n"); acb_printn(detB, 50, 0); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(AB, 15); flint_printf("\n\n"); flint_printf("detAB = \n"); acb_printn(detAB, 50, 0); flint_printf("\n\n"); flint_printf("detA*detB = \n"); acb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_mat_det_lu(detAb, A, prec1); acb_mat_det_lu(detBb, B, prec2); acb_mat_det_lu(detABb, AB, prec3); if (!acb_overlaps(detA, detAb) || !acb_overlaps(detB, detBb) || !acb_overlaps(detAB, detABb)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("n = %wd, prec1 = %wd, prec2 = %wd, prec3 = %wd\n", n, prec1, prec2, prec3); flint_printf("\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("detA = \n"); acb_printn(detA, 50, 0); flint_printf("\n\n"); flint_printf("detAb = \n"); acb_printn(detAb, 50, 0); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("detB = \n"); acb_printn(detB, 50, 0); flint_printf("\n\n"); flint_printf("detBb = \n"); acb_printn(detBb, 50, 0); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(AB, 15); flint_printf("\n\n"); flint_printf("detAB = \n"); acb_printn(detAB, 50, 0); flint_printf("\n\n"); flint_printf("detABb = \n"); acb_printn(detABb, 50, 0); flint_printf("\n\n"); flint_abort(); } acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(AB); acb_clear(detA); acb_clear(detB); acb_clear(detAB); acb_clear(t); acb_clear(detAb); acb_clear(detBb); acb_clear(detABb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-dft.c000066400000000000000000000032671417376376500161240ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("dft...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { acb_mat_t A, Ainv, AT; slong n, prec; n = n_randint(state, 10); prec = 53 + n_randint(state, 30); acb_mat_init(A, n, n); acb_mat_init(Ainv, n, n); acb_mat_init(AT, n, n); acb_mat_randtest(A, state, 100, 10); acb_mat_dft(A, 0, prec); if (!acb_mat_inv(Ainv, A, prec)) { flint_printf("FAIL: small DFT matrix (n = %wd) not invertible\n", n); flint_abort(); } acb_mat_conjugate_transpose(AT, A); if (!acb_mat_overlaps(AT, Ainv)) { flint_printf("FAIL: overlap (n = %wd)\n", n); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); acb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_printf("AT = \n"); acb_mat_printd(AT, 15); flint_printf("\n\n"); flint_abort(); } acb_mat_clear(A); acb_mat_clear(Ainv); acb_mat_clear(AT); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-eig_enclosure_rump.c000066400000000000000000000177761417376376500212470ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("eig_enclosure_rump...."); fflush(stdout); flint_randinit(state); /* Test random matrices */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_mat_t A, X, R, AR, J, RJ, Z, Z0; acb_ptr E, F; acb_t b, lambda; slong i, j, h, k, n, iter2, prec, found_eigenvalue; n = 1 + n_randint(state, 7); prec = 2 + n_randint(state, 200); acb_mat_init(A, n, n); acb_mat_init(X, n, n); acb_init(lambda); acb_init(b); E = _acb_vec_init(n); F = _acb_vec_init(n); if (n_randint(state, 2)) { for (i = 0; i < n; i++) acb_randtest(E + i, state, prec, 3); } else { /* Randomly repeat eigenvalues. */ for (i = 0; i < n; i++) { if (i == 0 || n_randint(state, 2)) acb_randtest(E + i, state, prec, 3); else acb_set(E + i, E + n_randint(state, i)); } } if (n_randint(state, 2)) { for (i = 0; i < n; i++) acb_get_mid(E + i, E + i); } acb_mat_randtest_eig(A, state, E, prec); acb_mat_approx_eig_qr(F, NULL, X, A, NULL, 0, prec); /* Perturb F further. */ if (n_randint(state, 4) == 0) { for (i = 0; i < n; i++) { acb_randtest(b, state, prec, 1); acb_mul_2exp_si(b, b, -n_randint(state, prec)); acb_add(F + i, F + i, b, prec); } } /* Perturb X further. */ if (n_randint(state, 10) == 0) { j = n_randint(state, n); for (i = 0; i < n; i++) { acb_randtest(b, state, prec, 1); acb_mul_2exp_si(b, b, -10 - n_randint(state, prec)); acb_add(acb_mat_entry(X, i, j), acb_mat_entry(X, i, j), b, prec); } } /* Test k = 1 */ if (1) { acb_mat_init(R, n, 1); acb_mat_init(AR, n, 1); acb_mat_init(Z, n, 1); acb_mat_init(Z0, n, 1); for (j = 0; j < n; j++) { acb_set(lambda, F + j); for (i = 0; i < n; i++) acb_set(acb_mat_entry(R, i, 0), acb_mat_entry(X, i, j)); acb_mat_eig_enclosure_rump(lambda, NULL, R, A, lambda, R, prec); acb_mat_mul(AR, A, R, prec); acb_mat_neg(Z, AR); acb_mat_scalar_addmul_acb(Z, R, lambda, prec); if (!acb_mat_contains(Z, Z0)) { flint_printf("FAIL: not containing zero!\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("lambda = \n"); acb_printd(lambda, 20); flint_printf("\n\n"); flint_printf("Z = \n"); acb_mat_printd(Z, 20); flint_printf("\n\n"); flint_printf("E = \n"); for (j = 0; j < n; j++) { acb_printd(E + j, 20); flint_printf("\n"); } flint_abort(); } found_eigenvalue = 0; for (j = 0; j < n; j++) { if (acb_contains(lambda, E + j)) found_eigenvalue++; } if (found_eigenvalue == 0) { flint_printf("FAIL: eigenvalue not found\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("lambda = \n"); acb_printd(lambda, 20); flint_printf("\n\n"); flint_printf("Z = \n"); acb_mat_printd(Z, 20); flint_printf("\n\n"); flint_printf("E = \n"); for (j = 0; j < n; j++) { acb_printd(E + j, 20); flint_printf("\n"); } flint_abort(); } } acb_mat_clear(R); acb_mat_clear(AR); acb_mat_clear(Z); acb_mat_clear(Z0); } /* Test k > 1 */ for (iter2 = 1; iter2 < n; iter2++) { k = n_randint(state, n + 1); k = FLINT_MAX(k, 2); acb_mat_init(R, n, k); acb_mat_init(AR, n, k); acb_mat_init(Z, n, k); acb_mat_init(Z0, n, k); acb_mat_init(J, k, k); acb_mat_init(RJ, n, k); /* Random selection */ for (h = 0; h < k; h++) { j = n_randint(state, n); if (h == 0 || n_randint(state, 2)) acb_set(lambda, F + j); for (i = 0; i < n; i++) acb_set(acb_mat_entry(R, i, h), acb_mat_entry(X, i, j)); } acb_mat_eig_enclosure_rump(lambda, J, R, A, lambda, R, prec); /* AY = YJ */ acb_mat_mul(AR, A, R, prec); acb_mat_mul(RJ, R, J, prec); acb_mat_sub(Z, AR, RJ, prec); if (!acb_mat_contains(Z, Z0)) { flint_printf("FAIL: not containing zero! (k = %wd, prec = %wd)\n\n", k, prec); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("lambda = \n"); acb_printd(lambda, 20); flint_printf("\n\n"); flint_printf("J = \n"); acb_mat_printd(J, 20); flint_printf("\n\n"); flint_printf("Z = \n"); acb_mat_printd(Z, 20); flint_printf("\n\n"); flint_printf("E = \n"); for (j = 0; j < n; j++) { acb_printd(E + j, 20); flint_printf("\n"); } flint_abort(); } found_eigenvalue = 0; for (j = 0; j < n; j++) { if (acb_contains(lambda, E + j)) found_eigenvalue++; } if (found_eigenvalue < k) { flint_printf("FAIL: eigenvalue not found (k = %wd, found = %wd)\n\n", k, found_eigenvalue); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("lambda = \n"); acb_printd(lambda, 20); flint_printf("\n\n"); flint_printf("Z = \n"); acb_mat_printd(Z, 20); flint_printf("\n\n"); flint_printf("E = \n"); for (j = 0; j < n; j++) { acb_printd(E + j, 20); flint_printf("\n"); } flint_abort(); } acb_mat_clear(R); acb_mat_clear(AR); acb_mat_clear(Z); acb_mat_clear(Z0); acb_mat_clear(J); acb_mat_clear(RJ); } acb_mat_clear(A); acb_mat_clear(X); acb_clear(lambda); acb_clear(b); _acb_vec_clear(E, n); _acb_vec_clear(F, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-eig_global_enclosure.c000066400000000000000000000054411417376376500215060ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("eig_global_enclosure...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { acb_mat_t A, X; acb_ptr E, F, B; mag_t eps; slong i, j, n, prec; int success; n = n_randint(state, 8); prec = 2 + n_randint(state, 100); acb_mat_init(A, n, n); acb_mat_init(X, n, n); E = _acb_vec_init(n); F = _acb_vec_init(n); B = _acb_vec_init(n); mag_init(eps); for (i = 0; i < n; i++) acb_randtest(E + i, state, prec, 3); acb_mat_randtest_eig(A, state, E, prec); acb_mat_approx_eig_qr(F, NULL, X, A, NULL, 0, prec); /* perturb F further */ if (n_randint(state, 2)) { for (i = 0; i < n; i++) { acb_randtest(B, state, prec, 1); acb_mul_2exp_si(B, B, -n_randint(state, prec)); acb_add(F + i, F + i, B, prec); } } acb_mat_eig_global_enclosure(eps, A, F, X, prec); _acb_vec_set(B, F, n); for (i = 0; i < n; i++) acb_add_error_mag(B + i, eps); for (i = 0; i < n; i++) { success = 0; for (j = 0; j < n; j++) { if (acb_contains(B + j, E + i)) { success = 1; break; } } if (!success) { flint_printf("FAIL\n\n"); flint_printf("A =\n"); acb_mat_printd(A, 20); flint_printf("\n\ni = %wd\n\n", i); flint_printf("\nE =\n"); for (j = 0; j < n; j++) { acb_printn(E + j, 20, 0); flint_printf("\n"); } flint_printf("\nB =\n"); for (j = 0; j < n; j++) { acb_printn(B + j, 20, 0); flint_printf("\n"); } flint_abort(); } } acb_mat_clear(A); acb_mat_clear(X); _acb_vec_clear(E, n); _acb_vec_clear(F, n); _acb_vec_clear(B, n); mag_clear(eps); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-eig_multiple.c000066400000000000000000000151421417376376500200210ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("eig_multiple...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_mat_t A, R; acb_ptr E, F; acb_t b; slong i, j, n, prec, count, count2; int result; n = n_randint(state, 8); prec = 2 + n_randint(state, 200); acb_init(b); acb_mat_init(A, n, n); acb_mat_init(R, n, n); E = _acb_vec_init(n); F = _acb_vec_init(n); if (n_randint(state, 10) != 0) { for (i = 0; i < n; i++) acb_randtest(E + i, state, prec, 2); } else { /* Randomly repeat eigenvalues. */ for (i = 0; i < n; i++) { if (i == 0 || n_randint(state, 2)) acb_randtest(E + i, state, prec, 2); else acb_set(E + i, E + n_randint(state, i)); } } if (n_randint(state, 2)) { for (i = 0; i < n; i++) acb_get_mid(E + i, E + i); } acb_mat_randtest_eig(A, state, E, prec); acb_mat_approx_eig_qr(F, NULL, R, A, NULL, 0, prec); /* Perturb F further. */ if (n_randint(state, 10) == 0) { for (i = 0; i < n; i++) { acb_randtest(b, state, prec, 1); acb_mul_2exp_si(b, b, -n_randint(state, prec)); acb_add(F + i, F + i, b, prec); } } /* Perturb R further. */ if (n_randint(state, 10) == 0) { j = n_randint(state, n); for (i = 0; i < n; i++) { acb_randtest(b, state, prec, 1); acb_mul_2exp_si(b, b, -10 - n_randint(state, prec)); acb_add(acb_mat_entry(R, i, j), acb_mat_entry(R, i, j), b, prec); } } if (n_randint(state, 2)) result = acb_mat_eig_multiple_rump(F, A, E, R, prec); else result = acb_mat_eig_multiple(F, A, E, R, prec); if (result) { count = 0; count2 = 0; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (j == 0 || !acb_equal(F + j, F + j - 1)) count += acb_contains(F + j, E + i); } for (j = 0; j < n; j++) { if (j == 0 || !acb_equal(F + j, F + j - 1)) count2 += acb_overlaps(F + j, E + i); } } if (count != n || count2 != n) { flint_printf("FAIL: count\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("count = %wd, count2 = %wd\n\n", count, count2); flint_printf("E = \n"); for (j = 0; j < n; j++) { acb_printd(E + j, 20); flint_printf("\n"); } flint_printf("F = \n"); for (j = 0; j < n; j++) { acb_printd(F + j, 20); flint_printf("\n"); } flint_abort(); } } acb_mat_clear(A); acb_mat_clear(R); _acb_vec_clear(E, n); _acb_vec_clear(F, n); acb_clear(b); } /* Test convergence for DFT matrices */ for (iter = 0; iter < 50 * arb_test_multiplier(); iter++) { acb_mat_t A, R, QC; acb_ptr E; acb_t t; fmpq_mat_t Q, Qinv; slong i, n, c0, c1, c2, c3; slong prec; int algorithm, result; n = n_randint(state, 30); algorithm = n_randint(state, 2); acb_mat_init(A, n, n); acb_mat_init(R, n, n); E = _acb_vec_init(n); acb_init(t); acb_mat_init(QC, n, n); fmpq_mat_init(Q, n, n); fmpq_mat_init(Qinv, n, n); /* The current algorithm is not robust enough. */ #if 0 do { fmpq_mat_randtest(Q, state, 2 + n_randint(state, 10)); } while (!fmpq_mat_inv(Qinv, Q)); #else fmpq_mat_one(Q); fmpq_mat_one(Qinv); #endif for (prec = 32; ; prec *= 2) { if (prec > 10000) { flint_printf("FAIL: unsuccessful, prec > 10000\n\n"); flint_printf("algorithm = %d, iter %wd\n\n", algorithm, iter); flint_abort(); } acb_mat_dft(A, 0, prec); #if 0 acb_mat_set_fmpq_mat(QC, Q, prec); acb_mat_mul(A, A, QC, prec); acb_mat_set_fmpq_mat(QC, Qinv, prec); acb_mat_mul(A, QC, A, prec); #endif acb_mat_approx_eig_qr(E, NULL, R, A, NULL, 0, prec); if (algorithm == 0) result = acb_mat_eig_multiple_rump(E, A, E, R, prec); else result = acb_mat_eig_multiple(E, A, E, R, prec); /* Verify the known eigenvalues + multiplicities */ if (result) { c0 = c1 = c2 = c3 = 0; for (i = 0; i < n; i++) { acb_set_d_d(t, 1.0, 0.0); c0 += acb_contains(E + i, t); acb_set_d_d(t, -1.0, 0.0); c1 += acb_contains(E + i, t); acb_set_d_d(t, 0.0, 1.0); c2 += acb_contains(E + i, t); acb_set_d_d(t, 0.0, -1.0); c3 += acb_contains(E + i, t); } result = (n == 0 || (c0 == (n+4)/4 && c1 == (n+2)/4 && c2 == (n-1)/4 && c3 == (n+1)/4)); } if (result) break; } acb_mat_clear(A); acb_mat_clear(R); acb_mat_clear(QC); _acb_vec_clear(E, n); acb_clear(t); fmpq_mat_clear(Q); fmpq_mat_clear(Qinv); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-eig_simple.c000066400000000000000000000235161417376376500174630ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("eig_simple...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_mat_t A, L, R, LAR, D; acb_ptr E, F; acb_t b; slong i, j, n, prec, count, count2; int result, algorithm; n = n_randint(state, 8); prec = 2 + n_randint(state, 200); algorithm = n_randint(state, 3); acb_mat_init(A, n, n); acb_mat_init(L, n, n); acb_mat_init(R, n, n); acb_mat_init(LAR, n, n); acb_mat_init(D, n, n); acb_init(b); E = _acb_vec_init(n); F = _acb_vec_init(n); if (n_randint(state, 10) != 0) { for (i = 0; i < n; i++) acb_randtest(E + i, state, prec, 2); } else { /* Randomly repeat eigenvalues. */ for (i = 0; i < n; i++) { if (i == 0 || n_randint(state, 2)) acb_randtest(E + i, state, prec, 2); else acb_set(E + i, E + n_randint(state, i)); } } if (n_randint(state, 2)) { for (i = 0; i < n; i++) acb_get_mid(E + i, E + i); } acb_mat_randtest_eig(A, state, E, prec); acb_mat_approx_eig_qr(F, NULL, R, A, NULL, 0, prec); /* Perturb F further. */ if (n_randint(state, 10) == 0) { for (i = 0; i < n; i++) { acb_randtest(b, state, prec, 1); acb_mul_2exp_si(b, b, -n_randint(state, prec)); acb_add(F + i, F + i, b, prec); } } /* Perturb R further. */ if (n_randint(state, 10) == 0) { j = n_randint(state, n); for (i = 0; i < n; i++) { acb_randtest(b, state, prec, 1); acb_mul_2exp_si(b, b, -10 - n_randint(state, prec)); acb_add(acb_mat_entry(R, i, j), acb_mat_entry(R, i, j), b, prec); } } if (n_randint(state, 2)) { if (algorithm == 0) result = acb_mat_eig_simple(F, L, R, A, E, R, prec); else if (algorithm == 1) result = acb_mat_eig_simple_rump(F, L, R, A, E, R, prec); else result = acb_mat_eig_simple_vdhoeven_mourrain(F, L, R, A, E, R, prec); } else { int r1, r2; if (algorithm == 0) { r1 = acb_mat_eig_simple(F, L, NULL, A, E, R, prec); r2 = acb_mat_eig_simple(F, NULL, R, A, E, R, prec); } else if (algorithm == 1) { r1 = acb_mat_eig_simple_rump(F, L, NULL, A, E, R, prec); r2 = acb_mat_eig_simple_rump(F, NULL, R, A, E, R, prec); } else { r1 = acb_mat_eig_simple_vdhoeven_mourrain(F, L, NULL, A, E, R, prec); r2 = acb_mat_eig_simple_vdhoeven_mourrain(F, NULL, R, A, E, R, prec); } result = n_randint(state, 2) ? r1 : r2; } acb_mat_mul(LAR, L, A, prec); acb_mat_mul(LAR, LAR, R, prec); for (i = 0; i < n; i++) acb_set(acb_mat_entry(D, i, i), F + i); if (!acb_mat_overlaps(LAR, D)) { flint_printf("FAIL: overlap\n\n"); flint_printf("algorithm = %d\n\n", algorithm); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("L = \n"); acb_mat_printd(L, 20); flint_printf("\n\n"); flint_printf("D = \n"); acb_mat_printd(D, 20); flint_printf("\n\n"); flint_printf("LAR = \n"); acb_mat_printd(LAR, 20); flint_printf("\n\n"); flint_abort(); } if (result) { for (i = 0; i < n; i++) { count = 0; for (j = 0; j < n; j++) count += acb_contains(F + i, E + j); count2 = 0; for (j = 0; j < n; j++) count2 += acb_overlaps(F + i, E + j); if (count != 1 || count2 != 1) { flint_printf("FAIL: count\n\n"); flint_printf("algorithm = %d\n\n", algorithm); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("L = \n"); acb_mat_printd(L, 20); flint_printf("\n\n"); flint_printf("D = \n"); acb_mat_printd(D, 20); flint_printf("\n\n"); flint_printf("LAR = \n"); acb_mat_printd(LAR, 20); flint_printf("\n\n"); flint_printf("i = %wd, count = %wd, count2 = %wd\n\n", i, count, count2); flint_abort(); } } } acb_mat_clear(A); acb_mat_clear(L); acb_mat_clear(R); acb_mat_clear(LAR); acb_mat_clear(D); acb_clear(b); _acb_vec_clear(E, n); _acb_vec_clear(F, n); } /* Test convergence, given companion matrices */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_mat_t A, R, QC; acb_ptr E; acb_ptr roots; fmpq_mat_t Q, Qinv; acb_poly_t f; slong i, j, n, prec, count, count2; int algorithm, success; algorithm = n_randint(state, 3); n = n_randint(state, 10); roots = _acb_vec_init(n); E = _acb_vec_init(n); acb_poly_init(f); acb_mat_init(A, n, n); acb_mat_init(R, n, n); fmpq_mat_init(Q, n, n); fmpq_mat_init(Qinv, n, n); acb_mat_init(QC, n, n); for (i = 0; i < n; i++) { new_root: acb_randtest(roots + i, state, 2 + n_randint(state, 100), 4); acb_get_mid(roots + i, roots + i); for (j = 0; j < i; j++) if (acb_equal(roots + i, roots + j)) goto new_root; } do { fmpq_mat_randtest(Q, state, 2 + n_randint(state, 100)); } while (!fmpq_mat_inv(Qinv, Q)); success = 0; for (prec = 32; !success; prec *= 2) { if (prec > 10000) { flint_printf("FAIL: unsuccessful, prec > 10000\n\n"); flint_printf("algorithm = %d, iter %wd\n\n", algorithm, iter); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("roots = \n"); for (j = 0; j < n; j++) { acb_printd(roots + j, 20); flint_printf("\n"); } flint_abort(); } acb_poly_product_roots(f, roots, n, prec); acb_mat_companion(A, f, prec); acb_mat_set_fmpq_mat(QC, Q, prec); acb_mat_mul(A, A, QC, prec); acb_mat_set_fmpq_mat(QC, Qinv, prec); acb_mat_mul(A, QC, A, prec); acb_mat_approx_eig_qr(E, NULL, R, A, NULL, 0, prec); if (algorithm == 0) success = acb_mat_eig_simple(E, NULL, NULL, A, E, R, prec); else if (algorithm == 1) success = acb_mat_eig_simple_rump(E, NULL, NULL, A, E, R, prec); else success = acb_mat_eig_simple_vdhoeven_mourrain(E, NULL, NULL, A, E, R, prec); if (success) { for (i = 0; i < n; i++) { count = 0; for (j = 0; j < n; j++) count += acb_contains(E + i, roots + j); count2 = 0; for (j = 0; j < n; j++) count2 += acb_overlaps(E + i, roots + j); if (count != 1 || count2 != 1) { flint_printf("FAIL: count\n\n"); flint_printf("algorithm = %d\n\n", algorithm); flint_printf("A = \n"); acb_mat_printd(A, 20); flint_printf("\n\n"); flint_printf("R = \n"); acb_mat_printd(R, 20); flint_printf("\n\n"); flint_printf("i = %wd, count = %wd, count2 = %wd\n\n", i, count, count2); flint_printf("roots = \n"); for (j = 0; j < n; j++) { acb_printd(roots + j, 20); flint_printf("\n"); } flint_printf("E = \n"); for (j = 0; j < n; j++) { acb_printd(E + j, 20); flint_printf("\n"); } flint_abort(); } } } } fmpq_mat_clear(Q); fmpq_mat_clear(Qinv); acb_mat_clear(QC); acb_mat_clear(A); acb_mat_clear(R); acb_poly_clear(f); _acb_vec_clear(roots, n); _acb_vec_clear(E, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-exp.c000066400000000000000000000057341417376376500161440ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void _fmpq_mat_randtest_for_exp(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong i, j; slong d, l, u; d = n_randint(state, 5); l = n_randint(state, 5); u = n_randint(state, 5); fmpq_mat_zero(mat); for (i = 0; i < fmpq_mat_nrows(mat); i++) { for (j = 0; j < fmpq_mat_ncols(mat); j++) { if ((i == j && d) || (i < j && u) || (i > j && l)) { fmpq_randtest(fmpq_mat_entry(mat, i, j), state, bits); } } } } int main() { slong iter; flint_rand_t state; flint_printf("exp...."); fflush(stdout); flint_randinit(state); /* check exp(A)*exp(c*A) = exp((1+c)*A) */ for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_mat_t A, E, F, EF, G; fmpq_mat_t Q; acb_t c, d; slong n, qbits, prec; n = n_randint(state, 5); qbits = 2 + n_randint(state, 300); prec = 2 + n_randint(state, 300); acb_init(c); acb_init(d); fmpq_mat_init(Q, n, n); acb_mat_init(A, n, n); acb_mat_init(E, n, n); acb_mat_init(F, n, n); acb_mat_init(EF, n, n); acb_mat_init(G, n, n); _fmpq_mat_randtest_for_exp(Q, state, qbits); acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_exp(E, A, prec); acb_randtest(c, state, prec, 10); acb_mat_scalar_mul_acb(F, A, c, prec); acb_mat_exp(F, F, prec); acb_add_ui(d, c, 1, prec); acb_mat_scalar_mul_acb(G, A, d, prec); acb_mat_exp(G, G, prec); acb_mat_mul(EF, E, F, prec); if (!acb_mat_overlaps(EF, G)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("c = \n"); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("E = \n"); acb_mat_printd(E, 15); flint_printf("\n\n"); flint_printf("F = \n"); acb_mat_printd(F, 15); flint_printf("\n\n"); flint_printf("E*F = \n"); acb_mat_printd(EF, 15); flint_printf("\n\n"); flint_printf("G = \n"); acb_mat_printd(G, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(c); acb_clear(d); fmpq_mat_clear(Q); acb_mat_clear(A); acb_mat_clear(E); acb_mat_clear(F); acb_mat_clear(EF); acb_mat_clear(G); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-exp_taylor_sum.c000066400000000000000000000044531417376376500204170ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_sum_taylor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_mat_t A, S1, S2, S3; fmpz_t f; slong n, N, prec1, prec2; n = n_randint(state, 5); N = n_randint(state, 40); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); acb_mat_init(A, n, n); acb_mat_init(S1, n, n); acb_mat_init(S2, n, n); acb_mat_init(S3, n, n); fmpz_init(f); acb_mat_randtest(A, state, prec1, 10); acb_mat_randtest(S1, state, prec1, 10); acb_mat_randtest(S2, state, prec1, 10); acb_mat_exp_taylor_sum(S1, A, N, prec1); acb_mat_exp_taylor_sum(S2, A, N + 1, prec2); acb_mat_pow_ui(S3, A, N, prec2); fmpz_fac_ui(f, N); acb_mat_scalar_div_fmpz(S3, S3, f, prec2); acb_mat_add(S3, S3, S1, prec2); if (!acb_mat_overlaps(S2, S3)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, N = %wd\n", n, N); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("S1 = \n"); acb_mat_printd(S1, 15); flint_printf("\n\n"); flint_printf("S2 = \n"); acb_mat_printd(S2, 15); flint_printf("\n\n"); flint_printf("S3 = \n"); acb_mat_printd(S3, 15); flint_printf("\n\n"); flint_abort(); } acb_mat_exp_taylor_sum(A, A, N, prec1); if (!acb_mat_overlaps(A, S1)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_mat_clear(A); acb_mat_clear(S1); acb_mat_clear(S2); acb_mat_clear(S3); fmpz_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-frobenius_norm.c000066400000000000000000000167451417376376500204030ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" static void _acb_mat_set_fmpq_mat_fmpq_mat(acb_mat_t C, const fmpq_mat_t rsrc, const fmpq_mat_t isrc, slong prec) { slong i, j; for (i = 0; i < acb_mat_nrows(C); i++) { for (j = 0; j < acb_mat_ncols(C); j++) { arb_set_fmpq(acb_realref(acb_mat_entry(C, i, j)), fmpq_mat_entry(rsrc, i, j), prec); arb_set_fmpq(acb_imagref(acb_mat_entry(C, i, j)), fmpq_mat_entry(isrc, i, j), prec); } } } static void _acb_mat_conjugate_transpose(acb_mat_t B, const acb_mat_t A) { slong i, j; acb_mat_transpose(B, A); for (i = 0; i < acb_mat_nrows(B); i++) for (j = 0; j < acb_mat_ncols(B); j++) acb_conj(acb_mat_entry(B, i, j), acb_mat_entry(B, i, j)); } static void _fmpq_mat_sum_of_squares(fmpq_t res, const fmpq_mat_t Q) { slong i, j; fmpq_zero(res); for (i = 0; i < fmpq_mat_nrows(Q); i++) { for (j = 0; j < fmpq_mat_ncols(Q); j++) { fmpq_addmul(res, fmpq_mat_entry(Q, i, j), fmpq_mat_entry(Q, i, j)); } } } int main() { slong iter; flint_rand_t state; flint_printf("frobenius_norm...."); fflush(stdout); flint_randinit(state); /* compare to the exact rational norm */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Qr, Qi; fmpq_t q; acb_mat_t A; slong n, qbits, prec; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Qr, n, n); fmpq_mat_init(Qi, n, n); fmpq_init(q); acb_mat_init(A, n, n); fmpq_mat_randtest(Qr, state, qbits); fmpq_mat_randtest(Qi, state, qbits); /* compute the square of the exact rational norm */ { fmpq_t qr, qi; fmpq_init(qr); fmpq_init(qi); _fmpq_mat_sum_of_squares(qr, Qr); _fmpq_mat_sum_of_squares(qi, Qi); fmpq_add(q, qr, qi); fmpq_clear(qr); fmpq_clear(qi); } _acb_mat_set_fmpq_mat_fmpq_mat(A, Qr, Qi, prec); /* check that the arb interval contains the exact value */ { arb_t a; arb_init(a); acb_mat_frobenius_norm(a, A, prec); arb_mul(a, a, a, prec); if (!arb_contains_fmpq(a, q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Qr = \n"); fmpq_mat_print(Qr); flint_printf("\n\n"); flint_printf("Qi = \n"); fmpq_mat_print(Qi); flint_printf("\n\n"); flint_printf("frobenius_norm(Q)^2 = \n"); fmpq_print(q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A)^2 = \n"); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A)^2 = \n"); arb_print(a); flint_printf("\n\n"); flint_abort(); } arb_clear(a); } /* check that the upper bound is not less than the exact value */ { mag_t b; fmpq_t y; mag_init(b); fmpq_init(y); acb_mat_bound_frobenius_norm(b, A); mag_mul(b, b, b); mag_get_fmpq(y, b); if (fmpq_cmp(q, y) > 0) { flint_printf("FAIL (bound, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Qr = \n"); fmpq_mat_print(Qr); flint_printf("\n\n"); flint_printf("Qi = \n"); fmpq_mat_print(Qi); flint_printf("\n\n"); flint_printf("frobenius_norm(Q)^2 = \n"); fmpq_print(q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A)^2 = \n"); mag_printd(b, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A)^2 = \n"); mag_print(b); flint_printf("\n\n"); flint_abort(); } mag_clear(b); fmpq_clear(y); } fmpq_mat_clear(Qr); fmpq_mat_clear(Qi); fmpq_clear(q); acb_mat_clear(A); } /* check trace(A^H A) = frobenius_norm(A)^2 */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, prec; acb_mat_t A, AH, AHA; acb_t t; prec = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); acb_mat_init(A, m, n); acb_mat_init(AH, n, m); acb_mat_init(AHA, n, n); acb_init(t); acb_mat_randtest(A, state, 2 + n_randint(state, 100), 10); _acb_mat_conjugate_transpose(AH, A); acb_mat_mul(AHA, AH, A, prec); acb_mat_trace(t, AHA, prec); acb_sqrt(t, t, prec); /* check the norm bound */ { mag_t low, frobenius; mag_init(low); acb_get_mag_lower(low, t); mag_init(frobenius); acb_mat_bound_frobenius_norm(frobenius, A); if (mag_cmp(low, frobenius) > 0) { flint_printf("FAIL (frobenius norm bound)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("lower(sqrt(trace(A^H A))) = \n"); mag_printd(low, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A) = \n"); mag_printd(frobenius, 15); flint_printf("\n\n"); flint_abort(); } mag_clear(low); mag_clear(frobenius); } /* check the norm interval */ { arb_t frobenius; arb_init(frobenius); acb_mat_frobenius_norm(frobenius, A, prec); if (!arb_overlaps(acb_realref(t), frobenius)) { flint_printf("FAIL (frobenius norm overlap)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("sqrt(trace(A^H A)) = \n"); acb_printd(t, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A) = \n"); arb_printd(frobenius, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(frobenius); } acb_mat_clear(A); acb_mat_clear(AH); acb_mat_clear(AHA); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-inv.c000066400000000000000000000074431417376376500161430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("inv...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, Qinv; acb_mat_t A, Ainv; slong n, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(Qinv, n, n); acb_mat_init(A, n, n); acb_mat_init(Ainv, n, n); fmpq_mat_randtest(Q, state, qbits); q_invertible = fmpq_mat_inv(Qinv, Q); if (!q_invertible) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_inv(Ainv, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); acb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_inv(Ainv, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!acb_mat_contains_fmpq_mat(Ainv, Qinv)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qinv = \n"); fmpq_mat_print(Qinv); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); acb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = acb_mat_inv(A, A, prec); if (!acb_mat_equal(A, Ainv) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); acb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(Qinv); acb_mat_clear(A); acb_mat_clear(Ainv); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-lu.c000066400000000000000000000103611417376376500157600ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int fmpq_mat_is_invertible(const fmpq_mat_t A) { int r; fmpq_t t; fmpq_init(t); fmpq_mat_det(t, A); r = !fmpq_is_zero(t); fmpq_clear(t); return r; } int main() { slong iter; flint_rand_t state; flint_printf("lu...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; acb_mat_t A, LU, P, L, U, T; slong i, j, n, qbits, prec, *perm; int q_invertible, r_invertible; n = n_randint(state, 10); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 202); fmpq_mat_init(Q, n, n); acb_mat_init(A, n, n); acb_mat_init(LU, n, n); acb_mat_init(P, n, n); acb_mat_init(L, n, n); acb_mat_init(U, n, n); acb_mat_init(T, n, n); perm = _perm_init(n); fmpq_mat_randtest(Q, state, qbits); q_invertible = fmpq_mat_is_invertible(Q); if (!q_invertible) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_lu(perm, LU, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); acb_mat_printd(LU, 15); flint_printf("\n\n"); } } else { /* now this must converge */ while (1) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_lu(perm, LU, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_abort(); } prec *= 2; } } acb_mat_one(L); for (i = 0; i < n; i++) for (j = 0; j < i; j++) acb_set(acb_mat_entry(L, i, j), acb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) for (j = i; j < n; j++) acb_set(acb_mat_entry(U, i, j), acb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) acb_one(acb_mat_entry(P, perm[i], i)); acb_mat_mul(T, P, L, prec); acb_mat_mul(T, T, U, prec); if (!acb_mat_contains_fmpq_mat(T, Q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); acb_mat_printd(LU, 15); flint_printf("\n\n"); flint_printf("L = \n"); acb_mat_printd(L, 15); flint_printf("\n\n"); flint_printf("U = \n"); acb_mat_printd(U, 15); flint_printf("\n\n"); flint_printf("P*L*U = \n"); acb_mat_printd(T, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); acb_mat_clear(A); acb_mat_clear(LU); acb_mat_clear(P); acb_mat_clear(L); acb_mat_clear(U); acb_mat_clear(T); _perm_clear(perm); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-lu_recursive.c000066400000000000000000000122101417376376500200420ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int fmpq_mat_is_invertible(const fmpq_mat_t A) { int r; fmpq_t t; fmpq_init(t); fmpq_mat_det(t, A); r = !fmpq_is_zero(t); fmpq_clear(t); return r; } int main() { slong iter; flint_rand_t state; flint_printf("lu_recursive...."); fflush(stdout); flint_randinit(state); /* Dummy test with rectangular matrices. Rectangular matrices are not actually supported (the output may be bogus), but the algorithm should at least not crash. */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, prec; slong *perm; acb_mat_t A, LU; n = n_randint(state, 20); m = n_randint(state, 20); prec = 2 + n_randint(state, 200); acb_mat_init(A, n, m); acb_mat_init(LU, n, m); perm = _perm_init(n); acb_mat_randtest(A, state, prec, 10); if (n_randint(state, 2)) { acb_mat_lu_recursive(perm, LU, A, prec); } else { acb_mat_set(LU, A); acb_mat_lu_recursive(perm, LU, LU, prec); } acb_mat_clear(A); acb_mat_clear(LU); _perm_clear(perm); } for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; acb_mat_t A, LU, P, L, U, T; slong i, j, n, qbits, prec, *perm; int q_invertible, r_invertible; n = n_randint(state, 20); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 202); fmpq_mat_init(Q, n, n); acb_mat_init(A, n, n); acb_mat_init(LU, n, n); acb_mat_init(P, n, n); acb_mat_init(L, n, n); acb_mat_init(U, n, n); acb_mat_init(T, n, n); perm = _perm_init(n); fmpq_mat_randtest(Q, state, qbits); q_invertible = fmpq_mat_is_invertible(Q); if (!q_invertible) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_lu_recursive(perm, LU, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); acb_mat_printd(LU, 15); flint_printf("\n\n"); } } else { /* now this must converge */ while (1) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_lu_recursive(perm, LU, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_abort(); } prec *= 2; } } acb_mat_one(L); for (i = 0; i < n; i++) for (j = 0; j < i; j++) acb_set(acb_mat_entry(L, i, j), acb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) for (j = i; j < n; j++) acb_set(acb_mat_entry(U, i, j), acb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) acb_one(acb_mat_entry(P, perm[i], i)); acb_mat_mul(T, P, L, prec); acb_mat_mul(T, T, U, prec); if (!acb_mat_contains_fmpq_mat(T, Q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); acb_mat_printd(LU, 15); flint_printf("\n\n"); flint_printf("L = \n"); acb_mat_printd(L, 15); flint_printf("\n\n"); flint_printf("U = \n"); acb_mat_printd(U, 15); flint_printf("\n\n"); flint_printf("P*L*U = \n"); acb_mat_printd(T, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); acb_mat_clear(A); acb_mat_clear(LU); acb_mat_clear(P); acb_mat_clear(L); acb_mat_clear(U); acb_mat_clear(T); _perm_clear(perm); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-mul.c000066400000000000000000000212251417376376500161360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void _acb_mat_init_randtest(acb_mat_t mat, slong r, slong c, flint_rand_t state) { acb_mat_init(mat, r, c); acb_mat_randtest(mat, state, 2 + n_randint(state, 200), 10); } void _acb_mat_nprintd(const char * name, acb_mat_t mat) { flint_printf("%s = ", name); acb_mat_printd(mat, 15); flint_printf("\n\n"); } int main() { slong iter; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, k, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; acb_mat_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); k = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, n, k); fmpq_mat_init(C, m, k); acb_mat_init(a, m, n); acb_mat_init(b, n, k); acb_mat_init(c, m, k); acb_mat_init(d, m, k); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); fmpq_mat_mul(C, A, B); acb_mat_set_fmpq_mat(a, A, rbits1); acb_mat_set_fmpq_mat(b, B, rbits2); acb_mat_mul(c, a, b, rbits3); if (!acb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd, k = %wd, bits3 = %wd\n", m, n, k, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (acb_mat_nrows(a) == acb_mat_nrows(c) && acb_mat_ncols(a) == acb_mat_ncols(c)) { acb_mat_set(d, a); acb_mat_mul(d, d, b, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (acb_mat_nrows(b) == acb_mat_nrows(c) && acb_mat_ncols(b) == acb_mat_ncols(c)) { acb_mat_set(d, b); acb_mat_mul(d, a, d, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); } /* check algebraic properties like associativity and distributivity */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, k, l; slong rbits; acb_mat_t a, b, c, d, ab, ac, bd, cd, s; rbits = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); k = n_randint(state, 10); l = n_randint(state, 10); _acb_mat_init_randtest(a, m, n, state); _acb_mat_init_randtest(b, n, k, state); _acb_mat_init_randtest(c, n, k, state); _acb_mat_init_randtest(d, k, l, state); acb_mat_init(ab, m, k); acb_mat_init(ac, m, k); acb_mat_init(bd, n, l); acb_mat_init(cd, n, l); acb_mat_init(s, n, k); acb_mat_mul(ab, a, b, rbits); acb_mat_mul(ac, a, c, rbits); acb_mat_mul(bd, b, d, rbits); acb_mat_mul(cd, c, d, rbits); acb_mat_add(s, b, c, rbits); /* check associativity of multiplication */ /* (A*B)*D = A*(B*D) */ { acb_mat_t lhs, rhs; acb_mat_init(lhs, m, l); acb_mat_init(rhs, m, l); acb_mat_mul(lhs, ab, d, rbits); acb_mat_mul(rhs, a, bd, rbits); if (!acb_mat_overlaps(lhs, rhs)) { flint_printf("FAIL\n\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("a", a); _acb_mat_nprintd("b", b); _acb_mat_nprintd("d", d); _acb_mat_nprintd("(a*b)*d", lhs); _acb_mat_nprintd("a*(b*d)", rhs); flint_abort(); } acb_mat_clear(lhs); acb_mat_clear(rhs); } /* check left distributivity of multiplication over addition */ /* A*(B + C) = A*B + A*C */ { acb_mat_t lhs, rhs; acb_mat_init(lhs, m, k); acb_mat_init(rhs, m, k); acb_mat_mul(lhs, a, s, rbits); acb_mat_add(rhs, ab, ac, rbits); if (!acb_mat_overlaps(lhs, rhs)) { flint_printf("FAIL\n\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("a", a); _acb_mat_nprintd("b", b); _acb_mat_nprintd("c", c); _acb_mat_nprintd("a*(b + c)", lhs); _acb_mat_nprintd("a*b + b*c", rhs); flint_abort(); } acb_mat_clear(lhs); acb_mat_clear(rhs); } /* check right distributivity of multiplication over addition */ /* (B + C)*D = B*D + C*D */ { acb_mat_t lhs, rhs; acb_mat_init(lhs, n, l); acb_mat_init(rhs, n, l); acb_mat_mul(lhs, s, d, rbits); acb_mat_add(rhs, bd, cd, rbits); if (!acb_mat_overlaps(lhs, rhs)) { flint_printf("FAIL\n\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("b", b); _acb_mat_nprintd("c", c); _acb_mat_nprintd("d", d); _acb_mat_nprintd("(b + c)*d", lhs); _acb_mat_nprintd("b*d + c*d", rhs); flint_abort(); } acb_mat_clear(lhs); acb_mat_clear(rhs); } /* check left multiplicative identity I*D = D */ { acb_mat_t one, lhs; acb_mat_init(one, k, k); acb_mat_init(lhs, k, l); acb_mat_one(one); acb_mat_mul(lhs, one, d, rbits); if (!acb_mat_contains(lhs, d)) { flint_printf("FAIL\n\n"); flint_printf("k = %wd, l = %wd\n", k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("identity * d", lhs); _acb_mat_nprintd("d", d); flint_abort(); } acb_mat_clear(one); acb_mat_clear(lhs); } /* check right multiplicative identity A*I = A */ { acb_mat_t one, lhs; acb_mat_init(one, n, n); acb_mat_init(lhs, m, n); acb_mat_one(one); acb_mat_mul(lhs, a, one, rbits); if (!acb_mat_contains(lhs, a)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd\n", m, n); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("a * identity", lhs); _acb_mat_nprintd("a", a); flint_abort(); } acb_mat_clear(one); acb_mat_clear(lhs); } acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); acb_mat_clear(ab); acb_mat_clear(ac); acb_mat_clear(bd); acb_mat_clear(cd); acb_mat_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-mul_entrywise.c000066400000000000000000000070601417376376500202500ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void _fmpq_mat_mul_entrywise(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B) { slong i, j; for (i = 0; i < fmpq_mat_nrows(A); i++) { for (j = 0; j < fmpq_mat_ncols(A); j++) { fmpq_mul(fmpq_mat_entry(C, i, j), fmpq_mat_entry(A, i, j), fmpq_mat_entry(B, i, j)); } } } int main() { slong iter; flint_rand_t state; flint_printf("mul_entrywise...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; acb_mat_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, m, n); fmpq_mat_init(C, m, n); acb_mat_init(a, m, n); acb_mat_init(b, m, n); acb_mat_init(c, m, n); acb_mat_init(d, m, n); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); _fmpq_mat_mul_entrywise(C, A, B); acb_mat_set_fmpq_mat(a, A, rbits1); acb_mat_set_fmpq_mat(b, B, rbits2); acb_mat_mul_entrywise(c, a, b, rbits3); if (!acb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd, bits3 = %wd\n", m, n, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (acb_mat_nrows(a) == acb_mat_nrows(c) && acb_mat_ncols(a) == acb_mat_ncols(c)) { acb_mat_set(d, a); acb_mat_mul_entrywise(d, d, b, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (acb_mat_nrows(b) == acb_mat_nrows(c) && acb_mat_ncols(b) == acb_mat_ncols(c)) { acb_mat_set(d, b); acb_mat_mul_entrywise(d, a, d, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-mul_reorder.c000066400000000000000000000253031417376376500176610ustar00rootroot00000000000000/* Copyright (C) 2012, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void _acb_mat_init_randtest(acb_mat_t mat, slong r, slong c, flint_rand_t state) { acb_mat_init(mat, r, c); acb_mat_randtest(mat, state, 2 + n_randint(state, 200), 10); } void _acb_mat_nprintd(const char * name, acb_mat_t mat) { flint_printf("%s = ", name); acb_mat_printd(mat, 15); flint_printf("\n\n"); } int main() { slong iter; flint_rand_t state; flint_printf("mul_reorder...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, k, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; acb_mat_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 8); n = n_randint(state, 8); k = n_randint(state, 8); fmpq_mat_init(A, m, n); fmpq_mat_init(B, n, k); fmpq_mat_init(C, m, k); acb_mat_init(a, m, n); acb_mat_init(b, n, k); _acb_mat_init_randtest(c, m, k, state); _acb_mat_init_randtest(d, m, k, state); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); fmpq_mat_mul(C, A, B); acb_mat_set_fmpq_mat(a, A, rbits1); acb_mat_set_fmpq_mat(b, B, rbits2); acb_mat_mul_reorder(c, a, b, rbits3); if (!acb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd, k = %wd, bits3 = %wd\n", m, n, k, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (acb_mat_nrows(a) == acb_mat_nrows(c) && acb_mat_ncols(a) == acb_mat_ncols(c)) { acb_mat_set(d, a); acb_mat_mul_reorder(d, d, b, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (acb_mat_nrows(b) == acb_mat_nrows(c) && acb_mat_ncols(b) == acb_mat_ncols(c)) { acb_mat_set(d, b); acb_mat_mul_reorder(d, a, d, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); } /* general aliasing test */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n; slong rbits; acb_mat_t a, b, c, d; rbits = 2 + n_randint(state, 200); m = n_randint(state, 8); n = n_randint(state, 8); _acb_mat_init_randtest(a, m, n, state); _acb_mat_init_randtest(b, n, n, state); _acb_mat_init_randtest(c, m, n, state); _acb_mat_init_randtest(d, m, n, state); acb_mat_mul_reorder(c, a, b, rbits); acb_mat_set(d, a); acb_mat_mul_reorder(d, d, b, rbits); if (!acb_mat_equal(c, d)) { flint_printf("FAIL (aliasing 3)\n\n"); _acb_mat_nprintd("a", a); _acb_mat_nprintd("b", b); _acb_mat_nprintd("c", d); _acb_mat_nprintd("d", d); flint_abort(); } acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); _acb_mat_init_randtest(a, m, m, state); _acb_mat_init_randtest(b, m, n, state); _acb_mat_init_randtest(c, m, n, state); _acb_mat_init_randtest(d, m, n, state); acb_mat_mul_reorder(c, a, b, rbits); acb_mat_set(d, b); acb_mat_mul_reorder(d, a, d, rbits); if (!acb_mat_equal(c, d)) { flint_printf("FAIL (aliasing 4)\n\n"); _acb_mat_nprintd("a", a); _acb_mat_nprintd("b", b); _acb_mat_nprintd("c", d); _acb_mat_nprintd("d", d); flint_abort(); } acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); } /* check algebraic properties like associativity and distributivity */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, k, l; slong rbits; acb_mat_t a, b, c, d, ab, ac, bd, cd, s; rbits = 2 + n_randint(state, 200); m = n_randint(state, 8); n = n_randint(state, 8); k = n_randint(state, 8); l = n_randint(state, 8); _acb_mat_init_randtest(a, m, n, state); _acb_mat_init_randtest(b, n, k, state); _acb_mat_init_randtest(c, n, k, state); _acb_mat_init_randtest(d, k, l, state); _acb_mat_init_randtest(ab, m, k, state); _acb_mat_init_randtest(ac, m, k, state); _acb_mat_init_randtest(bd, n, l, state); _acb_mat_init_randtest(cd, n, l, state); _acb_mat_init_randtest(s, n, k, state); acb_mat_mul_reorder(ab, a, b, rbits); acb_mat_mul_reorder(ac, a, c, rbits); acb_mat_mul_reorder(bd, b, d, rbits); acb_mat_mul_reorder(cd, c, d, rbits); acb_mat_add(s, b, c, rbits); /* check associativity of multiplication */ /* (A*B)*D = A*(B*D) */ { acb_mat_t lhs, rhs; _acb_mat_init_randtest(lhs, m, l, state); _acb_mat_init_randtest(rhs, m, l, state); acb_mat_mul_reorder(lhs, ab, d, rbits); acb_mat_mul_reorder(rhs, a, bd, rbits); if (!acb_mat_overlaps(lhs, rhs)) { flint_printf("FAIL\n\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("a", a); _acb_mat_nprintd("b", b); _acb_mat_nprintd("d", d); _acb_mat_nprintd("(a*b)*d", lhs); _acb_mat_nprintd("a*(b*d)", rhs); flint_abort(); } acb_mat_clear(lhs); acb_mat_clear(rhs); } /* check left distributivity of multiplication over addition */ /* A*(B + C) = A*B + A*C */ { acb_mat_t lhs, rhs; _acb_mat_init_randtest(lhs, m, k, state); _acb_mat_init_randtest(rhs, m, k, state); acb_mat_mul_reorder(lhs, a, s, rbits); acb_mat_add(rhs, ab, ac, rbits); if (!acb_mat_overlaps(lhs, rhs)) { flint_printf("FAIL\n\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("a", a); _acb_mat_nprintd("b", b); _acb_mat_nprintd("c", c); _acb_mat_nprintd("a*(b + c)", lhs); _acb_mat_nprintd("a*b + b*c", rhs); flint_abort(); } acb_mat_clear(lhs); acb_mat_clear(rhs); } /* check right distributivity of multiplication over addition */ /* (B + C)*D = B*D + C*D */ { acb_mat_t lhs, rhs; _acb_mat_init_randtest(lhs, n, l, state); _acb_mat_init_randtest(rhs, n, l, state); acb_mat_mul_reorder(lhs, s, d, rbits); acb_mat_add(rhs, bd, cd, rbits); if (!acb_mat_overlaps(lhs, rhs)) { flint_printf("FAIL\n\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("b", b); _acb_mat_nprintd("c", c); _acb_mat_nprintd("d", d); _acb_mat_nprintd("(b + c)*d", lhs); _acb_mat_nprintd("b*d + c*d", rhs); flint_abort(); } acb_mat_clear(lhs); acb_mat_clear(rhs); } /* check left multiplicative identity I*D = D */ { acb_mat_t one, lhs; _acb_mat_init_randtest(one, k, k, state); _acb_mat_init_randtest(lhs, k, l, state); acb_mat_one(one); acb_mat_mul_reorder(lhs, one, d, rbits); if (!acb_mat_contains(lhs, d)) { flint_printf("FAIL\n\n"); flint_printf("k = %wd, l = %wd\n", k, l); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("identity * d", lhs); _acb_mat_nprintd("d", d); flint_abort(); } acb_mat_clear(one); acb_mat_clear(lhs); } /* check right multiplicative identity A*I = A */ { acb_mat_t one, lhs; _acb_mat_init_randtest(one, n, n, state); _acb_mat_init_randtest(lhs, m, n, state); acb_mat_one(one); acb_mat_mul_reorder(lhs, a, one, rbits); if (!acb_mat_contains(lhs, a)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd\n", m, n); flint_printf("rbits = %wd\n", rbits); _acb_mat_nprintd("a * identity", lhs); _acb_mat_nprintd("a", a); flint_abort(); } acb_mat_clear(one); acb_mat_clear(lhs); } acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); acb_mat_clear(ab); acb_mat_clear(ac); acb_mat_clear(bd); acb_mat_clear(cd); acb_mat_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-mul_threaded.c000066400000000000000000000065311417376376500200010ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_threaded...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { slong m, n, k, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; acb_mat_t a, b, c, d; flint_set_num_threads(1 + n_randint(state, 5)); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); k = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, n, k); fmpq_mat_init(C, m, k); acb_mat_init(a, m, n); acb_mat_init(b, n, k); acb_mat_init(c, m, k); acb_mat_init(d, m, k); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); fmpq_mat_mul(C, A, B); acb_mat_set_fmpq_mat(a, A, rbits1); acb_mat_set_fmpq_mat(b, B, rbits2); acb_mat_mul_threaded(c, a, b, rbits3); if (!acb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("threads = %d, m = %wd, n = %wd, k = %wd, bits3 = %wd\n", flint_get_num_threads(), m, n, k, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (acb_mat_nrows(a) == acb_mat_nrows(c) && acb_mat_ncols(a) == acb_mat_ncols(c)) { acb_mat_set(d, a); acb_mat_mul_threaded(d, d, b, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (acb_mat_nrows(b) == acb_mat_nrows(c) && acb_mat_ncols(b) == acb_mat_ncols(c)) { acb_mat_set(d, b); acb_mat_mul_threaded(d, a, d, rbits3); if (!acb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); acb_mat_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-solve.c000066400000000000000000000110331417376376500164650ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; acb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 10); m = n_randint(state, 10); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); acb_mat_init(A, n, n); acb_mat_init(X, n, m); acb_mat_init(B, n, m); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_solve(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_set_fmpq_mat(B, QB, prec); r_invertible = acb_mat_solve(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!acb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = acb_mat_solve(B, A, B, prec); if (!acb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-solve_lu.c000066400000000000000000000110471417376376500171720ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_lu...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; acb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 10); m = n_randint(state, 10); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); acb_mat_init(A, n, n); acb_mat_init(X, n, m); acb_mat_init(B, n, m); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_solve_lu(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_set_fmpq_mat(B, QB, prec); r_invertible = acb_mat_solve_lu(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!acb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = acb_mat_solve_lu(B, A, B, prec); if (!acb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-solve_precond.c000066400000000000000000000135461417376376500202120ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_precond...."); fflush(stdout); flint_randinit(state); /* test random matrices, to test complex solving */ for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_mat_t A, X, B, Y; slong n, m, prec; n = n_randint(state, 10); m = n_randint(state, 10); acb_mat_init(A, n, n); acb_mat_init(X, n, m); acb_mat_init(B, n, m); acb_mat_init(Y, n, m); prec = 2 + n_randint(state, 200); acb_mat_randtest(A, state, 200, 1 + n_randint(state, 10)); acb_mat_randtest(X, state, 200, 1 + n_randint(state, 10)); acb_mat_randtest(Y, state, 200, 1 + n_randint(state, 10)); acb_mat_mul(B, A, X, prec); if (acb_mat_solve_precond(Y, A, B, prec)) { if (!acb_mat_contains(Y, X)) { flint_printf("FAIL: containment\n"); flint_printf("A = \n"); acb_mat_printd(A, 30); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(A, 30); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(A, 30); flint_printf("\n\n"); flint_printf("Y = \n"); acb_mat_printd(A, 30); flint_printf("\n\n"); flint_abort(); } } acb_mat_clear(A); acb_mat_clear(X); acb_mat_clear(B); acb_mat_clear(Y); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; acb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); m = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); acb_mat_init(A, n, n); acb_mat_init(X, n, m); acb_mat_init(B, n, m); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { acb_mat_set_fmpq_mat(A, Q, prec); r_invertible = acb_mat_solve_precond(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over C\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_set_fmpq_mat(B, QB, prec); r_invertible = acb_mat_solve_precond(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!acb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = acb_mat_solve_precond(B, A, B, prec); if (!acb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-solve_tril.c000066400000000000000000000061361417376376500175270ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_tril...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_mat_t A, X, B, Y; slong rows, cols, prec, i, j; int unit; prec = 2 + n_randint(state, 200); if (n_randint(state, 10) == 0) { rows = n_randint(state, 60); cols = n_randint(state, 60); } else { rows = n_randint(state, 10); cols = n_randint(state, 10); } unit = n_randint(state, 2); acb_mat_init(A, rows, rows); acb_mat_init(B, rows, cols); acb_mat_init(X, rows, cols); acb_mat_init(Y, rows, cols); acb_mat_randtest(A, state, prec, 10); acb_mat_randtest(X, state, prec, 10); acb_mat_randtest(Y, state, prec, 10); for (i = 0; i < rows; i++) { if (unit) acb_one(acb_mat_entry(A, i, i)); else acb_set_ui(acb_mat_entry(A, i, i), 1 + n_randint(state, 100)); for (j = i + 1; j < rows; j++) acb_zero(acb_mat_entry(A, i, j)); } acb_mat_mul(B, A, X, prec); if (unit) /* check that diagonal entries are ignored */ { for (i = 0; i < rows; i++) acb_set_ui(acb_mat_entry(A, i, i), 1 + n_randint(state, 100)); } /* Check Y = A^(-1) * (A * X) = X */ acb_mat_solve_tril(Y, A, B, unit, prec); if (!acb_mat_overlaps(Y, X)) { flint_printf("FAIL\n"); flint_printf("A = \n"); acb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); acb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } /* Check aliasing */ acb_mat_solve_tril(B, A, B, unit, prec); if (!acb_mat_equal(B, Y)) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); acb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); acb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(X); acb_mat_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-solve_triu.c000066400000000000000000000061271417376376500175400ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_triu...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_mat_t A, X, B, Y; slong rows, cols, prec, i, j; int unit; prec = 2 + n_randint(state, 200); if (n_randint(state, 10) == 0) { rows = n_randint(state, 60); cols = n_randint(state, 60); } else { rows = n_randint(state, 10); cols = n_randint(state, 10); } unit = n_randint(state, 2); acb_mat_init(A, rows, rows); acb_mat_init(B, rows, cols); acb_mat_init(X, rows, cols); acb_mat_init(Y, rows, cols); acb_mat_randtest(A, state, prec, 10); acb_mat_randtest(X, state, prec, 10); acb_mat_randtest(Y, state, prec, 10); for (i = 0; i < rows; i++) { if (unit) acb_one(acb_mat_entry(A, i, i)); else acb_set_ui(acb_mat_entry(A, i, i), 1 + n_randint(state, 100)); for (j = 0; j < i; j++) acb_zero(acb_mat_entry(A, i, j)); } acb_mat_mul(B, A, X, prec); if (unit) /* check that diagonal entries are ignored */ { for (i = 0; i < rows; i++) acb_set_ui(acb_mat_entry(A, i, i), 1 + n_randint(state, 100)); } /* Check Y = A^(-1) * (A * X) = X */ acb_mat_solve_triu(Y, A, B, unit, prec); if (!acb_mat_overlaps(Y, X)) { flint_printf("FAIL\n"); flint_printf("A = \n"); acb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); acb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } /* Check aliasing */ acb_mat_solve_triu(B, A, B, unit, prec); if (!acb_mat_equal(B, Y)) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); acb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); acb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); acb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); acb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(X); acb_mat_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-sqr.c000066400000000000000000000041451417376376500161500ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("sqr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong n, qbits1, rbits1, rbits2; fmpq_mat_t A, B; acb_mat_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = n_randint(state, 10); fmpq_mat_init(A, n, n); fmpq_mat_init(B, n, n); acb_mat_init(a, n, n); acb_mat_init(b, n, n); acb_mat_init(c, n, n); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_mul(B, A, A); acb_mat_set_fmpq_mat(a, A, rbits1); acb_mat_sqr(b, a, rbits2); if (!acb_mat_contains_fmpq_mat(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_mat_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ acb_mat_set(c, a); acb_mat_sqr(c, c, rbits2); if (!acb_mat_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_mat_clear(A); fmpq_mat_clear(B); acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-trace.c000066400000000000000000000072651417376376500164470ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("trace...."); fflush(stdout); flint_randinit(state); /* check that the acb trace contains the fmpq trace */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; fmpq_t Qtrace; acb_mat_t A; acb_t Atrace; slong n, qbits, prec; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_init(Qtrace); acb_mat_init(A, n, n); acb_init(Atrace); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_trace(Qtrace, Q); acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_trace(Atrace, A, prec); if (!acb_contains_fmpq(Atrace, Qtrace)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qtrace = \n"); fmpq_print(Qtrace); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Atrace = \n"); acb_printd(Atrace, 15); flint_printf("\n\n"); flint_printf("Atrace = \n"); acb_print(Atrace); flint_printf("\n\n"); flint_abort(); } fmpq_mat_clear(Q); fmpq_clear(Qtrace); acb_mat_clear(A); acb_clear(Atrace); } /* check trace(A*B) = trace(B*A) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, prec; acb_mat_t a, b, ab, ba; acb_t trab, trba; prec = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); acb_mat_init(a, m, n); acb_mat_init(b, n, m); acb_mat_init(ab, m, m); acb_mat_init(ba, n, n); acb_init(trab); acb_init(trba); acb_mat_randtest(a, state, 2 + n_randint(state, 100), 10); acb_mat_randtest(b, state, 2 + n_randint(state, 100), 10); acb_mat_mul(ab, a, b, prec); acb_mat_mul(ba, b, a, prec); acb_mat_trace(trab, ab, prec); acb_mat_trace(trba, ba, prec); if (!acb_overlaps(trab, trba)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("a = \n"); acb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = \n"); acb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("ab = \n"); acb_mat_printd(ab, 15); flint_printf("\n\n"); flint_printf("ba = \n"); acb_mat_printd(ba, 15); flint_printf("\n\n"); flint_printf("trace(ab) = \n"); acb_printd(trab, 15); flint_printf("\n\n"); flint_printf("trace(ba) = \n"); acb_printd(trba, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(trab); acb_clear(trba); acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(ab); acb_mat_clear(ba); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/test/t-transpose.c000066400000000000000000000033261417376376500173610ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("transpose...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n; acb_mat_t a, b, c; m = n_randint(state, 10); n = n_randint(state, 10); acb_mat_init(a, m, n); acb_mat_init(b, n, m); acb_mat_init(c, m, n); acb_mat_randtest(a, state, 2 + n_randint(state, 100), 10); acb_mat_randtest(b, state, 2 + n_randint(state, 100), 10); acb_mat_randtest(c, state, 2 + n_randint(state, 100), 10); acb_mat_transpose(b, a); acb_mat_transpose(c, b); if (!acb_mat_equal(c, a)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd\n", m, n); flint_abort(); } if (acb_mat_nrows(a) == acb_mat_ncols(a)) { acb_mat_transpose(c, a); acb_mat_transpose(a, a); if (!acb_mat_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } } acb_mat_clear(a); acb_mat_clear(b); acb_mat_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_mat/trace.c000066400000000000000000000015461417376376500152230ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_trace(acb_t trace, const acb_mat_t mat, slong prec) { slong i; if (!acb_mat_is_square(mat)) { flint_printf("acb_mat_trace: a square matrix is required!\n"); flint_abort(); } if (acb_mat_is_empty(mat)) { acb_zero(trace); return; } acb_set(trace, acb_mat_entry(mat, 0, 0)); for (i = 1; i < acb_mat_nrows(mat); i++) { acb_add(trace, trace, acb_mat_entry(mat, i, i), prec); } } arb-2.22.1/acb_mat/transpose.c000066400000000000000000000023401417376376500161340ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_transpose(acb_mat_t B, const acb_mat_t A) { slong i, j; if (acb_mat_nrows(B) != acb_mat_ncols(A) || acb_mat_ncols(B) != acb_mat_nrows(A)) { flint_printf("Exception (acb_mat_transpose). Incompatible dimensions.\n"); flint_abort(); } if (acb_mat_is_empty(A)) return; if (A == B) /* In-place, guaranteed to be square */ { for (i = 0; i < acb_mat_nrows(A) - 1; i++) { for (j = i + 1; j < acb_mat_ncols(A); j++) { acb_swap(acb_mat_entry(A, i, j), acb_mat_entry(A, j, i)); } } } else /* Not aliased; general case */ { for (i = 0; i < acb_mat_nrows(B); i++) for (j = 0; j < acb_mat_ncols(B); j++) acb_set(acb_mat_entry(B, i, j), acb_mat_entry(A, j, i)); } } arb-2.22.1/acb_mat/window_init.c000066400000000000000000000013631417376376500164540ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_window_init(acb_mat_t window, const acb_mat_t mat, slong r1, slong c1, slong r2, slong c2) { slong i; window->entries = NULL; window->rows = flint_malloc((r2 - r1) * sizeof(acb_ptr)); for (i = 0; i < r2 - r1; i++) window->rows[i] = mat->rows[r1 + i] + c1; window->r = r2 - r1; window->c = c2 - c1; } arb-2.22.1/acb_mat/zero.c000066400000000000000000000011261417376376500150760ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_mat.h" void acb_mat_zero(acb_mat_t mat) { slong i, j; for (i = 0; i < acb_mat_nrows(mat); i++) for (j = 0; j < acb_mat_ncols(mat); j++) acb_zero(acb_mat_entry(mat, i, j)); } arb-2.22.1/acb_modular.h000066400000000000000000000131701417376376500150100ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_MODULAR_H #define ACB_MODULAR_H #include #include "flint/fmpz_poly.h" #include "acb.h" #include "acb_poly.h" #ifdef __cplusplus extern "C" { #endif typedef struct { fmpz a; fmpz b; fmpz c; fmpz d; } psl2z_struct; typedef psl2z_struct psl2z_t[1]; static __inline__ void psl2z_init(psl2z_t g) { fmpz_init(&g->a); fmpz_init(&g->b); fmpz_init(&g->c); fmpz_init(&g->d); fmpz_one(&g->a); fmpz_one(&g->d); } static __inline__ void psl2z_clear(psl2z_t g) { fmpz_clear(&g->a); fmpz_clear(&g->b); fmpz_clear(&g->c); fmpz_clear(&g->d); } static __inline__ void psl2z_swap(psl2z_t f, psl2z_t g) { psl2z_struct h = *f; *f = *g; *g = h; } static __inline__ void psl2z_set(psl2z_t h, const psl2z_t g) { fmpz_set(&h->a, &g->a); fmpz_set(&h->b, &g->b); fmpz_set(&h->c, &g->c); fmpz_set(&h->d, &g->d); } static __inline__ void psl2z_one(psl2z_t g) { fmpz_one(&g->a); fmpz_zero(&g->b); fmpz_zero(&g->c); fmpz_one(&g->d); } static __inline__ void psl2z_fprint(FILE * file, const psl2z_t g) { flint_fprintf(file, "["); fmpz_fprint(file, &g->a); flint_fprintf(file, " "); fmpz_fprint(file, &g->b); flint_fprintf(file, "; "); fmpz_fprint(file, &g->c); flint_fprintf(file, " "); fmpz_fprint(file, &g->d); flint_fprintf(file, "]"); } static __inline__ void psl2z_print(const psl2z_t g) { psl2z_fprint(stdout, g); } static __inline__ int psl2z_equal(const psl2z_t f, const psl2z_t g) { return fmpz_equal(&f->a, &g->a) && fmpz_equal(&f->b, &g->b) && fmpz_equal(&f->c, &g->c) && fmpz_equal(&f->d, &g->d); } void psl2z_mul(psl2z_t h, const psl2z_t f, const psl2z_t g); void psl2z_inv(psl2z_t h, const psl2z_t g); int psl2z_is_one(const psl2z_t g); int psl2z_is_correct(const psl2z_t g); void psl2z_randtest(psl2z_t g, flint_rand_t state, slong bits); void acb_modular_transform(acb_t w, const psl2z_t g, const acb_t z, slong prec); void acb_modular_fundamental_domain_approx_d(psl2z_t g, double x, double y, double one_minus_eps); void acb_modular_fundamental_domain_approx_arf(psl2z_t g, const arf_t xx, const arf_t yy, const arf_t one_minus_eps, slong prec); void acb_modular_fundamental_domain_approx(acb_t w, psl2z_t g, const acb_t z, const arf_t one_minus_eps, slong prec); int acb_modular_is_in_fundamental_domain(const acb_t z, const arf_t tol, slong prec); void acb_modular_addseq_theta(slong * exponents, slong * aindex, slong * bindex, slong num); void acb_modular_addseq_eta(slong * exponents, slong * aindex, slong * bindex, slong num); void acb_modular_fill_addseq(slong * tab, slong len); void acb_modular_theta_transform(int * R, int * S, int * C, const psl2z_t g); void acb_modular_theta_const_sum(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong prec); void acb_modular_theta_const_sum_basecase(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong N, slong prec); void acb_modular_theta_const_sum_rs(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong N, slong prec); void acb_modular_theta_sum(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t w, int w_is_unit, const acb_t q, slong len, slong prec); void acb_modular_theta_notransform(acb_t theta1, acb_t theta2, acb_t theta3, acb_t theta4, const acb_t z, const acb_t tau, slong prec); void acb_modular_theta(acb_t theta1, acb_t theta2, acb_t theta3, acb_t theta4, const acb_t z, const acb_t tau, slong prec); void acb_modular_theta_jet_notransform(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t z, const acb_t tau, slong len, slong prec); void acb_modular_theta_jet(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t z, const acb_t tau, slong len, slong prec); void _acb_modular_theta_series(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec); void acb_modular_theta_series(acb_poly_t theta1, acb_poly_t theta2, acb_poly_t theta3, acb_poly_t theta4, const acb_poly_t z, const acb_t tau, slong len, slong prec); void acb_modular_j(acb_t z, const acb_t tau, slong prec); int acb_modular_epsilon_arg(const psl2z_t g); void acb_modular_eta_sum(acb_t eta, const acb_t q, slong prec); void acb_modular_eta(acb_t z, const acb_t tau, slong prec); void acb_modular_lambda(acb_t r, const acb_t tau, slong prec); void acb_modular_delta(acb_t r, const acb_t tau, slong prec); void acb_modular_eisenstein(acb_ptr r, const acb_t tau, slong len, slong prec); void acb_modular_elliptic_p(acb_t r, const acb_t z, const acb_t tau, slong prec); void acb_modular_elliptic_p_zpx(acb_ptr r, const acb_t z, const acb_t tau, slong len, slong prec); void acb_modular_elliptic_k(acb_t k, const acb_t m, slong prec); void acb_modular_elliptic_k_cpx(acb_ptr w, const acb_t m, slong len, slong prec); void acb_modular_elliptic_e(acb_t res, const acb_t m, slong prec); void acb_modular_hilbert_class_poly(fmpz_poly_t res, slong D); /* this is a performance hack until the main arb/acb functions improve */ void _acb_modular_mul(acb_t z, acb_t tmp1, acb_t tmp2, const acb_t x, const acb_t y, slong wprec, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_modular/000077500000000000000000000000001417376376500146355ustar00rootroot00000000000000arb-2.22.1/acb_modular/addseq.c000066400000000000000000000066631417376376500162550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" static slong bisect(slong needle, const slong * haystack, slong len) { slong a, b, mid; a = 0; b = len - 1; while (a < b) { mid = (a + b) / 2; if (haystack[mid] < needle) a = mid + 1; else b = mid; } if (a == b && haystack[a] == needle) { return a; } return -1; } /* write p = 2a with a in P */ static int write_as_2a(slong * i1, slong * i2, slong p, const slong * P, slong Plen) { if (p % 2 == 0) { slong i = bisect(p / 2, P, Plen); if (i != -1) { *i1 = *i2 = i; return 1; } } return 0; } /* write p = a + b with a, b in P */ static int write_as_a_b(slong * i1, slong * i2, slong p, const slong * P, slong Plen) { slong i, j, pi; for (i = 0; i < Plen; i++) { pi = P[i]; j = bisect(p - pi, P, Plen); if (j != -1) { *i1 = i; *i2 = j; return 1; } } return 0; } /* write p = 2a + b with a, b in P */ static int write_as_2a_b(slong * i1, slong * i2, slong p, const slong * P, slong Plen) { slong i, j, pi; for (i = 0; i < Plen; i++) { pi = P[i]; if (2 * pi > p) break; j = bisect(p - 2*pi, P, Plen); if (j != -1) { *i1 = i; *i2 = j; return 1; } } return 0; } void acb_modular_addseq_theta(slong * exponents, slong * aindex, slong * bindex, slong num) { slong i; slong c; for (i = 0; i < num; i++) { if (i == 0) { exponents[i] = 1; aindex[i] = 0; bindex[i] = 0; continue; } else { c = ((i + 2) * (i + 2)) / 4; exponents[i] = c; if (write_as_2a(aindex + i, bindex + i, c, exponents, i)) continue; if (write_as_a_b(aindex + i, bindex + i, c, exponents, i)) continue; if (write_as_2a_b(aindex + i, bindex + i, c, exponents, i)) continue; flint_printf("i = %wd, c = %wu: bad addition sequence!\n", i, c); flint_abort(); } } } void acb_modular_addseq_eta(slong * exponents, slong * aindex, slong * bindex, slong num) { slong i; slong c; for (i = 0; i < num; i++) { if (i == 0) { exponents[i] = 1; aindex[i] = 0; bindex[i] = 0; continue; } else { c = ((i + 2) / 2) * ((3 * i + 5) / 2) / 2; exponents[i] = c; if (write_as_2a(aindex + i, bindex + i, c, exponents, i)) continue; if (write_as_a_b(aindex + i, bindex + i, c, exponents, i)) continue; if (write_as_2a_b(aindex + i, bindex + i, c, exponents, i)) continue; flint_printf("i = %wd, c = %wu: bad addition sequence!\n", i, c); flint_abort(); } } } arb-2.22.1/acb_modular/delta.c000066400000000000000000000034671417376376500161040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_delta(acb_t z, const acb_t tau, slong prec) { psl2z_t g; arf_t one_minus_eps; acb_t tau_prime, t1, t2, t3, t4, q; int real; if (!arb_is_positive(acb_imagref(tau)) || !arb_is_finite(acb_realref(tau))) { acb_indeterminate(z); return; } real = arb_is_int_2exp_si(acb_realref(tau), -1); psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(t1); acb_init(t2); acb_init(t3); acb_init(t4); acb_init(q); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_exp_pi_i(q, tau_prime, prec); acb_modular_theta_const_sum(t2, t3, t4, q, prec); /* (t2 t3 t4) ^ 8 * q^2 */ acb_mul(t1, t2, t3, prec); acb_mul(t1, t1, t4, prec); acb_mul(t1, t1, t1, prec); acb_mul(t1, t1, t1, prec); acb_mul(t1, t1, q, prec); acb_mul(t1, t1, t1, prec); acb_mul_2exp_si(t1, t1, -8); if (!fmpz_is_zero(&g->c)) { acb_mul_fmpz(t2, tau, &g->c, prec); acb_add_fmpz(t2, t2, &g->d, prec); acb_pow_ui(t2, t2, 12, prec); acb_div(t1, t1, t2, prec); } acb_set(z, t1); if (real) arb_zero(acb_imagref(z)); psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(t1); acb_clear(t2); acb_clear(t3); acb_clear(t4); acb_clear(q); } arb-2.22.1/acb_modular/eisenstein.c000066400000000000000000000073451417376376500171600ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_eisenstein(acb_ptr r, const acb_t tau, slong len, slong prec) { psl2z_t g; arf_t one_minus_eps; acb_t tau_prime, t1, t2, t3, t4, q; slong m, n; int real; if (len < 1) return; if (!arb_is_positive(acb_imagref(tau)) || !arb_is_finite(acb_realref(tau))) { _acb_vec_indeterminate(r, len); return; } real = arb_is_int_2exp_si(acb_realref(tau), -1); psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(t1); acb_init(t2); acb_init(t3); acb_init(t4); acb_init(q); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_exp_pi_i(q, tau_prime, prec); acb_modular_theta_const_sum(t2, t3, t4, q, prec); /* fourth powers of the theta functions (a, b, c) */ acb_mul(t2, t2, t2, prec); acb_mul(t2, t2, t2, prec); acb_mul(t2, t2, q, prec); acb_mul(t3, t3, t3, prec); acb_mul(t3, t3, t3, prec); acb_mul(t4, t4, t4, prec); acb_mul(t4, t4, t4, prec); /* c2 = pi^4 * (a^8 + b^8 + c^8) / 30 */ /* c3 = pi^6 * (b^12 + c^12 - 3a^8 * (b^4+c^4)) / 189 */ /* r = a^8 */ acb_mul(r, t2, t2, prec); if (len > 1) { /* r[1] = -3 a^8 * (b^4 + c^4) */ acb_add(r + 1, t3, t4, prec); acb_mul(r + 1, r + 1, r, prec); acb_mul_si(r + 1, r + 1, -3, prec); } /* b^8 */ acb_mul(t1, t3, t3, prec); acb_add(r, r, t1, prec); /* b^12 */ if (len > 1) acb_addmul(r + 1, t1, t3, prec); /* c^8 */ acb_mul(t1, t4, t4, prec); acb_add(r, r, t1, prec); /* c^12 */ if (len > 1) acb_addmul(r + 1, t1, t4, prec); acb_const_pi(t1, prec); acb_mul(t1, t1, t1, prec); acb_mul(t2, t1, t1, prec); acb_mul(r, r, t2, prec); acb_div_ui(r, r, 30, prec); if (len > 1) { acb_mul(t2, t2, t1, prec); acb_mul(r + 1, r + 1, t2, prec); acb_div_ui(r + 1, r + 1, 189, prec); } /* apply modular transformation */ if (!fmpz_is_zero(&g->c)) { acb_mul_fmpz(t1, tau, &g->c, prec); acb_add_fmpz(t1, t1, &g->d, prec); acb_inv(t1, t1, prec); acb_mul(t1, t1, t1, prec); acb_mul(t2, t1, t1, prec); acb_mul(r, r, t2, prec); if (len > 1) { acb_mul(t2, t1, t2, prec); acb_mul(r + 1, r + 1, t2, prec); } } if (real) { arb_zero(acb_imagref(r)); if (len > 1) arb_zero(acb_imagref(r + 1)); } /* compute more coefficients using recurrence */ for (n = 4; n < len + 2; n++) { acb_zero(r + n - 2); m = 2; for (m = 2; m * 2 < n; m++) acb_addmul(r + n - 2, r + m - 2, r + n - m - 2, prec); acb_mul_2exp_si(r + n - 2, r + n - 2, 1); if (n % 2 == 0) acb_addmul(r + n - 2, r + n / 2 - 2, r + n / 2 - 2, prec); acb_mul_ui(r + n - 2, r + n - 2, 3, prec); acb_div_ui(r + n - 2, r + n - 2, (2 * n + 1) * (n - 3), prec); } /* convert c's to G's */ for (n = 0; n < len; n++) acb_div_ui(r + n, r + n, 2 * n + 3, prec); psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(t1); acb_clear(t2); acb_clear(t3); acb_clear(t4); acb_clear(q); } arb-2.22.1/acb_modular/elliptic_e.c000066400000000000000000000010311417376376500171050ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_elliptic.h" void acb_modular_elliptic_e(acb_t res, const acb_t m, slong prec) { acb_elliptic_e(res, m, prec); } arb-2.22.1/acb_modular/elliptic_k.c000066400000000000000000000010251417376376500171160ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_elliptic.h" void acb_modular_elliptic_k(acb_t k, const acb_t m, slong prec) { acb_elliptic_k(k, m, prec); } arb-2.22.1/acb_modular/elliptic_k_cpx.c000066400000000000000000000010571417376376500177750ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_elliptic.h" void acb_modular_elliptic_k_cpx(acb_ptr w, const acb_t m, slong len, slong prec) { acb_elliptic_k_jet(w, m, len, prec); } arb-2.22.1/acb_modular/elliptic_p.c000066400000000000000000000010531417376376500171240ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_elliptic.h" void acb_modular_elliptic_p(acb_t r, const acb_t z, const acb_t tau, slong prec) { acb_elliptic_p(r, z, tau, prec); } arb-2.22.1/acb_modular/elliptic_p_zpx.c000066400000000000000000000011331417376376500200240ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_poly.h" #include "acb_elliptic.h" void acb_modular_elliptic_p_zpx(acb_ptr r, const acb_t z, const acb_t tau, slong len, slong prec) { acb_elliptic_p_jet(r, z, tau, len, prec); } arb-2.22.1/acb_modular/epsilon_arg.c000066400000000000000000000035311417376376500173050ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" static int fmpz_kronecker1(const fmpz_t a, const fmpz_t b) { if (fmpz_sgn(b) < 0) { int r; fmpz_t t; fmpz_init(t); fmpz_neg(t, b); r = fmpz_kronecker1(a, t); fmpz_clear(t); return r; } else if (fmpz_is_one(b)) { return 1; } else { return fmpz_jacobi(a, b); } } int acb_modular_epsilon_arg(const psl2z_t g) { #define a (&g->a) #define b (&g->b) #define c (&g->c) #define d (&g->d) if (fmpz_is_zero(c)) { return fmpz_fdiv_ui(b, 24); } else { int aa, bb, cc, dd; int u; aa = fmpz_fdiv_ui(a, 24); bb = fmpz_fdiv_ui(b, 24); cc = fmpz_fdiv_ui(c, 24); dd = fmpz_fdiv_ui(d, 24); if (cc % 2 == 1) { u = fmpz_kronecker1(a, c); aa = aa*bb + 2*aa*cc - 3*cc + cc*dd*(1-aa*aa); } else { u = fmpz_kronecker1(c, a); aa = aa*bb - aa*cc + 3*aa - 3 + cc*dd*(1-aa*aa); } if (u == -1) { aa += 12; } else if (u != 1) { flint_printf("bad kronecker input\n"); flint_abort(); } /* mod 24 */ if (aa < 0) { aa = 24 - ((-aa) % 24); if (aa == 24) aa = 0; } else aa = aa % 24; return aa; } #undef a #undef b #undef c #undef d } arb-2.22.1/acb_modular/eta.c000066400000000000000000000031001417376376500155440ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_eta(acb_t z, const acb_t tau, slong prec) { psl2z_t g; fmpq_t t; arf_t one_minus_eps; acb_t tau_prime, eta, q, q24; psl2z_init(g); fmpq_init(t); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(eta); acb_init(q); acb_init(q24); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_div_ui(q24, tau_prime, 12, prec); acb_exp_pi_i(q24, q24, prec); acb_pow_ui(q, q24, 24, prec); acb_modular_eta_sum(eta, q, prec); acb_mul(eta, eta, q24, prec); /* epsilon^-1 */ fmpq_set_si(t, -acb_modular_epsilon_arg(g), 12); arb_sin_cos_pi_fmpq(acb_imagref(q), acb_realref(q), t, prec); acb_mul(eta, eta, q, prec); /* (c*tau+d)^(-1/2) */ if (!fmpz_is_zero(&g->c)) { acb_mul_fmpz(q, tau, &g->c, prec); acb_add_fmpz(q, q, &g->d, prec); acb_rsqrt(q, q, prec); acb_mul(eta, eta, q, prec); } acb_set(z, eta); psl2z_clear(g); fmpq_clear(t); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(eta); acb_clear(q); acb_clear(q24); } arb-2.22.1/acb_modular/eta_sum.c000066400000000000000000000164411417376376500164440ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" static const int pentagonal_best_m[] = { 2, 5, 7, 11, 13, 17, 19, 23, 25, 35, 55, 65, 77, 91, 119, 133, 143, 175, 275, 325, 385, 455, 595, 665, 715, 935, 1001, 1309, 1463, 1547, 1729, 1925, 2275, 2975, 3325, 3575, 4675, 5005, 6545, 7315, 7735, 8645, 10465, 11305, 12155, 13585, 16445, 17017, 19019, 23023, 24871, 25025, 32725, 36575, 38675, 43225, 52325, 56525, 60775, 67925, 82225, 85085, 95095, 115115, 124355, 145145, 146965, 168245, 177905, 198835, 224315, 230945, 279565, 312455, 323323, 391391, 425425, 475475, 575575, 621775, 725725, 734825, 841225, 889525, 994175, 0 }; static const int pentagonal_best_m_residues[] = { 2, 3, 4, 6, 7, 9, 10, 12, 11, 12, 18, 21, 24, 28, 36, 40, 42, 44, 66, 77, 72, 84, 108, 120, 126, 162, 168, 216, 240, 252, 280, 264, 308, 396, 440, 462, 594, 504, 648, 720, 756, 840, 1008, 1080, 1134, 1260, 1512, 1512, 1680, 2016, 2160, 1848, 2376, 2640, 2772, 3080, 3696, 3960, 4158, 4620, 5544, 4536, 5040, 6048, 6480, 7560, 7560, 8640, 9072, 10080, 11340, 11340, 13608, 15120, 15120, 18144, 16632, 18480, 22176, 23760, 27720, 27720, 31680, 33264, 36960, 0 }; slong acb_modular_rs_optimal_m(const int * best_ms, const int * num_residues, slong N); #define PENTAGONAL(N) ((((N)+2)/2) * ((3*(N)+5)/2)/2) void _acb_modular_mul(acb_t z, acb_t tmp1, acb_t tmp2, const acb_t x, const acb_t y, slong wprec, slong prec) { if (prec <= 1024) { acb_mul(z, x, y, wprec); } else if (x == y) { acb_set_round(tmp1, x, wprec); acb_mul(z, tmp1, tmp1, wprec); } else { acb_set_round(tmp1, x, wprec); acb_set_round(tmp2, y, wprec); acb_mul(z, tmp1, tmp2, wprec); } } void _acb_modular_eta_sum_basecase(acb_t eta, const acb_t q, double log2q_approx, slong N, slong prec) { slong e, e1, e2, k, k1, k2, num, term_prec; slong *exponents, *aindex, *bindex; acb_ptr qpow; acb_t tmp1, tmp2; double log2term_approx; if (N <= 5) { if (N <= 1) { acb_set_ui(eta, N != 0); } else if (N == 2) { acb_sub_ui(eta, q, 1, prec); acb_neg(eta, eta); } else { acb_mul(eta, q, q, prec); acb_add(eta, eta, q, prec); acb_neg(eta, eta); acb_add_ui(eta, eta, 1, prec); } return; } num = 1; while (PENTAGONAL(num) < N) num++; acb_init(tmp1); acb_init(tmp2); exponents = flint_malloc(sizeof(slong) * 3 * num); aindex = exponents + num; bindex = aindex + num; qpow = _acb_vec_init(num); acb_modular_addseq_eta(exponents, aindex, bindex, num); acb_set_round(qpow + 0, q, prec); acb_zero(eta); for (k = 0; k < num; k++) { e = exponents[k]; log2term_approx = e * log2q_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); if (k > 0) { k1 = aindex[k]; k2 = bindex[k]; e1 = exponents[k1]; e2 = exponents[k2]; if (e == e1 + e2) { _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + k1, qpow + k2, term_prec, prec); } else if (e == 2 * e1 + e2) { _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + k1, qpow + k1, term_prec, prec); _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + k, qpow + k2, term_prec, prec); } else { flint_printf("exponent not in addition sequence!\n"); flint_abort(); } } if (k % 4 <= 1) acb_sub(eta, eta, qpow + k, prec); else acb_add(eta, eta, qpow + k, prec); } acb_add_ui(eta, eta, 1, prec); flint_free(exponents); _acb_vec_clear(qpow, num); acb_clear(tmp1); acb_clear(tmp2); } void _acb_modular_eta_sum_rs(acb_t eta, const acb_t q, double log2q_approx, slong N, slong prec) { slong * tab; slong k, term_prec, i, e, eprev; slong m, num_pentagonal; double log2term_approx; acb_ptr qpow; acb_t tmp1, tmp2; acb_init(tmp1); acb_init(tmp2); /* choose rectangular splitting parameters */ m = acb_modular_rs_optimal_m(pentagonal_best_m, pentagonal_best_m_residues, N); /* build addition sequence */ tab = flint_calloc(m + 1, sizeof(slong)); for (k = 0; PENTAGONAL(k) < N; k++) tab[PENTAGONAL(k) % m] = -1; num_pentagonal = k; tab[m] = -1; /* compute powers in addition sequence */ qpow = _acb_vec_init(m + 1); acb_modular_fill_addseq(tab, m + 1); for (k = 0; k < m + 1; k++) { if (k == 0) { acb_one(qpow + k); } else if (k == 1) { acb_set_round(qpow + k, q, prec); } else if (tab[k] != 0) { log2term_approx = k * log2q_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + tab[k], qpow + k - tab[k], term_prec, prec); } } /* compute eta */ acb_zero(eta); term_prec = prec; for (k = num_pentagonal - 1; k >= 0; k--) { e = PENTAGONAL(k); /* exponent */ eprev = PENTAGONAL(k+1); log2term_approx = e * log2q_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); /* giant steps */ for (i = e / m; i < eprev / m; i++) { if (!acb_is_zero(eta)) _acb_modular_mul(eta, tmp1, tmp2, eta, qpow + m, term_prec, prec); } if (k % 4 <= 1) acb_sub(eta, eta, qpow + (e % m), prec); else acb_add(eta, eta, qpow + (e % m), prec); } acb_add_ui(eta, eta, 1, prec); acb_clear(tmp1); acb_clear(tmp2); _acb_vec_clear(qpow, m + 1); flint_free(tab); } void acb_modular_eta_sum(acb_t eta, const acb_t q, slong prec) { mag_t err, qmag; double log2q_approx; int q_is_real; slong N; mag_init(err); mag_init(qmag); q_is_real = arb_is_zero(acb_imagref(q)); acb_get_mag(qmag, q); log2q_approx = mag_get_d_log2_approx(qmag); if (log2q_approx >= 0.0) { N = 1; mag_inf(err); } else /* Pick N and compute error bound */ { N = 0; while (0.05 * N * N < prec) { if (log2q_approx * PENTAGONAL(N) < -prec - 2) break; N++; } N = PENTAGONAL(N); mag_geom_series(err, qmag, N); if (mag_is_inf(err)) N = 1; } if (N < 400) _acb_modular_eta_sum_basecase(eta, q, log2q_approx, N, prec); else _acb_modular_eta_sum_rs(eta, q, log2q_approx, N, prec); if (q_is_real) arb_add_error_mag(acb_realref(eta), err); else acb_add_error_mag(eta, err); mag_clear(err); mag_clear(qmag); } arb-2.22.1/acb_modular/fill_addseq.c000066400000000000000000000034241417376376500172530ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_fill_addseq(slong * tab, slong len) { slong i, j; for (i = 2; i < len; i++) { if (tab[i] == -1) { /* prefer doubling (squaring) */ if ((i % 2) == 0 && tab[i / 2] != 0) { tab[i] = i / 2; } else { /* check if it can be written as a sum */ /* prefer unbalanced, because one power will have low precision */ #if 1 for (j = 1; 2 * j <= i; j++) #else for (j = i / 2; j >= 1; j--) #endif { if (tab[j] != 0 && tab[i-j] != 0) { tab[i] = j; break; } } /* extend and start over */ if (tab[i] == -1) { tab[i] = i / 2; if (tab[i / 2] == 0) tab[i / 2] = -1; if (tab[i - i / 2] == 0) tab[i - i / 2] = -1; i = 1; } } } } /* prefer squaring (extra entries may have been inserted) */ for (i = 2; i < len; i += 2) { if (tab[i] != 0 && tab[i] != i / 2) { if (tab[i / 2] != 0) tab[i] = i / 2; } } } arb-2.22.1/acb_modular/fundamental_domain_approx.c000066400000000000000000000051141417376376500222200ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" static int good_enough(const acb_t z, const arf_t one_minus_eps, slong prec) { arf_t m; int res; if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -1) > 0) return 0; if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) >= 0) return 1; arf_init(m); arf_mul(m, arb_midref(acb_realref(z)), arb_midref(acb_realref(z)), prec, ARF_RND_DOWN); arf_addmul(m, arb_midref(acb_imagref(z)), arb_midref(acb_imagref(z)), prec, ARF_RND_DOWN); res = (arf_cmp(m, one_minus_eps) >= 0); arf_clear(m); return res; } void acb_modular_fundamental_domain_approx(acb_t w, psl2z_t g, const acb_t z, const arf_t one_minus_eps, slong prec) { acb_t t; psl2z_one(g); /* we must be in the upper half-plane */ if (!acb_is_finite(z) || arf_sgn(arb_midref(acb_imagref(z))) <= 0) { acb_set(w, z); return; } /* too large real-value shift */ if (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), prec) > 0) { acb_set(w, z); return; } /* y >= 1: just shift x */ if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) >= 0) { arf_get_fmpz(&g->b, arb_midref(acb_realref(z)), ARF_RND_NEAR); acb_sub_fmpz(w, z, &g->b, prec); fmpz_neg(&g->b, &g->b); return; } acb_init(t); /* try using doubles */ if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -40) > 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 40) < 0) { double zred, zimd; zred = arf_get_d(arb_midref(acb_realref(z)), ARF_RND_DOWN); zimd = arf_get_d(arb_midref(acb_imagref(z)), ARF_RND_DOWN); acb_modular_fundamental_domain_approx_d(g, zred, zimd, arf_get_d(one_minus_eps, ARF_RND_UP)); acb_modular_transform(t, g, z, prec); if (good_enough(t, one_minus_eps, prec)) { acb_swap(w, t); acb_clear(t); return; } } /* try with full precision */ acb_modular_fundamental_domain_approx_arf(g, arb_midref(acb_realref(z)), arb_midref(acb_imagref(z)), one_minus_eps, prec); acb_modular_transform(t, g, z, prec); acb_swap(w, t); acb_clear(t); } arb-2.22.1/acb_modular/fundamental_domain_approx_arf.c000066400000000000000000000045361417376376500230570ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_fundamental_domain_approx_arf(psl2z_t g, const arf_t xx, const arf_t yy, const arf_t one_minus_eps, slong prec) { slong i; arf_t x, y, t; fmpz_t n; psl2z_one(g); /* we must be in the upper half-plane */ if (!arf_is_finite(xx) || !arf_is_finite(yy) || arf_sgn(yy) <= 0) return; arf_init(x); arf_init(y); arf_init(t); fmpz_init(n); arf_set_round(x, xx, prec, ARF_RND_DOWN); arf_set_round(y, yy, prec, ARF_RND_DOWN); for (i = 0; i < 10 + prec / 4; i++) { /* too large shift */ if (arf_cmpabs_2exp_si(x, prec) > 0) { psl2z_one(g); break; } if (fmpz_bits(&g->a) > prec || fmpz_bits(&g->b) > prec || fmpz_bits(&g->c) > prec || fmpz_bits(&g->d) > prec) { psl2z_one(g); break; } /* shift */ if (arf_cmpabs_2exp_si(x, -1) > 0) { arf_get_fmpz(n, x, ARF_RND_NEAR); arf_sub_fmpz(x, x, n, prec, ARF_RND_DOWN); fmpz_submul(&g->a, &g->c, n); fmpz_submul(&g->b, &g->d, n); continue; } arf_mul(t, x, x, prec, ARF_RND_DOWN); arf_addmul(t, y, y, prec, ARF_RND_DOWN); /* inversion */ if (arf_cmp(t, one_minus_eps) < 0) { arf_div(x, x, t, prec, ARF_RND_DOWN); arf_neg(x, x); arf_div(y, y, t, prec, ARF_RND_DOWN); fmpz_swap(&g->a, &g->c); fmpz_swap(&g->b, &g->d); fmpz_neg(&g->a, &g->a); fmpz_neg(&g->b, &g->b); continue; } /* we're good */ break; } if (fmpz_sgn(&g->c) < 0 || (fmpz_is_zero(&g->c) && fmpz_sgn(&g->d) < 0)) { fmpz_neg(&g->a, &g->a); fmpz_neg(&g->b, &g->b); fmpz_neg(&g->c, &g->c); fmpz_neg(&g->d, &g->d); } arf_clear(x); arf_clear(y); arf_clear(t); fmpz_clear(n); } arb-2.22.1/acb_modular/fundamental_domain_approx_d.c000066400000000000000000000035721417376376500225310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" static __inline__ int d_is_ok(double x) { return (x > -1e15) && (x < 1e15); } void acb_modular_fundamental_domain_approx_d(psl2z_t g, double x, double y, double one_minus_eps) { double a, b, c, d, aa, bb, t; int i; a = d = 1; b = c = 0; for (i = 0; i < 20; i++) { if (!d_is_ok(x) || !d_is_ok(y) || !(y > 0.0)) { psl2z_one(g); return; } /* shift */ if (x < -0.5 || x > 0.5) { t = floor(x + 0.5); x -= t; a -= t * c; b -= t * d; /* too large to guarantee exactness */ if (!d_is_ok(a) || !d_is_ok(b)) { psl2z_one(g); return; } continue; } t = x*x + y*y; /* can't divide by a too small number */ if (t < 1e-30) { psl2z_one(g); break; } /* inversion */ if (t < one_minus_eps) { t = 1.0 / t; x *= -t; y *= t; aa = a; bb = b; a = -c; b = -d; c = aa; d = bb; continue; } /* we're good */ break; } if (c < 0 || (c == 0 && d < 0)) { a = -a; b = -b; c = -c; d = -d; } fmpz_set_d(&g->a, a); fmpz_set_d(&g->b, b); fmpz_set_d(&g->c, c); fmpz_set_d(&g->d, d); } arb-2.22.1/acb_modular/hilbert_class_poly.c000066400000000000000000000107021417376376500206620ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "acb_modular.h" static void bsplit(arb_poly_t pol, const arb_t sqrtD, const slong * qbf, slong a, slong b, slong prec) { if (b - a == 0) { arb_poly_one(pol); } else if (b - a == 1) { acb_t z; acb_init(z); /* j((-b+sqrt(-D))/(2a)) */ arb_set_si(acb_realref(z), -FLINT_ABS(qbf[3 * a + 1])); arb_set(acb_imagref(z), sqrtD); acb_div_si(z, z, 2 * qbf[3 * a], prec); acb_modular_j(z, z, prec); if (qbf[3 * a + 1] < 0) { /* (x^2 - 2re(j) x + |j|^2) */ arb_poly_fit_length(pol, 3); arb_mul(pol->coeffs, acb_realref(z), acb_realref(z), prec); arb_addmul(pol->coeffs, acb_imagref(z), acb_imagref(z), prec); arb_mul_2exp_si(pol->coeffs + 1, acb_realref(z), 1); arb_neg(pol->coeffs + 1, pol->coeffs + 1); arb_one(pol->coeffs + 2); _arb_poly_set_length(pol, 3); } else { /* (x-j) */ arb_poly_fit_length(pol, 2); arb_neg(pol->coeffs, acb_realref(z)); arb_one(pol->coeffs + 1); _arb_poly_set_length(pol, 2); } acb_clear(z); } else { arb_poly_t tmp; arb_poly_init(tmp); bsplit(pol, sqrtD, qbf, a, a + (b - a) / 2, prec); bsplit(tmp, sqrtD, qbf, a + (b - a) / 2, b, prec); arb_poly_mul(pol, pol, tmp, prec); arb_poly_clear(tmp); } } int _acb_modular_hilbert_class_poly(fmpz_poly_t res, slong D, const slong * qbf, slong qbf_len, slong prec) { arb_t sqrtD; arb_poly_t pol; int success; arb_init(sqrtD); arb_poly_init(pol); arb_set_si(sqrtD, -D); arb_sqrt(sqrtD, sqrtD, prec); bsplit(pol, sqrtD, qbf, 0, qbf_len, prec); success = arb_poly_get_unique_fmpz_poly(res, pol); arb_clear(sqrtD); arb_poly_clear(pol); return success; } void acb_modular_hilbert_class_poly(fmpz_poly_t res, slong D) { slong i, a, b, c, ac, h, qbf_alloc, qbf_len, prec; slong * qbf; double lgh; if (D >= 0 || ((D & 3) > 1)) { fmpz_poly_zero(res); return; } qbf_alloc = qbf_len = 0; qbf = NULL; b = D & 1; h = 0; /* Cohen algorithm 5.3.5 */ do { ac = (b*b - D) / 4; a = FLINT_MAX(b, 1); do { if (ac % a == 0 && n_gcd_full(n_gcd(a, b), ac/a) == 1) { c = ac / a; if (qbf_len >= qbf_alloc) { qbf_alloc = FLINT_MAX(4, FLINT_MAX(qbf_len + 1, qbf_alloc * 2)); qbf = flint_realloc(qbf, qbf_alloc * 3 * sizeof(slong)); } if (a == b || a*a == ac || b == 0) { qbf[3 * qbf_len + 0] = a; qbf[3 * qbf_len + 1] = b; qbf[3 * qbf_len + 2] = c; h += 1; } else { /* -b indicates that we have both b and -b */ qbf[3 * qbf_len + 0] = a; qbf[3 * qbf_len + 1] = -b; qbf[3 * qbf_len + 2] = c; h += 2; } qbf_len++; } a++; } while (a*a <= ac); b += 2; } while (3*b*b <= -D); /* Estimate precision - see p.7 in http://hal.inria.fr/inria-00001040 */ lgh = 0.0; for (i = 0; i < qbf_len; i++) { if (qbf[3 * i + 1] < 0) lgh += 2.0 / qbf[3 * i]; else lgh += 1.0 / qbf[3 * i]; } lgh = 3.141593 * sqrt(-D) * lgh; #if 0 lgh += 3.012 * h; prec = lgh * 1.442696; prec = prec + 10; #else prec = lgh * 1.442696; /* heuristic, but more accurate */ prec = prec * 1.005 + 20; #endif while (!_acb_modular_hilbert_class_poly(res, D, qbf, qbf_len, prec)) { flint_printf("hilbert_class_poly failed at %wd bits of precision\n", prec); prec = prec * 1.2 + 10; } flint_free(qbf); } arb-2.22.1/acb_modular/is_in_fundamental_domain.c000066400000000000000000000024101417376376500220040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int acb_modular_is_in_fundamental_domain(const acb_t z, const arf_t tol, slong prec) { arb_t t; arb_init(t); /* require re(w) + 1/2 >= 0 */ arb_set_ui(t, 1); arb_mul_2exp_si(t, t, -1); arb_add(t, t, acb_realref(z), prec); arb_add_arf(t, t, tol, prec); if (!arb_is_nonnegative(t)) { arb_clear(t); return 0; } /* require re(w) - 1/2 <= 0 */ arb_set_ui(t, 1); arb_mul_2exp_si(t, t, -1); arb_sub(t, acb_realref(z), t, prec); arb_sub_arf(t, t, tol, prec); if (!arb_is_nonpositive(t)) { arb_clear(t); return 0; } /* require |w| >= 1 - tol, i.e. |w| - 1 + tol >= 0 */ acb_abs(t, z, prec); arb_sub_ui(t, t, 1, prec); arb_add_arf(t, t, tol, prec); if (!arb_is_nonnegative(t)) { arb_clear(t); return 0; } arb_clear(t); return 1; } arb-2.22.1/acb_modular/j.c000066400000000000000000000035731417376376500152420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_j(acb_t z, const acb_t tau, slong prec) { psl2z_t g; arf_t one_minus_eps; acb_t tau_prime, t2, t3, t4, q; int real; if (!arb_is_positive(acb_imagref(tau)) || !arb_is_finite(acb_realref(tau))) { acb_indeterminate(z); return; } real = arb_is_int_2exp_si(acb_realref(tau), -1); psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(t2); acb_init(t3); acb_init(t4); acb_init(q); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_exp_pi_i(q, tau_prime, prec); acb_modular_theta_const_sum(t2, t3, t4, q, prec); /* theta2 ^ 8 */ acb_mul(t2, t2, t2, prec); acb_mul(t2, t2, t2, prec); acb_mul(t2, t2, q, prec); acb_mul(t2, t2, t2, prec); /* theta3 ^ 8 */ acb_mul(t3, t3, t3, prec); acb_mul(t3, t3, t3, prec); acb_mul(t3, t3, t3, prec); /* theta4 ^ 8 */ acb_mul(t4, t4, t4, prec); acb_mul(t4, t4, t4, prec); acb_mul(t4, t4, t4, prec); acb_mul(z, t2, t3, prec); acb_mul(z, z, t4, prec); acb_add(t2, t2, t3, prec); acb_add(t2, t2, t4, prec); acb_cube(t2, t2, prec); acb_div(z, t2, z, prec); acb_mul_2exp_si(z, z, 5); if (real) arb_zero(acb_imagref(z)); psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(t2); acb_clear(t3); acb_clear(t4); acb_clear(q); } arb-2.22.1/acb_modular/lambda.c000066400000000000000000000034371417376376500162300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_lambda(acb_t r, const acb_t tau, slong prec) { psl2z_t g; arf_t one_minus_eps; acb_t tau_prime, q; acb_struct thetas[4]; int R[4], S[4], C; int Rsum, qpower; psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(q); acb_init(thetas + 0); acb_init(thetas + 1); acb_init(thetas + 2); acb_init(thetas + 3); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_modular_theta_transform(R, S, &C, g); acb_exp_pi_i(q, tau_prime, prec); acb_modular_theta_const_sum(thetas + 1, thetas + 2, thetas + 3, q, prec); acb_zero(thetas + 0); /* divide the transformation factors */ Rsum = 4 * (R[1] - R[2]); /* possible factor [q^(+/- 1/4)]^4 needed for theta_1^4 or theta_2^4 */ qpower = (S[1] == 0 || S[1] == 1) - (S[2] == 0 || S[2] == 1); acb_div(r, thetas + S[1], thetas + S[2], prec); acb_mul(r, r, r, prec); acb_mul(r, r, r, prec); if ((Rsum & 7) == 4) acb_neg(r, r); if (qpower == 1) acb_mul(r, r, q, prec); else if (qpower == -1) acb_div(r, r, q, prec); psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(q); acb_clear(thetas + 0); acb_clear(thetas + 1); acb_clear(thetas + 2); acb_clear(thetas + 3); } arb-2.22.1/acb_modular/psl2z_inv.c000066400000000000000000000013471417376376500167340ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void psl2z_inv(psl2z_t h, const psl2z_t g) { if (h != g) psl2z_set(h, g); if (fmpz_is_zero(&h->c) && fmpz_sgn(&h->a) > 0) { fmpz_neg(&h->b, &h->b); fmpz_swap(&h->d, &h->a); } else { fmpz_swap(&h->a, &h->d); fmpz_neg(&h->a, &h->a); fmpz_neg(&h->d, &h->d); } } arb-2.22.1/acb_modular/psl2z_is_correct.c000066400000000000000000000013451417376376500202720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int psl2z_is_correct(const psl2z_t g) { int res; fmpz_t t; if (fmpz_sgn(&g->c) < 0) return 0; if (fmpz_is_zero(&g->c) && fmpz_sgn(&g->d) <= 0) return 0; fmpz_init(t); fmpz_mul(t, &g->a, &g->d); fmpz_submul(t, &g->b, &g->c); res = fmpz_is_one(t); fmpz_clear(t); return res; } arb-2.22.1/acb_modular/psl2z_is_one.c000066400000000000000000000010541417376376500174070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int psl2z_is_one(const psl2z_t g) { return fmpz_is_one(&g->a) && fmpz_is_zero(&g->b) && fmpz_is_zero(&g->c) && fmpz_is_one(&g->d); } arb-2.22.1/acb_modular/psl2z_mul.c000066400000000000000000000022071417376376500167310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void psl2z_mul(psl2z_t h, const psl2z_t f, const psl2z_t g) { if (h == f || h == g) { psl2z_t t; psl2z_init(t); psl2z_mul(t, f, g); psl2z_swap(t, h); psl2z_clear(t); return; } fmpz_mul(&h->a, &f->a, &g->a); fmpz_addmul(&h->a, &f->b, &g->c); fmpz_mul(&h->b, &f->a, &g->b); fmpz_addmul(&h->b, &f->b, &g->d); fmpz_mul(&h->c, &f->c, &g->a); fmpz_addmul(&h->c, &f->d, &g->c); fmpz_mul(&h->d, &f->c, &g->b); fmpz_addmul(&h->d, &f->d, &g->d); if (fmpz_sgn(&h->c) < 0 || (fmpz_is_zero(&h->c) && fmpz_sgn(&h->d) < 0)) { fmpz_neg(&h->a, &h->a); fmpz_neg(&h->b, &h->b); fmpz_neg(&h->c, &h->c); fmpz_neg(&h->d, &h->d); } } arb-2.22.1/acb_modular/psl2z_randtest.c000066400000000000000000000023121417376376500177550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void psl2z_randtest(psl2z_t g, flint_rand_t state, slong bits) { bits = FLINT_MAX(bits, 1); fmpz_randtest(&g->a, state, bits); fmpz_randtest(&g->b, state, bits); if (fmpz_is_zero(&g->a) && fmpz_is_zero(&g->b)) { psl2z_one(g); } else { fmpz_t t; fmpz_init(t); fmpz_xgcd(t, &g->d, &g->c, &g->a, &g->b); fmpz_divexact(&g->a, &g->a, t); fmpz_divexact(&g->b, &g->b, t); if (fmpz_sgn(&g->c) < 0) fmpz_neg(&g->c, &g->c); else fmpz_neg(&g->b, &g->b); if (fmpz_is_zero(&g->c) && fmpz_sgn(&g->d) < 0) { fmpz_neg(&g->a, &g->a); fmpz_neg(&g->b, &g->b); fmpz_neg(&g->c, &g->c); fmpz_neg(&g->d, &g->d); } fmpz_clear(t); } } arb-2.22.1/acb_modular/test/000077500000000000000000000000001417376376500156145ustar00rootroot00000000000000arb-2.22.1/acb_modular/test/t-delta.c000066400000000000000000000041611417376376500173140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("delta...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t tau, z1, z2; slong e0, prec0, prec1, prec2; acb_init(tau); acb_init(z1); acb_init(z2); e0 = 1 + n_randint(state, 10); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest(tau, state, prec0, e0); acb_randtest(z1, state, prec0, e0); acb_randtest(z2, state, prec0, e0); /* compare with eta */ acb_modular_delta(z1, tau, prec1); acb_modular_eta(z2, tau, prec2); acb_pow_ui(z2, z2, 24, prec2); if (!acb_overlaps(z1, z2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } acb_modular_delta(tau, tau, prec1); if (!acb_overlaps(z1, tau)) { flint_printf("FAIL (aliasing)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z1); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-eisenstein.c000066400000000000000000000051771417376376500204010ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("eisenstein...."); fflush(stdout); flint_randinit(state); /* Test functional equation */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t tau1, tau2, t; acb_ptr r1, r2; slong e0, prec0, prec1, prec2, len1, len2, i; psl2z_t g; psl2z_init(g); acb_init(tau1); acb_init(tau2); acb_init(t); e0 = 1 + n_randint(state, 200); prec0 = 2 + n_randint(state, 2000); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); len1 = n_randint(state, 20); len2 = n_randint(state, 20); r1 = _acb_vec_init(len1); r2 = _acb_vec_init(len2); acb_randtest(tau1, state, prec0, e0); acb_randtest(tau2, state, prec0, e0); psl2z_randtest(g, state, 1 + n_randint(state, 200)); acb_modular_transform(tau2, g, tau1, prec0); acb_modular_eisenstein(r1, tau1, len1, prec1); acb_modular_eisenstein(r2, tau2, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { acb_mul_fmpz(t, tau1, &g->c, prec1); acb_add_fmpz(t, t, &g->d, prec1); acb_pow_ui(t, t, 2 * i + 4, prec1); acb_mul(t, t, r1 + i, prec1); if (!acb_overlaps(t, r2 + i)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau1 = "); acb_printd(tau1, 15); flint_printf("\n\n"); flint_printf("tau2 = "); acb_printd(tau2, 15); flint_printf("\n\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1 + i, 15); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2 + i, 15); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(tau1); acb_clear(tau2); acb_clear(t); _acb_vec_clear(r1, len1); _acb_vec_clear(r2, len2); psl2z_clear(g); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-elliptic_e.c000066400000000000000000000044301417376376500203330ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("elliptic_e...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_t m, w, K, Kp, E, Ep, r, pi2; slong prec; acb_init(m); acb_init(w); acb_init(K); acb_init(Kp); acb_init(E); acb_init(Ep); acb_init(r); acb_init(pi2); prec = 2 + n_randint(state, 1000); acb_randtest(m, state, prec, 1 + n_randint(state, 100)); acb_sub_ui(w, m, 1, prec); acb_neg(w, w); acb_const_pi(pi2, prec); acb_mul_2exp_si(pi2, pi2, -1); acb_modular_elliptic_k(K, m, prec); acb_modular_elliptic_k(Kp, w, prec); acb_modular_elliptic_e(E, m, prec); acb_modular_elliptic_e(Ep, w, prec); acb_mul(r, K, Ep, prec); acb_addmul(r, E, Kp, prec); acb_submul(r, K, Kp, prec); if (!acb_overlaps(r, pi2)) { flint_printf("FAIL (overlap)\n\n"); flint_printf("m = "); acb_printd(m, 30); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 30); flint_printf("\n\n"); flint_printf("K = "); acb_printd(K, 30); flint_printf("\n\n"); flint_printf("Kp = "); acb_printd(Kp, 30); flint_printf("\n\n"); flint_printf("E = "); acb_printd(E, 30); flint_printf("\n\n"); flint_printf("Ep = "); acb_printd(Ep, 30); flint_printf("\n\n"); flint_printf("r = "); acb_printd(r, 30); flint_printf("\n\n"); flint_abort(); } acb_clear(m); acb_clear(w); acb_clear(K); acb_clear(Kp); acb_clear(E); acb_clear(Ep); acb_clear(r); acb_clear(pi2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-elliptic_k.c000066400000000000000000000132561417376376500203470ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #define EPS 1e-13 #define NUM_DERIVS 4 #define NUM_TESTS 7 const double k_testdata[NUM_TESTS][10] = { {0.0, 0.0, 1.5707963267948966192, 0.0, 0.39269908169872415481, 0.0, 0.22089323345553233708, 0.0, 0.15339807878856412297, 0.0}, {0.5, 0.0, 1.8540746773013719184, 0.0, 0.84721308479397908661, 0.0, 0.92703733865068595922, 0.0, 1.2708196271909686299, 0.0}, {-1.0, 0.0, 1.3110287771460599052, 0.0, 0.17798966494456595038, 0.0, 0.051552950136795718707, 0.0, 0.018179887959689603011, 0.0}, {2.0, 0.0, 1.3110287771460599052, -1.3110287771460599052, -0.47752472362846400224, 0.17798966494456595038, 0.2762042441497192576, -0.051552950136795718707, -0.18666835846938225718, 0.018179887959689603011}, {-3.0, 0.0, 1.0782578237498216177, 0.0, 0.078788301660931975886, 0.0, 0.011748068987044517782, 0.0, 0.0021065590680576326689, 0.0}, {1.0, 1.0, 1.5092369540512728293, 0.62514641520269688427, -0.079689518666051625811, 0.40903679001382547524, -0.23159955416582020342, -0.028627375924621981072, 0.014191044435751759097, -0.16030448214657194629}, {-2.0, -3.0, 1.0408718798817036, -0.24497111630480680352, 0.04401149835588265436, -0.060184042863324675054, -0.0012755513109907959184, -0.01044301570409968822, -0.0013811810360989366762, -0.0011248246747562196271} }; int main() { slong iter; flint_rand_t state; flint_printf("elliptic_k...."); fflush(stdout); flint_randinit(state); /* check particular values against table */ { acb_t z, t; acb_ptr w1; slong i, j, prec, cnj; acb_init(z); acb_init(t); w1 = _acb_vec_init(NUM_DERIVS); for (prec = 32; prec <= 512; prec *= 4) { for (i = 0; i < NUM_TESTS; i++) { for (cnj = 0; cnj < 2; cnj++) { if (cnj == 1 && k_testdata[i][0] > 1 && k_testdata[i][1] == 0) continue; acb_zero(z); arf_set_d(arb_midref(acb_realref(z)), k_testdata[i][0]); arf_set_d(arb_midref(acb_imagref(z)), cnj ? -k_testdata[i][1] : k_testdata[i][1]); acb_modular_elliptic_k_cpx(w1, z, NUM_DERIVS, prec); for (j = 0; j < NUM_DERIVS; j++) { arf_set_d(arb_midref(acb_realref(t)), k_testdata[i][2+2*j]); mag_set_d(arb_radref(acb_realref(t)), fabs(k_testdata[i][2+2*j]) * EPS); arf_set_d(arb_midref(acb_imagref(t)), cnj ? -k_testdata[i][2+2*j+1] : k_testdata[i][2+2*j+1]); mag_set_d(arb_radref(acb_imagref(t)), fabs(k_testdata[i][2+2*j+1]) * EPS); if (!acb_overlaps(w1 + j, t)) { flint_printf("FAIL\n\n"); flint_printf("j = %wd\n\n", j); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 15); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1 + j, 15); flint_printf("\n\n"); flint_abort(); } } } } } _acb_vec_clear(w1, NUM_DERIVS); acb_clear(z); acb_clear(t); } /* self-consistency test */ for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_ptr m1, m2; acb_t z1, z2, t; slong i, len1, len2, prec1, prec2; len1 = n_randint(state, 10); len2 = n_randint(state, 10); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); m1 = _acb_vec_init(len1); m2 = _acb_vec_init(len2); acb_init(z1); acb_init(z2); acb_init(t); acb_randtest(z1, state, prec1, 1 + n_randint(state, 100)); if (n_randint(state, 2)) { acb_set(z2, z1); } else { acb_randtest(t, state, prec2, 1 + n_randint(state, 100)); acb_add(z2, z1, t, prec2); acb_sub(z2, z2, t, prec2); } acb_modular_elliptic_k_cpx(m1, z1, len1, prec1); acb_modular_elliptic_k_cpx(m2, z2, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(m1 + i, m2 + i)) { flint_printf("FAIL (overlap)\n\n"); flint_printf("iter = %wd, i = %wd, len1 = %wd, len2 = %wd, prec1 = %wd, prec2 = %wd\n\n", iter, i, len1, len2, prec1, prec2); flint_printf("z1 = "); acb_printd(z1, 30); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 30); flint_printf("\n\n"); flint_printf("m1 = "); acb_printd(m1, 30); flint_printf("\n\n"); flint_printf("m2 = "); acb_printd(m2, 30); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(m1, len1); _acb_vec_clear(m2, len2); acb_clear(z1); acb_clear(z2); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-elliptic_p.c000066400000000000000000000130171417376376500203470ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #define NUM_TESTS 6 #define EPS 1e-13 /* z, tau, p(z, tau) checked with Mathematica: N[{z, tau, WeierstrassP[z, WeierstrassInvariants[{1, tau}/2]]}, 20] */ const double testdata[NUM_TESTS][6] = { { 1.4142135623730950488, 1.7320508075688772935, 2.2360679774997896964, 2.6457513110645905905, -3.3440423818409419071, 0.1143522489547216990 }, { -3.0, -2.0, -7.0, 3.0, -3.3640051024505898616, 0.0 }, { 0.1, 0.0, 0.6, 0.2, 99.322596953997138519, 2.258818666973309701 }, { 0.0, 0.1, 0.6, 0.2, -99.322596953997138519, -2.258818666973309701 }, { 0.5, 0.0, 0.333333333333333333, 20.0, 6.5797362673929057459, 0.0 }, { 3.6666666666666667, 2014.0, -3.1415926535897932385, 0.1, -36.988356711748296440, -102.242185767588750178 } }; static void acb_set_dddd(acb_t z, double a, double ar, double b, double br) { arf_set_d(arb_midref(acb_realref(z)), a); mag_set_d(arb_radref(acb_realref(z)), ar); arf_set_d(arb_midref(acb_imagref(z)), b); mag_set_d(arb_radref(acb_imagref(z)), br); } int main() { slong iter; flint_rand_t state; flint_printf("elliptic_p...."); fflush(stdout); flint_randinit(state); /* check test values */ for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { slong i; acb_t z, tau, p1, p2; acb_init(z); acb_init(tau); acb_init(p1); acb_init(p2); for (i = 0; i < NUM_TESTS; i++) { acb_set_dddd(z, testdata[i][0], 0.0, testdata[i][1], 0.0); acb_set_dddd(tau, testdata[i][2], 0.0, testdata[i][3], 0.0); if (i == NUM_TESTS - 1) /* sensitive to rounding errors in doubles */ acb_set_dddd(p2, testdata[i][4], 1e-6, testdata[i][5], 1e-6); else acb_set_dddd(p2, testdata[i][4], EPS, testdata[i][5], EPS); acb_modular_elliptic_p(p1, z, tau, 2 + n_randint(state, 1000)); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (test value)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } acb_modular_elliptic_p(p2, z, tau, 2 + n_randint(state, 1000)); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (test value 2)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(z); acb_clear(tau); acb_clear(p1); acb_clear(p2); } /* Test periods */ for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t tau, z1, z2, p1, p2; slong m, n, e0, prec0, prec1, prec2; acb_init(tau); acb_init(z1); acb_init(z2); acb_init(p1); acb_init(p2); e0 = 1 + n_randint(state, 10); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest(tau, state, prec0, e0); if (arf_sgn(arb_midref(acb_imagref(tau))) < 0) acb_neg(tau, tau); acb_randtest(z1, state, prec0, e0); acb_randtest(p1, state, prec0, e0); acb_randtest(p2, state, prec0, e0); /* z2 = z1 + m + n*tau */ m = n_randint(state, 10); n = n_randint(state, 10); acb_add_ui(z2, z1, m, prec0); acb_addmul_ui(z2, tau, n, prec0); acb_modular_elliptic_p(p1, z1, tau, prec1); acb_modular_elliptic_p(p2, z2, tau, prec2); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); flint_abort(); } acb_modular_elliptic_p(z1, z1, tau, prec1); if (!acb_overlaps(z1, p1)) { flint_printf("FAIL (aliasing)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z1); acb_clear(z2); acb_clear(p1); acb_clear(p2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-elliptic_p_zpx.c000066400000000000000000000101261417376376500212460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("elliptic_p_zpx...."); fflush(stdout); flint_randinit(state); /* Test differential equation */ for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_t tau, z; acb_ptr g, wp, wp3, wpd, wpd2; slong prec, len, i; len = 1 + n_randint(state, 15); prec = 2 + n_randint(state, 1000); acb_init(tau); acb_init(z); g = _acb_vec_init(2); wp = _acb_vec_init(len + 1); wp3 = _acb_vec_init(len); wpd = _acb_vec_init(len); wpd2 = _acb_vec_init(len); acb_randtest(tau, state, prec, 10); acb_randtest(z, state, prec, 10); acb_modular_elliptic_p_zpx(wp, z, tau, len + 1, prec); acb_modular_eisenstein(g, tau, 2, prec); acb_mul_ui(g, g, 60, prec); acb_mul_ui(g + 1, g + 1, 140, prec); _acb_poly_derivative(wpd, wp, len + 1, prec); _acb_poly_mullow(wpd2, wpd, len, wpd, len, len, prec); _acb_poly_pow_ui_trunc_binexp(wp3, wp, len, 3, len, prec); _acb_vec_scalar_mul_ui(wp3, wp3, len, 4, prec); _acb_vec_scalar_submul(wp3, wp, len, g, prec); acb_sub(wp3, wp3, g + 1, prec); for (i = 0; i < len; i++) { if (!acb_overlaps(wpd2 + i, wp3 + i)) { flint_printf("FAIL (overlap)\n"); flint_printf("i = %wd len = %wd prec = %wd\n\n", i, len, prec); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("wp = "); acb_printd(wp + i, 15); flint_printf("\n\n"); flint_printf("wpd = "); acb_printd(wpd + i, 15); flint_printf("\n\n"); flint_printf("wp3 = "); acb_printd(wp3 + i, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(tau); acb_clear(z); _acb_vec_clear(g, 2); _acb_vec_clear(wp, len + 1); _acb_vec_clear(wp3, len); _acb_vec_clear(wpd, len); _acb_vec_clear(wpd2, len); } /* Consistency test */ for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_t tau, z; acb_ptr wp1, wp2; slong prec1, prec2, len1, len2, i; len1 = n_randint(state, 15); len2 = n_randint(state, 15); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_init(tau); acb_init(z); wp1 = _acb_vec_init(len1); wp2 = _acb_vec_init(len2); acb_randtest(tau, state, prec1, 10); acb_randtest(z, state, prec1, 10); acb_modular_elliptic_p_zpx(wp1, z, tau, len1, prec1); acb_modular_elliptic_p_zpx(wp2, z, tau, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(wp1 + i, wp2 + i)) { flint_printf("FAIL (overlap)\n"); flint_printf("i = %wd len1 = %wd len2 = %wd\n\n", i, len1, len2); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("wp1 = "); acb_printd(wp1 + i, 15); flint_printf("\n\n"); flint_printf("wp2 = "); acb_printd(wp2 + i, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(tau); acb_clear(z); _acb_vec_clear(wp1, len1); _acb_vec_clear(wp2, len2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-epsilon_arg.c000066400000000000000000000045421417376376500205300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "flint/arith.h" static void acb_modular_epsilon_arg_naive(fmpq_t arg, const psl2z_t g) { #define a (&g->a) #define b (&g->b) #define c (&g->c) #define d (&g->d) if (fmpz_is_zero(c)) { fmpz_set(fmpq_numref(arg), b); fmpz_set_ui(fmpq_denref(arg), 12); fmpq_canonicalise(arg); } else { fmpq_t t; fmpq_init(t); fmpz_add(fmpq_numref(arg), a, d); fmpz_submul_ui(fmpq_numref(arg), c, 3); fmpz_mul_ui(fmpq_denref(arg), c, 12); fmpq_canonicalise(arg); arith_dedekind_sum(t, d, c); fmpq_sub(arg, arg, t); fmpq_clear(t); } #undef a #undef b #undef c #undef d } int main() { slong iter; flint_rand_t state; flint_printf("eta_epsilon_arg...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { psl2z_t g; fmpq_t x, y; acb_t a, b; psl2z_init(g); fmpq_init(x); fmpq_init(y); acb_init(a); acb_init(b); psl2z_randtest(g, state, n_randint(state, 200)); fmpq_randtest(x, state, 100); fmpq_randtest(y, state, 100); fmpq_set_si(x, acb_modular_epsilon_arg(g), 12); acb_modular_epsilon_arg_naive(y, g); arb_sin_cos_pi_fmpq(acb_imagref(a), acb_realref(a), x, 200); arb_sin_cos_pi_fmpq(acb_imagref(b), acb_realref(b), x, 200); if (!acb_overlaps(a, b)) { flint_printf("FAIL\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n"); flint_abort(); } psl2z_clear(g); fmpq_clear(x); fmpq_clear(y); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-eta.c000066400000000000000000000103311417376376500167700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("eta...."); fflush(stdout); flint_randinit(state); /* Test functional equation */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t tau1, tau2, z1, z2, z3, t; fmpq_t arg; slong e0, prec0, prec1, prec2; psl2z_t g; psl2z_init(g); fmpq_init(arg); acb_init(tau1); acb_init(tau2); acb_init(z1); acb_init(z2); acb_init(z3); acb_init(t); e0 = 1 + n_randint(state, 200); prec0 = 2 + n_randint(state, 2000); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); acb_randtest(tau1, state, prec0, e0); acb_randtest(tau2, state, prec0, e0); acb_randtest(z1, state, prec0, e0); acb_randtest(z2, state, prec0, e0); psl2z_randtest(g, state, 1 + n_randint(state, 200)); acb_modular_transform(tau2, g, tau1, prec0); acb_modular_eta(z1, tau1, prec1); acb_modular_eta(z2, tau2, prec2); /* apply transformation */ fmpq_set_si(arg, acb_modular_epsilon_arg(g), 12); arb_sin_cos_pi_fmpq(acb_imagref(t), acb_realref(t), arg, prec1); acb_mul(z3, z1, t, prec1); acb_mul_fmpz(t, tau1, &g->c, prec1); acb_add_fmpz(t, t, &g->d, prec1); acb_sqrt(t, t, prec1); acb_mul(z3, z3, t, prec1); if (!acb_overlaps(z3, z2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau1 = "); acb_printd(tau1, 15); flint_printf("\n\n"); flint_printf("tau2 = "); acb_printd(tau2, 15); flint_printf("\n\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_printf("z3 = "); acb_printd(z3, 15); flint_printf("\n\n"); flint_abort(); } acb_modular_eta(tau1, tau1, prec2); if (!acb_overlaps(z1, tau1)) { flint_printf("FAIL (aliasing)\n"); flint_printf("tau1 = "); acb_print(tau1); flint_printf("\n\n"); flint_printf("tau2 = "); acb_print(tau2); flint_printf("\n\n"); flint_printf("z1 = "); acb_print(z1); flint_printf("\n\n"); flint_printf("z2 = "); acb_print(z2); flint_printf("\n\n"); flint_abort(); } acb_clear(tau1); acb_clear(tau2); acb_clear(z1); acb_clear(z2); acb_clear(z3); acb_clear(t); psl2z_clear(g); fmpq_clear(arg); } /* Test special values */ for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { acb_t tau, z; arb_t t, u; slong prec; acb_init(tau); acb_init(z); arb_init(t); arb_init(u); prec = 2 + n_randint(state, 10000); acb_randtest(z, state, prec, 10); acb_onei(tau); acb_modular_eta(z, tau, prec); arb_one(t); arb_mul_2exp_si(t, t, -2); arb_gamma(t, t, prec); arb_const_pi(u, prec); arb_root_ui(u, u, 4, prec); arb_pow_ui(u, u, 3, prec); arb_div(t, t, u, prec); arb_mul_2exp_si(t, t, -1); if (!arb_overlaps(acb_realref(z), t) || !arb_contains_zero(acb_imagref(z))) { flint_printf("FAIL (value 1)\n"); flint_printf("tau = "); acb_print(tau); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z); arb_clear(t); arb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-fundamental_domain_approx.c000066400000000000000000000104271417376376500234430ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("fundamental_domain_approx...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_t x, y; psl2z_t g; arf_t one_minus_eps, tol; acb_t z, w, w2; arb_t t; slong prec; fmpq_init(x); fmpq_init(y); psl2z_init(g); acb_init(z); acb_init(w); acb_init(w2); arf_init(one_minus_eps); arf_init(tol); arb_init(t); /* pick an exact point in the upper half plane */ fmpq_randtest(x, state, 1 + n_randint(state, 500)); do { fmpq_randtest(y, state, 1 + n_randint(state, 500)); } while (fmpz_sgn(fmpq_numref(y)) <= 0); /* pick a tolerance */ arf_set_ui_2exp_si(tol, 1, -(slong) n_randint(state, 500)); /* now increase the precision until convergence */ for (prec = 32; ; prec *= 2) { if (prec > 16384) { flint_printf("FAIL (no convergence)\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 50); flint_printf("\n\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_abort(); } arb_set_fmpq(acb_realref(z), x, prec); arb_set_fmpq(acb_imagref(z), y, prec); arf_set_ui_2exp_si(one_minus_eps, 1, -prec / 4); arf_sub_ui(one_minus_eps, one_minus_eps, 1, prec, ARF_RND_DOWN); arf_neg(one_minus_eps, one_minus_eps); acb_modular_fundamental_domain_approx(w, g, z, one_minus_eps, prec); acb_modular_transform(w2, g, z, prec); if (!psl2z_is_correct(g) || !acb_overlaps(w, w2)) { flint_printf("FAIL (incorrect transformation)\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 50); flint_printf("\n\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_abort(); } /* success */ if (acb_modular_is_in_fundamental_domain(w, tol, prec)) break; } /* check that g^(-1) * w contains x+yi */ psl2z_inv(g, g); acb_modular_transform(w2, g, w, 2 + n_randint(state, 1000)); if (!arb_contains_fmpq(acb_realref(w2), x) || !arb_contains_fmpq(acb_imagref(w2), y)) { flint_printf("FAIL (inverse containment)\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 50); flint_printf("\n\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_abort(); } fmpq_clear(x); fmpq_clear(y); psl2z_clear(g); acb_clear(z); acb_clear(w); acb_clear(w2); arf_clear(one_minus_eps); arf_clear(tol); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-hilbert_class_poly.c000066400000000000000000000166411417376376500221120ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/fmpz_poly.h" #include "acb_modular.h" /* reference values h_(-d)(2015) mod 31337 computed using sage */ static const short hilbert_poly_values[1000] = { 0, 0, 0, 2015, 287, 0, 0, 5390, 25352, 0, 0, 3446, 10689, 0, 0, 7571, 27889, 0, 0, 9315, 17503, 0, 0, 20694, 1734, 0, 0, 5911, 29250, 0, 0, 6194, 3783, 0, 0, 6982, 30449, 0, 0, 10645, 11069, 0, 0, 494, 29262, 0, 0, 10595, 22835, 0, 0, 18309, 24632, 0, 0, 6433, 5042, 0, 0, 9174, 24082, 0, 0, 3463, 30027, 0, 0, 11406, 22491, 0, 0, 16831, 8457, 0, 0, 21721, 19275, 0, 0, 23777, 28295, 0, 0, 13585, 26717, 0, 0, 632, 20965, 0, 0, 9886, 852, 0, 0, 18674, 12461, 0, 0, 17204, 23887, 0, 0, 132, 11124, 0, 0, 29609, 2760, 0, 0, 29227, 28978, 0, 0, 29543, 20831, 0, 0, 12260, 15153, 0, 0, 18215, 29267, 0, 0, 13864, 4648, 0, 0, 9591, 3948, 0, 0, 29683, 20283, 0, 0, 30212, 23760, 0, 0, 10290, 17465, 0, 0, 31207, 21341, 0, 0, 19076, 29310, 0, 0, 740, 11697, 0, 0, 20446, 7258, 0, 0, 16515, 29406, 0, 0, 19948, 20065, 0, 0, 8576, 19014, 0, 0, 1647, 1354, 0, 0, 19468, 6933, 0, 0, 2065, 17883, 0, 0, 19430, 5539, 0, 0, 5738, 25233, 0, 0, 21651, 6815, 0, 0, 23927, 28399, 0, 0, 3108, 23302, 0, 0, 17409, 7911, 0, 0, 26800, 31051, 0, 0, 14360, 11091, 0, 0, 10984, 11954, 0, 0, 26389, 3557, 0, 0, 3298, 18516, 0, 0, 22211, 2972, 0, 0, 22613, 5274, 0, 0, 27799, 13362, 0, 0, 8002, 23366, 0, 0, 31122, 20593, 0, 0, 356, 19130, 0, 0, 10024, 2373, 0, 0, 19390, 28768, 0, 0, 25504, 4440, 0, 0, 14798, 8726, 0, 0, 6180, 7623, 0, 0, 12941, 31038, 0, 0, 14370, 29147, 0, 0, 166, 10994, 0, 0, 8397, 354, 0, 0, 26973, 17435, 0, 0, 21128, 5064, 0, 0, 20453, 30343, 0, 0, 25679, 6503, 0, 0, 28364, 4924, 0, 0, 6341, 11339, 0, 0, 10624, 17028, 0, 0, 28001, 192, 0, 0, 27052, 28470, 0, 0, 10034, 12162, 0, 0, 25236, 6842, 0, 0, 19334, 7593, 0, 0, 29159, 26694, 0, 0, 14719, 26199, 0, 0, 9382, 25741, 0, 0, 31174, 8440, 0, 0, 4218, 17722, 0, 0, 11574, 8090, 0, 0, 9938, 4982, 0, 0, 22701, 6931, 0, 0, 29372, 29088, 0, 0, 28, 24186, 0, 0, 23852, 7521, 0, 0, 18508, 9883, 0, 0, 2392, 30611, 0, 0, 26103, 11926, 0, 0, 27676, 24118, 0, 0, 7495, 15441, 0, 0, 12681, 20030, 0, 0, 8106, 3260, 0, 0, 25626, 24143, 0, 0, 17471, 9620, 0, 0, 24315, 24991, 0, 0, 25966, 12488, 0, 0, 9839, 25896, 0, 0, 14932, 27863, 0, 0, 20652, 11663, 0, 0, 1779, 5540, 0, 0, 2066, 24758, 0, 0, 23522, 20408, 0, 0, 26357, 2423, 0, 0, 14671, 18184, 0, 0, 16904, 264, 0, 0, 27879, 30997, 0, 0, 1506, 23000, 0, 0, 1236, 13243, 0, 0, 24917, 2346, 0, 0, 2397, 14849, 0, 0, 21298, 15702, 0, 0, 9627, 8103, 0, 0, 26185, 6738, 0, 0, 2476, 21350, 0, 0, 7578, 9859, 0, 0, 19157, 5329, 0, 0, 401, 3223, 0, 0, 30337, 21258, 0, 0, 25707, 14593, 0, 0, 8611, 15496, 0, 0, 12225, 1505, 0, 0, 23534, 16704, 0, 0, 13230, 19926, 0, 0, 12220, 19104, 0, 0, 6130, 12697, 0, 0, 19881, 6864, 0, 0, 25044, 7436, 0, 0, 29137, 14435, 0, 0, 20628, 26292, 0, 0, 30933, 8606, 0, 0, 28752, 23603, 0, 0, 11633, 21739, 0, 0, 22592, 18621, 0, 0, 20125, 1595, 0, 0, 25306, 15723, 0, 0, 1643, 16444, 0, 0, 11825, 27858, 0, 0, 13835, 4948, 0, 0, 29003, 12298, 0, 0, 16479, 12920, 0, 0, 25238, 15558, 0, 0, 4102, 16578, 0, 0, 10456, 546, 0, 0, 3738, 28968, 0, 0, 20266, 8035, 0, 0, 9779, 25941, 0, 0, 5911, 20127, 0, 0, 18291, 28982, 0, 0, 18831, 29846, 0, 0, 21272, 11493, 0, 0, 24427, 28574, 0, 0, 22664, 14849, 0, 0, 30445, 20996, 0, 0, 13612, 18604, 0, 0, 19880, 19227, 0, 0, 6230, 17398, 0, 0, 29192, 29933, 0, 0, 25046, 14031, 0, 0, 24100, 463, 0, 0, 19254, 17038, 0, 0, 19912, 10339, 0, 0, 12475, 24909, 0, 0, 3292, 18482, 0, 0, 1542, 24603, 0, 0, 24850, 2332, 0, 0, 22262, 14510, 0, 0, 16526, 18396, 0, 0, 30544, 14396, 0, 0, 2788, 18461, 0, 0, 17619, 14749, 0, 0, 29832, 24740, 0, 0, 19298, 20355, 0, 0, 538, 18003, 0, 0, 4225, 4401, 0, 0, 28095, 1371, 0, 0, 2724, 353, 0, 0, 8917, 943, 0, 0, 4998, 2384, 0, 0, 14677, 9528, 0, 0, 7351, 13960, 0, 0, 4467, 8153, 0, 0, 16711, 8606, 0, 0, 24590, 1061, 0, 0, 7678, 5647, 0, 0, 27940, 3563, 0, 0, 11137, 29574, 0, 0, 15623, 29261, 0, 0, 15422, 3266, 0, 0, 26284, 9039, 0, 0, 9616, 21817, 0, 0, 2661, 8479, 0, 0, 19882, 5965, 0, 0, 13459, 2231, 0, 0, 10839, 22085, 0, 0, 23581, 14883, 0, 0, 7516, 20147, 0, 0, 7072, 16192, 0, 0, 26870, 29168, 0, 0, 5724, 19808, 0, 0, 25458, 21905, 0, 0, 28942, 29586, 0, 0, 13256, 6359, 0, 0, 15267, 8726, 0, 0, 29008, 24734, 0, 0, 2786, 716, 0, 0, 29798, 3021, 0, 0, 1388, 28017, 0, 0, 26001, 11541, 0, 0, 19326, 2630, 0, 0, 5326, 1153, 0, 0, 12367, 12089, 0, 0, 15701, 7816, 0, 0, 28096, 13980, 0, 0, 15683, 16412, 0, 0, 29609, 21907, 0, 0, 2266, 30126, 0, 0, 26922, 29563, 0, 0, 27024, 11031, 0, 0, 28714, 4013, 0, 0, 20446, 30395, 0, 0, 1980, 26546, 0, 0, 26413, 13346, 0, 0, 4083, 837, 0, 0, 7134, 251, 0, 0, 29540, 6521, 0, 0, 18515, 2436, 0, 0, 21198, 24291, 0, 0, 26451, 28377, 0, 0, 18689, 15300, 0, 0, 8527, 27153, 0, 0, 18586, 30431, 0, 0, 28981, 13795, 0, 0, 11286, 26207, 0, 0, 11870, 2833, 0, 0, 6996, 19018, 0, 0, 22638, 18958, 0, 0, 10333, 12804, 0, 0, 13618, 8212, 0, 0, 30926, 11947, 0, 0, 6681 }; static const int hilbert_poly_values_2[] = { -2000, 13490, -1999, 10172, -4000, 2042, -3999, 16478, -8000, 14919, -7999, 15365, -16000, 8190, -15999, 30928, -32000, 10486, -31999, 2808, -64000, 26310, -63999, 23551, /* slow -128000, 30815, -127999, 2144, -256000, 5257, -255999, 18151, -512000, 31288, -511999, 30227, -1024000, 14241, -1023999, 16711, */ 0, 0, }; int main() { flint_printf("hilbert_class_poly...."); fflush(stdout); { slong i; mp_limb_t c; fmpz_poly_t hd; nmod_poly_t hdp; fmpz_poly_init(hd); nmod_poly_init(hdp, 31337); for (i = 0; i < 1000; i++) { acb_modular_hilbert_class_poly(hd, -i); fmpz_poly_get_nmod_poly(hdp, hd); c = nmod_poly_evaluate_nmod(hdp, 2015); if (c != hilbert_poly_values[i]) { flint_printf("FAIL!\n"); flint_printf("D = %wd\n", -i); flint_printf("c = %wu\n", c); flint_printf("expected = %d\n", (int) hilbert_poly_values[i]); flint_abort(); } } for (i = 0; hilbert_poly_values_2[2 * i] != 0; i++) { acb_modular_hilbert_class_poly(hd, hilbert_poly_values_2[2 * i]); fmpz_poly_get_nmod_poly(hdp, hd); c = nmod_poly_evaluate_nmod(hdp, 2015); if (c != hilbert_poly_values_2[2 * i + 1]) { flint_printf("FAIL!\n"); flint_printf("D = %wd\n", -i); flint_printf("c = %wu\n", c); flint_printf("expected = %d\n", (int) hilbert_poly_values_2[2*i+1]); flint_abort(); } } fmpz_poly_clear(hd); nmod_poly_clear(hdp); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-j.c000066400000000000000000000070721417376376500164600ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("j...."); fflush(stdout); flint_randinit(state); /* Test SL2Z invariance */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t tau1, tau2, z1, z2; slong e0, prec0, prec1, prec2; psl2z_t g; psl2z_init(g); acb_init(tau1); acb_init(tau2); acb_init(z1); acb_init(z2); e0 = 1 + n_randint(state, 100); prec0 = 2 + n_randint(state, 2000); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); acb_randtest(tau1, state, prec0, e0); acb_randtest(tau2, state, prec0, e0); acb_randtest(z1, state, prec0, e0); acb_randtest(z2, state, prec0, e0); psl2z_randtest(g, state, 1 + n_randint(state, 200)); acb_modular_transform(tau2, g, tau1, prec0); acb_modular_j(z1, tau1, prec1); acb_modular_j(z2, tau2, prec2); if (!acb_overlaps(z1, z2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau1 = "); acb_print(tau1); flint_printf("\n\n"); flint_printf("tau2 = "); acb_print(tau2); flint_printf("\n\n"); flint_printf("z1 = "); acb_print(z1); flint_printf("\n\n"); flint_printf("z2 = "); acb_print(z2); flint_printf("\n\n"); flint_abort(); } acb_modular_j(tau1, tau1, prec2); if (!acb_overlaps(z1, tau1)) { flint_printf("FAIL (aliasing)\n"); flint_printf("tau1 = "); acb_print(tau1); flint_printf("\n\n"); flint_printf("tau2 = "); acb_print(tau2); flint_printf("\n\n"); flint_printf("z1 = "); acb_print(z1); flint_printf("\n\n"); flint_printf("z2 = "); acb_print(z2); flint_printf("\n\n"); flint_abort(); } acb_clear(tau1); acb_clear(tau2); acb_clear(z1); acb_clear(z2); psl2z_clear(g); } /* Test special values */ for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { acb_t tau, z; slong prec; acb_init(tau); acb_init(z); prec = 2 + n_randint(state, 2000); acb_randtest(z, state, prec, 10); acb_onei(tau); acb_modular_j(z, tau, prec); acb_sub_ui(z, z, 1728, prec); if (!acb_contains_zero(z)) { flint_printf("FAIL (value 1)\n"); flint_printf("tau = "); acb_print(tau); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_abort(); } acb_set_ui(tau, 2); acb_div_ui(tau, tau, 3, prec); acb_exp_pi_i(tau, tau, prec); acb_modular_j(z, tau, prec); if (!acb_contains_zero(z)) { flint_printf("FAIL (value 2)\n"); flint_printf("tau = "); acb_print(tau); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); flint_abort(); } acb_clear(tau); acb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-lambda.c000066400000000000000000000066741417376376500174560ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("lambda...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t tau1, tau2, z1, z2, z3, t; slong e0, prec0, prec1, prec2, step; acb_init(tau1); acb_init(tau2); acb_init(z1); acb_init(z2); acb_init(z3); acb_init(t); e0 = 1 + n_randint(state, 100); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest(tau1, state, prec0, e0); acb_randtest(tau2, state, prec0, e0); acb_randtest(z1, state, prec0, e0); acb_randtest(z2, state, prec0, e0); acb_set(tau2, tau1); step = n_randint(state, 10); /* Test invariance */ while (step --> 0) { if (n_randint(state, 2)) { acb_add_ui(tau2, tau2, 2, prec0); } else { acb_mul_si(z1, tau2, -2, prec0); acb_add_ui(z1, z1, 1, prec0); acb_div(tau2, tau2, z1, prec0); } } acb_modular_lambda(z1, tau1, prec1); acb_modular_lambda(z2, tau2, prec2); /* Compare with eta */ acb_mul_2exp_si(tau1, tau1, -1); acb_modular_eta(z3, tau1, prec2); acb_mul_2exp_si(tau1, tau1, 2); acb_modular_eta(t, tau1, prec2); acb_mul(t, t, t, prec2); acb_mul(z3, z3, t, prec2); acb_mul_2exp_si(tau1, tau1, -1); acb_modular_eta(t, tau1, prec2); acb_pow_ui(t, t, 3, prec2); acb_div(z3, z3, t, prec2); acb_pow_ui(z3, z3, 8, prec2); acb_mul_2exp_si(z3, z3, 4); if (!acb_overlaps(z1, z2) || !acb_overlaps(z1, z3)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau1 = "); acb_printd(tau1, 15); flint_printf("\n\n"); flint_printf("tau2 = "); acb_printd(tau2, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_printf("z3 = "); acb_printd(z3, 15); flint_printf("\n\n"); flint_abort(); } acb_modular_lambda(tau1, tau1, prec2); if (!acb_overlaps(z1, tau1)) { flint_printf("FAIL (aliasing)\n"); flint_printf("tau1 = "); acb_printd(tau1, 15); flint_printf("\n\n"); flint_printf("tau2 = "); acb_printd(tau2, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(tau1); acb_clear(tau2); acb_clear(z1); acb_clear(z2); acb_clear(z3); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-psl2z_inv.c000066400000000000000000000036121417376376500201510ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("psl2z_inv...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { psl2z_t f, g, h, i; psl2z_init(f); psl2z_init(g); psl2z_init(h); psl2z_init(i); psl2z_randtest(f, state, n_randint(state, 100)); psl2z_randtest(g, state, n_randint(state, 100)); psl2z_randtest(h, state, n_randint(state, 100)); psl2z_inv(g, f); psl2z_mul(h, f, g); psl2z_one(i); if (!psl2z_equal(h, i) || !psl2z_is_correct(g)) { flint_printf("FAIL\n"); flint_printf("f = "); psl2z_print(f); flint_printf("\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n"); flint_printf("h = "); psl2z_print(h); flint_printf("\n"); flint_printf("i = "); psl2z_print(i); flint_printf("\n"); flint_abort(); } psl2z_inv(f, f); if (!psl2z_equal(f, g) || !psl2z_is_correct(f)) { flint_printf("FAIL (aliasing)\n"); flint_printf("f = "); psl2z_print(f); flint_printf("\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n"); flint_abort(); } psl2z_clear(f); psl2z_clear(g); psl2z_clear(h); psl2z_clear(i); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-psl2z_mul.c000066400000000000000000000036331417376376500201550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("psl2z_mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { psl2z_t f, g, h, u, v; psl2z_init(f); psl2z_init(g); psl2z_init(h); psl2z_init(u); psl2z_init(v); psl2z_randtest(f, state, n_randint(state, 100)); psl2z_randtest(g, state, n_randint(state, 100)); psl2z_randtest(h, state, n_randint(state, 100)); psl2z_randtest(u, state, n_randint(state, 100)); psl2z_randtest(v, state, n_randint(state, 100)); /* test (f*g)*h = f*(g*h) */ psl2z_mul(u, f, g); psl2z_mul(u, u, h); psl2z_mul(v, g, h); psl2z_mul(v, f, v); if (!psl2z_equal(u, v) || !psl2z_is_correct(u) || !psl2z_is_correct(v)) { flint_printf("FAIL\n"); flint_printf("f = "); psl2z_print(f); flint_printf("\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n"); flint_printf("h = "); psl2z_print(h); flint_printf("\n"); flint_printf("u = "); psl2z_print(u); flint_printf("\n"); flint_printf("v = "); psl2z_print(v); flint_printf("\n"); flint_abort(); } psl2z_clear(f); psl2z_clear(g); psl2z_clear(h); psl2z_clear(u); psl2z_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-theta.c000066400000000000000000000056061417376376500173350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("theta...."); fflush(stdout); flint_randinit(state); /* Test consistency with/without transform */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t t1, t2, t3, t4, t1b, t2b, t3b, t4b, z, tau; slong prec0, prec1, prec2, e0; acb_init(t1); acb_init(t2); acb_init(t3); acb_init(t4); acb_init(t1b); acb_init(t2b); acb_init(t3b); acb_init(t4b); acb_init(z); acb_init(tau); prec0 = 2 + n_randint(state, 2000); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); e0 = 1 + n_randint(state, 100); acb_randtest(tau, state, prec0, e0); acb_randtest(z, state, prec0, e0); arb_abs(acb_imagref(tau), acb_imagref(tau)); if (n_randint(state, 3) == 0) arb_set_si(acb_realref(tau), -10 + n_randint(state, 20)); if (n_randint(state, 3) == 0) arb_zero(acb_imagref(z)); if (n_randint(state, 3) == 0) arb_zero(acb_realref(z)); acb_modular_theta(t1, t2, t3, t4, z, tau, prec1); acb_modular_theta_notransform(t1b, t2b, t3b, t4b, z, tau, prec2); if (!acb_overlaps(t1, t1b) || !acb_overlaps(t2, t2b) || !acb_overlaps(t3, t3b) || !acb_overlaps(t4, t4b)) { flint_printf("FAIL (overlap)\n"); flint_printf("z = "); acb_printd(z, 25); flint_printf("\n\n"); flint_printf("tau = "); acb_printd(tau, 25); flint_printf("\n\n"); flint_printf("t1 = "); acb_printd(t1, 15); flint_printf("\n\n"); flint_printf("t1b = "); acb_printd(t1b, 15); flint_printf("\n\n"); flint_printf("t2 = "); acb_printd(t2, 15); flint_printf("\n\n"); flint_printf("t2b = "); acb_printd(t2b, 15); flint_printf("\n\n"); flint_printf("t3 = "); acb_printd(t3, 15); flint_printf("\n\n"); flint_printf("t3b = "); acb_printd(t3b, 15); flint_printf("\n\n"); flint_printf("t4 = "); acb_printd(t4, 15); flint_printf("\n\n"); flint_printf("t4b = "); acb_printd(t4b, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(t1); acb_clear(t2); acb_clear(t3); acb_clear(t4); acb_clear(t1b); acb_clear(t2b); acb_clear(t3b); acb_clear(t4b); acb_clear(z); acb_clear(tau); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-theta_const_sum_rs.c000066400000000000000000000047151417376376500221330ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("theta_const_sum_rs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_t q, t2a, t2b, t3a, t3b, t4a, t4b; slong prec1, prec2, N; acb_init(q); acb_init(t2a); acb_init(t2b); acb_init(t3a); acb_init(t3b); acb_init(t4a); acb_init(t4b); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); N = n_randint(state, 300); acb_randtest(q, state, prec1, 3); acb_randtest(t2a, state, prec1, 3); acb_randtest(t2b, state, prec1, 3); acb_randtest(t3a, state, prec1, 3); acb_randtest(t3b, state, prec1, 3); acb_randtest(t4a, state, prec1, 3); acb_randtest(t4b, state, prec1, 3); acb_modular_theta_const_sum_basecase(t2a, t3a, t4a, q, N, prec1); acb_modular_theta_const_sum_rs(t2b, t3b, t4b, q, N, prec2); if (!acb_overlaps(t2a, t2b) || !acb_overlaps(t3a, t3b) || !acb_overlaps(t4a, t4b)) { flint_printf("FAIL (overlap) iter = %wd\n", iter); flint_printf("N = %wd\n", N); flint_printf("q = "); acb_printd(q, 50); flint_printf("\n\n"); flint_printf("t2a = "); acb_printd(t2a, 50); flint_printf("\n\n"); flint_printf("t2b = "); acb_printd(t2b, 50); flint_printf("\n\n"); flint_printf("t3a = "); acb_printd(t3a, 50); flint_printf("\n\n"); flint_printf("t3b = "); acb_printd(t3b, 50); flint_printf("\n\n"); flint_printf("t4a = "); acb_printd(t4a, 50); flint_printf("\n\n"); flint_printf("t4b = "); acb_printd(t4b, 50); flint_printf("\n\n"); flint_abort(); } acb_clear(q); acb_clear(t2a); acb_clear(t2b); acb_clear(t3a); acb_clear(t3b); acb_clear(t4a); acb_clear(t4b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-theta_jet.c000066400000000000000000000077131417376376500202000ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("theta_jet...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_ptr t1a, t1b, t2a, t2b, t3a, t3b, t4a, t4b; acb_t z, tau; slong prec0, e0, prec1, prec2, len1, len2, i; acb_init(z); acb_init(tau); e0 = 1 + n_randint(state, 10); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); len1 = 1 + n_randint(state, 10); len2 = 1 + n_randint(state, 10); t1a = _acb_vec_init(len1); t2a = _acb_vec_init(len1); t3a = _acb_vec_init(len1); t4a = _acb_vec_init(len1); t1b = _acb_vec_init(len2); t2b = _acb_vec_init(len2); t3b = _acb_vec_init(len2); t4b = _acb_vec_init(len2); acb_randtest(z, state, prec0, e0); acb_randtest(tau, state, prec0, e0); arb_abs(acb_imagref(tau), acb_imagref(tau)); for (i = 0; i < len1; i++) { acb_randtest(t1a + i, state, prec0, e0); acb_randtest(t2a + i, state, prec0, e0); acb_randtest(t3a + i, state, prec0, e0); acb_randtest(t4a + i, state, prec0, e0); } for (i = 0; i < len2; i++) { acb_randtest(t1b + i, state, prec0, e0); acb_randtest(t2b + i, state, prec0, e0); acb_randtest(t3b + i, state, prec0, e0); acb_randtest(t4b + i, state, prec0, e0); } acb_modular_theta_jet_notransform(t1a, t2a, t3a, t4a, z, tau, len1, prec1); acb_modular_theta_jet(t1b, t2b, t3b, t4b, z, tau, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(t1a + i, t1b + i) || !acb_overlaps(t2a + i, t2b + i) || !acb_overlaps(t3a + i, t3b + i) || !acb_overlaps(t4a + i, t4b + i)) { flint_printf("FAIL (overlap) iter = %wd\n", iter); flint_printf("len1 = %wd, len2 = %wd, prec1 = %wd, prec2 = %wd\n\n", len1, len2, prec1, prec2); flint_printf("i = %wd\n\n", i); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n\n"); flint_printf("tau = "); acb_printd(tau, 50); flint_printf("\n\n"); flint_printf("t1a = "); acb_printd(t1a + i, 50); flint_printf("\n\n"); flint_printf("t1b = "); acb_printd(t1b + i, 50); flint_printf("\n\n"); flint_printf("t2a = "); acb_printd(t2a + i, 50); flint_printf("\n\n"); flint_printf("t2b = "); acb_printd(t2b + i, 50); flint_printf("\n\n"); flint_printf("t3a = "); acb_printd(t3a + i, 50); flint_printf("\n\n"); flint_printf("t3b = "); acb_printd(t3b + i, 50); flint_printf("\n\n"); flint_printf("t4a = "); acb_printd(t4a + i, 50); flint_printf("\n\n"); flint_printf("t4b = "); acb_printd(t4b + i, 50); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(t1a, len1); _acb_vec_clear(t2a, len1); _acb_vec_clear(t3a, len1); _acb_vec_clear(t4a, len1); _acb_vec_clear(t1b, len2); _acb_vec_clear(t2b, len2); _acb_vec_clear(t3b, len2); _acb_vec_clear(t4b, len2); acb_clear(z); acb_clear(tau); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-theta_series.c000066400000000000000000000075271417376376500207130ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("theta_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t t1, t2, t3, t4, t1b, t2b, t3b, t4b, z; acb_t tau; slong len1, len2, prec1, prec2; unsigned int mask; acb_poly_init(t1); acb_poly_init(t1b); acb_poly_init(t2); acb_poly_init(t2b); acb_poly_init(t3); acb_poly_init(t3b); acb_poly_init(t4); acb_poly_init(t4b); acb_poly_init(z); acb_init(tau); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); len1 = n_randint(state, 6); len2 = n_randint(state, 6); acb_poly_randtest(t1, state, 10, prec1, 10); acb_poly_randtest(t2, state, 10, prec1, 10); acb_poly_randtest(t3, state, 10, prec1, 10); acb_poly_randtest(t4, state, 10, prec1, 10); acb_poly_randtest(z, state, 1 + n_randint(state, 10), prec1, 10); acb_randtest(tau, state, prec1, 10); acb_modular_theta_series(t1, t2, t3, t4, z, tau, len1, prec1); mask = n_randlimb(state); acb_modular_theta_series((mask & 1) ? t1b : NULL, (mask & 2) ? t2b : NULL, (mask & 4) ? t3b : NULL, (mask & 8) ? t4b : NULL, z, tau, len2, prec2); acb_poly_truncate(t1, FLINT_MIN(len1, len2)); acb_poly_truncate(t1b, FLINT_MIN(len1, len2)); acb_poly_truncate(t2, FLINT_MIN(len1, len2)); acb_poly_truncate(t2b, FLINT_MIN(len1, len2)); acb_poly_truncate(t3, FLINT_MIN(len1, len2)); acb_poly_truncate(t3b, FLINT_MIN(len1, len2)); acb_poly_truncate(t4, FLINT_MIN(len1, len2)); acb_poly_truncate(t4b, FLINT_MIN(len1, len2)); if (((mask & 1) && (!acb_poly_overlaps(t1, t1b))) || ((mask & 2) && (!acb_poly_overlaps(t2, t2b))) || ((mask & 4) && (!acb_poly_overlaps(t3, t3b))) || ((mask & 8) && (!acb_poly_overlaps(t4, t4b)))) { flint_printf("FAIL: consistency (mask)\n\n"); flint_printf("mask = %u\n\n", mask); flint_printf("len1 = %wd, len2 = %wd\n\n", len1, len2); flint_printf("z = "); acb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("tau = "); acb_printd(tau, 30); flint_printf("\n\n"); flint_printf("t1 = "); acb_poly_printd(t1, 30); flint_printf("\n\n"); flint_printf("t1b = "); acb_poly_printd(t1b, 30); flint_printf("\n\n"); flint_printf("t2 = "); acb_poly_printd(t2, 30); flint_printf("\n\n"); flint_printf("t2b = "); acb_poly_printd(t2b, 30); flint_printf("\n\n"); flint_printf("t3 = "); acb_poly_printd(t3, 30); flint_printf("\n\n"); flint_printf("t3b = "); acb_poly_printd(t3b, 30); flint_printf("\n\n"); flint_printf("t4 = "); acb_poly_printd(t4, 30); flint_printf("\n\n"); flint_printf("t4b = "); acb_poly_printd(t4b, 30); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(t1); acb_poly_clear(t1b); acb_poly_clear(t2); acb_poly_clear(t2b); acb_poly_clear(t3); acb_poly_clear(t3b); acb_poly_clear(t4); acb_poly_clear(t4b); acb_poly_clear(z); acb_clear(tau); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-theta_sum.c000066400000000000000000000105561417376376500202210ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("theta_sum...."); fflush(stdout); flint_randinit(state); /* Very weak test, just testing the error bounds and not that we compute the right functions */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_ptr t1a, t1b, t2a, t2b, t3a, t3b, t4a, t4b; acb_t w, q; int w_is_unit; slong prec0, e0, prec1, prec2, len1, len2, i; acb_init(w); acb_init(q); e0 = 1 + n_randint(state, 100); prec0 = 2 + n_randint(state, 3000); prec1 = 2 + n_randint(state, 3000); prec2 = 2 + n_randint(state, 3000); len1 = 1 + n_randint(state, 30); len2 = 1 + n_randint(state, 30); t1a = _acb_vec_init(len1); t2a = _acb_vec_init(len1); t3a = _acb_vec_init(len1); t4a = _acb_vec_init(len1); t1b = _acb_vec_init(len2); t2b = _acb_vec_init(len2); t3b = _acb_vec_init(len2); t4b = _acb_vec_init(len2); if (n_randint(state, 2)) { arb_randtest(acb_realref(q), state, prec0, e0); arb_zero(acb_imagref(q)); acb_exp_pi_i(w, q, prec0); w_is_unit = n_randint(state, 2); } else { acb_randtest(w, state, prec0, e0); w_is_unit = 0; } acb_randtest(q, state, prec0, e0); for (i = 0; i < len1; i++) { acb_randtest(t1a + i, state, prec0, e0); acb_randtest(t2a + i, state, prec0, e0); acb_randtest(t3a + i, state, prec0, e0); acb_randtest(t4a + i, state, prec0, e0); } for (i = 0; i < len2; i++) { acb_randtest(t1b + i, state, prec0, e0); acb_randtest(t2b + i, state, prec0, e0); acb_randtest(t3b + i, state, prec0, e0); acb_randtest(t4b + i, state, prec0, e0); } acb_modular_theta_sum(t1a, t2a, t3a, t4a, w, w_is_unit, q, len1, prec1); acb_modular_theta_sum(t1b, t2b, t3b, t4b, w, w_is_unit & n_randint(state, 2), q, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(t1a + i, t1b + i) || !acb_overlaps(t2a + i, t2b + i) || !acb_overlaps(t3a + i, t3b + i) || !acb_overlaps(t4a + i, t4b + i)) { flint_printf("FAIL (overlap) iter = %wd\n", iter); flint_printf("len1 = %wd, len2 = %wd, prec1 = %wd, prec2 = %wd\n\n", len1, len2, prec1, prec2); flint_printf("i = %wd\n\n", i); flint_printf("q = "); acb_printd(q, 50); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 50); flint_printf("\n\n"); flint_printf("t1a = "); acb_printd(t1a + i, 50); flint_printf("\n\n"); flint_printf("t1b = "); acb_printd(t1b + i, 50); flint_printf("\n\n"); flint_printf("t2a = "); acb_printd(t2a + i, 50); flint_printf("\n\n"); flint_printf("t2b = "); acb_printd(t2b + i, 50); flint_printf("\n\n"); flint_printf("t3a = "); acb_printd(t3a + i, 50); flint_printf("\n\n"); flint_printf("t3b = "); acb_printd(t3b + i, 50); flint_printf("\n\n"); flint_printf("t4a = "); acb_printd(t4a + i, 50); flint_printf("\n\n"); flint_printf("t4b = "); acb_printd(t4b + i, 50); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(t1a, len1); _acb_vec_clear(t2a, len1); _acb_vec_clear(t3a, len1); _acb_vec_clear(t4a, len1); _acb_vec_clear(t1b, len2); _acb_vec_clear(t2b, len2); _acb_vec_clear(t3b, len2); _acb_vec_clear(t4b, len2); acb_clear(w); acb_clear(q); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/test/t-transform.c000066400000000000000000000040251417376376500202350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" int main() { slong iter; flint_rand_t state; flint_printf("transform...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { psl2z_t g; acb_t z, w1, w2, t; slong prec; psl2z_init(g); acb_init(z); acb_init(w1); acb_init(w2); acb_init(t); psl2z_randtest(g, state, n_randint(state, 20)); acb_randtest(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 20)); acb_randtest(w1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 20)); acb_randtest(w2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 20)); acb_modular_transform(w1, g, z, 2 + n_randint(state, 200)); prec = 2 + n_randint(state, 200); acb_mul_fmpz(t, z, &g->a, prec); acb_add_fmpz(t, t, &g->b, prec); acb_mul_fmpz(w2, z, &g->c, prec); acb_add_fmpz(w2, w2, &g->d, prec); acb_div(w2, t, w2, prec); if (!acb_overlaps(w1, w2)) { flint_printf("FAIL\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_abort(); } psl2z_clear(g); acb_clear(z); acb_clear(w1); acb_clear(w2); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_modular/theta.c000066400000000000000000000170321417376376500161110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" static void acb_mul_4th_root(acb_t y, const acb_t x, int r, slong prec) { r &= 7; if (r == 0) { acb_set(y, x); } else if (r == 4) { acb_neg(y, x); } else if (r == 2) { acb_mul_onei(y, x); } else if (r == 6) { acb_mul_onei(y, x); acb_neg(y, y); } else { fmpq_t t; fmpq_init(t); fmpq_set_si(t, r, 4); arb_sin_cos_pi_fmpq(acb_imagref(y), acb_realref(y), t, prec); acb_mul(y, y, x, prec); fmpq_clear(t); } } void acb_modular_theta(acb_t theta1, acb_t theta2, acb_t theta3, acb_t theta4, const acb_t z, const acb_t tau, slong prec) { fmpq_t t; psl2z_t g; arf_t one_minus_eps; acb_t z_prime, tau_prime, q, q4, w, A, B; acb_struct thetas[4]; int w_is_unit, R[4], S[4], C; int t1r, t1i, t2r, t2i, t3r, t4r; if (!acb_is_finite(z) || !acb_is_finite(tau) || !arb_is_positive(acb_imagref(tau))) { acb_indeterminate(theta1); acb_indeterminate(theta2); acb_indeterminate(theta3); acb_indeterminate(theta4); return; } /* special cases when real(tau) is an integer n: z is real: theta1 real if n mod 4 = 0 theta1 imaginary if n mod 4 = 2 theta2 real if n mod 4 = 0 theta2 imaginary if n mod 4 = 2 theta3 real always theta4 real always z is imaginary: theta1 real if n mod 4 = 2 theta1 imaginary if n mod 4 = 0 theta2 real if n mod 4 = 0 theta2 imaginary if n mod 4 = 2 theta3 real always theta4 real always */ t1r = t1i = t2r = t2i = t3r = t4r = 0; if (arb_is_int(acb_realref(tau))) { int val; if (arb_is_int_2exp_si(acb_realref(tau), 2)) val = 2; else if (arb_is_int_2exp_si(acb_realref(tau), 1)) val = 1; else val = 0; if (arb_is_zero(acb_imagref(z))) { t3r = t4r = 1; if (val == 2) t1r = t2r = 1; if (val == 1) t1i = t2i = 1; } if (arb_is_zero(acb_realref(z))) { t3r = t4r = 1; if (val == 2) t1i = t2r = 1; if (val == 1) t1r = t2i = 1; } } psl2z_init(g); fmpq_init(t); arf_init(one_minus_eps); acb_init(z_prime); acb_init(tau_prime); acb_init(q); acb_init(q4); acb_init(w); acb_init(thetas + 0); acb_init(thetas + 1); acb_init(thetas + 2); acb_init(thetas + 3); acb_init(A); acb_init(B); /* move tau to the fundamental domain */ arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); /* compute transformation parameters */ acb_modular_theta_transform(R, S, &C, g); if (C == 0) { acb_set(z_prime, z); acb_one(A); } else { /* B = 1/(c*tau+d) (temporarily) */ acb_mul_fmpz(B, tau, &g->c, prec); acb_add_fmpz(B, B, &g->d, prec); acb_inv(B, B, prec); /* -z/(c*tau+d) */ acb_mul(z_prime, z, B, prec); acb_neg(z_prime, z_prime); /* A = sqrt(i/(c*tau+d)) */ acb_mul_onei(A, B); acb_sqrt(A, A, prec); /* B = exp(-pi i c z^2/(c*tau+d)) */ /* we first compute the argument here */ if (acb_is_zero(z)) { acb_zero(B); } else { acb_mul(B, z_prime, z, prec); acb_mul_fmpz(B, B, &g->c, prec); } } /* reduce z_prime modulo tau_prime if the imaginary part is large */ if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z_prime)), 4) > 0) { arb_t nn; arb_init(nn); arf_div(arb_midref(nn), arb_midref(acb_imagref(z_prime)), arb_midref(acb_imagref(tau_prime)), prec, ARF_RND_DOWN); arf_mul_2exp_si(arb_midref(nn), arb_midref(nn), 1); arf_add_ui(arb_midref(nn), arb_midref(nn), 1, prec, ARF_RND_DOWN); arf_mul_2exp_si(arb_midref(nn), arb_midref(nn), -1); arf_floor(arb_midref(nn), arb_midref(nn)); /* transform z_prime further */ acb_submul_arb(z_prime, tau_prime, nn, prec); /* add -tau n^2 - 2nz to B */ arb_mul_2exp_si(nn, nn, 1); acb_submul_arb(B, z_prime, nn, prec); arb_mul_2exp_si(nn, nn, -1); arb_sqr(nn, nn, prec); acb_submul_arb(B, tau_prime, nn, prec); /* theta1, theta4 pick up factors (-1)^n */ if (!arf_is_int_2exp_si(arb_midref(nn), 1)) { int i; for (i = 0; i < 4; i++) { if (S[i] == 0 || S[i] == 3) R[i] += 4; } } C = 1; arb_clear(nn); } if (C != 0) acb_exp_pi_i(B, B, prec); /* compute q_{1/4}, q */ acb_mul_2exp_si(q4, tau_prime, -2); acb_exp_pi_i(q4, q4, prec); acb_pow_ui(q, q4, 4, prec); /* compute w */ acb_exp_pi_i(w, z_prime, prec); w_is_unit = arb_is_zero(acb_imagref(z_prime)); /* evaluate theta functions of transformed variables */ acb_modular_theta_sum(thetas + 0, thetas + 1, thetas + 2, thetas + 3, w, w_is_unit, q, 1, prec); acb_mul(thetas + 0, thetas + 0, q4, prec); acb_mul(thetas + 1, thetas + 1, q4, prec); /* multiply by roots of unity */ acb_mul_4th_root(theta1, thetas + S[0], R[0], prec); acb_mul_4th_root(theta2, thetas + S[1], R[1], prec); acb_mul_4th_root(theta3, thetas + S[2], R[2], prec); acb_mul_4th_root(theta4, thetas + S[3], R[3], prec); if (C != 0) { acb_mul(A, A, B, prec); acb_mul(theta1, theta1, A, prec); acb_mul(theta2, theta2, A, prec); acb_mul(theta3, theta3, A, prec); acb_mul(theta4, theta4, A, prec); } if (t1r) arb_zero(acb_imagref(theta1)); if (t1i) arb_zero(acb_realref(theta1)); if (t2r) arb_zero(acb_imagref(theta2)); if (t2i) arb_zero(acb_realref(theta2)); if (t3r) arb_zero(acb_imagref(theta3)); if (t4r) arb_zero(acb_imagref(theta4)); psl2z_clear(g); fmpq_clear(t); arf_clear(one_minus_eps); acb_clear(z_prime); acb_clear(tau_prime); acb_clear(q); acb_clear(q4); acb_clear(w); acb_clear(thetas + 0); acb_clear(thetas + 1); acb_clear(thetas + 2); acb_clear(thetas + 3); acb_clear(A); acb_clear(B); } void acb_modular_theta_notransform(acb_t theta1, acb_t theta2, acb_t theta3, acb_t theta4, const acb_t z, const acb_t tau, slong prec) { acb_t q, q4, w; int w_is_unit; acb_init(q); acb_init(q4); acb_init(w); /* compute q_{1/4}, q */ acb_mul_2exp_si(q4, tau, -2); acb_exp_pi_i(q4, q4, prec); acb_pow_ui(q, q4, 4, prec); /* compute w */ acb_exp_pi_i(w, z, prec); w_is_unit = arb_is_zero(acb_imagref(z)); /* evaluate theta functions */ acb_modular_theta_sum(theta1, theta2, theta3, theta4, w, w_is_unit, q, 1, prec); acb_mul(theta1, theta1, q4, prec); acb_mul(theta2, theta2, q4, prec); acb_clear(q); acb_clear(q4); acb_clear(w); } arb-2.22.1/acb_modular/theta_const_sum.c000066400000000000000000000035311417376376500202020ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_theta_const_sum(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong prec) { mag_t qmag, err; double log2q_approx; int is_real, is_real_or_imag; slong N; mag_init(qmag); mag_init(err); acb_get_mag(qmag, q); log2q_approx = mag_get_d_log2_approx(qmag); is_real = arb_is_zero(acb_imagref(q)); is_real_or_imag = is_real || arb_is_zero(acb_realref(q)); if (log2q_approx >= 0.0) { N = 1; mag_inf(err); } else { N = 0; while (0.05 * N * N < prec) { if (log2q_approx * ((N+2)*(N+2)/4) < -prec - 2) break; N++; } N = (N+2)*(N+2)/4; mag_geom_series(err, qmag, N); mag_mul_2exp_si(err, err, 1); /* each term is taken twice */ if (mag_is_inf(err)) N = 1; } if (N < 1800) acb_modular_theta_const_sum_basecase(theta2, theta3, theta4, q, N, prec); else acb_modular_theta_const_sum_rs(theta2, theta3, theta4, q, N, prec); if (is_real_or_imag) arb_add_error_mag(acb_realref(theta2), err); else acb_add_error_mag(theta2, err); if (is_real) { arb_add_error_mag(acb_realref(theta3), err); arb_add_error_mag(acb_realref(theta4), err); } else { acb_add_error_mag(theta3, err); acb_add_error_mag(theta4, err); } mag_clear(qmag); mag_clear(err); } arb-2.22.1/acb_modular/theta_const_sum_basecase.c000066400000000000000000000110261417376376500220260ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_theta_const_sum_basecase(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong N, slong prec) { slong * tab; slong k, term_prec; double log2q_approx, log2term_approx; mag_t qmag; acb_ptr qpow; acb_t s1, s2, s3, t1, t2; if (N < 2) { acb_set_ui(theta2, 2 * (N > 0)); acb_set_ui(theta3, N > 0); acb_set(theta4, theta3); return; } if (N < 25) { acb_t q1, q2, q4, q8, q16; acb_init(q1); acb_init(q2); acb_init(q4); acb_init(q8); acb_init(q16); acb_set_round(q1, q, prec); if (N > 2) acb_mul(q2, q1, q1, prec); if (N > 4) acb_mul(q4, q2, q2, prec); if (N > 9) acb_mul(q8, q4, q4, prec); if (N > 16) acb_mul(q16, q8, q8, prec); /* theta2 = 2 + 2q^2 + 2q^4 [2q^2 + 2q^8 + 2q^16] */ if (N > 6) { if (N > 12) { acb_add(theta2, q2, q8, prec); if (N > 20) acb_add(theta2, theta2, q16, prec); acb_mul(theta2, theta2, q4, prec); } else { acb_mul(theta2, q2, q4, prec); } acb_add(theta2, theta2, q2, prec); acb_add_ui(theta2, theta2, 1, prec); } else if (N > 2) acb_add_ui(theta2, q2, 1, prec); else acb_one(theta2); acb_mul_2exp_si(theta2, theta2, 1); /* theta3 = [1 + 2q^4 + 2q^16] + [2q + 2q^9] */ /* theta4 = [1 + 2q^4 + 2q^16] - [2q + 2q^9] */ if (N > 4) { if (N > 16) acb_add(q4, q4, q16, prec); acb_mul_2exp_si(q4, q4, 1); acb_add_ui(q4, q4, 1, prec); if (N > 9) acb_addmul(q1, q1, q8, prec); acb_mul_2exp_si(q1, q1, 1); acb_add(theta3, q4, q1, prec); acb_sub(theta4, q4, q1, prec); } else { acb_mul_2exp_si(q1, q1, 1); acb_add_ui(theta3, q1, 1, prec); acb_sub_ui(theta4, q1, 1, prec); acb_neg(theta4, theta4); } acb_clear(q1); acb_clear(q2); acb_clear(q4); acb_clear(q8); acb_clear(q16); return; } mag_init(qmag); acb_init(s1); acb_init(s2); acb_init(s3); acb_init(t1); acb_init(t2); tab = flint_calloc(N, sizeof(slong)); qpow = _acb_vec_init(N); for (k = 0; k*(k+1) < N; k++) tab[k*(k+1)] = -1; for (k = 0; 4*k*k < N; k++) tab[4*k*k] = -1; for (k = 0; 4*k*(k+1) + 1 < N; k++) tab[4*k*(k+1)] = -1; if (N > 0) tab[0] = 0; if (N > 1) tab[1] = 1; acb_modular_fill_addseq(tab, N); acb_get_mag(qmag, q); log2q_approx = mag_get_d_log2_approx(qmag); for (k = 0; k < N; k++) { if (k == 0) { acb_one(qpow + k); } else if (k == 1) { acb_set_round(qpow + k, q, prec); } else if (tab[k] != 0) { log2term_approx = k * log2q_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); _acb_modular_mul(qpow + k, t1, t2, qpow + tab[k], qpow + k - tab[k], term_prec, prec); } } for (k = 0; k*(k+1) < N; k++) acb_add(s1, s1, qpow + k*(k+1), prec); for (k = 1; 4*k*k < N; k++) acb_add(s2, s2, qpow + 4*k*k, prec); for (k = 0; 4*k*(k+1) + 1 < N; k++) acb_add(s3, s3, qpow + 4*k*(k+1), prec); /* theta2 = 2 + 2q^2 + 2q^6 + 2q^12 + 2q^20 + 2q^30 + ... theta3 = 1 + 2 (q^4 + q^16 + ...) + 2q (1 + q^8 + q^24 + ...) theta4 = 1 + 2 (q^4 + q^16 + ...) - 2q (1 + q^8 + q^24 + ...) */ acb_mul(s3, s3, q, prec); acb_mul_2exp_si(s3, s3, 1); acb_mul_2exp_si(s2, s2, 1); acb_add(theta3, s2, s3, prec); acb_sub(theta4, s2, s3, prec); acb_add_ui(theta3, theta3, 1, prec); acb_add_ui(theta4, theta4, 1, prec); acb_mul_2exp_si(theta2, s1, 1); _acb_vec_clear(qpow, N); flint_free(tab); acb_clear(s1); acb_clear(s2); acb_clear(s3); acb_clear(t1); acb_clear(t2); mag_clear(qmag); } arb-2.22.1/acb_modular/theta_const_sum_rs.c000066400000000000000000000137711417376376500207150ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" static const int square_best_m[] = { 2, 3, 4, 8, 12, 16, 32, 48, 80, 96, 112, 144, 240, 288, 336, 480, 560, 576, 720, 1008, 1440, 1680, 2016, 2640, 2880, 3600, 4032, 5040, 7920, 9360, 10080, 15840, 18480, 20160, 25200, 31680, 37440, 39600, 44352, 50400, 55440, 65520, 85680, 95760, 102960, 110880, 131040, 171360, 191520, 205920, 221760, 262080, 277200, 327600, 383040, 411840, 514800, 554400, 655200, 720720, 942480, 0 }; static const int square_best_m_residues[] = { 2, 2, 2, 3, 4, 4, 7, 8, 12, 14, 16, 16, 24, 28, 32, 42, 48, 48, 48, 64, 84, 96, 112, 144, 144, 176, 192, 192, 288, 336, 336, 504, 576, 576, 704, 864, 1008, 1056, 1152, 1232, 1152, 1344, 1728, 1920, 2016, 2016, 2352, 3024, 3360, 3528, 3456, 4032, 4224, 4928, 5760, 6048, 7392, 7392, 8624, 8064, 10368, 0 }; static const int trigonal_best_m[] = { 2, 6, 10, 14, 18, 30, 42, 66, 70, 90, 126, 198, 210, 330, 390, 450, 630, 990, 1170, 1386, 1638, 2142, 2310, 2730, 3150, 4950, 5850, 6930, 8190, 10710, 11970, 12870, 16830, 18018, 23562, 26334, 27846, 30030, 34650, 40950, 53550, 59850, 64350, 84150, 90090, 117810, 131670, 139230, 155610, 188370, 203490, 218790, 244530, 270270, 296010, 306306, 342342, 414414, 447678, 450450, 589050, 658350, 696150, 778050, 941850, 0 }; static const int trigonal_best_m_residues[] = { 1, 2, 3, 4, 4, 6, 8, 12, 12, 12, 16, 24, 24, 36, 42, 44, 48, 72, 84, 96, 112, 144, 144, 168, 176, 264, 308, 288, 336, 432, 480, 504, 648, 672, 864, 960, 1008, 1008, 1056, 1232, 1584, 1760, 1848, 2376, 2016, 2592, 2880, 3024, 3360, 4032, 4320, 4536, 5040, 5544, 6048, 6048, 6720, 8064, 8640, 7392, 9504, 10560, 11088, 12320, 14784, 0, }; slong acb_modular_rs_optimal_m(const int * best_ms, const int * num_residues, slong N) { slong i, m, cost, best_i, best_m, best_cost; best_i = 0; best_m = best_ms[0]; best_cost = WORD_MAX; for (i = 0; (m = best_ms[i]) != 0; i++) { cost = N / m + num_residues[i]; if (i == 0 || cost < best_cost) { best_i = i; best_cost = cost; best_m = m; } } /* flint_printf("N = %wd, best_m = %wd, best_cost = %wd, s(m) = %d\n", N, best_m, best_cost, num_residues[best_i]); */ i = best_i; return best_m; } void acb_modular_theta_const_sum_rs(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong N, slong prec) { slong * tab; slong k, term_prec, i, e, eprev; slong M, m2, m3, num_square, num_trigonal; double log2q_approx, log2term_approx; acb_ptr qpow; acb_t tmp1, tmp2; mag_t qmag; mag_init(qmag); acb_get_mag(qmag, q); log2q_approx = mag_get_d_log2_approx(qmag); mag_clear(qmag); acb_init(tmp1); acb_init(tmp2); /* choose rectangular splitting parameters */ m2 = acb_modular_rs_optimal_m(trigonal_best_m, trigonal_best_m_residues, N); m3 = acb_modular_rs_optimal_m(square_best_m, square_best_m_residues, N); M = FLINT_MAX(m2, m3) + 1; /* build addition sequence */ tab = flint_calloc(M, sizeof(slong)); for (k = 0; k*(k+1) < N; k++) tab[(k*(k+1)) % m2] = -1; num_trigonal = k; for (k = 0; k*k < N; k++) tab[(k*k) % m3] = -1; num_square = k; tab[m2] = -1; tab[m3] = -1; /* compute powers in addition sequence */ qpow = _acb_vec_init(M); acb_modular_fill_addseq(tab, M); for (k = 0; k < M; k++) { if (k == 0) { acb_one(qpow + k); } else if (k == 1) { acb_set_round(qpow + k, q, prec); } else if (tab[k] != 0) { log2term_approx = k * log2q_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + tab[k], qpow + k - tab[k], term_prec, prec); } } /* compute theta2 */ acb_zero(theta2); term_prec = prec; for (k = num_trigonal - 1; k >= 0; k--) { e = k * (k + 1); /* exponent */ eprev = (k + 1) * (k + 2); log2term_approx = e * log2q_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); /* giant steps */ for (i = e / m2; i < eprev / m2; i++) { if (!acb_is_zero(theta2)) _acb_modular_mul(theta2, tmp1, tmp2, theta2, qpow + m2, term_prec, prec); } acb_add(theta2, theta2, qpow + (e % m2), prec); } acb_mul_2exp_si(theta2, theta2, 1); /* compute theta3, theta4 */ acb_zero(theta3); acb_zero(theta4); term_prec = prec; for (k = num_square - 1; k >= 0; k--) { e = k * k; /* exponent */ eprev = (k + 1) * (k + 1); log2term_approx = e * log2q_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); /* giant steps */ for (i = e / m3; i < eprev / m3; i++) { if (!acb_is_zero(theta3)) _acb_modular_mul(theta3, tmp1, tmp2, theta3, qpow + m3, term_prec, prec); if (!acb_is_zero(theta4)) _acb_modular_mul(theta4, tmp1, tmp2, theta4, qpow + m3, term_prec, prec); } if (k == 0) { acb_mul_2exp_si(theta3, theta3, 1); acb_mul_2exp_si(theta4, theta4, 1); } acb_add(theta3, theta3, qpow + (e % m3), prec); if (k % 2 == 0) acb_add(theta4, theta4, qpow + (e % m3), prec); else acb_sub(theta4, theta4, qpow + (e % m3), prec); } acb_clear(tmp1); acb_clear(tmp2); _acb_vec_clear(qpow, M); flint_free(tab); } arb-2.22.1/acb_modular/theta_jet.c000066400000000000000000000210371417376376500167530ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" #include "acb_poly.h" static void _acb_vec_mul_4th_root(acb_ptr y, acb_srcptr x, slong len, int r, slong prec) { slong k; r &= 7; if (r == 0) { _acb_vec_set(y, x, len); } else if (r == 4) { _acb_vec_neg(y, x, len); } else if (r == 2) { for (k = 0; k < len; k++) acb_mul_onei(y + k, x + k); } else if (r == 6) { for (k = 0; k < len; k++) { acb_mul_onei(y + k, x + k); acb_neg(y + k, y + k); } } else { fmpq_t t; acb_t w; fmpq_init(t); acb_init(w); fmpq_set_si(t, r, 4); arb_sin_cos_pi_fmpq(acb_imagref(w), acb_realref(w), t, prec); _acb_vec_scalar_mul(y, x, len, w, prec); fmpq_clear(t); acb_clear(w); } } void acb_modular_theta_jet(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t z, const acb_t tau, slong len, slong prec) { fmpq_t t; psl2z_t g; arf_t one_minus_eps; acb_t z_prime, tau_prime, q, q4, w, A; acb_ptr B; acb_ptr thetas[4]; int w_is_unit, R[4], S[4], C, rescale; slong k; if (len == 0) return; if (len == 1) { acb_modular_theta(theta1, theta2, theta3, theta4, z, tau, prec); return; } psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); /* move tau to the fundamental domain */ arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); if (psl2z_is_one(g) && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 4) <= 0) { acb_modular_theta_jet_notransform(theta1, theta2, theta3, theta4, z, tau, len, prec); } else { fmpq_init(t); acb_init(z_prime); acb_init(q); acb_init(q4); acb_init(w); acb_init(A); B = _acb_vec_init(len); thetas[0] = _acb_vec_init(len); thetas[1] = _acb_vec_init(len); thetas[2] = _acb_vec_init(len); thetas[3] = _acb_vec_init(len); /* compute transformation parameters */ acb_modular_theta_transform(R, S, &C, g); if (C == 0) { acb_set(z_prime, z); acb_one(A); rescale = 0; } else { rescale = 1; /* B = 1/(c*tau+d) (temporarily) */ acb_mul_fmpz(B, tau, &g->c, prec); acb_add_fmpz(B, B, &g->d, prec); acb_inv(B, B, prec); /* z' = -z/(c*tau+d) */ acb_mul(z_prime, z, B, prec); acb_neg(z_prime, z_prime); /* A = sqrt(i/(c*tau+d)) */ acb_mul_onei(A, B); acb_sqrt(A, A, prec); /* B = c/(c*tau+d) */ acb_mul_fmpz(B, B, &g->c, prec); /* B[2] = -c/(c*tau+d) */ if (len >= 3) acb_neg(B + 2, B); if (len >= 2) { /* B[1] = -2*z*c/(c*tau+d) */ acb_mul(B + 1, B, z, prec); acb_mul_2exp_si(B + 1, B + 1, 1); acb_neg(B + 1, B + 1); } acb_mul(B, z_prime, z, prec); acb_mul_fmpz(B, B, &g->c, prec); /* we will have B = exp(-pi i c (z+x)^2/(c*tau+d)) after computing the exponential later */ } /* reduce z_prime modulo tau_prime if the imaginary part is large */ if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z_prime)), 4) > 0) { arb_t nn; arb_init(nn); arf_div(arb_midref(nn), arb_midref(acb_imagref(z_prime)), arb_midref(acb_imagref(tau_prime)), prec, ARF_RND_DOWN); arf_mul_2exp_si(arb_midref(nn), arb_midref(nn), 1); arf_add_ui(arb_midref(nn), arb_midref(nn), 1, prec, ARF_RND_DOWN); arf_mul_2exp_si(arb_midref(nn), arb_midref(nn), -1); arf_floor(arb_midref(nn), arb_midref(nn)); /* transform z_prime further */ acb_submul_arb(z_prime, tau_prime, nn, prec); /* add -tau n^2 - 2n(z+x)' to B */ arb_mul_2exp_si(nn, nn, 1); acb_submul_arb(B, z_prime, nn, prec); if (len >= 2) { acb_t u; acb_init(u); /* the x picks up a factor -1/(tau*c+d) */ if (rescale) { acb_mul_fmpz(u, tau, &g->c, prec); acb_add_fmpz(u, u, &g->d, prec); acb_inv(u, u, prec); acb_neg(u, u); acb_mul_arb(u, u, nn, prec); acb_sub(B + 1, B + 1, u, prec); } else { acb_sub_arb(B + 1, B + 1, nn, prec); } acb_clear(u); } arb_mul_2exp_si(nn, nn, -1); arb_sqr(nn, nn, prec); acb_submul_arb(B, tau_prime, nn, prec); /* theta1, theta4 pick up factors (-1)^n */ if (!arf_is_int_2exp_si(arb_midref(nn), 1)) { int i; for (i = 0; i < 4; i++) { if (S[i] == 0 || S[i] == 3) R[i] += 4; } } C = 1; arb_clear(nn); } if (C != 0) _acb_poly_exp_pi_i_series(B, B, FLINT_MIN(len, 3), len, prec); /* compute q_{1/4}, q */ acb_mul_2exp_si(q4, tau_prime, -2); acb_exp_pi_i(q4, q4, prec); acb_pow_ui(q, q4, 4, prec); /* compute w */ acb_exp_pi_i(w, z_prime, prec); w_is_unit = arb_is_zero(acb_imagref(z_prime)); /* evaluate theta functions of transformed variables */ acb_modular_theta_sum(thetas[0], thetas[1], thetas[2], thetas[3], w, w_is_unit, q, len, prec); /* correct for change of variables */ if (rescale) { /* [-1/(tau*c+d)]]^k */ acb_mul_fmpz(z_prime, tau, &g->c, prec); acb_add_fmpz(z_prime, z_prime, &g->d, prec); acb_inv(z_prime, z_prime, prec); acb_neg(z_prime, z_prime); acb_set(w, z_prime); for (k = 1; k < len; k++) { acb_mul(thetas[0] + k, thetas[0] + k, w, prec); acb_mul(thetas[1] + k, thetas[1] + k, w, prec); acb_mul(thetas[2] + k, thetas[2] + k, w, prec); acb_mul(thetas[3] + k, thetas[3] + k, w, prec); acb_mul(w, w, z_prime, prec); } } /* todo: fuse */ _acb_vec_scalar_mul(thetas[0], thetas[0], len, q4, prec); _acb_vec_scalar_mul(thetas[1], thetas[1], len, q4, prec); /* multiply by roots of unity */ _acb_vec_mul_4th_root(theta1, thetas[S[0]], len, R[0], prec); _acb_vec_mul_4th_root(theta2, thetas[S[1]], len, R[1], prec); _acb_vec_mul_4th_root(theta3, thetas[S[2]], len, R[2], prec); _acb_vec_mul_4th_root(theta4, thetas[S[3]], len, R[3], prec); if (C != 0) { _acb_vec_scalar_mul(B, B, len, A, prec); _acb_poly_mullow(thetas[0], theta1, len, B, len, len, prec); _acb_poly_mullow(thetas[1], theta2, len, B, len, len, prec); _acb_poly_mullow(thetas[2], theta3, len, B, len, len, prec); _acb_poly_mullow(thetas[3], theta4, len, B, len, len, prec); for (k = 0; k < len; k++) acb_swap(theta1 + k, thetas[0] + k); for (k = 0; k < len; k++) acb_swap(theta2 + k, thetas[1] + k); for (k = 0; k < len; k++) acb_swap(theta3 + k, thetas[2] + k); for (k = 0; k < len; k++) acb_swap(theta4 + k, thetas[3] + k); } fmpq_clear(t); acb_clear(z_prime); acb_clear(q); acb_clear(q4); acb_clear(w); acb_clear(A); _acb_vec_clear(B, len); _acb_vec_clear(thetas[0], len); _acb_vec_clear(thetas[1], len); _acb_vec_clear(thetas[2], len); _acb_vec_clear(thetas[3], len); } psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); } arb-2.22.1/acb_modular/theta_jet_notransform.c000066400000000000000000000022501417376376500213770ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_theta_jet_notransform(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t z, const acb_t tau, slong len, slong prec) { acb_t q, q4, w; int w_is_unit; acb_init(q); acb_init(q4); acb_init(w); /* compute q_{1/4}, q */ acb_mul_2exp_si(q4, tau, -2); acb_exp_pi_i(q4, q4, prec); acb_pow_ui(q, q4, 4, prec); /* compute w */ acb_exp_pi_i(w, z, prec); w_is_unit = arb_is_zero(acb_imagref(z)); /* evaluate theta functions */ acb_modular_theta_sum(theta1, theta2, theta3, theta4, w, w_is_unit, q, len, prec); _acb_vec_scalar_mul(theta1, theta1, len, q4, prec); _acb_vec_scalar_mul(theta2, theta2, len, q4, prec); acb_clear(q); acb_clear(q4); acb_clear(w); } arb-2.22.1/acb_modular/theta_series.c000066400000000000000000000064741417376376500174730ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void _acb_modular_theta_series(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec) { acb_ptr t1, t2, t3, t4, t, v; zlen = FLINT_MIN(zlen, len); if (zlen <= 0) return; t = _acb_vec_init(4 * len); t1 = t; t2 = t1 + len; t3 = t2 + len; t4 = t3 + len; acb_modular_theta_jet(t1, t2, t3, t4, z, tau, len, prec); if (len == 1) { if (theta1 != NULL) acb_set(theta1, t1); if (theta2 != NULL) acb_set(theta2, t2); if (theta3 != NULL) acb_set(theta3, t3); if (theta4 != NULL) acb_set(theta4, t4); } else { v = _acb_vec_init(zlen); /* compose with nonconstant part */ acb_zero(v); _acb_vec_set(v + 1, z + 1, zlen - 1); if (theta1 != NULL) _acb_poly_compose_series(theta1, t1, len, v, zlen, len, prec); if (theta2 != NULL) _acb_poly_compose_series(theta2, t2, len, v, zlen, len, prec); if (theta3 != NULL) _acb_poly_compose_series(theta3, t3, len, v, zlen, len, prec); if (theta4 != NULL) _acb_poly_compose_series(theta4, t4, len, v, zlen, len, prec); _acb_vec_clear(v, zlen); } _acb_vec_clear(t, 4 * len); } void acb_modular_theta_series(acb_poly_t theta1, acb_poly_t theta2, acb_poly_t theta3, acb_poly_t theta4, const acb_poly_t z, const acb_t tau, slong len, slong prec) { if (len == 0) { if (theta1 != NULL) acb_poly_zero(theta1); if (theta2 != NULL) acb_poly_zero(theta2); if (theta3 != NULL) acb_poly_zero(theta3); if (theta4 != NULL) acb_poly_zero(theta4); return; } if (z->length <= 1) len = 1; if (theta1 != NULL) acb_poly_fit_length(theta1, len); if (theta2 != NULL) acb_poly_fit_length(theta2, len); if (theta3 != NULL) acb_poly_fit_length(theta3, len); if (theta4 != NULL) acb_poly_fit_length(theta4, len); if (z->length == 0) { acb_t t; acb_init(t); _acb_modular_theta_series(theta1 ? theta1->coeffs : NULL, theta2 ? theta2->coeffs : NULL, theta3 ? theta3->coeffs : NULL, theta4 ? theta4->coeffs : NULL, t, 1, tau, len, prec); acb_clear(t); } else { _acb_modular_theta_series(theta1 ? theta1->coeffs : NULL, theta2 ? theta2->coeffs : NULL, theta3 ? theta3->coeffs : NULL, theta4 ? theta4->coeffs : NULL, z->coeffs, z->length, tau, len, prec); } if (theta1 != NULL) _acb_poly_set_length(theta1, len); if (theta2 != NULL) _acb_poly_set_length(theta2, len); if (theta3 != NULL) _acb_poly_set_length(theta3, len); if (theta4 != NULL) _acb_poly_set_length(theta4, len); if (theta1 != NULL) _acb_poly_normalise(theta1); if (theta2 != NULL) _acb_poly_normalise(theta2); if (theta3 != NULL) _acb_poly_normalise(theta3); if (theta4 != NULL) _acb_poly_normalise(theta4); } arb-2.22.1/acb_modular/theta_sum.c000066400000000000000000000325551417376376500170040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_theta_sum(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t w, int w_is_unit, const acb_t q, slong len, slong prec) { mag_t qmag, wmag, vmag; mag_ptr err; double log2q_approx, log2w_approx, log2term_approx; slong e, e1, e2, k, k1, k2, r, n, N, WN, term_prec; slong *exponents, *aindex, *bindex; acb_ptr qpow, wpow, vpow; acb_t tmp1, tmp2, v; int q_is_real, w_is_one; q_is_real = arb_is_zero(acb_imagref(q)); w_is_one = acb_is_one(w); if (w_is_one && len == 1) { acb_modular_theta_const_sum(theta2, theta3, theta4, q, prec); acb_zero(theta1); return; } mag_init(qmag); mag_init(wmag); mag_init(vmag); acb_init(tmp1); acb_init(tmp2); acb_init(v); err = _mag_vec_init(len); if (w_is_one) acb_one(v); else if (w_is_unit) acb_conj(v, w); else acb_inv(v, w, prec); acb_get_mag(qmag, q); log2q_approx = mag_get_d_log2_approx(qmag); if (w_is_unit) { mag_one(wmag); mag_one(vmag); log2w_approx = 0.0; } else { acb_get_mag(wmag, w); acb_get_mag(vmag, v); mag_max(wmag, wmag, vmag); log2w_approx = mag_get_d_log2_approx(wmag); } if (log2q_approx >= 0.0) { N = 1; for (r = 0; r < len; r++) mag_inf(err + r); } else /* Pick N and compute error bound */ { mag_t den, cmag, dmag; mag_init(den); mag_init(cmag); mag_init(dmag); N = 1; while (0.05 * N * N < prec) { log2term_approx = log2q_approx * ((N+2)*(N+2)/4) + (N+2)*log2w_approx; if (log2term_approx < -prec - 2) break; N++; } if (len == 1) { if (w_is_unit) { mag_one(den); mag_sub_lower(den, den, qmag); /* 1 - |q| is good enough */ } else /* denominator: 1 - |q|^(floor((N+1)/2)+1) * max(|w|,1/|w|) */ { mag_pow_ui(err, qmag, (N + 1) / 2 + 1); mag_mul(err, err, wmag); mag_one(den); mag_sub_lower(den, den, err); } /* no convergence */ if (mag_is_zero(den)) { N = 1; mag_inf(err); } else if (w_is_unit) { mag_pow_ui(err, qmag, ((N + 2) * (N + 2)) / 4); mag_div(err, err, den); mag_mul_2exp_si(err, err, 1); } else { mag_pow_ui(err, qmag, ((N + 2) * (N + 2)) / 4); mag_pow_ui(vmag, wmag, N + 2); mag_mul(err, err, vmag); mag_div(err, err, den); mag_mul_2exp_si(err, err, 1); } } else { /* numerator: 2 |q|^E * max(|w|,|v|)^(N+2) * (N+2)^r */ mag_pow_ui(err, qmag, ((N + 2) * (N + 2)) / 4); if (!w_is_one) { mag_pow_ui(vmag, wmag, N + 2); mag_mul(err, err, vmag); } mag_mul_2exp_si(err, err, 1); for (r = 1; r < len; r++) mag_mul_ui(err + r, err + r - 1, N + 2); /* den: 1 - |q|^floor((N+1)/2+1) * max(|w|,|v|) * exp(r/(N+2)) */ mag_pow_ui(cmag, qmag, (N + 1) / 2 + 1); mag_mul(cmag, cmag, wmag); for (r = 0; r < len; r++) { mag_set_ui(dmag, r); mag_div_ui(dmag, dmag, N + 2); mag_exp(dmag, dmag); mag_mul(dmag, cmag, dmag); mag_one(den); mag_sub_lower(den, den, dmag); if (mag_is_zero(den)) mag_inf(err + r); else mag_div(err + r, err + r, den); } } /* don't do work if we can't determine the zeroth derivative */ if (mag_is_inf(err)) N = 1; mag_clear(den); mag_clear(cmag); mag_clear(dmag); } exponents = flint_malloc(sizeof(slong) * 3 * N); aindex = exponents + N; bindex = aindex + N; qpow = _acb_vec_init(N); acb_modular_addseq_theta(exponents, aindex, bindex, N); acb_set_round(qpow + 0, q, prec); _acb_vec_zero(theta1, len); _acb_vec_zero(theta2, len); _acb_vec_zero(theta3, len); _acb_vec_zero(theta4, len); WN = (N + 3) / 2; /* compute powers of w^2 and 1/w^2 */ /* todo: conjugates... */ if (!w_is_one) { wpow = _acb_vec_init(WN); vpow = _acb_vec_init(WN + 1); acb_mul(tmp1, w, w, prec); acb_mul(tmp2, v, v, prec); _acb_vec_set_powers(wpow, tmp1, WN, prec); _acb_vec_set_powers(vpow, tmp2, WN + 1, prec); } else { wpow = vpow = NULL; } for (k = 0; k < N; k++) { e = exponents[k]; log2term_approx = e * log2q_approx + (k+2) * log2w_approx; term_prec = FLINT_MIN(FLINT_MAX(prec + log2term_approx + 16.0, 16.0), prec); if (k > 0) { k1 = aindex[k]; k2 = bindex[k]; e1 = exponents[k1]; e2 = exponents[k2]; if (e == e1 + e2) { _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + k1, qpow + k2, term_prec, prec); } else if (e == 2 * e1 + e2) { _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + k1, qpow + k1, term_prec, prec); _acb_modular_mul(qpow + k, tmp1, tmp2, qpow + k, qpow + k2, term_prec, prec); } else { flint_printf("exponent not in addition sequence!\n"); flint_abort(); } } if (w_is_one && len == 1) { if (k % 2 == 0) { acb_add(theta3, theta3, qpow + k, prec); if (k % 4 == 0) acb_sub(theta4, theta4, qpow + k, prec); else acb_add(theta4, theta4, qpow + k, prec); } else { acb_add(theta2, theta2, qpow + k, prec); } } else { n = k / 2 + 1; if (k % 2 == 0) { acb_ptr term; if (w_is_one) { acb_mul_2exp_si(tmp1, qpow + k, 1); acb_zero(tmp2); } else { /* tmp1 = w^(2n) + v^(2n) ~= 2 cos(2n) */ acb_add(tmp1, wpow + n, vpow + n, term_prec); acb_mul(tmp1, qpow + k, tmp1, term_prec); /* tmp2 = w^(2n) - v^(2n) ~= 2 sin(2n) */ if (len > 1) { acb_sub(tmp2, wpow + n, vpow + n, term_prec); acb_mul(tmp2, qpow + k, tmp2, term_prec); } } /* compute all the derivatives */ for (r = 0; r < len; r++) { term = (r % 2 == 0) ? tmp1 : tmp2; if (r == 1) acb_mul_ui(term, term, 2 * n, term_prec); else if (r > 1) acb_mul_ui(term, term, 4 * n * n, term_prec); acb_add(theta3 + r, theta3 + r, term, prec); if (k % 4 == 0) acb_sub(theta4 + r, theta4 + r, term, prec); else acb_add(theta4 + r, theta4 + r, term, prec); } } else { acb_ptr term; if (w_is_one) { acb_mul_2exp_si(tmp1, qpow + k, 1); acb_zero(tmp2); } else { /* tmp1 = w^(2n) + v^(2n+2) ~= 2 cos(2n+1) / w */ acb_add(tmp1, wpow + n, vpow + n + 1, term_prec); acb_mul(tmp1, qpow + k, tmp1, term_prec); /* tmp2 = w^(2n) - v^(2n+2) ~= 2 sin(2n+1) / w */ acb_sub(tmp2, wpow + n, vpow + n + 1, term_prec); acb_mul(tmp2, qpow + k, tmp2, term_prec); } /* compute all the derivatives */ for (r = 0; r < len; r++) { if (r > 0) { acb_mul_ui(tmp1, tmp1, 2 * n + 1, term_prec); acb_mul_ui(tmp2, tmp2, 2 * n + 1, term_prec); } term = (r % 2 == 0) ? tmp2 : tmp1; if (k % 4 == 1) acb_sub(theta1 + r, theta1 + r, term, prec); else acb_add(theta1 + r, theta1 + r, term, prec); term = (r % 2 == 0) ? tmp1 : tmp2; acb_add(theta2 + r, theta2 + r, term, prec); } } } } if (w_is_one && len == 1) { acb_mul_2exp_si(theta2, theta2, 1); acb_mul_2exp_si(theta3, theta3, 1); acb_mul_2exp_si(theta4, theta4, 1); } /* theta1: w * sum + 2 sin */ /* theta2: w * sum + 2 cos */ if (!w_is_one) { _acb_vec_scalar_mul(theta1, theta1, len, w, prec); _acb_vec_scalar_mul(theta2, theta2, len, w, prec); acb_add(tmp1, w, v, prec); acb_sub(tmp2, w, v, prec); } else { acb_set_ui(tmp1, 2); acb_zero(tmp2); } for (r = 0; r < len; r++) { acb_add(theta1 + r, theta1 + r, (r % 2 == 0) ? tmp2 : tmp1, prec); acb_add(theta2 + r, theta2 + r, (r % 2 == 0) ? tmp1 : tmp2, prec); } /* Coefficient r in the z-expansion gains a factor: pi^r / r! times a sign: + 2 cos = +1 * (exp + 1/exp) - 2 sin = +i * (exp - 1/exp) - 2 cos = -1 * (exp + 1/exp) + 2 sin = -i * (exp - 1/exp) ... */ acb_mul_onei(theta1, theta1); acb_neg(theta1, theta1); for (r = 1; r < len; r++) { if (r % 4 == 0) { acb_mul_onei(theta1 + r, theta1 + r); acb_neg(theta1 + r, theta1 + r); } else if (r % 4 == 1) { acb_mul_onei(theta2 + r, theta2 + r); acb_mul_onei(theta3 + r, theta3 + r); acb_mul_onei(theta4 + r, theta4 + r); } else if (r % 4 == 2) { acb_mul_onei(theta1 + r, theta1 + r); acb_neg(theta2 + r, theta2 + r); acb_neg(theta3 + r, theta3 + r); acb_neg(theta4 + r, theta4 + r); } else { acb_neg(theta1 + r, theta1 + r); acb_mul_onei(theta2 + r, theta2 + r); acb_mul_onei(theta3 + r, theta3 + r); acb_mul_onei(theta4 + r, theta4 + r); acb_neg(theta2 + r, theta2 + r); acb_neg(theta3 + r, theta3 + r); acb_neg(theta4 + r, theta4 + r); } } /* Add error bound. Note that this must be done after the rearrangements above, and before scaling by pi^r / r! below. */ for (r = 0; r < len; r++) { if (q_is_real && w_is_unit) /* result must be real */ { arb_add_error_mag(acb_realref(theta1 + r), err + r); arb_add_error_mag(acb_realref(theta2 + r), err + r); arb_add_error_mag(acb_realref(theta3 + r), err + r); arb_add_error_mag(acb_realref(theta4 + r), err + r); } else { acb_add_error_mag(theta1 + r, err + r); acb_add_error_mag(theta2 + r, err + r); acb_add_error_mag(theta3 + r, err + r); acb_add_error_mag(theta4 + r, err + r); } } if (len > 1) { arb_t c, d; arb_init(c); arb_init(d); arb_const_pi(c, prec); arb_set(d, c); for (r = 1; r < len; r++) { acb_mul_arb(theta1 + r, theta1 + r, d, prec); acb_mul_arb(theta2 + r, theta2 + r, d, prec); acb_mul_arb(theta3 + r, theta3 + r, d, prec); acb_mul_arb(theta4 + r, theta4 + r, d, prec); if (r + 1 < len) { arb_mul(d, d, c, prec); arb_div_ui(d, d, r + 1, prec); } } arb_clear(c); arb_clear(d); } acb_add_ui(theta3, theta3, 1, prec); acb_add_ui(theta4, theta4, 1, prec); if (!w_is_one) { _acb_vec_clear(wpow, WN); _acb_vec_clear(vpow, WN + 1); } flint_free(exponents); _acb_vec_clear(qpow, N); acb_clear(tmp1); acb_clear(tmp2); acb_clear(v); mag_clear(qmag); mag_clear(wmag); mag_clear(vmag); _mag_vec_clear(err, len); } arb-2.22.1/acb_modular/theta_transform.c000066400000000000000000000045141417376376500202050ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" /* convert theta_{m,n} to theta_i */ static int swappy1(int m, int n) { m = m & 1; n = n & 1; if (m == 0 && n == 0) return 2; if (m == 0 && n == 1) return 3; if (m == 1 && n == 0) return 1; return 0; } /* extra phase shift picked up: a factor (-1)^n when m is congruent to 2,3 (mod 4), and possibly a factor i = sqrt(-1) when converting from theta_1 to theta_{1,1} */ static int swappy2(int m, int n) { m = m & 3; n = n & 1; if (m == 1 && n == 1) return 2; /* i */ if (m == 2 && n == 1) return 4; /* (-1)^n */ if (m == 3 && n == 1) return 6; /* (-1)^n * i */ return 0; } void acb_modular_theta_transform(int * R, int * S, int * C, const psl2z_t g) { R[0] = 0; R[1] = 0; R[2] = 0; R[3] = 0; S[0] = 0; S[1] = 1; S[2] = 2; S[3] = 3; if (fmpz_is_zero(&g->c)) { C[0] = 0; if (fmpz_is_odd(&g->b)) { S[2] = 3; S[3] = 2; } /* -b mod 8 */ R[0] = (- (int) fmpz_fdiv_ui(&g->b, 8)) & 7; R[1] = R[0]; } else { int a, b, c, d, e1, e2; psl2z_t h; psl2z_init(h); psl2z_inv(h, g); e1 = acb_modular_epsilon_arg(h); e2 = acb_modular_epsilon_arg(g); psl2z_clear(h); C[0] = 1; a = fmpz_fdiv_ui(&g->a, 8); b = fmpz_fdiv_ui(&g->b, 8); c = fmpz_fdiv_ui(&g->c, 8); d = fmpz_fdiv_ui(&g->d, 8); R[0] = e1 + 1; R[1] = -e2 + 5 + (2 - c) * a; R[2] = -e2 + 4 + (c - d - 2) * (b - a); R[3] = -e2 + 3 - (2 + d) * b; S[1] = swappy1(1 - c, 1 + a); R[1] += swappy2(1 - c, 1 + a); S[2] = swappy1(1 + d - c, 1 - b + a); R[2] += swappy2(1 + d - c, 1 - b + a); S[3] = swappy1(1 + d, 1 - b); R[3] += swappy2(1 + d, 1 - b); /* floor mod by 8 */ R[0] &= 7; R[1] &= 7; R[2] &= 7; R[3] &= 7; } } arb-2.22.1/acb_modular/transform.c000066400000000000000000000046001417376376500170140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_modular.h" void acb_modular_transform(acb_t w, const psl2z_t g, const acb_t z, slong prec) { #define a (&g->a) #define b (&g->b) #define c (&g->c) #define d (&g->d) #define x acb_realref(z) #define y acb_imagref(z) if (fmpz_is_zero(c)) { /* (az+b)/d, where we must have a = d = 1 */ acb_add_fmpz(w, z, b, prec); } else if (fmpz_is_zero(a)) { /* b/(cz+d), where -bc = 1, c = 1 => -1/(z+d) */ acb_add_fmpz(w, z, d, prec); acb_inv(w, w, prec); acb_neg(w, w); } else if (0) { acb_t t, u; acb_init(t); acb_init(u); acb_set_fmpz(t, b); acb_addmul_fmpz(t, z, a, prec); acb_set_fmpz(u, d); acb_addmul_fmpz(u, z, c, prec); acb_div(w, t, u, prec); acb_clear(t); acb_clear(u); } else { /* (az+b)/(cz+d) = (re+im*i)/den where re = bd + (bc+ad)x + ac(x^2+y^2) im = (ad-bc)y den = c^2(x^2+y^2) + 2cdx + d^2 */ fmpz_t t; arb_t re, im, den; arb_init(re); arb_init(im); arb_init(den); fmpz_init(t); arb_mul(im, x, x, prec); arb_addmul(im, y, y, prec); fmpz_mul(t, b, d); arb_set_fmpz(re, t); fmpz_mul(t, b, c); fmpz_addmul(t, a, d); arb_addmul_fmpz(re, x, t, prec); fmpz_mul(t, a, c); arb_addmul_fmpz(re, im, t, prec); fmpz_mul(t, d, d); arb_set_fmpz(den, t); fmpz_mul(t, c, d); fmpz_mul_2exp(t, t, 1); arb_addmul_fmpz(den, x, t, prec); fmpz_mul(t, c, c); arb_addmul_fmpz(den, im, t, prec); fmpz_mul(t, a, d); fmpz_submul(t, b, c); arb_mul_fmpz(im, y, t, prec); arb_div(acb_realref(w), re, den, prec); arb_div(acb_imagref(w), im, den, prec); arb_clear(re); arb_clear(im); arb_clear(den); fmpz_clear(t); } #undef a #undef b #undef c #undef d #undef x #undef y } arb-2.22.1/acb_poly.h000066400000000000000000000706761417376376500143460ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ACB_POLY_H #define ACB_POLY_H #ifdef ACB_POLY_INLINES_C #define ACB_POLY_INLINE #else #define ACB_POLY_INLINE static __inline__ #endif #include #include "acb.h" #include "arb_poly.h" #ifdef __cplusplus extern "C" { #endif typedef struct { acb_ptr coeffs; slong length; slong alloc; } acb_poly_struct; typedef acb_poly_struct acb_poly_t[1]; /* Memory management */ void acb_poly_init(acb_poly_t poly); void acb_poly_init2(acb_poly_t poly, slong len); void acb_poly_clear(acb_poly_t poly); void acb_poly_fit_length(acb_poly_t poly, slong len); void _acb_poly_set_length(acb_poly_t poly, slong len); void _acb_poly_normalise(acb_poly_t poly); ACB_POLY_INLINE void acb_poly_swap(acb_poly_t poly1, acb_poly_t poly2) { acb_poly_struct t = *poly1; *poly1 = *poly2; *poly2 = t; } ACB_POLY_INLINE slong acb_poly_length(const acb_poly_t poly) { return poly->length; } ACB_POLY_INLINE slong acb_poly_degree(const acb_poly_t poly) { return poly->length - 1; } slong acb_poly_valuation(const acb_poly_t poly); ACB_POLY_INLINE int acb_poly_is_zero(const acb_poly_t z) { return acb_poly_length(z) == 0; } ACB_POLY_INLINE int acb_poly_is_one(const acb_poly_t z) { return (acb_poly_length(z) == 1) && acb_is_one(z->coeffs); } ACB_POLY_INLINE int acb_poly_is_x(const acb_poly_t z) { return (acb_poly_length(z) == 2) && acb_is_zero(z->coeffs) && acb_is_one(z->coeffs + 1); } ACB_POLY_INLINE void acb_poly_zero(acb_poly_t poly) { poly->length = 0; } ACB_POLY_INLINE void acb_poly_one(acb_poly_t poly) { acb_poly_fit_length(poly, 1); acb_one(poly->coeffs); _acb_poly_set_length(poly, 1); } void acb_poly_set_coeff_si(acb_poly_t poly, slong n, slong x); void acb_poly_set_coeff_acb(acb_poly_t poly, slong n, const acb_t x); void acb_poly_get_coeff_acb(acb_t x, const acb_poly_t poly, slong n); #define acb_poly_get_coeff_ptr(poly, n) \ ((n) < (poly)->length ? (poly)->coeffs + (n) : NULL) void _acb_poly_shift_right(acb_ptr res, acb_srcptr poly, slong len, slong n); void acb_poly_shift_right(acb_poly_t res, const acb_poly_t poly, slong n); void _acb_poly_shift_left(acb_ptr res, acb_srcptr poly, slong len, slong n); void acb_poly_shift_left(acb_poly_t res, const acb_poly_t poly, slong n); ACB_POLY_INLINE void acb_poly_truncate(acb_poly_t poly, slong newlen) { if (poly->length > newlen) { slong i; for (i = newlen; i < poly->length; i++) acb_zero(poly->coeffs + i); poly->length = newlen; _acb_poly_normalise(poly); } } void _acb_poly_majorant(arb_ptr res, acb_srcptr vec, slong len, slong prec); void acb_poly_majorant(arb_poly_t res, const acb_poly_t poly, slong prec); void acb_poly_fprintd(FILE * file, const acb_poly_t poly, slong digits); ACB_POLY_INLINE void acb_poly_printd(const acb_poly_t poly, slong digits) { acb_poly_fprintd(stdout, poly, digits); } void _acb_poly_evaluate_horner(acb_t res, acb_srcptr f, slong len, const acb_t a, slong prec); void acb_poly_evaluate_horner(acb_t res, const acb_poly_t f, const acb_t a, slong prec); void _acb_poly_evaluate_rectangular(acb_t y, acb_srcptr poly, slong len, const acb_t x, slong prec); void acb_poly_evaluate_rectangular(acb_t res, const acb_poly_t f, const acb_t a, slong prec); void _acb_poly_evaluate(acb_t res, acb_srcptr f, slong len, const acb_t a, slong prec); void acb_poly_evaluate(acb_t res, const acb_poly_t f, const acb_t a, slong prec); void _acb_poly_evaluate2_horner(acb_t y, acb_t z, acb_srcptr f, slong len, const acb_t x, slong prec); void acb_poly_evaluate2_horner(acb_t y, acb_t z, const acb_poly_t f, const acb_t x, slong prec); void _acb_poly_evaluate2_rectangular(acb_t y, acb_t z, acb_srcptr f, slong len, const acb_t x, slong prec); void acb_poly_evaluate2_rectangular(acb_t y, acb_t z, const acb_poly_t f, const acb_t x, slong prec); void _acb_poly_evaluate2(acb_t y, acb_t z, acb_srcptr f, slong len, const acb_t x, slong prec); void acb_poly_evaluate2(acb_t y, acb_t z, const acb_poly_t f, const acb_t x, slong prec); void _acb_poly_derivative(acb_ptr res, acb_srcptr poly, slong len, slong prec); void acb_poly_derivative(acb_poly_t res, const acb_poly_t poly, slong prec); void _acb_poly_integral(acb_ptr res, acb_srcptr poly, slong len, slong prec); void acb_poly_integral(acb_poly_t res, const acb_poly_t poly, slong prec); /* Transforms */ void acb_poly_borel_transform(acb_poly_t res, const acb_poly_t poly, slong prec); void _acb_poly_borel_transform(acb_ptr res, acb_srcptr poly, slong len, slong prec); void acb_poly_inv_borel_transform(acb_poly_t res, const acb_poly_t poly, slong prec); void _acb_poly_inv_borel_transform(acb_ptr res, acb_srcptr poly, slong len, slong prec); void _acb_poly_binomial_transform_basecase(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec); void acb_poly_binomial_transform_basecase(acb_poly_t b, const acb_poly_t a, slong len, slong prec); void _acb_poly_binomial_transform_convolution(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec); void acb_poly_binomial_transform_convolution(acb_poly_t b, const acb_poly_t a, slong len, slong prec); void _acb_poly_binomial_transform(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec); void acb_poly_binomial_transform(acb_poly_t b, const acb_poly_t a, slong len, slong prec); void _acb_poly_graeffe_transform(acb_ptr b, acb_srcptr a, slong len, slong prec); void acb_poly_graeffe_transform(acb_poly_t b, const acb_poly_t a, slong prec); void acb_poly_set(acb_poly_t dest, const acb_poly_t src); void acb_poly_set_round(acb_poly_t dest, const acb_poly_t src, slong prec); void acb_poly_set_trunc(acb_poly_t res, const acb_poly_t poly, slong n); void acb_poly_set_trunc_round(acb_poly_t res, const acb_poly_t poly, slong n, slong prec); void acb_poly_set_arb_poly(acb_poly_t poly, const arb_poly_t re); void acb_poly_set2_arb_poly(acb_poly_t poly, const arb_poly_t re, const arb_poly_t im); void acb_poly_set_fmpq_poly(acb_poly_t poly, const fmpq_poly_t re, slong prec); void acb_poly_set2_fmpq_poly(acb_poly_t poly, const fmpq_poly_t re, const fmpq_poly_t im, slong prec); void acb_poly_set_fmpz_poly(acb_poly_t poly, const fmpz_poly_t src, slong prec); void acb_poly_set2_fmpz_poly(acb_poly_t poly, const fmpz_poly_t re, const fmpz_poly_t im, slong prec); int acb_poly_get_unique_fmpz_poly(fmpz_poly_t res, const acb_poly_t src); ACB_POLY_INLINE void acb_poly_set_acb(acb_poly_t poly, const acb_t c) { acb_poly_fit_length(poly, 1); acb_set(poly->coeffs, c); _acb_poly_set_length(poly, !acb_is_zero(poly->coeffs)); } void acb_poly_set_si(acb_poly_t poly, slong c); void acb_poly_randtest(acb_poly_t poly, flint_rand_t state, slong len, slong prec, slong mag_bits); int acb_poly_equal(const acb_poly_t A, const acb_poly_t B); int acb_poly_contains_fmpz_poly(const acb_poly_t poly1, const fmpz_poly_t poly2); int acb_poly_contains_fmpq_poly(const acb_poly_t poly1, const fmpq_poly_t poly2); int _acb_poly_overlaps(acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2); int acb_poly_overlaps(const acb_poly_t poly1, const acb_poly_t poly2); int acb_poly_contains(const acb_poly_t poly1, const acb_poly_t poly2); ACB_POLY_INLINE int acb_poly_is_real(const acb_poly_t poly) { return _acb_vec_is_real(poly->coeffs, poly->length); } void _acb_poly_add(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec); void acb_poly_add(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec); void acb_poly_add_si(acb_poly_t res, const acb_poly_t poly, slong c, slong prec); void _acb_poly_sub(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec); void acb_poly_sub(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec); void acb_poly_add_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong len, slong prec); void acb_poly_sub_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong len, slong prec); ACB_POLY_INLINE void acb_poly_neg(acb_poly_t res, const acb_poly_t poly) { acb_poly_fit_length(res, poly->length); _acb_vec_neg(res->coeffs, poly->coeffs, poly->length); _acb_poly_set_length(res, poly->length); } ACB_POLY_INLINE void acb_poly_scalar_mul_2exp_si(acb_poly_t res, const acb_poly_t poly, slong c) { acb_poly_fit_length(res, poly->length); _acb_vec_scalar_mul_2exp_si(res->coeffs, poly->coeffs, poly->length, c); _acb_poly_set_length(res, poly->length); } ACB_POLY_INLINE void acb_poly_scalar_mul(acb_poly_t res, const acb_poly_t poly, const acb_t c, slong prec) { acb_poly_fit_length(res, poly->length); _acb_vec_scalar_mul(res->coeffs, poly->coeffs, poly->length, c, prec); _acb_poly_set_length(res, poly->length); _acb_poly_normalise(res); } ACB_POLY_INLINE void acb_poly_scalar_div(acb_poly_t res, const acb_poly_t poly, const acb_t c, slong prec) { acb_poly_fit_length(res, poly->length); _acb_vec_scalar_div(res->coeffs, poly->coeffs, poly->length, c, prec); _acb_poly_set_length(res, poly->length); _acb_poly_normalise(res); } void acb_poly_mullow_classical(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec); void _acb_poly_mullow_classical(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec); void _acb_poly_mullow_transpose(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec); void acb_poly_mullow_transpose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec); void _acb_poly_mullow_transpose_gauss(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec); void acb_poly_mullow_transpose_gauss(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec); void _acb_poly_mullow(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec); void acb_poly_mullow(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec); void _acb_poly_mul(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec); void acb_poly_mul(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec); ACB_POLY_INLINE void _acb_poly_mul_monic(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) { if (len1 + len2 - 2 > 0) _acb_poly_mullow(res, poly1, len1, poly2, len2, len1 + len2 - 2, prec); acb_one(res + len1 + len2 - 2); } void _acb_poly_inv_series(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong len, slong prec); void acb_poly_inv_series(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec); void _acb_poly_div_series(acb_ptr Q, acb_srcptr A, slong Alen, acb_srcptr B, slong Blen, slong n, slong prec); void acb_poly_div_series(acb_poly_t Q, const acb_poly_t A, const acb_poly_t B, slong n, slong prec); void _acb_poly_reverse(acb_ptr res, acb_srcptr poly, slong len, slong n); void _acb_poly_div(acb_ptr Q, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec); void _acb_poly_divrem(acb_ptr Q, acb_ptr R, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec); void _acb_poly_rem(acb_ptr R, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec); int acb_poly_divrem(acb_poly_t Q, acb_poly_t R, const acb_poly_t A, const acb_poly_t B, slong prec); void _acb_poly_div_root(acb_ptr Q, acb_t R, acb_srcptr A, slong len, const acb_t c, slong prec); /* Composition */ void _acb_poly_taylor_shift_horner(acb_ptr poly, const acb_t c, slong n, slong prec); void acb_poly_taylor_shift_horner(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec); void _acb_poly_taylor_shift_divconquer(acb_ptr poly, const acb_t c, slong n, slong prec); void acb_poly_taylor_shift_divconquer(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec); void _acb_poly_taylor_shift_convolution(acb_ptr poly, const acb_t c, slong n, slong prec); void acb_poly_taylor_shift_convolution(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec); void _acb_poly_taylor_shift(acb_ptr poly, const acb_t c, slong n, slong prec); void acb_poly_taylor_shift(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec); void _acb_poly_compose(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec); void acb_poly_compose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec); void _acb_poly_compose_horner(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec); void acb_poly_compose_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec); void _acb_poly_compose_divconquer(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec); void acb_poly_compose_divconquer(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec); void _acb_poly_compose_series_horner(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec); void acb_poly_compose_series_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec); void _acb_poly_compose_series_brent_kung(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec); void acb_poly_compose_series_brent_kung(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec); void _acb_poly_compose_series(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec); void acb_poly_compose_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec); /* Reversion */ void _acb_poly_revert_series_lagrange(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec); void acb_poly_revert_series_lagrange(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec); void _acb_poly_revert_series_newton(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec); void acb_poly_revert_series_newton(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec); void _acb_poly_revert_series_lagrange_fast(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec); void acb_poly_revert_series_lagrange_fast(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec); void _acb_poly_revert_series(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec); void acb_poly_revert_series(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec); void _acb_poly_evaluate_vec_fast_precomp(acb_ptr vs, acb_srcptr poly, slong plen, acb_ptr * tree, slong len, slong prec); void _acb_poly_evaluate_vec_fast(acb_ptr ys, acb_srcptr poly, slong plen, acb_srcptr xs, slong n, slong prec); void acb_poly_evaluate_vec_fast(acb_ptr ys, const acb_poly_t poly, acb_srcptr xs, slong n, slong prec); void _acb_poly_evaluate_vec_iter(acb_ptr ys, acb_srcptr poly, slong plen, acb_srcptr xs, slong n, slong prec); void acb_poly_evaluate_vec_iter(acb_ptr ys, const acb_poly_t poly, acb_srcptr xs, slong n, slong prec); void _acb_poly_interpolate_barycentric(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec); void acb_poly_interpolate_barycentric(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec); void _acb_poly_interpolation_weights(acb_ptr w, acb_ptr * tree, slong len, slong prec); void _acb_poly_interpolate_fast_precomp(acb_ptr poly, acb_srcptr ys, acb_ptr * tree, acb_srcptr weights, slong len, slong prec); void _acb_poly_interpolate_fast(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong len, slong prec); void acb_poly_interpolate_fast(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec); void _acb_poly_interpolate_newton(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec); void acb_poly_interpolate_newton(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec); void _acb_poly_product_roots(acb_ptr poly, acb_srcptr xs, slong n, slong prec); void acb_poly_product_roots(acb_poly_t poly, acb_srcptr xs, slong n, slong prec); acb_ptr * _acb_poly_tree_alloc(slong len); void _acb_poly_tree_free(acb_ptr * tree, slong len); void _acb_poly_tree_build(acb_ptr * tree, acb_srcptr roots, slong len, slong prec); void _acb_poly_root_inclusion(acb_t r, const acb_t m, acb_srcptr poly, acb_srcptr polyder, slong len, slong prec); slong _acb_poly_validate_roots(acb_ptr roots, acb_srcptr poly, slong len, slong prec); void _acb_poly_refine_roots_durand_kerner(acb_ptr roots, acb_srcptr poly, slong len, slong prec); slong _acb_poly_find_roots(acb_ptr roots, acb_srcptr poly, acb_srcptr initial, slong len, slong maxiter, slong prec); slong acb_poly_find_roots(acb_ptr roots, const acb_poly_t poly, acb_srcptr initial, slong maxiter, slong prec); void _acb_poly_root_bound_fujiwara(mag_t bound, acb_srcptr poly, slong len); void acb_poly_root_bound_fujiwara(mag_t bound, acb_poly_t poly); int _acb_poly_validate_real_roots(acb_srcptr roots, acb_srcptr poly, slong len, slong prec); int acb_poly_validate_real_roots(acb_srcptr roots, const acb_poly_t poly, slong prec); /* Special functions */ void _acb_poly_pow_ui_trunc_binexp(acb_ptr res, acb_srcptr f, slong flen, ulong exp, slong len, slong prec); void acb_poly_pow_ui_trunc_binexp(acb_poly_t res, const acb_poly_t poly, ulong exp, slong len, slong prec); void _acb_poly_pow_ui(acb_ptr res, acb_srcptr f, slong flen, ulong exp, slong prec); void acb_poly_pow_ui(acb_poly_t res, const acb_poly_t poly, ulong exp, slong prec); void _acb_poly_rsqrt_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_rsqrt_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_sqrt_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_sqrt_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_log_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec); void acb_poly_log_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec); void _acb_poly_log1p_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec); void acb_poly_log1p_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec); void _acb_poly_atan_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec); void acb_poly_atan_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec); void _acb_poly_exp_series_basecase(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_exp_series_basecase(acb_poly_t f, const acb_poly_t h, slong n, slong prec); void _acb_poly_exp_series(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_exp_series(acb_poly_t f, const acb_poly_t h, slong n, slong prec); void _acb_poly_exp_pi_i_series(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_exp_pi_i_series(acb_poly_t f, const acb_poly_t h, slong n, slong prec); void _acb_poly_sinh_cosh_series_basecase(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_sinh_cosh_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec); void _acb_poly_sinh_cosh_series_exponential(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_sinh_cosh_series_exponential(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec); void _acb_poly_sinh_cosh_series(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_sinh_cosh_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec); void _acb_poly_sinh_series(acb_ptr s, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_sinh_series(acb_poly_t s, const acb_poly_t h, slong n, slong prec); void _acb_poly_cosh_series(acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_cosh_series(acb_poly_t c, const acb_poly_t h, slong n, slong prec); void _acb_poly_sin_cos_series_basecase(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec, int times_pi); void acb_poly_sin_cos_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec, int times_pi); void _acb_poly_sin_cos_series_tangent(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong len, slong prec, int times_pi); void acb_poly_sin_cos_series_tangent(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec, int times_pi); void _acb_poly_sin_cos_series(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_sin_cos_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec); void _acb_poly_sin_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_sin_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_cos_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_cos_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_sin_cos_pi_series(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_sin_cos_pi_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec); void _acb_poly_sin_pi_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_sin_pi_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_cos_pi_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_cos_pi_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_cot_pi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_cot_pi_series(acb_poly_t res, const acb_poly_t f, slong len, slong prec); void _acb_poly_tan_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_tan_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_sinc_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_sinc_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); void _acb_poly_lambertw_series(acb_ptr res, acb_srcptr z, slong zlen, const fmpz_t k, int flags, slong len, slong prec); void acb_poly_lambertw_series(acb_poly_t res, const acb_poly_t z, const fmpz_t k, int flags, slong len, slong prec); void _acb_poly_gamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_gamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec); void _acb_poly_rgamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_rgamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec); void _acb_poly_lgamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_lgamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec); void _acb_poly_digamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec); void acb_poly_digamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec); void _acb_poly_rising_ui_series(acb_ptr res, acb_srcptr f, slong flen, ulong r, slong trunc, slong prec); void acb_poly_rising_ui_series(acb_poly_t res, const acb_poly_t f, ulong r, slong trunc, slong prec); void _acb_poly_pow_acb_series(acb_ptr h, acb_srcptr f, slong flen, const acb_t g, slong len, slong prec); void acb_poly_pow_acb_series(acb_poly_t h, const acb_poly_t f, const acb_t g, slong len, slong prec); void _acb_poly_pow_series(acb_ptr h, acb_srcptr f, slong flen, acb_srcptr g, slong glen, slong len, slong prec); void acb_poly_pow_series(acb_poly_t h, const acb_poly_t f, const acb_poly_t g, slong len, slong prec); void _acb_poly_binomial_pow_acb_series(acb_ptr h, acb_srcptr f, slong flen, const acb_t g, slong len, slong prec); /* TODO: document */ ACB_POLY_INLINE void _acb_poly_acb_pow_cpx(acb_ptr w, const acb_t a, const acb_t b, slong len, slong prec) { if (len == 1) { acb_pow(w, a, b, prec); } else { acb_t log_a; slong k; acb_init(log_a); acb_log(log_a, a, prec); acb_mul(w, log_a, b, prec); acb_exp(w, w, prec); for (k = 1; k < len; k++) { acb_mul(w + k, w + k - 1, log_a, prec); acb_div_ui(w + k, w + k, k, prec); } acb_clear(log_a); } } #define _acb_poly_pow_cpx _acb_poly_acb_pow_cpx /* TODO: document */ void _acb_poly_acb_invpow_cpx(acb_ptr res, const acb_t N, const acb_t c, slong trunc, slong prec); /* TODO: document */ void _acb_poly_mullow_cpx(acb_ptr res, acb_srcptr src, slong len, const acb_t c, slong trunc, slong prec); void _acb_poly_powsum_series_naive(acb_ptr z, const acb_t s, const acb_t a, const acb_t q, slong n, slong len, slong prec); void _acb_poly_powsum_series_naive_threaded(acb_ptr z, const acb_t s, const acb_t a, const acb_t q, slong n, slong len, slong prec); void _acb_poly_powsum_one_series_sieved(acb_ptr z, const acb_t s, slong n, slong len, slong prec); void _acb_poly_zeta_em_sum(acb_ptr z, const acb_t s, const acb_t a, int deflate, ulong N, ulong M, slong d, slong prec); void _acb_poly_zeta_em_choose_param(mag_t bound, ulong * N, ulong * M, const acb_t s, const acb_t a, slong d, slong target, slong prec); void _acb_poly_zeta_em_bound1(mag_t bound, const acb_t s, const acb_t a, slong N, slong M, slong d, slong wp); void _acb_poly_zeta_em_bound(arb_ptr vec, const acb_t s, const acb_t a, ulong N, ulong M, slong d, slong wp); void _acb_poly_zeta_em_tail_naive(acb_ptr sum, const acb_t s, const acb_t Na, acb_srcptr Nasx, slong M, slong len, slong prec); void _acb_poly_zeta_em_tail_bsplit(acb_ptr z, const acb_t s, const acb_t Na, acb_srcptr Nasx, slong M, slong len, slong prec); void _acb_poly_zeta_cpx_series(acb_ptr z, const acb_t s, const acb_t a, int deflate, slong d, slong prec); void _acb_poly_zeta_series(acb_ptr res, acb_srcptr h, slong hlen, const acb_t a, int deflate, slong len, slong prec); void acb_poly_zeta_series(acb_poly_t res, const acb_poly_t f, const acb_t a, int deflate, slong n, slong prec); void _acb_poly_polylog_cpx_zeta(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec); void _acb_poly_polylog_cpx_small(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec); void _acb_poly_polylog_cpx(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec); void _acb_poly_polylog_series(acb_ptr res, acb_srcptr s, slong slen, const acb_t z, slong len, slong prec); void acb_poly_polylog_series(acb_poly_t res, const acb_poly_t s, const acb_t z, slong n, slong prec); void _acb_poly_agm1_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec); void acb_poly_agm1_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec); void _acb_poly_elliptic_k_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec); void acb_poly_elliptic_k_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec); void _acb_poly_elliptic_p_series(acb_ptr res, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec); void acb_poly_elliptic_p_series(acb_poly_t res, const acb_poly_t z, const acb_t tau, slong n, slong prec); void _acb_poly_erf_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec); void acb_poly_erf_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec); ACB_POLY_INLINE slong acb_poly_allocated_bytes(const acb_poly_t x) { return _acb_vec_allocated_bytes(x->coeffs, x->alloc); } #ifdef __cplusplus } #endif #endif arb-2.22.1/acb_poly/000077500000000000000000000000001417376376500141555ustar00rootroot00000000000000arb-2.22.1/acb_poly/add.c000066400000000000000000000022601417376376500150510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_add(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) { slong i, min = FLINT_MIN(len1, len2); for (i = 0; i < min; i++) acb_add(res + i, poly1 + i, poly2 + i, prec); for (i = min; i < len1; i++) acb_set_round(res + i, poly1 + i, prec); for (i = min; i < len2; i++) acb_set_round(res + i, poly2 + i, prec); } void acb_poly_add(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) { slong max = FLINT_MAX(poly1->length, poly2->length); acb_poly_fit_length(res, max); _acb_poly_add(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); _acb_poly_set_length(res, max); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/add_series.c000066400000000000000000000015731417376376500164310ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_add_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong len, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; len1 = FLINT_MIN(len1, len); len2 = FLINT_MIN(len2, len); len = FLINT_MAX(len1, len2); acb_poly_fit_length(res, len); _acb_poly_add(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/add_si.c000066400000000000000000000016671417376376500155560ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_add_si(acb_poly_t res, const acb_poly_t x, slong y, slong prec) { slong len = x->length; if (len == 0) { acb_poly_set_si(res, y); } else { acb_poly_fit_length(res, len); if (y >= 0) acb_add_ui(res->coeffs, x->coeffs, y, prec); else acb_sub_ui(res->coeffs, x->coeffs, -y, prec); if (res != x) _acb_vec_set(res->coeffs + 1, x->coeffs + 1, len - 1); _acb_poly_set_length(res, len); _acb_poly_normalise(res); } } arb-2.22.1/acb_poly/agm1_series.c000066400000000000000000000025341417376376500165240ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_agm1_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) { acb_ptr t, u; zlen = FLINT_MIN(zlen, len); t = _acb_vec_init(len); u = _acb_vec_init(len); acb_agm1_cpx(t, z, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, z + 1, zlen - 1); _acb_poly_compose_series(res, t, len, u, zlen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void acb_poly_agm1_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec) { if (n == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, n); if (z->length == 0) { acb_t t; acb_init(t); _acb_poly_agm1_series(res->coeffs, t, 1, n, prec); acb_clear(t); } else { _acb_poly_agm1_series(res->coeffs, z->coeffs, z->length, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/atan_series.c000066400000000000000000000030521417376376500166160ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_atan_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { acb_t c; acb_init(c); acb_atan(c, h, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _acb_vec_zero(g + 1, n - 1); } else { acb_ptr t, u; slong ulen; t = _acb_vec_init(n); u = _acb_vec_init(n); /* atan(h(x)) = integral(h'(x)/(1+h(x)^2)) */ ulen = FLINT_MIN(n, 2 * hlen - 1); _acb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); acb_add_ui(u, u, 1, prec); _acb_poly_derivative(t, h, hlen, prec); _acb_poly_div_series(g, t, hlen - 1, u, ulen, n, prec); _acb_poly_integral(g, g, n, prec); _acb_vec_clear(t, n); _acb_vec_clear(u, n); } acb_swap(g, c); acb_clear(c); } void acb_poly_atan_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { acb_poly_zero(g); return; } acb_poly_fit_length(g, n); _acb_poly_atan_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/binomial_transform.c000066400000000000000000000024161417376376500202110ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_binomial_transform(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec) { if (alen < 10 || len < 10) _acb_poly_binomial_transform_basecase(b, a, alen, len, prec); else _acb_poly_binomial_transform_convolution(b, a, alen, len, prec); } void acb_poly_binomial_transform(acb_poly_t b, const acb_poly_t a, slong len, slong prec) { if (len == 0 || a->length == 0) { acb_poly_zero(b); return; } if (b == a) { acb_poly_t c; acb_poly_init2(c, len); _acb_poly_binomial_transform(c->coeffs, a->coeffs, a->length, len, prec); acb_poly_swap(b, c); acb_poly_clear(c); } else { acb_poly_fit_length(b, len); _acb_poly_binomial_transform(b->coeffs, a->coeffs, a->length, len, prec); } _acb_poly_set_length(b, len); _acb_poly_normalise(b); } arb-2.22.1/acb_poly/binomial_transform_basecase.c000066400000000000000000000031351417376376500220360ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_binomial_transform_basecase(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec) { slong n, k; fmpz_t t; fmpz_init(t); for (n = 0; n < len; n++) { acb_zero(b + n); for (k = 0; k < FLINT_MIN(n + 1, alen); k++) { if (k == 0) { fmpz_one(t); } else { fmpz_mul_si(t, t, -(n - k + 1)); fmpz_divexact_ui(t, t, k); } acb_addmul_fmpz(b + n, a + k, t, prec); } } fmpz_clear(t); } void acb_poly_binomial_transform_basecase(acb_poly_t b, const acb_poly_t a, slong len, slong prec) { if (len == 0 || a->length == 0) { acb_poly_zero(b); return; } if (b == a) { acb_poly_t c; acb_poly_init2(c, len); _acb_poly_binomial_transform_basecase(c->coeffs, a->coeffs, a->length, len, prec); acb_poly_swap(b, c); acb_poly_clear(c); } else { acb_poly_fit_length(b, len); _acb_poly_binomial_transform_basecase(b->coeffs, a->coeffs, a->length, len, prec); } _acb_poly_set_length(b, len); _acb_poly_normalise(b); } arb-2.22.1/acb_poly/binomial_transform_convolution.c000066400000000000000000000032121417376376500226430ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_poly.h" void _acb_poly_binomial_transform_convolution(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec) { slong i; acb_ptr c, d; alen = FLINT_MIN(alen, len); c = _acb_vec_init(alen); d = _acb_vec_init(len); _acb_poly_borel_transform(c, a, alen, prec); for (i = 1; i < alen; i += 2) acb_neg(c + i, c + i); acb_one(d); for (i = 1; i < len; i++) acb_div_ui(d + i, d + i - 1, i, prec); _acb_poly_mullow(b, d, len, c, alen, len, prec); _acb_poly_inv_borel_transform(b, b, len, prec); _acb_vec_clear(c, alen); _acb_vec_clear(d, len); } void acb_poly_binomial_transform_convolution(acb_poly_t b, const acb_poly_t a, slong len, slong prec) { if (len == 0 || a->length == 0) { acb_poly_zero(b); return; } if (b == a) { acb_poly_t c; acb_poly_init2(c, len); _acb_poly_binomial_transform_convolution(c->coeffs, a->coeffs, a->length, len, prec); acb_poly_swap(b, c); acb_poly_clear(c); } else { acb_poly_fit_length(b, len); _acb_poly_binomial_transform_convolution(b->coeffs, a->coeffs, a->length, len, prec); } _acb_poly_set_length(b, len); _acb_poly_normalise(b); } arb-2.22.1/acb_poly/borel_transform.c000066400000000000000000000017561417376376500175300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_borel_transform(acb_ptr res, acb_srcptr poly, slong len, slong prec) { slong i; arb_t t; arb_init(t); arb_one(t); for (i = 0; i < len; i++) { if (i > 1) arb_mul_ui(t, t, i, prec); acb_div_arb(res + i, poly + i, t, prec); } arb_clear(t); } void acb_poly_borel_transform(acb_poly_t res, const acb_poly_t poly, slong prec) { acb_poly_fit_length(res, poly->length); _acb_poly_borel_transform(res->coeffs, poly->coeffs, poly->length, prec); _acb_poly_set_length(res, poly->length); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/clear.c000066400000000000000000000010641417376376500154100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_clear(acb_poly_t poly) { slong i; for (i = 0; i < poly->alloc; i++) acb_clear(poly->coeffs + i); flint_free(poly->coeffs); } arb-2.22.1/acb_poly/compose.c000066400000000000000000000064221417376376500157720ustar00rootroot00000000000000/* Copyright (C) 2010 William Hart Copyright (C) 2012 Sebastian Pancratz Copyright (C) 2012, 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" /* compose by poly2 = a*x^n + c, no aliasing; n >= 1 */ void _acb_poly_compose_axnc(acb_ptr res, acb_srcptr poly1, slong len1, const acb_t c, const acb_t a, slong n, slong prec) { slong i; _acb_vec_set_round(res, poly1, len1, prec); /* shift by c (c = 0 case will be fast) */ _acb_poly_taylor_shift(res, c, len1, prec); /* multiply by powers of a */ if (!acb_is_one(a)) { if (acb_equal_si(a, -1)) { for (i = 1; i < len1; i += 2) acb_neg(res + i, res + i); } else if (len1 == 2) { acb_mul(res + 1, res + 1, a, prec); } else { acb_t t; acb_init(t); acb_set(t, a); for (i = 1; i < len1; i++) { acb_mul(res + i, res + i, t, prec); if (i + 1 < len1) acb_mul(t, t, a, prec); } acb_clear(t); } } /* stretch */ for (i = len1 - 1; i >= 1 && n > 1; i--) { acb_swap(res + i * n, res + i); _acb_vec_zero(res + (i - 1) * n + 1, n - 1); } } void _acb_poly_compose(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) { if (len1 == 1) { acb_set_round(res, poly1, prec); } else if (len2 == 1) { _acb_poly_evaluate(res, poly1, len1, poly2, prec); } else if (_acb_vec_is_zero(poly2 + 1, len2 - 2)) { _acb_poly_compose_axnc(res, poly1, len1, poly2, poly2 + len2 - 1, len2 - 1, prec); } else if (len1 <= 7) { _acb_poly_compose_horner(res, poly1, len1, poly2, len2, prec); } else { _acb_poly_compose_divconquer(res, poly1, len1, poly2, len2, prec); } } void acb_poly_compose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) { const slong len1 = poly1->length; const slong len2 = poly2->length; if (len1 == 0) { acb_poly_zero(res); } else if (len1 == 1 || len2 == 0) { acb_poly_set_acb(res, poly1->coeffs); } else { const slong lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { acb_poly_fit_length(res, lenr); _acb_poly_compose(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); } else { acb_poly_t t; acb_poly_init2(t, lenr); _acb_poly_compose(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); acb_poly_swap(res, t); acb_poly_clear(t); } _acb_poly_set_length(res, lenr); _acb_poly_normalise(res); } } arb-2.22.1/acb_poly/compose_divconquer.c000066400000000000000000000116001417376376500202230ustar00rootroot00000000000000/* Copyright (C) 2010 William Hart Copyright (C) 2012 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_compose_divconquer(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) { slong i, j, k, n; slong *hlen, alloc, powlen; acb_ptr v, pow, temp; acb_ptr * h; if (len1 == 1) { acb_set(res, poly1); return; } if (len2 == 1) { _acb_poly_evaluate(res, poly1, len1, poly2, prec); return; } if (len1 == 2) { _acb_poly_compose_horner(res, poly1, len1, poly2, len2, prec); return; } /* Initialisation */ hlen = (slong *) flint_malloc(((len1 + 1) / 2) * sizeof(slong)); for (k = 1; (2 << k) < len1; k++) ; hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1; for (i = k - 1; i > 0; i--) { slong hi = (len1 + (1 << i) - 1) / (1 << i); for (n = (hi + 1) / 2; n < hi; n++) hlen[n] = ((1 << i) - 1) * (len2 - 1) + 1; } powlen = (1 << k) * (len2 - 1) + 1; alloc = 0; for (i = 0; i < (len1 + 1) / 2; i++) alloc += hlen[i]; v = _acb_vec_init(alloc + 2 * powlen); h = (acb_ptr *) flint_malloc(((len1 + 1) / 2) * sizeof(acb_ptr)); h[0] = v; for (i = 0; i < (len1 - 1) / 2; i++) { h[i + 1] = h[i] + hlen[i]; hlen[i] = 0; } hlen[(len1 - 1) / 2] = 0; pow = v + alloc; temp = pow + powlen; /* Let's start the actual work */ for (i = 0, j = 0; i < len1 / 2; i++, j += 2) { if (!acb_is_zero(poly1 + j + 1)) { _acb_vec_scalar_mul(h[i], poly2, len2, poly1 + j + 1, prec); acb_add(h[i], h[i], poly1 + j, prec); hlen[i] = len2; } else if (!acb_is_zero(poly1 + j)) { acb_set(h[i], poly1 + j); hlen[i] = 1; } } if ((len1 & WORD(1))) { if (!acb_is_zero(poly1 + j)) { acb_set(h[i], poly1 + j); hlen[i] = 1; } } _acb_poly_mul(pow, poly2, len2, poly2, len2, prec); powlen = 2 * len2 - 1; for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) { if (hlen[1] > 0) { slong templen = powlen + hlen[1] - 1; _acb_poly_mul(temp, pow, powlen, h[1], hlen[1], prec); _acb_poly_add(h[0], temp, templen, h[0], hlen[0], prec); hlen[0] = FLINT_MAX(hlen[0], templen); } for (i = 1; i < n / 2; i++) { if (hlen[2*i + 1] > 0) { _acb_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1], prec); hlen[i] = hlen[2*i + 1] + powlen - 1; } else hlen[i] = 0; _acb_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i], prec); hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]); } if ((n & WORD(1))) { _acb_vec_set(h[i], h[2*i], hlen[2*i]); hlen[i] = hlen[2*i]; } _acb_poly_mul(temp, pow, powlen, pow, powlen, prec); powlen += powlen - 1; { acb_ptr t = pow; pow = temp; temp = t; } } _acb_poly_mul(res, pow, powlen, h[1], hlen[1], prec); _acb_vec_add(res, res, h[0], hlen[0], prec); _acb_vec_clear(v, alloc + 2 * powlen); flint_free(h); flint_free(hlen); } void acb_poly_compose_divconquer(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) { const slong len1 = poly1->length; const slong len2 = poly2->length; if (len1 == 0) { acb_poly_zero(res); } else if (len1 == 1 || len2 == 0) { acb_poly_set_acb(res, poly1->coeffs); } else { const slong lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { acb_poly_fit_length(res, lenr); _acb_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); } else { acb_poly_t t; acb_poly_init2(t, lenr); _acb_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); acb_poly_swap(res, t); acb_poly_clear(t); } _acb_poly_set_length(res, lenr); _acb_poly_normalise(res); } } arb-2.22.1/acb_poly/compose_horner.c000066400000000000000000000055401417376376500173470ustar00rootroot00000000000000/* Copyright (C) 2010 William Hart Copyright (C) 2012 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_compose_horner(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) { if (len1 == 1) { acb_set(res, poly1); } else if (len2 == 1) { _acb_poly_evaluate(res, poly1, len1, poly2, prec); } else if (len1 == 2) { _acb_vec_scalar_mul(res, poly2, len2, poly1 + 1, prec); acb_add(res, res, poly1, prec); } else { const slong alloc = (len1 - 1) * (len2 - 1) + 1; slong i = len1 - 1, lenr = len2; acb_ptr t, t1, t2; t = _acb_vec_init(alloc); if (len1 % 2 == 0) { t1 = res; t2 = t; } else { t1 = t; t2 = res; } /* Perform the first two steps as one, "res = a(m) * poly2 + a(m-1)". */ { _acb_vec_scalar_mul(t1, poly2, len2, poly1 + i, prec); i--; acb_add(t1 + 0, t1 + 0, poly1 + i, prec); } while (i--) { _acb_poly_mul(t2, t1, lenr, poly2, len2, prec); lenr += len2 - 1; { void *t_ = t1; t1 = t2; t2 = t_; } acb_add(t1 + 0, t1 + 0, poly1 + i, prec); } _acb_vec_clear(t, alloc); } } void acb_poly_compose_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) { const slong len1 = poly1->length; const slong len2 = poly2->length; if (len1 == 0) { acb_poly_zero(res); } else if (len1 == 1 || len2 == 0) { acb_poly_set_acb(res, poly1->coeffs); } else { const slong lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { acb_poly_fit_length(res, lenr); _acb_poly_compose_horner(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); } else { acb_poly_t t; acb_poly_init2(t, lenr); _acb_poly_compose_horner(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); acb_poly_swap(res, t); acb_poly_clear(t); } _acb_poly_set_length(res, lenr); _acb_poly_normalise(res); } } arb-2.22.1/acb_poly/compose_series.c000066400000000000000000000056161417376376500173500ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_compose_series(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) { if (len2 == 1) { acb_set_round(res, poly1, prec); _acb_vec_zero(res + 1, n - 1); } else if (_acb_vec_is_zero(poly2 + 1, len2 - 2)) /* poly2 is a monomial */ { slong i, j; acb_t t; acb_init(t); acb_set(t, poly2 + len2 - 1); acb_set_round(res, poly1, prec); for (i = 1, j = len2 - 1; i < len1 && j < n; i++, j += len2 - 1) { acb_mul(res + j, poly1 + i, t, prec); if (i + 1 < len1 && j + len2 - 1 < n) acb_mul(t, t, poly2 + len2 - 1, prec); } if (len2 != 2) for (i = 1; i < n; i++) if (i % (len2 - 1) != 0) acb_zero(res + i); acb_clear(t); } else if (len1 < 6 || n < 6) { _acb_poly_compose_series_horner(res, poly1, len1, poly2, len2, n, prec); } else { _acb_poly_compose_series_brent_kung(res, poly1, len1, poly2, len2, n, prec); } } void acb_poly_compose_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) { slong len1 = poly1->length; slong len2 = poly2->length; slong lenr; if (len2 != 0 && !acb_is_zero(poly2->coeffs)) { flint_printf("exception: compose_series: inner " "polynomial must have zero constant term\n"); flint_abort(); } if (len1 == 0 || n == 0) { acb_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { acb_poly_set_acb(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { acb_poly_fit_length(res, lenr); _acb_poly_compose_series(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _acb_poly_set_length(res, lenr); _acb_poly_normalise(res); } else { acb_poly_t t; acb_poly_init2(t, lenr); _acb_poly_compose_series(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _acb_poly_set_length(t, lenr); _acb_poly_normalise(t); acb_poly_swap(res, t); acb_poly_clear(t); } } arb-2.22.1/acb_poly/compose_series_brent_kung.c000066400000000000000000000062251417376376500215630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_mat.h" void _acb_poly_compose_series_brent_kung(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) { acb_mat_t A, B, C; acb_ptr t, h; slong i, m; if (n == 1) { acb_set(res, poly1); return; } m = n_sqrt(n) + 1; acb_mat_init(A, m, n); acb_mat_init(B, m, m); acb_mat_init(C, m, n); h = _acb_vec_init(n); t = _acb_vec_init(n); /* Set rows of B to the segments of poly1 */ for (i = 0; i < len1 / m; i++) _acb_vec_set(B->rows[i], poly1 + i*m, m); _acb_vec_set(B->rows[i], poly1 + i*m, len1 % m); /* Set rows of A to powers of poly2 */ acb_set_ui(A->rows[0] + 0, UWORD(1)); _acb_vec_set(A->rows[1], poly2, len2); for (i = 2; i < m; i++) _acb_poly_mullow(A->rows[i], A->rows[(i + 1) / 2], n, A->rows[i / 2], n, n, prec); acb_mat_mul(C, B, A, prec); /* Evaluate block composition using the Horner scheme */ _acb_vec_set(res, C->rows[m - 1], n); _acb_poly_mullow(h, A->rows[m - 1], n, poly2, len2, n, prec); for (i = m - 2; i >= 0; i--) { _acb_poly_mullow(t, res, n, h, n, n, prec); _acb_poly_add(res, t, n, C->rows[i], n, prec); } _acb_vec_clear(h, n); _acb_vec_clear(t, n); acb_mat_clear(A); acb_mat_clear(B); acb_mat_clear(C); } void acb_poly_compose_series_brent_kung(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) { slong len1 = poly1->length; slong len2 = poly2->length; slong lenr; if (len2 != 0 && !acb_is_zero(poly2->coeffs)) { flint_printf("exception: compose_series: inner " "polynomial must have zero constant term\n"); flint_abort(); } if (len1 == 0 || n == 0) { acb_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { acb_poly_set_acb(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { acb_poly_fit_length(res, lenr); _acb_poly_compose_series_brent_kung(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _acb_poly_set_length(res, lenr); _acb_poly_normalise(res); } else { acb_poly_t t; acb_poly_init2(t, lenr); _acb_poly_compose_series_brent_kung(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _acb_poly_set_length(t, lenr); _acb_poly_normalise(t); acb_poly_swap(res, t); acb_poly_clear(t); } } arb-2.22.1/acb_poly/compose_series_horner.c000066400000000000000000000054011417376376500207150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_compose_series_horner(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) { if (n == 1) { acb_set(res, poly1); } else { slong i = len1 - 1; slong lenr; acb_ptr t = _acb_vec_init(n); lenr = len2; _acb_vec_scalar_mul(res, poly2, len2, poly1 + i, prec); i--; acb_add(res, res, poly1 + i, prec); while (i > 0) { i--; if (lenr + len2 - 1 < n) { _acb_poly_mul(t, res, lenr, poly2, len2, prec); lenr = lenr + len2 - 1; } else { _acb_poly_mullow(t, res, lenr, poly2, len2, n, prec); lenr = n; } _acb_poly_add(res, t, lenr, poly1 + i, 1, prec); } _acb_vec_zero(res + lenr, n - lenr); _acb_vec_clear(t, n); } } void acb_poly_compose_series_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) { slong len1 = poly1->length; slong len2 = poly2->length; slong lenr; if (len2 != 0 && !acb_is_zero(poly2->coeffs)) { flint_printf("exception: compose_series: inner " "polynomial must have zero constant term\n"); flint_abort(); } if (len1 == 0 || n == 0) { acb_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { acb_poly_set_acb(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { acb_poly_fit_length(res, lenr); _acb_poly_compose_series_horner(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _acb_poly_set_length(res, lenr); _acb_poly_normalise(res); } else { acb_poly_t t; acb_poly_init2(t, lenr); _acb_poly_compose_series_horner(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _acb_poly_set_length(t, lenr); _acb_poly_normalise(t); acb_poly_swap(res, t); acb_poly_clear(t); } } arb-2.22.1/acb_poly/contains.c000066400000000000000000000014751417376376500161460ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int acb_poly_contains(const acb_poly_t poly1, const acb_poly_t poly2) { slong i; if (poly2->length > poly1->length) return 0; for (i = 0; i < poly2->length; i++) { if (!acb_contains(poly1->coeffs + i, poly2->coeffs + i)) return 0; } for (i = poly2->length; i < poly1->length; i++) if (!acb_contains_zero(poly1->coeffs + i)) return 0; return 1; } arb-2.22.1/acb_poly/contains_fmpq_poly.c000066400000000000000000000017201417376376500202250ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int acb_poly_contains_fmpq_poly(const acb_poly_t poly1, const fmpq_poly_t poly2) { slong i; fmpq_t t; if (poly2->length > poly1->length) return 0; fmpq_init(t); for (i = 0; i < poly2->length; i++) { fmpq_poly_get_coeff_fmpq(t, poly2, i); if (!acb_contains_fmpq(poly1->coeffs + i, t)) { fmpq_clear(t); return 0; } } fmpq_clear(t); for (i = poly2->length; i < poly1->length; i++) if (!acb_contains_zero(poly1->coeffs + i)) return 0; return 1; } arb-2.22.1/acb_poly/contains_fmpz_poly.c000066400000000000000000000015021417376376500202340ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int acb_poly_contains_fmpz_poly(const acb_poly_t poly1, const fmpz_poly_t poly2) { slong i; if (poly2->length > poly1->length) return 0; for (i = 0; i < poly2->length; i++) if (!acb_contains_fmpz(poly1->coeffs + i, poly2->coeffs + i)) return 0; for (i = poly2->length; i < poly1->length; i++) if (!acb_contains_zero(poly1->coeffs + i)) return 0; return 1; } arb-2.22.1/acb_poly/cos_pi_series.c000066400000000000000000000027641417376376500171600ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_cos_pi_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_cos_pi(g, h, prec); _acb_vec_zero(g + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_sin_cos_pi(t, g, h, prec); acb_neg(t, t); acb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ acb_const_pi(t, prec); acb_mul(g + 1, g + 1, t, prec); acb_clear(t); } else { acb_ptr t = _acb_vec_init(n); _acb_poly_sin_cos_pi_series(t, g, h, hlen, n, prec); _acb_vec_clear(t, n); } } void acb_poly_cos_pi_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_one(g); return; } if (hlen == 1) n = 1; acb_poly_fit_length(g, n); _acb_poly_cos_pi_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/cos_series.c000066400000000000000000000026331417376376500164630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_cos_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_cos(g, h, prec); _acb_vec_zero(g + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_sin_cos(t, g, h, prec); acb_neg(t, t); acb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ acb_clear(t); } else { acb_ptr t = _acb_vec_init(n); _acb_poly_sin_cos_series(t, g, h, hlen, n, prec); _acb_vec_clear(t, n); } } void acb_poly_cos_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_one(g); return; } if (hlen == 1) n = 1; acb_poly_fit_length(g, n); _acb_poly_cos_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/cosh_series.c000066400000000000000000000026141417376376500166320ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_cosh_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_cosh(g, h, prec); _acb_vec_zero(g + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_sinh_cosh(t, g, h, prec); acb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ acb_clear(t); } else { acb_ptr t = _acb_vec_init(n); _acb_poly_sinh_cosh_series(t, g, h, hlen, n, prec); _acb_vec_clear(t, n); } } void acb_poly_cosh_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_one(g); return; } if (hlen == 1) n = 1; acb_poly_fit_length(g, n); _acb_poly_cosh_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/cot_pi_series.c000066400000000000000000000051711417376376500171540ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_cot_pi_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_cot_pi(g, h, prec); _acb_vec_zero(g + 1, len - 1); } else { acb_ptr t, u; t = _acb_vec_init(len); u = _acb_vec_init(len); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(h)), 0) < 0) { _acb_poly_sin_cos_pi_series(t, u, h, hlen, len, prec); _acb_poly_div_series(g, u, len, t, len, len, prec); } else { _acb_vec_scalar_mul_2exp_si(t, h, hlen, 1); if (arf_sgn(arb_midref(acb_imagref(h))) > 0) { acb_const_pi(u, prec); acb_mul_onei(u, u); _acb_vec_scalar_mul(t, t, hlen, u, prec); _acb_poly_exp_series(t, t, hlen, len, prec); acb_sub_ui(u, t, 1, prec); _acb_vec_set(u + 1, t + 1, len - 1); _acb_poly_div_series(g, t, len, u, len, len, prec); _acb_vec_scalar_mul_2exp_si(g, g, len, 1); acb_sub_ui(g, g, 1, prec); _acb_vec_scalar_mul_onei(g, g, len); } else { acb_const_pi(u, prec); acb_div_onei(u, u); _acb_vec_scalar_mul(t, t, hlen, u, prec); _acb_poly_exp_series(t, t, hlen, len, prec); acb_sub_ui(u, t, 1, prec); _acb_vec_set(u + 1, t + 1, len - 1); _acb_poly_div_series(g, t, len, u, len, len, prec); _acb_vec_scalar_mul_2exp_si(g, g, len, 1); acb_sub_ui(g, g, 1, prec); _acb_vec_scalar_mul_onei(g, g, len); _acb_vec_neg(g, g, len); } } _acb_vec_clear(t, len); _acb_vec_clear(u, len); } } void acb_poly_cot_pi_series(acb_poly_t res, const acb_poly_t f, slong len, slong prec) { acb_poly_fit_length(res, len); if (f->length == 0 || len == 0) _acb_vec_indeterminate(res->coeffs, len); else _acb_poly_cot_pi_series(res->coeffs, f->coeffs, f->length, len, prec); _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/derivative.c000066400000000000000000000016371417376376500164720ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_derivative(acb_ptr res, acb_srcptr poly, slong len, slong prec) { slong i; for (i = 1; i < len; i++) acb_mul_ui(res + i - 1, poly + i, i, prec); } void acb_poly_derivative(acb_poly_t res, const acb_poly_t poly, slong prec) { slong len = poly->length; if (len < 2) { acb_poly_zero(res); } else { acb_poly_fit_length(res, len - 1); _acb_poly_derivative(res->coeffs, poly->coeffs, len, prec); _acb_poly_set_length(res, len - 1); } } arb-2.22.1/acb_poly/digamma_series.c000066400000000000000000000100651417376376500172740ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t x, int use_reflect, int digamma, slong prec); void _acb_poly_gamma_stirling_eval(acb_ptr res, const acb_t z, slong n, slong num, slong prec); void _acb_poly_gamma_stirling_eval2(acb_ptr res, const acb_t z, slong n, slong num, int diff, slong prec); void _acb_poly_digamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong i, r, n, rflen, wp; acb_t zr; acb_ptr t, u, v; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_digamma(res, h, prec); if (acb_is_finite(res)) _acb_vec_zero(res + 1, len - 1); else _acb_vec_indeterminate(res + 1, len - 1); return; } /* use real code for real input */ if (_acb_vec_is_real(h, hlen)) { arb_ptr tmp = _arb_vec_init(len); for (i = 0; i < hlen; i++) arb_set(tmp + i, acb_realref(h + i)); _arb_poly_digamma_series(tmp, tmp, hlen, len, prec); for (i = 0; i < len; i++) acb_set_arb(res + i, tmp + i); _arb_vec_clear(tmp, len); return; } wp = prec + FLINT_BIT_COUNT(prec); t = _acb_vec_init(len + 1); u = _acb_vec_init(len + 1); v = _acb_vec_init(len + 1); acb_init(zr); /* use Stirling series */ acb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 1, wp); /* psi(x) = psi((1-x)+r) - h(1-x,r) - pi*cot(pi*x) */ if (reflect) { if (r != 0) /* otherwise t = 0 */ { acb_sub_ui(v, h, 1, wp); acb_neg(v, v); acb_one(v + 1); rflen = FLINT_MIN(len + 1, r + 1); _acb_poly_rising_ui_series(u, v, 2, r, rflen, wp); _acb_poly_derivative(v, u, rflen, wp); _acb_poly_div_series(t, v, rflen - 1, u, rflen, len, wp); for (i = 1; i < len; i += 2) acb_neg(t + i, t + i); } acb_sub_ui(zr, h, r + 1, wp); acb_neg(zr, zr); _acb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); for (i = 1; i < len; i += 2) acb_neg(u + i, u + i); _acb_vec_sub(u, u, t, len, wp); acb_set(t, h); acb_one(t + 1); _acb_poly_cot_pi_series(t, t, 2, len, wp); acb_const_pi(v, wp); _acb_vec_scalar_mul(t, t, len, v, wp); _acb_vec_sub(u, u, t, len, wp); } else { if (r == 0) { acb_add_ui(zr, h, r, wp); _acb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); } else { acb_set(v, h); acb_one(v + 1); rflen = FLINT_MIN(len + 1, r + 1); _acb_poly_rising_ui_series(u, v, 2, r, rflen, wp); _acb_poly_derivative(v, u, rflen, wp); _acb_poly_div_series(t, v, rflen - 1, u, rflen, len, wp); acb_add_ui(zr, h, r, wp); _acb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); _acb_vec_sub(u, u, t, len, wp); } } /* compose with nonconstant part */ acb_zero(t); _acb_vec_set(t + 1, h + 1, hlen - 1); _acb_poly_compose_series(res, u, len, t, hlen, len, prec); acb_clear(zr); _acb_vec_clear(t, len + 1); _acb_vec_clear(u, len + 1); _acb_vec_clear(v, len + 1); } void acb_poly_digamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) { acb_poly_fit_length(res, n); if (f->length == 0 || n == 0) _acb_vec_indeterminate(res->coeffs, n); else _acb_poly_digamma_series(res->coeffs, f->coeffs, f->length, n, prec); _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/div_root.c000066400000000000000000000021311417376376500161430ustar00rootroot00000000000000/* Copyright (C) 2011 William Hart Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_div_root(acb_ptr Q, acb_t R, acb_srcptr A, slong len, const acb_t c, slong prec) { acb_t r, t; slong i; if (len < 2) { acb_zero(R); return; } acb_init(r); acb_init(t); acb_set(t, A + len - 2); acb_set(Q + len - 2, A + len - 1); acb_set(r, Q + len - 2); /* TODO: avoid the extra assignments (but still support aliasing) */ for (i = len - 2; i > 0; i--) { acb_mul(r, r, c, prec); acb_add(r, r, t, prec); acb_set(t, A + i - 1); acb_set(Q + i - 1, r); } acb_mul(r, r, c, prec); acb_add(R, r, t, prec); acb_clear(r); acb_clear(t); } arb-2.22.1/acb_poly/div_series.c000066400000000000000000000053361417376376500164640ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_div_series(acb_ptr Q, acb_srcptr A, slong Alen, acb_srcptr B, slong Blen, slong n, slong prec) { Alen = FLINT_MIN(Alen, n); Blen = FLINT_MIN(Blen, n); if (Blen == 1) { _acb_vec_scalar_div(Q, A, Alen, B, prec); _acb_vec_zero(Q + Alen, n - Alen); } else if (n == 2) { if (Alen == 1) { acb_div(Q, A, B, prec); acb_div(Q + 1, Q, B, prec); acb_mul(Q + 1, Q + 1, B + 1, prec); acb_neg(Q + 1, Q + 1); } else { acb_div(Q, A, B, prec); acb_mul(Q + 1, Q, B + 1, prec); acb_sub(Q + 1, A + 1, Q + 1, prec); acb_div(Q + 1, Q + 1, B, prec); } } else if (Blen == 2 || n <= 10) { /* The basecase algorithm is faster for much larger Blen and n than this, but unfortunately has worse numerical stability. */ slong i; acb_t q; acb_init(q); acb_inv(q, B, prec); acb_div(Q, A, B, prec); for (i = 1; i < n; i++) { acb_dot(Q + i, (i < Alen) ? A + i : NULL, 1, B + 1, 1, Q + i - 1, -1, FLINT_MIN(i, Blen - 1), prec); if (!acb_is_one(q)) acb_mul(Q + i, Q + i, q, prec); } acb_clear(q); } else { acb_ptr Binv; Binv = _acb_vec_init(n); _acb_poly_inv_series(Binv, B, Blen, n, prec); _acb_poly_mullow(Q, Binv, n, A, Alen, n, prec); _acb_vec_clear(Binv, n); } } void acb_poly_div_series(acb_poly_t Q, const acb_poly_t A, const acb_poly_t B, slong n, slong prec) { if (n == 0) { acb_poly_zero(Q); return; } if (B->length == 0) { acb_poly_fit_length(Q, n); _acb_vec_indeterminate(Q->coeffs, n); _acb_poly_set_length(Q, n); return; } if (A->length == 0) { acb_poly_zero(Q); return; } if (Q == A || Q == B) { acb_poly_t t; acb_poly_init(t); acb_poly_div_series(t, A, B, n, prec); acb_poly_swap(Q, t); acb_poly_clear(t); return; } acb_poly_fit_length(Q, n); _acb_poly_div_series(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, n, prec); _acb_poly_set_length(Q, n); _acb_poly_normalise(Q); } arb-2.22.1/acb_poly/divrem.c000066400000000000000000000056601417376376500156160ustar00rootroot00000000000000/* Copyright (C) 2011 William Hart Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" /* TODO: tighten this code */ void _acb_poly_div(acb_ptr Q, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) { slong lenQ, lenB2; acb_ptr Arev, Brev; lenQ = lenA - lenB + 1; Arev = _acb_vec_init(2 * lenQ); Brev = Arev + lenQ; _acb_poly_reverse(Arev, A + (lenA - lenQ), lenQ, lenQ); if (lenB >= lenQ) { _acb_poly_reverse(Brev, B + (lenB - lenQ), lenQ, lenQ); lenB2 = lenQ; } else { _acb_poly_reverse(Brev, B, lenB, lenB); lenB2 = lenB; } _acb_poly_div_series(Q, Arev, lenQ, Brev, lenB2, lenQ, prec); _acb_poly_reverse(Q, Q, lenQ, lenQ); _acb_vec_clear(Arev, 2 * lenQ); } void _acb_poly_divrem(acb_ptr Q, acb_ptr R, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) { const slong lenQ = lenA - lenB + 1; _acb_poly_div(Q, A, lenA, B, lenB, prec); if (lenB > 1) { if (lenQ >= lenB - 1) _acb_poly_mullow(R, Q, lenQ, B, lenB - 1, lenB - 1, prec); else _acb_poly_mullow(R, B, lenB - 1, Q, lenQ, lenB - 1, prec); _acb_vec_sub(R, A, R, lenB - 1, prec); } } void _acb_poly_rem(acb_ptr R, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) { const slong lenQ = lenA - lenB + 1; acb_ptr Q = _acb_vec_init(lenQ); _acb_poly_divrem(Q, R, A, lenA, B, lenB, prec); _acb_vec_clear(Q, lenQ); } int acb_poly_divrem(acb_poly_t Q, acb_poly_t R, const acb_poly_t A, const acb_poly_t B, slong prec) { const slong lenA = A->length, lenB = B->length; if (lenB == 0 || acb_contains_zero(B->coeffs + lenB - 1)) { return 0; } if (lenA < lenB) { acb_poly_set(R, A); acb_poly_zero(Q); return 1; } if (Q == A || Q == B) { acb_poly_t T; acb_poly_init(T); acb_poly_divrem(T, R, A, B, prec); acb_poly_swap(Q, T); acb_poly_clear(T); return 1; } if (R == A || R == B) { acb_poly_t U; acb_poly_init(U); acb_poly_divrem(Q, U, A, B, prec); acb_poly_swap(R, U); acb_poly_clear(U); return 1; } acb_poly_fit_length(Q, lenA - lenB + 1); acb_poly_fit_length(R, lenB - 1); _acb_poly_divrem(Q->coeffs, R->coeffs, A->coeffs, lenA, B->coeffs, lenB, prec); _acb_poly_set_length(Q, lenA - lenB + 1); _acb_poly_set_length(R, lenB - 1); _acb_poly_normalise(R); return 1; } arb-2.22.1/acb_poly/elliptic_k_series.c000066400000000000000000000013501417376376500200110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_modular.h" #include "acb_elliptic.h" void _acb_poly_elliptic_k_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) { _acb_elliptic_k_series(res, z, zlen, len, prec); } void acb_poly_elliptic_k_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec) { acb_elliptic_k_series(res, z, n, prec); } arb-2.22.1/acb_poly/elliptic_p_series.c000066400000000000000000000014241417376376500200200ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_modular.h" #include "acb_elliptic.h" void _acb_poly_elliptic_p_series(acb_ptr res, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec) { _acb_elliptic_p_series(res, z, zlen, tau, len, prec); } void acb_poly_elliptic_p_series(acb_poly_t res, const acb_poly_t z, const acb_t tau, slong n, slong prec) { acb_elliptic_p_series(res, z, tau, n, prec); } arb-2.22.1/acb_poly/equal.c000066400000000000000000000012231417376376500154260ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int acb_poly_equal(const acb_poly_t A, const acb_poly_t B) { slong i; if (A->length != B->length) return 0; for (i = 0; i < A->length; i++) if (!acb_equal(A->coeffs + i, B->coeffs + i)) return 0; return 1; } arb-2.22.1/acb_poly/erf_series.c000066400000000000000000000012671417376376500164550ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_hypgeom.h" void _acb_poly_erf_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { _acb_hypgeom_erf_series(g, h, hlen, n, prec); } void acb_poly_erf_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { acb_hypgeom_erf_series(g, h, n, prec); } arb-2.22.1/acb_poly/evaluate.c000066400000000000000000000017321417376376500161320ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_evaluate(acb_t res, acb_srcptr f, slong len, const acb_t x, slong prec) { if ((prec >= 1024) && (len >= 5 + 20000 / prec)) { slong fbits; fbits = _acb_vec_bits(f, len); if (fbits <= prec / 2) { _acb_poly_evaluate_rectangular(res, f, len, x, prec); return; } } _acb_poly_evaluate_horner(res, f, len, x, prec); } void acb_poly_evaluate(acb_t res, const acb_poly_t f, const acb_t a, slong prec) { _acb_poly_evaluate(res, f->coeffs, f->length, a, prec); } arb-2.22.1/acb_poly/evaluate2.c000066400000000000000000000017251417376376500162160ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_evaluate2(acb_t y, acb_t z, acb_srcptr f, slong len, const acb_t x, slong prec) { if ((prec >= 1024) && (len >= 5 + 20000 / prec)) { slong fbits; fbits = _acb_vec_bits(f, len); if (fbits <= prec / 2) { _acb_poly_evaluate2_rectangular(y, z, f, len, x, prec); return; } } _acb_poly_evaluate2_horner(y, z, f, len, x, prec); } void acb_poly_evaluate2(acb_t r, acb_t s, const acb_poly_t f, const acb_t a, slong prec) { _acb_poly_evaluate2(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/acb_poly/evaluate2_horner.c000066400000000000000000000031771417376376500175760ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_evaluate2_horner(acb_t y, acb_t z, acb_srcptr poly, slong len, const acb_t x, slong prec) { if (len == 0) { acb_zero(y); acb_zero(z); } else if (len == 1) { acb_set_round(y, poly + 0, prec); acb_zero(z); } else if (acb_is_zero(x)) { acb_set_round(y, poly + 0, prec); acb_set_round(z, poly + 1, prec); } else if (len == 2) { acb_mul(y, x, poly + 1, prec); acb_add(y, y, poly + 0, prec); acb_set_round(z, poly + 1, prec); } else { acb_t t, u, v; slong i; acb_init(t); acb_init(u); acb_init(v); acb_set_round(u, poly + len - 1, prec); acb_zero(v); for (i = len - 2; i >= 0; i--) { acb_mul(t, v, x, prec); acb_add(v, u, t, prec); acb_mul(t, u, x, prec); acb_add(u, t, poly + i, prec); } acb_swap(y, u); acb_swap(z, v); acb_clear(t); acb_clear(u); acb_clear(v); } } void acb_poly_evaluate2_horner(acb_t r, acb_t s, const acb_poly_t f, const acb_t a, slong prec) { _acb_poly_evaluate2_horner(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/acb_poly/evaluate2_rectangular.c000066400000000000000000000047031417376376500206040ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_evaluate2_rectangular(acb_t y, acb_t z, acb_srcptr poly, slong len, const acb_t x, slong prec) { slong i, j, m, r; acb_ptr xs; acb_t s, t, c; if (len < 3) { if (len == 0) { acb_zero(y); acb_zero(z); } else if (len == 1) { acb_set_round(y, poly + 0, prec); acb_zero(z); } else if (len == 2) { acb_mul(y, x, poly + 1, prec); acb_add(y, y, poly + 0, prec); acb_set_round(z, poly + 1, prec); } return; } m = n_sqrt(len) + 1; m *= 1; r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); acb_init(c); _acb_vec_set_powers(xs, x, m + 1, prec); acb_dot(y, poly + (r - 1) * m, 0, xs + 1, 1, poly + (r - 1) * m + 1, 1, len - (r - 1) * m - 1, prec); for (i = r - 2; i >= 0; i--) { acb_dot(s, poly + i * m, 0, xs + 1, 1, poly + i * m + 1, 1, m - 1, prec); acb_mul(y, y, xs + m, prec); acb_add(y, y, s, prec); } /* todo: rewrite using acb_dot */ len -= 1; r = (len + m - 1) / m; acb_mul_ui(z, poly + (r - 1) * m + 1, (r - 1) * m + 1, ARF_PREC_EXACT); for (j = 1; (r - 1) * m + j < len; j++) { acb_mul_ui(c, poly + (r - 1) * m + j + 1, (r - 1) * m + j + 1, ARF_PREC_EXACT); acb_addmul(z, xs + j, c, prec); } for (i = r - 2; i >= 0; i--) { acb_mul_ui(s, poly + i * m + 1, i * m + 1, ARF_PREC_EXACT); for (j = 1; j < m; j++) { acb_mul_ui(c, poly + i * m + j + 1, i * m + j + 1, ARF_PREC_EXACT); acb_addmul(s, xs + j, c, prec); } acb_mul(z, z, xs + m, prec); acb_add(z, z, s, prec); } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); acb_clear(c); } void acb_poly_evaluate2_rectangular(acb_t r, acb_t s, const acb_poly_t f, const acb_t a, slong prec) { _acb_poly_evaluate2_rectangular(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/acb_poly/evaluate_horner.c000066400000000000000000000024471417376376500175130ustar00rootroot00000000000000/* Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_evaluate_horner(acb_t y, acb_srcptr f, slong len, const acb_t x, slong prec) { if (len == 0) { acb_zero(y); } else if (len == 1 || acb_is_zero(x)) { acb_set_round(y, f, prec); } else if (len == 2) { acb_mul(y, x, f + 1, prec); acb_add(y, y, f + 0, prec); } else { slong i = len - 1; acb_t t, u; acb_init(t); acb_init(u); acb_set(u, f + i); for (i = len - 2; i >= 0; i--) { acb_mul(t, u, x, prec); acb_add(u, f + i, t, prec); } acb_swap(y, u); acb_clear(t); acb_clear(u); } } void acb_poly_evaluate_horner(acb_t res, const acb_poly_t f, const acb_t a, slong prec) { _acb_poly_evaluate_horner(res, f->coeffs, f->length, a, prec); } arb-2.22.1/acb_poly/evaluate_rectangular.c000066400000000000000000000032021417376376500205130ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_evaluate_rectangular(acb_t y, acb_srcptr poly, slong len, const acb_t x, slong prec) { slong i, m, r; acb_ptr xs; acb_t s, t, c; if (len < 3) { if (len == 0) { acb_zero(y); } else if (len == 1) { acb_set_round(y, poly + 0, prec); } else if (len == 2) { acb_mul(y, x, poly + 1, prec); acb_add(y, y, poly + 0, prec); } return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); acb_init(c); _acb_vec_set_powers(xs, x, m + 1, prec); acb_dot(y, poly + (r - 1) * m, 0, xs + 1, 1, poly + (r - 1) * m + 1, 1, len - (r - 1) * m - 1, prec); for (i = r - 2; i >= 0; i--) { acb_dot(s, poly + i * m, 0, xs + 1, 1, poly + i * m + 1, 1, m - 1, prec); acb_mul(y, y, xs + m, prec); acb_add(y, y, s, prec); } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); acb_clear(c); } void acb_poly_evaluate_rectangular(acb_t res, const acb_poly_t f, const acb_t a, slong prec) { _acb_poly_evaluate_rectangular(res, f->coeffs, f->length, a, prec); } arb-2.22.1/acb_poly/evaluate_vec_fast.c000066400000000000000000000067131417376376500200100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" /* This gives some speedup for small lengths. */ static __inline__ void _acb_poly_rem_2(acb_ptr r, acb_srcptr a, slong al, acb_srcptr b, slong bl, slong prec) { if (al == 2) { acb_mul(r + 0, a + 1, b + 0, prec); acb_sub(r + 0, a + 0, r + 0, prec); } else { _acb_poly_rem(r, a, al, b, bl, prec); } } void _acb_poly_evaluate_vec_fast_precomp(acb_ptr vs, acb_srcptr poly, slong plen, acb_ptr * tree, slong len, slong prec) { slong height, i, j, pow, left; slong tree_height; slong tlen; acb_ptr t, u, swap, pa, pb, pc; /* avoid worrying about some degenerate cases */ if (len < 2 || plen < 2) { if (len == 1) { acb_t tmp; acb_init(tmp); acb_neg(tmp, tree[0] + 0); _acb_poly_evaluate(vs + 0, poly, plen, tmp, prec); acb_clear(tmp); } else if (len != 0 && plen == 0) { _acb_vec_zero(vs, len); } else if (len != 0 && plen == 1) { for (i = 0; i < len; i++) acb_set(vs + i, poly + 0); } return; } t = _acb_vec_init(len); u = _acb_vec_init(len); left = len; /* Initial reduction. We allow the polynomial to be larger or smaller than the number of points. */ height = FLINT_BIT_COUNT(plen - 1) - 1; tree_height = FLINT_CLOG2(len); while (height >= tree_height) height--; pow = WORD(1) << height; for (i = j = 0; i < len; i += pow, j += (pow + 1)) { tlen = ((i + pow) <= len) ? pow : len % pow; _acb_poly_rem(t + i, poly, plen, tree[height] + j, tlen + 1, prec); } for (i = height - 1; i >= 0; i--) { pow = WORD(1) << i; left = len; pa = tree[i]; pb = t; pc = u; while (left >= 2 * pow) { _acb_poly_rem_2(pc, pb, 2 * pow, pa, pow + 1, prec); _acb_poly_rem_2(pc + pow, pb, 2 * pow, pa + pow + 1, pow + 1, prec); pa += 2 * pow + 2; pb += 2 * pow; pc += 2 * pow; left -= 2 * pow; } if (left > pow) { _acb_poly_rem(pc, pb, left, pa, pow + 1, prec); _acb_poly_rem(pc + pow, pb, left, pa + pow + 1, left - pow + 1, prec); } else if (left > 0) _acb_vec_set(pc, pb, left); swap = t; t = u; u = swap; } _acb_vec_set(vs, t, len); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void _acb_poly_evaluate_vec_fast(acb_ptr ys, acb_srcptr poly, slong plen, acb_srcptr xs, slong n, slong prec) { acb_ptr * tree; tree = _acb_poly_tree_alloc(n); _acb_poly_tree_build(tree, xs, n, prec); _acb_poly_evaluate_vec_fast_precomp(ys, poly, plen, tree, n, prec); _acb_poly_tree_free(tree, n); } void acb_poly_evaluate_vec_fast(acb_ptr ys, const acb_poly_t poly, acb_srcptr xs, slong n, slong prec) { _acb_poly_evaluate_vec_fast(ys, poly->coeffs, poly->length, xs, n, prec); } arb-2.22.1/acb_poly/evaluate_vec_iter.c000066400000000000000000000015331417376376500200110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_evaluate_vec_iter(acb_ptr ys, acb_srcptr poly, slong plen, acb_srcptr xs, slong n, slong prec) { slong i; for (i = 0; i < n; i++) _acb_poly_evaluate(ys + i, poly, plen, xs + i, prec); } void acb_poly_evaluate_vec_iter(acb_ptr ys, const acb_poly_t poly, acb_srcptr xs, slong n, slong prec) { _acb_poly_evaluate_vec_iter(ys, poly->coeffs, poly->length, xs, n, prec); } arb-2.22.1/acb_poly/exp_pi_i_series.c000066400000000000000000000033701417376376500174720ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_exp_pi_i_series(acb_ptr f, acb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_exp_pi_i(f, h, prec); _acb_vec_zero(f + 1, len - 1); } else if (len == 2) { arb_t t; arb_init(t); arb_const_pi(t, prec); acb_exp_pi_i(f, h, prec); acb_mul_arb(f + 1, h + 1, t, prec); acb_mul_onei(f + 1, f + 1); acb_mul(f + 1, f + 1, f + 0, prec); arb_clear(t); } else { acb_ptr t; t = _acb_vec_init(hlen + 1); acb_const_pi(t, prec); acb_mul_onei(t, t); _acb_vec_scalar_mul(t + 1, h + 1, hlen - 1, t, prec); acb_zero(t); acb_exp_pi_i(t + hlen, h, prec); _acb_poly_exp_series(f, t, hlen, len, prec); _acb_vec_scalar_mul(f, f, len, t + hlen, prec); _acb_vec_clear(t, hlen + 1); } } void acb_poly_exp_pi_i_series(acb_poly_t f, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(f); return; } if (hlen == 0) { acb_poly_one(f); return; } if (hlen == 1) n = 1; acb_poly_fit_length(f, n); _acb_poly_exp_pi_i_series(f->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(f, n); _acb_poly_normalise(f); } arb-2.22.1/acb_poly/exp_series.c000066400000000000000000000116711417376376500164750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" /* allow changing this from the test code */ ARB_DLL slong acb_poly_newton_exp_cutoff = 0; /* with inverse=1 simultaneously computes g = exp(-x) to length n with inverse=0 uses g as scratch space, computing g = exp(-x) only to length (n+1)/2 */ static void _acb_poly_exp_series_newton(acb_ptr f, acb_ptr g, acb_srcptr h, slong len, slong prec, int inverse, slong cutoff) { slong alloc; acb_ptr T, U, hprime; alloc = 3 * len; T = _acb_vec_init(alloc); U = T + len; hprime = U + len; _acb_poly_derivative(hprime, h, len, prec); acb_zero(hprime + len - 1); NEWTON_INIT(cutoff, len) /* f := exp(h) + O(x^m), g := exp(-h) + O(x^m2) */ NEWTON_BASECASE(n) _acb_poly_exp_series_basecase(f, h, n, n, prec); _acb_poly_inv_series(g, f, (n + 1) / 2, (n + 1) / 2, prec); NEWTON_END_BASECASE /* extend from length m to length n */ NEWTON_LOOP(m, n) slong m2 = (m + 1) / 2; slong l = m - 1; /* shifted for derivative */ /* g := exp(-h) + O(x^m) */ _acb_poly_mullow(T, f, m, g, m2, m, prec); _acb_poly_mullow(g + m2, g, m2, T + m2, m - m2, m - m2, prec); _acb_vec_neg(g + m2, g + m2, m - m2); /* U := h' + g (f' - f h') + O(x^(n-1)) Note: should replace h' by h' mod x^(m-1) */ _acb_vec_zero(f + m, n - m); _acb_poly_mullow(T, f, n, hprime, n, n, prec); /* should be mulmid */ _acb_poly_derivative(U, f, n, prec); acb_zero(U + n - 1); /* should skip low terms */ _acb_vec_sub(U + l, U + l, T + l, n - l, prec); _acb_poly_mullow(T + l, g, n - m, U + l, n - m, n - m, prec); _acb_vec_add(U + l, hprime + l, T + l, n - m, prec); /* f := f + f * (h - int U) + O(x^n) = exp(h) + O(x^n) */ _acb_poly_integral(U, U, n, prec); /* should skip low terms */ _acb_vec_sub(U + m, h + m, U + m, n - m, prec); _acb_poly_mullow(f + m, f, n - m, U + m, n - m, n - m, prec); /* g := exp(-h) + O(x^n) */ /* not needed if we only want exp(x) */ if (n == len && inverse) { _acb_poly_mullow(T, f, n, g, m, n, prec); _acb_poly_mullow(g + m, g, m, T + m, n - m, n - m, prec); _acb_vec_neg(g + m, g + m, n - m); } NEWTON_END_LOOP NEWTON_END _acb_vec_clear(T, alloc); } void _acb_poly_exp_series(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_exp(f, h, prec); _acb_vec_zero(f + 1, n - 1); } else if (n == 2) { acb_exp(f, h, prec); acb_mul(f + 1, f, h + 1, prec); /* safe since hlen >= 2 */ } else if (_acb_vec_is_zero(h + 1, hlen - 2)) /* h = a + bx^d */ { slong i, j, d = hlen - 1; acb_t t; acb_init(t); acb_set(t, h + d); acb_exp(f, h, prec); for (i = 1, j = d; j < n; j += d, i++) { acb_mul(f + j, f + j - d, t, prec); acb_div_ui(f + j, f + j, i, prec); _acb_vec_zero(f + j - d + 1, hlen - 2); } _acb_vec_zero(f + j - d + 1, n - (j - d + 1)); acb_clear(t); } else { slong cutoff; if (acb_poly_newton_exp_cutoff != 0) cutoff = acb_poly_newton_exp_cutoff; else if (prec <= 256) cutoff = 750; else cutoff = 1e5 / pow(log(prec), 3); if (hlen <= cutoff) { _acb_poly_exp_series_basecase(f, h, hlen, n, prec); } else { acb_ptr g, t; acb_t u; int fix; g = _acb_vec_init((n + 1) / 2); fix = (hlen < n || h == f || !acb_is_zero(h)); if (fix) { t = _acb_vec_init(n); _acb_vec_set(t + 1, h + 1, hlen - 1); } else t = (acb_ptr) h; acb_init(u); acb_exp(u, h, prec); _acb_poly_exp_series_newton(f, g, t, n, prec, 0, cutoff); if (!acb_is_one(u)) _acb_vec_scalar_mul(f, f, n, u, prec); _acb_vec_clear(g, (n + 1) / 2); if (fix) _acb_vec_clear(t, n); acb_clear(u); } } } void acb_poly_exp_series(acb_poly_t f, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(f); return; } if (hlen == 0) { acb_poly_one(f); return; } if (hlen == 1) n = 1; acb_poly_fit_length(f, n); _acb_poly_exp_series(f->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(f, n); _acb_poly_normalise(f); } arb-2.22.1/acb_poly/exp_series_basecase.c000066400000000000000000000044351417376376500203230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" static void _acb_poly_exp_series_basecase_rec(acb_ptr f, acb_ptr a, acb_srcptr h, slong hlen, slong n, slong prec) { slong k; acb_t s; acb_init(s); acb_exp(f, h, prec); for (k = 1; k < hlen; k++) acb_mul_ui(a + k, h + k, k, prec); for (k = 1; k < n; k++) { acb_dot(s, NULL, 0, a + 1, 1, f + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); acb_div_ui(f + k, s, k, prec); } acb_clear(s); } void _acb_poly_exp_series_basecase(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(n, hlen); if (n < 20 || hlen < 0.9 * n || prec <= 2 * FLINT_BITS || n < 1000.0 / log(prec + 10) - 70) { acb_ptr t = _acb_vec_init(hlen); _acb_poly_exp_series_basecase_rec(f, t, h, hlen, n, prec); _acb_vec_clear(t, hlen); } else { slong m, v; acb_ptr t, u; m = (n + 2) / 3; v = m * 2; t = _acb_vec_init(n); u = _acb_vec_init(n - m); _acb_poly_mullow(t, h + m, hlen - m, h + m, hlen - m, n - v, prec); _acb_vec_scalar_mul_2exp_si(t, t, n - v, -1); _acb_vec_set(u, h + m, v - m); _acb_poly_add(u + v - m, t, n - v, h + v, hlen - v, prec); _acb_poly_exp_series_basecase_rec(f, t, h, m, n, prec); _acb_poly_mullow(t, f, n, u, n - m, n - m, prec); _acb_poly_add(f + m, f + m, n - m, t, n - m, prec); _acb_vec_clear(t, n); _acb_vec_clear(u, n - m); } } void acb_poly_exp_series_basecase(acb_poly_t f, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(f); return; } if (hlen == 0) { acb_poly_one(f); return; } acb_poly_fit_length(f, n); _acb_poly_exp_series_basecase(f->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(f, n); _acb_poly_normalise(f); } arb-2.22.1/acb_poly/find_roots.c000066400000000000000000000077211417376376500164760ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" slong _acb_get_mid_mag(const acb_t z) { slong rm, im; rm = arf_abs_bound_lt_2exp_si(arb_midref(acb_realref(z))); im = arf_abs_bound_lt_2exp_si(arb_midref(acb_imagref(z))); return FLINT_MAX(rm, im); } slong _acb_get_rad_mag(const acb_t z) { slong rm, im; /* TODO: write mag function */ arf_t t; arf_init(t); arf_set_mag(t, arb_radref(acb_realref(z))); rm = arf_abs_bound_lt_2exp_si(t); arf_set_mag(t, arb_radref(acb_imagref(z))); im = arf_abs_bound_lt_2exp_si(t); arf_clear(t); return FLINT_MAX(rm, im); } void _acb_poly_roots_initial_values(acb_ptr roots, slong deg, slong prec) { slong i; fmpq_t q; fmpq_init(q); fmpq_set_si(q, 4, 10); arb_set_fmpq(acb_realref(roots + 0), q, prec); mag_zero(arb_radref(acb_realref(roots + 0))); fmpq_set_si(q, 9, 10); arb_set_fmpq(acb_imagref(roots + 0), q, prec); mag_zero(arb_radref(acb_imagref(roots + 0))); fmpq_clear(q); for (i = 1; i < deg; i++) { acb_mul(roots + i, roots + i - 1, roots + 0, prec); mag_zero(arb_radref(acb_realref(roots + i))); mag_zero(arb_radref(acb_imagref(roots + i))); } } slong _acb_poly_find_roots(acb_ptr roots, acb_srcptr poly, acb_srcptr initial, slong len, slong maxiter, slong prec) { slong iter, i, deg; slong rootmag, max_rootmag, correction, max_correction; deg = len - 1; if (deg == 0) { return 0; } else if (acb_contains_zero(poly + len - 1)) { /* if the leading coefficient contains zero, roots can be anywhere */ for (i = 0; i < deg; i++) { arb_zero_pm_inf(acb_realref(roots + i)); arb_zero_pm_inf(acb_imagref(roots + i)); } return 0; } else if (deg == 1) { acb_inv(roots + 0, poly + 1, prec); acb_mul(roots + 0, roots + 0, poly + 0, prec); acb_neg(roots + 0, roots + 0); return 1; } if (initial == NULL) _acb_poly_roots_initial_values(roots, deg, prec); else _acb_vec_set(roots, initial, deg); if (maxiter == 0) maxiter = 2 * deg + n_sqrt(prec); for (iter = 0; iter < maxiter; iter++) { max_rootmag = -ARF_PREC_EXACT; for (i = 0; i < deg; i++) { rootmag = _acb_get_mid_mag(roots + i); max_rootmag = FLINT_MAX(rootmag, max_rootmag); } _acb_poly_refine_roots_durand_kerner(roots, poly, len, prec); max_correction = -ARF_PREC_EXACT; for (i = 0; i < deg; i++) { correction = _acb_get_rad_mag(roots + i); max_correction = FLINT_MAX(correction, max_correction); } /* estimate the correction relative to the whole set of roots */ max_correction -= max_rootmag; /* flint_printf("ITER %wd MAX CORRECTION: %wd\n", iter, max_correction); */ if (max_correction < -prec / 2) maxiter = FLINT_MIN(maxiter, iter + 2); else if (max_correction < -prec / 3) maxiter = FLINT_MIN(maxiter, iter + 3); else if (max_correction < -prec / 4) maxiter = FLINT_MIN(maxiter, iter + 4); } return _acb_poly_validate_roots(roots, poly, len, prec); } slong acb_poly_find_roots(acb_ptr roots, const acb_poly_t poly, acb_srcptr initial, slong maxiter, slong prec) { slong len = poly->length; if (len == 0) { flint_printf("find_roots: expected a nonzero polynomial"); flint_abort(); } return _acb_poly_find_roots(roots, poly->coeffs, initial, len, maxiter, prec); } arb-2.22.1/acb_poly/fit_length.c000066400000000000000000000014231417376376500164440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_fit_length(acb_poly_t poly, slong len) { slong i; if (len > poly->alloc) { if (len < 2 * poly->alloc) len = 2 * poly->alloc; poly->coeffs = flint_realloc(poly->coeffs, len * sizeof(acb_struct)); for (i = poly->alloc; i < len; i++) acb_init(poly->coeffs + i); poly->alloc = len; } } arb-2.22.1/acb_poly/fprintd.c000066400000000000000000000013771417376376500157770ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_fprintd(FILE * file, const acb_poly_t poly, slong digits) { slong i; flint_fprintf(file, "["); for (i = 0; i < poly->length; i++) { acb_fprintd(file, poly->coeffs + i, digits); if (i + 1 < poly->length) flint_fprintf(file, "\n"); } flint_fprintf(file, "]"); } arb-2.22.1/acb_poly/gamma_series.c000066400000000000000000000214121417376376500167550ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_gamma_stirling_bound(mag_ptr err, const acb_t x, slong k0, slong knum, slong n); void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t x, int use_reflect, int digamma, slong prec); void arb_gamma_stirling_coeff(arb_t b, ulong k, int digamma, slong prec); static void bsplit(acb_ptr Q, acb_ptr T, const acb_t z, slong a, slong b, slong num, slong prec) { if (b - a == 1) { arb_gamma_stirling_coeff(acb_realref(T), a, 0, prec); arb_zero(acb_imagref(T)); if (a == 1) { /* (z + t) */ acb_set(Q, z); if (num > 1) acb_one(Q + 1); if (num > 2) acb_zero(Q + 2); } else { /* (z + t)^2 */ acb_mul(Q, z, z, prec); /* TODO: precompute */ if (num > 1) acb_mul_2exp_si(Q + 1, z, 1); if (num > 2) acb_one(Q + 2); } } else { slong m, n1, n2, q1len, q2len, t1len, t2len, qlen, tlen, alloc; acb_ptr Q1, T1, Q2, T2; m = a + (b - a) / 2; n1 = m - a; n2 = b - m; q1len = FLINT_MIN(2 * n1 + 1, num); t1len = FLINT_MIN(2 * n1 - 1, num); q2len = FLINT_MIN(2 * n2 + 1, num); t2len = FLINT_MIN(2 * n2 - 1, num); qlen = FLINT_MIN(q1len + q2len - 1, num); tlen = FLINT_MIN(t1len + q2len - 1, num); alloc = q1len + q2len + t1len + t2len; Q1 = _acb_vec_init(alloc); Q2 = Q1 + q1len; T1 = Q2 + q2len; T2 = T1 + t1len; bsplit(Q1, T1, z, a, m, num, prec); bsplit(Q2, T2, z, m, b, num, prec); _acb_poly_mullow(Q, Q2, q2len, Q1, q1len, qlen, prec); _acb_poly_mullow(T, Q2, q2len, T1, t1len, tlen, prec); _acb_poly_add(T, T, tlen, T2, t2len, prec); _acb_vec_clear(Q1, alloc); } } void _acb_poly_log_cpx_series(acb_ptr res, const acb_t c, slong num, slong prec) { slong i; for (i = 0; i < num; i++) { if (i == 0) acb_log(res + i, c, prec); else if (i == 1) acb_inv(res + i, c, prec); else acb_mul(res + i, res + i - 1, res + 1, prec); } for (i = 2; i < num; i++) { acb_div_ui(res + i, res + i, i, prec); if (i % 2 == 0) acb_neg(res + i, res + i); } } void _acb_poly_gamma_stirling_eval2(acb_ptr res, const acb_t z, slong n, slong num, int diff, slong prec) { slong k, tlen, qlen; acb_ptr T, Q; mag_ptr err; acb_t c; T = _acb_vec_init(num); Q = _acb_vec_init(num); err = _mag_vec_init(num); acb_init(c); acb_gamma_stirling_bound(err, z, 0, num, n); if (n <= 1) { _acb_vec_zero(res, num); } else { qlen = FLINT_MIN(2 * (n - 1) + 1, num); tlen = FLINT_MIN(2 * (n - 1) - 1, num); bsplit(Q, T, z, 1, n, num, prec); _acb_poly_div_series(res, T, tlen, Q, qlen, num, prec); } if (diff) { _acb_vec_add_error_mag_vec(res, err, num); _acb_poly_derivative(res, res, num, prec); if (num > 1) { /* add log(z+x) - 1/(2(z+x)) */ acb_inv(c, z, prec); _acb_vec_set_powers(T, c, num, prec); for (k = 1; k < num - 1; k++) { acb_mul_2exp_si(T, z, 1); acb_div_ui(T, T, k, prec); acb_add_ui(T, T, 1, prec); acb_mul_2exp_si(T, T, -1); if (k % 2 == 0) acb_submul(res + k, T, T + k + 1, prec); else acb_addmul(res + k, T, T + k + 1, prec); } acb_mul_2exp_si(c, c, -1); acb_sub(res, res, c, prec); acb_log(c, z, prec); acb_add(res, res, c, prec); } } else { /* ((z-1/2) + t) * log(z+t) */ _acb_poly_log_cpx_series(T, z, num, prec); acb_one(c); acb_mul_2exp_si(c, c, -1); acb_sub(c, z, c, prec); _acb_poly_mullow_cpx(T, T, num, c, num, prec); /* constant term */ arb_const_log_sqrt2pi(acb_realref(c), prec); arb_zero(acb_imagref(c)); acb_add(T, T, c, prec); /* subtract (z+t) */ acb_sub(T, T, z, prec); if (num > 1) acb_sub_ui(T + 1, T + 1, 1, prec); _acb_vec_add(res, res, T, num, prec); _acb_vec_add_error_mag_vec(res, err, num); } _acb_vec_clear(T, num); _acb_vec_clear(Q, num); _mag_vec_clear(err, num); acb_clear(c); } void _acb_poly_gamma_stirling_eval(acb_ptr res, const acb_t z, slong n, slong num, slong prec) { _acb_poly_gamma_stirling_eval2(res, z, n, num, 0, prec); } void _acb_poly_gamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong i, rflen, r, n, wp; acb_ptr t, u, v; acb_struct f[2]; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_gamma(res, h, prec); if (acb_is_finite(res)) _acb_vec_zero(res + 1, len - 1); else _acb_vec_indeterminate(res + 1, len - 1); return; } /* use real code for real input */ if (_acb_vec_is_real(h, hlen)) { arb_ptr tmp = _arb_vec_init(len); for (i = 0; i < hlen; i++) arb_set(tmp + i, acb_realref(h + i)); _arb_poly_gamma_series(tmp, tmp, hlen, len, prec); for (i = 0; i < len; i++) acb_set_arb(res + i, tmp + i); _arb_vec_clear(tmp, len); return; } wp = prec + FLINT_BIT_COUNT(prec); t = _acb_vec_init(len); u = _acb_vec_init(len); v = _acb_vec_init(len); acb_init(f); acb_init(f + 1); /* use Stirling series */ acb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 0, wp); /* gamma(h) = (rf(1-h, r) * pi) / (gamma(1-h+r) sin(pi h)), h = h0 + t*/ if (reflect) { /* u = 1/gamma(r+1-h) */ acb_sub_ui(f, h, r + 1, wp); acb_neg(f, f); _acb_poly_gamma_stirling_eval(t, f, n, len, wp); _acb_vec_neg(t, t, len); _acb_poly_exp_series(u, t, len, len, wp); for (i = 1; i < len; i += 2) acb_neg(u + i, u + i); /* v = 1/sin(pi x) */ acb_set(f, h); acb_one(f + 1); _acb_poly_sin_pi_series(t, f, 2, len, wp); _acb_poly_inv_series(v, t, len, len, wp); _acb_poly_mullow(t, u, len, v, len, len, wp); /* rf(1-h,r) * pi */ if (r == 0) { rflen = 1; acb_const_pi(u, wp); } else { acb_sub_ui(f, h, 1, wp); acb_neg(f, f); acb_set_si(f + 1, -1); rflen = FLINT_MIN(len, r + 1); _acb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), r, rflen, wp); acb_const_pi(v, wp); _acb_vec_scalar_mul(u, u, rflen, v, wp); } /* multiply by rising factorial */ _acb_poly_mullow(v, t, len, u, rflen, len, wp); } else { /* gamma(h) = gamma(h+r) / rf(h,r) */ if (r == 0) { acb_add_ui(f, h, r, wp); _acb_poly_gamma_stirling_eval(t, f, n, len, wp); _acb_poly_exp_series(v, t, len, len, wp); } else { /* TODO: div_series may be better (once it has a good basecase), if the rising factorial is short */ acb_set(f, h); acb_one(f + 1); rflen = FLINT_MIN(len, r + 1); _acb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), r, rflen, wp); _acb_poly_inv_series(t, u, rflen, len, wp); acb_add_ui(f, h, r, wp); _acb_poly_gamma_stirling_eval(v, f, n, len, wp); _acb_poly_exp_series(u, v, len, len, wp); _acb_poly_mullow(v, u, len, t, len, len, wp); } } /* compose with nonconstant part */ acb_zero(t); _acb_vec_set(t + 1, h + 1, hlen - 1); _acb_poly_compose_series(res, v, len, t, hlen, len, prec); acb_clear(f); acb_clear(f + 1); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(v, len); } void acb_poly_gamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) { acb_poly_fit_length(res, n); if (f->length == 0 || n == 0) _acb_vec_indeterminate(res->coeffs, n); else _acb_poly_gamma_series(res->coeffs, f->coeffs, f->length, n, prec); _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/get_coeff_acb.c000066400000000000000000000010731417376376500170500ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_get_coeff_acb(acb_t x, const acb_poly_t poly, slong n) { if (n < poly->length) acb_set(x, poly->coeffs + n); else acb_zero(x); } arb-2.22.1/acb_poly/get_unique_fmpz_poly.c000066400000000000000000000013221417376376500205630ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int acb_poly_get_unique_fmpz_poly(fmpz_poly_t res, const acb_poly_t src) { int success; fmpz_poly_fit_length(res, src->length); success = _acb_vec_get_unique_fmpz_vec(res->coeffs, src->coeffs, src->length); _fmpz_poly_set_length(res, src->length); _fmpz_poly_normalise(res); return success; } arb-2.22.1/acb_poly/graeffe_transform.c000066400000000000000000000027421417376376500200200ustar00rootroot00000000000000/* Copyright (C) 2021 Matthias Gessinger This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_graeffe_transform(acb_ptr b, acb_srcptr a, slong len, slong prec) { slong lo, le, ls, deg, i; acb_ptr pe, po; if (len <= 1) { if (len) acb_sqr(b, a, prec); return; } deg = len - 1; lo = len / 2; ls = 2 * lo - 1; le = deg / 2 + 1; po = _acb_vec_init(lo); pe = _acb_vec_init(FLINT_MAX(le, ls)); for (i = deg; i >= 0; i--) { if (i % 2 == 0) acb_set(pe + i / 2, a + i); else acb_set(po + i / 2, a + i); } _acb_poly_mul(b, pe, le, pe, le, prec); _acb_poly_mul(pe, po, lo, po, lo, prec); _acb_poly_sub(b + 1, b + 1, ls, pe, ls, prec); if (len % 2 == 0) { _acb_vec_neg(b, b, deg); acb_set(b + deg, pe + (deg - 1)); } _acb_vec_clear(pe, FLINT_MAX(le, ls)); _acb_vec_clear(po, lo); } void acb_poly_graeffe_transform(acb_poly_t b, const acb_poly_t a, slong prec) { acb_poly_fit_length(b, a->length); _acb_poly_graeffe_transform(b->coeffs, a->coeffs, a->length, prec); _acb_poly_set_length(b, a->length); } arb-2.22.1/acb_poly/init.c000066400000000000000000000011611417376376500152630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_init(acb_poly_t poly) { poly->coeffs = NULL; poly->length = 0; poly->alloc = 0; } void acb_poly_init2(acb_poly_t poly, slong len) { acb_poly_init(poly); acb_poly_fit_length(poly, len); } arb-2.22.1/acb_poly/inlines.c000066400000000000000000000006561417376376500157710ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ACB_POLY_INLINES_C #include "acb_poly.h" arb-2.22.1/acb_poly/integral.c000066400000000000000000000015771417376376500161400ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_integral(acb_ptr res, acb_srcptr poly, slong len, slong prec) { slong k = len - 1; for (k = len - 1; k > 0; k--) acb_div_ui(res + k, poly + k - 1, k, prec); acb_zero(res); } void acb_poly_integral(acb_poly_t res, const acb_poly_t poly, slong prec) { acb_poly_fit_length(res, poly->length + 1); _acb_poly_integral(res->coeffs, poly->coeffs, poly->length + 1, prec); _acb_poly_set_length(res, poly->length + 1); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/interpolate_barycentric.c000066400000000000000000000034131417376376500212350ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_interpolate_barycentric(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) { acb_ptr P, Q, w; acb_t t; slong i, j; if (n == 1) { acb_set(poly, ys); return; } P = _acb_vec_init(n + 1); Q = _acb_vec_init(n); w = _acb_vec_init(n); acb_init(t); _acb_poly_product_roots(P, xs, n, prec); for (i = 0; i < n; i++) { acb_one(w + i); for (j = 0; j < n; j++) { if (i != j) { acb_sub(t, xs + i, xs + j, prec); acb_mul(w + i, w + i, t, prec); } } acb_inv(w + i, w + i, prec); } _acb_vec_zero(poly, n); for (i = 0; i < n; i++) { _acb_poly_div_root(Q, t, P, n + 1, xs + i, prec); acb_mul(t, w + i, ys + i, prec); _acb_vec_scalar_addmul(poly, Q, n, t, prec); } _acb_vec_clear(P, n + 1); _acb_vec_clear(Q, n); _acb_vec_clear(w, n); acb_clear(t); } void acb_poly_interpolate_barycentric(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) { if (n == 0) { acb_poly_zero(poly); } else { acb_poly_fit_length(poly, n); _acb_poly_set_length(poly, n); _acb_poly_interpolate_barycentric(poly->coeffs, xs, ys, n, prec); _acb_poly_normalise(poly); } } arb-2.22.1/acb_poly/interpolate_fast.c000066400000000000000000000057461417376376500177000ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_interpolation_weights(acb_ptr w, acb_ptr * tree, slong len, slong prec) { acb_ptr tmp; slong i, n, height; if (len == 0) return; if (len == 1) { acb_one(w); return; } tmp = _acb_vec_init(len + 1); height = FLINT_CLOG2(len); n = WORD(1) << (height - 1); _acb_poly_mul_monic(tmp, tree[height-1], n + 1, tree[height-1] + (n + 1), (len - n + 1), prec); _acb_poly_derivative(tmp, tmp, len + 1, prec); _acb_poly_evaluate_vec_fast_precomp(w, tmp, len, tree, len, prec); for (i = 0; i < len; i++) acb_inv(w + i, w + i, prec); _acb_vec_clear(tmp, len + 1); } void _acb_poly_interpolate_fast_precomp(acb_ptr poly, acb_srcptr ys, acb_ptr * tree, acb_srcptr weights, slong len, slong prec) { acb_ptr t, u, pa, pb; slong i, pow, left; if (len == 0) return; t = _acb_vec_init(len); u = _acb_vec_init(len); for (i = 0; i < len; i++) acb_mul(poly + i, weights + i, ys + i, prec); for (i = 0; i < FLINT_CLOG2(len); i++) { pow = (WORD(1) << i); pa = tree[i]; pb = poly; left = len; while (left >= 2 * pow) { _acb_poly_mul(t, pa, pow + 1, pb + pow, pow, prec); _acb_poly_mul(u, pa + pow + 1, pow + 1, pb, pow, prec); _acb_vec_add(pb, t, u, 2 * pow, prec); left -= 2 * pow; pa += 2 * pow + 2; pb += 2 * pow; } if (left > pow) { _acb_poly_mul(t, pa, pow + 1, pb + pow, left - pow, prec); _acb_poly_mul(u, pb, pow, pa + pow + 1, left - pow + 1, prec); _acb_vec_add(pb, t, u, left, prec); } } _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void _acb_poly_interpolate_fast(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong len, slong prec) { acb_ptr * tree; acb_ptr w; tree = _acb_poly_tree_alloc(len); _acb_poly_tree_build(tree, xs, len, prec); w = _acb_vec_init(len); _acb_poly_interpolation_weights(w, tree, len, prec); _acb_poly_interpolate_fast_precomp(poly, ys, tree, w, len, prec); _acb_vec_clear(w, len); _acb_poly_tree_free(tree, len); } void acb_poly_interpolate_fast(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) { if (n == 0) { acb_poly_zero(poly); } else { acb_poly_fit_length(poly, n); _acb_poly_set_length(poly, n); _acb_poly_interpolate_fast(poly->coeffs, xs, ys, n, prec); _acb_poly_normalise(poly); } } arb-2.22.1/acb_poly/interpolate_newton.c000066400000000000000000000043161417376376500202450ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" static void _interpolate_newton(acb_ptr ys, acb_srcptr xs, slong n, slong prec) { acb_t p, q, t; slong i, j; acb_init(p); acb_init(q); acb_init(t); for (i = 1; i < n; i++) { acb_set(t, ys + i - 1); for (j = i; j < n; j++) { acb_sub(p, ys + j, t, prec); acb_sub(q, xs + j, xs + j - i, prec); acb_set(t, ys + j); acb_div(ys + j, p, q, prec); } } acb_clear(p); acb_clear(q); acb_clear(t); } static void _newton_to_monomial(acb_ptr ys, acb_srcptr xs, slong n, slong prec) { acb_t t, u; slong i, j; acb_init(t); acb_init(u); for (i = n - 2; i >= 0; i--) { acb_set(t, ys + i); acb_set(ys + i, ys + i + 1); for (j = i + 1; j < n - 1; j++) { acb_mul(u, ys + j, xs + i, prec); acb_sub(ys + j, ys + j + 1, u, prec); } acb_mul(u, ys + n - 1, xs + i, prec); acb_sub(ys + n - 1, t, u, prec); } _acb_poly_reverse(ys, ys, n, n); acb_clear(t); acb_clear(u); } void _acb_poly_interpolate_newton(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) { if (n == 1) { acb_set(poly, ys); } else { _acb_vec_set(poly, ys, n); _interpolate_newton(poly, xs, n, prec); while (n > 0 && acb_is_zero(poly + n - 1)) n--; _newton_to_monomial(poly, xs, n, prec); } } void acb_poly_interpolate_newton(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) { if (n == 0) { acb_poly_zero(poly); } else { acb_poly_fit_length(poly, n); _acb_poly_set_length(poly, n); _acb_poly_interpolate_newton(poly->coeffs, xs, ys, n, prec); _acb_poly_normalise(poly); } } arb-2.22.1/acb_poly/inv_borel_transform.c000066400000000000000000000017721417376376500204020ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_inv_borel_transform(acb_ptr res, acb_srcptr poly, slong len, slong prec) { slong i; arb_t t; arb_init(t); arb_one(t); for (i = 0; i < len; i++) { if (i > 1) arb_mul_ui(t, t, i, prec); acb_mul_arb(res + i, poly + i, t, prec); } arb_clear(t); } void acb_poly_inv_borel_transform(acb_poly_t res, const acb_poly_t poly, slong prec) { acb_poly_fit_length(res, poly->length); _acb_poly_inv_borel_transform(res->coeffs, poly->coeffs, poly->length, prec); _acb_poly_set_length(res, poly->length); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/inv_series.c000066400000000000000000000054631417376376500164770ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #define MULLOW(z, x, xn, y, yn, nn, prec) \ if ((xn) >= (yn)) \ _acb_poly_mullow(z, x, xn, y, yn, nn, prec); \ else \ _acb_poly_mullow(z, y, yn, x, xn, nn, prec); \ void _acb_poly_inv_series(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong len, slong prec) { Qlen = FLINT_MIN(Qlen, len); acb_inv(Qinv, Q, prec); if (Qlen == 1) { _acb_vec_zero(Qinv + 1, len - 1); } else if (len == 2) { acb_mul(Qinv + 1, Qinv, Qinv, prec); acb_mul(Qinv + 1, Qinv + 1, Q + 1, prec); acb_neg(Qinv + 1, Qinv + 1); } else { slong i, blen; /* The basecase algorithm is faster for much larger Qlen or len than this, but unfortunately also much less numerically stable. */ if (Qlen == 2 || len <= 8) blen = len; else blen = FLINT_MIN(len, 4); for (i = 1; i < blen; i++) { acb_dot(Qinv + i, NULL, 1, Q + 1, 1, Qinv + i - 1, -1, FLINT_MIN(i, Qlen - 1), prec); if (!acb_is_one(Qinv)) acb_mul(Qinv + i, Qinv + i, Qinv, prec); } if (len > blen) { slong Qnlen, Wlen, W2len; acb_ptr W; W = _acb_vec_init(len); NEWTON_INIT(blen, len) NEWTON_LOOP(m, n) Qnlen = FLINT_MIN(Qlen, n); Wlen = FLINT_MIN(Qnlen + m - 1, n); W2len = Wlen - m; MULLOW(W, Q, Qnlen, Qinv, m, Wlen, prec); MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m, prec); _acb_vec_neg(Qinv + m, Qinv + m, n - m); NEWTON_END_LOOP NEWTON_END _acb_vec_clear(W, len); } } } void acb_poly_inv_series(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec) { if (n == 0) { acb_poly_zero(Qinv); return; } if (Q->length == 0) { acb_poly_fit_length(Qinv, n); _acb_vec_indeterminate(Qinv->coeffs, n); _acb_poly_set_length(Qinv, n); return; } if (Qinv == Q) { acb_poly_t t; acb_poly_init(t); acb_poly_inv_series(t, Q, n, prec); acb_poly_swap(Qinv, t); acb_poly_clear(t); return; } acb_poly_fit_length(Qinv, n); _acb_poly_inv_series(Qinv->coeffs, Q->coeffs, Q->length, n, prec); _acb_poly_set_length(Qinv, n); _acb_poly_normalise(Qinv); } arb-2.22.1/acb_poly/lambertw_series.c000066400000000000000000000045121417376376500175120ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_lambertw_series(acb_ptr res, acb_srcptr z, slong zlen, const fmpz_t k, int flags, slong len, slong prec) { acb_ptr w, ew, t, u; acb_t ew0; zlen = FLINT_MIN(zlen, len); if (zlen == 1) { acb_lambertw(res, z, k, flags, prec); _acb_vec_zero(res + 1, len - 1); return; } w = _acb_vec_init(len); ew = _acb_vec_init(len); t = _acb_vec_init(len); u = _acb_vec_init(len); acb_init(ew0); acb_lambertw(w, z, k, flags, prec); if (acb_contains_zero(w)) acb_exp(ew0, w, prec); else acb_div(ew0, z, w, prec); acb_add(t, ew0, z, prec); acb_div(w + 1, z + 1, t, prec); NEWTON_INIT(2, len) NEWTON_LOOP(m, n) /* _acb_poly_exp_series(ew, w, m, n, prec); */ acb_zero(t); _acb_vec_set(t + 1, w + 1, m - 1); _acb_poly_exp_series(ew, t, m, n, prec); _acb_vec_scalar_mul(ew, ew, n, ew0, prec); _acb_poly_mullow(t, ew, n, w, m, n, prec); _acb_poly_sub(u, t, n, z, FLINT_MIN(zlen, n), prec); _acb_vec_add(t, t, ew, n, prec); _acb_poly_div_series(ew, u, n, t, n, n, prec); _acb_vec_neg(w + m, ew + m, n - m); NEWTON_END_LOOP NEWTON_END _acb_vec_set(res, w, len); _acb_vec_clear(w, len); _acb_vec_clear(ew, len); _acb_vec_clear(t, len); _acb_vec_clear(u, len); acb_clear(ew0); } void acb_poly_lambertw_series(acb_poly_t res, const acb_poly_t z, const fmpz_t k, int flags, slong len, slong prec) { if (len == 0 || (fmpz_is_zero(k) && z->length == 0)) { acb_poly_zero(res); return; } if (z->length == 0) { acb_poly_fit_length(res, len); _acb_vec_indeterminate(res->coeffs, len); _acb_poly_set_length(res, len); return; } acb_poly_fit_length(res, len); _acb_poly_lambertw_series(res->coeffs, z->coeffs, z->length, k, flags, len, prec); _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/lgamma_series.c000066400000000000000000000102421417376376500171300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_hypgeom.h" void _acb_log_rising_correct_branch(acb_t t, const acb_t t_wrong, const acb_t z, ulong r, slong prec); void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t x, int use_reflect, int digamma, slong prec); void _acb_poly_gamma_stirling_eval(acb_ptr res, const acb_t z, slong n, slong num, slong prec); void _acb_poly_lgamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong i, r, n, wp; acb_t zr; acb_ptr t, u; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_lgamma(res, h, prec); if (acb_is_finite(res)) _acb_vec_zero(res + 1, len - 1); else _acb_vec_indeterminate(res + 1, len - 1); return; } if (len == 2) { acb_t v; acb_init(v); acb_set(v, h + 1); acb_digamma(res + 1, h, prec); acb_lgamma(res, h, prec); acb_mul(res + 1, res + 1, v, prec); acb_clear(v); return; } /* use real code for real input and output */ if (_acb_vec_is_real(h, hlen) && arb_is_positive(acb_realref(h))) { arb_ptr tmp = _arb_vec_init(len); for (i = 0; i < hlen; i++) arb_set(tmp + i, acb_realref(h + i)); _arb_poly_lgamma_series(tmp, tmp, hlen, len, prec); for (i = 0; i < len; i++) acb_set_arb(res + i, tmp + i); _arb_vec_clear(tmp, len); return; } wp = prec + FLINT_BIT_COUNT(prec); t = _acb_vec_init(len); u = _acb_vec_init(len); acb_init(zr); /* use Stirling series */ acb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 0, wp); if (reflect) { /* log gamma(h+x) = log rf(1-(h+x), r) - log gamma(1-(h+x)+r) - log sin(pi (h+x)) + log(pi) */ if (r != 0) /* otherwise t = 0 */ { acb_sub_ui(u, h, 1, wp); acb_neg(u, u); acb_hypgeom_log_rising_ui_jet(t, u, r, len, wp); for (i = 1; i < len; i += 2) acb_neg(t + i, t + i); } acb_sub_ui(u, h, 1, wp); acb_neg(u, u); acb_add_ui(zr, u, r, wp); _acb_poly_gamma_stirling_eval(u, zr, n, len, wp); for (i = 1; i < len; i += 2) acb_neg(u + i, u + i); _acb_vec_sub(t, t, u, len, wp); /* log(sin) is unstable with large imaginary parts; cot_pi is implemented in a numerically stable way */ acb_set(u, h); acb_one(u + 1); _acb_poly_cot_pi_series(u, u, 2, len - 1, wp); _acb_poly_integral(u, u, len, wp); acb_const_pi(u, wp); _acb_vec_scalar_mul(u + 1, u + 1, len - 1, u, wp); acb_log_sin_pi(u, h, wp); _acb_vec_sub(u, t, u, len, wp); acb_const_pi(t, wp); /* todo: constant for log pi */ acb_log(t, t, wp); acb_add(u, u, t, wp); } else { /* log gamma(x) = log gamma(x+r) - log rf(x,r) */ acb_add_ui(zr, h, r, wp); _acb_poly_gamma_stirling_eval(u, zr, n, len, wp); if (r != 0) { acb_hypgeom_log_rising_ui_jet(t, h, r, len, wp); _acb_vec_sub(u, u, t, len, wp); } } /* compose with nonconstant part */ acb_zero(t); _acb_vec_set(t + 1, h + 1, hlen - 1); _acb_poly_compose_series(res, u, len, t, hlen, len, prec); acb_clear(zr); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void acb_poly_lgamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) { acb_poly_fit_length(res, n); if (f->length == 0 || n == 0) _acb_vec_indeterminate(res->coeffs, n); else _acb_poly_lgamma_series(res->coeffs, f->coeffs, f->length, n, prec); _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/log1p_series.c000066400000000000000000000045411417376376500167210ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_log1p_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec) { acb_t a; flen = FLINT_MIN(flen, n); acb_init(a); acb_log1p(a, f, prec); if (flen == 1) { _acb_vec_zero(res + 1, n - 1); } else if (n == 2) { acb_add_ui(res, f + 0, 1, prec); acb_div(res + 1, f + 1, res + 0, prec); } else if (_acb_vec_is_zero(f + 1, flen - 2)) /* f = a + bx^d */ { slong i, j, d = flen - 1; acb_add_ui(res, f + 0, 1, prec); for (i = 1, j = d; j < n; j += d, i++) { if (i == 1) acb_div(res + j, f + d, res, prec); else acb_mul(res + j, res + j - d, res + d, prec); _acb_vec_zero(res + j - d + 1, flen - 2); } _acb_vec_zero(res + j - d + 1, n - (j - d + 1)); for (i = 2, j = 2 * d; j < n; j += d, i++) acb_div_si(res + j, res + j, i % 2 ? i : -i, prec); } else { acb_ptr f_diff, f_inv; slong alloc; alloc = n + flen; f_inv = _acb_vec_init(alloc); f_diff = f_inv + n; acb_add_ui(f_diff, f, 1, prec); _acb_vec_set(f_diff + 1, f + 1, flen - 1); _acb_poly_inv_series(f_inv, f_diff, flen, n, prec); _acb_poly_derivative(f_diff, f, flen, prec); _acb_poly_mullow(res, f_inv, n - 1, f_diff, flen - 1, n - 1, prec); _acb_poly_integral(res, res, n, prec); _acb_vec_clear(f_inv, alloc); } acb_swap(res, a); acb_clear(a); } void acb_poly_log1p_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) { slong flen = f->length; if (flen == 0 || n == 0) { acb_poly_zero(res); return; } if (flen == 1 /*&& !acb_contains_si(f->coeffs, -1)*/) n = 1; acb_poly_fit_length(res, n); _acb_poly_log1p_series(res->coeffs, f->coeffs, flen, n, prec); _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/log_series.c000066400000000000000000000045041417376376500164570ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_log_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec) { flen = FLINT_MIN(flen, n); if (flen == 1) { acb_log(res, f, prec); _acb_vec_zero(res + 1, n - 1); } else if (n == 2) { acb_div(res + 1, f + 1, f + 0, prec); /* safe since hlen >= 2 */ acb_log(res, f, prec); } else if (_acb_vec_is_zero(f + 1, flen - 2)) /* f = a + bx^d */ { slong i, j, d = flen - 1; for (i = 1, j = d; j < n; j += d, i++) { if (i == 1) acb_div(res + j, f + d, f + 0, prec); else acb_mul(res + j, res + j - d, res + d, prec); _acb_vec_zero(res + j - d + 1, flen - 2); } _acb_vec_zero(res + j - d + 1, n - (j - d + 1)); for (i = 2, j = 2 * d; j < n; j += d, i++) acb_div_si(res + j, res + j, i % 2 ? i : -i, prec); acb_log(res, f, prec); /* done last to allow aliasing */ } else { acb_ptr f_diff, f_inv; acb_t a; slong alloc; alloc = n + flen - 1; f_inv = _acb_vec_init(alloc); f_diff = f_inv + n; acb_init(a); acb_log(a, f, prec); _acb_poly_derivative(f_diff, f, flen, prec); _acb_poly_inv_series(f_inv, f, flen, n, prec); _acb_poly_mullow(res, f_inv, n - 1, f_diff, flen - 1, n - 1, prec); _acb_poly_integral(res, res, n, prec); acb_swap(res, a); acb_clear(a); _acb_vec_clear(f_inv, alloc); } } void acb_poly_log_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) { if (n == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, n); if (f->length == 0) _acb_vec_indeterminate(res->coeffs, n); else _acb_poly_log_series(res->coeffs, f->coeffs, f->length, n, prec); _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/majorant.c000066400000000000000000000015661417376376500161440ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_majorant(arb_ptr res, acb_srcptr vec, slong len, slong prec) { slong i; for (i = 0; i < len; i++) { acb_get_abs_ubound_arf(arb_midref(res + i), vec + i, prec); mag_zero(arb_radref(res + i)); } } void acb_poly_majorant(arb_poly_t res, const acb_poly_t poly, slong prec) { arb_poly_fit_length(res, poly->length); _acb_poly_majorant(res->coeffs, poly->coeffs, poly->length, prec); _arb_poly_set_length(res, poly->length); } arb-2.22.1/acb_poly/mul.c000066400000000000000000000026561417376376500151270ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_mul(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) { _acb_poly_mullow(C, A, lenA, B, lenB, lenA + lenB - 1, prec); } void acb_poly_mul(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) { slong len_out; if ((poly1->length == 0) || (poly2->length == 0)) { acb_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (res == poly1 || res == poly2) { acb_poly_t temp; acb_poly_init2(temp, len_out); _acb_poly_mul(temp->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); acb_poly_swap(res, temp); acb_poly_clear(temp); } else { acb_poly_fit_length(res, len_out); _acb_poly_mul(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); } _acb_poly_set_length(res, len_out); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/mullow.c000066400000000000000000000074721417376376500156520ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_mullow(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) { if (n == 1) { acb_mul(res, poly1, poly2, prec); } else if (n <= 7 || len1 <= 7 || len2 <= 7) { _acb_poly_mullow_classical(res, poly1, len1, poly2, len2, n, prec); } else { slong cutoff; double p; if (prec <= 2 * FLINT_BITS) { cutoff = 110; } else { p = log(prec); cutoff = 10000.0 / (p * p * p); cutoff = FLINT_MIN(cutoff, 60); if (poly1 == poly2 && prec >= 256) cutoff *= 1.25; if (poly1 == poly2 && prec >= 4096) cutoff *= 1.25; cutoff = FLINT_MAX(cutoff, 8); } if (2 * FLINT_MIN(len1, len2) <= cutoff || n <= cutoff) _acb_poly_mullow_classical(res, poly1, len1, poly2, len2, n, prec); else _acb_poly_mullow_transpose(res, poly1, len1, poly2, len2, n, prec); } } void acb_poly_mullow(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; if (len1 == 0 || len2 == 0 || n == 0) { acb_poly_zero(res); return; } n = FLINT_MIN((len1 + len2 - 1), n); len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); /* Hack to avoid temporary allocations with first derivatives. */ if (n <= 2 && !(len1 == 2 && len2 == 2)) { acb_poly_fit_length(res, n); if (n == 1) { acb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); } else if (len2 == 1) { acb_mul(res->coeffs + 1, poly1->coeffs + 1, poly2->coeffs, prec); acb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); } else if (len1 == 1) { acb_mul(res->coeffs + 1, poly2->coeffs + 1, poly1->coeffs, prec); acb_mul(res->coeffs, poly2->coeffs, poly1->coeffs, prec); } else { if (res == poly1 || res == poly2) { acb_t t; acb_init(t); acb_mul(t, poly1->coeffs, poly2->coeffs + 1, prec); acb_addmul(t, poly2->coeffs, poly1->coeffs + 1, prec); acb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); acb_swap(t, res->coeffs + 1); acb_clear(t); } else { acb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); acb_mul(res->coeffs + 1, poly1->coeffs, poly2->coeffs + 1, prec); acb_addmul(res->coeffs + 1, poly2->coeffs, poly1->coeffs + 1, prec); } } _acb_poly_set_length(res, n); _acb_poly_normalise(res); return; } if (res == poly1 || res == poly2) { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_mullow(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); acb_poly_swap(res, t); acb_poly_clear(t); } else { acb_poly_fit_length(res, n); _acb_poly_mullow(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/mullow_classical.c000066400000000000000000000063351417376376500176650ustar00rootroot00000000000000/* Copyright (C) 2008, 2009 William Hart Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_mullow_classical(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) { len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); if (n == 1) { acb_mul(res, poly1, poly2, prec); } else if (poly1 == poly2 && len1 == len2) { slong i, start, stop; acb_sqr(res, poly1, prec); acb_mul(res + 1, poly1, poly1 + 1, prec); acb_mul_2exp_si(res + 1, res + 1, 1); for (i = 2; i < FLINT_MIN(n, 2 * len1 - 3); i++) { start = FLINT_MAX(0, i - len1 + 1); stop = FLINT_MIN(len1 - 1, (i + 1) / 2 - 1); acb_dot(res + i, NULL, 0, poly1 + start, 1, poly1 + i - start, -1, stop - start + 1, prec); acb_mul_2exp_si(res + i, res + i, 1); if (i % 2 == 0 && i / 2 < len1) acb_addmul(res + i, poly1 + i / 2, poly1 + i / 2, prec); } if (len1 > 2 && n >= 2 * len1 - 2) { acb_mul(res + 2 * len1 - 3, poly1 + len1 - 1, poly1 + len1 - 2, prec); acb_mul_2exp_si(res + 2 * len1 - 3, res + 2 * len1 - 3, 1); } if (n >= 2 * len1 - 1) acb_sqr(res + 2 * len1 - 2, poly1 + len1 - 1, prec); } else if (len1 == 1) { _acb_vec_scalar_mul(res, poly2, n, poly1, prec); } else if (len2 == 1) { _acb_vec_scalar_mul(res, poly1, n, poly2, prec); } else { slong i, top1, top2; acb_mul(res, poly1, poly2, prec); for (i = 1; i < n; i++) { top1 = FLINT_MIN(len1 - 1, i); top2 = FLINT_MIN(len2 - 1, i); acb_dot(res + i, NULL, 0, poly1 + i - top2, 1, poly2 + top2, -1, top1 + top2 - i + 1, prec); } } } void acb_poly_mullow_classical(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) { slong len_out; if (poly1->length == 0 || poly2->length == 0 || n == 0) { acb_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (n > len_out) n = len_out; if (res == poly1 || res == poly2) { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_mullow_classical(t->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n, prec); acb_poly_swap(res, t); acb_poly_clear(t); } else { acb_poly_fit_length(res, n); _acb_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/mullow_transpose.c000066400000000000000000000055411417376376500177430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_mullow_transpose(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) { arb_ptr a, b, c, d, e, f, w; arb_ptr t; slong i; len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); w = flint_malloc(sizeof(arb_struct) * (2 * (len1 + len2 + n))); a = w; b = a + len1; c = b + len1; d = c + len2; e = d + len2; f = e + n; /* (e+fi) = (a+bi)(c+di) = (ac - bd) + (ad + bc)i */ t = _arb_vec_init(n); for (i = 0; i < len1; i++) { a[i] = *acb_realref(poly1 + i); b[i] = *acb_imagref(poly1 + i); } for (i = 0; i < len2; i++) { c[i] = *acb_realref(poly2 + i); d[i] = *acb_imagref(poly2 + i); } for (i = 0; i < n; i++) { e[i] = *acb_realref(res + i); f[i] = *acb_imagref(res + i); } _arb_poly_mullow(e, a, len1, c, len2, n, prec); _arb_poly_mullow(t, b, len1, d, len2, n, prec); _arb_vec_sub(e, e, t, n, prec); _arb_poly_mullow(f, a, len1, d, len2, n, prec); /* squaring */ if (poly1 == poly2 && len1 == len2) { _arb_vec_scalar_mul_2exp_si(f, f, n, 1); } else { _arb_poly_mullow(t, b, len1, c, len2, n, prec); _arb_vec_add(f, f, t, n, prec); } for (i = 0; i < n; i++) { *acb_realref(res + i) = e[i]; *acb_imagref(res + i) = f[i]; } _arb_vec_clear(t, n); flint_free(w); } void acb_poly_mullow_transpose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; if (len1 == 0 || len2 == 0 || n == 0) { acb_poly_zero(res); return; } n = FLINT_MIN((len1 + len2 - 1), n); len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); if (res == poly1 || res == poly2) { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_mullow_transpose(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); acb_poly_swap(res, t); acb_poly_clear(t); } else { acb_poly_fit_length(res, n); _acb_poly_mullow_transpose(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/mullow_transpose_gauss.c000066400000000000000000000055311417376376500211440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_mullow_transpose_gauss(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) { arb_ptr a, b, c, d, e, f, w; arb_ptr t, u, v; slong i; len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); w = flint_malloc(sizeof(arb_struct) * (2 * (len1 + len2 + n))); a = w; b = a + len1; c = b + len1; d = c + len2; e = d + len2; f = e + n; t = _arb_vec_init(n); u = _arb_vec_init(n); v = _arb_vec_init(n); for (i = 0; i < len1; i++) { a[i] = *acb_realref(poly1 + i); b[i] = *acb_imagref(poly1 + i); } for (i = 0; i < len2; i++) { c[i] = *acb_realref(poly2 + i); d[i] = *acb_imagref(poly2 + i); } for (i = 0; i < n; i++) { e[i] = *acb_realref(res + i); f[i] = *acb_imagref(res + i); } _arb_vec_add(t, a, b, len1, prec); _arb_vec_add(u, c, d, len2, prec); _arb_poly_mullow(v, t, len1, u, len2, n, prec); _arb_poly_mullow(t, a, len1, c, len2, n, prec); _arb_poly_mullow(u, b, len1, d, len2, n, prec); _arb_vec_sub(e, t, u, n, prec); _arb_vec_sub(f, v, t, n, prec); _arb_vec_sub(f, f, u, n, prec); for (i = 0; i < n; i++) { *acb_realref(res + i) = e[i]; *acb_imagref(res + i) = f[i]; } _arb_vec_clear(t, n); _arb_vec_clear(u, n); _arb_vec_clear(v, n); flint_free(w); } void acb_poly_mullow_transpose_gauss(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; if (len1 == 0 || len2 == 0 || n == 0) { acb_poly_zero(res); return; } n = FLINT_MIN((len1 + len2 - 1), n); len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); if (res == poly1 || res == poly2) { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_mullow_transpose_gauss(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); acb_poly_swap(res, t); acb_poly_clear(t); } else { acb_poly_fit_length(res, n); _acb_poly_mullow_transpose_gauss(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/normalise.c000066400000000000000000000011021417376376500163040ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_normalise(acb_poly_t poly) { slong i; for (i = poly->length - 1; (i >= 0) && acb_is_zero(poly->coeffs + i); i--); poly->length = i + 1; } arb-2.22.1/acb_poly/overlaps.c000066400000000000000000000020371417376376500161560ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int _acb_poly_overlaps(acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2) { slong i; for (i = 0; i < len2; i++) if (!acb_overlaps(poly1 + i, poly2 + i)) return 0; for (i = len2; i < len1; i++) if (!acb_contains_zero(poly1 + i)) return 0; return 1; } int acb_poly_overlaps(const acb_poly_t poly1, const acb_poly_t poly2) { slong len1 = poly1->length; slong len2 = poly2->length; if (len1 >= len2) return _acb_poly_overlaps(poly1->coeffs, len1, poly2->coeffs, len2); else return _acb_poly_overlaps(poly2->coeffs, len2, poly1->coeffs, len1); } arb-2.22.1/acb_poly/polylog_series.c000066400000000000000000000200101417376376500173510ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_hypgeom.h" /* note: will not return a wrong value, as arf_get_si aborts on overflow */ slong arb_get_si_lower(const arb_t x) { arf_t t; slong v; arf_init(t); arf_set_mag(t, arb_radref(x)); arf_sub(t, arb_midref(x), t, 2 * FLINT_BITS, ARF_RND_FLOOR); v = arf_get_si(t, ARF_RND_FLOOR); arf_clear(t); return v; } slong polylog_choose_terms(mag_t err, slong sigma, const mag_t z, slong d, slong prec) { slong N; for (N = 3; ; N = FLINT_MAX(N+3, N*1.1)) { mag_polylog_tail(err, z, sigma, d, N); /* TODO: do something else when |Li_s(z)| is very small/very large? */ if (mag_cmp_2exp_si(err, -prec) < 0) break; if (N > 100 * prec) { N = 3; mag_inf(err); break; } } return N; } int polylog_is_real(const acb_t s, const acb_t z) { if (!arb_is_zero(acb_imagref(s))) return 0; else if (!arb_is_zero(acb_imagref(z))) return 0; else if (arb_contains_si(acb_realref(z), 1)) return 0; else if (acb_is_int(s) && arb_is_nonpositive(acb_realref(s))) return 1; else return (arf_cmp_2exp_si(arb_midref(acb_realref(z)), 0) < 0); } void _acb_poly_polylog_cpx_zeta(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec) { acb_ptr e1, e2, z1, z2, e1z1, e2z2; acb_t t, u, v; slong k, len2; int deflate_zeta, deflate_gamma, is_real; if (!acb_is_finite(s) || !acb_is_finite(z)) { _acb_vec_indeterminate(w, len); return; } if (acb_is_one(z)) { if (arb_gt(acb_realref(s), acb_realref(z))) /* Re(s) > 1 */ { acb_zeta(w, s, prec); _acb_vec_indeterminate(w + 1, len - 1); } else { _acb_vec_indeterminate(w, len); } return; } is_real = polylog_is_real(s, z); acb_init(t); acb_init(u); acb_init(v); /* v = 1-s */ acb_one(v); acb_sub(v, v, s, prec); /* pole of zeta */ deflate_zeta = acb_is_one(v); /* poles of gamma at nonpositive integer v */ deflate_gamma = (arb_is_zero(acb_imagref(v)) && arb_is_int(acb_realref(v)) && arf_sgn(arb_midref(acb_realref(v))) <= 0); len2 = len + deflate_gamma; e1 = _acb_vec_init(len + 1); e2 = _acb_vec_init(len + 1); z1 = _acb_vec_init(len + 1); z2 = _acb_vec_init(len + 1); e1z1 = _acb_vec_init(len + 1); e2z2 = _acb_vec_init(len + 1); /* u = log(-z)/(pi*i) */ acb_neg(t, z); acb_log(t, t, prec); acb_const_pi(u, prec); acb_mul_onei(u, u); acb_div(u, t, u, prec); /* z1 = zeta(v+x, 1/2 + log(-z)/(2*pi*i)) */ acb_one(t); acb_add(t, t, u, prec); acb_mul_2exp_si(t, t, -1); _acb_poly_zeta_cpx_series(z1, v, t, deflate_zeta, len2, prec); /* z2 = zeta(v+x, 1/2 - log(-z)/(2*pi*i)) */ acb_one(t); acb_sub(t, t, u, prec); acb_mul_2exp_si(t, t, -1); _acb_poly_zeta_cpx_series(z2, v, t, deflate_zeta, len2, prec); /* e1 = (i/(2pi))^(v+x) */ acb_onei(t); acb_const_pi(u, prec); acb_div(t, t, u, prec); acb_mul_2exp_si(t, t, -1); _acb_poly_acb_pow_cpx(e1, t, v, len + (deflate_zeta || deflate_gamma), prec); /* e2 = (1/(2 pi i))^(v+x) */ acb_conj(t, t); _acb_poly_acb_pow_cpx(e2, t, v, len + (deflate_zeta || deflate_gamma), prec); _acb_poly_mullow(e1z1, e1, len2, z1, len2, len2, prec); _acb_poly_mullow(e2z2, e2, len2, z2, len2, len2, prec); _acb_vec_add(z1, e1z1, e2z2, len2, prec); if (deflate_gamma) { /* gamma(v+x) = pi/sin(pi(v+x)) * 1/gamma(1-v-x) */ /* TODO: write a csc function? */ acb_zero(e1); acb_const_pi(e1 + 1, prec); acb_mul_2exp_si(e2, v, -1); if (!arb_is_int(acb_realref(e2))) acb_neg(e1 + 1, e1 + 1); _acb_poly_sin_series(e2, e1, 2, len2, prec); _acb_poly_inv_series(e1, e2 + 1, len, len, prec); acb_const_pi(e2, prec); _acb_vec_scalar_mul(e1, e1, len, e2, prec); acb_set(z2, s); acb_set_si(z2 + 1, -1); _acb_poly_rgamma_series(e2, z2, 2, len, prec); _acb_poly_mullow(z2, e1, len, e2, len, len, prec); _acb_poly_mullow(w, z1 + 1, len, z2, len, len, prec); } else { if (deflate_zeta) { for (k = 0; k < len; k++) { arb_mul_2exp_si(acb_realref(e1 + k + 1), acb_realref(e1 + k + 1), 1); arb_add(acb_realref(z1 + k), acb_realref(z1 + k), acb_realref(e1 + k + 1), prec); } } /* gamma(v+x) */ acb_set(e1, v); if (len > 1) acb_one(e1 + 1); _acb_poly_gamma_series(z2, e1, FLINT_MIN(len, 2), len, prec); _acb_poly_mullow(w, z2, len, z1, len, len, prec); } /* correct signs (from s -> 1-s) */ for (k = 1; k < len; k += 2) acb_neg(w + k, w + k); if (is_real) if (acb_is_finite(w)) arb_zero(acb_imagref(w)); _acb_vec_clear(e1, len + 1); _acb_vec_clear(e2, len + 1); _acb_vec_clear(z1, len + 1); _acb_vec_clear(z2, len + 1); _acb_vec_clear(e1z1, len + 1); _acb_vec_clear(e2z2, len + 1); acb_clear(t); acb_clear(u); acb_clear(v); } void _acb_poly_polylog_cpx_small(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec) { slong k, N, sigma; int is_real; mag_t zmag, err, errf; acb_t a; acb_init(a); mag_init(zmag); mag_init(err); mag_init(errf); is_real = polylog_is_real(s, z); acb_get_mag(zmag, z); sigma = arb_get_si_lower(acb_realref(s)); N = polylog_choose_terms(err, sigma, zmag, len - 1, prec); /* TODO: allow threading */ acb_one(a); _acb_poly_powsum_series_naive(w, s, a, z, N - 1, len, prec); _acb_vec_scalar_mul(w, w, len, z, prec); for (k = 0; k < len; k++) { mag_polylog_tail(err, zmag, sigma, k, N); mag_rfac_ui(errf, k); mag_mul(err, err, errf); if (is_real && mag_is_finite(err)) arb_add_error_mag(acb_realref(w + k), err); else acb_add_error_mag(w + k, err); } acb_clear(a); mag_clear(zmag); mag_clear(err); mag_clear(errf); } void _acb_poly_polylog_cpx(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec) { mag_t zmag; if (len == 1 && acb_equal_si(s, 2)) { acb_hypgeom_dilog(w, z, prec); return; } mag_init(zmag); acb_get_mag(zmag, z); if (mag_cmp_2exp_si(zmag, -1) < 0) _acb_poly_polylog_cpx_small(w, s, z, len, prec); else _acb_poly_polylog_cpx_zeta(w, s, z, len, prec); mag_clear(zmag); } void _acb_poly_polylog_series(acb_ptr res, acb_srcptr s, slong slen, const acb_t z, slong len, slong prec) { acb_ptr t, u; slen = FLINT_MIN(slen, len); t = _acb_vec_init(len); u = _acb_vec_init(len); _acb_poly_polylog_cpx(t, s, z, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, s + 1, slen - 1); _acb_poly_compose_series(res, t, len, u, slen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void acb_poly_polylog_series(acb_poly_t res, const acb_poly_t s, const acb_t z, slong n, slong prec) { if (n == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, n); if (s->length == 0) { acb_t t; acb_init(t); _acb_poly_polylog_series(res->coeffs, t, 1, z, n, prec); acb_clear(t); } else { _acb_poly_polylog_series(res->coeffs, s->coeffs, s->length, z, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/pow_acb_series.c000066400000000000000000000074451417376376500173170ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" /* (a + bx^c)^g where a = f[0] and b = f[flen-1] */ void _acb_poly_binomial_pow_acb_series(acb_ptr h, acb_srcptr f, slong flen, const acb_t g, slong len, slong prec) { slong i, j, d; acb_t t; acb_init(t); d = flen - 1; acb_pow(h, f, g, prec); acb_div(t, f + d, f, prec); for (i = 1, j = d; j < len; i++, j += d) { acb_sub_ui(h + j, g, i - 1, prec); acb_mul(h + j, h + j, h + j - d, prec); acb_mul(h + j, h + j, t, prec); acb_div_ui(h + j, h + j, i, prec); } if (d > 1) { for (i = 1; i < len; i++) if (i % d != 0) acb_zero(h + i); } acb_clear(t); return; } void _acb_poly_pow_acb_series(acb_ptr h, acb_srcptr f, slong flen, const acb_t g, slong len, slong prec) { int f_binomial, g_exact, g_int; while (flen > 0 && acb_is_zero(f + flen - 1)) flen--; if (flen <= 1) { acb_pow(h, f, g, prec); _acb_vec_zero(h + 1, len - 1); return; } g_exact = acb_is_exact(g); g_int = acb_is_real(g) && arb_is_int(acb_realref(g)); f_binomial = _acb_vec_is_zero(f + 1, flen - 2); /* g = small integer */ if (g_exact && g_int && arf_cmpabs_2exp_si(arb_midref(acb_realref(g)), FLINT_BITS - 1) < 0) { slong e, hlen; e = arf_get_si(arb_midref(acb_realref(g)), ARF_RND_DOWN); hlen = poly_pow_length(flen, FLINT_ABS(e), len); if (e >= 0) { _acb_poly_pow_ui_trunc_binexp(h, f, flen, e, hlen, prec); _acb_vec_zero(h + hlen, len - hlen); return; } else if (!f_binomial) { acb_ptr t; t = _acb_vec_init(hlen); _acb_poly_pow_ui_trunc_binexp(t, f, flen, -e, hlen, prec); _acb_poly_inv_series(h, t, hlen, len, prec); _acb_vec_clear(t, hlen); return; } } /* (a + bx^c)^g */ if (f_binomial) { _acb_poly_binomial_pow_acb_series(h, f, flen, g, len, prec); return; } /* g = +/- 1/2 */ if (g_exact && acb_is_real(g) && arf_cmpabs_2exp_si(arb_midref(acb_realref(g)), -1) == 0) { if (arf_sgn(arb_midref(acb_realref(g))) > 0) _acb_poly_sqrt_series(h, f, flen, len, prec); else _acb_poly_rsqrt_series(h, f, flen, len, prec); return; } /* f^g = exp(g*log(f)) */ _acb_poly_log_series(h, f, flen, len, prec); _acb_vec_scalar_mul(h, h, len, g, prec); _acb_poly_exp_series(h, h, len, len, prec); } void acb_poly_pow_acb_series(acb_poly_t h, const acb_poly_t f, const acb_t g, slong len, slong prec) { slong flen; flen = f->length; flen = FLINT_MIN(flen, len); if (len == 0) { acb_poly_zero(h); return; } if (acb_is_zero(g)) { acb_poly_one(h); return; } if (flen == 0) { acb_poly_zero(h); return; } if (f == h) { acb_poly_t t; acb_poly_init2(t, len); _acb_poly_pow_acb_series(t->coeffs, f->coeffs, flen, g, len, prec); _acb_poly_set_length(t, len); _acb_poly_normalise(t); acb_poly_swap(t, h); acb_poly_clear(t); } else { acb_poly_fit_length(h, len); _acb_poly_pow_acb_series(h->coeffs, f->coeffs, flen, g, len, prec); _acb_poly_set_length(h, len); _acb_poly_normalise(h); } } arb-2.22.1/acb_poly/pow_series.c000066400000000000000000000045221417376376500165030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_pow_series(acb_ptr h, acb_srcptr f, slong flen, acb_srcptr g, slong glen, slong len, slong prec) { if (glen == 1) { _acb_poly_pow_acb_series(h, f, flen, g, len, prec); return; } /* f^g = exp(g * log(f)) */ if (flen == 1) { acb_t t; acb_init(t); acb_log(t, f, prec); _acb_vec_scalar_mul(h, g, glen, t, prec); _acb_poly_exp_series(h, h, glen, len, prec); acb_clear(t); } else { acb_ptr t; t = _acb_vec_init(len); _acb_poly_log_series(t, f, flen, len, prec); _acb_poly_mullow(h, t, len, g, glen, len, prec); _acb_poly_exp_series(h, h, len, len, prec); _acb_vec_clear(t, len); } } void acb_poly_pow_series(acb_poly_t h, const acb_poly_t f, const acb_poly_t g, slong len, slong prec) { slong flen, glen; flen = f->length; glen = g->length; flen = FLINT_MIN(flen, len); glen = FLINT_MIN(glen, len); if (len == 0) { acb_poly_zero(h); return; } if (glen == 0) { acb_poly_one(h); return; } if (flen == 0) { acb_poly_zero(h); return; } if (flen == 1 && glen == 1) { acb_poly_fit_length(h, 1); acb_pow(h->coeffs, f->coeffs, g->coeffs, prec); _acb_poly_set_length(h, 1); _acb_poly_normalise(h); return; } if (f == h || g == h) { acb_poly_t t; acb_poly_init2(t, len); _acb_poly_pow_series(t->coeffs, f->coeffs, flen, g->coeffs, glen, len, prec); _acb_poly_set_length(t, len); _acb_poly_normalise(t); acb_poly_swap(t, h); acb_poly_clear(t); } else { acb_poly_fit_length(h, len); _acb_poly_pow_series(h->coeffs, f->coeffs, flen, g->coeffs, glen, len, prec); _acb_poly_set_length(h, len); _acb_poly_normalise(h); } } arb-2.22.1/acb_poly/pow_ui.c000066400000000000000000000027161417376376500156310ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_pow_ui(acb_ptr res, acb_srcptr f, slong flen, ulong exp, slong prec) { _acb_poly_pow_ui_trunc_binexp(res, f, flen, exp, exp * (flen - 1) + 1, prec); } void acb_poly_pow_ui(acb_poly_t res, const acb_poly_t poly, ulong exp, slong prec) { slong flen, rlen; flen = poly->length; if (exp == 0) { acb_poly_one(res); } else if (flen == 0) { acb_poly_zero(res); } else { rlen = exp * (flen - 1) + 1; if (res != poly) { acb_poly_fit_length(res, rlen); _acb_poly_pow_ui(res->coeffs, poly->coeffs, flen, exp, prec); _acb_poly_set_length(res, rlen); _acb_poly_normalise(res); } else { acb_poly_t t; acb_poly_init2(t, rlen); _acb_poly_pow_ui(t->coeffs, poly->coeffs, flen, exp, prec); _acb_poly_set_length(t, rlen); _acb_poly_normalise(t); acb_poly_swap(res, t); acb_poly_clear(t); } } } arb-2.22.1/acb_poly/pow_ui_trunc_binexp.c000066400000000000000000000063161417376376500204110ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #define MUL(z, zlen, x, xlen, y, ylen, trunc, prec) \ do { \ slong slen = FLINT_MIN(xlen + ylen - 1, trunc); \ _acb_poly_mullow(z, x, xlen, y, ylen, slen, prec); \ zlen = slen; \ } while (0) void _acb_poly_pow_ui_trunc_binexp(acb_ptr res, acb_srcptr f, slong flen, ulong exp, slong len, slong prec) { acb_ptr v, R, S, T; slong rlen; ulong bit; if (exp <= 1) { if (exp == 0) acb_one(res); else if (exp == 1) _acb_vec_set_round(res, f, len, prec); return; } /* (f * x^r)^m = x^(rm) * f^m */ while (flen > 1 && acb_is_zero(f)) { if (((ulong) len) > exp) { _acb_vec_zero(res, exp); len -= exp; res += exp; } else { _acb_vec_zero(res, len); return; } f++; flen--; } if (exp == 2) { _acb_poly_mullow(res, f, flen, f, flen, len, prec); return; } if (flen == 1) { acb_pow_ui(res, f, exp, prec); return; } v = _acb_vec_init(len); bit = UWORD(1) << (FLINT_BIT_COUNT(exp) - 2); if (n_zerobits(exp) % 2) { R = res; S = v; } else { R = v; S = res; } MUL(R, rlen, f, flen, f, flen, len, prec); if (bit & exp) { MUL(S, rlen, R, rlen, f, flen, len, prec); T = R; R = S; S = T; } while (bit >>= 1) { if (bit & exp) { MUL(S, rlen, R, rlen, R, rlen, len, prec); MUL(R, rlen, S, rlen, f, flen, len, prec); } else { MUL(S, rlen, R, rlen, R, rlen, len, prec); T = R; R = S; S = T; } } _acb_vec_clear(v, len); } void acb_poly_pow_ui_trunc_binexp(acb_poly_t res, const acb_poly_t poly, ulong exp, slong len, slong prec) { slong flen, rlen; flen = poly->length; if (exp == 0 && len != 0) { acb_poly_one(res); } else if (flen == 0 || len == 0) { acb_poly_zero(res); } else { rlen = poly_pow_length(flen, exp, len); if (res != poly) { acb_poly_fit_length(res, rlen); _acb_poly_pow_ui_trunc_binexp(res->coeffs, poly->coeffs, flen, exp, rlen, prec); _acb_poly_set_length(res, rlen); _acb_poly_normalise(res); } else { acb_poly_t t; acb_poly_init2(t, rlen); _acb_poly_pow_ui_trunc_binexp(t->coeffs, poly->coeffs, flen, exp, rlen, prec); _acb_poly_set_length(t, rlen); _acb_poly_normalise(t); acb_poly_swap(res, t); acb_poly_clear(t); } } } arb-2.22.1/acb_poly/powsum_one_series_sieved.c000066400000000000000000000011171417376376500214250ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_dirichlet.h" void _acb_poly_powsum_one_series_sieved(acb_ptr z, const acb_t s, slong n, slong len, slong prec) { acb_dirichlet_powsum_sieved(z, s, n, len, prec); } arb-2.22.1/acb_poly/powsum_series_naive.c000066400000000000000000000043111417376376500204060ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_acb_invpow_cpx(acb_ptr res, const acb_t N, const acb_t c, slong trunc, slong prec) { slong i; acb_t logN; acb_init(logN); acb_log(logN, N, prec); acb_mul(res + 0, logN, c, prec); acb_neg(res + 0, res + 0); acb_exp(res + 0, res + 0, prec); for (i = 1; i < trunc; i++) { acb_mul(res + i, res + i - 1, logN, prec); acb_div_si(res + i, res + i, -i, prec); } acb_clear(logN); } void _acb_poly_powsum_series_naive(acb_ptr z, const acb_t s, const acb_t a, const acb_t q, slong n, slong len, slong prec) { slong k, i; int q_one, s_int; acb_t ak, logak, t, qpow, negs; acb_init(ak); acb_init(logak); acb_init(t); acb_init(qpow); acb_init(negs); _acb_vec_zero(z, len); acb_one(qpow); acb_neg(negs, s); q_one = acb_is_one(q); s_int = arb_is_int(acb_realref(s)) && arb_is_zero(acb_imagref(s)); for (k = 0; k < n; k++) { acb_add_ui(ak, a, k, prec); if (len == 1) { acb_pow(t, ak, negs, prec); } else { acb_log(logak, ak, prec); if (s_int) { acb_pow(t, ak, negs, prec); } else { acb_mul(t, logak, negs, prec); acb_exp(t, t, prec); } } if (!q_one) { acb_mul(t, t, qpow, prec); if (k < n - 1) acb_mul(qpow, qpow, q, prec); } acb_add(z, z, t, prec); for (i = 1; i < len; i++) { acb_mul(t, t, logak, prec); acb_div_si(t, t, -i, prec); acb_add(z + i, z + i, t, prec); } } acb_clear(ak); acb_clear(logak); acb_clear(t); acb_clear(qpow); acb_clear(negs); } arb-2.22.1/acb_poly/powsum_series_naive_threaded.c000066400000000000000000000104741417376376500222550ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "acb_poly.h" typedef struct { acb_ptr z; acb_srcptr s; acb_srcptr a; acb_srcptr q; slong n0; slong n1; slong d0; slong len; slong prec; } powsum_arg_t; void * _acb_zeta_powsum_evaluator(void * arg_ptr) { powsum_arg_t arg = *((powsum_arg_t *) arg_ptr); slong i, k; int q_one, s_int; acb_t t, u, v, ak, qpow, negs; arb_t f; acb_init(t); acb_init(u); acb_init(v); acb_init(ak); acb_init(qpow); acb_init(negs); arb_init(f); _acb_vec_zero(arg.z, arg.len); q_one = acb_is_one(arg.q); s_int = arb_is_int(acb_realref(arg.s)) && arb_is_zero(acb_imagref(arg.s)); if (!q_one) acb_pow_ui(qpow, arg.q, arg.n0, arg.prec); acb_neg(negs, arg.s); arb_fac_ui(f, arg.d0, arg.prec); for (k = arg.n0; k < arg.n1; k++) { acb_add_ui(ak, arg.a, k, arg.prec); if (arg.d0 == 0 && arg.len == 1) { /* u = (a+k)^(-s) */ acb_pow(u, ak, negs, arg.prec); } else { /* t = log(a+k) */ acb_log(t, ak, arg.prec); /* u = (a+k)^(-s) */ if (s_int) { acb_pow(u, ak, negs, arg.prec); } else { acb_mul(u, t, negs, arg.prec); acb_exp(u, u, arg.prec); } } /* u = u * q^k */ if (!q_one) { acb_mul(u, u, qpow, arg.prec); if (k < arg.n1 - 1) acb_mul(qpow, qpow, arg.q, arg.prec); } /* forward: u *= (-1)^d * log(a+k)^d / d! */ if (arg.d0 != 0) { acb_pow_ui(v, t, arg.d0, arg.prec); acb_mul(u, u, v, arg.prec); arb_div(acb_realref(u), acb_realref(u), f, arg.prec); arb_div(acb_imagref(u), acb_imagref(u), f, arg.prec); if (arg.d0 % 2) acb_neg(u, u); } acb_add(arg.z, arg.z, u, arg.prec); for (i = 1; i < arg.len; i++) { acb_mul(u, u, t, arg.prec); acb_div_si(u, u, -(arg.d0 + i), arg.prec); acb_add(arg.z + i, arg.z + i, u, arg.prec); } } acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(ak); acb_clear(qpow); acb_clear(negs); arb_clear(f); flint_cleanup(); return NULL; } void _acb_poly_powsum_series_naive_threaded(acb_ptr z, const acb_t s, const acb_t a, const acb_t q, slong n, slong len, slong prec) { pthread_t * threads; powsum_arg_t * args; slong i, num_threads; int split_each_term; num_threads = flint_get_num_threads(); threads = flint_malloc(sizeof(pthread_t) * num_threads); args = flint_malloc(sizeof(powsum_arg_t) * num_threads); split_each_term = (len > 1000); for (i = 0; i < num_threads; i++) { args[i].s = s; args[i].a = a; args[i].q = q; if (split_each_term) { slong n0, n1; n0 = (len * i) / num_threads; n1 = (len * (i + 1)) / num_threads; args[i].z = z + n0; args[i].n0 = 0; args[i].n1 = n; args[i].d0 = n0; args[i].len = n1 - n0; } else { args[i].z = _acb_vec_init(len); args[i].n0 = (n * i) / num_threads; args[i].n1 = (n * (i + 1)) / num_threads; args[i].d0 = 0; args[i].len = len; } args[i].prec = prec; pthread_create(&threads[i], NULL, _acb_zeta_powsum_evaluator, &args[i]); } for (i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); } if (!split_each_term) { _acb_vec_zero(z, len); for (i = 0; i < num_threads; i++) { _acb_vec_add(z, z, args[i].z, len, prec); _acb_vec_clear(args[i].z, len); } } flint_free(threads); flint_free(args); } arb-2.22.1/acb_poly/product_roots.c000066400000000000000000000033731417376376500172350ustar00rootroot00000000000000/* Copyright (C) 2011 William Hart Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_product_roots(acb_ptr poly, acb_srcptr xs, slong n, slong prec) { if (n == 0) { acb_one(poly); } else if (n == 1) { acb_neg(poly, xs); acb_one(poly + 1); } else if (n == 2) { acb_mul(poly, xs + 0, xs + 1, prec); acb_add(poly + 1, xs + 0, xs + 1, prec); acb_neg(poly + 1, poly + 1); acb_one(poly + 2); } else if (n == 3) { acb_mul(poly + 1, xs, xs + 1, prec); acb_mul(poly, poly + 1, xs + 2, prec); acb_neg(poly, poly); acb_add(poly + 2, xs, xs + 1, prec); acb_addmul(poly + 1, poly + 2, xs + 2, prec); acb_add(poly + 2, poly + 2, xs + 2, prec); acb_neg(poly + 2, poly + 2); acb_one(poly + 3); } else { const slong m = (n + 1) / 2; acb_ptr tmp; tmp = _acb_vec_init(n + 2); _acb_poly_product_roots(tmp, xs, m, prec); _acb_poly_product_roots(tmp + m + 1, xs + m, n - m, prec); _acb_poly_mul_monic(poly, tmp, m + 1, tmp + m + 1, n - m + 1, prec); _acb_vec_clear(tmp, n + 2); } } void acb_poly_product_roots(acb_poly_t poly, acb_srcptr xs, slong n, slong prec) { acb_poly_fit_length(poly, n + 1); _acb_poly_product_roots(poly->coeffs, xs, n, prec); _acb_poly_set_length(poly, n + 1); } arb-2.22.1/acb_poly/randtest.c000066400000000000000000000021561417376376500161510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_randtest(acb_poly_t poly, flint_rand_t state, slong len, slong prec, slong mag_bits) { slong i; acb_poly_fit_length(poly, len); if (n_randint(state, 2)) { for (i = 0; i < len; i++) { arb_randtest(acb_realref(poly->coeffs + i), state, prec, mag_bits); arb_randtest(acb_imagref(poly->coeffs + i), state, prec, mag_bits); } } else { for (i = 0; i < len; i++) { arb_randtest_precise(acb_realref(poly->coeffs + i), state, prec, mag_bits); arb_randtest_precise(acb_imagref(poly->coeffs + i), state, prec, mag_bits); } } _acb_poly_set_length(poly, len); _acb_poly_normalise(poly); } arb-2.22.1/acb_poly/refine_roots_durand_kerner.c000066400000000000000000000066561417376376500217370ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" /* we don't need any error bounding, so we define a few helper functions that ignore the radii */ static __inline__ void acb_sub_mid(acb_t z, const acb_t x, const acb_t y, slong prec) { arf_sub(arb_midref(acb_realref(z)), arb_midref(acb_realref(x)), arb_midref(acb_realref(y)), prec, ARF_RND_DOWN); arf_sub(arb_midref(acb_imagref(z)), arb_midref(acb_imagref(x)), arb_midref(acb_imagref(y)), prec, ARF_RND_DOWN); } static __inline__ void acb_add_mid(acb_t z, const acb_t x, const acb_t y, slong prec) { arf_add(arb_midref(acb_realref(z)), arb_midref(acb_realref(x)), arb_midref(acb_realref(y)), prec, ARF_RND_DOWN); arf_add(arb_midref(acb_imagref(z)), arb_midref(acb_imagref(x)), arb_midref(acb_imagref(y)), prec, ARF_RND_DOWN); } static __inline__ void acb_mul_mid(acb_t z, const acb_t x, const acb_t y, slong prec) { #define a arb_midref(acb_realref(x)) #define b arb_midref(acb_imagref(x)) #define c arb_midref(acb_realref(y)) #define d arb_midref(acb_imagref(y)) #define e arb_midref(acb_realref(z)) #define f arb_midref(acb_imagref(z)) arf_complex_mul(e, f, a, b, c, d, prec, ARF_RND_DOWN); #undef a #undef b #undef c #undef d #undef e #undef f } static __inline__ void acb_inv_mid(acb_t z, const acb_t x, slong prec) { arf_t t; arf_init(t); #define a arb_midref(acb_realref(x)) #define b arb_midref(acb_imagref(x)) #define e arb_midref(acb_realref(z)) #define f arb_midref(acb_imagref(z)) arf_mul(t, a, a, prec, ARF_RND_DOWN); arf_addmul(t, b, b, prec, ARF_RND_DOWN); arf_div(e, a, t, prec, ARF_RND_DOWN); arf_div(f, b, t, prec, ARF_RND_DOWN); arf_neg(f, f); #undef a #undef b #undef e #undef f arf_clear(t); } void _acb_poly_evaluate_mid(acb_t res, acb_srcptr f, slong len, const acb_t a, slong prec) { slong i = len - 1; acb_t t; acb_init(t); acb_set(res, f + i); for (i = len - 2; i >= 0; i--) { acb_mul_mid(t, res, a, prec); acb_add_mid(res, f + i, t, prec); } acb_clear(t); } void _acb_poly_refine_roots_durand_kerner(acb_ptr roots, acb_srcptr poly, slong len, slong prec) { slong i, j; acb_t x, y, t; acb_init(x); acb_init(y); acb_init(t); for (i = 0; i < len - 1; i++) { _acb_poly_evaluate_mid(x, poly, len, roots + i, prec); acb_set(y, poly + len - 1); for (j = 0; j < len - 1; j++) { if (i != j) { acb_sub_mid(t, roots + i, roots + j, prec); acb_mul_mid(y, y, t, prec); } } mag_zero(arb_radref(acb_realref(y))); mag_zero(arb_radref(acb_imagref(y))); acb_inv_mid(t, y, prec); acb_mul_mid(t, t, x, prec); acb_sub_mid(roots + i, roots + i, t, prec); arf_get_mag(arb_radref(acb_realref(roots + i)), arb_midref(acb_realref(t))); arf_get_mag(arb_radref(acb_imagref(roots + i)), arb_midref(acb_imagref(t))); } acb_clear(x); acb_clear(y); acb_clear(t); } arb-2.22.1/acb_poly/reverse.c000066400000000000000000000017101417376376500157730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_reverse(acb_ptr res, acb_srcptr poly, slong len, slong n) { if (res == poly) { slong i; for (i = 0; i < n / 2; i++) { acb_struct t = res[i]; res[i] = res[n - 1 - i]; res[n - 1 - i] = t; } for (i = 0; i < n - len; i++) acb_zero(res + i); } else { slong i; for (i = 0; i < n - len; i++) acb_zero(res + i); for (i = 0; i < len; i++) acb_set(res + (n - len) + i, poly + (len - 1) - i); } } arb-2.22.1/acb_poly/revert_series.c000066400000000000000000000026141417376376500172050ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_revert_series(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec) { _acb_poly_revert_series_lagrange_fast(Qinv, Q, Qlen, n, prec); } void acb_poly_revert_series(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !acb_is_zero(Q->coeffs) || acb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (acb_poly_revert_series). Input must \n" "have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { acb_poly_fit_length(Qinv, n); _acb_poly_revert_series(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_revert_series(t->coeffs, Q->coeffs, Qlen, n, prec); acb_poly_swap(Qinv, t); acb_poly_clear(t); } _acb_poly_set_length(Qinv, n); _acb_poly_normalise(Qinv); } arb-2.22.1/acb_poly/revert_series_lagrange.c000066400000000000000000000041141417376376500210420ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_revert_series_lagrange(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec) { slong i; acb_ptr R, S, T, tmp; if (n <= 2) { if (n >= 1) acb_zero(Qinv); if (n == 2) acb_inv(Qinv + 1, Q + 1, prec); return; } R = _acb_vec_init(n - 1); S = _acb_vec_init(n - 1); T = _acb_vec_init(n - 1); acb_zero(Qinv); acb_inv(Qinv + 1, Q + 1, prec); _acb_poly_inv_series(R, Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); _acb_vec_set(S, R, n - 1); for (i = 2; i < n; i++) { _acb_poly_mullow(T, S, n - 1, R, n - 1, n - 1, prec); acb_div_ui(Qinv + i, T + i - 1, i, prec); tmp = S; S = T; T = tmp; } _acb_vec_clear(R, n - 1); _acb_vec_clear(S, n - 1); _acb_vec_clear(T, n - 1); } void acb_poly_revert_series_lagrange(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !acb_is_zero(Q->coeffs) || acb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (acb_poly_revert_series_lagrange). Input must \n" "have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { acb_poly_fit_length(Qinv, n); _acb_poly_revert_series_lagrange(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_revert_series_lagrange(t->coeffs, Q->coeffs, Qlen, n, prec); acb_poly_swap(Qinv, t); acb_poly_clear(t); } _acb_poly_set_length(Qinv, n); _acb_poly_normalise(Qinv); } arb-2.22.1/acb_poly/revert_series_lagrange_fast.c000066400000000000000000000053041417376376500220610ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" /* pointer to (x/Q)^i */ #define Ri(ii) (R + (n-1)*((ii)-1)) void _acb_poly_revert_series_lagrange_fast(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec) { slong i, j, m; acb_ptr R, S, T, tmp; acb_t t; if (n <= 2) { if (n >= 1) acb_zero(Qinv); if (n == 2) acb_inv(Qinv + 1, Q + 1, prec); return; } m = n_sqrt(n); acb_init(t); R = _acb_vec_init((n - 1) * m); S = _acb_vec_init(n - 1); T = _acb_vec_init(n - 1); acb_zero(Qinv); acb_inv(Qinv + 1, Q + 1, prec); _acb_poly_inv_series(Ri(1), Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); for (i = 2; i <= m; i++) _acb_poly_mullow(Ri(i), Ri((i + 1) / 2), n - 1, Ri(i / 2), n - 1, n - 1, prec); for (i = 2; i < m; i++) acb_div_ui(Qinv + i, Ri(i) + i - 1, i, prec); _acb_vec_set(S, Ri(m), n - 1); for (i = m; i < n; i += m) { acb_div_ui(Qinv + i, S + i - 1, i, prec); for (j = 1; j < m && i + j < n; j++) { acb_dot(t, NULL, 0, S, 1, Ri(j) + i + j - 1, -1, i + j, prec); acb_div_ui(Qinv + i + j, t, i + j, prec); } if (i + 1 < n) { _acb_poly_mullow(T, S, n - 1, Ri(m), n - 1, n - 1, prec); tmp = S; S = T; T = tmp; } } acb_clear(t); _acb_vec_clear(R, (n - 1) * m); _acb_vec_clear(S, n - 1); _acb_vec_clear(T, n - 1); } void acb_poly_revert_series_lagrange_fast(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !acb_is_zero(Q->coeffs) || acb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (acb_poly_revert_series_lagrange_fast). Input \n" "must have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { acb_poly_fit_length(Qinv, n); _acb_poly_revert_series_lagrange_fast(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_revert_series_lagrange_fast(t->coeffs, Q->coeffs, Qlen, n, prec); acb_poly_swap(Qinv, t); acb_poly_clear(t); } _acb_poly_set_length(Qinv, n); _acb_poly_normalise(Qinv); } arb-2.22.1/acb_poly/revert_series_newton.c000066400000000000000000000045711417376376500206030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #define CUTOFF 5 void _acb_poly_revert_series_newton(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong n, slong prec) { slong i, k, a[FLINT_BITS]; acb_ptr T, U, V; if (n <= 2) { if (n >= 1) acb_zero(Qinv); if (n == 2) acb_inv(Qinv + 1, Q + 1, prec); return; } T = _acb_vec_init(n); U = _acb_vec_init(n); V = _acb_vec_init(n); k = n; for (i = 1; (WORD(1) << i) < k; i++); a[i = 0] = k; while (k >= CUTOFF) a[++i] = (k = (k + 1) / 2); _acb_poly_revert_series_lagrange(Qinv, Q, Qlen, k, prec); _acb_vec_zero(Qinv + k, n - k); for (i--; i >= 0; i--) { k = a[i]; _acb_poly_compose_series(T, Q, FLINT_MIN(Qlen, k), Qinv, k, k, prec); _acb_poly_derivative(U, T, k, prec); acb_zero(U + k - 1); acb_zero(T + 1); _acb_poly_div_series(V, T, k, U, k, k, prec); _acb_poly_derivative(T, Qinv, k, prec); _acb_poly_mullow(U, V, k, T, k, k, prec); _acb_vec_sub(Qinv, Qinv, U, k, prec); } _acb_vec_clear(T, n); _acb_vec_clear(U, n); _acb_vec_clear(V, n); } void acb_poly_revert_series_newton(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !acb_is_zero(Q->coeffs) || acb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (acb_poly_revert_series_newton). Input must \n" "have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { acb_poly_fit_length(Qinv, n); _acb_poly_revert_series_newton(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { acb_poly_t t; acb_poly_init2(t, n); _acb_poly_revert_series_newton(t->coeffs, Q->coeffs, Qlen, n, prec); acb_poly_swap(Qinv, t); acb_poly_clear(t); } _acb_poly_set_length(Qinv, n); _acb_poly_normalise(Qinv); } arb-2.22.1/acb_poly/rgamma_series.c000066400000000000000000000104361417376376500171430ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t x, int use_reflect, int digamma, slong prec); void _acb_poly_gamma_stirling_eval(acb_ptr res, const acb_t z, slong n, slong num, slong prec); void _acb_poly_rgamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong i, rflen, r, n, wp; acb_ptr t, u, v; acb_struct f[2]; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_rgamma(res, h, prec); _acb_vec_zero(res + 1, len - 1); return; } /* use real code for real input */ if (_acb_vec_is_real(h, hlen)) { arb_ptr tmp = _arb_vec_init(len); for (i = 0; i < hlen; i++) arb_set(tmp + i, acb_realref(h + i)); _arb_poly_rgamma_series(tmp, tmp, hlen, len, prec); for (i = 0; i < len; i++) acb_set_arb(res + i, tmp + i); _arb_vec_clear(tmp, len); return; } wp = prec + FLINT_BIT_COUNT(prec); t = _acb_vec_init(len); u = _acb_vec_init(len); v = _acb_vec_init(len); acb_init(f); acb_init(f + 1); /* otherwise use Stirling series */ acb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 0, wp); /* rgamma(h) = (gamma(1-h+r) sin(pi h)) / (rf(1-h, r) * pi), h = h0 + t*/ if (reflect) { /* u = gamma(r+1-h) */ acb_sub_ui(f, h, r + 1, wp); acb_neg(f, f); _acb_poly_gamma_stirling_eval(t, f, n, len, wp); _acb_poly_exp_series(u, t, len, len, wp); for (i = 1; i < len; i += 2) acb_neg(u + i, u + i); /* v = sin(pi x) */ acb_set(f, h); acb_one(f + 1); _acb_poly_sin_pi_series(v, f, 2, len, wp); _acb_poly_mullow(t, u, len, v, len, len, wp); /* rf(1-h,r) * pi */ if (r == 0) { acb_const_pi(u, wp); _acb_vec_scalar_div(v, t, len, u, wp); } else { acb_sub_ui(f, h, 1, wp); acb_neg(f, f); acb_set_si(f + 1, -1); rflen = FLINT_MIN(len, r + 1); _acb_poly_rising_ui_series(v, f, FLINT_MIN(2, len), r, rflen, wp); acb_const_pi(u, wp); _acb_vec_scalar_mul(v, v, rflen, u, wp); /* divide by rising factorial */ /* TODO: might better to use div_series, when it has a good basecase */ _acb_poly_inv_series(u, v, rflen, len, wp); _acb_poly_mullow(v, t, len, u, len, len, wp); } } else { /* rgamma(h) = rgamma(h+r) rf(h,r) */ if (r == 0) { acb_add_ui(f, h, r, wp); _acb_poly_gamma_stirling_eval(t, f, n, len, wp); _acb_vec_neg(t, t, len); _acb_poly_exp_series(v, t, len, len, wp); } else { acb_set(f, h); acb_one(f + 1); rflen = FLINT_MIN(len, r + 1); _acb_poly_rising_ui_series(t, f, FLINT_MIN(2, len), r, rflen, wp); acb_add_ui(f, h, r, wp); _acb_poly_gamma_stirling_eval(v, f, n, len, wp); _acb_vec_neg(v, v, len); _acb_poly_exp_series(u, v, len, len, wp); _acb_poly_mullow(v, u, len, t, rflen, len, wp); } } /* compose with nonconstant part */ acb_zero(t); _acb_vec_set(t + 1, h + 1, hlen - 1); _acb_poly_compose_series(res, v, len, t, hlen, len, prec); acb_clear(f); acb_clear(f + 1); _acb_vec_clear(t, len); _acb_vec_clear(u, len); _acb_vec_clear(v, len); } void acb_poly_rgamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) { if (f->length == 0 || n == 0) { acb_poly_zero(res); } else { acb_poly_fit_length(res, n); _acb_poly_rgamma_series(res->coeffs, f->coeffs, f->length, n, prec); _acb_poly_set_length(res, n); _acb_poly_normalise(res); } } arb-2.22.1/acb_poly/rising_ui_series.c000066400000000000000000000047351417376376500176740ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" static void _acb_poly_rising_ui_series_bsplit(acb_ptr res, acb_srcptr f, slong flen, ulong a, ulong b, slong trunc, slong prec) { flen = FLINT_MIN(flen, trunc); if (b - a == 1) { acb_add_ui(res, f, a, prec); _acb_vec_set(res + 1, f + 1, flen - 1); } else { acb_ptr L, R; slong len1, len2; slong m = a + (b - a) / 2; len1 = poly_pow_length(flen, m - a, trunc); len2 = poly_pow_length(flen, b - m, trunc); L = _acb_vec_init(len1 + len2); R = L + len1; _acb_poly_rising_ui_series_bsplit(L, f, flen, a, m, trunc, prec); _acb_poly_rising_ui_series_bsplit(R, f, flen, m, b, trunc, prec); _acb_poly_mullow(res, L, len1, R, len2, FLINT_MIN(trunc, len1 + len2 - 1), prec); _acb_vec_clear(L, len1 + len2); } } void _acb_poly_rising_ui_series(acb_ptr res, acb_srcptr f, slong flen, ulong r, slong trunc, slong prec) { if (trunc == 1 || flen == 1) { acb_rising_ui(res, f, r, prec); _acb_vec_zero(res + 1, trunc - 1); } else if (trunc == 2) { acb_rising2_ui(res, res + 1, f, r, prec); acb_mul(res + 1, res + 1, f + 1, prec); } else { _acb_poly_rising_ui_series_bsplit(res, f, flen, 0, r, trunc, prec); } } void acb_poly_rising_ui_series(acb_poly_t res, const acb_poly_t f, ulong r, slong trunc, slong prec) { slong len; if ((f->length == 0 && r != 0) || trunc == 0) { acb_poly_zero(res); return; } if (r == 0) { acb_poly_one(res); return; } len = poly_pow_length(f->length, r, trunc); if (f == res) { acb_poly_t tmp; acb_poly_init(tmp); acb_poly_rising_ui_series(tmp, f, r, len, prec); acb_poly_swap(tmp, res); acb_poly_clear(tmp); } else { acb_poly_fit_length(res, len); _acb_poly_rising_ui_series(res->coeffs, f->coeffs, f->length, r, len, prec); _acb_poly_set_length(res, len); _acb_poly_normalise(res); } } arb-2.22.1/acb_poly/root_bound_fujiwara.c000066400000000000000000000023201417376376500203600ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_root_bound_fujiwara(mag_t bound, acb_srcptr poly, slong len) { mag_t t, u, v; slong i; if (len <= 1) { mag_inf(bound); return; } mag_init(t); mag_init(u); mag_init(v); /* u = 1/leading */ acb_get_mag_lower(t, poly + len - 1); mag_one(u); mag_div(u, u, t); mag_zero(v); for (i = 0; i < len - 1; i++) { acb_get_mag(t, poly + len - 2 - i); mag_mul(t, t, u); if (i == len - 2) mag_mul_2exp_si(t, t, -1); mag_root(t, t, i + 1); mag_max(v, v, t); } mag_mul_2exp_si(bound, v, 1); mag_clear(t); mag_clear(u); mag_clear(v); } void acb_poly_root_bound_fujiwara(mag_t bound, acb_poly_t poly) { _acb_poly_root_bound_fujiwara(bound, poly->coeffs, poly->length); } arb-2.22.1/acb_poly/root_inclusion.c000066400000000000000000000025201417376376500173660ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_root_inclusion(acb_t r, const acb_t m, acb_srcptr poly, acb_srcptr polyder, slong len, slong prec) { acb_t t; arf_t u, v; acb_init(t); arf_init(u); arf_init(v); acb_set(r, m); mag_zero(arb_radref(acb_realref(r))); mag_zero(arb_radref(acb_imagref(r))); _acb_poly_evaluate(t, poly, len, r, prec); acb_get_abs_ubound_arf(u, t, MAG_BITS); /* it could happen that we have an exact root, in which case we should avoid dividing by the derivative */ if (!arf_is_zero(u)) { _acb_poly_evaluate(t, polyder, len - 1, r, prec); acb_inv(t, t, MAG_BITS); acb_get_abs_ubound_arf(v, t, MAG_BITS); arf_mul(u, u, v, MAG_BITS, ARF_RND_UP); arf_mul_ui(u, u, len - 1, MAG_BITS, ARF_RND_UP); } arf_get_mag(arb_radref(acb_realref(r)), u); arf_get_mag(arb_radref(acb_imagref(r)), u); arf_clear(u); arf_clear(v); acb_clear(t); } arb-2.22.1/acb_poly/rsqrt_series.c000066400000000000000000000044751417376376500170600ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_rsqrt_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); while (hlen > 0 && acb_is_zero(h + hlen - 1)) hlen--; if (hlen <= 1) { acb_rsqrt(g, h, prec); _acb_vec_zero(g + 1, len - 1); } else if (len == 2) { acb_rsqrt(g, h, prec); acb_div(g + 1, h + 1, h, prec); acb_mul(g + 1, g + 1, g, prec); acb_mul_2exp_si(g + 1, g + 1, -1); acb_neg(g + 1, g + 1); } else if (_acb_vec_is_zero(h + 1, hlen - 2)) { acb_t t; acb_init(t); arf_set_si_2exp_si(arb_midref(acb_realref(t)), -1, -1); _acb_poly_binomial_pow_acb_series(g, h, hlen, t, len, prec); acb_clear(t); } else { acb_ptr t, u; slong tlen; t = _acb_vec_init(2 * len); u = t + len; acb_rsqrt(g, h, prec); NEWTON_INIT(1, len) NEWTON_LOOP(m, n) tlen = FLINT_MIN(2 * m - 1, n); _acb_poly_mullow(t, g, m, g, m, tlen, prec); _acb_poly_mullow(u, g, m, t, tlen, n, prec); _acb_poly_mullow(t, u, n, h, hlen, n, prec); _acb_vec_scalar_mul_2exp_si(g + m, t + m, n - m, -1); _acb_vec_neg(g + m, g + m, n - m); NEWTON_END_LOOP NEWTON_END _acb_vec_clear(t, 2 * len); } } void acb_poly_rsqrt_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { if (n == 0) { acb_poly_zero(g); return; } if (g == h) { acb_poly_t t; acb_poly_init(t); acb_poly_rsqrt_series(t, h, n, prec); acb_poly_swap(g, t); acb_poly_clear(t); return; } acb_poly_fit_length(g, n); if (h->length == 0) _acb_vec_indeterminate(g->coeffs, n); else _acb_poly_rsqrt_series(g->coeffs, h->coeffs, h->length, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/set.c000066400000000000000000000011631417376376500151150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set(acb_poly_t dest, const acb_poly_t src) { slong len = acb_poly_length(src); acb_poly_fit_length(dest, len); _acb_vec_set(dest->coeffs, src->coeffs, len); _acb_poly_set_length(dest, len); } arb-2.22.1/acb_poly/set2_arb_poly.c000066400000000000000000000025741417376376500170750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_arb_poly(acb_poly_t poly, const arb_poly_t re) { slong i, len; len = arb_poly_length(re); acb_poly_fit_length(poly, len); for (i = 0; i < len; i++) { arb_set(acb_realref(poly->coeffs + i), re->coeffs + i); arb_zero(acb_imagref(poly->coeffs + i)); } _acb_poly_set_length(poly, len); } void acb_poly_set2_arb_poly(acb_poly_t poly, const arb_poly_t re, const arb_poly_t im) { slong i, rlen, ilen, len; rlen = arb_poly_length(re); ilen = arb_poly_length(im); len = FLINT_MAX(rlen, ilen); acb_poly_fit_length(poly, len); for (i = 0; i < rlen; i++) arb_set(acb_realref(poly->coeffs + i), re->coeffs + i); for (i = rlen; i < len; i++) arb_zero(acb_realref(poly->coeffs + i)); for (i = 0; i < ilen; i++) arb_set(acb_imagref(poly->coeffs + i), im->coeffs + i); for (i = ilen; i < len; i++) arb_zero(acb_imagref(poly->coeffs + i)); _acb_poly_set_length(poly, len); } arb-2.22.1/acb_poly/set2_fmpq_poly.c000066400000000000000000000017111417376376500172640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_fmpq_poly(acb_poly_t poly, const fmpq_poly_t re, slong prec) { arb_poly_t t; arb_poly_init(t); arb_poly_set_fmpq_poly(t, re, prec); acb_poly_set_arb_poly(poly, t); arb_poly_clear(t); } void acb_poly_set2_fmpq_poly(acb_poly_t poly, const fmpq_poly_t re, const fmpq_poly_t im, slong prec) { arb_poly_t t, u; arb_poly_init(t); arb_poly_init(u); arb_poly_set_fmpq_poly(t, re, prec); arb_poly_set_fmpq_poly(u, im, prec); acb_poly_set2_arb_poly(poly, t, u); arb_poly_clear(t); arb_poly_clear(u); } arb-2.22.1/acb_poly/set2_fmpz_poly.c000066400000000000000000000013511417376376500172750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set2_fmpz_poly(acb_poly_t poly, const fmpz_poly_t re, const fmpz_poly_t im, slong prec) { arb_poly_t t, u; arb_poly_init(t); arb_poly_init(u); arb_poly_set_fmpz_poly(t, re, prec); arb_poly_set_fmpz_poly(u, im, prec); acb_poly_set2_arb_poly(poly, t, u); arb_poly_clear(t); arb_poly_clear(u); } arb-2.22.1/acb_poly/set_coeff_acb.c000066400000000000000000000013241417376376500170630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_coeff_acb(acb_poly_t poly, slong n, const acb_t x) { acb_poly_fit_length(poly, n + 1); if (n + 1 > poly->length) { _acb_vec_zero(poly->coeffs + poly->length, n - poly->length); poly->length = n + 1; } acb_set(poly->coeffs + n, x); _acb_poly_normalise(poly); } arb-2.22.1/acb_poly/set_coeff_si.c000066400000000000000000000013201417376376500167450ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_coeff_si(acb_poly_t poly, slong n, slong x) { acb_poly_fit_length(poly, n + 1); if (n + 1 > poly->length) { _acb_vec_zero(poly->coeffs + poly->length, n - poly->length); poly->length = n + 1; } acb_set_si(poly->coeffs + n, x); _acb_poly_normalise(poly); } arb-2.22.1/acb_poly/set_fmpz_poly.c000066400000000000000000000012771417376376500172220ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_fmpz_poly(acb_poly_t poly, const fmpz_poly_t src, slong prec) { slong i, len = fmpz_poly_length(src); acb_poly_fit_length(poly, len); _acb_poly_set_length(poly, len); for (i = 0; i < len; i++) acb_set_round_fmpz(poly->coeffs + i, src->coeffs + i, prec); } arb-2.22.1/acb_poly/set_length.c000066400000000000000000000011611417376376500164540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_set_length(acb_poly_t poly, slong len) { slong i; if (poly->length > len) { for (i = len; i < poly->length; i++) acb_zero(poly->coeffs + i); } poly->length = len; } arb-2.22.1/acb_poly/set_round.c000066400000000000000000000012211417376376500163170ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_round(acb_poly_t dest, const acb_poly_t src, slong prec) { slong len = acb_poly_length(src); acb_poly_fit_length(dest, len); _acb_vec_set_round(dest->coeffs, src->coeffs, len, prec); _acb_poly_set_length(dest, len); } arb-2.22.1/acb_poly/set_si.c000066400000000000000000000012071417376376500156070ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_si(acb_poly_t poly, slong c) { if (c == 0) { acb_poly_zero(poly); } else { acb_poly_fit_length(poly, 1); acb_set_si(poly->coeffs, c); _acb_poly_set_length(poly, 1); } } arb-2.22.1/acb_poly/set_trunc.c000066400000000000000000000015301417376376500163260ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_trunc(acb_poly_t res, const acb_poly_t poly, slong n) { if (poly == res) { acb_poly_truncate(res, n); } else { slong rlen; rlen = FLINT_MIN(n, poly->length); while (rlen > 0 && acb_is_zero(poly->coeffs + rlen - 1)) rlen--; acb_poly_fit_length(res, rlen); _acb_vec_set(res->coeffs, poly->coeffs, rlen); _acb_poly_set_length(res, rlen); } } arb-2.22.1/acb_poly/set_trunc_round.c000066400000000000000000000016771417376376500175510ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_set_trunc_round(acb_poly_t res, const acb_poly_t poly, slong n, slong prec) { if (poly == res) { acb_poly_truncate(res, n); _acb_vec_set_round(res->coeffs, res->coeffs, res->length, prec); } else { slong rlen; rlen = FLINT_MIN(n, poly->length); while (rlen > 0 && acb_is_zero(poly->coeffs + rlen - 1)) rlen--; acb_poly_fit_length(res, rlen); _acb_vec_set_round(res->coeffs, poly->coeffs, rlen, prec); _acb_poly_set_length(res, rlen); } } arb-2.22.1/acb_poly/shift_left.c000066400000000000000000000024441417376376500164540ustar00rootroot00000000000000/* Copyright (C) 2008, 2009 William Hart Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_shift_left(acb_ptr res, acb_srcptr poly, slong len, slong n) { slong i; /* Copy in reverse to avoid writing over unshifted coefficients */ if (res != poly) { for (i = len; i--; ) acb_set(res + n + i, poly + i); } else { for (i = len; i--; ) acb_swap(res + n + i, res + i); } for (i = 0; i < n; i++) acb_zero(res + i); } void acb_poly_shift_left(acb_poly_t res, const acb_poly_t poly, slong n) { if (n == 0) { acb_poly_set(res, poly); return; } if (poly->length == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, poly->length + n); _acb_poly_shift_left(res->coeffs, poly->coeffs, poly->length, n); _acb_poly_set_length(res, poly->length + n); } arb-2.22.1/acb_poly/shift_right.c000066400000000000000000000024101417376376500166300ustar00rootroot00000000000000/* Copyright (C) 2008, 2009 William Hart Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_shift_right(acb_ptr res, acb_srcptr poly, slong len, slong n) { slong i; /* Copy in forward order to avoid writing over unshifted coefficients */ if (res != poly) { for (i = 0; i < len - n; i++) acb_set(res + i, poly + n + i); } else { for (i = 0; i < len - n; i++) acb_swap(res + i, res + n + i); } } void acb_poly_shift_right(acb_poly_t res, const acb_poly_t poly, slong n) { if (n == 0) { acb_poly_set(res, poly); return; } if (poly->length <= n) { acb_poly_zero(res); return; } acb_poly_fit_length(res, poly->length - n); _acb_poly_shift_right(res->coeffs, poly->coeffs, poly->length, n); _acb_poly_set_length(res, poly->length - n); } arb-2.22.1/acb_poly/sin_cos_pi_series.c000066400000000000000000000040331417376376500200200ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sin_cos_pi_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sin_cos_pi(s, c, h, prec); _acb_vec_zero(s + 1, n - 1); _acb_vec_zero(c + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_const_pi(t, prec); acb_mul(t, t, h + 1, prec); acb_sin_cos_pi(s, c, h, prec); acb_mul(s + 1, c, t, prec); acb_neg(t, t); acb_mul(c + 1, s, t, prec); acb_clear(t); } else { slong cutoff; if (prec <= 128) { cutoff = 1400; } else { cutoff = 100000 / pow(log(prec), 3); cutoff = FLINT_MIN(cutoff, 700); } if (hlen < cutoff) _acb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 1); else _acb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 1); } } void acb_poly_sin_cos_pi_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(s); acb_poly_zero(c); return; } if (hlen == 0) { acb_poly_zero(s); acb_poly_one(c); return; } if (hlen == 1) n = 1; acb_poly_fit_length(s, n); acb_poly_fit_length(c, n); _acb_poly_sin_cos_pi_series(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(s, n); _acb_poly_normalise(s); _acb_poly_set_length(c, n); _acb_poly_normalise(c); } arb-2.22.1/acb_poly/sin_cos_series.c000066400000000000000000000037451417376376500173410ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sin_cos_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sin_cos(s, c, h, prec); _acb_vec_zero(s + 1, n - 1); _acb_vec_zero(c + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_set(t, h + 1); acb_sin_cos(s, c, h, prec); acb_mul(s + 1, c, t, prec); acb_neg(t, t); acb_mul(c + 1, s, t, prec); acb_clear(t); } else { slong cutoff; if (prec <= 128) { cutoff = 1400; } else { cutoff = 100000 / pow(log(prec), 3); cutoff = FLINT_MIN(cutoff, 700); } if (hlen < cutoff) _acb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 0); else _acb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 0); } } void acb_poly_sin_cos_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(s); acb_poly_zero(c); return; } if (hlen == 0) { acb_poly_zero(s); acb_poly_one(c); return; } if (hlen == 1) n = 1; acb_poly_fit_length(s, n); acb_poly_fit_length(c, n); _acb_poly_sin_cos_series(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(s, n); _acb_poly_normalise(s); _acb_poly_set_length(c, n); _acb_poly_normalise(c); } arb-2.22.1/acb_poly/sin_cos_series_basecase.c000066400000000000000000000040471417376376500211630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sin_cos_series_basecase(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec, int times_pi) { slong k, alen = FLINT_MIN(n, hlen); acb_ptr a; acb_t t, u; if (times_pi) acb_sin_cos_pi(s, c, h, prec); else acb_sin_cos(s, c, h, prec); if (hlen == 1) { _acb_vec_zero(s + 1, n - 1); _acb_vec_zero(c + 1, n - 1); return; } acb_init(t); acb_init(u); a = _acb_vec_init(alen); for (k = 1; k < alen; k++) acb_mul_ui(a + k, h + k, k, prec); if (times_pi) { acb_const_pi(t, prec); _acb_vec_scalar_mul(a + 1, a + 1, alen - 1, t, prec); } for (k = 1; k < n; k++) { acb_dot(t, NULL, 1, a + 1, 1, s + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); acb_dot(u, NULL, 0, a + 1, 1, c + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); acb_div_ui(c + k, t, k, prec); acb_div_ui(s + k, u, k, prec); } acb_clear(t); acb_clear(u); _acb_vec_clear(a, alen); } void acb_poly_sin_cos_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec, int times_pi) { slong hlen = h->length; if (n == 0) { acb_poly_zero(s); acb_poly_zero(c); return; } if (hlen == 0) { acb_poly_zero(s); acb_poly_one(c); return; } acb_poly_fit_length(s, n); acb_poly_fit_length(c, n); _acb_poly_sin_cos_series_basecase(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec, times_pi); _acb_poly_set_length(s, n); _acb_poly_normalise(s); _acb_poly_set_length(c, n); _acb_poly_normalise(c); } arb-2.22.1/acb_poly/sin_cos_series_tangent.c000066400000000000000000000060101417376376500210450ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sin_cos_series_tangent(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong len, slong prec, int times_pi) { acb_ptr t, u, v; acb_t s0, c0; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { if (times_pi) acb_sin_cos_pi(s, c, h, prec); else acb_sin_cos(s, c, h, prec); _acb_vec_zero(s + 1, len - 1); _acb_vec_zero(c + 1, len - 1); return; } /* sin(x) = 2*tan(x/2)/(1+tan(x/2)^2) cos(x) = (1-tan(x/2)^2)/(1+tan(x/2)^2) */ acb_init(s0); acb_init(c0); t = _acb_vec_init(3 * len); u = t + len; v = u + len; /* sin, cos of h0 */ if (times_pi) acb_sin_cos_pi(s0, c0, h, prec); else acb_sin_cos(s0, c0, h, prec); /* t = tan((h-h0)/2) */ acb_zero(u); _acb_vec_scalar_mul_2exp_si(u + 1, h + 1, hlen - 1, -1); if (times_pi) { acb_const_pi(t, prec); _acb_vec_scalar_mul(u + 1, u + 1, hlen - 1, t, prec); } _acb_poly_tan_series(t, u, hlen, len, prec); /* v = 1 + t^2 */ _acb_poly_mullow(v, t, len, t, len, len, prec); acb_add_ui(v, v, 1, prec); /* u = 1/(1+t^2) */ _acb_poly_inv_series(u, v, len, len, prec); /* sine */ _acb_poly_mullow(s, t, len, u, len, len, prec); _acb_vec_scalar_mul_2exp_si(s, s, len, 1); /* cosine */ acb_sub_ui(v, v, 2, prec); _acb_vec_neg(v, v, len); _acb_poly_mullow(c, v, len, u, len, len, prec); /* sin(h0 + h1) = cos(h0) sin(h1) + sin(h0) cos(h1) cos(h0 + h1) = cos(h0) cos(h1) - sin(h0) sin(h1) */ if (!acb_is_zero(s0)) { _acb_vec_scalar_mul(t, s, len, c0, prec); _acb_vec_scalar_mul(u, c, len, s0, prec); _acb_vec_scalar_mul(v, s, len, s0, prec); _acb_vec_add(s, t, u, len, prec); _acb_vec_scalar_mul(t, c, len, c0, prec); _acb_vec_sub(c, t, v, len, prec); } _acb_vec_clear(t, 3 * len); acb_clear(s0); acb_clear(c0); } void acb_poly_sin_cos_series_tangent(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec, int times_pi) { slong hlen = h->length; if (n == 0) { acb_poly_zero(s); acb_poly_zero(c); return; } if (hlen == 0) { acb_poly_zero(s); acb_poly_one(c); return; } acb_poly_fit_length(s, n); acb_poly_fit_length(c, n); _acb_poly_sin_cos_series_tangent(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec, times_pi); _acb_poly_set_length(s, n); _acb_poly_normalise(s); _acb_poly_set_length(c, n); _acb_poly_normalise(c); } arb-2.22.1/acb_poly/sin_pi_series.c000066400000000000000000000026411417376376500171570ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sin_pi_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sin_pi(g, h, prec); _acb_vec_zero(g + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_sin_cos_pi(g, t, h, prec); acb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ acb_const_pi(t, prec); acb_mul(g + 1, g + 1, t, prec); acb_clear(t); } else { acb_ptr t = _acb_vec_init(n); _acb_poly_sin_cos_pi_series(g, t, h, hlen, n, prec); _acb_vec_clear(t, n); } } void acb_poly_sin_pi_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { acb_poly_zero(g); return; } if (hlen == 1) n = 1; acb_poly_fit_length(g, n); _acb_poly_sin_pi_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/sin_series.c000066400000000000000000000025101417376376500164620ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sin_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sin(g, h, prec); _acb_vec_zero(g + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_sin_cos(g, t, h, prec); acb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ acb_clear(t); } else { acb_ptr t = _acb_vec_init(n); _acb_poly_sin_cos_series(g, t, h, hlen, n, prec); _acb_vec_clear(t, n); } } void acb_poly_sin_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { acb_poly_zero(g); return; } if (hlen == 1) n = 1; acb_poly_fit_length(g, n); _acb_poly_sin_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/sinc_series.c000066400000000000000000000031201417376376500166230ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sinc_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sinc(g, h, prec); _acb_vec_zero(g + 1, n - 1); } else { acb_ptr t, u; t = _acb_vec_init(n + 1); u = _acb_vec_init(hlen); _acb_vec_set(u, h, hlen); if (acb_is_zero(h)) { _acb_poly_sin_series(t, u, hlen, n + 1, prec); _acb_poly_div_series(g, t + 1, n, u + 1, hlen - 1, n, prec); } else { _acb_poly_sin_series(t, u, hlen, n, prec); _acb_poly_div_series(g, t, n, u, hlen, n, prec); } _acb_vec_clear(t, n + 1); _acb_vec_clear(u, hlen); } } void acb_poly_sinc_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(g); return; } if (hlen == 0) { acb_poly_one(g); return; } if (hlen == 1) n = 1; acb_poly_fit_length(g, n); _acb_poly_sinc_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/sinh_cosh_series.c000066400000000000000000000036021417376376500176510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sinh_cosh_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sinh_cosh(s, c, h, prec); _acb_vec_zero(s + 1, n - 1); _acb_vec_zero(c + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_set(t, h + 1); acb_sinh_cosh(s, c, h, prec); acb_mul(s + 1, c, t, prec); acb_mul(c + 1, s, t, prec); acb_clear(t); } else { slong cutoff; if (prec <= 128) cutoff = 400; else cutoff = 30000 / pow(log(prec), 3); if (hlen < cutoff) _acb_poly_sinh_cosh_series_basecase(s, c, h, hlen, n, prec); else _acb_poly_sinh_cosh_series_exponential(s, c, h, hlen, n, prec); } } void acb_poly_sinh_cosh_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(s); acb_poly_zero(c); return; } if (hlen == 0) { acb_poly_zero(s); acb_poly_one(c); return; } if (hlen == 1) n = 1; acb_poly_fit_length(s, n); acb_poly_fit_length(c, n); _acb_poly_sinh_cosh_series(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(s, n); _acb_poly_normalise(s); _acb_poly_set_length(c, n); _acb_poly_normalise(c); } arb-2.22.1/acb_poly/sinh_cosh_series_basecase.c000066400000000000000000000035071417376376500215030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sinh_cosh_series_basecase(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) { slong k, alen = FLINT_MIN(n, hlen); acb_ptr a; acb_t t, u; acb_sinh_cosh(s, c, h, prec); if (hlen == 1) { _acb_vec_zero(s + 1, n - 1); _acb_vec_zero(c + 1, n - 1); return; } acb_init(t); acb_init(u); a = _acb_vec_init(alen); for (k = 1; k < alen; k++) acb_mul_ui(a + k, h + k, k, prec); for (k = 1; k < n; k++) { acb_dot(t, NULL, 0, a + 1, 1, s + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); acb_dot(u, NULL, 0, a + 1, 1, c + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); acb_div_ui(c + k, t, k, prec); acb_div_ui(s + k, u, k, prec); } acb_clear(t); acb_clear(u); _acb_vec_clear(a, alen); } void acb_poly_sinh_cosh_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(s); acb_poly_zero(c); return; } if (hlen == 0) { acb_poly_zero(s); acb_poly_one(c); return; } acb_poly_fit_length(s, n); acb_poly_fit_length(c, n); _acb_poly_sinh_cosh_series_basecase(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(s, n); _acb_poly_normalise(s); _acb_poly_set_length(c, n); _acb_poly_normalise(c); } arb-2.22.1/acb_poly/sinh_cosh_series_exponential.c000066400000000000000000000050031417376376500222540ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sinh_cosh_series_exponential(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong len, slong prec) { acb_ptr t, u, v; acb_t s0, c0; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_sinh_cosh(s, c, h, prec); _acb_vec_zero(s + 1, len - 1); _acb_vec_zero(c + 1, len - 1); return; } acb_init(s0); acb_init(c0); t = _acb_vec_init(3 * len); u = t + len; v = u + len; acb_sinh_cosh(s0, c0, h, prec); _acb_vec_set(t + 1, h + 1, hlen - 1); _acb_poly_exp_series(t, t, len, len, prec); /* todo: part of the inverse could be avoided since exp computes it internally to half the length */ _acb_poly_inv_series(u, t, len, len, prec); /* hyperbolic sine */ _acb_vec_sub(s, t, u, len, prec); _acb_vec_scalar_mul_2exp_si(s, s, len, -1); /* hyperbolic cosine */ _acb_vec_add(c, t, u, len, prec); _acb_vec_scalar_mul_2exp_si(c, c, len, -1); /* sinh(h0 + h1) = cosh(h0) sinh(h1) + sinh(h0) cosh(h1) cosh(h0 + h1) = cosh(h0) cosh(h1) + sinh(h0) sinh(h1) */ if (!acb_is_zero(s0)) { _acb_vec_scalar_mul(t, s, len, c0, prec); _acb_vec_scalar_mul(u, c, len, s0, prec); _acb_vec_scalar_mul(v, s, len, s0, prec); _acb_vec_add(s, t, u, len, prec); _acb_vec_scalar_mul(t, c, len, c0, prec); _acb_vec_add(c, t, v, len, prec); } _acb_vec_clear(t, 3 * len); acb_clear(s0); acb_clear(c0); } void acb_poly_sinh_cosh_series_exponential(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { acb_poly_zero(s); acb_poly_zero(c); return; } if (hlen == 0) { acb_poly_zero(s); acb_poly_one(c); return; } acb_poly_fit_length(s, n); acb_poly_fit_length(c, n); _acb_poly_sinh_cosh_series_exponential(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(s, n); _acb_poly_normalise(s); _acb_poly_set_length(c, n); _acb_poly_normalise(c); } arb-2.22.1/acb_poly/sinh_series.c000066400000000000000000000025201417376376500166330ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sinh_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sinh(g, h, prec); _acb_vec_zero(g + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_sinh_cosh(g, t, h, prec); acb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ acb_clear(t); } else { acb_ptr t = _acb_vec_init(n); _acb_poly_sinh_cosh_series(g, t, h, hlen, n, prec); _acb_vec_clear(t, n); } } void acb_poly_sinh_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { acb_poly_zero(g); return; } if (hlen == 1) n = 1; acb_poly_fit_length(g, n); _acb_poly_sinh_series(g->coeffs, h->coeffs, hlen, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/sqrt_series.c000066400000000000000000000036361417376376500166740ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sqrt_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); while (hlen > 0 && acb_is_zero(h + hlen - 1)) hlen--; if (hlen <= 1) { acb_sqrt(g, h, prec); _acb_vec_zero(g + 1, len - 1); } else if (len == 2) { acb_sqrt(g, h, prec); acb_div(g + 1, h + 1, h, prec); acb_mul(g + 1, g + 1, g, prec); acb_mul_2exp_si(g + 1, g + 1, -1); } else if (_acb_vec_is_zero(h + 1, hlen - 2)) { acb_t t; acb_init(t); arf_set_si_2exp_si(arb_midref(acb_realref(t)), 1, -1); _acb_poly_binomial_pow_acb_series(g, h, hlen, t, len, prec); acb_clear(t); } else { acb_ptr t; t = _acb_vec_init(len); _acb_poly_rsqrt_series(t, h, hlen, len, prec); _acb_poly_mullow(g, t, len, h, hlen, len, prec); _acb_vec_clear(t, len); } } void acb_poly_sqrt_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { if (n == 0) { acb_poly_zero(g); return; } if (g == h) { acb_poly_t t; acb_poly_init(t); acb_poly_sqrt_series(t, h, n, prec); acb_poly_swap(g, t); acb_poly_clear(t); return; } acb_poly_fit_length(g, n); if (h->length == 0) _acb_vec_indeterminate(g->coeffs, n); else _acb_poly_sqrt_series(g->coeffs, h->coeffs, h->length, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/sub.c000066400000000000000000000022601417376376500151120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_sub(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) { slong i, min = FLINT_MIN(len1, len2); for (i = 0; i < min; i++) acb_sub(res + i, poly1 + i, poly2 + i, prec); for (i = min; i < len1; i++) acb_set_round(res + i, poly1 + i, prec); for (i = min; i < len2; i++) acb_neg_round(res + i, poly2 + i, prec); } void acb_poly_sub(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) { slong max = FLINT_MAX(poly1->length, poly2->length); acb_poly_fit_length(res, max); _acb_poly_sub(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); _acb_poly_set_length(res, max); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/sub_series.c000066400000000000000000000015731417376376500164720ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void acb_poly_sub_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong len, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; len1 = FLINT_MIN(len1, len); len2 = FLINT_MIN(len2, len); len = FLINT_MAX(len1, len2); acb_poly_fit_length(res, len); _acb_poly_sub(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); _acb_poly_set_length(res, len); _acb_poly_normalise(res); } arb-2.22.1/acb_poly/tan_series.c000066400000000000000000000041611417376376500164570ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #define TAN_NEWTON_CUTOFF 20 void _acb_poly_tan_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_tan(g, h, prec); _acb_vec_zero(g + 1, len - 1); } else if (len == 2) { acb_t t; acb_init(t); acb_tan(g, h, prec); acb_mul(t, g, g, prec); acb_add_ui(t, t, 1, prec); acb_mul(g + 1, t, h + 1, prec); /* safe since hlen >= 2 */ acb_clear(t); } else { acb_ptr t, u; t = _acb_vec_init(2 * len); u = t + len; NEWTON_INIT(TAN_NEWTON_CUTOFF, len) NEWTON_BASECASE(n) _acb_poly_sin_cos_series_basecase(t, u, h, hlen, n, prec, 0); _acb_poly_div_series(g, t, n, u, n, n, prec); NEWTON_END_BASECASE NEWTON_LOOP(m, n) _acb_poly_mullow(u, g, m, g, m, n, prec); acb_add_ui(u, u, 1, prec); _acb_poly_atan_series(t, g, m, n, prec); _acb_poly_sub(t + m, h + m, FLINT_MAX(0, hlen - m), t + m, n - m, prec); _acb_poly_mullow(g + m, u, n, t + m, n - m, n - m, prec); NEWTON_END_LOOP NEWTON_END _acb_vec_clear(t, 2 * len); } } void acb_poly_tan_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) { if (h->length == 0 || n == 0) { acb_poly_zero(g); return; } if (g == h) { acb_poly_t t; acb_poly_init(t); acb_poly_tan_series(t, h, n, prec); acb_poly_swap(g, t); acb_poly_clear(t); return; } acb_poly_fit_length(g, n); _acb_poly_tan_series(g->coeffs, h->coeffs, h->length, n, prec); _acb_poly_set_length(g, n); _acb_poly_normalise(g); } arb-2.22.1/acb_poly/taylor_shift.c000066400000000000000000000021001417376376500170210ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_taylor_shift(acb_ptr poly, const acb_t c, slong n, slong prec) { if (n <= 30 || (n <= 500 && acb_bits(c) == 1 && n < 30 + 3 * sqrt(prec)) || (n <= 100 && acb_bits(c) < 0.01 * prec)) { _acb_poly_taylor_shift_horner(poly, c, n, prec); } else if (prec > 2 * n) { _acb_poly_taylor_shift_convolution(poly, c, n, prec); } else { _acb_poly_taylor_shift_divconquer(poly, c, n, prec); } } void acb_poly_taylor_shift(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) { if (f != g) acb_poly_set_round(g, f, prec); _acb_poly_taylor_shift(g->coeffs, c, g->length, prec); } arb-2.22.1/acb_poly/taylor_shift_convolution.c000066400000000000000000000040051417376376500214660ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_taylor_shift_convolution(acb_ptr p, const acb_t c, slong len, slong prec) { slong i, n = len - 1; acb_t d; arb_t f; acb_ptr t, u; if (acb_is_zero(c) || len <= 1) return; t = _acb_vec_init(len); u = _acb_vec_init(len); arb_init(f); acb_init(d); arb_one(f); for (i = 2; i <= n; i++) { arb_mul_ui(f, f, i, prec); acb_mul_arb(p + i, p + i, f, prec); } _acb_poly_reverse(p, p, len, len); acb_one(t + n); for (i = n; i > 0; i--) acb_mul_ui(t + i - 1, t + i, i, prec); if (acb_equal_si(c, -1)) { for (i = 1; i <= n; i += 2) acb_neg(t + i, t + i); } else if (!acb_is_one(c)) { acb_set(d, c); for (i = 1; i <= n; i++) { acb_mul(t + i, t + i, d, prec); acb_mul(d, d, c, prec); } } _acb_poly_mullow(u, p, len, t, len, len, prec); arb_mul(f, f, f, prec); if (arb_bits(f) > 0.25 * prec) { arb_inv(f, f, prec); } else { for (i = 0; i <= n; i++) acb_div_arb(u + i, u + i, f, prec); arb_one(f); } for (i = n; i >= 0; i--) { acb_mul_arb(p + i, u + n - i, f, prec); arb_mul_ui(f, f, (i == 0) ? 1 : i, prec); } _acb_vec_clear(t, len); _acb_vec_clear(u, len); arb_clear(f); acb_clear(d); } void acb_poly_taylor_shift_convolution(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) { if (f != g) acb_poly_set_round(g, f, prec); _acb_poly_taylor_shift_convolution(g->coeffs, c, g->length, prec); } arb-2.22.1/acb_poly/taylor_shift_divconquer.c000066400000000000000000000020241417376376500212650ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_taylor_shift_divconquer(acb_ptr poly, const acb_t c, slong len, slong prec) { acb_struct d[2]; if (len <= 1 || acb_is_zero(c)) return; if (len == 2) { acb_addmul(poly, poly + 1, c, prec); return; } d[0] = *c; acb_init(d + 1); acb_one(d + 1); /* no need to free */ _acb_poly_compose_divconquer(poly, poly, len, d, 2, prec); } void acb_poly_taylor_shift_divconquer(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) { if (f != g) acb_poly_set_round(g, f, prec); _acb_poly_taylor_shift_divconquer(g->coeffs, c, g->length, prec); } arb-2.22.1/acb_poly/taylor_shift_horner.c000066400000000000000000000024021417376376500204030ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" void _acb_poly_taylor_shift_horner(acb_ptr poly, const acb_t c, slong n, slong prec) { slong i, j; if (acb_is_one(c)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) acb_add(poly + j, poly + j, poly + j + 1, prec); } else if (acb_equal_si(c, -1)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) acb_sub(poly + j, poly + j, poly + j + 1, prec); } else if (!acb_is_zero(c)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) acb_addmul(poly + j, poly + j + 1, c, prec); } } void acb_poly_taylor_shift_horner(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) { if (f != g) acb_poly_set_round(g, f, prec); _acb_poly_taylor_shift_horner(g->coeffs, c, g->length, prec); } arb-2.22.1/acb_poly/test/000077500000000000000000000000001417376376500151345ustar00rootroot00000000000000arb-2.22.1/acb_poly/test/t-add.c000066400000000000000000000055641417376376500163030ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("add...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_add(C, A, B); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_add(c, a, b, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_add(d, d, b, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_add(d, a, d, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-add_series.c000066400000000000000000000044531417376376500176510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("add_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d; slong len, prec; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, 1 + n_randint(state, 10), 100, 10); acb_poly_randtest(b, state, 1 + n_randint(state, 10), 100, 10); acb_poly_randtest(c, state, 1 + n_randint(state, 10), 100, 10); acb_poly_randtest(d, state, 1 + n_randint(state, 10), 100, 10); prec = 2 + n_randint(state, 100); len = n_randint(state, 10); acb_poly_add_series(c, a, b, len, prec); acb_poly_add(d, a, b, prec); acb_poly_truncate(d, len); if (!acb_poly_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_add_series(d, d, b, len, prec); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_add_series(d, a, d, len, prec); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-add_si.c000066400000000000000000000035111417376376500167640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("add_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d; slong v; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); acb_poly_randtest(b, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); acb_poly_randtest(c, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); acb_poly_randtest(d, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); v = n_randtest(state); acb_poly_set_si(b, v); acb_poly_add(c, a, b, 2 + n_randint(state, 200)); acb_poly_add_si(d, a, v, 2 + n_randint(state, 200)); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_abort(); } acb_poly_add_si(a, a, v, 2 + n_randint(state, 200)); if (!acb_poly_overlaps(a, d)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-agm1_series.c000066400000000000000000000042051417376376500177410ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("agm1_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_poly_agm1_series(A, S, n1, bits2); acb_poly_agm1_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_agm1_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-atan_series.c000066400000000000000000000054301417376376500200400ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("atan_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; acb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, m, qbits); fmpq_poly_set_coeff_si(A, 0, 0); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_atan_series(b, a, n, rbits2); /* Check 2 atan(x) = atan(2x/(1-x^2)) + C */ acb_poly_mullow(c, a, a, n, rbits2); acb_poly_one(d); acb_poly_sub(c, d, c, rbits2); acb_poly_add(d, a, a, rbits2); if (acb_poly_length(c) != 0) { acb_poly_div_series(c, d, c, n, rbits2); acb_poly_atan_series(c, c, n, rbits2); acb_poly_add(d, b, b, rbits2); /* TODO: also check the first coefficient */ acb_poly_set_coeff_si(c, 0, 0); acb_poly_set_coeff_si(d, 0, 0); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } } acb_poly_atan_series(a, a, n, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-binomial_transform.c000066400000000000000000000060511417376376500214300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("binomial_transform...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d; slong j, n, prec; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); n = n_randint(state, 20); prec = 2 + n_randint(state, 200); acb_poly_randtest(a, state, n, prec, 10); acb_poly_randtest(b, state, n, prec, 10); acb_poly_randtest(c, state, n, prec, 10); /* check self-inversion property */ acb_poly_binomial_transform(b, a, n, prec); acb_poly_binomial_transform(c, b, n, prec); acb_poly_set(d, a); acb_poly_truncate(d, n); if (!acb_poly_contains(c, d)) { flint_printf("FAIL (containment)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_binomial_transform(d, d, n, prec); if (!acb_poly_equal(d, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* compare with power series operations */ acb_poly_zero(d); for (j = 1; j < n; j++) acb_poly_set_coeff_si(d, j, -1); acb_poly_compose_series(c, a, d, n, prec); for (j = 0; j < n; j++) acb_poly_set_coeff_si(d, j, 1); acb_poly_mullow(c, c, d, n, prec); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL (power series)\n\n"); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-binomial_transform_basecase.c000066400000000000000000000061151417376376500232570ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("binomial_transform_basecase...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d; slong j, n, prec; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); n = n_randint(state, 20); prec = 2 + n_randint(state, 200); acb_poly_randtest(a, state, n, prec, 10); acb_poly_randtest(b, state, n, prec, 10); acb_poly_randtest(c, state, n, prec, 10); /* check self-inversion property */ acb_poly_binomial_transform_basecase(b, a, n, prec); acb_poly_binomial_transform_basecase(c, b, n, prec); acb_poly_set(d, a); acb_poly_truncate(d, n); if (!acb_poly_contains(c, d)) { flint_printf("FAIL (containment)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_binomial_transform_basecase(d, d, n, prec); if (!acb_poly_equal(d, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* compare with power series operations */ acb_poly_zero(d); for (j = 1; j < n; j++) acb_poly_set_coeff_si(d, j, -1); acb_poly_compose_series(c, a, d, n, prec); for (j = 0; j < n; j++) acb_poly_set_coeff_si(d, j, 1); acb_poly_mullow(c, c, d, n, prec); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL (power series)\n\n"); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-binomial_transform_convolution.c000066400000000000000000000061311417376376500240660ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("binomial_transform_convolution...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d; slong j, n, prec; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); n = n_randint(state, 20); prec = 2 + n_randint(state, 200); acb_poly_randtest(a, state, n, prec, 10); acb_poly_randtest(b, state, n, prec, 10); acb_poly_randtest(c, state, n, prec, 10); /* check self-inversion property */ acb_poly_binomial_transform_convolution(b, a, n, prec); acb_poly_binomial_transform_convolution(c, b, n, prec); acb_poly_set(d, a); acb_poly_truncate(d, n); if (!acb_poly_contains(c, d)) { flint_printf("FAIL (containment)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_binomial_transform_convolution(d, d, n, prec); if (!acb_poly_equal(d, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* compare with power series operations */ acb_poly_zero(d); for (j = 1; j < n; j++) acb_poly_set_coeff_si(d, j, -1); acb_poly_compose_series(c, a, d, n, prec); for (j = 0; j < n; j++) acb_poly_set_coeff_si(d, j, 1); acb_poly_mullow(c, c, d, n, prec); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL (power series)\n\n"); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-borel_transform.c000066400000000000000000000035231417376376500207420ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("borel_transform...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d; slong n, prec; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); n = n_randint(state, 30); prec = n_randint(state, 200); acb_poly_randtest(a, state, n, prec, 10); acb_poly_randtest(b, state, n, prec, 10); acb_poly_randtest(c, state, n, prec, 10); acb_poly_borel_transform(b, a, prec); acb_poly_inv_borel_transform(c, b, prec); if (!acb_poly_contains(c, a)) { flint_printf("FAIL (containment)\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_borel_transform(d, d, prec); if (!acb_poly_equal(d, b)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_inv_borel_transform(d, d, prec); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-compose.c000066400000000000000000000055171417376376500172160ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_compose(C, A, B); acb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 4); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_compose(c, a, b, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_compose(d, d, b, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_compose(d, a, d, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-compose_divconquer.c000066400000000000000000000054601417376376500214520ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_divconquer...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_compose(C, A, B); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_compose_divconquer(c, a, b, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_compose_divconquer(d, d, b, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_compose_divconquer(d, a, d, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-compose_horner.c000066400000000000000000000054401417376376500205660ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_compose(C, A, B); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_compose_horner(c, a, b, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_compose_horner(d, d, b, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_compose_horner(d, a, d, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-compose_series.c000066400000000000000000000057341417376376500205710ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, n; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); fmpq_poly_set_coeff_ui(B, 0, 0); fmpq_poly_compose_series(C, A, B, n); acb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 4); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_compose_series(c, a, b, n, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits3 = %wd\n", n, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_compose_series(d, d, b, n, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_compose_series(d, a, d, n, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-compose_series_brent_kung.c000066400000000000000000000056751417376376500230130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_series_brent_kung...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, n; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); fmpq_poly_set_coeff_ui(B, 0, 0); fmpq_poly_compose_series(C, A, B, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_compose_series_brent_kung(c, a, b, n, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits3 = %wd\n", n, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_compose_series_brent_kung(d, d, b, n, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_compose_series_brent_kung(d, a, d, n, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-compose_series_horner.c000066400000000000000000000056551417376376500221500ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_series_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, n; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); fmpq_poly_set_coeff_ui(B, 0, 0); fmpq_poly_compose_series(C, A, B, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_compose_series_horner(c, a, b, n, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits3 = %wd\n", n, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_compose_series_horner(d, d, b, n, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_compose_series_horner(d, a, d, n, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-cos_pi_series.c000066400000000000000000000044631417376376500203760ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("cos_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t pi; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(pi); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_poly_cos_pi_series(A, S, n1, bits2); acb_const_pi(pi, bits3); acb_poly_set_acb(B, pi); acb_poly_mul(B, S, B, bits3); acb_poly_cos_series(B, B, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_cos_pi_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(pi); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-cot_pi_series.c000066400000000000000000000040401417376376500203660ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("cot_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, bits1, bits2, bits3; acb_poly_t S, A, B, C; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 10); acb_poly_randtest(A, state, m, bits1, 10); acb_poly_randtest(B, state, m, bits1, 10); acb_poly_cot_pi_series(A, S, n1, bits2); acb_poly_sin_cos_pi_series(B, C, S, n1, bits3); acb_poly_div_series(B, C, B, n1, bits3); if (!acb_poly_overlaps(A, B)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_cot_pi_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-digamma_series.c000066400000000000000000000055161417376376500205210ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("digamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; acb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 300); rbits2 = 2 + n_randint(state, 300); rbits3 = 2 + n_randint(state, 300); m = n_randint(state, 25); n1 = n_randint(state, 25); n2 = n_randint(state, 25); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_digamma_series(b, a, n1, rbits2); acb_poly_digamma_series(c, a, n2, rbits3); acb_poly_set(d, b); acb_poly_truncate(d, FLINT_MIN(n1, n2)); acb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); acb_poly_printd(a, 50); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 50); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 50); flint_printf("\n\n"); flint_abort(); } /* check psi(a) + 1/a = psi(a+1) */ acb_poly_inv_series(c, a, n1, rbits2); acb_poly_add(c, b, c, rbits2); acb_poly_add_si(d, a, 1, rbits2); acb_poly_digamma_series(d, d, n1, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_digamma_series(a, a, n1, rbits2); if (!acb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-div_series.c000066400000000000000000000061061417376376500177000ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("div_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, p, qbits, rbits1, rbits2; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); p = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, m, qbits); do { fmpq_poly_randtest_not_zero(B, state, n, qbits); } while (B->coeffs[0] == 0); fmpq_poly_div_series(C, A, B, p); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits1); acb_poly_div_series(c, a, b, p, rbits2); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_div_series(d, d, b, p, rbits2); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_div_series(d, a, d, p, rbits2); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_div_series(c, d, d, p, rbits2); acb_poly_div_series(d, d, d, p, rbits2); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 3)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-divrem.c000066400000000000000000000066731417376376500170430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("divrem...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong m, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, Q, R; acb_poly_t a, b, q, r; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(Q); fmpq_poly_init(R); acb_poly_init(a); acb_poly_init(b); acb_poly_init(q); acb_poly_init(r); fmpq_poly_randtest(A, state, m, qbits1); fmpq_poly_randtest_not_zero(B, state, n, qbits2); fmpq_poly_divrem(Q, R, A, B); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_divrem(q, r, a, b, rbits3); if (!acb_poly_contains_fmpq_poly(q, Q) || !acb_poly_contains_fmpq_poly(r, R)) { flint_printf("FAIL\n\n"); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("Q = "); fmpq_poly_print(Q); flint_printf("\n\n"); flint_printf("R = "); fmpq_poly_print(R); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("q = "); acb_poly_printd(q, 15); flint_printf("\n\n"); flint_printf("r = "); acb_poly_printd(r, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_divrem(a, r, a, b, rbits3); if (!acb_poly_equal(a, q)) { flint_printf("FAIL (aliasing q, a)\n\n"); } acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_divrem(b, r, a, b, rbits3); if (!acb_poly_equal(b, q)) { flint_printf("FAIL (aliasing q, b)\n\n"); flint_abort(); } acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_divrem(q, a, a, b, rbits3); if (!acb_poly_equal(a, r)) { flint_printf("FAIL (aliasing r, a)\n\n"); flint_abort(); } acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_divrem(q, b, a, b, rbits3); if (!acb_poly_equal(b, r)) { flint_printf("FAIL (aliasing r, b)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(Q); fmpq_poly_clear(R); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(q); acb_poly_clear(r); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-elliptic_k_series.c000066400000000000000000000042351417376376500212360ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("elliptic_k_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_poly_elliptic_k_series(A, S, n1, bits2); acb_poly_elliptic_k_series(B, S, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_elliptic_k_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-elliptic_p_series.c000066400000000000000000000045271417376376500212470ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("elliptic_p_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t z; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(z); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_randtest(z, state, bits1, 3); acb_poly_elliptic_p_series(A, S, z, n1, bits2); acb_poly_elliptic_p_series(B, S, z, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_elliptic_p_series(S, S, z, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate.c000066400000000000000000000045771417376376500173640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq_t X, Y; acb_poly_t f; acb_t x, y; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(F); fmpq_init(X); fmpq_init(Y); acb_poly_init(f); acb_init(x); acb_init(y); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); fmpq_randtest(X, state, qbits2); fmpq_poly_evaluate_fmpq(Y, F, X); acb_poly_set_fmpq_poly(f, F, rbits1); acb_set_fmpq(x, X, rbits2); acb_poly_evaluate(y, f, x, rbits3); if (!acb_contains_fmpq(y, Y)) { flint_printf("FAIL\n\n"); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 15); flint_printf("\n\n"); flint_abort(); } /* aliasing */ acb_poly_evaluate(x, f, x, rbits3); if (!acb_contains_fmpq(x, Y)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(F); fmpq_clear(X); fmpq_clear(Y); acb_poly_clear(f); acb_clear(x); acb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate2.c000066400000000000000000000043061417376376500174340ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate2...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_poly_t f, g; acb_t x, y1, z1, y2, z2; acb_init(x); acb_init(y1); acb_init(z1); acb_init(y2); acb_init(z2); acb_poly_init(f); acb_poly_init(g); acb_randtest(x, state, 2 + n_randint(state, 1000), 5); acb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); acb_poly_derivative(g, f, 2 + n_randint(state, 1000)); acb_poly_evaluate2(y1, z1, f, x, 2 + n_randint(state, 1000)); acb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); acb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); if (!acb_overlaps(y1, y2) || !acb_overlaps(z1, z2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("y2 = "); acb_printd(y2, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_clear(x); acb_clear(y1); acb_clear(z1); acb_clear(y2); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate2_horner.c000066400000000000000000000043241417376376500210110ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate2_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_poly_t f, g; acb_t x, y1, z1, y2, z2; acb_init(x); acb_init(y1); acb_init(z1); acb_init(y2); acb_init(z2); acb_poly_init(f); acb_poly_init(g); acb_randtest(x, state, 2 + n_randint(state, 1000), 5); acb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); acb_poly_derivative(g, f, 2 + n_randint(state, 1000)); acb_poly_evaluate2_horner(y1, z1, f, x, 2 + n_randint(state, 1000)); acb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); acb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); if (!acb_overlaps(y1, y2) || !acb_overlaps(z1, z2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("y2 = "); acb_printd(y2, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_clear(x); acb_clear(y1); acb_clear(z1); acb_clear(y2); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate2_rectangular.c000066400000000000000000000043361417376376500220260ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate2_rectangular...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_poly_t f, g; acb_t x, y1, z1, y2, z2; acb_init(x); acb_init(y1); acb_init(z1); acb_init(y2); acb_init(z2); acb_poly_init(f); acb_poly_init(g); acb_randtest(x, state, 2 + n_randint(state, 1000), 5); acb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); acb_poly_derivative(g, f, 2 + n_randint(state, 1000)); acb_poly_evaluate2_rectangular(y1, z1, f, x, 2 + n_randint(state, 1000)); acb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); acb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); if (!acb_overlaps(y1, y2) || !acb_overlaps(z1, z2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("y2 = "); acb_printd(y2, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_clear(x); acb_clear(y1); acb_clear(z1); acb_clear(y2); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate_horner.c000066400000000000000000000046241417376376500207320ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq_t X, Y; acb_poly_t f; acb_t x, y; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(F); fmpq_init(X); fmpq_init(Y); acb_poly_init(f); acb_init(x); acb_init(y); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); fmpq_randtest(X, state, qbits2); fmpq_poly_evaluate_fmpq(Y, F, X); acb_poly_set_fmpq_poly(f, F, rbits1); acb_set_fmpq(x, X, rbits2); acb_poly_evaluate_horner(y, f, x, rbits3); if (!acb_contains_fmpq(y, Y)) { flint_printf("FAIL\n\n"); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y, 15); flint_printf("\n\n"); flint_abort(); } /* aliasing */ acb_poly_evaluate_horner(x, f, x, rbits3); if (!acb_contains_fmpq(x, Y)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(F); fmpq_clear(X); fmpq_clear(Y); acb_poly_clear(f); acb_clear(x); acb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate_rectangular.c000066400000000000000000000032631417376376500217420ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_rectangular...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_poly_t f; acb_t x, y1, y2; acb_init(x); acb_init(y1); acb_init(y2); acb_poly_init(f); acb_randtest(x, state, 2 + n_randint(state, 1000), 5); acb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); acb_poly_evaluate_rectangular(y1, f, x, 2 + n_randint(state, 1000)); acb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); if (!acb_overlaps(y1, y2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 15); flint_printf("\n\n"); flint_printf("y2 = "); acb_printd(y2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_clear(x); acb_clear(y1); acb_clear(y2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate_vec_fast.c000066400000000000000000000051061417376376500212230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_vec_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq * X, * Y; acb_poly_t f; acb_ptr x, y; qbits1 = 2 + n_randint(state, 100); qbits2 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = n_randint(state, 10); fmpq_poly_init(F); X = _fmpq_vec_init(n); Y = _fmpq_vec_init(n); acb_poly_init(f); x = _acb_vec_init(n); y = _acb_vec_init(n); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); for (i = 0; i < n; i++) fmpq_randtest(X + i, state, qbits2); for (i = 0; i < n; i++) fmpq_poly_evaluate_fmpq(Y + i, F, X + i); acb_poly_set_fmpq_poly(f, F, rbits1); for (i = 0; i < n; i++) acb_set_fmpq(x + i, X + i, rbits2); acb_poly_evaluate_vec_fast(y, f, x, n, rbits3); for (i = 0; i < n; i++) { if (!acb_contains_fmpq(y + i, Y + i)) { flint_printf("FAIL (%wd of %wd)\n\n", i, n); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X + i); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y + i); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x + i, 15); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y + i, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_poly_clear(F); _fmpq_vec_clear(X, n); _fmpq_vec_clear(Y, n); acb_poly_clear(f); _acb_vec_clear(x, n); _acb_vec_clear(y, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-evaluate_vec_iter.c000066400000000000000000000051061417376376500212310ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_vec_iter...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq * X, * Y; acb_poly_t f; acb_ptr x, y; qbits1 = 2 + n_randint(state, 100); qbits2 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = n_randint(state, 10); fmpq_poly_init(F); X = _fmpq_vec_init(n); Y = _fmpq_vec_init(n); acb_poly_init(f); x = _acb_vec_init(n); y = _acb_vec_init(n); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); for (i = 0; i < n; i++) fmpq_randtest(X + i, state, qbits2); for (i = 0; i < n; i++) fmpq_poly_evaluate_fmpq(Y + i, F, X + i); acb_poly_set_fmpq_poly(f, F, rbits1); for (i = 0; i < n; i++) acb_set_fmpq(x + i, X + i, rbits2); acb_poly_evaluate_vec_iter(y, f, x, n, rbits3); for (i = 0; i < n; i++) { if (!acb_contains_fmpq(y + i, Y + i)) { flint_printf("FAIL (%wd of %wd)\n\n", i, n); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X + i); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y + i); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x + i, 15); flint_printf("\n\n"); flint_printf("y = "); acb_printd(y + i, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_poly_clear(F); _fmpq_vec_clear(X, n); _fmpq_vec_clear(Y, n); acb_poly_clear(f); _acb_vec_clear(x, n); _acb_vec_clear(y, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-exp_pi_i_series.c000066400000000000000000000041451417376376500207130ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_pi_i_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, prec; acb_poly_t a, b, c; acb_t t; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_init(t); prec = 2 + n_randint(state, 100); acb_poly_randtest(a, state, 1 + n_randint(state, 20), prec, 5); acb_poly_randtest(b, state, 1 + n_randint(state, 20), prec, 5); acb_poly_randtest(c, state, 1 + n_randint(state, 20), prec, 5); m = n_randint(state, 20); n = n_randint(state, 20); if (n_randint(state, 2) == 0) acb_poly_exp_pi_i_series(b, a, m, prec); else { acb_poly_set(b, a); acb_poly_exp_pi_i_series(b, b, m, prec); } acb_const_pi(t, prec); acb_mul_onei(t, t); acb_poly_scalar_mul(c, a, t, prec); acb_poly_exp_series(c, c, n, prec); acb_poly_truncate(b, FLINT_MIN(m, n)); acb_poly_truncate(c, FLINT_MIN(m, n)); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-exp_series.c000066400000000000000000000047731417376376500177220ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" ARB_DLL extern slong acb_poly_newton_exp_cutoff; int main() { slong iter; flint_rand_t state; flint_printf("exp_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, bits1, bits2, bits3; acb_poly_t a, b, c, d; bits1 = 2 + n_randint(state, 100); bits2 = 2 + n_randint(state, 100); bits3 = 2 + n_randint(state, 100); if (iter > 1000) { acb_poly_newton_exp_cutoff = 5 + n_randint(state, 50); } if (n_randint(state, 100) == 0) { m = 1 + n_randint(state, 100); n = 1 + n_randint(state, 100); } else { m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); } acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, bits1, 5); acb_poly_randtest(b, state, m, bits1, 5); acb_poly_randtest(c, state, 1 + n_randint(state, 300), bits1, 10); acb_poly_randtest(d, state, 1 + n_randint(state, 300), bits1, 10); /* check exp(a+b) = exp(a) exp(b) */ acb_poly_exp_series(c, a, n, bits2); acb_poly_exp_series(d, b, n, bits2); acb_poly_mullow(c, c, d, n, bits2); acb_poly_add(d, a, b, bits3); acb_poly_exp_series(d, d, n, bits3); /* also aliasing test */ if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-exp_series_basecase.c000066400000000000000000000040521417376376500215360ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_series_basecase...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, bits1, bits2, bits3; acb_poly_t a, b, c, d; bits1 = 2 + n_randint(state, 100); bits2 = 2 + n_randint(state, 100); bits3 = 2 + n_randint(state, 100); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, bits1, 5); acb_poly_randtest(b, state, m, bits1, 5); /* check exp(a+b) = exp(a) exp(b) */ acb_poly_exp_series_basecase(c, a, n, bits2); acb_poly_exp_series_basecase(d, b, n, bits2); acb_poly_mullow(c, c, d, n, bits2); acb_poly_add(d, a, b, bits3); acb_poly_exp_series_basecase(d, d, n, bits3); /* also aliasing test */ if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-find_roots.c000066400000000000000000000051271417376376500177140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("find_roots...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t A; acb_poly_t B; acb_poly_t C; acb_t t; acb_ptr roots; slong i, deg, isolated; slong prec = 10 + n_randint(state, 400); acb_init(t); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); do { acb_poly_randtest(A, state, 2 + n_randint(state, 15), prec, 5); } while (A->length == 0); deg = A->length - 1; roots = _acb_vec_init(deg); isolated = acb_poly_find_roots(roots, A, NULL, 0, prec); if (isolated == deg) { acb_poly_fit_length(B, 1); acb_set(B->coeffs, A->coeffs + deg); _acb_poly_set_length(B, 1); for (i = 0; i < deg; i++) { acb_poly_fit_length(C, 2); acb_one(C->coeffs + 1); acb_neg(C->coeffs + 0, roots + i); _acb_poly_set_length(C, 2); acb_poly_mul(B, B, C, prec); } if (!acb_poly_contains(B, A)) { flint_printf("FAIL: product does not equal polynomial\n"); acb_poly_printd(A, 15); flint_printf("\n\n"); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } } for (i = 0; i < isolated; i++) { acb_poly_evaluate(t, A, roots + i, prec); if (!acb_contains_zero(t)) { flint_printf("FAIL: poly(root) does not contain zero\n"); acb_poly_printd(A, 15); flint_printf("\n\n"); acb_printd(roots + i, 15); flint_printf("\n\n"); acb_printd(t, 15); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(roots, deg); acb_clear(t); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-gamma_series.c000066400000000000000000000057041417376376500202030ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; acb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 25); n1 = 1 + n_randint(state, 25); n2 = 1 + n_randint(state, 25); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, rbits1, 3); acb_poly_randtest(b, state, m, rbits1, 3); acb_poly_randtest(c, state, m, rbits1, 3); acb_poly_gamma_series(b, a, n1, rbits2); acb_poly_gamma_series(c, a, n2, rbits3); acb_poly_set(d, b); acb_poly_truncate(d, FLINT_MIN(n1, n2)); acb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check gamma(a) * a = gamma(a+1) */ acb_poly_mullow(c, b, a, n1, rbits2); acb_poly_set(d, a); acb_add_ui(d->coeffs, d->coeffs, 1, rbits2); acb_poly_gamma_series(d, d, n1, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation, n1 = %wd)\n\n", n1); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_gamma_series(a, a, n1, rbits2); if (!acb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-get_coeff_ptr.c000066400000000000000000000027221417376376500203520ustar00rootroot00000000000000/* Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main(void) { int i, result; flint_rand_t state; flint_printf("get_coeff_ptr...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 1000; i++) { acb_poly_t A; acb_t a; slong n = n_randint(state, 100); acb_poly_init(A); acb_poly_randtest(A, state, n_randint(state, 100), 100, 10); acb_init(a); acb_poly_get_coeff_acb(a, A, n); result = n < acb_poly_length(A) ? acb_equal(a, acb_poly_get_coeff_ptr(A, n)) : acb_poly_get_coeff_ptr(A, n) == NULL; if (!result) { flint_printf("FAIL:\n"); flint_printf("A = "), acb_poly_printd(A, 10), flint_printf("\n\n"); flint_printf("a = "), acb_print(a), flint_printf("\n\n"); flint_printf("n = %wd\n\n", n); flint_abort(); } acb_poly_clear(A); acb_clear(a); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/acb_poly/test/t-get_set_coeff_fmprb.c000066400000000000000000000031531417376376500215250ustar00rootroot00000000000000/* Copyright (C) 2009 William Hart Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main(void) { int i, j, result; flint_rand_t state; flint_printf("get/set_coeff_acb...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 100; i++) { acb_poly_t a; acb_t x1, x2; slong coeff, len; acb_poly_init(a); acb_init(x1); acb_init(x2); len = n_randint(state, 100) + 1; for (j = 0; j < 100; j++) { acb_randtest(x1, state, 2 + n_randint(state, 200), 10); coeff = n_randint(state, len); acb_poly_set_coeff_acb(a, coeff, x1); acb_poly_get_coeff_acb(x2, a, coeff); result = (acb_equal(x1, x2)); if (!result) { flint_printf("FAIL:\n"); flint_printf("x1 = "), acb_print(x1), flint_printf("\n"); flint_printf("x2 = "), acb_print(x2), flint_printf("\n"); flint_printf("coeff = %wd, length = %wd\n", coeff, len); flint_abort(); } } acb_clear(x1); acb_clear(x2); acb_poly_clear(a); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/acb_poly/test/t-get_unique_fmpz_poly.c000066400000000000000000000044121417376376500220060ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("get_unique_fmpz_poly...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong prec, c; fmpz_poly_t A, B, C; acb_poly_t a, b; fmpz_poly_init(A); fmpz_poly_init(B); fmpz_poly_init(C); acb_poly_init(a); acb_poly_init(b); fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000)); fmpz_poly_randtest(B, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000)); fmpz_poly_randtest(C, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000)); c = 1 + n_randint(state, 1000); prec = 2 + n_randint(state, 100); for ( ; ; ) { acb_poly_set_fmpz_poly(a, A, prec); acb_poly_set2_fmpz_poly(b, B, C, prec); acb_poly_scalar_mul_2exp_si(b, b, -c); acb_poly_add(a, a, b, prec); acb_poly_sub(a, a, b, prec); if (acb_poly_get_unique_fmpz_poly(B, a)) { if (!fmpz_poly_equal(A, B)) { flint_printf("FAIL\n\n"); flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_abort(); } break; } else { prec *= 2; } } fmpz_poly_clear(A); fmpz_poly_clear(B); fmpz_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-graeffe_transform.c000066400000000000000000000050641417376376500212400ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; acb_poly_t a, b, c; acb_ptr roots; acb_t leading; flint_printf("graeffe_transform...."); fflush(stdout); flint_randinit(state); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_init(leading); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong n, prec, i; n = n_randint(state, 20); prec = 2 + n_randint(state, 256); roots = _acb_vec_init(n); acb_randtest(leading, state, prec, n_randint(state, 16)); for (i = 0; i < n; i++) acb_randtest(roots + i, state, prec, n_randint(state, 16)); acb_poly_product_roots(a, roots, n, prec); acb_poly_scalar_mul(a, a, leading, prec); for (i = 0; i < n; i++) acb_sqr(roots + i, roots + i, prec); acb_sqr(leading, leading, prec); acb_poly_product_roots(c, roots, n, prec); acb_poly_scalar_mul(c, c, leading, prec); acb_poly_graeffe_transform(b, a, prec); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL (overlap)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_graeffe_transform(a, a, prec); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } _acb_vec_clear(roots, n); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_clear(leading); flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-interpolate_barycentric.c000066400000000000000000000047301417376376500224600ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("interpolate_barycentric...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t P; acb_poly_t R, S; fmpq_t t, u; acb_ptr xs, ys; fmpq_poly_init(P); acb_poly_init(R); acb_poly_init(S); fmpq_init(t); fmpq_init(u); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 5); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); n = P->length; xs = _acb_vec_init(n); ys = _acb_vec_init(n); acb_poly_set_fmpq_poly(R, P, rbits1); if (n > 0) { fmpq_randtest(t, state, qbits2); acb_set_fmpq(xs, t, rbits2); for (i = 1; i < n; i++) { fmpq_randtest_not_zero(u, state, qbits2); fmpq_abs(u, u); fmpq_add(t, t, u); acb_set_fmpq(xs + i, t, rbits2); } } for (i = 0; i < n; i++) acb_poly_evaluate(ys + i, R, xs + i, rbits2); acb_poly_interpolate_barycentric(S, xs, ys, n, rbits3); if (!acb_poly_contains_fmpq_poly(S, P)) { flint_printf("FAIL:\n"); flint_printf("P = "); fmpq_poly_print(P); flint_printf("\n\n"); flint_printf("R = "); acb_poly_printd(R, 15); flint_printf("\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(P); acb_poly_clear(R); acb_poly_clear(S); fmpq_clear(t); fmpq_clear(u); _acb_vec_clear(xs, n); _acb_vec_clear(ys, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-interpolate_fast.c000066400000000000000000000047121417376376500211100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("interpolate_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t P; acb_poly_t R, S; fmpq_t t, u; acb_ptr xs, ys; fmpq_poly_init(P); acb_poly_init(R); acb_poly_init(S); fmpq_init(t); fmpq_init(u); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 5); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); n = P->length; xs = _acb_vec_init(n); ys = _acb_vec_init(n); acb_poly_set_fmpq_poly(R, P, rbits1); if (n > 0) { fmpq_randtest(t, state, qbits2); acb_set_fmpq(xs, t, rbits2); for (i = 1; i < n; i++) { fmpq_randtest_not_zero(u, state, qbits2); fmpq_abs(u, u); fmpq_add(t, t, u); acb_set_fmpq(xs + i, t, rbits2); } } for (i = 0; i < n; i++) acb_poly_evaluate(ys + i, R, xs + i, rbits2); acb_poly_interpolate_fast(S, xs, ys, n, rbits3); if (!acb_poly_contains_fmpq_poly(S, P)) { flint_printf("FAIL:\n"); flint_printf("P = "); fmpq_poly_print(P); flint_printf("\n\n"); flint_printf("R = "); acb_poly_printd(R, 15); flint_printf("\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(P); acb_poly_clear(R); acb_poly_clear(S); fmpq_clear(t); fmpq_clear(u); _acb_vec_clear(xs, n); _acb_vec_clear(ys, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-interpolate_newton.c000066400000000000000000000047161417376376500214710ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("interpolate_newton...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t P; acb_poly_t R, S; fmpq_t t, u; acb_ptr xs, ys; fmpq_poly_init(P); acb_poly_init(R); acb_poly_init(S); fmpq_init(t); fmpq_init(u); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 5); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); n = P->length; xs = _acb_vec_init(n); ys = _acb_vec_init(n); acb_poly_set_fmpq_poly(R, P, rbits1); if (n > 0) { fmpq_randtest(t, state, qbits2); acb_set_fmpq(xs, t, rbits2); for (i = 1; i < n; i++) { fmpq_randtest_not_zero(u, state, qbits2); fmpq_abs(u, u); fmpq_add(t, t, u); acb_set_fmpq(xs + i, t, rbits2); } } for (i = 0; i < n; i++) acb_poly_evaluate(ys + i, R, xs + i, rbits2); acb_poly_interpolate_newton(S, xs, ys, n, rbits3); if (!acb_poly_contains_fmpq_poly(S, P)) { flint_printf("FAIL:\n"); flint_printf("P = "); fmpq_poly_print(P); flint_printf("\n\n"); flint_printf("R = "); acb_poly_printd(R, 15); flint_printf("\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(P); acb_poly_clear(R); acb_poly_clear(S); fmpq_clear(t); fmpq_clear(u); _acb_vec_clear(xs, n); _acb_vec_clear(ys, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-inv_series.c000066400000000000000000000065121417376376500177130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("inv_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; acb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); do { fmpq_poly_randtest_not_zero(A, state, m, qbits); } while (A->coeffs[0] == 0); fmpq_poly_inv_series(B, A, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_inv_series(b, a, n, rbits2); if (!acb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_inv_series(a, a, n, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); } /* check f * f^-1 = 1 */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, trunc; acb_poly_t a, b, ab; fmpq_poly_t id; bits = 2 + n_randint(state, 200); trunc = 1 + n_randint(state, 10); acb_poly_init(a); acb_poly_init(b); acb_poly_init(ab); fmpq_poly_init(id); do { acb_poly_randtest(a, state, 1 + n_randint(state, 10), bits, 5); } while (a->length == 0 || acb_contains_zero(a->coeffs + 0)); acb_poly_inv_series(b, a, trunc, bits); acb_poly_mullow(ab, a, b, trunc, bits); fmpq_poly_set_ui(id, 1); if (!acb_poly_contains_fmpq_poly(ab, id)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("ab = "); acb_poly_printd(ab, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(ab); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-lambertw_series.c000066400000000000000000000106701417376376500207340ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("lambertw_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t x1, x2, t, w1, w2; slong prec1, prec2, n1, n2, ebits; fmpz_t k; acb_poly_init(x1); acb_poly_init(x2); acb_poly_init(t); acb_poly_init(w1); acb_poly_init(w2); fmpz_init(k); n1 = n_randint(state, 15); n2 = n_randint(state, 15); if (n_randint(state, 4) == 0) { prec1 = 2 + n_randint(state, 3000); prec2 = 2 + n_randint(state, 3000); ebits = 1 + n_randint(state, 1000); } else { prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 50); } fmpz_randtest(k, state, ebits); acb_poly_randtest(x1, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); acb_poly_randtest(x2, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); acb_poly_randtest(t, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); acb_poly_randtest(w1, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); acb_poly_randtest(w2, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); if (n_randint(state, 4) == 0) { acb_t u; acb_init(u); arb_const_e(acb_realref(u), 2 * prec1); acb_inv(u, u, 2 * prec1); acb_poly_set_acb(t, u); acb_poly_sub(x1, x1, t, 2 * prec1); acb_clear(u); } if (n_randint(state, 2)) { acb_poly_set(x2, x1); } else { acb_poly_add(x2, x1, t, 2 * prec1); acb_poly_sub(x2, x2, t, 2 * prec1); } acb_poly_lambertw_series(w1, x1, k, 0, n1, prec1); if (n_randint(state, 2)) { acb_poly_set(w2, x2); acb_poly_lambertw_series(w2, w2, k, 0, n2, prec1); } else { acb_poly_lambertw_series(w2, x2, k, 0, n2, prec1); } acb_poly_truncate(w1, FLINT_MIN(n1, n2)); acb_poly_truncate(w2, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(w1, w2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter %wd, branch = ", iter); fmpz_print(k); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); acb_poly_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); acb_poly_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); acb_poly_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_poly_printd(w2, 50); flint_printf("\n\n"); flint_abort(); } acb_poly_exp_series(t, w1, FLINT_MIN(n1, n2), prec1); acb_poly_mullow(t, t, w1, FLINT_MIN(n1, n2), prec1); acb_poly_truncate(x1, FLINT_MIN(n1, n2)); if (!acb_poly_contains(t, x1)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("iter %wd, branch = ", iter); fmpz_print(k); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); acb_poly_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); acb_poly_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); acb_poly_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); acb_poly_printd(w2, 50); flint_printf("\n\n"); flint_printf("t = "); acb_poly_printd(t, 50); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(x1); acb_poly_clear(x2); acb_poly_clear(t); acb_poly_clear(w1); acb_poly_clear(w2); fmpz_clear(k); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-lgamma_series.c000066400000000000000000000073461417376376500203630ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("lgamma_series...."); fflush(stdout); flint_randinit(state); /* special accuracy test case */ { acb_poly_t a; acb_t c; acb_init(c); acb_poly_init(a); arb_set_str(acb_realref(c), "-20.25", 53); arb_set_str(acb_imagref(c), "1e1000", 53); acb_poly_set_coeff_acb(a, 0, c); acb_poly_set_coeff_si(a, 1, 1); acb_poly_lgamma_series(a, a, 3, 53); if (acb_rel_accuracy_bits(a->coeffs) < 40 || acb_rel_accuracy_bits(a->coeffs + 1) < 40 || acb_rel_accuracy_bits(a->coeffs + 2) < 40) { flint_printf("FAIL: accuracy (reflection formula)\n\n"); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_clear(c); } for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; acb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_randtest(b, state, m, rbits1, 10); acb_poly_randtest(c, state, m, rbits1, 10); acb_poly_lgamma_series(b, a, n1, rbits2); acb_poly_lgamma_series(c, a, n2, rbits3); acb_poly_set(d, b); acb_poly_truncate(d, FLINT_MIN(n1, n2)); acb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check loggamma(a) + log(a) = loggamma(a+1) */ acb_poly_log_series(c, a, n1, rbits2); acb_poly_add(c, b, c, rbits2); acb_poly_set(d, a); acb_add_ui(d->coeffs, d->coeffs, 1, rbits2); acb_poly_lgamma_series(d, d, n1, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_lgamma_series(a, a, n1, rbits2); if (!acb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-log1p_series.c000066400000000000000000000040651417376376500201420ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("log1p_series...."); fflush(stdout); flint_randinit(state); /* compare with log_series */ for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c; slong m, n, prec; prec = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_randtest(a, state, 1 + n_randint(state, 10), prec, 5); acb_poly_randtest(b, state, 1 + n_randint(state, 10), prec, 5); acb_poly_randtest(c, state, 1 + n_randint(state, 10), prec, 5); if (n_randint(state, 2)) acb_poly_log1p_series(b, a, n, prec); else { acb_poly_set(b, a); acb_poly_log1p_series(b, b, n, prec); } acb_poly_add_si(c, a, 1, prec); acb_poly_log_series(c, c, m, prec); acb_poly_truncate(b, FLINT_MIN(m, n)); acb_poly_truncate(c, FLINT_MIN(m, n)); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd\n\n", m, n); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-log_series.c000066400000000000000000000115401417376376500176750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("log_series...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; acb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); fmpq_poly_randtest_not_zero(A, state, m, qbits); fmpq_poly_set_coeff_ui(A, 0, UWORD(1)); fmpq_poly_log_series(B, A, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); acb_poly_log_series(b, a, n, rbits2); if (!acb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); } /* test aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; acb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); acb_poly_init(a); acb_poly_init(b); do { fmpq_poly_randtest_not_zero(A, state, m, qbits); } while (fmpz_sgn(A->coeffs + 0) <= 0); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_log_series(b, a, n, rbits2); acb_poly_log_series(a, a, n, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); acb_poly_clear(a); acb_poly_clear(b); } /* test that exp(log(f)) contains f */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2, rbits3; fmpq_poly_t A; acb_poly_t a, b, c; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); do { fmpq_poly_randtest_not_zero(A, state, m, qbits); } while (fmpz_sgn(A->coeffs + 0) <= 0); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); acb_poly_log_series(b, a, n, rbits2); acb_poly_exp_series_basecase(c, b, n, rbits3); fmpq_poly_truncate(A, n); if (!acb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-mullow.c000066400000000000000000000122101417376376500170540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mullow...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_mullow(C, A, B, trunc); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_mullow(c, a, b, trunc, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_mullow(d, d, b, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_mullow(d, a, d, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ acb_poly_set(b, a); acb_poly_mullow(c, a, b, trunc, rbits3); acb_poly_mullow(d, a, a, trunc, rbits3); if (!acb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_mullow(a, a, a, trunc, rbits3); if (!acb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } /* compare with classical */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, trunc; acb_poly_t a, b, ab, ab2; bits = 2 + n_randint(state, 200); trunc = n_randint(state, 10); acb_poly_init(a); acb_poly_init(b); acb_poly_init(ab); acb_poly_init(ab2); acb_poly_randtest(a, state, 1 + n_randint(state, 10), bits, 5); acb_poly_randtest(b, state, 1 + n_randint(state, 10), bits, 5); acb_poly_mullow_classical(ab, a, b, trunc, bits); acb_poly_mullow(ab2, a, b, trunc, bits); if (!acb_poly_overlaps(ab, ab2)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("ab = "); acb_poly_printd(ab, 15); flint_printf("\n\n"); flint_printf("ab2 = "); acb_poly_printd(ab2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(ab); acb_poly_clear(ab2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-mullow_classical.c000066400000000000000000000133601417376376500211010ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mullow_classical...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_mullow(C, A, B, trunc); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_mullow_classical(c, a, b, trunc, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_mullow_classical(d, d, b, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_mullow_classical(d, a, d, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ acb_poly_set(b, a); acb_poly_mullow_classical(c, a, b, trunc, rbits3); acb_poly_mullow_classical(d, a, a, trunc, rbits3); if (!acb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_mullow_classical(a, a, a, trunc, rbits3); if (!acb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } /* check a*(b+c) = a*b+a*c */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, trunc; acb_poly_t a, b, c, bc, abc, ab, ac, abac; bits = 2 + n_randint(state, 200); trunc = n_randint(state, 10); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(bc); acb_poly_init(abc); acb_poly_init(ab); acb_poly_init(ac); acb_poly_init(abac); acb_poly_randtest(a, state, 1 + n_randint(state, 10), bits, 5); acb_poly_randtest(b, state, 1 + n_randint(state, 10), bits, 5); acb_poly_randtest(c, state, 1 + n_randint(state, 10), bits, 5); acb_poly_add(bc, b, c, bits); acb_poly_mullow_classical(abc, a, bc, trunc, bits); acb_poly_mullow_classical(ab, a, b, trunc, bits); acb_poly_mullow_classical(ac, a, c, trunc, bits); acb_poly_add(abac, ab, ac, bits); if (!acb_poly_overlaps(abc, abac)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("abc = "); acb_poly_printd(abc, 15); flint_printf("\n\n"); flint_printf("abac = "); acb_poly_printd(abac, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(bc); acb_poly_clear(abc); acb_poly_clear(ab); acb_poly_clear(ac); acb_poly_clear(abac); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-mullow_transpose.c000066400000000000000000000123301417376376500211550ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mullow_transpose...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_mullow(C, A, B, trunc); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_mullow_transpose(c, a, b, trunc, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_mullow_transpose(d, d, b, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_mullow_transpose(d, a, d, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ acb_poly_set(b, a); acb_poly_mullow_transpose(c, a, b, trunc, rbits3); acb_poly_mullow_transpose(d, a, a, trunc, rbits3); if (!acb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_mullow_transpose(a, a, a, trunc, rbits3); if (!acb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } /* compare with classical */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, trunc; acb_poly_t a, b, ab, ab2; bits = 2 + n_randint(state, 200); trunc = n_randint(state, 10); acb_poly_init(a); acb_poly_init(b); acb_poly_init(ab); acb_poly_init(ab2); acb_poly_randtest(a, state, 1 + n_randint(state, 10), bits, 5); acb_poly_randtest(b, state, 1 + n_randint(state, 10), bits, 5); acb_poly_mullow_classical(ab, a, b, trunc, bits); acb_poly_mullow_transpose(ab2, a, b, trunc, bits); if (!acb_poly_overlaps(ab, ab2)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("ab = "); acb_poly_printd(ab, 15); flint_printf("\n\n"); flint_printf("ab2 = "); acb_poly_printd(ab2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(ab); acb_poly_clear(ab2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-mullow_transpose_gauss.c000066400000000000000000000124101417376376500223560ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mullow_transpose_gauss...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_mullow(C, A, B, trunc); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_mullow_transpose_gauss(c, a, b, trunc, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_mullow_transpose_gauss(d, d, b, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_mullow_transpose_gauss(d, a, d, trunc, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ acb_poly_set(b, a); acb_poly_mullow_transpose_gauss(c, a, b, trunc, rbits3); acb_poly_mullow_transpose_gauss(d, a, a, trunc, rbits3); if (!acb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_mullow_transpose_gauss(a, a, a, trunc, rbits3); if (!acb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } /* compare with classical */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, trunc; acb_poly_t a, b, ab, ab2; bits = 2 + n_randint(state, 200); trunc = n_randint(state, 10); acb_poly_init(a); acb_poly_init(b); acb_poly_init(ab); acb_poly_init(ab2); acb_poly_randtest(a, state, 1 + n_randint(state, 10), bits, 5); acb_poly_randtest(b, state, 1 + n_randint(state, 10), bits, 5); acb_poly_mullow_classical(ab, a, b, trunc, bits); acb_poly_mullow_transpose_gauss(ab2, a, b, trunc, bits); if (!acb_poly_overlaps(ab, ab2)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("ab = "); acb_poly_printd(ab, 15); flint_printf("\n\n"); flint_printf("ab2 = "); acb_poly_printd(ab2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(ab); acb_poly_clear(ab2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-polylog_cpx.c000066400000000000000000000317171417376376500201110ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #define EPS 1e-13 #define NUM_DERIVS 3 #define NUM_TESTS 56 const double polylog_testdata[NUM_TESTS][10] = { {-2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-2.0, 0.0, -0.5, 0.0, -0.0740740740740740741, 0.0, -0.158799035455864473, 0.0, 0.00278425812292977954, 0.0}, {-2.0, 0.0, 0.99609375, 0.0, 33358080.0, 0.0, -215693527.719090182, 0.0, 703924885.809675425, 0.0}, {-2.0, 0.0, 1.00390625, 0.0, -33751296.0, 0.0, 218367905.967311029, -106032823.56283664, -546519337.1290267, 686023009.262281684}, {-2.0, 0.0, -4.25, 0.0, 0.0954540546377281071, 0.0, -0.0297817299750221174, 0.0, -0.196648773789941696, 0.0}, {-2.0, 0.0, 3.5, 0.0, -1.008, 0.0, 0.691243661008350802, -3.19575256895409845, 4.53340070033764442, 2.22882281653983385}, {-2.0, 0.0, 0.0, -1.0, 0.0, 0.5, -0.852556797635011582, -0.25189536315108886, 0.345626503121598963, -0.46292146649778986}, {-2.0, 0.0, 0.125, 0.125, 0.071424, 0.280832, 0.0646851488459364134, -0.118051747326526959, -0.0396751348737248634, 0.0452067417426917285}, {-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-1.0, 0.0, -0.5, 0.0, -0.222222222222222222, 0.0, -0.131883201632587537, 0.0, 0.0199225628389378777, 0.0}, {-1.0, 0.0, 0.99609375, 0.0, 65280.0, 0.0, -389461.499432291984, 0.0, 1182814.77437627002, 0.0}, {-1.0, 0.0, 1.00390625, 0.0, 65792.0, 0.0, -392773.095775796478, 206691.925664168516, 868954.597422132011, -1233932.55215831045}, {-1.0, 0.0, -4.25, 0.0, -0.154195011337868481, 0.0, -0.474824989764482489, 0.0, -0.21428706813151403, 0.0}, {-1.0, 0.0, 3.5, 0.0, 0.56, 0.0, -0.322735710701998933, 2.00176023742981729, -3.09698193717149541, -0.395213225234415973}, {-1.0, 0.0, 0.0, -1.0, -0.5, 0.0, -0.183855151549436048, -0.58312180806163756, 0.254077251327014729, 0.0351429519611278982}, {-1.0, 0.0, 0.125, 0.125, 0.1088, 0.1984, 0.0192018441183911, -0.0548368329876085499, -0.0115465156713130216, 0.020954643261003461}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, -0.5, 0.0, -0.333333333333333333, 0.0, -0.0904116649848191551, 0.0, 0.0199028637728058217, 0.0}, {0.0, 0.0, 0.99609375, 0.0, 255.0, 0.0, -1269.73106874463507, 0.0, 3359.60296533314103, 0.0}, {0.0, 0.0, 1.00390625, 0.0, -257.0, 0.0, 1273.86116119868176, -805.817494984366455, -2113.9649224353639, 4004.84182305521042}, {0.0, 0.0, -4.25, 0.0, -0.809523809523809524, 0.0, -0.795769271870623909, 0.0, -0.0965372637237445457, 0.0}, {0.0, 0.0, 3.5, 0.0, -1.4, 0.0, -1.78816683065098841, -2.50773109725857055, 1.83790031889197745, -2.01262260402527512}, {0.0, 0.0, 0.0, -1.0, -0.5, -0.5, 0.120782237635245222, -0.391594392706836776, 0.0669079578849868665, 0.116416441749488305}, {0.0, 0.0, 0.125, 0.125, 0.12, 0.16, 0.00583206536388767829, -0.0256940749384562616, -0.00344424777009813297, 0.00965046958017889366}, {-0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-0.5, 0.0, -0.5, 0.0, -0.283012810746506023, 0.0, -0.111080563146094489, 0.0, 0.0211430885590715694, 0.0}, {-0.5, 0.0, 0.99609375, 0.0, 3619.14124113924805, 0.0, -20195.2825251289493, 0.0, 58032.3050555790807, 0.0}, {-0.5, 0.0, 1.00390625, 0.0, -0.207985517845521836, 3640.61848390552728, -11437.7014354502895, -20327.8206114649109, 63861.4335397379033, 40487.2831296029499}, {-0.5, 0.0, -4.25, 0.0, -0.441427843410865187, 0.0, -0.665497904840929966, 0.0, -0.162969337925229287, 0.0}, {-0.5, 0.0, 3.5, 0.0, -0.232043460812781422, 0.63203565652521718, -2.44367789279529917, 0.119367210264842707, -0.763914228371074801, -2.81228485141461073}, {-0.5, 0.0, 0.0, -1.0, -0.537549381115898973, -0.27517974122882025, 0.0158915835170861709, -0.505981074388456133, 0.147999289996985447, 0.105632732120539676}, {-0.5, 0.0, 0.125, 0.125, 0.116021225799463628, 0.175602658223910358, 0.0105539353881710306, -0.0374742285737420805, -0.0062875342272019156, 0.0142081398192247589}, {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {1.0, 0.0, -0.5, 0.0, -0.405465108108164382, 0.0, -0.0556552111040376179, 0.0, 0.0145754167941056437, 0.0}, {1.0, 0.0, 0.99609375, 0.0, 5.54517744447956248, 0.0, -13.0766609768056118, 0.0, 24.0940545588450487, 0.0}, {1.0, 0.0, 1.00390625, 0.0, 5.54517744447956248, -3.14159265358979324, -8.16844417312495553, 15.6134381896777968, -0.38789687903338657, -36.2148484363837508}, {1.0, 0.0, -4.25, 0.0, -1.65822807660353238, 0.0, -0.861140718490863904, 0.0, 0.0240108114276114004, 0.0}, {1.0, 0.0, 3.5, 0.0, -0.916290731874155065, -3.14159265358979324, 2.57284574234941582, -2.52133906787958123, 1.44241441233798233, 1.57208443290129947}, {1.0, 0.0, 0.0, -1.0, -0.346573590279972655, -0.78539816339744831, 0.160292055087885226, -0.192901316796912429, -0.0115066749133700615, 0.0770708622146679417}, {1.0, 0.0, 0.125, 0.125, 0.123430038965762899, 0.141897054604163923, 0.00180689203856968544, -0.0122114794810442984, -0.00105066979284378462, 0.00449853805632375062}, {2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {2.0, 0.0, -0.5, 0.0, -0.448414206923646202, 0.0, -0.0320237060779612787, 0.0, 0.0092536571135294828, 0.0}, {2.0, 0.0, 0.99609375, 0.0, 1.61932072927810507, 0.0, -0.863010139919679163, 0.0, 0.825515949454683347, 0.0}, {2.0, 0.0, 1.00390625, 0.0, 1.6704551616562229, -0.0122479400888173039, -0.992661633138610541, 0.0731191212424626706, 1.04852574935488925, -0.214307793003452771}, {2.0, 0.0, -4.25, 0.0, -2.46898738747224279, 0.0, -0.739287387997829118, 0.0, 0.0874470644522297429, 0.0}, {2.0, 0.0, 3.5, 0.0, 2.1959348115757808, -3.93567093851438969, 2.87640729249480637, 0.777030723254221356, -0.81939570865486996, 1.19241843763256774}, {2.0, 0.0, 0.0, -1.0, -0.205616758356028305, -0.915965594177219015, 0.117193531789480469, -0.0815807361165927951, -0.0255408233794369879, 0.0372076062178391175}, {2.0, 0.0, 0.125, 0.125, 0.124500148439393858, 0.133240721203487057, 0.000569113907620539642, -0.00588251562210034232, -0.000326714635669985778, 0.00213086661076891839}, {-2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-2.0, 2.0, -0.5, 0.0, -0.132203419506655614, -0.390689361106274866, -0.256343261725123592, 0.106175177622871437, 0.0749290443999118563, 0.0319207027895210173}, {-2.0, 2.0, 0.99609375, 0.0, 13841369.6929212372, -8339597.62269406988, -87251051.2148652244, 65225350.0315463319, 273254167.909661771, -247710863.316563213}, {-2.0, 2.0, 1.00390625, 0.0, -26028.6661639721745, 15961.1559569935978, 113847.512122984734, -206358.723605581203, 6578.40068463757013, 908971.828153761815}, {-2.0, 2.0, -4.25, 0.0, 1.26205464628714387, 0.274313692011971484, 0.442242006131113713, -1.61799252235272836, -0.927785295033312282, -0.172205994085466244}, {-2.0, 2.0, 3.5, 0.0, 0.0870998538268457367, 0.0980699787750225838, 0.152937181587789832, -0.0211963252018165386, 0.0431921445114569281, -0.0695183434413184998}, {-2.0, 2.0, 0.0, -1.0, 0.199312975007554535, -0.0775592701795263651, -0.0210851901426345675, -0.167326332453265841, -0.0632997708310078762, -0.0392019115527122943}, {-2.0, 2.0, 0.125, 0.125, 0.315234332693229892, 0.165559827416958489, -0.16530664867351669, -0.0392852937947218337, 0.0780220225006149953, 0.0215283250955342792}, }; int main() { slong iter; flint_rand_t state; flint_printf("polylog_cpx...."); fflush(stdout); flint_randinit(state); /* check particular values against table */ { acb_t s, z, t; acb_ptr w1, w2; slong i, j, prec; acb_init(s); acb_init(z); acb_init(t); w1 = _acb_vec_init(NUM_DERIVS); w2 = _acb_vec_init(NUM_DERIVS); for (prec = 32; prec <= 512; prec *= 4) { for (i = 0; i < NUM_TESTS; i++) { acb_zero(s); arf_set_d(arb_midref(acb_realref(s)), polylog_testdata[i][0]); arf_set_d(arb_midref(acb_imagref(s)), polylog_testdata[i][1]); acb_zero(z); arf_set_d(arb_midref(acb_realref(z)), polylog_testdata[i][2]); arf_set_d(arb_midref(acb_imagref(z)), polylog_testdata[i][3]); _acb_poly_polylog_cpx_small(w1, s, z, NUM_DERIVS, prec); _acb_poly_polylog_cpx_zeta(w2, s, z, NUM_DERIVS, prec); for (j = 0; j < NUM_DERIVS; j++) { arf_set_d(arb_midref(acb_realref(t)), polylog_testdata[i][4+2*j]); mag_set_d(arb_radref(acb_realref(t)), fabs(polylog_testdata[i][4+2*j]) * EPS); arf_set_d(arb_midref(acb_imagref(t)), polylog_testdata[i][4+2*j+1]); mag_set_d(arb_radref(acb_imagref(t)), fabs(polylog_testdata[i][4+2*j+1]) * EPS); if (!acb_overlaps(w1 + j, t) || !acb_overlaps(w2 + j, t) || !acb_overlaps(w1 + j, w2 + j)) { flint_printf("FAIL\n\n"); flint_printf("s = "); acb_printd(s, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 15); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1 + j, 15); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2 + j, 15); flint_printf("\n\n"); flint_abort(); } } } } _acb_vec_clear(w1, NUM_DERIVS); _acb_vec_clear(w2, NUM_DERIVS); acb_clear(s); acb_clear(z); acb_clear(t); } for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { acb_t s, z; acb_ptr w1, w2; slong i, len1, len2, prec1, prec2; acb_init(s); acb_init(z); if (n_randint(state, 2)) acb_randtest(s, state, 1 + n_randint(state, 300), 3); else acb_set_si(s, n_randint(state, 20) - 10); switch (n_randint(state, 3)) { case 0: acb_randtest(z, state, 1 + n_randint(state, 300), 10); break; case 1: arb_randtest(acb_realref(z), state, 1 + n_randint(state, 300), 10); break; case 2: acb_one(z); break; } prec1 = 2 + n_randint(state, 300); prec2 = prec1 + 30; len1 = 1 + n_randint(state, 20); len2 = 1 + n_randint(state, 20); w1 = _acb_vec_init(len1); w2 = _acb_vec_init(len2); switch (n_randint(state, 5)) { case 0: _acb_poly_polylog_cpx_small(w1, s, z, len1, prec1); break; case 1: _acb_poly_polylog_cpx_zeta(w1, s, z, len1, prec1); break; default: _acb_poly_polylog_cpx(w1, s, z, len1, prec1); break; } switch (n_randint(state, 5)) { case 0: _acb_poly_polylog_cpx_small(w2, s, z, len2, prec2); break; case 1: _acb_poly_polylog_cpx_zeta(w2, s, z, len2, prec2); break; default: _acb_poly_polylog_cpx(w2, s, z, len2, prec2); break; } for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(w1 + i, w2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("len1 = %wd, len2 = %wd, i = %wd\n\n", len1, len2, i); flint_printf("s = "); acb_printd(s, prec1 / 3.33); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, prec1 / 3.33); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1 + i, prec1 / 3.33); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2 + i, prec2 / 3.33); flint_printf("\n\n"); flint_abort(); } } acb_clear(s); acb_clear(z); _acb_vec_clear(w1, len1); _acb_vec_clear(w2, len2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-polylog_series.c000066400000000000000000000045131417376376500206030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("polylog_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t z; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(z); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_randtest(z, state, bits1, 3); acb_poly_polylog_series(A, S, z, n1, bits2); acb_poly_polylog_series(B, S, z, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_polylog_series(S, S, z, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-pow_acb_series.c000066400000000000000000000052551417376376500205340ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_acb_series...."); fflush(stdout); flint_randinit(state); /* compare with exp/log */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong prec, trunc; acb_poly_t f, g, h1, h2; acb_t c; prec = 2 + n_randint(state, 200); trunc = n_randint(state, 20); acb_poly_init(f); acb_poly_init(g); acb_poly_init(h1); acb_poly_init(h2); acb_init(c); /* generate binomials */ if (n_randint(state, 20) == 0) { acb_randtest(c, state, prec, 10); acb_poly_set_coeff_acb(f, 0, c); acb_randtest(c, state, prec, 10); acb_poly_set_coeff_acb(f, 1 + n_randint(state, 20), c); } else { acb_poly_randtest(f, state, 1 + n_randint(state, 20), prec, 10); } acb_poly_randtest(h1, state, 1 + n_randint(state, 20), prec, 10); acb_randtest(c, state, prec, 10); acb_poly_set_acb(g, c); /* f^c */ acb_poly_pow_acb_series(h1, f, c, trunc, prec); /* f^c = exp(c*log(f)) */ acb_poly_log_series(h2, f, trunc, prec); acb_poly_mullow(h2, h2, g, trunc, prec); acb_poly_exp_series(h2, h2, trunc, prec); if (!acb_poly_overlaps(h1, h2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("trunc = %wd\n", trunc); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("h1 = "); acb_poly_printd(h1, 15); flint_printf("\n\n"); flint_printf("h2 = "); acb_poly_printd(h2, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_pow_acb_series(f, f, c, trunc, prec); if (!acb_poly_overlaps(f, h1)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_poly_clear(h1); acb_poly_clear(h2); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-pow_series.c000066400000000000000000000055551417376376500177320ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong rbits1, rbits2, len; acb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); len = n_randint(state, 25); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); if (n_randint(state, 4) == 0) acb_poly_randtest(a, state, 1, rbits1, 25); else acb_poly_randtest(a, state, 1 + n_randint(state, 20), rbits1, 5); if (n_randint(state, 4) == 0) acb_poly_randtest(b, state, 1, rbits1, 25); else acb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); acb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 5); acb_poly_pow_series(c, a, b, len, rbits2); /* a^b = exp(b log a) */ acb_poly_log_series(d, a, len, rbits2); acb_poly_mullow(d, d, b, len, rbits2); acb_poly_exp_series(d, d, len, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (iter %wd)\n\n", iter); flint_printf("bits2 = %wd\n", rbits2); flint_printf("len = %wd\n", len); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* check aliasing */ if (iter < 5000) { acb_poly_set(d, a); acb_poly_pow_series(d, d, b, len, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (aliasing 1)\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_pow_series(d, a, d, len, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (aliasing 2)\n"); flint_abort(); } } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-pow_ui.c000066400000000000000000000041531417376376500170460ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_ui...."); fflush(stdout); flint_randinit(state); /* compare with fmpz_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong zbits1, rbits1, rbits2; ulong e; fmpz_poly_t A, B; acb_poly_t a, b; zbits1 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); e = n_randint(state, 30); fmpz_poly_init(A); fmpz_poly_init(B); acb_poly_init(a); acb_poly_init(b); fmpz_poly_randtest(A, state, 1 + n_randint(state, 8), zbits1); fmpz_poly_pow(B, A, e); acb_poly_set_fmpz_poly(a, A, rbits1); acb_poly_pow_ui(b, a, e, rbits2); if (!acb_poly_contains_fmpz_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("e = %wu\n", e); flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_pow_ui(a, a, e, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpz_poly_clear(A); fmpz_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-pow_ui_trunc_binexp.c000066400000000000000000000044151417376376500216270ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_ui_trunc_binexp...."); fflush(stdout); flint_randinit(state); /* compare with fmpz_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong zbits1, rbits1, rbits2, trunc; ulong e; fmpz_poly_t A, B; acb_poly_t a, b; zbits1 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); e = n_randint(state, 50); trunc = n_randint(state, 40); fmpz_poly_init(A); fmpz_poly_init(B); acb_poly_init(a); acb_poly_init(b); fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), zbits1); fmpz_poly_pow_trunc(B, A, e, trunc); acb_poly_set_fmpz_poly(a, A, rbits1); acb_poly_pow_ui_trunc_binexp(b, a, e, trunc, rbits2); if (!acb_poly_contains_fmpz_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("e = %wu\n", e); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_pow_ui_trunc_binexp(a, a, e, trunc, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpz_poly_clear(A); fmpz_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-powsum_one_series_sieved.c000066400000000000000000000046001417376376500226450ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("powsum_one_series_sieved...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t s, a, q; acb_ptr z1, z2; slong i, n, len, prec; acb_init(s); acb_init(a); acb_init(q); if (n_randint(state, 2)) { acb_randtest(s, state, 1 + n_randint(state, 200), 3); } else { arb_set_ui(acb_realref(s), 1); arb_mul_2exp_si(acb_realref(s), acb_realref(s), -1); arb_randtest(acb_imagref(s), state, 1 + n_randint(state, 200), 4); } acb_one(a); acb_one(q); prec = 2 + n_randint(state, 200); n = n_randint(state, 100); len = 1 + n_randint(state, 10); z1 = _acb_vec_init(len); z2 = _acb_vec_init(len); _acb_poly_powsum_series_naive(z1, s, a, q, n, len, prec); _acb_poly_powsum_one_series_sieved(z2, s, n, len, prec); for (i = 0; i < len; i++) { if (!acb_overlaps(z1 + i, z2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("n = %wd, prec = %wd, len = %wd, i = %wd\n\n", n, prec, len, i); flint_printf("s = "); acb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, prec / 3.33); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1 + i, prec / 3.33); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2 + i, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } acb_clear(a); acb_clear(s); acb_clear(q); _acb_vec_clear(z1, len); _acb_vec_clear(z2, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-powsum_series_naive_threaded.c000066400000000000000000000054071417376376500234750ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("powsum_series_naive_threaded...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t s, a, q; acb_ptr z1, z2; slong i, n, len, prec; acb_init(s); acb_init(a); acb_init(q); if (n_randint(state, 2)) { acb_randtest(s, state, 1 + n_randint(state, 200), 3); } else { arb_set_ui(acb_realref(s), 1); arb_mul_2exp_si(acb_realref(s), acb_realref(s), -1); arb_randtest(acb_imagref(s), state, 1 + n_randint(state, 200), 4); } if (n_randint(state, 2)) acb_one(a); else acb_randtest(a, state, 1 + n_randint(state, 200), 3); if (n_randint(state, 2)) acb_one(q); else acb_randtest(q, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); n = n_randint(state, 100); len = 1 + n_randint(state, 10); z1 = _acb_vec_init(len); z2 = _acb_vec_init(len); _acb_poly_powsum_series_naive(z1, s, a, q, n, len, prec); flint_set_num_threads(1 + n_randint(state, 3)); _acb_poly_powsum_series_naive_threaded(z2, s, a, q, n, len, prec); for (i = 0; i < len; i++) { if (!acb_overlaps(z1 + i, z2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("n = %wd, prec = %wd, len = %wd, i = %wd\n\n", n, prec, len, i); flint_printf("s = "); acb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, prec / 3.33); flint_printf("\n\n"); flint_printf("q = "); acb_printd(q, prec / 3.33); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1 + i, prec / 3.33); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2 + i, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } acb_clear(a); acb_clear(s); acb_clear(q); _acb_vec_clear(z1, len); _acb_vec_clear(z2, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-product_roots.c000066400000000000000000000042321417376376500204500ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("product_roots...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong prec, len, m, i; acb_poly_t a, b, c, d; acb_ptr r; prec = 2 + n_randint(state, 200); len = n_randint(state, 12); if (len > 0) m = n_randint(state, len); else m = 0; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); r = _acb_vec_init(len); for (i = 0; i < len; i++) acb_randtest(r + i, state, 1 + n_randint(state, 200), 10); acb_poly_product_roots(a, r, len, prec); acb_poly_product_roots(b, r, m, prec); acb_poly_product_roots(c, r + m, len - m, prec); acb_poly_mul(d, b, c, prec); if (!acb_poly_overlaps(a, d)) { flint_printf("FAIL\n\n"); flint_printf("len = %wd, m = %wd\n\n", len, m); for (i = 0; i < len; i++) { acb_printd(r + i, 15); flint_printf("\n"); } flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); _acb_vec_clear(r, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-revert_series.c000066400000000000000000000044251417376376500204270ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; acb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_revert_series(b, a, n, rbits2); if (!acb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(c, a); acb_poly_revert_series(c, c, n, rbits2); if (!acb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-revert_series_lagrange.c000066400000000000000000000044601417376376500222660ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series_lagrange...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; acb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_revert_series_lagrange(b, a, n, rbits2); if (!acb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(c, a); acb_poly_revert_series_lagrange(c, c, n, rbits2); if (!acb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-revert_series_lagrange_fast.c000066400000000000000000000044771417376376500233130ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series_lagrange_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; acb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_revert_series_lagrange_fast(b, a, n, rbits2); if (!acb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(c, a); acb_poly_revert_series_lagrange_fast(c, c, n, rbits2); if (!acb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-revert_series_newton.c000066400000000000000000000044521417376376500220210ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series_newton...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; acb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_revert_series_newton(b, a, n, rbits2); if (!acb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(c, a); acb_poly_revert_series_newton(c, c, n, rbits2); if (!acb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-rgamma_series.c000066400000000000000000000056401417376376500203640ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rgamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; acb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, rbits1, 3); acb_poly_randtest(b, state, m, rbits1, 3); acb_poly_randtest(c, state, m, rbits1, 3); acb_poly_rgamma_series(b, a, n1, rbits2); acb_poly_rgamma_series(c, a, n2, rbits3); acb_poly_set(d, b); acb_poly_truncate(d, FLINT_MIN(n1, n2)); acb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check rgamma(a) = a gamma(a+1) */ acb_poly_add_si(d, a, 1, rbits2); acb_poly_rgamma_series(d, d, n1, rbits2); acb_poly_mullow(c, d, a, n1, rbits2); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL (functional equation, n1 = %wd)\n\n", n1); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_rgamma_series(a, a, n1, rbits2); if (!acb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-rising_ui_series.c000066400000000000000000000064711417376376500211130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rising_ui_series...."); fflush(stdout); flint_randinit(state); /* check rf(f, a) * rf(f + a, b) = rf(f, a + b) */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong bits, trunc; ulong a, b; acb_poly_t f, g, h1, h2, h1h2, h3; bits = 2 + n_randint(state, 200); trunc = 1 + n_randint(state, 20); a = n_randint(state, 10); b = n_randint(state, 10); acb_poly_init(f); acb_poly_init(g); acb_poly_init(h1); acb_poly_init(h2); acb_poly_init(h1h2); acb_poly_init(h3); acb_poly_randtest(f, state, 1 + n_randint(state, 20), bits, 4); acb_poly_set(g, f); /* g = f + 1 */ if (g->length == 0) { acb_poly_fit_length(g, 1); acb_set_ui(g->coeffs, a); _acb_poly_set_length(g, 1); _acb_poly_normalise(g); } else { acb_add_ui(g->coeffs, g->coeffs, a, bits); _acb_poly_normalise(g); } acb_poly_rising_ui_series(h1, f, a, trunc, bits); acb_poly_rising_ui_series(h2, g, b, trunc, bits); acb_poly_rising_ui_series(h3, f, a + b, trunc, bits); acb_poly_mullow(h1h2, h1, h2, trunc, bits); if (!acb_poly_overlaps(h1h2, h3)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = %wu\n", a); flint_printf("b = %wu\n", a); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("h1 = "); acb_poly_printd(h1, 15); flint_printf("\n\n"); flint_printf("h2 = "); acb_poly_printd(h2, 15); flint_printf("\n\n"); flint_printf("h1h2 = "); acb_poly_printd(h1h2, 15); flint_printf("\n\n"); flint_printf("h3 = "); acb_poly_printd(h3, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_rising_ui_series(f, f, a, trunc, bits); if (!acb_poly_equal(f, h1)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = %wu\n", a); flint_printf("b = %wu\n", a); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("h1 = "); acb_poly_printd(h1, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_poly_clear(h1); acb_poly_clear(h2); acb_poly_clear(h1h2); acb_poly_clear(h3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-root_bound_fujiwara.c000066400000000000000000000044631417376376500216120ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("root_bound_fujiwara...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_poly_t a; acb_ptr roots; acb_t t; mag_t mag1, mag2; slong i, deg, prec; prec = 10 + n_randint(state, 400); deg = n_randint(state, 10); acb_init(t); acb_poly_init(a); mag_init(mag1); mag_init(mag2); roots = _acb_vec_init(deg); for (i = 0; i < deg; i++) acb_randtest(roots + i, state, prec, 1 + n_randint(state, 20)); acb_poly_product_roots(a, roots, deg, prec); acb_randtest(t, state, prec, 1 + n_randint(state, 20)); acb_poly_scalar_mul(a, a, t, prec); acb_poly_root_bound_fujiwara(mag1, a); for (i = 0; i < deg; i++) { acb_get_mag(mag2, roots + i); /* acb_get_mag gives an upper bound which due to rounding could be larger than mag1, so we pick a slightly smaller number */ mag_mul_ui(mag2, mag2, 10000); mag_div_ui(mag2, mag2, 10001); if (mag_cmp(mag2, mag1) > 0) { flint_printf("FAIL\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("root = "); acb_printd(roots + i, 15); flint_printf("\n\n"); flint_printf("mag1 = "); mag_printd(mag1, 10); flint_printf("\n\n"); flint_printf("mag2 = "); mag_printd(mag2, 10); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(roots, deg); acb_clear(t); acb_poly_clear(a); mag_clear(mag1); mag_clear(mag2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-rsqrt_series.c000066400000000000000000000044321417376376500202710ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rsqrt_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; acb_poly_t a, b, c; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); fmpq_poly_randtest_not_zero(A, state, m, qbits); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); acb_poly_rsqrt_series(b, a, n, rbits2); /* Check 1/((1/sqrt(a))^2) = a */ acb_poly_mullow(c, b, b, n, rbits2); acb_poly_inv_series(c, c, n, rbits2); fmpq_poly_truncate(A, n); if (!acb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_rsqrt_series(a, a, n, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-set_trunc_round.c000066400000000000000000000044151417376376500207620ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main(void) { int iter; flint_rand_t state; flint_printf("set_trunc_round...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d, e; slong n, prec; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); acb_poly_randtest(a, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); acb_poly_randtest(b, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); acb_poly_randtest(c, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); acb_poly_randtest(d, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); acb_poly_randtest(e, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); n = n_randint(state, 10); prec = 2 + n_randint(state, 200); acb_poly_set_trunc(b, a, n); acb_poly_set_round(b, b, prec); acb_poly_set_round(c, a, prec); acb_poly_set_trunc(c, c, n); acb_poly_set_trunc_round(d, a, n, prec); acb_poly_set(e, a); acb_poly_set_trunc_round(e, e, n, prec); if (!acb_poly_equal(b, c) || !acb_poly_equal(c, d) || !acb_poly_equal(d, e)) { flint_printf("FAIL\n\n"); acb_poly_printd(a, 50), flint_printf("\n\n"); acb_poly_printd(b, 50), flint_printf("\n\n"); acb_poly_printd(c, 50), flint_printf("\n\n"); acb_poly_printd(d, 50), flint_printf("\n\n"); acb_poly_printd(e, 50), flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/acb_poly/test/t-shift_left_right.c000066400000000000000000000055731417376376500210770ustar00rootroot00000000000000/* Copyright (C) 2009 William Hart Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main(void) { int i, result; flint_rand_t state; flint_printf("shift_left/right...."); fflush(stdout); flint_randinit(state); /* Check aliasing of a and b for left shift */ for (i = 0; i < 1000; i++) { acb_poly_t a, b; slong shift = n_randint(state, 100); acb_poly_init(a); acb_poly_init(b); acb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); acb_poly_shift_left(b, a, shift); acb_poly_shift_left(a, a, shift); result = (acb_poly_equal(a, b)); if (!result) { flint_printf("FAIL:\n"); acb_poly_printd(a, 10), flint_printf("\n\n"); acb_poly_printd(b, 10), flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); } /* Check aliasing of a and b for right shift */ for (i = 0; i < 1000; i++) { acb_poly_t a, b; slong shift = n_randint(state, 100); acb_poly_init(a); acb_poly_init(b); acb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); acb_poly_shift_right(b, a, shift); acb_poly_shift_right(a, a, shift); result = (acb_poly_equal(a, b)); if (!result) { flint_printf("FAIL:\n"); acb_poly_printd(a, 10), flint_printf("\n\n"); acb_poly_printd(b, 10), flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); } /* Check shift left then right does nothing */ for (i = 0; i < 1000; i++) { acb_poly_t a, b, c; slong shift = n_randint(state, 100); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); acb_poly_shift_left(b, a, shift); acb_poly_shift_right(c, b, shift); result = (acb_poly_equal(c, a)); if (!result) { flint_printf("FAIL:\n"); acb_poly_printd(a, 10), flint_printf("\n\n"); acb_poly_printd(b, 10), flint_printf("\n\n"); acb_poly_printd(c, 10), flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/acb_poly/test/t-sin_cos_pi_series.c000066400000000000000000000053551417376376500212500ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; acb_poly_t a, b, c, d, e; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); fmpq_poly_randtest(A, state, m, qbits); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_sin_cos_pi_series(b, c, a, n, rbits2); /* Check sin(x)^2 + cos(x)^2 = 1 */ acb_poly_mullow(d, b, b, n, rbits2); acb_poly_mullow(e, c, c, n, rbits2); acb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!acb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_pi_series(d, c, d, n, rbits2); if (!acb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_pi_series(b, d, d, n, rbits2); if (!acb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sin_cos_series.c000066400000000000000000000047771417376376500205670ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, rbits1, rbits2; fmpq_poly_t B; acb_poly_t a, b, c, d, e; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_sin_cos_series(b, c, a, n, rbits2); /* Check sin(x)^2 + cos(x)^2 = 1 */ acb_poly_mullow(d, b, b, n, rbits2); acb_poly_mullow(e, c, c, n, rbits2); acb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!acb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_series(d, c, d, n, rbits2); if (!acb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_series(b, d, d, n, rbits2); if (!acb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sin_cos_series_basecase.c000066400000000000000000000051771417376376500224100ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_series_basecase...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, rbits1, rbits2; fmpq_poly_t B; acb_poly_t a, b, c, d, e; int times_pi; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); times_pi = n_randint(state, 2); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_sin_cos_series_basecase(b, c, a, n, rbits2, times_pi); /* Check sin(x)^2 + cos(x)^2 = 1 */ acb_poly_mullow(d, b, b, n, rbits2); acb_poly_mullow(e, c, c, n, rbits2); acb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!acb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_series_basecase(d, c, d, n, rbits2, times_pi); if (!acb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_series_basecase(b, d, d, n, rbits2, times_pi); if (!acb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sin_cos_series_tangent.c000066400000000000000000000051731417376376500222760ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_series_tangent...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, rbits1, rbits2; fmpq_poly_t B; acb_poly_t a, b, c, d, e; int times_pi; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); times_pi = n_randint(state, 2); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_sin_cos_series_tangent(b, c, a, n, rbits2, times_pi); /* Check sin(x)^2 + cos(x)^2 = 1 */ acb_poly_mullow(d, b, b, n, rbits2); acb_poly_mullow(e, c, c, n, rbits2); acb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!acb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_series_tangent(d, c, d, n, rbits2, times_pi); if (!acb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_cos_series_tangent(b, d, d, n, rbits2, times_pi); if (!acb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sin_pi_series.c000066400000000000000000000044631417376376500204030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t pi; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(pi); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_poly_sin_pi_series(A, S, n1, bits2); acb_const_pi(pi, bits3); acb_poly_set_acb(B, pi); acb_poly_mul(B, S, B, bits3); acb_poly_sin_series(B, B, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_sin_pi_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(pi); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sin_series_cos_series.c000066400000000000000000000050371417376376500221270ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_series/cos_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, rbits1, rbits2; fmpq_poly_t B; acb_poly_t a, b, c, d, e; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(B); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_sin_series(b, a, n, rbits2); acb_poly_cos_series(c, a, n, rbits2); /* Check sin(x)^2 + cos(x)^2 = 1 */ acb_poly_mullow(d, b, b, n, rbits2); acb_poly_mullow(e, c, c, n, rbits2); acb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!acb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sin_series(d, d, n, rbits2); if (!acb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_cos_series(d, d, n, rbits2); if (!acb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(B); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sinc_series.c000066400000000000000000000055141417376376500200540ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sinc_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; acb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 300); rbits2 = 2 + n_randint(state, 300); rbits3 = 2 + n_randint(state, 300); m = n_randint(state, 15); n1 = n_randint(state, 15); n2 = n_randint(state, 15); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_randtest(b, state, 10, rbits1, 10); acb_poly_randtest(c, state, 10, rbits1, 10); acb_poly_sinc_series(b, a, n1, rbits2); acb_poly_sinc_series(c, a, n2, rbits3); acb_poly_set(d, b); acb_poly_truncate(d, FLINT_MIN(n1, n2)); acb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); acb_poly_printd(a, 50); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 50); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 50); flint_printf("\n\n"); flint_abort(); } /* check x sinc(x) = sin(x) */ acb_poly_mullow(c, b, a, n1, rbits2); acb_poly_sin_series(d, a, n1, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_sinc_series(a, a, n1, rbits2); if (!acb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sinh_cosh_series.c000066400000000000000000000100251417376376500210660ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sinh_cosh_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d, e; slong n1, n2, prec; int alg1, alg2; prec = 2 + n_randint(state, 200); if (n_randint(state, 40) == 0) { n1 = n_randint(state, 300); n2 = n_randint(state, 300); } else { n1 = n_randint(state, 30); n2 = n_randint(state, 30); } acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); acb_poly_randtest(a, state, 20, prec, 3); acb_poly_randtest(b, state, 20, prec, 10); acb_poly_randtest(c, state, 20, prec, 10); acb_poly_randtest(d, state, 20, prec, 10); acb_poly_randtest(e, state, 20, prec, 10); alg1 = n_randint(state, 4); alg2 = n_randint(state, 7); switch (alg1) { case 0: acb_poly_sinh_cosh_series(b, c, a, n1, prec); break; case 1: acb_poly_sinh_cosh_series_basecase(b, c, a, n1, prec); break; case 2: acb_poly_sinh_cosh_series_exponential(b, c, a, n1, prec); break; default: acb_poly_sinh_series(b, a, n1, prec); acb_poly_cosh_series(c, a, n1, prec); break; } switch (alg2) { case 0: acb_poly_sinh_cosh_series(d, e, a, n2, prec); break; case 1: acb_poly_sinh_cosh_series_basecase(d, e, a, n2, prec); break; case 2: acb_poly_sinh_cosh_series_exponential(d, e, a, n2, prec); break; case 3: acb_poly_sinh_series(d, a, n2, prec); acb_poly_cosh_series(e, a, n2, prec); break; case 4: acb_poly_set(d, a); acb_poly_sinh_cosh_series(d, e, d, n2, prec); break; case 5: acb_poly_set(e, a); acb_poly_sinh_cosh_series(d, e, e, n2, prec); break; default: acb_poly_set(d, a); acb_poly_sinh_series(d, d, n2, prec); acb_poly_set(e, a); acb_poly_cosh_series(e, e, n2, prec); break; } acb_poly_truncate(b, FLINT_MIN(n1, n2)); acb_poly_truncate(c, FLINT_MIN(n1, n2)); acb_poly_truncate(d, FLINT_MIN(n1, n2)); acb_poly_truncate(e, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(b, d) || !acb_poly_overlaps(c, e)) { flint_printf("FAIL\n\n"); flint_printf("alg1 = %d, alg2 = %d, n1 = %wd, n2 = %wd\n\n", alg1, alg2, n1, n2); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(e, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sqrt_series.c000066400000000000000000000042261417376376500201100ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; acb_poly_t a, b, c; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); fmpq_poly_randtest_not_zero(A, state, m, qbits); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_sqrt_series(b, a, n, rbits2); /* Check sqrt(a)^2 = a */ acb_poly_mullow(c, b, b, n, rbits2); fmpq_poly_truncate(A, n); if (!acb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_sqrt_series(a, a, n, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sub.c000066400000000000000000000055641417376376500163440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sub...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; acb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_sub(C, A, B); acb_poly_set_fmpq_poly(a, A, rbits1); acb_poly_set_fmpq_poly(b, B, rbits2); acb_poly_sub(c, a, b, rbits3); if (!acb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sub(d, d, b, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_sub(d, a, d, rbits3); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-sub_series.c000066400000000000000000000044531417376376500177120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t a, b, c, d; slong len, prec; acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, 1 + n_randint(state, 10), 100, 10); acb_poly_randtest(b, state, 1 + n_randint(state, 10), 100, 10); acb_poly_randtest(c, state, 1 + n_randint(state, 10), 100, 10); acb_poly_randtest(d, state, 1 + n_randint(state, 10), 100, 10); prec = 2 + n_randint(state, 100); len = n_randint(state, 10); acb_poly_sub_series(c, a, b, len, prec); acb_poly_sub(d, a, b, prec); acb_poly_truncate(d, len); if (!acb_poly_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_set(d, a); acb_poly_sub_series(d, d, b, len, prec); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } acb_poly_set(d, b); acb_poly_sub_series(d, a, d, len, prec); if (!acb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-tan_series.c000066400000000000000000000046401417376376500177010ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("tan_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong m, n, rbits1, rbits2; acb_poly_t a, b, c, d, e; rbits1 = 2 + n_randint(state, 100); rbits2 = 2 + n_randint(state, 100); if (n_randint(state, 10) == 0) { m = 1 + n_randint(state, 50); n = 1 + n_randint(state, 50); } else { m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); } acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_init(e); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_tan_series(b, a, n, rbits2); /* check tan(x) = 2*tan(x/2)/(1-tan(x/2)^2) */ acb_poly_scalar_mul_2exp_si(c, a, -1); acb_poly_tan_series(c, c, n, rbits2); acb_poly_mullow(d, c, c, n, rbits2); acb_poly_one(e); acb_poly_sub(e, e, d, rbits2); acb_poly_div_series(c, c, e, n, rbits2); acb_poly_scalar_mul_2exp_si(c, c, 1); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_tan_series(a, a, n, rbits2); if (!acb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); acb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-taylor_shift.c000066400000000000000000000044561417376376500202610ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong prec1, prec2; acb_poly_t f, g; acb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_poly_init(f); acb_poly_init(g); acb_init(c); acb_init(d); acb_init(e); acb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); acb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) acb_set_si(c, n_randint(state, 5) - 2); else acb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) acb_set_si(d, n_randint(state, 5) - 2); else acb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ acb_poly_taylor_shift(g, f, e, prec2); acb_poly_taylor_shift(f, f, c, prec1); acb_poly_taylor_shift(f, f, d, prec1); if (!acb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-taylor_shift_convolution.c000066400000000000000000000045361417376376500227170ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift_convolution...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong prec1, prec2; acb_poly_t f, g; acb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_poly_init(f); acb_poly_init(g); acb_init(c); acb_init(d); acb_init(e); acb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); acb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) acb_set_si(c, n_randint(state, 5) - 2); else acb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) acb_set_si(d, n_randint(state, 5) - 2); else acb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ acb_poly_taylor_shift_convolution(g, f, e, prec2); acb_poly_taylor_shift_convolution(f, f, c, prec1); acb_poly_taylor_shift_convolution(f, f, d, prec1); if (!acb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-taylor_shift_divconquer.c000066400000000000000000000045321417376376500225130ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift_divconquer...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong prec1, prec2; acb_poly_t f, g; acb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_poly_init(f); acb_poly_init(g); acb_init(c); acb_init(d); acb_init(e); acb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); acb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) acb_set_si(c, n_randint(state, 5) - 2); else acb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) acb_set_si(d, n_randint(state, 5) - 2); else acb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ acb_poly_taylor_shift_divconquer(g, f, e, prec2); acb_poly_taylor_shift_divconquer(f, f, c, prec1); acb_poly_taylor_shift_divconquer(f, f, d, prec1); if (!acb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-taylor_shift_horner.c000066400000000000000000000045121417376376500216270ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong prec1, prec2; acb_poly_t f, g; acb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); acb_poly_init(f); acb_poly_init(g); acb_init(c); acb_init(d); acb_init(e); acb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); acb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) acb_set_si(c, n_randint(state, 5) - 2); else acb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) acb_set_si(d, n_randint(state, 5) - 2); else acb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); acb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ acb_poly_taylor_shift_horner(g, f, e, prec2); acb_poly_taylor_shift_horner(f, f, c, prec1); acb_poly_taylor_shift_horner(f, f, d, prec1); if (!acb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); acb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); acb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(f); acb_poly_clear(g); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-zeta_cpx_series.c000066400000000000000000000053121417376376500207310ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_cpx_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t s, a; acb_ptr z1, z2; slong i, len, prec1, prec2; int deflate; acb_init(s); acb_init(a); if (n_randint(state, 2)) { acb_randtest(s, state, 1 + n_randint(state, 300), 3); } else { arb_set_ui(acb_realref(s), 1); arb_mul_2exp_si(acb_realref(s), acb_realref(s), -1); arb_randtest(acb_imagref(s), state, 1 + n_randint(state, 300), 4); } switch (n_randint(state, 3)) { case 0: acb_randtest(a, state, 1 + n_randint(state, 300), 3); break; case 1: arb_randtest(acb_realref(a), state, 1 + n_randint(state, 300), 3); break; case 2: acb_one(a); break; } prec1 = 2 + n_randint(state, 300); prec2 = prec1 + 30; len = 1 + n_randint(state, 20); deflate = n_randint(state, 2); z1 = _acb_vec_init(len); z2 = _acb_vec_init(len); _acb_poly_zeta_cpx_series(z1, s, a, deflate, len, prec1); _acb_poly_zeta_cpx_series(z2, s, a, deflate, len, prec2); for (i = 0; i < len; i++) { if (!acb_overlaps(z1 + i, z2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("deflate = %d, len = %wd, i = %wd\n\n", deflate, len, i); flint_printf("s = "); acb_printd(s, prec1 / 3.33); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, prec1 / 3.33); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1 + i, prec1 / 3.33); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2 + i, prec2 / 3.33); flint_printf("\n\n"); flint_abort(); } } acb_clear(a); acb_clear(s); _acb_vec_clear(z1, len); _acb_vec_clear(z2, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-zeta_em_tail_bsplit.c000066400000000000000000000042071417376376500215560ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_em_tail_bsplit...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t Na, s; acb_ptr z1, z2, Nasx; slong i, M, len, prec; prec = 2 + n_randint(state, 400); len = 1 + n_randint(state, 30); M = n_randint(state, 40); acb_init(Na); acb_init(s); Nasx = _acb_vec_init(len); z1 = _acb_vec_init(len); z2 = _acb_vec_init(len); acb_randtest(Na, state, prec, 4); acb_randtest(s, state, prec, 4); _acb_poly_acb_invpow_cpx(Nasx, Na, s, len, prec); _acb_poly_zeta_em_tail_naive(z1, s, Na, Nasx, M, len, prec); _acb_poly_zeta_em_tail_bsplit(z2, s, Na, Nasx, M, len, prec); for (i = 0; i < len; i++) { if (!acb_overlaps(z1 + i, z2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd\n", iter); flint_printf("prec = %wd, len = %wd, M = %wd\n", prec, len, M); flint_printf("s = "); acb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_printf("Na = "); acb_printd(Na, prec / 3.33); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1 + i, prec / 3.33); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2 + i, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } acb_clear(Na); acb_clear(s); _acb_vec_clear(z1, len); _acb_vec_clear(z2, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/test/t-zeta_series.c000066400000000000000000000071161417376376500200630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 400 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; int deflate; acb_poly_t S, A, B, C, D, E, F; acb_t a, a1; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 25); n1 = 1 + n_randint(state, 25); n2 = 1 + n_randint(state, 25); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_init(D); acb_poly_init(E); acb_poly_init(F); acb_init(a); acb_init(a1); deflate = n_randint(state, 2); acb_poly_randtest(S, state, m, bits1, 3); arb_randtest_precise(acb_realref(a), state, bits1, 3); arb_randtest_precise(acb_imagref(a), state, bits1, 3); acb_poly_set_coeff_acb(S, 0, a); if (n_randint(state, 2)) acb_randtest(a, state, bits1, 3); else acb_one(a); acb_poly_zeta_series(A, S, a, deflate, n1, bits2); acb_poly_zeta_series(B, S, a, deflate, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } /* check zeta(s,a) = zeta(s,a+1) + a^(-s) */ acb_poly_set_acb(D, a); acb_poly_log_series(D, D, n1, bits2); acb_poly_mullow(D, D, S, n1, bits2); acb_poly_neg(D, D); acb_poly_exp_series(D, D, n1, bits2); acb_add_ui(a1, a, 1, bits2); acb_poly_zeta_series(E, S, a1, deflate, n1, bits2); acb_poly_add(E, E, D, bits2); if (!acb_poly_overlaps(A, E)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("E = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_zeta_series(S, S, a, deflate, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_poly_clear(D); acb_poly_clear(E); acb_poly_clear(F); acb_clear(a); acb_clear(a1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/acb_poly/tree.c000066400000000000000000000047641417376376500152730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" acb_ptr * _acb_poly_tree_alloc(slong len) { acb_ptr * tree = NULL; if (len) { slong i, height = FLINT_CLOG2(len); tree = flint_malloc(sizeof(acb_ptr) * (height + 1)); for (i = 0; i <= height; i++) tree[i] = _acb_vec_init(len + (len >> i) + 1); } return tree; } void _acb_poly_tree_free(acb_ptr * tree, slong len) { if (len) { slong i, height = FLINT_CLOG2(len); for (i = 0; i <= height; i++) _acb_vec_clear(tree[i], len + (len >> i) + 1); flint_free(tree); } } void _acb_poly_tree_build(acb_ptr * tree, acb_srcptr roots, slong len, slong prec) { slong height, pow, left, i; acb_ptr pa, pb; acb_srcptr a, b; if (len == 0) return; height = FLINT_CLOG2(len); /* zeroth level, (x-a) */ for (i = 0; i < len; i++) { acb_one(tree[0] + (2 * i + 1)); acb_neg(tree[0] + (2 * i), roots + i); } /* first level, (x-a)(x-b) = x^2 + (-a-b)*x + a*b */ if (height > 1) { pa = tree[1]; for (i = 0; i < len / 2; i++) { a = (acb_srcptr) (roots + (2 * i)); b = (acb_srcptr) (roots + (2 * i + 1)); acb_mul(pa + (3 * i), a, b, prec); acb_add(pa + (3 * i + 1), a, b, prec); acb_neg(pa + (3 * i + 1), pa + (3 * i + 1)); acb_one(pa + (3 * i + 2)); } if (len & 1) { acb_neg(pa + (3 * (len / 2)), roots + len - 1); acb_one(pa + (3 * (len / 2) + 1)); } } for (i = 1; i < height - 1; i++) { left = len; pow = WORD(1) << i; pa = tree[i]; pb = tree[i + 1]; while (left >= 2 * pow) { _acb_poly_mul_monic(pb, pa, pow + 1, pa + pow + 1, pow + 1, prec); left -= 2 * pow; pa += 2 * pow + 2; pb += 2 * pow + 1; } if (left > pow) { _acb_poly_mul_monic(pb, pa, pow + 1, pa + pow + 1, left - pow + 1, prec); } else if (left > 0) _acb_vec_set(pb, pa, left + 1); } } arb-2.22.1/acb_poly/validate_real_roots.c000066400000000000000000000070061417376376500203460ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #ifndef __compar_fn_t #if defined(_MSC_VER) typedef int(*__compar_fn_t) (const void *, const void *); #else typedef int(*__compar_fn_t) (__const void *, __const void *); #endif #endif int arb_cmp_mid(const arb_t a, const arb_t b) { return arf_cmp(arb_midref(a), arb_midref(b)); } void _arb_vec_sort_mid(arb_ptr vec, slong len) { qsort(vec, len, sizeof(arb_struct), (__compar_fn_t) arb_cmp_mid); } int _acb_poly_validate_real_roots(acb_srcptr roots, acb_srcptr poly, slong len, slong prec) { slong i, deg, num_real; arb_ptr real; int result; deg = len - 1; num_real = 0; result = 1; if (deg <= 1) return 1; real = _arb_vec_init(deg); /* pick out the candidate real roots */ for (i = 0; i < deg; i++) { if (arb_contains_zero(acb_imagref(roots + i))) { arb_set(real + num_real, acb_realref(roots + i)); num_real++; } } /* number of real roots must be even if the polynomial is even, and odd if the polynomial is odd (unless there are repeated roots... in which case the input is invalid) */ if ((num_real % 2) != (deg % 2)) { result = 0; } else if (num_real > 0) { int sign_neg_inf, sign_pos_inf, prev_sign; acb_t t; acb_init(t); /* by assumption that the roots are real and isolated, the lead coefficient really must be known to be either positive or negative */ sign_pos_inf = arb_is_positive(acb_realref(poly + deg)) ? 1 : -1; sign_neg_inf = (deg % 2) ? -sign_pos_inf : sign_pos_inf; /* now we check that there's a sign change between each root */ _arb_vec_sort_mid(real, num_real); prev_sign = sign_neg_inf; for (i = 0; i < num_real - 1; i++) { /* set t to the midpoint between the midpoints */ arb_zero(acb_imagref(t)); arf_add(arb_midref(acb_realref(t)), arb_midref(real + i), arb_midref(real + i + 1), prec, ARF_RND_DOWN); arf_mul_2exp_si(arb_midref(acb_realref(t)), arb_midref(acb_realref(t)), -1); mag_zero(arb_radref(acb_realref(t))); /* check that this point really is between both intervals (one interval could be much wider than the other */ if (arb_lt(real + i, acb_realref(t)) && arb_lt(acb_realref(t), real + i + 1)) { /* check sign change */ _acb_poly_evaluate(t, poly, len, t, prec); if (prev_sign == 1) result = arb_is_negative(acb_realref(t)); else result = arb_is_positive(acb_realref(t)); if (!result) break; prev_sign = -prev_sign; } else { result = 0; break; } } acb_clear(t); } _arb_vec_clear(real, deg); return result; } int acb_poly_validate_real_roots(acb_srcptr roots, const acb_poly_t poly, slong prec) { return _acb_poly_validate_real_roots(roots, poly->coeffs, poly->length, prec); } arb-2.22.1/acb_poly/validate_roots.c000066400000000000000000000036331417376376500173450ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" slong _acb_poly_validate_roots(acb_ptr roots, acb_srcptr poly, slong len, slong prec) { slong i, j, deg; slong isolated, nonisolated, total_isolated; acb_ptr deriv; acb_ptr tmp; int *overlap; deg = len - 1; deriv = _acb_vec_init(deg); overlap = flint_calloc(deg, sizeof(int)); tmp = flint_malloc(sizeof(acb_struct) * deg); _acb_poly_derivative(deriv, poly, len, prec); /* compute an inclusion interval for each point */ for (i = 0; i < deg; i++) { _acb_poly_root_inclusion(roots + i, roots + i, poly, deriv, len, prec); } /* find which points do not overlap with any other points */ for (i = 0; i < deg; i++) { for (j = i + 1; j < deg; j++) { if (acb_overlaps(roots + i, roots + j)) { overlap[i] = overlap[j] = 1; } } } /* count and move all isolated roots to the front of the array */ total_isolated = 0; for (i = 0; i < deg; i++) total_isolated += (overlap[i] == 0); for (i = 0; i < deg; i++) tmp[i] = roots[i]; isolated = 0; nonisolated = 0; for (i = 0; i < deg; i++) { if (overlap[i] == 0) { roots[isolated] = tmp[i]; isolated++; } else { roots[total_isolated + nonisolated] = tmp[i]; nonisolated++; } } _acb_vec_clear(deriv, deg); flint_free(tmp); flint_free(overlap); return isolated; } arb-2.22.1/acb_poly/valuation.c000066400000000000000000000011321417376376500163200ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" slong acb_poly_valuation(const acb_poly_t poly) { slong i, len = poly->length; for (i = 0; i < len; i++) if (!acb_is_zero(poly->coeffs + i)) return i; return -1; } arb-2.22.1/acb_poly/zeta_em_bound.c000066400000000000000000000107421417376376500171400ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" static void bound_I(arb_ptr I, const arb_t A, const arb_t B, const arb_t C, slong len, slong wp) { slong k; arb_t D, Dk, L, T, Bm1; arb_init(D); arb_init(Dk); arb_init(Bm1); arb_init(T); arb_init(L); arb_sub_ui(Bm1, B, 1, wp); arb_one(L); /* T = 1 / (A^Bm1 * Bm1) */ arb_inv(T, A, wp); arb_pow(T, T, Bm1, wp); arb_div(T, T, Bm1, wp); if (len > 1) { arb_log(D, A, wp); arb_add(D, D, C, wp); arb_mul(D, D, Bm1, wp); arb_set(Dk, D); } for (k = 0; k < len; k++) { if (k > 0) { arb_mul_ui(L, L, k, wp); arb_add(L, L, Dk, wp); arb_mul(Dk, Dk, D, wp); } arb_mul(I + k, L, T, wp); arb_div(T, T, Bm1, wp); } arb_clear(D); arb_clear(Dk); arb_clear(Bm1); arb_clear(T); arb_clear(L); } /* 0.5*(B/AN)^2 + |B|/AN */ static void bound_C(arb_t C, const arb_t AN, const arb_t B, slong wp) { arb_t t; arb_init(t); arb_abs(t, B); arb_div(t, t, AN, wp); arb_mul_2exp_si(C, t, -1); arb_add_ui(C, C, 1, wp); arb_mul(C, C, t, wp); arb_clear(t); } static void bound_K(arb_t C, const arb_t AN, const arb_t B, const arb_t T, slong wp) { if (arb_is_zero(B) || arb_is_zero(T)) { arb_one(C); } else { arb_div(C, B, AN, wp); /* TODO: atan is dumb, should also bound by pi/2 */ arb_atan(C, C, wp); arb_mul(C, C, T, wp); if (arb_is_nonpositive(C)) arb_one(C); else arb_exp(C, C, wp); } } static void bound_rfac(arb_ptr F, const acb_t s, ulong n, slong len, slong wp) { if (len == 1) { acb_rising_ui_get_mag(arb_radref(F), s, n); arf_set_mag(arb_midref(F), arb_radref(F)); mag_zero(arb_radref(F + 0)); } else { arb_struct sx[2]; arb_init(sx + 0); arb_init(sx + 1); acb_abs(sx + 0, s, wp); arb_one(sx + 1); _arb_vec_zero(F, len); _arb_poly_rising_ui_series(F, sx, 2, n, len, wp); arb_clear(sx + 0); arb_clear(sx + 1); } } void _acb_poly_zeta_em_bound(arb_ptr bound, const acb_t s, const acb_t a, ulong N, ulong M, slong len, slong wp) { arb_t K, C, AN, S2M; arb_ptr F, R; slong k; arb_srcptr alpha = acb_realref(a); arb_srcptr beta = acb_imagref(a); arb_srcptr sigma = acb_realref(s); arb_srcptr tau = acb_imagref(s); arb_init(AN); arb_init(S2M); /* require alpha + N > 1, sigma + 2M > 1 */ arb_add_ui(AN, alpha, N - 1, wp); arb_add_ui(S2M, sigma, 2*M - 1, wp); if (!arb_is_positive(AN) || !arb_is_positive(S2M) || N < 1 || M < 1) { arb_clear(AN); arb_clear(S2M); for (k = 0; k < len; k++) arb_pos_inf(bound + k); return; } /* alpha + N, sigma + 2M */ arb_add_ui(AN, AN, 1, wp); arb_add_ui(S2M, S2M, 1, wp); R = _arb_vec_init(len); F = _arb_vec_init(len); arb_init(K); arb_init(C); /* bound for power integral */ bound_C(C, AN, beta, wp); bound_K(K, AN, beta, tau, wp); bound_I(R, AN, S2M, C, len, wp); for (k = 0; k < len; k++) { arb_mul(R + k, R + k, K, wp); arb_div_ui(K, K, k + 1, wp); } /* bound for rising factorial */ bound_rfac(F, s, 2*M, len, wp); /* product (TODO: only need upper bound; write a function for this) */ _arb_poly_mullow(bound, F, len, R, len, len, wp); /* bound for bernoulli polynomials, 4 / (2pi)^(2M) */ arb_const_pi(C, wp); arb_mul_2exp_si(C, C, 1); arb_pow_ui(C, C, 2 * M, wp); arb_ui_div(C, 4, C, wp); _arb_vec_scalar_mul(bound, bound, len, C, wp); arb_clear(K); arb_clear(C); arb_clear(AN); arb_clear(S2M); _arb_vec_clear(R, len); _arb_vec_clear(F, len); } void _acb_poly_zeta_em_bound1(mag_t bound, const acb_t s, const acb_t a, slong N, slong M, slong len, slong wp) { arb_ptr vec = _arb_vec_init(len); _acb_poly_zeta_em_bound(vec, s, a, N, M, len, wp); _arb_vec_get_mag(bound, vec, len); _arb_vec_clear(vec, len); } arb-2.22.1/acb_poly/zeta_em_choose_param.c000066400000000000000000000054401417376376500204700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" static ulong choose_M(ulong N, slong target) { return FLINT_MIN(N, target + FLINT_MIN(N / 100, 2000)); } static void estimate_mag(mag_t m, const acb_t s, const acb_t a, slong prec) { acb_t t; acb_init(t); if (acb_contains_zero(a)) { mag_one(m); } else { acb_neg(t, s); acb_pow(t, a, t, prec); if (acb_is_finite(t)) acb_get_mag(m, t); else mag_one(m); } acb_clear(t); } void _acb_poly_zeta_em_choose_param(mag_t bound, ulong * N, ulong * M, const acb_t s, const acb_t a, slong d, slong target, slong prec) { ulong A, B, C, limit; mag_t Abound, Bbound, Cbound, tol; mag_init(Abound); mag_init(Bbound); mag_init(Cbound); mag_init(tol); if (!acb_is_one(a)) { /* estimate zeta(s,a) ~= a^-s -- todo: this can be very inaccurate */ estimate_mag(tol, s, a, prec); mag_mul_2exp_si(tol, tol, -target); } else { mag_set_ui_2exp_si(tol, 1, -target); } A = 1; B = 2; /* Hack: allow evaluation very high up in the critical strip... */ if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(s)), 10) > 0 && acb_is_real(a) /* && arb_is_positive(acb_realref(a)) */) { limit = UWORD_MAX / 4; mag_set_ui_2exp_si(tol, 1, -target); } else limit = 100 * target; /* but normally, fail more quickly */ _acb_poly_zeta_em_bound1(Bbound, s, a, B, choose_M(B, target), d, prec); if (mag_cmp(Bbound, tol) > 0) { while (mag_cmp(Bbound, tol) > 0 && B <= limit) { mag_set(Abound, Bbound); A *= 2; B *= 2; if (B == 0) flint_abort(); _acb_poly_zeta_em_bound1(Bbound, s, a, B, choose_M(B, target), d, prec); } /* bisect (-A, B] */ while (B > A + 4) { C = A + (B - A) / 2; _acb_poly_zeta_em_bound1(Cbound, s, a, C, choose_M(C, target), d, prec); if (mag_cmp(Cbound, tol) < 0) { B = C; mag_set(Bbound, Cbound); } else { A = C; mag_set(Abound, Cbound); } } } mag_set(bound, Bbound); *N = B; *M = choose_M(B, target); mag_clear(Abound); mag_clear(Bbound); mag_clear(Cbound); mag_clear(tol); } arb-2.22.1/acb_poly/zeta_em_sum.c000066400000000000000000000103331417376376500166310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_dirichlet.h" /* res = src * (c + x) */ void _acb_poly_mullow_cpx(acb_ptr res, acb_srcptr src, slong len, const acb_t c, slong trunc, slong prec) { slong i; if (len < trunc) acb_set(res + len, src + len - 1); for (i = len - 1; i > 0; i--) { acb_mul(res + i, src + i, c, prec); acb_add(res + i, res + i, src + i - 1, prec); } acb_mul(res, src, c, prec); } /* todo: don't hardcode this */ #define SIEVE_ALLOC_LIMIT 4e9 /* 4 GB */ void _acb_poly_zeta_em_sum(acb_ptr z, const acb_t s, const acb_t a, int deflate, ulong N, ulong M, slong d, slong prec) { acb_ptr t, u, v, term, sum; acb_t Na, one; slong i; t = _acb_vec_init(d + 1); u = _acb_vec_init(d); v = _acb_vec_init(d); term = _acb_vec_init(d); sum = _acb_vec_init(d); acb_init(Na); acb_init(one); prec += 2 * (FLINT_BIT_COUNT(N) + FLINT_BIT_COUNT(d)); acb_one(one); /* sum 1/(k+a)^(s+x) */ if (acb_is_one(a) && d <= 2 && _acb_vec_estimate_allocated_bytes(d * N / 6, prec) < SIEVE_ALLOC_LIMIT) acb_dirichlet_powsum_sieved(sum, s, N, d, prec); else if (acb_is_one(a) && d <= 4) /* todo: also better for slightly larger d, if N and prec large enough */ acb_dirichlet_powsum_smooth(sum, s, N, d, prec); else if (N > 50 && flint_get_num_threads() > 1) _acb_poly_powsum_series_naive_threaded(sum, s, a, one, N, d, prec); else _acb_poly_powsum_series_naive(sum, s, a, one, N, d, prec); /* t = 1/(N+a)^(s+x); we might need one extra term for deflation */ acb_add_ui(Na, a, N, prec); _acb_poly_acb_invpow_cpx(t, Na, s, d + 1, prec); /* sum += (N+a) * 1/((s+x)-1) * t */ if (!deflate) { /* u = (N+a)^(1-(s+x)) */ acb_sub_ui(v, s, 1, prec); _acb_poly_acb_invpow_cpx(u, Na, v, d, prec); /* divide by 1/((s-1) + x) */ acb_sub_ui(v, s, 1, prec); acb_div(u, u, v, prec); for (i = 1; i < d; i++) { acb_sub(u + i, u + i, u + i - 1, prec); acb_div(u + i, u + i, v, prec); } _acb_vec_add(sum, sum, u, d, prec); } /* sum += ((N+a)^(1-(s+x)) - 1) / ((s+x) - 1) */ else { /* at s = 1, this becomes (N*t - 1)/x, i.e. just remove one coeff */ if (acb_is_one(s)) { for (i = 0; i < d; i++) acb_mul(u + i, t + i + 1, Na, prec); _acb_vec_add(sum, sum, u, d, prec); } else { /* TODO: this is numerically unstable for large derivatives, and divides by zero if s contains 1. We want a good way to evaluate the power series ((N+a)^y - 1) / y where y has nonzero constant term, without doing a division. How is this best done? */ _acb_vec_scalar_mul(t, t, d, Na, prec); acb_sub_ui(t + 0, t + 0, 1, prec); acb_sub_ui(u + 0, s, 1, prec); acb_inv(u + 0, u + 0, prec); for (i = 1; i < d; i++) acb_mul(u + i, u + i - 1, u + 0, prec); for (i = 1; i < d; i += 2) acb_neg(u + i, u + i); _acb_poly_mullow(v, u, d, t, d, d, prec); _acb_vec_add(sum, sum, v, d, prec); _acb_poly_acb_invpow_cpx(t, Na, s, d, prec); } } /* sum += u = 1/2 * t */ _acb_vec_scalar_mul_2exp_si(u, t, d, -WORD(1)); _acb_vec_add(sum, sum, u, d, prec); /* Euler-Maclaurin formula tail */ if (d < 5 || d < M / 10) _acb_poly_zeta_em_tail_naive(u, s, Na, t, M, d, prec); else _acb_poly_zeta_em_tail_bsplit(u, s, Na, t, M, d, prec); _acb_vec_add(z, sum, u, d, prec); _acb_vec_clear(t, d + 1); _acb_vec_clear(u, d); _acb_vec_clear(v, d); _acb_vec_clear(term, d); _acb_vec_clear(sum, d); acb_clear(Na); acb_clear(one); } arb-2.22.1/acb_poly/zeta_em_tail_bsplit.c000066400000000000000000000063251417376376500203410ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "bernoulli.h" static void bsplit(acb_ptr P, acb_ptr T, const acb_t s, const acb_t Na, slong a, slong b, int cont, slong len, slong prec) { slong plen = FLINT_MIN(2 * (b - a) + 1, len); if (b - a == 1) { slong j = a; fmpz_t t; fmpz_init(t); if (j == 0) { acb_set(P, s); if (len > 1) acb_one(P + 1); if (len > 2) acb_zero(P + 2); } else { /* P = ((s+x)+2j-1)(s+x)+2j) */ /* constant term = s^2 + (4j-1)s + (4j^2-2j)*/ acb_mul(P, s, s, prec); acb_addmul_ui(P, s, 4*j-1, prec); fmpz_set_ui(t, 2*j); fmpz_mul_ui(t, t, 2*j-1); acb_add_fmpz(P, P, t, prec); /* x term = (2s+4j-1) */ if (len > 1) { acb_mul_ui(P + 1, s, 2, prec); acb_add_ui(P + 1, P + 1, 4*j-1, prec); } /* x^2 term = 1 */ if (len > 2) acb_one(P + 2); } /* P = P / ((2j+1)*(2j+2)) */ fmpz_set_ui(t, 2*j+1); fmpz_mul_ui(t, t, 2*j+2); _acb_vec_scalar_div_fmpz(P, P, plen, t, prec); /* P = P / Na or P / Na^2 */ if (j == 0) acb_set(T, Na); else acb_mul(T, Na, Na, prec); _acb_vec_scalar_div(P, P, plen, T, prec); /* T = P * B_{2j+2} */ _acb_vec_scalar_mul_fmpz(T, P, plen, fmpq_numref(bernoulli_cache + 2 * j + 2), prec); _acb_vec_scalar_div_fmpz(T, T, plen, fmpq_denref(bernoulli_cache + 2 * j + 2), prec); fmpz_clear(t); } else { slong m, len1, len2, alloc; acb_ptr P1, T1, P2, T2; m = a + (b - a) / 2; len1 = FLINT_MIN(2 * (m - a) + 1, len); len2 = FLINT_MIN(2 * (b - m) + 1, len); alloc = 2 * len1 + 2 * len2; P1 = _acb_vec_init(alloc); T1 = P1 + len1; P2 = T1 + len1; T2 = P2 + len2; bsplit(P1, T1, s, Na, a, m, 1, len, prec); bsplit(P2, T2, s, Na, m, b, 1, len, prec); /* P = P1 * P2 */ if (cont) _acb_poly_mullow(P, P2, len2, P1, len1, plen, prec); /* T = T1 + P1 * T2 */ _acb_poly_mullow(T, T2, len2, P1, len1, plen, prec); _acb_vec_add(T, T, T1, len1, prec); _acb_vec_clear(P1, alloc); } } void _acb_poly_zeta_em_tail_bsplit(acb_ptr z, const acb_t s, const acb_t Na, acb_srcptr Nasx, slong M, slong len, slong prec) { acb_ptr P, T; if (M < 1) { _acb_vec_zero(z, len); return; } BERNOULLI_ENSURE_CACHED(2 * M); P = _acb_vec_init(len); T = _acb_vec_init(len); bsplit(P, T, s, Na, 0, M, 0, len, prec); _acb_poly_mullow(z, T, len, Nasx, len, len, prec); _acb_vec_clear(P, len); _acb_vec_clear(T, len); } arb-2.22.1/acb_poly/zeta_em_tail_naive.c000066400000000000000000000052411417376376500201420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "bernoulli.h" void _acb_poly_mullow_cpx(acb_ptr res, acb_srcptr src, slong len, const acb_t c, slong trunc, slong prec); void _acb_poly_zeta_em_tail_naive(acb_ptr sum, const acb_t s, const acb_t Na, acb_srcptr Nasx, slong M, slong d, slong prec) { acb_ptr u, term; acb_t Na2, splus, rec; arb_t x; fmpz_t c; int aint; slong r; BERNOULLI_ENSURE_CACHED(2 * M); u = _acb_vec_init(d); term = _acb_vec_init(d); acb_init(splus); acb_init(rec); acb_init(Na2); arb_init(x); fmpz_init(c); _acb_vec_zero(sum, d); /* u = 1/2 * Nasx */ _acb_vec_scalar_mul_2exp_si(u, Nasx, d, -WORD(1)); /* term = u * (s+x) / (N+a) */ _acb_poly_mullow_cpx(u, u, d, s, d, prec); _acb_vec_scalar_div(term, u, d, Na, prec); /* (N+a)^2 or 1/(N+a)^2 */ acb_mul(Na2, Na, Na, prec); aint = acb_is_int(Na2); if (!aint) acb_inv(Na2, Na2, prec); for (r = 1; r <= M; r++) { /* flint_printf("sum 2: %wd %wd\n", r, M); */ /* sum += bernoulli number * term */ arb_set_round_fmpz(x, fmpq_numref(bernoulli_cache + 2 * r), prec); arb_div_fmpz(x, x, fmpq_denref(bernoulli_cache + 2 * r), prec); _acb_vec_scalar_mul_arb(u, term, d, x, prec); _acb_vec_add(sum, sum, u, d, prec); /* multiply term by ((s+x)+2r-1)((s+x)+2r) / ((N+a)^2 * (2*r+1)*(2*r+2)) */ acb_set(splus, s); arb_add_ui(acb_realref(splus), acb_realref(splus), 2*r-1, prec); _acb_poly_mullow_cpx(term, term, d, splus, d, prec); arb_add_ui(acb_realref(splus), acb_realref(splus), 1, prec); _acb_poly_mullow_cpx(term, term, d, splus, d, prec); /* TODO: combine with previous multiplication? */ if (aint) { arb_mul_ui(x, acb_realref(Na2), 2*r+1, prec); arb_mul_ui(x, x, 2*r+2, prec); _acb_vec_scalar_div_arb(term, term, d, x, prec); } else { fmpz_set_ui(c, 2*r+1); fmpz_mul_ui(c, c, 2*r+2); acb_div_fmpz(rec, Na2, c, prec); _acb_vec_scalar_mul(term, term, d, rec, prec); } } _acb_vec_clear(u, d); _acb_vec_clear(term, d); acb_clear(splus); acb_clear(rec); acb_clear(Na2); arb_clear(x); fmpz_clear(c); } arb-2.22.1/acb_poly/zeta_series.c000066400000000000000000000061221417376376500166370ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "acb_poly.h" #include "acb_dirichlet.h" void _acb_poly_zeta_cpx_series(acb_ptr z, const acb_t s, const acb_t a, int deflate, slong d, slong prec) { ulong M, N; slong i, bound_prec; mag_t bound; arb_ptr vb; int is_real, const_is_real; if (d < 1) return; if (!acb_is_finite(s) || !acb_is_finite(a)) { _acb_vec_indeterminate(z, d); return; } if (acb_is_one(s) && deflate && d == 1) { acb_digamma(z, a, prec); acb_neg(z, z); if (!acb_is_finite(z)) /* todo: in digamma */ acb_indeterminate(z); return; } is_real = const_is_real = 0; if (acb_is_real(s) && acb_is_real(a)) { if (arb_is_positive(acb_realref(a))) { is_real = const_is_real = 1; } else if (arb_is_int(acb_realref(a)) && arb_is_int(acb_realref(s)) && arb_is_nonpositive(acb_realref(s))) { const_is_real = 1; } } mag_init(bound); vb = _arb_vec_init(d); bound_prec = 40 + prec / 20; _acb_poly_zeta_em_choose_param(bound, &N, &M, s, a, FLINT_MIN(d, 2), prec, bound_prec); _acb_poly_zeta_em_bound(vb, s, a, N, M, d, bound_prec); _acb_poly_zeta_em_sum(z, s, a, deflate, N, M, d, prec); for (i = 0; i < d; i++) { arb_get_mag(bound, vb + i); arb_add_error_mag(acb_realref(z + i), bound); if (!is_real && !(i == 0 && const_is_real)) arb_add_error_mag(acb_imagref(z + i), bound); } mag_clear(bound); _arb_vec_clear(vb, d); } void _acb_poly_zeta_series(acb_ptr res, acb_srcptr h, slong hlen, const acb_t a, int deflate, slong len, slong prec) { acb_ptr t, u; hlen = FLINT_MIN(hlen, len); t = _acb_vec_init(len); u = _acb_vec_init(len); if (acb_is_one(a)) acb_dirichlet_zeta_jet(t, h, deflate, len, prec); else _acb_poly_zeta_cpx_series(t, h, a, deflate, len, prec); /* compose with nonconstant part */ acb_zero(u); _acb_vec_set(u + 1, h + 1, hlen - 1); _acb_poly_compose_series(res, t, len, u, hlen, len, prec); _acb_vec_clear(t, len); _acb_vec_clear(u, len); } void acb_poly_zeta_series(acb_poly_t res, const acb_poly_t f, const acb_t a, int deflate, slong n, slong prec) { if (n == 0) { acb_poly_zero(res); return; } acb_poly_fit_length(res, n); if (f->length == 0) { acb_t t; acb_init(t); _acb_poly_zeta_series(res->coeffs, t, 1, a, deflate, n, prec); acb_clear(t); } else { _acb_poly_zeta_series(res->coeffs, f->coeffs, f->length, a, deflate, n, prec); } _acb_poly_set_length(res, n); _acb_poly_normalise(res); } arb-2.22.1/appveyor.yml000066400000000000000000000052421417376376500147600ustar00rootroot00000000000000platform: - x64 os: Visual Studio 2017 clone_depth: 5 skip_tags: true matrix: fast_finish: false skip_commits: # Add [av skip] to commit messages message: /\[av skip\]/ environment: global: CONDA_INSTALL_LOCN_32: "C:\\Miniconda37" CONDA_INSTALL_LOCN_64: "C:\\Miniconda37-x64" VCVARSALL: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat" matrix: - COMPILER: cl ARCH: 64 - COMPILER: gcc ARCH: 64 - COMPILER: gcc ARCH: 32 - COMPILER: cl ARCH: 32 install: - if [%COMPILER%]==[gcc] set "PATH=C:\msys64\mingw%ARCH%\bin;%PATH%" - if [%COMPILER%]==[gcc] set "CMAKE_PREFIX_PATH=C:\msys64\mingw%ARCH%" - if [%COMPILER%]==[gcc] del /F /Q "C:\Program Files\Git\usr\bin\sh.exe" - dir "C:\msys64\mingw%ARCH%\lib" - dir "C:\msys64\mingw%ARCH%\bin" - if [%COMPILER%]==[cl] if [%ARCH%]==[64] set "CONDA_INSTALL_LOCN=%CONDA_INSTALL_LOCN_64%" - if [%COMPILER%]==[cl] if [%ARCH%]==[32] set "CONDA_INSTALL_LOCN=%CONDA_INSTALL_LOCN_32%" - if [%COMPILER%]==[cl] set "LIB=%CONDA_INSTALL_LOCN%\Library\lib;%LIB%" - if [%COMPILER%]==[cl] set "CPATH=%CONDA_INSTALL_LOCN%\Library\include;%CPATH%" - if [%COMPILER%]==[cl] call %CONDA_INSTALL_LOCN%\Scripts\activate.bat - if [%COMPILER%]==[cl] if [%ARCH%]==[64] call "%VCVARSALL%" x64 - if [%COMPILER%]==[cl] if [%ARCH%]==[32] call "%VCVARSALL%" x86 - if [%COMPILER%]==[cl] conda config --add channels conda-forge --force - if [%COMPILER%]==[cl] conda install --yes --quiet mpir=3.0.0 mpfr=4.* pthreads-win32 ninja - if [%COMPILER%]==[cl] set "CFLAGS=/wd4146 /wd4018 /wd4267 /wd4244" - cd .. && git clone https://github.com/wbhart/flint2 && cd flint2 && mkdir build && cd build - if [%COMPILER%]==[gcc] cmake -G "MinGW Makefiles" -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="C:\msys64\mingw%ARCH%" .. - if [%COMPILER%]==[cl] cmake -G "Ninja" -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="%CONDA_INSTALL_LOCN%\Library" .. - cmake --build . --target install -- -j2 - cd ../../arb before_build: - ps: if (-Not (Test-Path .\build)) { mkdir build } - cd build - if [%COMPILER%]==[gcc] cmake -G "MinGW Makefiles" -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF .. - if [%COMPILER%]==[cl] cmake -G "Ninja" -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Release .. build_script: - cmake --build . -- -j2 test_script: - set "ARB_TEST_MULTIPLIER=0.1" - ctest -j3 --output-on-failure --timeout 600 #on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) arb-2.22.1/arb.h000066400000000000000000001010651417376376500133050ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARB_H #define ARB_H #ifdef ARB_INLINES_C #define ARB_INLINE #else #define ARB_INLINE static __inline__ #endif #include #include "mag.h" #include "arf.h" #ifdef __cplusplus extern "C" { #endif #define __ARB_VERSION 2 #define __ARB_VERSION_MINOR 22 #define __ARB_VERSION_PATCHLEVEL 1 #define ARB_VERSION "2.22.1" #define __ARB_RELEASE (__ARB_VERSION * 10000 + \ __ARB_VERSION_MINOR * 100 + \ __ARB_VERSION_PATCHLEVEL) ARB_DLL extern const char * arb_version; double arb_test_multiplier(void); typedef struct { arf_struct mid; mag_struct rad; } arb_struct; typedef arb_struct arb_t[1]; typedef arb_struct * arb_ptr; typedef const arb_struct * arb_srcptr; #define arb_midref(x) (&(x)->mid) #define arb_radref(x) (&(x)->rad) #define ARB_IS_LAGOM(x) (ARF_IS_LAGOM(arb_midref(x)) && MAG_IS_LAGOM(arb_radref(x))) #define ARB_RND ARF_RND_DOWN ARB_INLINE void arb_init(arb_t x) { arf_init(arb_midref(x)); mag_init(arb_radref(x)); } void arb_clear(arb_t x); arb_ptr _arb_vec_init(slong n); void _arb_vec_clear(arb_ptr v, slong n); ARB_INLINE arf_ptr arb_mid_ptr(arb_t z) { return arb_midref(z); } ARB_INLINE mag_ptr arb_rad_ptr(arb_t z) { return arb_radref(z); } ARB_INLINE int arb_is_exact(const arb_t x) { return mag_is_zero(arb_radref(x)); } ARB_INLINE int arb_equal(const arb_t x, const arb_t y) { return arf_equal(arb_midref(x), arb_midref(y)) && mag_equal(arb_radref(x), arb_radref(y)); } ARB_INLINE int arb_equal_si(const arb_t x, slong y) { return arf_equal_si(arb_midref(x), y) && mag_is_zero(arb_radref(x)); } /* implementations are in arb/richcmp.c */ int arb_eq(const arb_t x, const arb_t y); int arb_ne(const arb_t x, const arb_t y); int arb_lt(const arb_t x, const arb_t y); int arb_le(const arb_t x, const arb_t y); int arb_gt(const arb_t x, const arb_t y); int arb_ge(const arb_t x, const arb_t y); void arb_zero(arb_t x); ARB_INLINE int arb_is_zero(const arb_t x) { return arf_is_zero(arb_midref(x)) && mag_is_zero(arb_radref(x)); } ARB_INLINE void arb_pos_inf(arb_t x) { arf_pos_inf(arb_midref(x)); mag_zero(arb_radref(x)); } ARB_INLINE void arb_neg_inf(arb_t x) { arf_neg_inf(arb_midref(x)); mag_zero(arb_radref(x)); } ARB_INLINE void arb_zero_pm_inf(arb_t x) { arf_zero(arb_midref(x)); mag_inf(arb_radref(x)); } ARB_INLINE void arb_zero_pm_one(arb_t x) { arf_zero(arb_midref(x)); mag_one(arb_radref(x)); } ARB_INLINE void arb_unit_interval(arb_t x) { arf_one(arb_midref(x)); mag_one(arb_radref(x)); ARF_EXP(arb_midref(x))--; MAG_EXP(arb_radref(x))--; } void arb_indeterminate(arb_t x); int arb_is_finite(const arb_t x); void arb_set(arb_t x, const arb_t y); ARB_INLINE void arb_swap(arb_t x, arb_t y) { arb_struct t = *x; *x = *y; *y = t; } void arb_set_round(arb_t z, const arb_t x, slong prec); void arb_trim(arb_t y, const arb_t x); void arb_neg(arb_t y, const arb_t x); void arb_neg_round(arb_t x, const arb_t y, slong prec); void arb_abs(arb_t y, const arb_t x); void arb_sgn(arb_t res, const arb_t x); int arb_sgn_nonzero(const arb_t x); void _arb_digits_round_inplace(char * s, flint_bitcnt_t * shift, fmpz_t error, slong n, arf_rnd_t rnd); int arb_set_str(arb_t res, const char * inp, slong prec); #define ARB_STR_MORE UWORD(1) #define ARB_STR_NO_RADIUS UWORD(2) #define ARB_STR_CONDENSE UWORD(16) char * arb_get_str(const arb_t x, slong n, ulong flags); ARB_INLINE void arb_set_arf(arb_t x, const arf_t y) { arf_set(arb_midref(x), y); mag_zero(arb_radref(x)); } void arb_set_si(arb_t x, slong y); void arb_set_ui(arb_t x, ulong y); void arb_set_d(arb_t x, double y); void arb_set_fmpz(arb_t x, const fmpz_t y); ARB_INLINE void arb_set_fmpz_2exp(arb_t x, const fmpz_t y, const fmpz_t exp) { arf_set_fmpz_2exp(arb_midref(x), y, exp); mag_zero(arb_radref(x)); } void arb_set_round_fmpz_2exp(arb_t y, const fmpz_t x, const fmpz_t exp, slong prec); void arb_set_round_fmpz(arb_t y, const fmpz_t x, slong prec); ARB_INLINE int arb_is_one(const arb_t f) { return arf_is_one(arb_midref(f)) && mag_is_zero(arb_radref(f)); } void arb_one(arb_t f); void arb_fprint(FILE * file, const arb_t x); void arb_fprintd(FILE * file, const arb_t x, slong digits); void arb_fprintn(FILE * file, const arb_t x, slong digits, ulong flags); ARB_INLINE void arb_print(const arb_t x) { arb_fprint(stdout, x); } ARB_INLINE void arb_printd(const arb_t x, slong digits) { arb_fprintd(stdout, x, digits); } ARB_INLINE void arb_printn(const arb_t x, slong digits, ulong flags) { arb_fprintn(stdout, x, digits, flags); } void arb_mul_2exp_si(arb_t y, const arb_t x, slong e); ARB_INLINE void arb_mul_2exp_fmpz(arb_t y, const arb_t x, const fmpz_t e) { arf_mul_2exp_fmpz(arb_midref(y), arb_midref(x), e); mag_mul_2exp_fmpz(arb_radref(y), arb_radref(x), e); } ARB_INLINE int arb_is_int(const arb_t x) { return mag_is_zero(arb_radref(x)) && arf_is_int(arb_midref(x)); } ARB_INLINE int arb_is_int_2exp_si(const arb_t x, slong e) { return mag_is_zero(arb_radref(x)) && arf_is_int_2exp_si(arb_midref(x), e); } /* implementations are in arb/richcmp.c */ int arb_contains_zero(const arb_t x); int arb_is_nonzero(const arb_t x); int arb_is_positive(const arb_t x); int arb_is_nonnegative(const arb_t x); int arb_is_negative(const arb_t x); int arb_is_nonpositive(const arb_t x); int arb_contains_negative(const arb_t x); int arb_contains_nonpositive(const arb_t x); int arb_contains_positive(const arb_t x); int arb_contains_nonnegative(const arb_t x); void arb_get_mag_lower(mag_t z, const arb_t x); void arb_get_mag_lower_nonnegative(mag_t z, const arb_t x); ARB_INLINE void arb_get_mag(mag_t z, const arb_t x) { mag_t t; mag_init_set_arf(t, arb_midref(x)); mag_add(z, t, arb_radref(x)); mag_clear(t); } ARB_INLINE void arb_get_mid_arb(arb_t z, const arb_t x) { arf_set(arb_midref(z), arb_midref(x)); mag_zero(arb_radref(z)); } ARB_INLINE void arb_get_rad_arb(arb_t z, const arb_t x) { arf_set_mag(arb_midref(z), arb_radref(x)); mag_zero(arb_radref(z)); } void arb_get_abs_ubound_arf(arf_t u, const arb_t x, slong prec); void arb_get_abs_lbound_arf(arf_t u, const arb_t x, slong prec); void arb_get_ubound_arf(arf_t u, const arb_t x, slong prec); void arb_get_lbound_arf(arf_t u, const arb_t x, slong prec); void arb_nonnegative_part(arb_t res, const arb_t x); slong arb_rel_error_bits(const arb_t x); ARB_INLINE slong arb_rel_accuracy_bits(const arb_t x) { return -arb_rel_error_bits(x); } slong arb_rel_one_accuracy_bits(const arb_t x); ARB_INLINE slong arb_bits(const arb_t x) { return arf_bits(arb_midref(x)); } void arb_randtest_exact(arb_t x, flint_rand_t state, slong prec, slong mag_bits); void arb_randtest_wide(arb_t x, flint_rand_t state, slong prec, slong mag_bits); void arb_randtest_precise(arb_t x, flint_rand_t state, slong prec, slong mag_bits); void arb_randtest(arb_t x, flint_rand_t state, slong prec, slong mag_bits); void arb_randtest_special(arb_t x, flint_rand_t state, slong prec, slong mag_bits); void arb_urandom(arb_t x, flint_rand_t state, slong prec); void arb_add_error_arf(arb_t x, const arf_t err); void arb_add_error_2exp_si(arb_t x, slong err); void arb_add_error_2exp_fmpz(arb_t x, const fmpz_t err); void arb_add_error(arb_t x, const arb_t error); ARB_INLINE void arb_add_error_mag(arb_t x, const mag_t err) { mag_add(arb_radref(x), arb_radref(x), err); } int arb_contains_arf(const arb_t x, const arf_t y); int arb_contains_fmpq(const arb_t x, const fmpq_t y); int arb_contains_fmpz(const arb_t x, const fmpz_t y); int arb_contains_si(const arb_t x, slong y); int arb_contains_mpfr(const arb_t x, const mpfr_t y); int arb_overlaps(const arb_t x, const arb_t y); int arb_contains(const arb_t x, const arb_t y); int arb_contains_interior(const arb_t x, const arb_t y); int arb_contains_int(const arb_t x); void arb_get_interval_fmpz_2exp(fmpz_t a, fmpz_t b, fmpz_t exp, const arb_t x); int arb_get_unique_fmpz(fmpz_t z, const arb_t x); void arb_get_fmpz_mid_rad_10exp(fmpz_t mid, fmpz_t rad, fmpz_t exp, const arb_t x, slong n); void arb_floor(arb_t z, const arb_t x, slong prec); void arb_ceil(arb_t z, const arb_t x, slong prec); void arb_set_interval_arf(arb_t x, const arf_t a, const arf_t b, slong prec); void arb_set_interval_mpfr(arb_t x, const mpfr_t a, const mpfr_t b, slong prec); void arb_get_interval_arf(arf_t a, arf_t b, const arb_t x, slong prec); void arb_get_interval_mpfr(mpfr_t a, mpfr_t b, const arb_t x); void arb_set_interval_mag(arb_t res, const mag_t a, const mag_t b, slong prec); void arb_set_interval_neg_pos_mag(arb_t res, const mag_t a, const mag_t b, slong prec); void arb_union(arb_t z, const arb_t x, const arb_t y, slong prec); int arb_intersection(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_get_rand_fmpq(fmpq_t q, flint_rand_t state, const arb_t x, slong bits); void arb_min(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_max(arb_t z, const arb_t x, const arb_t y, slong prec); int arb_can_round_arf(const arb_t x, slong prec, arf_rnd_t rnd); int arb_can_round_mpfr(const arb_t x, slong prec, mpfr_rnd_t rnd); void arb_add(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_add_arf(arb_t z, const arb_t x, const arf_t y, slong prec); void arb_add_ui(arb_t z, const arb_t x, ulong y, slong prec); void arb_add_si(arb_t z, const arb_t x, slong y, slong prec); void arb_add_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec); void arb_add_fmpz_2exp(arb_t z, const arb_t x, const fmpz_t man, const fmpz_t exp, slong prec); void arb_sub(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_sub_arf(arb_t z, const arb_t x, const arf_t y, slong prec); void arb_sub_ui(arb_t z, const arb_t x, ulong y, slong prec); void arb_sub_si(arb_t z, const arb_t x, slong y, slong prec); void arb_sub_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec); void arb_mul(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_mul_arf(arb_t z, const arb_t x, const arf_t y, slong prec); void arb_mul_si(arb_t z, const arb_t x, slong y, slong prec); void arb_mul_ui(arb_t z, const arb_t x, ulong y, slong prec); void arb_mul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec); void arb_addmul(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_addmul_arf(arb_t z, const arb_t x, const arf_t y, slong prec); void arb_addmul_si(arb_t z, const arb_t x, slong y, slong prec); void arb_addmul_ui(arb_t z, const arb_t x, ulong y, slong prec); void arb_addmul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec); void arb_submul(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_submul_arf(arb_t z, const arb_t x, const arf_t y, slong prec); void arb_submul_si(arb_t z, const arb_t x, slong y, slong prec); void arb_submul_ui(arb_t z, const arb_t x, ulong y, slong prec); void arb_submul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec); void arb_fma(arb_t res, const arb_t x, const arb_t y, const arb_t z, slong prec); void arb_fma_arf(arb_t res, const arb_t x, const arf_t y, const arb_t z, slong prec); void arb_fma_si(arb_t res, const arb_t x, slong y, const arb_t z, slong prec); void arb_fma_ui(arb_t res, const arb_t x, ulong y, const arb_t z, slong prec); void arb_fma_fmpz(arb_t res, const arb_t x, const fmpz_t y, const arb_t z, slong prec); void arb_dot_simple(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec); void arb_dot_precise(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec); void arb_dot(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec); void arb_approx_dot(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec); void arb_dot_ui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec); void arb_dot_si(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const slong * y, slong ystep, slong len, slong prec); void arb_dot_uiui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec); void arb_dot_siui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec); void arb_dot_fmpz(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const fmpz * y, slong ystep, slong len, slong prec); void arb_div(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_div_arf(arb_t z, const arb_t x, const arf_t y, slong prec); void arb_div_si(arb_t z, const arb_t x, slong y, slong prec); void arb_div_ui(arb_t z, const arb_t x, ulong y, slong prec); void arb_div_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec); void arb_fmpz_div_fmpz(arb_t z, const fmpz_t x, const fmpz_t y, slong prec); void arb_ui_div(arb_t z, ulong x, const arb_t y, slong prec); ARB_INLINE void arb_inv(arb_t y, const arb_t x, slong prec) { arb_ui_div(y, 1, x, prec); } ARB_INLINE void arb_set_fmpq(arb_t y, const fmpq_t x, slong prec) { arb_fmpz_div_fmpz(y, fmpq_numref(x), fmpq_denref(x), prec); } void arb_sqrt(arb_t z, const arb_t x, slong prec); void arb_sqrt_arf(arb_t z, const arf_t x, slong prec); void arb_sqrt_fmpz(arb_t z, const fmpz_t x, slong prec); void arb_sqrt_ui(arb_t z, ulong x, slong prec); void arb_sqrtpos(arb_t z, const arb_t x, slong prec); void arb_hypot(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_rsqrt(arb_t z, const arb_t x, slong prec); void arb_rsqrt_ui(arb_t z, ulong x, slong prec); void arb_sqrt1pm1(arb_t r, const arb_t z, slong prec); void arb_pow_fmpz_binexp(arb_t y, const arb_t b, const fmpz_t e, slong prec); void arb_pow_fmpz(arb_t y, const arb_t b, const fmpz_t e, slong prec); void arb_pow_ui(arb_t y, const arb_t b, ulong e, slong prec); void arb_ui_pow_ui(arb_t y, ulong b, ulong e, slong prec); void arb_si_pow_ui(arb_t y, slong b, ulong e, slong prec); void arb_pow_fmpq(arb_t y, const arb_t x, const fmpq_t a, slong prec); void arb_div_2expm1_ui(arb_t z, const arb_t x, ulong n, slong prec); void arb_pow(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_root_ui(arb_t z, const arb_t x, ulong k, slong prec); void arb_root(arb_t z, const arb_t x, ulong k, slong prec); /* back compat */ void arb_log(arb_t z, const arb_t x, slong prec); void arb_log_arf(arb_t z, const arf_t x, slong prec); void arb_log_ui(arb_t z, ulong x, slong prec); void arb_log_fmpz(arb_t z, const fmpz_t x, slong prec); void arb_log1p(arb_t r, const arb_t z, slong prec); void arb_log_base_ui(arb_t res, const arb_t x, ulong b, slong prec); void arb_log_hypot(arb_t res, const arb_t x, const arb_t y, slong prec); void arb_exp(arb_t z, const arb_t x, slong prec); void arb_expm1(arb_t z, const arb_t x, slong prec); void arb_exp_invexp(arb_t z, arb_t w, const arb_t x, slong prec); void arb_sin(arb_t s, const arb_t x, slong prec); void arb_cos(arb_t c, const arb_t x, slong prec); void arb_sin_cos(arb_t s, arb_t c, const arb_t x, slong prec); void arb_sin_pi(arb_t s, const arb_t x, slong prec); void arb_cos_pi(arb_t c, const arb_t x, slong prec); void arb_sin_cos_pi(arb_t s, arb_t c, const arb_t x, slong prec); void arb_tan(arb_t y, const arb_t x, slong prec); void arb_cot(arb_t y, const arb_t x, slong prec); void arb_tan_pi(arb_t y, const arb_t x, slong prec); void arb_cot_pi(arb_t y, const arb_t x, slong prec); void _arb_sin_pi_fmpq_algebraic(arb_t s, ulong p, ulong q, slong prec); void _arb_cos_pi_fmpq_algebraic(arb_t c, ulong p, ulong q, slong prec); void _arb_sin_cos_pi_fmpq_algebraic(arb_t s, arb_t c, ulong p, ulong q, slong prec); void arb_sin_cos_pi_fmpq(arb_t s, arb_t c, const fmpq_t x, slong prec); void arb_sin_pi_fmpq(arb_t s, const fmpq_t x, slong prec); void arb_cos_pi_fmpq(arb_t c, const fmpq_t x, slong prec); void arb_sinc(arb_t z, const arb_t x, slong prec); void arb_sinc_pi(arb_t z, const arb_t x, slong prec); void arb_sinh(arb_t z, const arb_t x, slong prec); void arb_cosh(arb_t z, const arb_t x, slong prec); void arb_sinh_cosh(arb_t s, arb_t c, const arb_t x, slong prec); void arb_tanh(arb_t y, const arb_t x, slong prec); void arb_coth(arb_t y, const arb_t x, slong prec); void arb_atan_arf(arb_t z, const arf_t x, slong prec); void arb_atan(arb_t z, const arb_t x, slong prec); void arb_atan2(arb_t z, const arb_t b, const arb_t a, slong prec); void arb_asin(arb_t z, const arb_t x, slong prec); void arb_acos(arb_t z, const arb_t x, slong prec); void arb_atanh(arb_t z, const arb_t x, slong prec); void arb_asinh(arb_t z, const arb_t x, slong prec); void arb_acosh(arb_t z, const arb_t x, slong prec); void arb_sec(arb_t res, const arb_t x, slong prec); void arb_csc(arb_t res, const arb_t x, slong prec); void arb_csc_pi(arb_t res, const arb_t x, slong prec); void arb_sech(arb_t res, const arb_t x, slong prec); void arb_csch(arb_t res, const arb_t x, slong prec); void arb_fac_ui(arb_t z, ulong n, slong prec); void arb_doublefac_ui(arb_t z, ulong n, slong prec); void arb_bin_ui(arb_t z, const arb_t n, ulong k, slong prec); void arb_bin_uiui(arb_t z, ulong n, ulong k, slong prec); void arb_fib_fmpz(arb_t z, const fmpz_t n, slong prec); void arb_fib_ui(arb_t z, ulong n, slong prec); void arb_const_pi(arb_t z, slong prec); void arb_const_sqrt_pi(arb_t z, slong prec); void arb_const_log_sqrt2pi(arb_t z, slong prec); void arb_const_log2(arb_t z, slong prec); void arb_const_log10(arb_t z, slong prec); void arb_const_euler(arb_t z, slong prec); void arb_const_catalan(arb_t z, slong prec); void arb_const_e(arb_t z, slong prec); void arb_const_khinchin(arb_t z, slong prec); void arb_const_glaisher(arb_t z, slong prec); void arb_agm(arb_t z, const arb_t x, const arb_t y, slong prec); void arb_lgamma(arb_t z, const arb_t x, slong prec); void arb_rgamma(arb_t z, const arb_t x, slong prec); void arb_gamma(arb_t z, const arb_t x, slong prec); void arb_gamma_fmpq(arb_t z, const fmpq_t x, slong prec); void arb_gamma_fmpz(arb_t z, const fmpz_t x, slong prec); void arb_digamma(arb_t y, const arb_t x, slong prec); void arb_zeta(arb_t z, const arb_t s, slong prec); void arb_hurwitz_zeta(arb_t z, const arb_t s, const arb_t a, slong prec); void arb_rising_ui(arb_t z, const arb_t x, ulong n, slong prec); void arb_rising_fmpq_ui(arb_t y, const fmpq_t x, ulong n, slong prec); void arb_rising(arb_t z, const arb_t x, const arb_t n, slong prec); void arb_rising2_ui(arb_t u, arb_t v, const arb_t x, ulong n, slong prec); void arb_log_ui_from_prev(arb_t s, ulong k, arb_t log_prev, ulong prev, slong prec); void arb_const_apery(arb_t s, slong prec); void arb_zeta_ui_asymp(arb_t x, ulong s, slong prec); void arb_zeta_ui_borwein_bsplit(arb_t x, ulong s, slong prec); void arb_zeta_ui_euler_product(arb_t z, ulong s, slong prec); void arb_zeta_ui_bernoulli(arb_t x, ulong n, slong prec); void arb_zeta_ui_vec_borwein(arb_ptr z, ulong start, slong num, ulong step, slong prec); void arb_zeta_ui(arb_t x, ulong n, slong prec); void arb_zeta_ui_vec_even(arb_ptr x, ulong start, slong num, slong prec); void arb_zeta_ui_vec_odd(arb_ptr x, ulong start, slong num, slong prec); void arb_zeta_ui_vec(arb_ptr x, ulong start, slong num, slong prec); void arb_bernoulli_ui(arb_t b, ulong n, slong prec); void arb_bernoulli_ui_zeta(arb_t b, ulong n, slong prec); void arb_bernoulli_fmpz(arb_t b, const fmpz_t n, slong prec); void arb_bernoulli_poly_ui(arb_t res, ulong n, const arb_t x, slong prec); void arb_polylog(arb_t w, const arb_t s, const arb_t z, slong prec); void arb_polylog_si(arb_t w, slong s, const arb_t z, slong prec); void arb_chebyshev_t_ui(arb_t a, ulong n, const arb_t x, slong prec); void arb_chebyshev_t2_ui(arb_t a, arb_t b, ulong n, const arb_t x, slong prec); void arb_chebyshev_u_ui(arb_t a, ulong n, const arb_t x, slong prec); void arb_chebyshev_u2_ui(arb_t a, arb_t b, ulong n, const arb_t x, slong prec); void arb_power_sum_vec(arb_ptr res, const arb_t a, const arb_t b, slong len, slong prec); void arb_bell_sum_taylor(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, slong prec); void arb_bell_sum_bsplit(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, slong prec); void arb_bell_fmpz(arb_t res, const fmpz_t n, slong prec); void arb_bell_ui(arb_t res, ulong n, slong prec); void arb_euler_number_fmpz(arb_t res, const fmpz_t n, slong prec); void arb_euler_number_ui(arb_t res, ulong n, slong prec); void arb_fmpz_euler_number_ui_multi_mod(fmpz_t res, ulong n, double alpha); void arb_fmpz_euler_number_ui(fmpz_t res, ulong n); void arb_partitions_fmpz(arb_t res, const fmpz_t n, slong prec); void arb_partitions_ui(arb_t res, ulong n, slong prec); void arb_primorial_nth_ui(arb_t res, ulong n, slong prec); void arb_primorial_ui(arb_t res, ulong n, slong prec); void arb_lambertw(arb_t res, const arb_t x, int flags, slong prec); ARB_INLINE void arb_sqr(arb_t res, const arb_t val, slong prec) { arb_mul(res, val, val, prec); } #define ARB_DEF_CACHED_CONSTANT(name, comp_func) \ TLS_PREFIX slong name ## _cached_prec = 0; \ TLS_PREFIX arb_t name ## _cached_value; \ void name ## _cleanup(void) \ { \ arb_clear(name ## _cached_value); \ name ## _cached_prec = 0; \ } \ void name(arb_t x, slong prec) \ { \ if (name ## _cached_prec < prec) \ { \ if (name ## _cached_prec == 0) \ { \ arb_init(name ## _cached_value); \ flint_register_cleanup_function(name ## _cleanup); \ } \ comp_func(name ## _cached_value, prec + 32); \ name ## _cached_prec = prec; \ } \ arb_set_round(x, name ## _cached_value, prec); \ } /* vector functions */ ARB_INLINE arb_ptr _arb_vec_entry_ptr(arb_ptr vec, slong i) { return vec + i; } ARB_INLINE void _arb_vec_printn(arb_srcptr vec, slong len, slong ndigits, ulong flags) { slong i; for (i = 0; i < len; i++) { arb_printn(vec + i, ndigits, flags); if (i < len - 1) flint_printf(", "); } } ARB_INLINE void _arb_vec_zero(arb_ptr A, slong n) { slong i; for (i = 0; i < n; i++) arb_zero(A + i); } ARB_INLINE int _arb_vec_is_zero(arb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) if (!arb_is_zero(vec + i)) return 0; return 1; } ARB_INLINE int _arb_vec_is_finite(arb_srcptr x, slong len) { slong i; for (i = 0; i < len; i++) if (!arb_is_finite(x + i)) return 0; return 1; } ARB_INLINE void _arb_vec_set(arb_ptr res, arb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) arb_set(res + i, vec + i); } ARB_INLINE void _arb_vec_set_round(arb_ptr res, arb_srcptr vec, slong len, slong prec) { slong i; for (i = 0; i < len; i++) arb_set_round(res + i, vec + i, prec); } ARB_INLINE void _arb_vec_swap(arb_ptr res, arb_ptr vec, slong len) { slong i; for (i = 0; i < len; i++) arb_swap(res + i, vec + i); } ARB_INLINE void _arb_vec_neg(arb_ptr B, arb_srcptr A, slong n) { slong i; for (i = 0; i < n; i++) arb_neg(B + i, A + i); } ARB_INLINE void _arb_vec_sub(arb_ptr C, arb_srcptr A, arb_srcptr B, slong n, slong prec) { slong i; for (i = 0; i < n; i++) arb_sub(C + i, A + i, B + i, prec); } ARB_INLINE void _arb_vec_add(arb_ptr C, arb_srcptr A, arb_srcptr B, slong n, slong prec) { slong i; for (i = 0; i < n; i++) arb_add(C + i, A + i, B + i, prec); } ARB_INLINE void _arb_vec_scalar_mul(arb_ptr res, arb_srcptr vec, slong len, const arb_t c, slong prec) { slong i; for (i = 0; i < len; i++) arb_mul(res + i, vec + i, c, prec); } ARB_INLINE void _arb_vec_scalar_div(arb_ptr res, arb_srcptr vec, slong len, const arb_t c, slong prec) { slong i; for (i = 0; i < len; i++) arb_div(res + i, vec + i, c, prec); } ARB_INLINE void _arb_vec_scalar_mul_fmpz(arb_ptr res, arb_srcptr vec, slong len, const fmpz_t c, slong prec) { slong i; arf_t t; arf_init(t); arf_set_fmpz(t, c); for (i = 0; i < len; i++) arb_mul_arf(res + i, vec + i, t, prec); arf_clear(t); } ARB_INLINE void _arb_vec_scalar_mul_2exp_si(arb_ptr res, arb_srcptr src, slong len, slong c) { slong i; for (i = 0; i < len; i++) arb_mul_2exp_si(res + i, src + i, c); } ARB_INLINE void _arb_vec_scalar_addmul(arb_ptr res, arb_srcptr vec, slong len, const arb_t c, slong prec) { slong i; for (i = 0; i < len; i++) arb_addmul(res + i, vec + i, c, prec); } void _arb_vec_get_mag(mag_t bound, arb_srcptr vec, slong len); ARB_INLINE slong _arb_vec_bits(arb_srcptr x, slong len) { slong i, b, c; b = 0; for (i = 0; i < len; i++) { c = arb_bits(x + i); b = FLINT_MAX(b, c); } return b; } void _arb_vec_set_powers(arb_ptr xs, const arb_t x, slong len, slong prec); ARB_INLINE void _arb_vec_add_error_arf_vec(arb_ptr res, arf_srcptr err, slong len) { slong i; for (i = 0; i < len; i++) arb_add_error_arf(res + i, err + i); } ARB_INLINE void _arb_vec_add_error_mag_vec(arb_ptr res, mag_srcptr err, slong len) { slong i; for (i = 0; i < len; i++) mag_add(arb_radref(res + i), arb_radref(res + i), err + i); } ARB_INLINE void _arb_vec_indeterminate(arb_ptr vec, slong len) { slong i; for (i = 0; i < len; i++) arb_indeterminate(vec + i); } ARB_INLINE void _arb_vec_trim(arb_ptr res, arb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) arb_trim(res + i, vec + i); } ARB_INLINE int _arb_vec_get_unique_fmpz_vec(fmpz * res, arb_srcptr vec, slong len) { slong i; for (i = 0; i < len; i++) if (!arb_get_unique_fmpz(res + i, vec + i)) return 0; return 1; } /* arctangent implementation */ #define ARB_ATAN_TAB1_BITS 8 #define ARB_ATAN_TAB1_PREC 512 #define ARB_ATAN_TAB1_LIMBS (ARB_ATAN_TAB1_PREC / FLINT_BITS) #define ARB_ATAN_TAB21_BITS 5 #define ARB_ATAN_TAB22_BITS 5 #define ARB_ATAN_TAB2_PREC 4608 #define ARB_ATAN_TAB2_LIMBS (ARB_ATAN_TAB2_PREC / FLINT_BITS) ARB_DLL extern const mp_limb_t arb_atan_tab1[1 << ARB_ATAN_TAB1_BITS][ARB_ATAN_TAB1_LIMBS]; ARB_DLL extern const mp_limb_t arb_atan_tab21[1 << ARB_ATAN_TAB21_BITS][ARB_ATAN_TAB2_LIMBS]; ARB_DLL extern const mp_limb_t arb_atan_tab22[1 << ARB_ATAN_TAB22_BITS][ARB_ATAN_TAB2_LIMBS]; ARB_DLL extern const mp_limb_t arb_atan_pi2_minus_one[ARB_ATAN_TAB2_LIMBS]; void _arb_atan_taylor_naive(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int alternating); void _arb_atan_taylor_rs(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int alternating); /* logarithm implementation */ #define ARB_LOG_TAB11_BITS 7 #define ARB_LOG_TAB12_BITS 7 #define ARB_LOG_TAB1_PREC 512 #define ARB_LOG_TAB1_LIMBS (ARB_LOG_TAB1_PREC / FLINT_BITS) #define ARB_LOG_TAB21_BITS 5 #define ARB_LOG_TAB22_BITS 5 #define ARB_LOG_TAB2_PREC 4608 #define ARB_LOG_TAB2_LIMBS (ARB_LOG_TAB2_PREC / FLINT_BITS) ARB_DLL extern const mp_limb_t arb_log_tab11[1 << ARB_LOG_TAB11_BITS][ARB_LOG_TAB1_LIMBS]; ARB_DLL extern const mp_limb_t arb_log_tab12[1 << ARB_LOG_TAB12_BITS][ARB_LOG_TAB1_LIMBS]; ARB_DLL extern const mp_limb_t arb_log_tab21[1 << ARB_LOG_TAB21_BITS][ARB_LOG_TAB2_LIMBS]; ARB_DLL extern const mp_limb_t arb_log_tab22[1 << ARB_LOG_TAB22_BITS][ARB_LOG_TAB2_LIMBS]; ARB_DLL extern const mp_limb_t arb_log_log2_tab[ARB_LOG_TAB2_LIMBS]; /* exponential implementation */ /* only goes up to log(2) * 256 */ #define ARB_EXP_TAB1_NUM 178 #define ARB_EXP_TAB1_BITS 8 #define ARB_EXP_TAB1_PREC 512 #define ARB_EXP_TAB1_LIMBS (ARB_EXP_TAB1_PREC / FLINT_BITS) /* only goes up to log(2) * 32 */ #define ARB_EXP_TAB21_NUM 23 #define ARB_EXP_TAB21_BITS 5 #define ARB_EXP_TAB22_NUM (1 << ARB_EXP_TAB22_BITS) #define ARB_EXP_TAB22_BITS 5 #define ARB_EXP_TAB2_PREC 4608 #define ARB_EXP_TAB2_LIMBS (ARB_EXP_TAB2_PREC / FLINT_BITS) ARB_DLL extern const mp_limb_t arb_exp_tab1[ARB_EXP_TAB1_NUM][ARB_EXP_TAB1_LIMBS]; ARB_DLL extern const mp_limb_t arb_exp_tab21[ARB_EXP_TAB21_NUM][ARB_EXP_TAB2_LIMBS]; ARB_DLL extern const mp_limb_t arb_exp_tab22[ARB_EXP_TAB22_NUM][ARB_EXP_TAB2_LIMBS]; void _arb_exp_taylor_naive(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N); void _arb_exp_taylor_rs(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N); void arb_exp_arf_bb(arb_t z, const arf_t x, slong prec, int minus_one); void arb_exp_arf_rs_generic(arb_t res, const arf_t x, slong prec, int minus_one); int _arb_get_mpn_fixed_mod_log2(mp_ptr w, fmpz_t q, mp_limb_t * error, const arf_t x, mp_size_t wn); slong _arb_exp_taylor_bound(slong mag, slong prec); void _arb_exp_sum_bs_powtab(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N); void _arb_exp_sum_bs_simple(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N); /* sin/cos implementation */ /* only goes up to (pi/4) * 256 */ #define ARB_SIN_COS_TAB1_NUM 203 #define ARB_SIN_COS_TAB1_BITS 8 #define ARB_SIN_COS_TAB1_PREC 512 #define ARB_SIN_COS_TAB1_LIMBS (ARB_SIN_COS_TAB1_PREC / FLINT_BITS) /* only goes up to (pi/4) * 32 */ #define ARB_SIN_COS_TAB21_NUM 26 #define ARB_SIN_COS_TAB21_BITS 5 #define ARB_SIN_COS_TAB22_NUM (1 << ARB_SIN_COS_TAB22_BITS) #define ARB_SIN_COS_TAB22_BITS 5 #define ARB_SIN_COS_TAB2_PREC 4608 #define ARB_SIN_COS_TAB2_LIMBS (ARB_SIN_COS_TAB2_PREC / FLINT_BITS) ARB_DLL extern const mp_limb_t arb_sin_cos_tab1[2 * ARB_SIN_COS_TAB1_NUM][ARB_SIN_COS_TAB1_LIMBS]; ARB_DLL extern const mp_limb_t arb_sin_cos_tab21[2 * ARB_SIN_COS_TAB21_NUM][ARB_SIN_COS_TAB2_LIMBS]; ARB_DLL extern const mp_limb_t arb_sin_cos_tab22[2 * ARB_SIN_COS_TAB22_NUM][ARB_SIN_COS_TAB2_LIMBS]; #define ARB_PI4_TAB_LIMBS (4608 / FLINT_BITS) ARB_DLL extern const mp_limb_t arb_pi4_tab[ARB_PI4_TAB_LIMBS]; void _arb_sin_cos_taylor_naive(mp_ptr ysin, mp_ptr ycos, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N); void _arb_sin_cos_taylor_rs(mp_ptr ysin, mp_ptr ycos, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int sinonly, int alternating); int _arb_get_mpn_fixed_mod_pi4(mp_ptr w, fmpz_t q, int * octant, mp_limb_t * error, const arf_t x, mp_size_t wn); void arb_sin_cos_arf_bb(arb_t zsin, arb_t zcos, const arf_t x, slong prec); void arb_sin_cos_arf_rs_generic(arb_t res_sin, arb_t res_cos, const arf_t x, slong prec); void arb_sin_cos_arf_generic(arb_t res_sin, arb_t res_cos, const arf_t x, slong prec); void _arb_sin_cos_wide(arb_t s, arb_t c, const arf_t x, const mag_t r, slong prec); void arb_sin_cos_wide(arb_t s, arb_t c, const arb_t x, slong prec); void _arb_sin_cos_generic(arb_t s, arb_t c, const arf_t x, const mag_t xrad, slong prec); void arb_sin_cos_generic(arb_t s, arb_t c, const arb_t x, slong prec); ARB_INLINE flint_bitcnt_t _arb_mpn_leading_zeros(mp_srcptr d, mp_size_t n) { mp_limb_t t; mp_size_t zero_limbs; flint_bitcnt_t bits; zero_limbs = 0; while (1) { t = d[n - zero_limbs - 1]; if (t != 0) { count_leading_zeros(bits, t); return bits + FLINT_BITS * zero_limbs; } zero_limbs++; if (zero_limbs == n) return FLINT_BITS * zero_limbs; } } void _arb_atan_sum_bs_simple(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N); void _arb_atan_sum_bs_powtab(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N); void arb_atan_arf_bb(arb_t z, const arf_t x, slong prec); ARB_INLINE slong arb_allocated_bytes(const arb_t x) { return arf_allocated_bytes(arb_midref(x)) + mag_allocated_bytes(arb_radref(x)); } ARB_INLINE slong _arb_vec_allocated_bytes(arb_srcptr vec, slong len) { slong i, size; size = len * sizeof(arb_struct); for (i = 0; i < len; i++) size += arb_allocated_bytes(vec + i); return size; } ARB_INLINE double _arb_vec_estimate_allocated_bytes(slong len, slong prec) { double size; size = len * (double) sizeof(arb_struct); if (prec > ARF_NOPTR_LIMBS * FLINT_BITS) size += len * (double) ((prec + FLINT_BITS - 1) / FLINT_BITS) * sizeof(mp_limb_t); return size; } int arb_load_str(arb_t res, const char * data); char * arb_dump_str(const arb_t x); int arb_load_file(arb_t res, FILE *stream); int arb_dump_file(FILE* stream, const arb_t x); #ifdef __cplusplus } #endif #endif arb-2.22.1/arb/000077500000000000000000000000001417376376500131315ustar00rootroot00000000000000arb-2.22.1/arb/abs.c000066400000000000000000000010151417376376500140370ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_abs(arb_t y, const arb_t x) { arf_abs(arb_midref(y), arb_midref(x)); mag_set(arb_radref(y), arb_radref(x)); } arb-2.22.1/arb/acos.c000066400000000000000000000024661417376376500142320ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_acos(arb_t z, const arb_t x, slong prec) { arb_t t, u; if (arb_is_exact(x)) { int side; if (arf_is_zero(arb_midref(x))) { arb_const_pi(z, prec); arb_mul_2exp_si(z, z, -1); return; } side = arf_cmpabs_2exp_si(arb_midref(x), 0); /* +/- 1 */ if (side == 0) { if (arf_is_one(arb_midref(x))) arb_zero(z); else arb_const_pi(z, prec); return; } else if (side > 0) { arb_indeterminate(z); return; } } arb_init(t); arb_init(u); arb_one(t); arb_submul(t, x, x, prec); arb_rsqrt(t, t, prec); arb_mul(t, x, t, prec); arb_atan(t, t, prec); arb_const_pi(u, prec); arb_mul_2exp_si(u, u, -1); arb_sub(z, u, t, prec); arb_clear(t); arb_clear(u); } arb-2.22.1/arb/acosh.c000066400000000000000000000013771417376376500144020ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_acosh(arb_t z, const arb_t x, slong prec) { if (arb_is_one(x)) { arb_zero(z); } else { arb_t t; arb_init(t); arb_mul(t, x, x, prec + 4); arb_sub_ui(t, t, 1, prec + 4); arb_sqrt(t, t, prec + 4); arb_add(t, t, x, prec + 4); arb_log(z, t, prec); arb_clear(t); } } arb-2.22.1/arb/add.c000066400000000000000000000044161417376376500140320ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_add(arb_t z, const arb_t x, const arb_t y, slong prec) { int inexact; inexact = arf_add(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); mag_add(arb_radref(z), arb_radref(x), arb_radref(y)); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } void arb_add_arf(arb_t z, const arb_t x, const arf_t y, slong prec) { int inexact; inexact = arf_add(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } void arb_add_ui(arb_t z, const arb_t x, ulong y, slong prec) { int inexact; inexact = arf_add_ui(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } void arb_add_si(arb_t z, const arb_t x, slong y, slong prec) { int inexact; inexact = arf_add_si(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } void arb_add_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) { int inexact; inexact = arf_add_fmpz(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } void arb_add_fmpz_2exp(arb_t z, const arb_t x, const fmpz_t man, const fmpz_t exp, slong prec) { int inexact; inexact = arf_add_fmpz_2exp(arb_midref(z), arb_midref(x), man, exp, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } arb-2.22.1/arb/add_error.c000066400000000000000000000032011417376376500152320ustar00rootroot00000000000000/* Copyright (C) 2012-2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_add_error_arf(arb_t x, const arf_t err) { mag_t t; if (arf_is_zero(err)) return; if (mag_is_zero(arb_radref(x))) { arf_get_mag(arb_radref(x), err); return; } mag_init(t); arf_get_mag(t, err); mag_add(arb_radref(x), arb_radref(x), t); mag_clear(t); } void arb_add_error_2exp_si(arb_t x, slong err) { fmpz_t t; if (mag_is_zero(arb_radref(x))) { mag_one(arb_radref(x)); mag_mul_2exp_si(arb_radref(x), arb_radref(x), err); return; } fmpz_init(t); fmpz_set_si(t, err); mag_add_2exp_fmpz(arb_radref(x), arb_radref(x), t); fmpz_clear(t); } void arb_add_error_2exp_fmpz(arb_t x, const fmpz_t err) { if (mag_is_zero(arb_radref(x))) { mag_one(arb_radref(x)); mag_mul_2exp_fmpz(arb_radref(x), arb_radref(x), err); return; } mag_add_2exp_fmpz(arb_radref(x), arb_radref(x), err); } void arb_add_error(arb_t x, const arb_t err) { mag_t u; if (arb_is_zero(err)) return; if (mag_is_zero(arb_radref(x))) { arb_get_mag(arb_radref(x), err); return; } mag_init(u); arb_get_mag(u, err); mag_add(arb_radref(x), arb_radref(x), u); mag_clear(u); } arb-2.22.1/arb/addmul.c000066400000000000000000000070151417376376500145460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_addmul_arf(arb_t z, const arb_t x, const arf_t y, slong prec) { mag_t ym; int inexact; if (arb_is_exact(x)) { inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else if (ARB_IS_LAGOM(x) && ARF_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(ym, y); mag_fast_addmul(arb_radref(z), ym, arb_radref(x)); inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else { mag_init_set_arf(ym, y); mag_addmul(arb_radref(z), ym, arb_radref(x)); inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); mag_clear(ym); } } void arb_addmul(arb_t z, const arb_t x, const arb_t y, slong prec) { mag_t zr, xm, ym; int inexact; if (arb_is_exact(y)) { arb_addmul_arf(z, x, arb_midref(y), prec); } else if (arb_is_exact(x)) { arb_addmul_arf(z, y, arb_midref(x), prec); } else if (ARB_IS_LAGOM(x) && ARB_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(xm, arb_midref(x)); mag_fast_init_set_arf(ym, arb_midref(y)); mag_fast_init_set(zr, arb_radref(z)); mag_fast_addmul(zr, xm, arb_radref(y)); mag_fast_addmul(zr, ym, arb_radref(x)); mag_fast_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_addmul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARF_RND_DOWN); if (inexact) arf_mag_fast_add_ulp(zr, zr, arb_midref(z), prec); *arb_radref(z) = *zr; } else { mag_init_set_arf(xm, arb_midref(x)); mag_init_set_arf(ym, arb_midref(y)); mag_init_set(zr, arb_radref(z)); mag_addmul(zr, xm, arb_radref(y)); mag_addmul(zr, ym, arb_radref(x)); mag_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_addmul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARF_RND_DOWN); if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_set(arb_radref(z), zr); mag_clear(zr); mag_clear(xm); mag_clear(ym); } } void arb_addmul_si(arb_t z, const arb_t x, slong y, slong prec) { arf_t t; arf_init_set_si(t, y); /* no need to free */ arb_addmul_arf(z, x, t, prec); } void arb_addmul_ui(arb_t z, const arb_t x, ulong y, slong prec) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ arb_addmul_arf(z, x, t, prec); } void arb_addmul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) { arf_t t; if (!COEFF_IS_MPZ(*y)) { arf_init_set_si(t, *y); /* no need to free */ arb_addmul_arf(z, x, t, prec); } else { arf_init(t); arf_set_fmpz(t, y); arb_addmul_arf(z, x, t, prec); arf_clear(t); } } arb-2.22.1/arb/agm.c000066400000000000000000000136011417376376500140420ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* Use series expansion of the elliptic integral pi/(4K(z^2)) = 1/2 - z^2/8 - 5z^4/128 - 11z^6/512 - 469z^8/32768 + O(z^10) to avoid computing the last couple of AGM iterations. The higher coefficients are bounded by 1/64, so the tail is easily bounded by a geometric series (the error is passed as input here). Note: the input data is a+b, a-b; the variables z, z2 are scratch space. */ static void arb_agm_close_taylor(arb_t res, arb_t z, arb_t z2, const arb_t aplusb, const arb_t aminusb, const mag_t err, slong prec) { arb_div(z, aminusb, aplusb, prec); arb_sqr(z, z, prec); arb_sqr(z2, z, prec); arb_mul_si(res, z2, -469, prec); arb_addmul_si(res, z, -704, prec); arb_mul(res, res, z2, prec); arb_addmul_si(res, z2, -1280, prec); arb_mul_2exp_si(z, z, 12); arb_sub(res, res, z, prec); arb_add_ui(res, res, 16384, prec); arb_mul_2exp_si(res, res, -15); arb_add_error_mag(res, err); arb_mul(res, res, aplusb, prec); } void mag_agm(mag_t res, const mag_t x, const mag_t y) { if (!mag_is_finite(x) || !mag_is_finite(y)) { mag_inf(res); } else if (mag_is_zero(x) || mag_is_zero(y)) { mag_zero(res); } else { mag_t t, u, a, b, one_eps; mag_init(a); mag_init(b); mag_init(t); mag_init(u); mag_init(one_eps); /* invariant: a is an upper bound for agm(x,y) */ /* b would be a lower bound if not for rounding errors */ mag_max(a, x, y); mag_min(b, x, y); mag_one(one_eps); mag_add_ui_2exp_si(one_eps, one_eps, 1, -26); while (1) { mag_mul(t, b, one_eps); if (mag_cmp(t, a) > 0) { mag_set(res, a); break; } mag_add(t, a, b); mag_mul_2exp_si(t, t, -1); mag_mul(u, a, b); mag_sqrt(u, u); mag_swap(t, a); mag_swap(u, b); } mag_clear(a); mag_clear(b); mag_clear(t); mag_clear(u); mag_clear(one_eps); } } void mag_agm_lower(mag_t res, const mag_t x, const mag_t y) { if (mag_is_zero(x) || mag_is_zero(y)) { mag_zero(res); } else if (!mag_is_finite(x) || !mag_is_finite(y)) { mag_inf(res); } else { mag_t t, u, a, b, one_eps; mag_init(a); mag_init(b); mag_init(t); mag_init(u); mag_init(one_eps); /* invariant: b is a lower bound for agm(x,y) */ /* a would be an upper bound if not for rounding errors */ mag_max(a, x, y); mag_min(b, x, y); mag_one(one_eps); mag_add_ui_2exp_si(one_eps, one_eps, 1, -26); while (1) { mag_mul(t, b, one_eps); if (mag_cmp(t, a) > 0) { mag_set(res, b); break; } mag_add_lower(t, a, b); mag_mul_2exp_si(t, t, -1); mag_mul_lower(u, a, b); mag_sqrt_lower(u, u); mag_swap(t, a); mag_swap(u, b); } mag_clear(a); mag_clear(b); mag_clear(t); mag_clear(u); mag_clear(one_eps); } } void arb_agm(arb_t res, const arb_t x, const arb_t y, slong prec) { arb_t a, b, t, u; mag_t err, err2; slong acc1, acc2, wp; if (!arb_is_nonnegative(x) || !arb_is_nonnegative(y) || !arb_is_finite(x) || !arb_is_finite(y)) { arb_indeterminate(res); return; } if (arb_is_zero(x) || arb_is_zero(y)) { arb_zero(res); return; } arb_init(a); arb_init(b); arb_init(t); arb_init(u); mag_init(err); mag_init(err2); arb_set(a, x); arb_set(b, y); wp = prec; while (1) { acc1 = arb_rel_accuracy_bits(a); acc2 = arb_rel_accuracy_bits(b); acc1 = FLINT_MIN(acc1, acc2); /* Compute lower and upper bounds if we don't need high precision. */ if (acc1 < 20 || wp < 20) { arb_get_mag_lower(arb_radref(t), a); arb_get_mag_lower(arb_radref(u), b); mag_agm_lower(err, arb_radref(t), arb_radref(u)); arb_get_mag(arb_radref(t), a); arb_get_mag(arb_radref(u), b); mag_agm(err2, arb_radref(t), arb_radref(u)); arf_set_mag(arb_midref(t), err); arf_set_mag(arb_midref(u), err2); arb_set_interval_arf(res, arb_midref(t), arb_midref(u), prec); break; } if (acc1 < wp - 2 * MAG_BITS) wp = acc1 + 2 * MAG_BITS; arb_sub(u, a, b, wp); /* Fallback exit. */ if (arb_contains_zero(u)) { arb_union(res, a, b, wp); break; } arb_add(t, a, b, wp); arb_get_mag(err, u); arb_get_mag_lower(err2, t); mag_div(err, err, err2); mag_geom_series(err, err, 10); mag_mul_2exp_si(err, err, -6); /* Use Taylor series when we have 1/10 the accurate bits. */ if (mag_cmp_2exp_si(err, -wp) < 0) { /* pass a, b as scratch space */ arb_agm_close_taylor(res, a, b, t, u, err, wp); break; } arb_mul_2exp_si(t, t, -1); arb_mul(u, a, b, wp); arb_sqrt(u, u, wp); arb_swap(t, a); arb_swap(u, b); } arb_clear(a); arb_clear(b); arb_clear(t); arb_clear(u); mag_clear(err); mag_clear(err2); } arb-2.22.1/arb/approx_dot.c000066400000000000000000000407751417376376500154710ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* We need uint64_t instead of mp_limb_t on 32-bit systems for safe summation of 30-bit error bounds. */ #include /* The following macros are found in FLINT's longlong.h, but the release version is out of date. */ /* x86 : 64 bit */ #if (GMP_LIMB_BITS == 64 && defined (__amd64__)) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addq %8,%q2\n\tadcq %6,%q1\n\tadcq %4,%q0" \ : "=r" (sh), "=&r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "rme" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "rme" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "rme" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subq %8,%q2\n\tsbbq %6,%q1\n\tsbbq %4,%q0" \ : "=r" (dh), "=&r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "rme" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "rme" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "rme" ((mp_limb_t)(sl))) \ #endif /* x86_64 */ /* x86 : 32 bit */ #if (GMP_LIMB_BITS == 32 && (defined (__i386__) \ || defined (__i486__) || defined(__amd64__))) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addl %8,%k2\n\tadcl %6,%k1\n\tadcl %4,%k0" \ : "=r" (sh), "=r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "g" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "g" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "g" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subl %8,%k2\n\tsbbl %6,%k1\n\tsbbl %4,%k0" \ : "=r" (dh), "=r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "g" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "g" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "g" ((mp_limb_t)(sl))) \ #endif /* x86 */ #if !defined(add_sssaaaaaa2) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ do { \ mp_limb_t __t, __u; \ add_ssaaaa(__t, sl, (mp_limb_t) 0, al, (mp_limb_t) 0, bl); \ add_ssaaaa(__u, sm, (mp_limb_t) 0, am, (mp_limb_t) 0, bm); \ add_ssaaaa(sh, sm, ah + bh, sm, __u, __t); \ } while (0) #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ do { \ mp_limb_t __t, __u; \ sub_ddmmss(__t, dl, (mp_limb_t) 0, ml, (mp_limb_t) 0, sl); \ sub_ddmmss(__u, dm, (mp_limb_t) 0, mm, (mp_limb_t) 0, sm); \ sub_ddmmss(dh, dm, mh - sh, dm, -__u, -__t); \ } while (0) #endif void _arb_dot_addmul_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, mp_srcptr yptr, mp_size_t yn, int negative, flint_bitcnt_t shift); void _arb_dot_add_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, int negative, flint_bitcnt_t shift); void arb_approx_dot_simple(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) { slong i; if (len <= 0) { if (initial == NULL) arf_zero(arb_midref(res)); else arf_set_round(arb_midref(res), arb_midref(initial), prec, ARB_RND); return; } if (initial == NULL) { arf_mul(arb_midref(res), arb_midref(x), arb_midref(y), prec, ARB_RND); } else { if (subtract) arf_neg(arb_midref(res), arb_midref(initial)); else arf_set(arb_midref(res), arb_midref(initial)); arf_addmul(arb_midref(res), arb_midref(x), arb_midref(y), prec, ARB_RND); } for (i = 1; i < len; i++) arf_addmul(arb_midref(res), arb_midref(x + i * xstep), arb_midref(y + i * ystep), prec, ARB_RND); if (subtract) arf_neg(arb_midref(res), arb_midref(res)); } void arb_approx_dot(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) { slong i, j, nonzero, padding, extend; slong xexp, yexp, exp, max_exp, min_exp, sum_exp; int xnegative, ynegative; mp_size_t xn, yn, sn, alloc; flint_bitcnt_t shift; arb_srcptr xi, yi; arf_srcptr xm, ym; mp_limb_t serr; /* Sum over arithmetic errors - not used, but need dummy for calls */ mp_ptr tmp, sum; /* Workspace */ ARF_ADD_TMP_DECL; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) arf_zero(arb_midref(res)); else { if (subtract) arf_neg_mul(arb_midref(res), arb_midref(x), arb_midref(y), prec, ARB_RND); else arf_mul(arb_midref(res), arb_midref(x), arb_midref(y), prec, ARB_RND); } return; } else if (len <= 0) { arf_set_round(arb_midref(res), arb_midref(initial), prec, ARB_RND); return; } } /* Number of nonzero midpoint terms in sum. */ nonzero = 0; /* Terms are bounded by 2^max_exp (with WORD_MIN = -infty) */ max_exp = WORD_MIN; /* Used to reduce the precision. */ min_exp = WORD_MAX; /* Account for the initial term. */ if (initial != NULL) { if (!ARF_IS_LAGOM(arb_midref(initial))) { arb_approx_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(initial); if (!arf_is_special(xm)) { max_exp = ARF_EXP(xm); nonzero++; if (prec > 2 * FLINT_BITS) min_exp = ARF_EXP(xm) - ARF_SIZE(xm) * FLINT_BITS; } } /* Determine maximum exponents for the main sum and the radius sum. */ for (i = 0; i < len; i++) { xi = x + i * xstep; yi = y + i * ystep; /* Fallback for huge exponents or non-finite values. */ if (!ARF_IS_LAGOM(arb_midref(xi)) || !ARF_IS_LAGOM(arb_midref(yi))) { arb_approx_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(xi); ym = arb_midref(yi); if (!arf_is_special(xm)) { xexp = ARF_EXP(xm); if (!arf_is_special(ym)) { yexp = ARF_EXP(ym); max_exp = FLINT_MAX(max_exp, xexp + yexp); nonzero++; if (prec > 2 * FLINT_BITS) { slong bot; bot = (xexp + yexp) - (ARF_SIZE(xm) + ARF_SIZE(ym)) * FLINT_BITS; min_exp = FLINT_MIN(min_exp, bot); } } } } /* The midpoint sum is zero. */ if (max_exp == WORD_MIN) { arf_zero(arb_midref(res)); return; } else { /* Reduce precision based on actual sizes. */ if (min_exp != WORD_MAX) prec = FLINT_MIN(prec, max_exp - min_exp + MAG_BITS); prec = FLINT_MAX(prec, 2); } /* Extend sum so that we can use two's complement addition. */ extend = FLINT_BIT_COUNT(nonzero) + 1; /* Extra bits to improve accuracy (optional). */ padding = 4 + FLINT_BIT_COUNT(len); /* Number of limbs. */ sn = (prec + extend + padding + FLINT_BITS - 1) / FLINT_BITS; /* Avoid having to make a special case for sn = 1. */ sn = FLINT_MAX(sn, 2); /* Exponent for the main sum. */ sum_exp = max_exp + extend; /* We need sn + 1 limb for the sum (sn limbs + 1 dummy limb for carry or borrow that avoids an extra branch). We need 2 * (sn + 2) limbs to store the product of two numbers with up to (sn + 2) limbs, plus 1 extra limb for shifting the product. */ alloc = (sn + 1) + 2 * (sn + 2) + 1; ARF_ADD_TMP_ALLOC(sum, alloc) tmp = sum + (sn + 1); /* Set sum to 0 */ serr = 0; for (j = 0; j < sn + 1; j++) sum[j] = 0; if (initial != NULL) { xm = arb_midref(initial); if (!arf_is_special(xm)) { mp_srcptr xptr; xexp = ARF_EXP(xm); xn = ARF_SIZE(xm); xnegative = ARF_SGNBIT(xm); shift = sum_exp - xexp; if (shift < sn * FLINT_BITS) { xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); _arb_dot_add_generic(sum, &serr, tmp, sn, xptr, xn, xnegative ^ subtract, shift); } } } for (i = 0; i < len; i++) { xi = x + i * xstep; yi = y + i * ystep; xm = arb_midref(xi); ym = arb_midref(yi); /* The midpoints of x[i] and y[i] are both nonzero. */ if (!arf_is_special(xm) && !arf_is_special(ym)) { xexp = ARF_EXP(xm); xn = ARF_SIZE(xm); xnegative = ARF_SGNBIT(xm); yexp = ARF_EXP(ym); yn = ARF_SIZE(ym); ynegative = ARF_SGNBIT(ym); exp = xexp + yexp; shift = sum_exp - exp; if (shift >= sn * FLINT_BITS) { /* do nothing */ } #if 0 else if (xn == 1 && yn == 1 && sn == 2 && shift < FLINT_BITS) /* Fastest path. */ { mp_limb_t hi, lo, x0, y0; x0 = ARF_NOPTR_D(xm)[0]; y0 = ARF_NOPTR_D(ym)[0]; umul_ppmm(hi, lo, x0, y0); lo = (lo >> shift) | (hi << (FLINT_BITS - shift)); hi = (hi >> shift); if (xnegative ^ ynegative) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], hi, lo); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], hi, lo); } else if (xn == 2 && yn == 2 && shift < FLINT_BITS && sn <= 3) { mp_limb_t x1, x0, y1, y0; mp_limb_t u3, u2, u1, u0; x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; nn_mul_2x2(u3, u2, u1, u0, x1, x0, y1, y0); u1 = (u1 >> shift) | (u2 << (FLINT_BITS - shift)); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); if (sn == 2) { if (xnegative ^ ynegative) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], u3, u2); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], u3, u2); } else { if (xnegative ^ ynegative) sub_dddmmmsss2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); else add_sssaaaaaa2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); } } #endif else if (xn <= 2 && yn <= 2 && sn <= 3) { mp_limb_t x1, x0, y1, y0; mp_limb_t u3, u2, u1, u0; if (xn == 1 && yn == 1) { x0 = ARF_NOPTR_D(xm)[0]; y0 = ARF_NOPTR_D(ym)[0]; umul_ppmm(u3, u2, x0, y0); u1 = u0 = 0; } else if (xn == 2 && yn == 2) { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; nn_mul_2x2(u3, u2, u1, u0, x1, x0, y1, y0); } else if (xn == 1) { x0 = ARF_NOPTR_D(xm)[0]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; nn_mul_2x1(u3, u2, u1, y1, y0, x0); u0 = 0; } else { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; nn_mul_2x1(u3, u2, u1, x1, x0, y0); u0 = 0; } if (sn == 2) { if (shift < FLINT_BITS) { u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { u2 = u3; u3 = 0; } else /* FLINT_BITS < shift < 2 * FLINT_BITS */ { u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } if (xnegative ^ ynegative) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], u3, u2); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], u3, u2); } else if (sn == 3) { if (shift < FLINT_BITS) { u1 = (u1 >> shift) | (u2 << (FLINT_BITS - shift)); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { u1 = u2; u2 = u3; u3 = 0; } else if (shift < 2 * FLINT_BITS) { u1 = (u3 << (2 * FLINT_BITS - shift)) | (u2 >> (shift - FLINT_BITS)); u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } else if (shift == 2 * FLINT_BITS) { u1 = u3; u2 = 0; u3 = 0; } else /* 2 * FLINT_BITS < shift < 3 * FLINT_BITS */ { u1 = (u3 >> (shift - 2 * FLINT_BITS)); u2 = 0; u3 = 0; } if (xnegative ^ ynegative) sub_dddmmmsss2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); else add_sssaaaaaa2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); } } else { mp_srcptr xptr, yptr; xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); yptr = (yn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(ym) : ARF_PTR_D(ym); _arb_dot_addmul_generic(sum, &serr, tmp, sn, xptr, xn, yptr, yn, xnegative ^ ynegative, shift); } } } xnegative = 0; if (sum[sn - 1] >= LIMB_TOP) { mpn_neg(sum, sum, sn); xnegative = 1; } if (sum[sn - 1] == 0) { slong sum_exp2; mp_size_t sn2; sn2 = sn; sum_exp2 = sum_exp; while (sn2 > 0 && sum[sn2 - 1] == 0) { sum_exp2 -= FLINT_BITS; sn2--; } if (sn2 == 0) { arf_zero(arb_midref(res)); } else { _arf_set_round_mpn(arb_midref(res), &exp, sum, sn2, xnegative ^ subtract, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp + sum_exp2); } } else { if (sn == 2) _arf_set_round_uiui(arb_midref(res), &exp, sum[1], sum[0], xnegative ^ subtract, prec, ARF_RND_DOWN); else _arf_set_round_mpn(arb_midref(res), &exp, sum, sn, xnegative ^ subtract, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp + sum_exp); } ARF_ADD_TMP_FREE(sum, alloc); } arb-2.22.1/arb/asin.c000066400000000000000000000024221417376376500142270ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_asin(arb_t z, const arb_t x, slong prec) { arb_t t; if (arb_is_exact(x)) { int side; if (arf_is_zero(arb_midref(x))) { arb_zero(z); return; } side = arf_cmpabs_2exp_si(arb_midref(x), 0); /* +/- 1 */ if (side == 0) { if (arf_is_one(arb_midref(x))) { arb_const_pi(z, prec); } else { arb_const_pi(z, prec); arb_neg(z, z); } arb_mul_2exp_si(z, z, -1); return; } else if (side > 0) { arb_indeterminate(z); return; } } arb_init(t); arb_one(t); arb_submul(t, x, x, prec); arb_rsqrt(t, t, prec); arb_mul(t, x, t, prec); arb_atan(z, t, prec); arb_clear(t); } arb-2.22.1/arb/asinh.c000066400000000000000000000016541417376376500144050ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_asinh(arb_t z, const arb_t x, slong prec) { if (arb_is_zero(x)) { arb_zero(z); } else { arb_t t; arb_init(t); arb_mul(t, x, x, prec + 4); arb_sqrt1pm1(t, t, prec + 4); if (arf_sgn(arb_midref(x)) >= 0) { arb_add(t, t, x, prec + 4); arb_log1p(z, t, prec); } else { arb_sub(t, t, x, prec + 4); arb_log1p(z, t, prec); arb_neg(z, z); } arb_clear(t); } } arb-2.22.1/arb/atan.c000066400000000000000000000073071417376376500142270ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_atan(arb_t res, const arb_t x, slong prec) { if (mag_is_zero(arb_radref(x))) { arb_atan_arf(res, arb_midref(x), prec); } else if (arf_is_nan(arb_midref(x))) { arb_indeterminate(res); } else if (mag_is_inf(arb_radref(x)) || arf_is_zero(arb_midref(x))) { mag_atan(arb_radref(res), arb_radref(x)); arf_zero(arb_midref(res)); } else if (arf_is_special(arb_midref(x))) /* at +/- inf */ { arb_atan_arf(res, arb_midref(x), prec); } else /* both mid(x), rad(x) non-special */ { slong acc; mag_t t, u; /* Estimate accuracy (first guess, only good near 0). */ acc = _fmpz_sub_small(ARF_EXPREF(arb_midref(x)), MAG_EXPREF(arb_radref(x))); if (acc < -10) /* Only compute a rough bound. */ { arb_get_mag(arb_radref(res), x); mag_atan(arb_radref(res), arb_radref(res)); arf_zero(arb_midref(res)); return; } mag_init(t); mag_init(u); arb_get_mag_lower(t, x); if (mag_is_zero(t)) /* Interval includes zero. */ { /* atan(rad(x) - |mid(x)|) */ arf_get_mag_lower(t, arb_midref(x)); mag_sub(t, arb_radref(x), t); mag_atan(t, t); /* atan(|mid(x)| + rad(x)) */ arf_get_mag(u, arb_midref(x)); mag_add(u, arb_radref(x), u); mag_atan(u, u); if (arf_sgn(arb_midref(x)) > 0) arb_set_interval_neg_pos_mag(res, t, u, FLINT_MIN(prec, MAG_BITS)); else arb_set_interval_neg_pos_mag(res, u, t, FLINT_MIN(prec, MAG_BITS)); } else { /* Adjust estimate of accuracy for large x. */ if (fmpz_sgn(MAG_EXPREF(t)) > 0) { /* acc = 2 * texp - radexp */ acc = _fmpz_sub_small(MAG_EXPREF(t), MAG_EXPREF(arb_radref(x))); if (acc < prec && !COEFF_IS_MPZ(MAG_EXP(t))) acc += MAG_EXP(t); } /* Clamp acc and adjust precision. */ acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); /* Compute using endpoints */ if (acc < 20) { arb_get_mag(u, x); mag_atan_lower(t, t); mag_atan(u, u); if (arf_sgn(arb_midref(x)) > 0) { arb_set_interval_mag(res, t, u, prec); } else { arb_set_interval_mag(res, t, u, prec); arb_neg(res, res); } } else { mag_mul_lower(t, t, t); mag_one(u); mag_add_lower(t, t, u); mag_div(t, arb_radref(x), t); if (mag_cmp_2exp_si(t, 0) > 0) { mag_const_pi(u); mag_min(t, t, u); } arb_atan_arf(res, arb_midref(x), prec); mag_add(arb_radref(res), arb_radref(res), t); } } mag_clear(t); mag_clear(u); } } arb-2.22.1/arb/atan2.c000066400000000000000000000062761417376376500143150ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_atan2(arb_t r, const arb_t b, const arb_t a, slong prec) { #define am arb_midref(a) #define ar arb_radref(a) #define bm arb_midref(b) #define br arb_radref(b) /* a + bi is a real number */ if (arb_is_zero(b)) { /* exactly zero */ if (arb_is_zero(a)) { /* define arg(0) = 0 by convention */ arb_zero(r); } /* interval contains only nonnegative numbers */ else if (arf_sgn(am) > 0 && arf_cmpabs_mag(am, ar) >= 0) { arb_zero(r); } /* interval contains only negative numbers */ else if (arf_sgn(am) < 0 && arf_cmpabs_mag(am, ar) > 0) { arb_const_pi(r, prec); } else { /* both positive and negative -- argument will be in [0, pi] */ mag_const_pi(arb_radref(r)); arf_set_mag(arb_midref(r), arb_radref(r)); arb_set_round(r, r, prec); arb_mul_2exp_si(r, r, -1); } } /* an imaginary number */ else if (arb_is_zero(a)) { /* interval contains only positive numbers */ if (arf_sgn(bm) > 0 && arf_cmpabs_mag(bm, br) > 0) { arb_const_pi(r, prec); arb_mul_2exp_si(r, r, -1); } /* interval contains only negative numbers */ else if (arf_sgn(bm) < 0 && arf_cmpabs_mag(bm, br) > 0) { arb_const_pi(r, prec); arb_neg(r, r); arb_mul_2exp_si(r, r, -1); } else { /* both positive and negative -- argument will be in 0 +/- pi/2 */ arf_zero(arb_midref(r)); mag_const_pi(arb_radref(r)); mag_mul_2exp_si(arb_radref(r), arb_radref(r), -1); } } /* strictly in the right half-plane -- atan(b/a) */ else if (arf_sgn(am) > 0 && arf_cmpabs_mag(am, ar) > 0) { arb_div(r, b, a, prec); arb_atan(r, r, prec); } /* strictly in the upper half-plane -- pi/2 - atan(a/b) */ else if (arf_sgn(bm) > 0 && arf_cmpabs_mag(bm, br) > 0) { arb_t t; arb_init(t); arb_div(r, a, b, prec); arb_atan(r, r, prec); arb_const_pi(t, prec); arb_mul_2exp_si(t, t, -1); arb_sub(r, t, r, prec); arb_clear(t); } /* strictly in the lower half-plane -- -pi/2 - atan(a/b) */ else if (arf_sgn(bm) < 0 && arf_cmpabs_mag(bm, br) > 0) { arb_t t; arb_init(t); arb_div(r, a, b, prec); arb_atan(r, r, prec); arb_const_pi(t, prec); arb_mul_2exp_si(t, t, -1); arb_add(r, t, r, prec); arb_neg(r, r); arb_clear(t); } /* overlaps the nonpositive half-axis -- [-pi, pi] */ else { arf_zero(arb_midref(r)); mag_const_pi(arb_radref(r)); } } arb-2.22.1/arb/atan_arf.c000066400000000000000000000177321417376376500150620ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define TMP_ALLOC_LIMBS(size) TMP_ALLOC((size) * sizeof(mp_limb_t)) /* atan(x) = x + eps, |eps| < x^3*/ void arb_atan_eps(arb_t z, const arf_t x, slong prec) { fmpz_t mag; fmpz_init(mag); fmpz_mul_ui(mag, ARF_EXPREF(x), 3); arb_set_arf(z, x); arb_set_round(z, z, prec); arb_add_error_2exp_fmpz(z, mag); fmpz_clear(mag); } /* atan(x) = pi/2 - eps, eps < 1/x <= 2^(1-mag) */ void arb_atan_inf_eps(arb_t z, const arf_t x, slong prec) { fmpz_t mag; fmpz_init(mag); fmpz_neg(mag, ARF_EXPREF(x)); fmpz_add_ui(mag, mag, 1); if (arf_sgn(x) > 0) { arb_const_pi(z, prec); } else { arb_const_pi(z, prec); arb_neg(z, z); } arb_mul_2exp_si(z, z, -1); arb_add_error_2exp_fmpz(z, mag); fmpz_clear(mag); } void arb_atan_arf(arb_t z, const arf_t x, slong prec) { if (arf_is_special(x)) { if (arf_is_zero(x)) { arb_zero(z); } else if (arf_is_pos_inf(x)) { arb_const_pi(z, prec); arb_mul_2exp_si(z, z, -1); } else if (arf_is_neg_inf(x)) { arb_const_pi(z, prec); arb_mul_2exp_si(z, z, -1); arb_neg(z, z); } else { arb_indeterminate(z); } } else if (COEFF_IS_MPZ(*ARF_EXPREF(x))) { if (fmpz_sgn(ARF_EXPREF(x)) < 0) arb_atan_eps(z, x, prec); else arb_atan_inf_eps(z, x, prec); } else { slong exp, wp, wn, N, r; mp_srcptr xp; mp_size_t xn, tn; mp_ptr tmp, w, t, u; mp_limb_t p1, q1bits, p2, q2bits, error, error2; int negative, inexact, reciprocal; TMP_INIT; exp = ARF_EXP(x); negative = ARF_SGNBIT(x); if (exp < -(prec/2) - 2 || exp > prec + 2) { if (exp < 0) arb_atan_eps(z, x, prec); else arb_atan_inf_eps(z, x, prec); return; } ARF_GET_MPN_READONLY(xp, xn, x); /* Special case: +/- 1 (we require |x| != 1 later on) */ if (exp == 1 && xn == 1 && xp[xn-1] == LIMB_TOP) { arb_const_pi(z, prec); arb_mul_2exp_si(z, z, -2); if (negative) arb_neg(z, z); return; } /* Absolute working precision (NOT rounded to a limb multiple) */ wp = prec - FLINT_MIN(0, exp) + 4; /* Too high precision to use table */ if (wp > ARB_ATAN_TAB2_PREC) { arb_atan_arf_bb(z, x, prec); return; } /* Working precision in limbs */ wn = (wp + FLINT_BITS - 1) / FLINT_BITS; TMP_START; tmp = TMP_ALLOC_LIMBS(4 * wn + 3); w = tmp; /* requires wn+1 limbs */ t = w + wn + 1; /* requires wn+1 limbs */ u = t + wn + 1; /* requires 2wn+1 limbs */ /* ----------------------------------------------------------------- */ /* Convert x or 1/x to a fixed-point number |w| < 1 */ /* ----------------------------------------------------------------- */ if (exp <= 0) /* |x| < 1 */ { reciprocal = 0; /* todo: just zero top */ flint_mpn_zero(w, wn); /* w = x as a fixed-point number */ error = _arf_get_integer_mpn(w, xp, xn, exp + wn * FLINT_BITS); } else /* |x| > 1 */ { slong one_exp, one_limbs, one_bits; mp_ptr one; reciprocal = 1; one_exp = xn * FLINT_BITS + wn * FLINT_BITS - exp; flint_mpn_zero(w, wn); /* 1/x becomes zero */ if (one_exp >= FLINT_BITS - 1) { /* w = 1/x */ one_limbs = one_exp / FLINT_BITS; one_bits = one_exp % FLINT_BITS; if (one_limbs + 1 >= xn) { one = TMP_ALLOC_LIMBS(one_limbs + 1); flint_mpn_zero(one, one_limbs); one[one_limbs] = UWORD(1) << one_bits; /* todo: only zero necessary part */ flint_mpn_zero(w, wn); mpn_tdiv_q(w, one, one_limbs + 1, xp, xn); /* Now w must be < 1 since x > 1 and we rounded down; thus w[wn] must be zero */ } } /* todo: moderate powers of two would be exact... */ error = 1; } /* ----------------------------------------------------------------- */ /* Table-based argument reduction */ /* ----------------------------------------------------------------- */ /* choose p such that p/q <= x < (p+1)/q */ if (wp <= ARB_ATAN_TAB1_PREC) q1bits = ARB_ATAN_TAB1_BITS; else q1bits = ARB_ATAN_TAB21_BITS; p1 = w[wn-1] >> (FLINT_BITS - q1bits); /* atan(w) = atan(p/q) + atan(w2) */ /* where w2 = (q*w-p)/(q+p*w) */ if (p1 != 0) { t[wn] = (UWORD(1) << q1bits) + mpn_mul_1(t, w, wn, p1); flint_mpn_zero(u, wn); u[2 * wn] = mpn_lshift(u + wn, w, wn, q1bits) - p1; mpn_tdiv_q(w, u, 2 * wn + 1, t, wn + 1); error++; /* w2 is computed with 1 ulp error */ } /* Do a second round of argument reduction */ if (wp <= ARB_ATAN_TAB1_PREC) { p2 = 0; } else { q2bits = ARB_ATAN_TAB21_BITS + ARB_ATAN_TAB22_BITS; p2 = w[wn-1] >> (FLINT_BITS - q2bits); if (p2 != 0) { t[wn] = (UWORD(1) << q2bits) + mpn_mul_1(t, w, wn, p2); flint_mpn_zero(u, wn); u[2 * wn] = mpn_lshift(u + wn, w, wn, q2bits) - p2; mpn_tdiv_q(w, u, 2 * wn + 1, t, wn + 1); error++; } } /* |w| <= 2^-r */ r = _arb_mpn_leading_zeros(w, wn); /* N >= (wp-r)/(2r) */ N = (wp - r + (2*r-1)) / (2*r); /* Evaluate Taylor series */ _arb_atan_taylor_rs(t, &error2, w, wn, N, 1); /* Taylor series evaluation error */ error += error2; /* Size of output number */ tn = wn; /* First table lookup */ if (p1 != 0) { if (wp <= ARB_ATAN_TAB1_PREC) mpn_add_n(t, t, arb_atan_tab1[p1] + ARB_ATAN_TAB1_LIMBS - tn, tn); else mpn_add_n(t, t, arb_atan_tab21[p1] + ARB_ATAN_TAB2_LIMBS - tn, tn); error++; } /* Second table lookup */ if (p2 != 0) { mpn_add_n(t, t, arb_atan_tab22[p2] + ARB_ATAN_TAB2_LIMBS - tn, tn); error++; } /* pi/2 - atan(1/x) */ if (reciprocal) { t[tn] = LIMB_ONE - mpn_sub_n(t, arb_atan_pi2_minus_one + ARB_ATAN_TAB2_LIMBS - tn, t, tn); /* result can be >= 1 */ tn += (t[tn] != 0); /* error of pi/2 */ error++; } /* The accumulated arithmetic error */ mag_set_ui_2exp_si(arb_radref(z), error, -wn * FLINT_BITS); /* Truncation error from the Taylor series */ mag_add_ui_2exp_si(arb_radref(z), arb_radref(z), 1, -r*(2*N+1)); /* Set the midpoint */ inexact = _arf_set_mpn_fixed(arb_midref(z), t, tn, wn, negative, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); TMP_END; } } arb-2.22.1/arb/atan_arf_bb.c000066400000000000000000000204231417376376500155140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* Determine N such that the error is bounded by 2^-prec. We choose an N with many trailing zeros to improve efficiency of the binary splitting. With N = 0, 1, 2, ... the highest included term is x, x^3, x^5, ... so the error is bounded by x^3, x^5, x^7, ... = x^(2N+3) */ static slong bs_num_terms(slong mag, slong prec) { slong N; if (mag >= 0) flint_abort(); N = 0; while (mag * (2 * N + 3) > -prec) N++; if (N > 10000) while (N % 128 != 0) N++; if (N > 1000) while (N % 16 != 0) N++; if (N > 100) while (N % 2 != 0) N++; return N; } /* Argument reduction: apply atan(x) = 2 atan(x/(1+sqrt(1+x^2))) a total of r times, and convert result to a fixed-point number res together with absolute error err. With an initial inversion if xmag > 0. */ void arb_atan_bb_reduce(fmpz_t res, mag_t err, const arf_t x, slong xmag, slong r, slong prec) { int inexact; if (r == 0) { if (xmag <= 0) { inexact = arf_get_fmpz_fixed_si(res, x, -prec); mag_set_ui_2exp_si(err, inexact, -prec); } else { slong wp; arb_t t; wp = FLINT_MAX(8, prec - xmag); arb_init(t); arb_set_arf(t, x); arb_set_round(t, t, wp); arb_ui_div(t, 1, t, wp); mag_set(err, arb_radref(t)); inexact = arf_get_fmpz_fixed_si(res, arb_midref(t), -prec); mag_add_ui_2exp_si(err, err, inexact, -prec); arb_clear(t); } } else { slong k; arb_t p, p2, q, q2; arb_init(p); arb_init(p2); arb_init(q); arb_init(q2); if (xmag <= 0) { arb_set_arf(p, x); arb_set_round(p, p, prec); arb_mul(p2, p, p, prec); arb_add_ui(q, p2, 1, prec); arb_sqrt(q, q, prec); arb_add_ui(q, q, 1, prec); for (k = 1; k < r; k++) { if (k == 1) { arb_mul_2exp_si(q2, q, 1); arb_add(q2, q2, p2, prec); } else { arb_mul(q2, q, q, prec); } arb_add(q2, p2, q2, prec); arb_sqrt(q2, q2, prec); arb_add(q, q, q2, prec); } } else { arb_one(p); arb_one(p2); arb_set_arf(q, x); arb_set_round(q, q, prec); for (k = 0; k < r; k++) { arb_mul(q2, q, q, prec); arb_add(q2, p2, q2, prec); arb_sqrt(q2, q2, prec); arb_add(q, q, q2, prec); } } arb_div(p, p, q, prec); mag_set(err, arb_radref(p)); inexact = arf_get_fmpz_fixed_si(res, arb_midref(p), -prec); mag_add_ui_2exp_si(err, err, inexact, -prec); arb_clear(p); arb_clear(p2); arb_clear(q); arb_clear(q2); } } void arb_atan_arf_bb(arb_t z, const arf_t x, slong prec) { slong iter, bits, r, mag, q, wp, N; slong argred_bits, start_bits; flint_bitcnt_t Qexp[1]; int inverse; mag_t inp_err; fmpz_t s, t, u, P, Q, err; if (arf_is_zero(x)) { arb_zero(z); return; } if (arf_is_special(x)) { flint_abort(); } if (ARF_SGNBIT(x)) { arf_t y; arf_init_neg_shallow(y, x); arb_atan_arf_bb(z, y, prec); arb_neg(z, z); return; } mag = arf_abs_bound_lt_2exp_si(x); /* We assume that this function only gets called with something reasonable as input (huge/tiny input will be handled by the main atan wrapper). */ if (FLINT_ABS(mag) > 2 * prec + 100) { flint_printf("arb_atan_arf_bb: unexpectedly large/small input\n"); flint_abort(); } /* approximate by x - x^3 / 3 or pi/2 - 1/x + (1/3)/x^3 */ if (mag < -prec / 4 - 2 || (mag-1) > prec / 5 + 3) { arb_t t; arb_init(t); arb_set_arf(t, x); if (mag < 0) { arb_mul(t, t, t, prec); arb_mul_arf(t, t, x, prec); arb_div_ui(t, t, 3, prec); arb_sub_arf(t, t, x, prec); arb_neg(z, t); /* error is bounded by x^5 */ mag_add_ui_2exp_si(arb_radref(z), arb_radref(z), 1, 5 * mag); } else { arb_ui_div(t, 1, t, prec); arb_mul(z, t, t, prec); arb_mul(z, z, t, prec); arb_div_ui(z, z, 3, prec); arb_sub(z, t, z, prec); arb_const_pi(t, prec + 2); arb_mul_2exp_si(t, t, -1); arb_sub(z, t, z, prec); /* error is bounded by 1/x^5, and 1/x <= 2^(1-mag) */ mag_add_ui_2exp_si(arb_radref(z), arb_radref(z), 1, 5 * (1-mag)); } arb_clear(t); return; } argred_bits = 8; start_bits = 16; /* Argument reduction q times. */ q = FLINT_MAX(0, mag + argred_bits); /* Determine working precision. */ wp = prec + 10 + 2 * q + 2 * FLINT_BIT_COUNT(prec); if (mag < 0) wp += (-mag); fmpz_init(s); fmpz_init(t); fmpz_init(u); fmpz_init(Q); fmpz_init(P); fmpz_init(err); /* in fixed-point ulp */ mag_init(inp_err); /* absolute error */ arb_atan_bb_reduce(t, inp_err, x, mag, q, wp); inverse = mag > 0; /* todo: compute in function, or pass to it */ /* s = 0, t = x */ for (iter = 0, bits = start_bits; !fmpz_is_zero(t); iter++, bits *= 2) { /* Extract bits. */ r = FLINT_MIN(bits, wp); fmpz_tdiv_q_2exp(u, t, wp - r); if (!fmpz_is_zero(u)) { /* Binary splitting (+1 fixed-point ulp truncation error). */ mag = fmpz_bits(u) - r; N = bs_num_terms(mag, wp); if (N != 0) { _arb_atan_sum_bs_powtab(P, Q, Qexp, u, r, N); /* multiply by u/2^r */ fmpz_mul(P, P, u); *Qexp += r; /* T = T / Q (+1 fixed-point ulp error). */ if (*Qexp >= wp) { fmpz_tdiv_q_2exp(P, P, *Qexp - wp); fmpz_tdiv_q(P, P, Q); } else { fmpz_mul_2exp(P, P, wp - *Qexp); fmpz_tdiv_q(P, P, Q); } fmpz_add(s, s, P); } /* add u/2^r */ fmpz_mul_2exp(Q, u, wp - r); fmpz_add(s, s, Q); /* 1 ulp from the division, 1 ulp from truncating the Taylor series */ fmpz_add_ui(err, err, 2); } /* atan(t) = atan(u/2^r) + atan((t 2^r - u)/(2^r + u t)) */ fmpz_mul_2exp(P, t, r); fmpz_mul_2exp(Q, u, wp); fmpz_sub(P, P, Q); fmpz_one(Q); fmpz_mul_2exp(Q, Q, r + wp); fmpz_addmul(Q, t, u); fmpz_mul_2exp(P, P, wp); fmpz_tdiv_q(t, P, Q); /* 1 ulp error from the division */ fmpz_add_ui(err, err, 1); } /* add both err and inp_err */ arf_set_fmpz(arb_midref(z), s); mag_set_fmpz(arb_radref(z), err); arb_mul_2exp_si(z, z, -wp); mag_add(arb_radref(z), arb_radref(z), inp_err); /* argument reduction: atan(x) = 2^q atan(x') */ arb_mul_2exp_si(z, z, q); /* outmost argument reduction: atan(x) = +/-pi/2 - atan(1/x) */ if (inverse) { arb_t pi2; arb_init(pi2); arb_const_pi(pi2, wp); arb_mul_2exp_si(pi2, pi2, -1); arb_sub(z, pi2, z, wp); arb_clear(pi2); } arb_set_round(z, z, prec); fmpz_clear(s); fmpz_clear(t); fmpz_clear(u); fmpz_clear(Q); fmpz_clear(P); fmpz_clear(err); mag_clear(inp_err); } arb-2.22.1/arb/atan_sum_bs_powtab.c000066400000000000000000000061061417376376500171470ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" slong _arb_compute_bs_exponents(slong * tab, slong n); slong _arb_get_exp_pos(const slong * tab, slong step); static void bsplit(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const slong * xexp, const fmpz * xpow, flint_bitcnt_t r, slong a, slong b) { if (b - a == 1) { fmpz_set(T, xpow); if (a % 2 == 0) fmpz_neg_ui(Q, 2 * a + 3); else fmpz_set_ui(Q, 2 * a + 3); *Qexp = 2 * r; } else if (b - a == 2) { fmpz_mul_ui(T, xpow, 2 * a + 5); fmpz_mul_2exp(T, T, 2 * r); fmpz_submul_ui(T, xpow + 1, 2 * a + 3); if (a % 2 == 1) fmpz_neg(T, T); fmpz_neg_ui(Q, 2 * a + 3); fmpz_mul_ui(Q, Q, 2 * a + 5); *Qexp = 4 * r; } else { slong step, m, i; flint_bitcnt_t Q2exp[1]; fmpz_t Q2, T2; step = (b - a) / 2; m = a + step; fmpz_init(Q2); fmpz_init(T2); bsplit(T, Q, Qexp, xexp, xpow, r, a, m); bsplit(T2, Q2, Q2exp, xexp, xpow, r, m, b); fmpz_mul(T, T, Q2); fmpz_mul_2exp(T, T, *Q2exp); /* find x^step in table */ i = _arb_get_exp_pos(xexp, step); fmpz_mul(T2, T2, Q); fmpz_addmul(T, xpow + i, T2); fmpz_clear(T2); fmpz_mul(Q, Q, Q2); *Qexp = *Qexp + *Q2exp; fmpz_clear(Q2); } } void _arb_atan_sum_bs_powtab(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) { slong * xexp; slong length, i; fmpz * xpow; /* compute the powers of x^2 that will appear (at least x^2) */ xexp = flint_calloc(2 * FLINT_BITS, sizeof(slong)); length = _arb_compute_bs_exponents(xexp, N); xpow = _fmpz_vec_init(length); fmpz_mul(xpow, x, x); /* build x^i table */ for (i = 1; i < length; i++) { if (xexp[i] == 2 * xexp[i-1]) { fmpz_mul(xpow + i, xpow + i - 1, xpow + i - 1); } else if (xexp[i] == 2 * xexp[i-2]) /* prefer squaring if possible */ { fmpz_mul(xpow + i, xpow + i - 2, xpow + i - 2); } else if (xexp[i] == 2 * xexp[i-1] + 1) { fmpz_mul(xpow + i, xpow + i - 1, xpow + i - 1); fmpz_mul(xpow + i, xpow + i, xpow); } else if (xexp[i] == 2 * xexp[i-2] + 1) { fmpz_mul(xpow + i, xpow + i - 2, xpow + i - 2); fmpz_mul(xpow + i, xpow + i, xpow); } else { flint_printf("power table has the wrong structure!\n"); flint_abort(); } } bsplit(T, Q, Qexp, xexp, xpow, r, 0, N); _fmpz_vec_clear(xpow, length); flint_free(xexp); } arb-2.22.1/arb/atan_sum_bs_simple.c000066400000000000000000000030461417376376500171440ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void bsplit(fmpz_t P, fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong a, slong b) { if (b - a == 1) { fmpz_mul(P, x, x); fmpz_set(T, P); if (a % 2 == 0) fmpz_neg_ui(Q, 2 * a + 3); else fmpz_set_ui(Q, 2 * a + 3); *Qexp = 2 * r; } else { slong step, m; flint_bitcnt_t Q2exp[1]; fmpz_t P2, Q2, T2; step = (b - a) / 2; m = a + step; fmpz_init(P2); fmpz_init(Q2); fmpz_init(T2); bsplit(P, T, Q, Qexp, x, r, a, m); bsplit(P2, T2, Q2, Q2exp, x, r, m, b); fmpz_mul(T, T, Q2); fmpz_mul_2exp(T, T, *Q2exp); fmpz_mul(T2, T2, Q); fmpz_addmul(T, P, T2); fmpz_mul(P, P, P2); fmpz_mul(Q, Q, Q2); *Qexp = *Qexp + *Q2exp; fmpz_clear(P2); fmpz_clear(Q2); fmpz_clear(T2); } } void _arb_atan_sum_bs_simple(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) { fmpz_t P; fmpz_init(P); bsplit(P, T, Q, Qexp, x, r, 0, N); fmpz_clear(P); } arb-2.22.1/arb/atan_tab.c000066400000000000000000004044001417376376500150500ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #if FLINT_BITS == 64 #define Z2(a,b) UWORD(0x ## b ## a) #else #define Z2(a,b) UWORD(0x ## a), UWORD(0x ## b) #endif #define Z8(a,b,c,d,e,f,g,h) Z2(a,b), Z2(c,d), Z2(e,f), Z2(g,h), const mp_limb_t arb_atan_pi2_minus_one[ARB_ATAN_TAB2_LIMBS] = { Z8(cd984a96,b6fe288f,9da97637,899cd975,9f3629da,b47db7d7,0cb51231,2f2e4f61) Z8(204fb062,60d4a7db,8260035d,cbb6705e,5b3ca61d,f1ff280d,7b746f7b,92ea3cec) Z8(c04c8dbd,83a9b964,a4f8e04d,6d87f569,68050924,9be86b92,214d811e,0dff6fb9) Z8(1b1fbb83,2769d531,ab60b553,a00d224f,42e09039,7037baec,9dc5af5f,3ec252e1) Z8(a2b7cfda,4677430c,41218744,33652c9f,9cd780bb,50f8b28e,3f7d954c,5d1df828) Z8(09bd1df2,b77785b6,55a899d1,4b07d394,6c2a17b4,3528d069,d5e9c478,33864e30) Z8(7b74b64d,10e33421,4f0fcdaf,34e47825,52421002,9705a241,c1fa211c,87b6b7f9) Z8(e9cb5662,11c49f40,75b28dc4,ee131181,f4c2bad8,77c22eae,2ef64019,a43e5630) Z8(7d90d4c8,b0ec04e6,b31410c9,e25ff40d,35a5dcd7,9dc7a44c,944ac33b,3d1929c0) Z8(b61267ae,57eb5d19,4dc3c98f,672e1f0b,ba0c18fb,15d4e2ae,b1b7de15,d9f70a08) Z8(be3974c9,50aa4357,08a0f467,5a662e1a,1555885b,2ae51cb5,31f40a20,2ba44c31) Z8(d52ad5ca,732a92f9,2ab02e30,bc5797ed,de98a593,6b8abbe0,d80f451f,364f0745) Z8(301d0c07,c73cee58,5c6d9c77,6520bc8c,943042f8,e2e8d811,95793009,ce186a9c) Z8(e12d2cda,3daa520e,410aa577,38c5e6ac,b9475b2c,06caba47,fa499ebf,d22c7f51) Z8(38aba734,31b4906c,42c77e0b,8400f971,d9c8b67b,9250cca3,f8963fcc,5d3e4822) Z8(b5133f4b,dc70d7f6,e80d6fdb,17feb96d,4c6fdad6,e89885d3,c4bcfd8d,c90b6aec) Z8(daa3848b,9fc26ada,e4be286e,605614db,9a748636,df2a3367,1c6809bb,a29410f3) Z8(76273644,04177d4c,14cf98e8,52049c11,01b839a2,898cc517,42d18469,921fb544) }; const mp_limb_t arb_atan_tab1[1 << ARB_ATAN_TAB1_BITS][ARB_ATAN_TAB1_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(800f56c0,471a535c,67be3ae1,d89ebbe4,6126f5a9,d62450d6,f625cdfb,6d688680) Z8(2682bef6,892248ad,eb9bc957,167c18ba,6b6d4f7e,4bb12afb,aaddddb9,00ffffaa) },{ Z8(d79ae2a7,570f29f8,9717e1e5,cc7790ed,ac4a4e52,6f9cb7c5,28bc8f59,2111d081) Z8(cfdd9ca1,3507a2ae,2e345e00,8ed0ad40,f77cc15e,d00c46a3,5bbba972,01fffd55) },{ Z8(61e8f518,1b37431d,e4186302,46af6bbf,91294bed,9e608b5c,ebea3e47,dc4ab848) Z8(ac4d1fad,14db0e87,1beddd8e,6f3b42e4,ee5a5b71,6d7f457b,30986134,02fff700) },{ Z8(4df9c218,85a1b8fb,797ad494,bcabe016,286e9ba4,68d09936,858d1e57,a36a1de9) Z8(c9d5872e,81a57e00,0437bbd1,2083bd97,0057dd81,ef9e3159,776e5356,03ffeaab) },{ Z8(a5a0cb92,6b52a899,206a0785,3293c311,165a6a5a,734d22a1,c5de3191,38d13644) Z8(a3132784,56335a58,5200eb10,fd306b02,04d3fd27,ec153c93,c629bfed,04ffd657) },{ Z8(a08edf4a,83a73639,cba0219c,a9c8faab,c0bef870,36a7ad69,89a224cf,6e211e53) Z8(4ac30913,c49cd215,6aaedaa2,8dd4fb81,cab5251b,ce7603f5,12970d6b,05ffb806) },{ Z8(c468bf81,d7aa9735,a501ca08,8750f3a2,175e84fc,c64cbc9c,549887da,63253408) Z8(02ffdb3c,9aaafeff,6171a4ba,cb479a5c,f7f8cafc,f209c454,ca45c470,06ff8db7) },{ Z8(6f362901,1358c95c,c276afc4,13c86927,f7a43e2d,0f282ff5,897e5f9d,3b2a91f5) Z8(a26b0830,b2380bed,a606dc40,9c036814,6ed46310,13bcebbb,ea5d892a,07ff556e) },{ Z8(879c8a25,fc7e1c8c,29974e6b,237c9daf,a9dcd26e,74fc920d,75f96824,d1bc0156) Z8(379ee4be,381d3599,1bc682b8,a4ff745e,89968a2a,0c123d1f,17624bb1,08ff0d2e) },{ Z8(59d2161b,993c1e86,eee6b8d2,aef449a6,a2c015f4,32971e8b,7d6fac19,0a0e82e9) Z8(7fd2da02,0729939d,220db88c,184ecc9b,30da72f6,918538b2,b4e4ec8b,09feb2f8) },{ Z8(b02c5942,89362e3f,c991b205,0adf3417,fcaf53f6,ec4b00d9,5f2e123c,9b020587) Z8(7c28c6a2,b6bd8276,525a72aa,3c64d55b,ff317148,76e77e9c,fd1d96a5,0afe44d2) },{ Z8(162c790b,257b0e0e,d755b36e,9b14ed68,6717017d,ed0894b8,439bbf1e,a5989626) Z8(17de7976,a7731202,f807f208,71dddd64,61df56ec,f220e10d,186d14fc,0bfdc0c2) },{ Z8(e376bcfd,068a96f1,dfbb2b41,2d70daca,1f0d1878,02748cfd,1e707ffe,8fe00659) Z8(e6d80f3a,b29c65b4,6fddb3ed,5847020d,578395ba,4520f5e1,34c26fa6,0cfd24cc) },{ Z8(8610cb40,ef5ac7c0,74a3fd6e,2ef90dd0,d44f2ce7,be000539,57af8bc6,b5ffc5d0) Z8(a8994635,0d1b3e5c,95a4be50,9a51f29e,00b0ebac,c03969ab,9ce221ce,0dfc6ef8) },{ Z8(d1766d52,3c9d4d00,98dcfd4f,d19de2a9,544ce10a,84887d3c,4a1a6eb6,00c86503) Z8(a07bc5f6,a582d3ae,c0fda8e7,6f59d19e,d0d2fcff,6b928efb,cf8c40fb,0efb9d4f) },{ Z8(4ef2a858,42521de9,625a4c0a,b1404b3e,6ac74803,493fe292,473e9b7d,d0249009) Z8(03c4b8ae,c387a9f8,f59d4b2d,1319c12c,c0e2e0d5,6cb2792d,967ef4e3,0ffaaddb) },{ Z8(311356a4,04dfff70,563610b9,5db92215,8f1c7737,74fdbeb3,665127c4,c6b9bf91) Z8(477b4061,6901c519,48fa3ec0,8cfb4ced,4ed8919d,fcb0089e,1d52a6f6,10f99ea7) },{ Z8(9ce1a4b4,050b6c31,eff0326b,655ccfe7,04d7c086,947dfc52,7fdd85df,f3fbc768) Z8(ce650b85,e438050a,1e15a474,529d558c,20fdb0fe,d447119a,082d58de,11f86dbf) },{ Z8(aa046358,42f420b7,f2798882,f832c092,b082f40a,e60a1616,5cf7d5a0,e392fa22) Z8(c0712f54,00e6fba3,518b299a,a22519ec,3003e5ca,7fa2ef37,8a4a9a02,12f71931) },{ Z8(6f670d1f,a5a33de5,c97d6dbf,8ed6a6f3,ee17ef02,36af16c3,6d3c33b4,078cb090) Z8(49818882,dc6b617d,4bf3790c,c9eb30fb,e11cd9be,1338a177,7c559d6b,13f59f0e) },{ Z8(69d09b1f,31bfc679,ee2f9557,0b1311ae,663e2829,b76dfb4a,4f11ad49,ab638665) Z8(e1e69218,3eef315f,ea17484d,e4d45ea9,2f3b2f1b,11a6c4c9,7292fb20,14f3fd67) },{ Z8(45a3b43c,3756c2f9,d997e93c,3bbfe2d2,f17a2f21,c0a38987,e97341e8,360e10c3) Z8(ad108b54,8510be0e,1c0afac1,735fa0c5,c637eace,a3691004,d2d7b262,15f2324f) },{ Z8(fe45558d,9314ca64,0abf3978,bbf07cdd,e13ab974,262264e2,2ea402ba,f6feaa8e) Z8(2d08e8b8,b14cd4e0,b1dd745c,4922f357,5e835fd9,0ff1aed0,ea4b0cec,16f03bdc) },{ Z8(e9ef63a5,f61cb520,147ccad0,b05362dd,cfc4eed0,c7006c6b,a4933246,45474c82) Z8(8c33e00b,65667e05,3055c1b8,cfc1508f,099f06ce,126acfcf,02f10e8c,17ee1826) },{ Z8(4a9522f6,34f12b4b,d47cc582,2566ac69,6f869e7a,38d9db2e,d5dfcebb,1b94fe5b) Z8(23c4c8d0,bd86f3b6,83909b1e,c78b7623,499750de,6510195a,78fb282e,18ebc544) },{ Z8(76b6d939,2b5d2c77,db955cd9,bb9fe797,dc3ae08d,07755f5e,7eb2f5a9,c1d8bf6a) Z8(24f4e839,8c91e6e3,727fec4a,9fa90ca2,11f8151e,ccb875a7,cfdcf168,19e94153) },{ Z8(6bfc6973,6d2b4b24,d2cb1484,fa19f142,597b7d78,a9a50ad8,00b991bc,ee882715) Z8(7981aea1,2c70ba3e,d88eba11,bbfe48a9,73b6e5bf,029cd221,c722b838,1ae68a71) },{ Z8(099335f2,7b563833,0f7d4806,ce55540a,9a97042b,bf2c072e,e10e85ee,91b36f11) Z8(68664f74,b1b0e0bd,d234427d,d21afca1,661cbb3d,ee3ca681,6f07c37d,1be39ebe) },{ Z8(42c48603,9e3f5b6d,c0aca8c5,4c94c1a1,7707b825,fc546c0e,8d2ed6ac,14cb3da8) Z8(5cb44d3e,b6d450fa,27c7e505,967b9dd8,314d28c1,71cc84b2,3cca3222,1ce07c5c) },{ Z8(357ca717,859d7037,8d550940,ad29bec8,4d65e896,46e04ecc,67d74e9e,028bfa2c) Z8(9bc0c871,b68ef497,f3435b28,910b169a,f95fab59,3bff35db,1eba6e65,1ddd2170) },{ Z8(7e25ed45,7953bff9,ca2d5709,2e37a5fe,bb6750b5,830963f5,b8999195,6fb3e1ca) Z8(76c0b90a,fd75ea0e,65679841,e9e36d84,c276a948,2d33d369,90043af6,1ed98c21) },{ Z8(57f08ded,a54d9b11,3e535f7f,abae7931,3c469ae3,a7ff4baa,403b384c,1a9a0100) Z8(bf6d82ed,5d926aef,2bb35b24,f1672afb,e7d111de,5912f313,ac2f6dc6,1fd5ba9a) },{ Z8(6a7adfff,5547ed24,14efc875,7df6d8e9,bee963be,793e76e9,2c350133,fce00e46) Z8(fac4ccb1,b1bc39a3,65afedb4,fcb8fbed,20176b74,e96be7f3,42567b30,20d1ab08) },{ Z8(8e763bf8,81217628,29474992,db4372f9,a57870c3,217f8cba,e62ac41e,ea493561) Z8(04a83365,86f87586,f8091428,4d87af78,97963968,72e72233,e8110314,21cd5b99) },{ Z8(63bd5bb6,362f0052,b4114288,b2df3ca8,29e9f297,84d054d0,7dbf0484,e2263753) Z8(c68fa69b,f93b0c5b,77f89387,62929db7,548d5e30,e774573f,0c10a0b5,22c8ca82) },{ Z8(d2620f4d,2c25d670,6a702710,7c24f7db,ccf5586e,f6876258,981f40da,d86815e7) Z8(0be90468,9802c41c,a7f00323,78a856b0,60e82be6,6f4dd64a,086e4dc9,23c3f5f6) },{ Z8(2299020d,7ada35c5,7d81bd76,0cff8011,41de86b1,3dc8067c,b5839fc7,5df2d3e0) Z8(999e0089,029970c1,103b7390,ad71a122,1883ce1c,36bdef0d,34a6b8be,24bedc2e) },{ Z8(80ea4d78,5352cf1c,78ebc7f7,82d4695f,412ef498,f23f2d2f,093a0e35,9135bb99) Z8(091ff212,e21eff2c,ac3c6138,b40fd271,54d14fca,ca1c1558,f743fe63,25b97b65) },{ Z8(94458a17,c31a5854,1c096d9a,c616945c,b307df04,e13ad104,7ec429b6,cd667d18) Z8(fdc4387d,3c856851,b577ec20,0b5bd245,d9ce2bd3,01458dcf,d733472d,26b3d1db) },{ Z8(be2d13b3,a4d22e76,c6fdac72,bb480a41,a8adca3f,de49b5b0,bc6aa4fc,6d60ea3b) Z8(d0a3c05b,132f0292,2eb74a37,5dd4bd3e,40d83fa1,d1d86749,8cc4d8b0,27adddd1) },{ Z8(e4774fdf,2fe9defe,653615f4,62f2a8a9,65ec851b,f242275b,d56d6f43,133b2b30) Z8(3bd019c4,790d4bc4,9165ca72,d9500829,3c5b858f,b29d9d2d,12553c8f,28a79d8c) },{ Z8(b24a7e09,a494772a,d2c966a8,630e9967,7c27bdc8,ce0f5b5d,201dcfa4,168365a5) Z8(3fcb54d0,71e7b47d,a602974f,85f820a0,8abcc1f7,991f8d6f,b49e2e8f,29a10f53) },{ Z8(72a10576,51f79d66,9871c02b,2bb9592d,6e8306a9,60b49f61,feffa815,78b884a9) Z8(c4f79607,f998a3ef,18607feb,52f68c3d,039baca9,14179442,22ae148c,2a9a3174) },{ Z8(70227d34,0d4661db,0101678b,bf80dddb,c39cd9f1,a4fd6da4,eb67c8dc,2514c715) Z8(f49ef530,07d8d94c,46c1ad33,0b4f9b75,c30b7a65,ad534ffb,7d84d3be,2b93023c) },{ Z8(7485ae76,eb2e71d3,d62dba77,953f1ebc,118ac689,bb0f3ba3,3b04b204,db25929a) Z8(b766dc2c,444ea8d2,c6d28096,18fddf54,d34c6f11,ac949883,6754e7e0,2c8b7fff) },{ Z8(bb7db1df,1ff62734,67d27ea1,b94ffed4,1e985042,ba26831a,78eca1e3,78ef8381) Z8(218ab4d9,1c29127f,79083c3e,b4ffb8c8,ef6549a0,aad627f0,1267b1b5,2d83a913) },{ Z8(0a561f65,da82afeb,700b6577,1b5a9ab0,64434707,fff7147c,17eb0d22,2cab1d24) Z8(0092d34d,a4c21996,77f6c0a1,8b622429,668d5f07,4bc24ad6,4fa403a9,2e7b7bd1) },{ Z8(54f8c53d,2a81b45b,08d5df80,e3546041,3f5c02f3,a2e0e37d,a1314740,65c41183) Z8(c79f5cb4,bc169a93,a0e28aca,e4eb4035,07271d21,1ec2d3e2,9cb6044d,2f72f697) },{ Z8(fefd4306,2bffbcce,bf0955fb,48f26c41,8acc7f96,8a388165,5eb3d2df,f9217c22) Z8(88ba6f5f,edc59923,0ade66d4,83aa9592,dbcc20fb,5bb33518,31d78fa9,306a17c7) },{ Z8(43bf3419,d021c10d,1d8a38a4,0645863e,0a7a037a,537477a5,f8da54e8,9ba2a914) Z8(a36d0e0c,eeb9d3f7,339400bd,a797d90c,9d85f2c5,39967e7b,0f385177,3160ddc5) },{ Z8(c89eb613,e5f60493,d8dce9c5,222f6b01,734adac3,37122f0d,41ef746b,df66b6f5) Z8(d621348e,784176a4,10efb2cb,bfd3e8e9,c4e1ec71,61097805,0a04e379,325746fa) },{ Z8(5dd19db4,bf646ff8,b1cd2237,a58182f3,1b8356ba,84f6edfe,64c501b4,3e50601a) Z8(2224cf0a,fc1796da,06f09d86,aafc4993,691bbace,ec03cf68,d90c4c39,334d51d2) },{ Z8(9079b934,466afaf5,cfd71a5b,1ec022dd,34bd93bd,88d7a6c9,993cb591,4d93ee4b) Z8(92927071,4e0f9b08,8664d9d8,8d8a7ad7,6463cf3b,083acfa8,21034b79,3442fcc0) },{ Z8(b893e1cd,482c2e08,6ee3bc74,ee743658,4af9b37a,24acd329,b140d9ee,9f24f2e8) Z8(75bd3ea2,82ec8d09,13c78e65,6909c145,542a8758,45df44e6,8064f287,35384636) },{ Z8(3cabd8ab,a9e22f00,da7b7f4d,4e1e1f8c,da1d0102,91d9eaa5,7d8052da,992be0f0) Z8(a1b814a0,3b878193,180edaf8,c9f4e6ac,6633f48a,951c0fa9,9af0179e,362d2cae) },{ Z8(2d953efb,d5f2f22e,9be36135,1bf788c7,bbace5d8,2a7d62b5,137701d5,10c6abd0) Z8(5fe10a3b,55881bc6,4e92c495,a19144a3,72d54bc0,bd886970,24c14408,3721aea5) },{ Z8(0b5cb505,71bcfb8f,a2a3c8ee,f32ad755,08bf886c,f2b6db3c,4023a354,f78257e7) Z8(7ff03acc,0be927c7,30228d39,92f30bc5,c9213bed,99205506,ed08cd7d,3815ca9a) },{ Z8(34995f9e,88ba3848,4b3757b8,05c7d432,efbed4bf,35845ab6,94f88a29,077a90b8) Z8(546b7e08,630280dd,c23af573,969f79c2,5766d521,908be5f4,e85cdb9a,39097f14) },{ Z8(090fd641,ad8c32cf,63714ab4,097865dd,e0ddcd03,60822f91,fb49c059,e497e262) Z8(3459a44b,5c89eeb2,1f847c4c,cc23f3b1,57dac766,dcd1fb8f,3aa72aa3,39fcca9c) },{ Z8(9ca4c5cf,f96efef5,843bc77e,c4a7522b,d7ca6cbc,b8c3e75f,560f6205,1e4e4bd1) Z8(8a276c06,79b6867e,80cbfc01,ec4b3b0a,cbef5e39,2468a9a2,40ae6ce3,3aefabbe) },{ Z8(b98a4ead,adc8eb8b,c9d1ce7d,673a4f94,aea9c1fd,218a01d8,bfd09321,ec406449) Z8(7110586a,1d0cbb9f,8b7a73c3,1c68abe9,b87f6509,7e74ac40,993b3bea,3be2210c) },{ Z8(4c43d654,590f749d,a1963ac0,de5c3e82,c43b6c29,dbdd37ed,8e027783,aa643149) Z8(0111d1fb,139179b4,4bff91cf,33bf6daf,bb281a07,3591014f,2dd89ac3,3cd4291d) },{ Z8(2319461e,f74f7152,262ecbdf,70131b7b,7eb36fcc,aa5d2e4c,b28a09ad,0999f94e) Z8(29b1e0f3,2497af53,b3d6cac6,91d7dacd,15bd423c,623dcee5,3b301999,3dc5c28a) },{ Z8(c0e660de,83d070ea,c1c793e6,8f0af089,e960c68f,c16fa316,9a395d94,64ae4945) Z8(251269d9,de8e9d9f,e22ce0da,6a9fea40,7de885f9,5b71e7bd,5901bac5,3eb6ebf2) },{ Z8(df555015,378f9610,033a32f8,b833470b,23384f63,c85b09e5,d48b6bf7,ed31c80e) Z8(ac347d38,df4f7199,b5d98d16,344f7ea1,8bd4f2b7,e28de743,81b7c826,3fa7a3f8) },{ Z8(22decba3,701977b6,36fa9167,81d25d92,dd26f167,5522dc95,4bd301ee,da5fd8b7) Z8(3ba76182,3eab212e,ace22cef,129d011d,5b85a52f,d2097cd0,1996d698,4097e944) },{ Z8(28c40514,aba26ad2,8a92b443,72170444,0a7d5cc4,d8d8727b,623ab47e,7154472a) Z8(3fe7098a,065fd18f,1fd4d38c,ff1fddaf,79fe16a0,113e49d5,f58a43d4,4187ba80) },{ Z8(fb2f32e3,fa0c0020,03fd1ec2,3eee4573,233656ac,b8e6b642,29fdcf5e,2e0b4533) Z8(02598228,742430ca,5b7e82d8,57128550,8655e9d1,e47390cb,618d8962,4277165f) },{ Z8(59675195,9ad2f74b,cf06beb4,50642b58,1adc2f84,743bdd77,b1b16b22,ec1f1489) Z8(77ca6b77,7e0be081,a05e2e0d,9af3fd40,3eae0bb7,c317bd5a,26b2cd47,4365fb94) },{ Z8(3636b048,a33d4e80,46d3bb97,267acb9c,8a97f939,65b54ac5,c0ec8aff,54b319bf) Z8(0d5e882f,876d4fea,ba0a243d,979d9a18,4613c81a,37236f88,90c726b2,445468d8) },{ Z8(2529bc52,f9c7fc1f,df3eebe6,b9e119e0,19c44f0d,930186b4,73a6679d,3cd7e9b3) Z8(48b7628b,3f9c4f95,002dbee3,4bf1726d,cd86108b,94580635,73951a86,45425cea) },{ Z8(3baa0802,9fcc00a8,e76734f4,56bac311,ae28c340,edf331ad,b8c8226d,28af6d95) Z8(a8450274,e5275dd6,e0d27de7,87e9714d,dfc414c6,6523a458,2fc5e098,462fd68c) },{ Z8(50c6afb8,60a79116,2b5c8197,07ee3283,72ddb269,229ef969,daf9f7e5,74b2522e) Z8(2de95dad,8d89bef4,f5b9dede,1131740e,86926c0d,329c39a6,b7620f41,471cd484) },{ Z8(4dd696a9,b4a3d209,e00913e9,e6ad44fa,a508fabe,e0ced958,b2094c62,b4e812be) Z8(45146f9c,15f20819,a06064a1,f2adf0ae,b78ccc11,e6e6b85e,91f25773,4809559f) },{ Z8(f2bae5e7,02a7a010,e216bae9,8871efae,3984042a,e7d92cc9,1427cc25,a7e8b5a6) Z8(9244ac7d,a985fa7c,4564b2ac,a0d090cf,fddebe99,b3a3a77f,e041078e,48f558ac) },{ Z8(f2dd3af1,4c887024,12f70f05,39a8dac3,94ce672f,51117749,d4e2af6c,77550ff3) Z8(3984379f,3d78b33a,906b1916,223e10cf,37f0a23d,8322c920,5fbd16f8,49e0dc81) },{ Z8(03d08a38,29a0dfe2,3058331b,b3c57771,f126d3e2,1e2ac1d5,84402d2d,3db4bbcc) Z8(fb74bd3d,bc11d84c,adec4ef0,f4cf1a52,6a2148aa,11e7e0e1,6d7f880a,4acbdff6) },{ Z8(57da08d2,0ca9b21f,0490a8a7,fdc85778,30017bc1,f1156669,d7bf2f67,62a6a1b6) Z8(e91ef2eb,ad4a61cc,4c2b9c5e,4f9e3ef2,964d0de3,892c7500,08f3f8dc,4bb661ea) },{ Z8(770054a9,7a1f9e42,98d14a85,93ea8da9,bf53f41a,de9d1bbc,6c80d44b,c3d2211b) Z8(6099f013,c7508825,d9a44682,a1f7c145,0d0dd218,a0f566c6,d6254656,4ca0613e) },{ Z8(97b49c80,dd8e02c6,cea6a96d,82674492,34643a2c,22033f7a,54eefbf3,699c6992) Z8(098263d7,fad2c806,8597aaff,045247c2,693d7994,e2d5da4c,1faf2f34,4d89dcdc) },{ Z8(76a38a1a,2f11f89f,877048de,240818a3,89c0247f,c63d814d,d985053b,48467703) Z8(ca70edb9,782a220b,e8ac86ab,1aa6b1c0,8ec8b08a,b25a5deb,d855eed0,4e72d3ad) },{ Z8(02d173c9,8790271e,3501bc05,588deb89,58a2ceee,8f40a28f,2c8e4f11,1124fb44) Z8(45615e28,83aa88d9,2b34e36a,98e65edf,589e8ce1,7ca41cc9,9c44d113,4f5b44a4) },{ Z8(9e6aea05,577638a0,eeff1be6,27bbd86d,492e65af,4c11bf3c,c80edeaf,7f10d8bb) Z8(17c27be7,55cb0d8f,e2d0c07d,cd697057,aedbd671,37451ec4,b1f4ca4f,50432eb5) },{ Z8(a28e0832,452f7370,3a4907e5,6c3e7633,4f3b5bde,cf10222f,26cf7aa8,ed9ec1da) Z8(e7581db1,ed22099b,1a2ec305,a7413c52,c45c6cf1,a1bc3aa4,0abc26a2,512a90db) },{ Z8(6f119a02,3defec71,d2913050,79601507,cdd18d9f,cf591d12,d3011a20,105eec8e) Z8(1427073e,c7d9a717,620f7a38,cb14d6ea,6a594645,28a7563c,43086d1e,52116a13) },{ Z8(5e042655,3557bb3f,6afb9122,1ef1c3c3,a4ff9e4a,e67e2aac,df3f25c1,21be8441) Z8(bf14c376,1792cda3,0866191f,0148a6da,c549d5fa,91c41eea,a2439b0d,52f7b961) },{ Z8(3d0026cb,528f518d,62a07664,be7904d7,ea71b5a4,04c9f360,8a9d28d8,221a4e2c) Z8(5b969c3b,e5399f1e,3089501d,587c4cf4,bbde5d5d,978c2003,1a65e39a,53dd7dce) },{ Z8(0e6d9a49,5ff2e209,61977292,daab7c7b,5e61c948,921dd49b,f930a1bb,707dd4bf) Z8(64f8f15b,d12e94ea,8f7a6be9,90961ce9,fbecf460,4cdbfbbd,4735276d,54c2b665) },{ Z8(25e6c1b8,d83fd3f0,87ab3042,85532e9b,106992ff,a12d0234,6b86a9cd,a3db34db) Z8(2d523e88,30a5e599,344c5a3e,5dbb882d,80ec7a65,9cf0c761,6d335f00,55a76238) },{ Z8(6e025da0,1b78b36c,1e7e0940,fc1d3bda,50b809cf,474c9ff1,189c2701,9c6bc20a) Z8(752d7e37,06eaecdb,6dd4ab0b,4eda313c,45741deb,b7a8f82e,783d3913,568b805d) },{ Z8(304351f2,6e34c8c8,b5ad91c6,c630ba0f,5db2c0aa,2a79d9bf,b7e3253d,aef6afec) Z8(50f634c4,2d070093,e7595d81,2cb9c490,bece25fb,0760dbb7,f9da34f5,576f0fee) },{ Z8(0f733f06,2cac7ee0,5888957e,51b401c3,1940ee0f,cae5879b,1b7c5ded,d7c10300) Z8(85005268,17eef8f6,4bd6b6b8,5a042e6f,100507e1,da8ea8ee,273f8658,5852100c) },{ Z8(b44a8d24,4327c217,6b9a5b84,d851301b,afa68266,21121830,6e932e61,3d6bd9c1) Z8(b0168cf2,9f5551d0,7cdbc7b5,848af963,242309f5,bfc183f0,d7071605,59347fd8) },{ Z8(6f87aeb4,ee01cb6c,ea24f1fa,faf57913,583a91b7,e4587223,4c5613e3,b6029dc5) Z8(36db9b4f,4038daa8,d95a515b,b58574b2,4ac7b49a,50fd65ca,7e9bf7db,5a165e7d) },{ Z8(d90bccf9,4287a50c,b71f178b,48efa71b,8c2a57a0,dfd7106b,251beac4,12e22eaf) Z8(dc549a6b,7711076d,a1ec768f,576944ac,5f6062fa,8ea70648,2f5db396,5af7ab27) },{ Z8(9a49ceae,243ead56,bd7d0d30,430b7703,0067b9e9,6e667254,1cfee06b,32662c10) Z8(19a48470,2399f2e5,d72a2ae6,9ec21cbb,6e7f2241,c5519091,937bc239,5bd86507) },{ Z8(14f80159,e6ccbf07,701bc5c5,c32a6518,36321b87,440cc956,57743f3d,938f993f) Z8(cbaa36b1,596df9e5,bf97b157,3df5116d,d8431518,36cb1860,ea8aa626,5cb88b54) },{ Z8(29dc33cf,625346c4,453bc84d,726767e2,967af23b,dadffa83,f43782dc,aec2918a) Z8(8ab750c5,5f8ad04e,98a66691,e3d8a986,13fffa13,5dd0dc67,05d407c4,5d981d4a) },{ Z8(b7bfd931,50a00100,2cf08293,1feba957,067f1ca5,c7a63e5a,fcb1fe12,5a0c8c03) Z8(e95b8ed4,7b4d1f80,74be0aa1,e2ad83c4,b0366780,ba09d077,4463440d,5e771a26) },{ Z8(475b86cb,714c74d2,34fd2cc9,ba326117,89478ccb,47d65dfc,bcd20a64,20529daa) Z8(1e74ec59,cb1fbef2,af2efb9f,12e09e0e,49a08813,c885c2b2,8ecfdd69,5f55812d) },{ Z8(4764d731,38c59383,eaca59cd,9d532dac,8362d5a5,4c4a9cb9,c9b18029,4cbfbbfc) Z8(95460575,909b7c56,372f9424,618c28f8,5e6cc5ec,606697b0,52c74218,603351a8) },{ Z8(84593dba,6a7d6ee7,e3e4ad23,76a48da9,dfb5d55f,c6eda544,984107ae,ffe7ddc0) Z8(09e11aa8,2aa1a59a,88d4dc13,8175a01c,1b5c3a3b,6a0299b4,7e575dd7,61108ae3) },{ Z8(d01d74db,c6b20f39,99972886,a764abac,199f972e,c1604fc3,e4d8d932,6e4b5b4b) Z8(fdc2df8f,67335fd6,77386fda,d580574f,8f0b9465,3055d05b,7afb6e92,61ed2c30) },{ Z8(b3ea0e6c,eb9e214c,9b5c63e5,be201df2,9f125b1d,a348ef4c,3a18f632,e3821dd4) Z8(d849a43e,413ddca5,869d50fb,e25be4f2,fa85146e,d0ba3748,286c95b6,62c934e5) },{ Z8(d3b5ae4f,8c26ef59,fcc501fb,d7a15f8e,24d8b216,95698578,6b6b5a93,05873f7a) Z8(49201fe8,d2cde838,eb360681,ee0dd669,afaf4343,0a7e12bf,d737a14c,63a4a45b) },{ Z8(af819db8,27cc0e8b,77406e1d,58b65e04,6806ec47,23d487c1,985febcd,9f56e7a5) Z8(c0bd6eb7,37a7a057,8b92df5b,37d32124,b536bec6,74188054,43198910,647f79f3) },{ Z8(c4a57c93,7e0ba8e5,c3147f3d,9832b084,2ef8bd4b,b859bebc,368062ab,4595f087) Z8(ddb0a5c7,7c311a23,68afe4fe,973e149e,795af8a9,80a9bf05,8d241ccd,6559b50e) },{ Z8(a7a7ed00,2d503b1d,f9413e9d,860ab793,bda9e833,ae70741d,11a5a672,1033627d) Z8(6dea2a48,0991b337,4410cb0a,c93d002a,a76cdbe1,6c988fd0,35ac619e,66335515) },{ Z8(74ba887f,c9afb778,dfec5842,b07edd48,3f8ba4fd,9fc246c8,ef5e863f,8178c086) Z8(106f2c72,46f78781,ef24abd8,29c10727,19f5325f,cd2c044a,16041c36,670c5973) },{ Z8(1b4a3471,48b7ba24,f3fc02a7,55afa598,71e79e20,f5eb5b4e,f6c1005c,8ab8886e) Z8(0447819e,847c5e96,03790b35,995f498a,c6581a7b,d8fb836b,5a000637,67e4c198) },{ Z8(e77539c8,68562ed4,fc57391c,59c264ae,aac58955,fee46f9f,ed5d01f4,c5f7dde1) Z8(ddbe058e,86690fdb,4831b491,67288190,21ac153c,5357de5c,794c2c60,68bc8cf9) },{ Z8(d6fa02dd,e1150332,dd66ae64,1b924c6d,29bfb62e,7bcb42c9,5e2241da,142bf420) Z8(89eebf14,1333bfc7,90b0d39e,3700206e,800f389b,213e4af4,308ff2db,6993bb0f) },{ Z8(94bf4f0e,7b8086fb,2defd0b0,3d6c4d16,0a589d30,4a6c6b43,17dc5859,40778929) Z8(7808827b,bcc0fc99,c0d45d26,c3f91d5a,b02d4a70,c85bfeeb,7a633c25,6a6a4b56) },{ Z8(c32677de,0e0a6de9,5ed2e794,ea7accca,62ee5c79,d073f531,b881b6a8,900ae95d) Z8(e3d8c4f6,f93f9ea2,014ae9c2,0a43580c,2e7eef7e,4c33891d,88162dfc,6b403d50) },{ Z8(437438a6,0f2a8783,b90c6c1a,615f314f,91f8c2b8,f04ae752,cb1ccde1,ddca2001) Z8(073ec382,6f139339,4d7b491a,ff35aaf2,baaa6bae,ec6b9c9c,ba4d0e6c,6c159082) },{ Z8(dd1cd9a8,427ecd17,a4926cd7,12095bb5,b8818fe5,d88cfb0a,e11bb506,f0b41878) Z8(aca1b3aa,6469134f,5fdb8226,aaa4088c,04031a2e,187b1ca5,9971b1ae,6cea4476) },{ Z8(f7709642,e32fc2a6,5bd87952,ff1590c9,73805eec,8ff03f2a,8f7b787f,1362259f) Z8(5d0457a4,e9c8d9f8,66ff409e,cd7949f8,863d50c8,6b2e6d9f,cdfbef8d,6dbe58b9) },{ Z8(0a725b29,c4e1a3b4,cde99b80,170485e9,45352e49,b0710485,bf4d1599,c6adc4c4) Z8(aea48300,19d62e63,d14d7353,c1897ca0,afe929ce,9a1b46e4,18929551,6e91ccde) },{ Z8(63964ecf,9dfb0b22,7c87e071,5b694f4c,4220370a,1a07fadf,1cd9af6c,4bab502e) Z8(585f6cf4,e8c8fa9b,73fc6ae7,9b4bded1,499b6620,eabc6509,4a0646b4,6f64a079) },{ Z8(49edc149,519673e7,5449ded6,6b947146,85651cfd,4fb13489,1a4d4498,56ab8ad2) Z8(2c32a5bd,ca859f5e,af9f5c11,db0a5f97,3cc65c01,e318f6cb,3b27be33,7036d325) },{ Z8(4a5df35c,9239d401,8730b4c8,3d7f72ab,d27e2dc4,a7ea6eeb,43250ba3,db58ee60) Z8(8080388c,11f68129,f5c2a636,68db9c1e,1123a708,820bcb4c,c47ada4e,7108647f) },{ Z8(4333c295,bd5631c6,658660c8,4c4a28ae,77bc6aeb,1f808d6e,6b31ca45,6bea5672) Z8(e9a08658,d35aa34a,6ae7e565,bf8b16e6,c1b87ea7,474008fb,b5c7e28b,71d9542a) },{ Z8(82e2ec1d,d416db06,bc4abe7c,a879f9b2,19227bed,fff14938,122e4bb8,7e21e4c2) Z8(6a18dbad,3e38f152,98792e64,56193985,b7a3f6a7,a833c0b1,cd8c6c0c,72a9a1cb) },{ Z8(ccebaa1c,91743da4,920b5c3c,a83eebfa,52c38f0b,33d0ce87,e08b7c3d,eb573dba) Z8(a0f59d94,0581e081,9e7941da,32592743,e536e164,305bbe70,b04d425d,73794d0c) },{ Z8(ddc9fe3a,c78f7735,92403ebe,3bb34acf,978ef7b7,b32ebc64,7f5291ec,3b05f640) Z8(8ff60eb0,aeeb3ba5,e05d438e,cebb3f7c,c302bbad,67835886,dfcab5be,7448559a) },{ Z8(6f7384b3,4d955938,7ab24ad4,5c3958e9,8e89004f,41da4ad6,535b540d,29ed1da8) Z8(43e8a4a7,9b8814c1,6ac5248f,69ae9416,c969a4a3,a108b1f7,b218acc4,7516bb27) },{ Z8(c9b2e941,195d1f4f,07bb1dd2,57fee8e5,18e3b139,2a0d8694,e3dd84e1,46fc7a78) Z8(01d2b559,f1615af4,dffeffc8,cb45b4d2,ac4fde79,f40ad24d,489bd35f,75e47d68) },{ Z8(431146de,eb6c2f1b,7e9e0009,6770f407,635230c1,43e4097c,c495a8b6,fd4e2c8b) Z8(74b12384,71678b73,930e6f80,b70a0ac3,5e1d4681,b7f222f6,86ed3da2,76b19c15) },{ Z8(e662917e,9e0ec0ef,0907c7f1,da84ef40,402f4c8f,0af8dc1c,9bf339eb,85921141) Z8(af19971a,95bbedff,83071db2,66efb530,912e14cb,ddd86050,09a5d0a1,777e16ec) },{ Z8(8f301d8c,84061563,c0543a9e,9d5d24ba,694af72c,173f4d3e,b37db4f4,43207a63) Z8(4a4bc94f,0c7167a7,f5fe0764,c787457e,ad55185b,3d9e719c,1d12bfb5,7849edac) },{ Z8(23c27c08,5313f7c8,80f03ecc,961ebfd5,bb5b14fd,09c4de93,7357a853,99b0e98a) Z8(4b055120,f8f29187,15d79e70,b11e90da,31e3ba15,4754259d,b3d46827,79152019) },{ Z8(3e6d54cf,6ba57a5c,cbe30ddc,04ecd0e8,93713515,9d0680bc,cf53d409,f87a0d00) Z8(27e899ff,eca3443d,402ec723,1790505c,4356f9fd,53dc1bf3,5d68d10e,79dfadfc) },{ Z8(f87500ba,5474f21d,33580869,65bbadf1,8a142bce,aedbe52f,0191dd6b,2082bcc0) Z8(80c7e3e4,2fb06843,0030dbc8,759edd0f,f82b549a,d967651d,3ca31097,7aa9971f) },{ Z8(e39aaf8e,a8999886,1adbf4da,55ae1bdf,ee452cb3,ea24fe10,118640d9,d9dfa295) Z8(d9859493,c806ecee,1b2d1a22,2c085d46,ec71326e,da2733dd,fe10d380,7b72db50) },{ Z8(38294033,a9a1152e,8275ef25,852f8923,047f8b07,d14dd4f5,31892a2e,09191e58) Z8(7dc1b9f2,dbf97fce,ffe98dfa,3efac40f,76bbe518,bf57834e,ce4f3ed0,7c3b7a63) },{ Z8(a6dc9901,215b810f,aab03c7d,c83a92d8,c35e080e,12df65ec,48c26c43,66ce6be1) Z8(09041335,b190087d,c5c5aac1,0806496f,aee47661,33691e3e,50505f2e,7d03742d) },{ Z8(b5a84f4c,b14dcbb7,9c52349b,6cd9771f,dcf4e3d9,7ee70918,d7aa375f,cd00a912) Z8(ff5371ff,a47f7e70,f26bdfdc,b9b4c8a2,dd004a57,27083dfa,93925452,7dcac886) },{ Z8(8a6a9f68,e5503922,98887779,82098553,e385fc82,14e05ec1,4d9894be,9db942af) Z8(99073e71,261a128e,b5412874,e6b4f66c,74b5310e,a9c23d72,0a496235,7e91774c) },{ Z8(b4fe5cbc,722959ce,c3503ee8,ab044b99,598a7168,8b2b9c42,261b465b,1aaba8ac) Z8(feda3967,17f74800,2228a703,9f93b5a8,d8a9d672,43d8f624,7f7e0c9d,7f57805d) },{ Z8(4efbf7a2,1a64cb22,0257e174,c3051249,c455de90,764e5cb1,a7a15c3b,434e6df2) Z8(9620b8c8,02f253ef,6fe2e1cc,69248632,4d938596,a6d6c6c5,0d205c99,801ce39e) },{ Z8(07722634,a680ef4a,25cddb51,f39ef511,6bc2b670,78f85250,cc9f220c,3109b636) Z8(bc199b54,0fd151a6,29b08174,ad73c708,1dbb92b1,689f9952,12116a7b,80e1a0f4) },{ Z8(840d4673,8c1d097b,d2f21932,527a6c07,02ef04a3,db10d86c,4db415e9,5f3b5ceb) Z8(e55e0781,3123f517,630bb75c,c9474f20,40ff5431,9b38d855,2824418f,81a5b849) },{ Z8(39a87e0a,b622442b,d15d449b,82fdded3,1927739b,26ab519b,510f33bd,a76401d8) Z8(6ed19a9c,3c042abe,88082c6d,bbff43ff,131d6a27,f39377a7,1a172dc6,8269298a) },{ Z8(f42af382,6ff1ea97,53ff817d,8e2871f5,d4bddc24,82c3bd5b,d4f13f4e,43d7d60c) Z8(1e5b65d0,55c6bdcf,774ddfbc,f1155cd8,61a515c0,4b6a09cb,d9867e2a,832bf4a6) },{ Z8(6389bafe,e1fbcb45,482aba2f,147fc691,5a107ad8,54615597,30d93e05,6051dd25) Z8(e2e7ff89,cd470655,797b9e09,c96ba6dc,0ac73920,0c9e0445,74d9c1b7,83ee1992) },{ Z8(7093de76,2e18760d,12a339b9,949a98ec,23c448e8,d49a7e53,6880ee04,2a95ee24) Z8(91a471e2,9e3f429f,5c56d4c5,aea47210,60d2aaea,e4df5ea5,0d2c7eed,84af9843) },{ Z8(6bc3c871,89fb68ab,551f7fa4,a7123346,cb93c484,ab8012f9,98005332,ba3ed0a5) Z8(4e7886d0,72b5a073,c037a182,75d49076,45a53e2c,5abf2de4,cc336107,857070b1) },{ Z8(b9515c90,0993b796,ebac1443,f6a5b3b9,b87b136b,c112f51c,9bd67954,45f54651) Z8(9cf54cc7,ae8bed89,94553290,92a950da,013ca37d,d3e84ed5,da1ed065,8630a2da) },{ Z8(cc6c4d2e,f66afd88,fd5036df,e4ae36b3,f40586d3,50ce16ac,1ddad3fb,c8e74cc9) Z8(7e4a61d5,208981dc,33c397b1,7c75090d,655622ba,97b4e3ad,537be67c,86f02ebd) },{ Z8(55e8c864,a1a5dd2f,3d4678f4,badcfeb3,33069252,d6dd6a02,82e42791,a2a7f4f8) Z8(1f428f58,2dea9c23,f150f32c,9bdd6bf9,4c868142,988d8bf6,3f14a800,87af145b) },{ Z8(240ab993,21e5977c,45f2d543,b3c1550b,a6636083,d0d0bc8e,37fe5a4d,9d410539) Z8(1a5e9ca1,c7b58739,98c02cf7,bce1325f,60af9f5d,867a898f,83d06ad3,886d53b9) },{ Z8(edb50f83,998d73c4,b2b51bdd,f42337e8,dfa2ae57,a2d08b4a,e396f760,31205dd0) Z8(65ff600e,28c0a22e,b9ddf67f,8fbe7b9f,472b4afb,094478fc,de9547b5,892aecdf) },{ Z8(c7e3a524,d43f64b0,e4b281a5,ff14350a,e7842a54,f607f342,3712644c,075ea1ea) Z8(a75b251f,f400d02f,aa77cc19,b2e59eef,a6f989c0,21cdf87d,d82b7262,89e7dfd8) },{ Z8(76f38bb2,12499354,a97d0535,f2d8d29b,c967a295,26225539,be81d9a5,458196e9) Z8(dc4a203b,b5fc0254,cfbbf3d6,fe76f7ec,879e8439,b0756e81,bb234d68,8aa42cb1) },{ Z8(c7832c8a,470d80d1,36ae3e59,b4b56564,9cb81009,299f56c0,9c06b113,4d37e8ad) Z8(9410115c,3f549952,ba02bf4d,99492cf6,d348634d,06fe141b,89bf0996,8b5fd37a) },{ Z8(23f2825f,c4e88cbc,5ff1e675,c7dd9b3f,88ad45d8,2a2e149b,a4a934c2,b8340b68) Z8(40364e6f,ca922e3e,0311ce06,f8e24449,60205920,439d8018,f3e09b8c,8c1ad445) },{ Z8(5083a8c0,943f5994,ccbc2484,2ae68ede,18f0d470,04c22fd8,40643c32,082c4f3d) Z8(86dca7f6,2cdaf3be,148f8aa6,8709d0f2,f9602b3b,f27a74e0,4cfcccb3,8cd52f29) },{ Z8(cda61010,9f183483,c877ab70,c488b568,12013d43,78a9fffb,e44976ce,8e0c22bd) Z8(4938f386,33d3ce86,5cb6dba3,dfc2b861,86b8a2cc,0b9ba883,8214276f,8d8ee43c) },{ Z8(807bdec7,b1171923,9d86e4e7,b7ed34dd,6b92045c,94ea9a9e,bf30f35a,adf93983) Z8(9a989102,94ca7636,885e59ba,ef9cec1a,929f8ecd,bbc9d5e7,0fb27928,8e47f39a) },{ Z8(a4333141,358f6440,7e523acc,29c4ed1d,073d6a58,66cd7dd3,918d712b,3669dcd3) Z8(13389eb2,f53da46d,652b375c,918a67e0,65c43747,5c835e16,f7f59f9b,8f005d5e) },{ Z8(63e1d8e1,e8e42d7c,9042f128,dd2e444f,1603e75f,3058e42f,31636f6c,b33adb8f) Z8(42aa3f89,6573867f,0e1ca0a2,b668d877,d47136a9,659f6d7d,b89c516c,8fb821aa) },{ Z8(ce01728d,0e32ee21,4e6ce066,1c8982a5,d8ff20fc,9b146e4e,f0d6ffa9,d44568ef) Z8(83f80434,fd954e72,419afea6,99f0a484,17850ab5,c5158289,411d8d0d,906f409f) },{ Z8(e822775f,8b370708,3cdac35e,ec0fe759,a3da5238,af657582,0c778e51,9f4f2fe1) Z8(28bd151e,25831acb,2051239d,b0b51d13,1880f6a2,a7bf114c,e8c953ad,9125ba60) },{ Z8(eda72c13,9f6e7953,2266c690,3994dadf,3eb0fb42,3ce54313,ee48c390,684ccd8d) Z8(06efbe97,6758f20e,fc353437,d995e8d1,126e021f,10e4f9c1,64f350e2,91db8f16) },{ Z8(ed880dee,027094cd,df0f70f9,2f3faad1,eb8a284b,f1315802,0716dec0,7dde84bc) Z8(86dc7ba3,24b7bedc,21bcbf2d,ea50b3e7,f3797d76,5511836c,bf280aad,9290bee8) },{ Z8(bced7f0c,222db398,a1106e41,de6c8285,3ae6bac9,303e8468,33e3fa3e,bedd38a6) Z8(feeb773f,aeaad9a7,c291b97d,c4db4f92,cf31c981,4d228131,4b6d3074,93454a03) },{ Z8(4aa2a382,e919b46a,0a1ede39,b4a83e2f,0747ee2c,78fe9f00,0275deba,2bfa01d6) Z8(4af2fbc4,d6a43647,f77c6d78,573dc02f,b3e2ecda,7e6c2a3b,9e8d9a87,93f93093) },{ Z8(0f2476cd,3ea57fe0,9fc8cdd2,307f9223,2342e027,892aebb8,b97e806e,366dbce1) Z8(8031c786,2c6b9f78,7a945eda,f38ae0f4,f78a32f8,18c4f393,847186f6,94ac72c9) },{ Z8(63d15ff5,02013b67,07e2277e,7d4977f6,3f6257a1,5faac905,3f5b6c6c,535e0730) Z8(6c550ef3,6e81047d,00ec6abf,748dbe47,45c3b111,180035a0,f6839b85,955f10d6) },{ Z8(a3017dc3,57075bdb,65b5cffa,51d623a6,72d045fa,17d7f06f,3e6ac2a3,4fb92fff) Z8(e59cc3c6,2595a117,94878366,49af3b91,683e2686,8fde4b8b,12232fd6,96110af0) },{ Z8(0d2dbc3f,7b980db2,4da61782,b8117ff7,de78a0a8,9654eff2,07b54f2d,04d4dfe8) Z8(ee5ae7c5,fbc20be4,62212fee,1fd293f4,afa42aa8,abdf5c91,0f245e0d,96c2614b) },{ Z8(ac3ea703,15f83a6a,b6e2a678,8173f3b2,cc921214,048b1a46,b871bf60,23b240c5) Z8(874c64d4,1faf20aa,4070578e,9798db27,f1aeb6b2,abd3fe19,365e538b,97731420) },{ Z8(4d3a3819,19b8255c,1683391e,986431aa,42ad7290,cbd555f9,a572d976,66cb95ff) Z8(b81de37c,1481e51f,64bdeff8,d14fc582,70cdba0e,8ed9e25e,d84856c1,982323a9) },{ Z8(efb7193c,d8a3ab60,074e1526,0efeead3,86d83c22,51c3add7,8b483675,84a48c05) Z8(9324c0a0,25f3e25b,999fc0da,fdcc108f,84892a42,9570f4f5,43a5f281,98d29024) },{ Z8(4de30a78,ad5594ba,183f9d16,0ac0a9b1,422cd579,20c62241,a9c5d9f0,d675d8ed) Z8(82d42a04,d521c6db,40b7b8af,593e8d1b,05678ad6,a5db0f75,bc42b2bb,998159cd) },{ Z8(1408e1ac,e9e70d29,9c44fa81,098e55dd,966bda9c,11620ae2,b74ad88f,4ccdbfe6) Z8(753afee4,77874d1e,17489d5c,dae46f06,204ff3bc,4226f8e2,71bdda20,9a2f80e6) },{ Z8(fff62941,d9ec50cf,b60a89e6,218780ae,0a167aca,aad9c242,b4e2ea0e,c496ecf6) Z8(43eaeb9a,643b5497,9d7f9d9b,6c03d1d8,172b7099,7433726d,766673c7,9add05b0) },{ Z8(cd48d3fe,ee73c1d8,ca15bc11,dcef5ee2,91d4f19a,e221dcf0,a60d5850,0aa57e64) Z8(25c95530,e01aa734,dab7679a,c5daac0e,7e4b6dd3,21d87f3a,b6281fac,9b89e86f) },{ Z8(359c4d88,2f36417d,8891df0e,03cc7481,0bc7c353,581ea595,4cdf5cc3,c5d14036) Z8(1d43e268,acbee350,6001e35e,e9293001,2bfbda16,e3c68283,ed88f490,9c362969) },{ Z8(252cd617,a95e1a5a,a36cef1e,f026319f,d72640ea,34d63cad,6cacdafa,c5acdb52) Z8(60d2cff2,f1e5725d,b26e793e,5a2ac6a3,174cf11c,f799c4e8,a0b8cdb9,9ce1c8e6) },{ Z8(f4481be3,cad840e0,b80a576b,a9998dd2,5ab03b8e,86e84f41,da8196d5,61ea308c) Z8(5ef33dec,eb87c63b,2e5585bb,feebfb01,d5420d93,6dde0f8a,12b256d0,9d8cc72f) },{ Z8(de7b447a,b7713e78,6d950e93,ecb6accb,4b2226f2,12a70377,360e6a28,161fda6a) Z8(54b2ce86,8c9ee65d,57c9913e,394f7ac8,8b128b9c,75ed605e,3c6e243d,9e37248e) },{ Z8(68ffebd3,664860bd,e3fc4e25,149bdb56,a5236aaf,875ccc16,0d8b79ad,9141cd38) Z8(51631e66,af09eda9,fd8b9437,925a09ff,2e1dfdf5,cc6e1e9d,c4282259,9ee0e150) },{ Z8(2c6123c8,149416e9,ed899dbd,4a8dcdfb,67674a8b,2837a0dd,77858f46,db768830) Z8(1c6f4dfb,00a35bc2,c801acaa,9d743d1b,4f0701df,f8b49264,f4b7a1ec,9f89fdc4) },{ Z8(7c231566,a8bcb9cc,4e31a5f0,de76ccd3,f1dd3e6b,7c4390ae,850b9376,99215509) Z8(ff055c49,570dac4c,99ca96f1,912c563a,a9be5a70,4ee0dc81,b4fa44aa,a0327a3a) },{ Z8(280167b1,0104baa5,be0760ad,70db77e1,524c029b,3a9aa868,5d2c3b83,dfe1392e) Z8(ad2e8823,33bc2432,f7c63704,39662ecb,b28ec568,b052993b,7f52089e,a0da5703) },{ Z8(dfbbbebf,89642133,104858ef,60a29d7d,a04b0820,9a50d136,ab6b4b52,c54d6eb8) Z8(85ab70c7,1031ccfe,017e3932,f0f53593,cc2ef763,d4ddf1e8,5936add9,a1819472) },{ Z8(98e4616e,7a2fec8c,0513d49b,96b02c2a,e6e91509,f1bc281e,2cfe1d33,345185e9) Z8(5022d783,15a11f3b,4fd55be4,d084146d,637af0e5,92fe9c08,cadaae08,a22832db) },{ Z8(db265e57,d181efda,4630d84e,4f87f3e9,f2373a5b,770208ac,b7c7b50f,b2a39eb0) Z8(5489905a,55753016,ecbcdf0a,3f56d575,6b7a893d,2d31d1c2,d6e3fa33,a2ce3295) },{ Z8(861204b6,481b5a55,353878c0,6b338fd3,b408341a,a25423e9,4c8045a6,2363a23f) Z8(1519b7d4,f1fdd467,574756da,8377a1ec,99b9efd3,232723dd,f238af63,a37393f7) },{ Z8(e2c5de2f,2f3c35f4,51157fbb,d1652a54,2afa72fe,6935ca95,37598735,1f8c1678) Z8(6777e14a,a6f75e8b,3a8e33af,d43b4e06,d63334d8,66a66626,fbdfef97,a418575a) },{ Z8(5480f6ce,c8ea0ca4,e782285a,91742ccc,d3d024b3,5762206e,933cb84f,a7f7b7db) Z8(8cc4ef3a,21486665,eeb2b9e7,e3f08689,457dac9e,19a87f2a,34f70924,a4bc7d19) },{ Z8(0f7e8e2b,4ebb7d10,b357f88c,b69b5678,9bf6f3e3,e09b3342,e9548892,4a9046c5) Z8(cddd1160,9b1cffb5,0cd0e58d,29ef1eca,2003eb46,1ce47057,38bb1364,a560058e) },{ Z8(8176c0ee,9f506f83,1f72af1a,3ebf1502,d46cd0be,45f44fad,004761ab,26d2e613) Z8(d72f6e55,ec759243,c916e8e8,464264c5,242451d4,a7c1ec1a,f4a7247e,a602f116) },{ Z8(c2658630,6068a970,0e0c3754,5b029b16,83d36f12,1ef1ec93,13545562,cc9b9d5d) Z8(1152656d,3318a32b,c2ed13cb,a1872a95,4580ee24,d448ed54,a0a740f1,a6a54011) },{ Z8(9c26849b,45f45943,a8eee072,f385b0ba,92cf61f4,09f64340,6ddbb825,39c4080f) Z8(494a1322,eb3fe5fa,d87a36a4,21b81774,2d74e019,67b7d66f,b7602294,a746f2dd) },{ Z8(cf362c29,6ac8c4f7,83cbe1ad,41da709b,12d4e3b8,c43078b5,dcbda61d,e9c2ff7d) Z8(f0d11959,566e7e8b,e235aaba,b0d212ca,4b4d1412,13f3e7c2,ee8bf1d5,a7e809db) },{ Z8(e2c7df9c,9c76be14,05d79a4b,dd835439,247e47ff,9ede3d4c,448c4b55,eca1ba5d) Z8(f257d01e,878211b1,af4bc660,e17ab4a5,63de1ee8,dcd6832a,2f6c0923,a888856e) },{ Z8(f9834a8e,d1ea5a0e,1e72816d,d998cbba,bec24271,28bfc71a,f528f87f,a88d2a6d) Z8(b62709d6,bdbab4d9,527462b0,73ca99a3,de41b9df,19217375,8f4fd7ab,a92865f7) },{ Z8(06151b1b,85c67da6,f8431ede,72eb259f,0562adec,ff7ad99b,36a1ca19,45931d74) Z8(7dbf5c4d,094f003a,e427bf1c,f9971655,be7933f5,916a84b5,4830f5c8,a9c7abdc) },{ Z8(2ee6065e,d84d5aeb,79d2847e,d4607a6b,cfa4716d,abc4e90a,102e3539,ec29e77a) Z8(f769d388,91bd6827,77ef508b,72cde548,782acc51,648ff1e8,b1647b14,aa665781) },{ Z8(632e0106,cab1b0aa,88b7fd78,9a2542b2,0e2c0151,286ac91b,e2ec9b6d,7fa5fb8a) Z8(5bca3585,9f321fca,8e69e270,fa1db9e7,11000fd4,739e1bd0,3861a332,ab04694e) },{ Z8(c13b6108,400185f2,618b50ba,cf855bad,ba485390,b40008b7,e73fb9c1,14ff539c) Z8(2a4d08e4,56a20620,e0d2c55b,03728b70,2b469fb6,fe5966f0,599dcc2b,aba1e1a9) },{ Z8(fd8a3574,d3fdb776,c3bde77f,4a195daf,6f325ae3,9b9aabd1,1ca234ff,3cc6eb35) Z8(a7edf055,b854b5cf,6c42068c,183db540,6afa8ef4,a36273a5,997dd6a1,ac3ec0fb) },{ Z8(36a498ee,4614067c,ffed0b20,f90a8bfd,39a2b99f,b278542a,9defb54c,64815216) Z8(c4e2513f,f4309a24,130dd772,1951bb83,8769f24d,f677dfb2,7d5cedc9,acdb07ae) },{ Z8(6fbacf1d,53a309f4,593da3a9,7bb25f2e,c109498e,8d0d947a,64684b8f,20410073) Z8(327860b8,361bd73d,5ac7f639,529f4f43,86cdb591,25ee2952,84a8bae6,ad76b62c) },{ Z8(42dc23e5,4c5681e8,10ced33d,c068fdf7,9c89b025,813b0f95,a482e425,1b7384af) Z8(c5f182b7,01e2dca4,c42ac104,c1476866,995154ab,8562c352,2213059c,ae11cce1) },{ Z8(c53c2cdf,5307ed4b,3b746c2d,3fd6f785,dd439af3,c6586fe1,eef1f3d7,95ee0fd1) Z8(c44fdd30,04407947,43effe26,03742b46,3e52070a,14725e2f,b4d8c080,aeac4c38) },{ Z8(19c27a4b,069518ef,608d99e1,778f23a9,43d8a1f6,3843bdcb,b6b5a68c,77bd59a9) Z8(4e3a097c,6dd5e77f,bfbb5c68,4736fc44,1904f916,08a41bae,821e7ef4,af4634a0) },{ Z8(0e621cec,cbf0d745,ef9a241a,b16df078,24d12ebd,f7f68473,916f0675,2a7b1f70) Z8(72810af7,922e6f31,f25347b4,7e411319,3aa0ae62,cc0bffd2,ae624f92,afdf8686) },{ Z8(ec62b0f9,ee29a6a0,3fcf63df,c74448b5,74cf6262,a5f8fbc4,e64810a7,1ddf854d) Z8(13d626cd,04696a5f,1149f517,a5b0f42a,cd9cdaf2,8f2ccd75,3702f448,b078425a) },{ Z8(21fb6e4b,3a0ebf2d,119ac76f,314716be,bdfca441,790bb09a,042594fc,205110bd) Z8(cce6db2b,5d3ed56b,4df9e1c7,09e2828d,b9f6a7b5,43d65788,ebdc6f6a,b110688a) },{ Z8(ea5ad26f,499d0c17,b70a6d35,52abf343,d2824dd1,06202b00,2db1af63,2e434885) Z8(d5f02eee,66a635d2,716ea56a,3ae3c1f6,b2f9e94a,5e62be56,68f9db3a,b1a7f989) },{ Z8(50442247,1a366759,6c3402d3,ead0314f,5fe4e0c5,39cb4dbb,84ef7278,25329c79) Z8(c0f40bad,3c3177a2,53734cea,b2a3bdca,b8c33242,d7eff716,105c7f84,b23ef5c7) },{ Z8(4d7b2d36,7763ad68,fc564739,c63c589b,c7c3f6c2,bdfba59e,63e3ba8f,dfe5b792) Z8(8a0944ed,ea469bc3,9071ce0e,a2d0847e,c6b9dc4b,63262866,03d81743,b2d55db6) },{ Z8(d039ae93,4785f476,9e977afb,0cfdc69c,fca71d8c,70c045a9,ef498a57,43ac8c5f) Z8(409dcd1e,751e5dec,0783f6fe,e469ff28,4462f939,59014174,1f043691,b36b31c9) },{ Z8(c06e926e,2238c933,a073dcc1,3d2abd15,7dd4e84f,75f0e008,8c44cea3,a6e1ef9d) Z8(ea37fc5f,43c06970,2ffd0ff7,69a53095,bc3f1576,56579305,f142bf9c,b4007273) },{ Z8(c024ee45,d3fdabd0,89caa556,3c2d9478,cc470fe0,0c2b1434,4359fdcf,7486ae52) Z8(551c4356,0a83bf69,8e5b3e75,7426f3bb,5971ca78,972b51d4,b7db53b2,b495202a) },{ Z8(b6b7c2b7,a308e1fb,c5632729,9a25eeaa,89f6a700,f453dc7b,ff66eee0,61ae10f0) Z8(01bbffe2,7c6c5a10,fab778f9,c0998af1,2c3f989b,934c772b,582bac12,b5293b62) },{ Z8(26ed1cad,ae8d5530,1792d5ca,ee8b0c5c,eeee6cf7,ba2ca0ef,6fa8d575,e58350f3) Z8(8cea9535,8cddaac1,b3891e07,75216f47,5e3907d5,f8f3cee7,59ecc4af,b5bcc490) },{ Z8(ac4d031e,6a18bd61,6e12b2a6,5318b2be,84d20003,7231de7d,7667216b,32f340bf) Z8(d59cf075,dc78e6d2,567914a6,ee7e3ade,80c8a0b6,9de29bd2,e18cc1c0,b64fbc2a) },{ Z8(bd39b09b,76e88d40,f851e99c,7851427f,c4551044,235a7456,37ad0b6c,e30321a9) Z8(622e4065,f25b5517,73b3fd15,0ad7a1ec,f5c86498,1de72a31,aa9d7790,b6e222a8) },{ Z8(13c3d8bd,f13b3aac,2b00266f,3d93f8ad,95595742,83f97104,eebef105,67a20c15) Z8(e0e3d97d,9bfbd896,0d67f497,f91a4955,4e3ef828,5dd460cc,02577ad2,b773f881) },{ Z8(945e8cf3,38257e41,4380781c,e8c53e21,2668272c,49c49ec7,cec98182,4655f065) Z8(64cae530,a012155f,14c79a80,3d7aecc1,10a4443d,cb2da552,c2319e73,b8053e2b) },{ Z8(47d04f2f,b7e0289b,564de9df,38d73bdc,c7501845,b772d374,edafdea6,dc6367da) Z8(fa8544aa,2801763c,aa36f135,5a4d5a41,102f7717,b2066fb1,4a8cc2b9,b895f421) },{ Z8(a91c42b1,0c4ccbf5,1fc7fb02,6a57f0ec,5ce1e224,59fc20bb,dadbb900,85a0e5c8) Z8(31debfaa,279fbde2,f28bcf2a,05fde833,266bc460,22ccb6cd,7d73d865,b9261ada) },{ Z8(4269812b,9f568d99,8d284245,929e144a,0cdd73d1,36ddd27f,7f14ee9c,fe9e8c16) Z8(ac1e21d1,2e44e671,d5d0f7a0,f01f06d4,2d100e70,5fd06a89,b96ff977,b9b5b2d0) },{ Z8(ee5469aa,c24f5187,62ea50d2,cbe25d89,37c5c425,ed6648f6,0d634fec,41a41f8d) Z8(51eece27,0672fcfd,d454a343,23228454,0942e386,654c2cb1,d470782f,ba44bc7d) },{ Z8(773d151b,a0ce4d29,31a19866,e98e80f5,f0fbf88e,cda43312,c372d285,f8603fba) Z8(989256d6,d8ae8b68,0a8c7b1e,48cca731,10da150b,95898e52,16c6c3dc,bad3385c) },{ Z8(d8317a9d,b58a00b1,5ae2bca9,3fed4473,86ae2a0f,892edee9,6927dd63,902eb955) Z8(05b79464,e2c7194d,6f8d6c65,1342deff,07915ae6,a4aa35b9,36360232,bb6126e6) },{ Z8(7ac67c19,ca1d2723,96ee2335,888ad40d,ff8f33bd,b1618881,94867be0,43eb5053) Z8(20d4c84d,877735b9,a599e7d2,740e9aaf,a7ae3e62,4c11f821,51163ae6,bbee8897) },{ Z8(c4c3c40d,994e9987,5d58da8a,920ba34f,d050067c,d4140c7b,569845f3,010c85fc) Z8(5514a995,231796bb,5ba4ab8a,13fab81f,e80fb290,d4113006,e98af280,bc7b5dea) },{ Z8(078d591c,2fc841ff,55ab5af7,75a8ca78,11f4d92f,afabb0ad,f3ec992a,04259565) Z8(c71fed79,be81bf84,8a497168,15d7d6a5,fabb5d74,e33e6c0a,e0cd1089,bd07a75c) },{ Z8(af58dc87,2b300fb3,924473f2,ce65df39,1202cd89,9f3a1bfe,5ca4f7fb,384a4671) Z8(56e4bb84,a593af0f,c726f312,89fb1e26,c09b1791,fe419f7d,7287ec62,bd936569) },{ Z8(db99522b,1495ad10,570f1ff0,64640bd9,c33c7379,a3c88dfd,639ea69e,7e4bb855) Z8(664ccbbe,9c2bf459,7fa58b32,6bbb76d2,5109b743,7965a606,30495b76,be1e988d) },{ Z8(eb3af07c,c26f2caa,16036500,14b1de73,edc0ee63,94f33cd5,014699b1,4130f65d) Z8(655bf345,74fdaef1,f13d5c3a,01438341,55282e7d,1043c5e7,fd049aac,bea94144) },{ Z8(948cdeea,3b85c8bc,189c9cdd,624975d4,49182faa,9801fe64,7bfd7059,ec13bb8d) Z8(e7738e7a,1511e852,a2606cd8,6f6bfd26,8e50ada6,a8ee913e,08a7ec6f,bf33600e) },{ Z8(91c017b8,905b317a,a99fba77,1a3acefd,f6180765,21db31c0,0de6e856,6093845c) Z8(64b3656a,6ab1d623,53934558,ce2085df,441a24b5,b9501d5a,cbc4c3fa,bfbcf565) },{ Z8(aebd0b6a,2234ea74,e80b5754,1856411b,4880f10e,215fd084,a87870f0,86e41e4e) Z8(b9a23642,548e902e,a46a50a5,59538bab,2b630d4d,19b11d41,034a55fe,c04601ca) },{ Z8(990563e3,dfe86b83,ac95ccb6,3ad03636,485bc5c2,a34ac5cf,51a62f57,44ffa53c) Z8(a10b2d25,37081467,aef436f6,d58ee867,6e92fa24,89dd62c4,ac526640,c0ce85b8) },{ Z8(f2ab784f,7d87e16d,d5ce0fad,74459366,e7517870,f29f8b05,83833ee6,8d6fdbad) Z8(d1575070,0987beec,703e16c4,695bf27c,d2425ea8,92fce924,00002945,c15681b0) },{ Z8(2de4649e,69584910,e337a1a4,4574b346,ead7180d,0458efab,16023b26,75af9aa6) Z8(815709d1,6653bbab,e3b003f2,1812b904,361448e7,838827fe,6f711098,c1ddf62e) },{ Z8(3ccfa487,5a07a42e,6570fc40,6ed05d32,b4e62c8d,c1a7586f,12dc125d,5b06891e) Z8(ce882276,fc8ce728,1847c57b,8039a8ec,c1713e2f,c9ee01f5,9fbf57e7,c264e3b2) },{ Z8(9f6c1e9a,5c930791,e8cb14e3,41f3a7c6,49d272f4,16f02476,00e8f7ef,ca811d6a) Z8(a9724511,a4a42eff,0e4baa66,e970ec0e,c61bb9fa,b373fe45,661628b5,c2eb4abb) },{ Z8(629652b2,5c2a2311,5ede1189,e88a3fcb,1159f52c,0df7a13e,df6f5268,c38e91ba) Z8(218c6d64,aa12aec8,d04b7f6a,93a72f30,c678fde0,5626eb9f,c3d72a04,c3712bc7) },{ Z8(6c572099,e2a717f3,dfd54159,31d1e173,9a81f5fb,c86286b1,826637a2,ca40809d) Z8(3061f2f3,57b7468f,cab62fb5,ce4aa623,4bc61565,f5ad957f,e2d1510a,c3f68756) },{ Z8(88c93f33,c2db39af,5903eb22,3a4558bd,438ff50d,0a313650,cb63ad19,1ccc9b7c) Z8(f32b4f93,91d85ec0,63cb83ea,97192bb8,667e2502,4b8b6951,1188c7b3,c47b5de8) },{ Z8(d28d2f5a,098b6ca9,0006bc9a,24ed1b16,f8463c22,a068eb0c,45c51352,b0fd5694) Z8(4f97d1fa,fe669d99,0039834e,4da621b6,bc9e0221,8cb43d10,bf8fbd54,c4ffaffa) },{ Z8(65f31f3b,388e1c1e,b8b30016,a8c80473,83abad85,3498d020,c61fe6c9,9ba8c506) Z8(b4ab95c9,f66d6033,14b2bfbe,6837d6da,9263d1d4,99db3524,79eff5e0,c5837e0e) },{ Z8(892289f0,149126ae,59c15a7b,1893fef7,5ce6c6be,449d5230,47a14fa2,f2db2abb) Z8(79a3ff17,442531f3,8a15c194,6f74b5da,66516455,480edb88,e7a4eb7d,c606c8a2) },{ Z8(4dd071bf,8c241234,57a88b57,cd4c845e,d58b13d2,69f86fc8,4647ee8f,6f575b7c) Z8(1422a61b,a723e05b,e3af549f,dd13c472,574ca266,e7345576,c626564f,c6899037) },{ Z8(7cd74955,f6c32fc7,4175eb9d,724d1c66,de8162ac,bb9c9bcf,b5848c7e,bd069fab) Z8(48417fda,adfde929,af9b702a,0e9c986e,09f2be38,e7d54fbd,e602ee13,c70bd54c) },{ Z8(6b4b1aa2,4d3fb729,fc0fe1f4,e0b01556,21b73f1e,b2be5028,5bb954e9,97285197) Z8(9d7e8a06,d41681b3,e8b4d30a,3c9c7639,9fe946b2,8e55c9c9,278b38ee,c78d9862) },{ Z8(e94d85d3,1eca4460,75c0f295,6f6ffd22,393e3682,9a21e260,119a5614,5c540c8c) Z8(7298a4a4,8402ae01,c708214c,3b7d29be,91ef71d4,ccbcac07,778c3ad0,c80ed9f7) },{ Z8(03e2135d,a0d8504a,644636cd,e0a59182,73ceabab,b0e884ab,01e3f55f,a5917ced) Z8(7ea0180b,d9884aae,e7b9333e,167b4c95,a90d530c,745076df,cc19d89d,c88f9a8c) }}; const mp_limb_t arb_atan_tab21[1 << ARB_ATAN_TAB21_BITS][ARB_ATAN_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(b05b5f26,0e71e093,0e01723a,81e8b531,5b7039bf,5077ba19,d2c215ef,f8683492) Z8(db5e2e25,083b4901,184e277e,48487df1,4489185c,db600462,9f50bd14,302e7051) Z8(e0ee0aa7,9a4b316c,89582fe4,32916544,dc172ba5,69a141a4,84ba4a5c,380f1768) Z8(b77501e0,9ebb1272,440d80cf,63fff32a,c8ffcd77,07e2a4dc,4e20aad8,c9bfa51b) Z8(0bdd5f0d,503f8851,1da324e4,77b05217,496d0a20,6c86a4e7,fc3f074c,1cc4f214) Z8(6fbf44e6,95583c13,d84f80dc,12dc69b0,228ce8b6,3480beea,554f25d4,3ebc36f7) Z8(62b425fb,f2bc846f,d3021773,836e1db1,1f7b3dbf,05d87ee7,bb74aa0f,407fb1b6) Z8(fe3e623f,a3d13d38,596a7b7f,dcd9e7cd,faaa0890,cece21bb,b868f38b,3aa5fd19) Z8(79ec81b3,c24479cd,157d9fd9,b1276330,aab2fb48,ef0d9133,feb17148,68ee429c) Z8(d9022ab5,8c9ed5ad,bf33872c,837e9ccd,c85eeb48,1fb2cd92,a7d87ae8,84d12671) Z8(c83e269b,8fddbe4c,53d59835,c38b6b3f,9ec9c439,27d81b23,b70c54d9,107f1ba3) Z8(f7c5f629,11fed0e8,c24d389b,535c7f97,79b53203,a94d5b55,f2204a83,e07290bf) Z8(7de781f3,1edadbe4,eb0d0d2d,2aa2c686,45a41873,2542bcea,ab381617,a96f6f0b) Z8(86bda292,90024115,9a021aa8,007cd63d,c63aee74,6b06eb7e,cb7ef091,d48c02b4) Z8(62e872f9,e79f94d2,b58df3bb,7a05eb9d,b400d0a2,4d6e16de,385e8484,d0aaa133) Z8(737b4914,e5bbc8bd,197ca05c,aac8a1ba,fb5cb3d5,a628e2f5,89d759fc,a9d14ab5) Z8(6f362901,1358c95c,c276afc4,13c86927,f7a43e2d,0f282ff5,897e5f9d,3b2a91f5) Z8(a26b0830,b2380bed,a606dc40,9c036814,6ed46310,13bcebbb,ea5d892a,07ff556e) },{ Z8(a04a314b,aee9953e,ede190bc,3d5577f9,9df5f7eb,b374863f,ddbbf656,89ae6707) Z8(bf218df6,493cd567,cd6fd15f,8d63640e,6ce8a993,fe4329a2,663f987b,0ddd0edb) Z8(6fe63d6d,1877d90e,1db23199,2e3e9d2b,497fb0f9,01a357df,788a5888,34c89866) Z8(804968ce,3060820f,0a674bdf,3398a491,88614364,67635542,68994e14,f8d8da21) Z8(dc7e331e,69234d96,734e2e85,32dd1357,0a37d6bc,ef1d7e62,e6b46593,40582814) Z8(27147ec6,624ed03d,0538d40d,3e9da0f7,e83245a2,991c58d7,fc013a81,83457bc4) Z8(e11f76b1,eb73d677,bad49ce5,8176cb83,e1da9fb3,c0af98fa,c634f7e7,4ce4dc27) Z8(fc080d7a,aa7781be,ca935085,03ebc23a,5b9dd531,83eb6d25,cb9fda8f,362c5a49) Z8(15e01e12,acc4f432,a95d6f11,de099b5b,fa8937c8,62a154da,945be2b6,d6975022) Z8(f5939c89,0808e92e,e1167691,4182e351,7f6f4729,5f0876f5,555834b1,f28da626) Z8(90f60b3a,9c0cd476,4c3695fa,d3a5535e,50d1dfec,a91e25cc,be5f7199,92286d47) Z8(61461357,e4003801,6959cd77,e4979789,6fc7575e,ae32790a,dc1e8d81,1ff3bd74) Z8(fea827e4,62c55f53,940af3d7,0c2b99ca,2ba9e91c,fe7ba779,bee42bbc,754589a4) Z8(6142a822,26407fa5,b01e7030,e08263f3,422098a2,e74c775d,8ad1d619,2abc57b8) Z8(00d679f5,6b3de22d,4ee676fe,5a437601,37fb5bf5,3d807d0d,bc1320a4,f1f6d154) Z8(4f9fcfba,99fa1886,ae1b4d65,272e54bd,eccad58c,4e8952ca,5bddaffe,d5c04e8a) Z8(4ef2a858,42521de9,625a4c0a,b1404b3e,6ac74803,493fe292,473e9b7d,d0249009) Z8(03c4b8ae,c387a9f8,f59d4b2d,1319c12c,c0e2e0d5,6cb2792d,967ef4e3,0ffaaddb) },{ Z8(b211403f,c67d3540,19dfc6a8,4cd7788a,5e0a1a09,5957a606,55eb15ab,10386d4d) Z8(d0e9aced,a922352e,f749dd95,3a80390f,eacd1a61,fc56533e,040407c6,91bf13f5) Z8(a1bc20de,8f3dffd5,a91eb7fb,e7207805,e8795f2e,899823cf,2c5d6219,2a93dedc) Z8(87e44a17,02c0b75c,01ba6087,a07475e0,b6b06206,e46f4795,334db346,e1d08bd4) Z8(5b9b070e,961df1b0,ead3d07d,a80c2169,63307a8d,1dea9f72,be4c9ec2,aebb9cb7) Z8(91ce2136,54bb304f,50c0ec8f,f8a9b3ca,526a5ee1,bdeec0e7,ab760adb,5f32ab45) Z8(7ebe8df4,73ea9791,c66070c8,445e91a3,688a6f71,5697dca4,631ff53a,22b99e04) Z8(258d455c,7aac9d55,e9d0b3ac,72c42fb6,f239fd56,13fc0525,9171d65f,37de6ad5) Z8(59664436,dcdde8d1,7eeb51d5,ba496f09,87f513d7,2c820771,cc113cc5,0ebd1a71) Z8(0fc2b166,3975b844,6970c215,7a48ba92,5c855a07,4a7703f1,26e16372,3f78d07b) Z8(cfe35126,b195310a,3dc3cad5,501ae206,90f2dd6a,41ab5f68,037d77cf,6d43eca0) Z8(d8b30834,2a526bde,f9faee38,f6883b2d,73765562,352b8e91,eb01314d,a0dcbce8) Z8(bcb15480,f885655b,2f7dce54,4ea5113f,5b5ce8fb,4680679a,f2b2af41,4799749c) Z8(db96d6be,d70f6f35,3dacfd0d,1a060c26,8668551f,9e706288,8f663655,fea59963) Z8(65382776,09b125c1,3fa3b89c,abab4e63,4a12bc39,689ee6e3,60b28ad8,3399bf1a) Z8(ebf0f3cf,ed830e7e,a722e4c5,7d741e6a,d17d6cf7,826f1b72,beab6d39,e4b108cd) Z8(e9ef63a5,f61cb520,147ccad0,b05362dd,cfc4eed0,c7006c6b,a4933246,45474c82) Z8(8c33e00b,65667e05,3055c1b8,cfc1508f,099f06ce,126acfcf,02f10e8c,17ee1826) },{ Z8(c630a635,8b739b70,768327a1,2f5e0255,88c400d0,c92ae87c,6aa1bf39,991c6a01) Z8(dbd9c6fe,b5267e9c,b987ed5b,76a7100b,2df2ac48,5b570e8f,472367e9,46b31084) Z8(bfaa3554,c917b349,8d548b59,d00bd1d5,7f1e80f5,4afa62f0,e7bdc73b,681aecc3) Z8(c437ea3c,2406719e,ed600edc,b53caa7e,6a938973,bc9aa4b4,cfdeda55,7ad2ec65) Z8(709896a2,fbb5318f,aad1300b,537c9a20,0786c28f,26c824d7,ef375383,792cdc8c) Z8(2b6dcc9d,02e1c872,9236da27,845d8678,0e466bfe,a2b937fb,6b07b53d,b58fbd3b) Z8(d4bf0358,189dc07d,ca72f0d0,8f0b8c7e,7a746da4,978836a8,552cb6be,d606cc7e) Z8(16ae418e,32fdec91,f3a6d5e1,97f6cab3,03d99344,ccd23b39,39800ea0,034e840a) Z8(c016dfea,9ab81f22,219bbb04,e884088b,998b6d86,f80f4e61,2e3b72bf,18795467) Z8(5c3884af,8051905f,d9a502a4,42221f4c,4ea67d5f,cd20007c,85af5fca,a240ea37) Z8(f1b2bf3e,18ab73e5,ba6b9a6d,b512ef18,5077a28d,356d51a8,7272bf1e,6944cbde) Z8(f8bd1246,cb6db4fe,5decf647,fd06658a,3bd2923e,19576621,478da9b3,2430439d) Z8(be249ea0,4b029876,2d1f2c96,d708bd87,fb330df0,ae026efe,c8bb1a5e,1c18d05f) Z8(7bd8f19e,8a15dc19,3e36978c,8bf3deba,0ccf31fa,e532f8f1,5faef8b1,e828090b) Z8(1b45c7f3,1357120c,a236a05f,604e87c3,40f20933,2da37ce1,0531822d,731d1796) Z8(09682ab4,109e4ef8,a13d17f0,dc0194b4,796a1d75,afab0859,bfa82285,bbee7451) Z8(57f08ded,a54d9b11,3e535f7f,abae7931,3c469ae3,a7ff4baa,403b384c,1a9a0100) Z8(bf6d82ed,5d926aef,2bb35b24,f1672afb,e7d111de,5912f313,ac2f6dc6,1fd5ba9a) },{ Z8(8c865d25,ace05c5a,9eceab05,77209dad,feebeaa4,4978a362,464b796f,9cfca9ad) Z8(9c8ffecb,5424dcc3,b511a23f,6e15030f,80652176,582c4da5,4d9f48d6,6ad6b6e1) Z8(a81fcfc0,976e01cc,b17ec185,66b3809f,080e3808,5389c498,68878e6b,8dbe319f) Z8(26716720,52ccccff,788e1d58,d3fb8660,59024b02,5476485a,aa1a1d7c,40643bf8) Z8(2d148422,e792693a,c407a5af,10d2fa42,c3988f0f,effcf38f,76a00441,aab38016) Z8(67a1c06f,cf5eea0e,1873b842,18014d10,2b437646,88c0dbdb,f25332b2,7701c0a3) Z8(a796bc80,30b8d08c,8b19b282,c6c86839,75b65a44,9083089b,59e2947e,5aebaa61) Z8(096f39ce,9d82dbef,424d0b2c,c0159236,48008c3d,144eef2b,b61490ee,7394743d) Z8(70ef749d,c080a69f,0810d12a,e6bf0cda,eaf60611,19daea3a,39ad97ca,0f9bd392) Z8(fbfe2f3e,60f8d765,c4be8483,851535fb,05eec70f,e7cffa82,8127e565,22d79df7) Z8(69ecedf4,6682dcca,8e7377ff,bb26408e,aad49692,d43b554e,9e841198,fe8680b8) Z8(f69769ac,8d970462,305f6fb0,f30522d5,f02d57fc,4f52c7d2,d6aa3237,2fb217af) Z8(80435350,c0cd9e53,60edfb24,a4cc7a7e,e9194d87,04d767d2,d59c725d,87b2e5f7) Z8(b98728e0,12fa0936,5a57e2a7,f0ade96b,e830817e,add90a80,43c5a75b,3825b54a) Z8(1c2d33d6,15b21b55,1c8af5e8,234c833a,b83dd11d,097a8fed,69a2052e,dc7bbcd9) Z8(4014967c,ce186a12,86c973c5,8b6a4ee4,8acae796,4425f0af,9b95a250,424af525) Z8(be2d13b3,a4d22e76,c6fdac72,bb480a41,a8adca3f,de49b5b0,bc6aa4fc,6d60ea3b) Z8(d0a3c05b,132f0292,2eb74a37,5dd4bd3e,40d83fa1,d1d86749,8cc4d8b0,27adddd1) },{ Z8(ad7a26d3,0cc2924f,f0995d08,755e0286,3db592a1,eb5d0679,d8271993,e2e6306b) Z8(e251fa90,1c3dc33e,8ee4812a,2a13d891,5bc8e050,eb53b323,54f91f2e,5d0e1341) Z8(a60d30e5,e51de084,81170255,2479014c,36a1af21,67090e87,e5ec39ec,309eacde) Z8(26fcf598,3e653e67,5c92c02b,d9f5314b,e8164552,2fd778d0,ac3c1600,8adf8615) Z8(f09199a3,1f8fc04e,f3927390,6a8e716e,3e9d7962,b4fb306c,00216028,e0684d9f) Z8(32c62bc1,337830da,c6f17291,6e97d077,75edd2a8,3a3be8f0,256c7808,b468e4b7) Z8(8689715b,82717c11,948d9fe4,4a191b17,0336aa10,6b6bb9e6,f00494a4,7e849ee8) Z8(f75ebe07,52c03c0c,0149d157,5b779f67,2cf6dc3e,5a30ad15,4a1c785a,24232995) Z8(ac2c3927,63ff68f9,8a8cb627,3e31ed75,e458447c,54e9d3b5,515af116,16a963cd) Z8(a6c13e85,8ed70b69,d4aa4b95,677ff24d,9cfc7472,9d9bd45a,a99c0f9f,e60b099b) Z8(7c86b41e,107cfbc6,3b3d8a6c,ad861437,b09b25e8,dfa59430,93810e95,6eb591f5) Z8(4b01c1df,21484501,e73cd6a8,3ec7c05c,202493fe,812fe2a1,9073245d,8fc03e46) Z8(7551fac3,d83a2b11,9c78e48e,0a940a44,f58754df,7f413a80,cd68b614,da16a32c) Z8(a10cf67e,3bf4630f,fdf1d4c7,0ab13e8d,0ce872d8,95cc7caa,634e4df4,39e636f2) Z8(92780162,73ff1c6b,a390fc6e,3f186ac1,c91d1f02,2927fa15,6436494c,ebdc6797) Z8(c2aba503,0b8af6b8,511f5e25,792437cf,63ccd2c2,bba5bacc,bf49b7fa,e54e79e5) Z8(54f8c53d,2a81b45b,08d5df80,e3546041,3f5c02f3,a2e0e37d,a1314740,65c41183) Z8(c79f5cb4,bc169a93,a0e28aca,e4eb4035,07271d21,1ec2d3e2,9cb6044d,2f72f697) },{ Z8(27529dc8,b0ab6422,93903fed,fbc920f3,12160667,efdc199e,502f5da1,79a4be92) Z8(be501656,4db8e927,7ac8ff35,eae59ed9,2e1855bf,7b08b763,c2a7e62a,f7f6504b) Z8(4d4ed159,c1cf3db0,a56d158f,87c37b3d,0bf7de77,befddcc8,46a0fb17,ad09725e) Z8(7c918484,2648ee07,b974bbe6,68f788d5,a167c7db,cb3978dd,d42b5117,799b6e82) Z8(5d722e25,48dbe00f,592de2fa,a117a7db,11abb2c5,ffa508ff,380a2dfe,33ad1f66) Z8(03862bd8,361e7e6e,bb125bed,97bc0b11,a1351f48,42fb1874,ad8591a5,1f40ecd6) Z8(8469af97,518fa321,26803d2a,864bf793,9d2a34ba,2dece0c0,5e2e2263,2c9070e5) Z8(337bac27,4be7e9fa,076bb994,aadace5d,cff150e5,0fec9ab3,2dec8bd4,17fe51ce) Z8(e043898f,1fd188a0,d2eebf21,30592996,6e52754a,17a516f3,18992caf,d4880a94) Z8(1557aaa7,bad2e43c,dca323ab,bb632b7e,5b44956e,c62562af,80af8d10,40afb295) Z8(2b4e600f,8688a5a3,78148111,657f242b,3ab5d43e,38fe5aec,23d36d00,d0397805) Z8(0464c5de,b6bbfc6e,5fcce8cb,3642cb21,8f807829,4e6cf20c,bd1aa56e,528ecaa9) Z8(7205cc27,727f43b3,58e16156,5448636b,22281ab1,fd838c6b,932d7b5a,35a08856) Z8(75f9f7da,5f8e83ae,244e7685,b3c74f19,f446ca9f,86f880f7,4195fb07,1148e410) Z8(7a3fc9d6,5500630a,aa093b3a,e0fa37b8,b6b33122,f49485a2,7ccdee8a,e1ca986d) Z8(9fe24284,727f75e4,c9bf110c,9ab8cc53,692d705d,f3798801,fb58fb52,1b48dab1) Z8(2d953efb,d5f2f22e,9be36135,1bf788c7,bbace5d8,2a7d62b5,137701d5,10c6abd0) Z8(5fe10a3b,55881bc6,4e92c495,a19144a3,72d54bc0,bd886970,24c14408,3721aea5) },{ Z8(e38e7b17,cb0f6d8a,61565873,d3ff89fd,d2225798,2b8962a3,260f5a2c,293dcce9) Z8(4efbe516,4872bd90,4ee8020f,95afe6da,03eb4e41,04bbacb3,7c7bfa89,0b5ee015) Z8(0e52d3b4,23a18aad,18b1c362,43e055a6,5797d662,13d83973,f08f973e,090f3d2f) Z8(1bef24a3,bd6fe4d5,62b759ff,1d86dbb9,afc2bb9e,0a3b44fd,6a0e2f5c,9a470683) Z8(a135fce5,53dd4c26,24e02c34,b3aed837,d2d4bc2b,1532734b,5c337380,c2330575) Z8(bae62399,f5a37055,25a34c75,818c2990,8904ad7f,ff604750,faa15c39,f1689c67) Z8(6b10e82d,d5b4d0c5,94549b3a,4be029c8,4eab81cb,579aeaf8,4f0d338b,dbaf3013) Z8(f5e0d9a3,5ede6f27,cbceb593,5bce3dd7,a47c2d5d,23019f21,11e3cbe5,cbdc9164) Z8(4ba879e8,17c3cef1,049456ec,80e97880,23c731e6,e55fea04,7482fa48,8aefe6ef) Z8(ab2d170f,9a8fc9e8,50406030,f2adc199,81878fa1,7eedf447,c38d6403,32fac50d) Z8(2e51ef27,3e5ace00,25198682,28610ea4,b4bb3e51,0f416267,fa023d03,47489927) Z8(27035f53,bca24487,7f5663ce,492e950c,eeba1875,da370e60,19069a95,e0df77bf) Z8(fcfcb528,dbfb0a1d,fb052714,69288aa1,65a9b682,38b150c7,1bed4dd3,d4f74652) Z8(a8abe21e,8ec90e37,1541aea6,3e0316be,05e8a59d,77b45574,3638a43e,6f3d2903) Z8(f52cc10e,76168ab6,172dfd3e,35202301,9382463f,c31b0a65,d9ea1204,6ee51de7) Z8(cf96f2cb,f848738f,eb389c81,023448d5,5756f724,fda27231,f8fca695,67a2add0) Z8(c0e660de,83d070ea,c1c793e6,8f0af089,e960c68f,c16fa316,9a395d94,64ae4945) Z8(251269d9,de8e9d9f,e22ce0da,6a9fea40,7de885f9,5b71e7bd,5901bac5,3eb6ebf2) },{ Z8(e9917bb8,76eea57f,f88e98a4,4f755ebf,a3095345,a7092ace,dcad1801,088d0318) Z8(495f04e3,28f54d8a,8c781be5,17d230a4,6091d624,e4c01e19,ce310468,1f2e4cd0) Z8(8ea58898,91c5d661,9120e753,97f53268,4dbcbf9f,0e4d4719,ae806b8e,437752ca) Z8(3801470d,ac18aa52,61b0d670,c0ca4cfe,345cdb9a,db5bd177,fee524ce,1a4e4aed) Z8(b872252f,ab67a8c4,4ecc80a3,2b4716bd,9e099671,025d2ea5,522e6f6c,40d48e9c) Z8(833ea095,9f248b41,10bb188e,6c78c14f,0d09b9dc,5892d9af,0ba3b97b,91118099) Z8(98422252,a8515cbb,daafc01d,b832b23b,fd32a7d1,84b5f2be,b9290623,2a9c1d48) Z8(e79d126e,58cc1fa1,669c65ab,76259b55,f439bce1,9520caf9,687c1395,8ad1ad02) Z8(204560d3,23e02343,41df1fb6,faad8c76,6bb331df,bf8ddb80,3990be61,cb60a595) Z8(557b7ee2,30db7a1f,7fcba68a,690d402c,ab0e6cd6,a440df1f,9353d317,71018c0c) Z8(5c238828,f4b4cbbe,1dc73dfd,88eef680,dbdaba6f,7e543f19,6ffdf36c,bd53e2e6) Z8(8a373a5e,4eaf378a,2f89fe99,2ce6e3e4,7b822a25,691564cc,f4ecc247,79457512) Z8(d87464c7,7633f333,ee180dbe,eb979053,b18c9cd2,38572510,e83f8973,1ed92da4) Z8(32325db3,f8dc9405,89caa408,a287112c,ccf9088e,76a4a66c,519b6f70,615a5589) Z8(847e278b,b7738f82,49570816,b25ba7fc,456661bb,b1e38cab,cda2ed3e,b9d373e1) Z8(fabfaa39,f3b7a912,542e4630,e691feda,7341fb34,cc8b2146,ca65990c,2c670176) Z8(3baa0802,9fcc00a8,e76734f4,56bac311,ae28c340,edf331ad,b8c8226d,28af6d95) Z8(a8450274,e5275dd6,e0d27de7,87e9714d,dfc414c6,6523a458,2fc5e098,462fd68c) },{ Z8(76c154b5,d7edba91,8b6f4b76,6062c15c,18f70c56,46651ab4,25690cea,e5a44715) Z8(1b07eaaa,c98c2bfa,4343a732,7438b8a4,7abd7693,2cfb9807,7df99f32,ce48b91e) Z8(9dcf5033,4b60bcd6,6f34e3da,40d3a7e8,0d1bf1b2,de4fc3e1,4e00fa8a,c282867f) Z8(32061b6b,53d8b228,0bddb19a,c9d26512,a61537f8,f78a814a,7b264b71,4481171c) Z8(271638aa,3411f3ff,14757e96,ff02fb69,1c7718cd,323c9cc6,10eab79f,24a5f032) Z8(d4fa8bab,5cc73e15,b4989a3a,c9fa0cfe,9d8610ea,4378d461,793eaa06,071cf7df) Z8(c6ed2dbe,bf3078f4,c508062f,8c2d860c,b3f10f39,25b81d2b,38ce793f,e81b0144) Z8(b1ac83f2,044ff60c,4bb28a8f,af5fbb0b,b6de7bec,7fdc9b56,01913fcc,4fde6138) Z8(5e44c28d,9bb6d369,faca1e4f,c8885bd5,8f772b26,e8f4cb1c,115fb824,af33e8ff) Z8(7fba3f68,8075f245,77652999,551544b7,69ed837a,b0bae561,3fee0df1,4da635be) Z8(6d912d7e,97b725bd,679f3d59,a0f6c5da,671f07fb,3f461603,bbbcd635,3191a4a6) Z8(53a81313,48be2a29,704a9604,4d4c70cf,5410febe,5f119f16,3282fe6e,a4d806b6) Z8(f8a03a02,d860ae9d,2f7f166f,c415b145,acc396da,293c96d7,8121db97,b797808c) Z8(18ee3335,bede8314,f9041881,d039d204,2a11e461,927c53cc,83f70faa,345d11c3) Z8(44981133,b10ff61c,d971bbe7,626139ac,2a907666,ece61d81,3871fb8d,5395490c) Z8(d22f5eb0,6c23414d,4b67ff1e,f92bf0b3,2061223d,a915f2e1,b3995d49,29866834) Z8(97b49c80,dd8e02c6,cea6a96d,82674492,34643a2c,22033f7a,54eefbf3,699c6992) Z8(098263d7,fad2c806,8597aaff,045247c2,693d7994,e2d5da4c,1faf2f34,4d89dcdc) },{ Z8(613ed910,76432573,50461bc3,53ab3625,30fddda0,b31c34e7,74ba1639,d0e4f925) Z8(9cf8e061,d85efdad,1399241b,2e8d1dd1,4e0b3191,836abd9a,0f237e3f,4cf97f14) Z8(f93311f2,c4313bfd,b2dc54fb,3654a1b4,379bd594,8f5258e7,b8845b17,3cea5bfb) Z8(2a7aecbc,43b282e2,80367480,91dd72d6,daf08218,e6642d9a,a98ee741,42b104b3) Z8(266afd0f,b6821900,51fb8bb1,7d0897f0,7a9e0a21,47848c3d,8c979078,3afac137) Z8(9108018d,717a99cb,575c29ba,091c213d,de9d34f2,ce63d0ff,950f9b9f,581b0296) Z8(3d284d94,b7ec73c9,94f1c966,eb2409be,1654e38d,26a159b9,d1cc0d52,42a146f9) Z8(d19e4fe1,5d4f6623,4fb6fff8,0a91fc22,02a98c64,a261ae50,80987cb1,4aa5a80f) Z8(da2b17ca,5f361134,d7e623fe,74cb12f2,9a84991a,6bec66c8,3d0e7368,e28ee05c) Z8(bd28223a,4a08fd8c,9ea05e06,4da46a2c,c955588b,83c41345,d1d4d75b,32402c2b) Z8(0f9472f9,444a497a,db257b4a,b13a85ad,8e28588b,59106189,d0071889,f637acee) Z8(0f384299,d994d27e,f8b0b243,7ff614e3,437b0f13,ae38c8a3,30aca01d,097f19b4) Z8(a3bdfdf7,854ad863,e27d0ff3,a63ae2b2,cd50d85f,a786b374,4624a687,bb6b84ad) Z8(4f4a237a,19fc15db,24ee7d41,9eb86fbb,c88e4933,e035eae0,3758a3ab,35e2090e) Z8(8d1ecd27,aa6e166e,d65f76d8,880fee1f,22450ed5,81a297e0,19968377,005c57dd) Z8(4ba745a3,b735132d,dcbdf80f,060fddbe,4da574c7,c053fe5c,0e3cc433,aedf94e4) Z8(0e6d9a49,5ff2e209,61977292,daab7c7b,5e61c948,921dd49b,f930a1bb,707dd4bf) Z8(64f8f15b,d12e94ea,8f7a6be9,90961ce9,fbecf460,4cdbfbbd,4735276d,54c2b665) },{ Z8(2cd57f9f,b857ff4e,e09283ba,0a6f29d5,3a6a42a1,cb101bfc,2cd9e207,4b5fb702) Z8(4079cbfb,35d48ce5,6bfa8ba6,6e7aba19,a9681425,e78ae520,a9aaaa47,9dbdab3a) Z8(6265989c,9c71dcf4,d7b691d8,04636bba,c89fdb72,255b7861,76c67acf,1f6f5999) Z8(c5b47b9e,a7c73717,a5c07643,202558c7,1be49dfd,68c8c262,33f5e984,3e420ff0) Z8(263e1ba3,cf889e1a,12c565a7,93264f4d,fdc532d8,40d3530b,e14c6824,066834a4) Z8(99f18a78,893f365d,7b702005,c20b2ddb,95d88b9c,2e5490c4,fb432421,f5f68d4c) Z8(6c33b1a2,df1a7684,7363c26b,d3ab9a53,170ad866,6f2a190e,177ae2ec,43876912) Z8(cc044bbd,dec547df,6611e911,9306caae,253b5c02,aed481a3,543b0d78,2bea0f97) Z8(d16e542b,3be97004,44becece,83e26ea1,df906edf,33d0eaae,32dbb700,0f7abbfe) Z8(d29fff24,76389c39,8b604e1c,2840db79,b1b52fc7,cda6f04b,5fc7c51a,81e501cc) Z8(e58fe00f,9b3cb1bb,f334ac04,bb3ed38a,c5104494,4dfc6788,1e255d09,7363c3d8) Z8(0e23d60b,daa104d9,987b306e,580cc084,210eb616,2a7467f0,7db99782,67a579fb) Z8(2172c0c8,10ea8ce6,588037be,33003cef,5aa246d8,b44ea69d,6226d39b,a111140e) Z8(57c56395,308c3175,8bdba5e3,f54ade7e,73f99d8e,ff3cbce4,3a9641da,0eb04c95) Z8(3bc15a3e,aa55a87c,a7c19472,48e1f679,1f24f4fb,f0486fba,75fd999b,35695f9d) Z8(a4e87b3a,db75285c,0171c14a,effb490b,439c36ac,efde15b2,60e2f380,df3ba66b) Z8(9a49ceae,243ead56,bd7d0d30,430b7703,0067b9e9,6e667254,1cfee06b,32662c10) Z8(19a48470,2399f2e5,d72a2ae6,9ec21cbb,6e7f2241,c5519091,937bc239,5bd86507) },{ Z8(75467468,539f7a64,81b2fd45,6c766776,fd6617c7,af3038f1,ce3a4883,cae73e23) Z8(9bc5126e,41b06448,6ad8c379,45ce99b6,3fefc3f4,82d86297,1093705a,5c046dec) Z8(2594d68b,19218519,93b1a9de,bbaa9bb7,5300853d,a63f5a65,115fe41e,a72d3fda) Z8(75bd1052,83f9754a,82050f07,ce9da08e,c6670b0a,af7746d9,0d2f9b52,649cb117) Z8(889cc04b,98dbe415,1d73f8ff,40baa433,4d054479,980b04af,9f46a275,08543eac) Z8(9dff9c34,31f8c999,15d5b9cc,63a5cc81,784b6fea,e0aa8dfc,edb24df0,5ce486c8) Z8(1e0874b4,fa954d11,5e779eab,5cc791d5,b062f132,8d5621a6,ee53e339,53bfa868) Z8(ad0a7cd8,466d2d68,763bea96,e4501215,9bbf331c,de32cd89,349ab6ab,d46076e1) Z8(a9eeb413,782eac8b,d1a934a8,ce2177ea,7ecb1528,6d390028,b9c5c626,91826012) Z8(48a980c4,519e1d36,51e15969,e5faa444,e79c8285,b8d357b2,d1a03981,c30b0f1c) Z8(f79b596f,8403e99c,d534130c,aa97de76,e0b7fa90,6830eecd,5dbdb7f0,7cf69425) Z8(0ef87b83,b3779cbf,e9e87df2,9210b736,edf97d47,26b8b7ed,2618018a,eb4873b2) Z8(98d733bf,fb9b9bee,014eba0c,5f95e12a,e37a42ec,629cd4f8,3b879b05,e21f2efd) Z8(2499fa5f,4d9b0d3a,12d873d9,606448e0,7bca3263,cb7b0ae8,4869edb0,887e4554) Z8(ab00ad8c,801acc25,3c4079b9,79edaa31,7afbaeaa,f977fcaf,fd0cc529,88f0d7a7) Z8(3dba8a62,e1ca3ea9,541e37c9,02cb4d75,6ca61d48,1f3db333,e21eb148,cbe7990a) Z8(b3ea0e6c,eb9e214c,9b5c63e5,be201df2,9f125b1d,a348ef4c,3a18f632,e3821dd4) Z8(d849a43e,413ddca5,869d50fb,e25be4f2,fa85146e,d0ba3748,286c95b6,62c934e5) },{ Z8(9eee6d63,372ea0c9,72d0d4e2,ab31fde4,d0ae5167,88bf66c7,9e35937e,0e5d3747) Z8(2fb2f8b3,515a49ec,7fdea545,19a2d45c,65762add,f1bc4bbd,6c742170,ff1070f3) Z8(43685188,c4b97bdb,9f6c77d0,8d70c509,9b9cfbfb,1a885086,64405049,d2fabeab) Z8(55445cdb,bac68ba7,80091bcf,3d0ed901,2220be0c,0539b468,80e2a4b4,fc3a1c52) Z8(4ae41a2a,aa9db4b9,98cc7b58,c82a89ad,120cb1d4,01e98468,81abce23,f396e5bf) Z8(58e9dc9d,7ccfdaa2,a5615799,03d9c7cd,54fd04b3,52170e72,897b4050,1b7c37ac) Z8(eccbc752,4a0400a1,deb600b6,da4281ae,60e37367,6e9427a5,433eda13,399718df) Z8(6f30f088,3de59566,f9d26ecb,edd7f608,0b91aea0,c35bb755,ce2ecd10,6c6d716d) Z8(c029f3ca,facb15ac,cc3e5dd5,778ad8dc,ced4f36a,acf8bba3,cd4f7258,8be20072) Z8(474cdbd3,72c477c3,cc7b1667,5bf314e5,bc323bd4,83849b50,487fbdcc,8685d378) Z8(af67b2a1,0fa2fdc1,d2abd9c4,d1420f06,ebdc3bdf,783761c7,5d371945,77cc48b9) Z8(d896bf46,71d96a81,e47c2b32,ebdf082b,cfee83df,7c49b143,29ab3c10,e235c0e7) Z8(6fa31b38,c31c15f1,8f6fb0b8,fa8f8229,ec254c74,c2cb9906,1b4a2bb0,1b850062) Z8(2265d600,a4216346,7420e4d1,79058971,cf15711a,5da290c9,0d747fcd,bed93eba) Z8(9f0e1b6d,dece0d5b,f427d1db,3984956f,0d61b841,a61f8220,bf00c21b,b848739c) Z8(41032aad,9a01e1cd,40ae2d69,de1afa50,a4fc4878,02d11ed9,b3402459,123354b6) Z8(d6fa02dd,e1150332,dd66ae64,1b924c6d,29bfb62e,7bcb42c9,5e2241da,142bf420) Z8(89eebf14,1333bfc7,90b0d39e,3700206e,800f389b,213e4af4,308ff2db,6993bb0f) },{ Z8(6b741d39,0f0c39dd,6da61e3e,81b6c039,3ae0f893,f053a8d7,0d06248c,368f5566) Z8(cc155383,a5cd3be3,359dc1fc,f91a1ed9,19081eeb,2c532c96,0c8ef07d,62294f26) Z8(dfa0b358,d643e5df,6cc27d20,1ecbd247,20b023b5,e239bf8e,0c33d34d,2ea48aae) Z8(bc5f7ed8,7dd86a92,49cd7b4e,5eee248c,7336bb58,e5290661,d4f094f8,46bac9f2) Z8(f9441ff6,b9fdb12d,d90dd53a,e36d352a,bc74afdd,827a2901,b39f78e2,cddc76ca) Z8(04cd0195,09d9a623,9032e9a0,febe2e02,a62c3a2c,58c10d9f,b7bc3644,1282846a) Z8(e99ae8ef,b3d5794f,c00f2101,7b23e663,3fe0750b,f920c9c8,c3fb67e8,75c1565d) Z8(eede0683,935e79dc,7752fb57,3ff17569,2f3eb9e1,5c2311e7,b69c8565,c9261d62) Z8(c02df446,6e21d1ea,59304c28,c4655ab5,4fbb1a5a,28f0b8ea,538fd28d,22d210b6) Z8(14d21f60,1dd8f5ab,93a478e2,ac1959ad,304a87f2,c03ec322,f3667818,8bb36195) Z8(80b94eaa,14e4cd1d,73d712f0,0ec66f68,1c57630f,653bed45,f57f9da1,ee7f2677) Z8(7202d477,318888e1,109c92b4,7fc3893f,79a44ea1,b9d29c59,4bb8281f,62c335fe) Z8(c36263e8,68db95fb,7d9466f0,d3bcf628,7de603bb,3853af4e,99bc12d8,c2c39c67) Z8(f822c3e2,ba3da124,2839bcfd,45116adf,43075665,fd569b3c,e86e4fa2,bb81bed9) Z8(3912b3cb,c544f1bc,45d17b5b,1bcbc0e4,c8de1163,c85b72b5,dd5b3bb0,522e17ef) Z8(cd687ada,62647640,9c011432,9d668065,f714d276,4b612159,515001f6,07cbeb3d) Z8(49edc149,519673e7,5449ded6,6b947146,85651cfd,4fb13489,1a4d4498,56ab8ad2) Z8(2c32a5bd,ca859f5e,af9f5c11,db0a5f97,3cc65c01,e318f6cb,3b27be33,7036d325) },{ Z8(1d23d6c8,f4c63d0a,66a0aebe,1b64f731,50a33f16,0c6020f4,cfab7065,32238aae) Z8(d60d7fb5,9d230f11,f6bbfc06,d3c6a469,e4666ab7,56962758,f4d20450,90d4ffc0) Z8(31d4fe0e,02955286,b6e8d51f,60d34dc2,a1c8f916,9764440a,4d3fdb8b,2caef97d) Z8(817bb2cb,4ced6a35,7ccc3b03,863fa78c,7a16b7c6,6702ffe1,3279c06f,87ad0a85) Z8(ec3b8b91,25be8e48,1151d530,807951c5,123935c7,895075e3,d0f22f6e,f074c3c4) Z8(50154692,0fe6e0d6,4689ad53,ec52b11e,63eaa22c,9d3e3bb7,324e7cc2,fdbe39fa) Z8(51b15439,3d1fa311,0acc40c3,50e307d1,c5f7bc60,919646f0,b24b9857,d5b24f0f) Z8(facf9460,138e11f2,27d04e52,c21436d0,2c199eaa,f966c4ad,bd8b28fe,2520c9df) Z8(a8c60d11,6d47f9c7,25826f91,3f227346,065005c5,80654833,5bfdcbe8,6727a46a) Z8(2c98a686,06174459,52096018,e4a87efc,9f67cf91,92c30765,6a93a397,c9dce75b) Z8(a1089f1d,02779ad9,85aa4abd,7a019cee,9a23f686,33f114c5,2ac08d49,dee18222) Z8(959994e8,4e35b0f4,0ef16ac0,249ddcb9,1c44e85d,87737149,41471f47,5bfceb6b) Z8(ce43a9bb,1505ac47,a3189d87,1cabf207,40e370d9,61eef99d,e4489f32,5f179322) Z8(453afdb5,95f769dc,b1e3dd9d,e623f003,eccb3d82,199f62ba,0963492f,8cb67bdd) Z8(51dd7b53,7869b213,2005ec2b,9e1b5358,dff702a6,f7d75c58,a5ebdf2d,e0b44f61) Z8(f0aa3bc8,6fe9362d,83b4ba9c,a99b6e84,04366583,b75ff501,a0d94db2,bc89a3a9) Z8(431146de,eb6c2f1b,7e9e0009,6770f407,635230c1,43e4097c,c495a8b6,fd4e2c8b) Z8(74b12384,71678b73,930e6f80,b70a0ac3,5e1d4681,b7f222f6,86ed3da2,76b19c15) },{ Z8(15b667b0,7273a8fa,9840a807,850b45b1,1b2df7f2,f3d3088d,b95726a2,29e9979a) Z8(b3dc1df4,5066dcad,7e0e36b4,de66ab89,2e3e261b,0e8b122b,b126e00d,d6d5030a) Z8(3fa11322,e0392a15,0e355b5d,7244a97a,a662a380,f89664e3,6013e98f,bbda6fcf) Z8(22c0af71,784156d0,3451095b,7932345c,02283f4e,94c81292,6d32ea13,0fe04a41) Z8(aeb4d046,715ad559,a661ba73,8e24a099,12dc987e,8f92d306,e1c76554,a54453a7) Z8(f469b06a,fbfb6096,cdfaff8e,934bfa9d,34f01ba0,655165f2,067e501b,83494359) Z8(60a5c559,d628a58e,148f694f,99d31618,e5988f86,c7a39727,2d6fa557,724bbcb8) Z8(d4da6b80,adb5025b,f4cdaff3,787007be,a793bd29,d5d47e39,2d25c5a9,c1c94a26) Z8(a529fef5,433f244c,dffb7eff,02b2e484,5c17c36b,20f3ae3d,355a26be,41065570) Z8(3fe03464,97a483a7,e0b396dd,5b483b3b,5f1d73f1,ac7c3656,2836f885,54265867) Z8(45c4491c,743dcfa4,b69661a1,46dbf7ee,3ed9d0a6,bde310b2,6056b2cf,cd648174) Z8(750f8448,d6699bd1,91ffff07,fe9d73e1,37f00b0b,efcd1c93,4db12f34,fe799546) Z8(35deda28,414e99a6,0221513e,47d654c4,ed975002,46089f15,3caa9143,7ffcd20d) Z8(bf58b8ee,6dc196c3,2b7d2098,c2a51d58,fce87a7d,6c4b7e77,2ab1f2da,df297e8e) Z8(7f5dfe25,3448544f,cfded89c,9002483b,bfd86afb,59e0c8b4,5c43d7df,bf3c0e9e) Z8(63328bd1,d0ef844a,12f2b3a7,33a838b3,f659ae87,6aa73f67,cf9848a3,593d4e63) Z8(a6dc9901,215b810f,aab03c7d,c83a92d8,c35e080e,12df65ec,48c26c43,66ce6be1) Z8(09041335,b190087d,c5c5aac1,0806496f,aee47661,33691e3e,50505f2e,7d03742d) },{ Z8(67b0a00e,ab068405,8d448d4d,09069727,254a8786,e100433e,f5f801c8,62f7ab74) Z8(ad439ab3,78c7512a,a462b61c,49d9101c,837ff50f,d7295d8e,f249a94f,7a65dc5b) Z8(12a5d604,bb3f4467,9930b909,4c27742d,43a22a1a,dcbb7e7b,12c55106,d37ea13c) Z8(4ce5dbc2,7f0dfcfe,cee94fef,83100a66,f4a5527a,55d11911,7531c70e,8e5a0551) Z8(e64eab5a,1ab2273b,c42fece2,22dcabdb,59770442,ca46c9b1,05c84522,070c5f25) Z8(59e5d6dc,49c0bb14,dfebe41c,443047d1,b39c55cf,127c6ac9,3572ac90,51d8366f) Z8(6197e352,47aa0ccb,55dce100,e46d868c,6e8dd747,e9ea4710,fc9927ab,f433c4ef) Z8(ad2efefe,e1890002,92dacaa4,49c4bb32,ef5bf268,ee096a61,e15fd069,41aae817) Z8(d88a6ef4,7ac4cbec,3e038ed3,9f4f2339,a89980d6,1cf4209f,ba2bb21d,2e1c0c39) Z8(b981b44b,922a2f9a,eff9135c,3fa03deb,c3366253,1ccffb08,d099e4fc,fc940ec1) Z8(9db366ab,b2aa9b4d,0671a515,9267b805,42b849f9,1887fe0d,f855b281,0f22bfe5) Z8(1c4fc779,945867d8,3280d00b,cc2cd433,d538fe73,070bac44,845f581d,970edb35) Z8(463bff0f,228108bb,de73e867,fe5638dc,15f03a7f,054e8ba1,443b0157,a722093a) Z8(03bf444a,612a2263,6a9adf1e,9fac12e7,ba4de235,284d8977,d69573ae,263728c7) Z8(ca543257,2f1a6972,ce264b5c,65f68207,0d8a76a5,57950537,9a599111,4d97718a) Z8(8b162808,9e6f48b8,41b9907a,266c344f,6671d2e2,b2ad63c7,735d76bc,be85a904) Z8(f42af382,6ff1ea97,53ff817d,8e2871f5,d4bddc24,82c3bd5b,d4f13f4e,43d7d60c) Z8(1e5b65d0,55c6bdcf,774ddfbc,f1155cd8,61a515c0,4b6a09cb,d9867e2a,832bf4a6) },{ Z8(2c7cb346,f34972d6,a19a82ff,c6047f47,9aa3d1af,78a9646d,874b47a2,a0c2f020) Z8(d8169f08,9f5c8302,2f7cb6a7,22057492,342e58ba,4b5f60de,6a522393,dc7e3943) Z8(5fc3805f,8c1eb333,e86a21ff,63e6368f,bfafaae5,0595e056,9fa3d198,aa13b66c) Z8(cfa5be6e,312ba1c2,fd8aff1d,77d5ad71,96892eba,d2072a0d,c4a67b22,fcd5ecad) Z8(55f9d25d,54cfad28,44826f5f,0c755fb1,6e8fc708,b19b7fe7,a87f65e3,23a7ca7e) Z8(c94ae302,b870b33c,aa5fc11c,06703791,5d97582c,40454c79,3b4c4034,ecb027ba) Z8(2a335021,d5634463,778be097,708176a4,fe4eea52,75f1392f,63d4158c,5c56e73b) Z8(f393a2e1,2da4d728,213412d6,c473c994,f43f943a,15ac0922,a3dec077,2e8e2600) Z8(cdec2769,e8c75f99,222b97ba,3fddf612,105f1634,ddbd255c,9152c444,3743c948) Z8(fbbe5ac5,34c632f2,42c09ed0,becb6283,a2661712,6aeb4e68,853002c9,1d239602) Z8(a9454d9d,6f643daa,8e2835ef,88f812f2,dd6d3379,1dfa3e97,a1180950,1a72df4f) Z8(7f0f7646,252816fa,f5714178,209fe04c,95371f46,b064e14f,bd79cb1c,ade988ec) Z8(c851eb54,4ce9e89d,1abbb62d,6a0f0265,160a867f,a384f2af,99d4563a,dc1d4322) Z8(0ed73499,57691205,94a75236,95dfe79a,242bed6d,7e71215d,aa3bbe45,90887160) Z8(00fe9e13,0c5c8ba5,50cd8206,37092d59,9762a7dc,5a3cb336,17077b53,ee6e36ca) Z8(e697f861,9a59ea31,37ba75dd,5e35144f,3c03f196,22bbff9c,914c7211,84d32e15) Z8(edb50f83,998d73c4,b2b51bdd,f42337e8,dfa2ae57,a2d08b4a,e396f760,31205dd0) Z8(65ff600e,28c0a22e,b9ddf67f,8fbe7b9f,472b4afb,094478fc,de9547b5,892aecdf) },{ Z8(4cd57851,7c94d031,06063a22,27443c2b,23fc3937,1f58e504,b04dc1a2,42116506) Z8(726647fd,de23c3f6,1eb711b3,aebd28de,971a72bd,1f5a9067,8afb30dd,8d3926b3) Z8(6f534d1b,2e30d022,14f8b9e8,ed5d96c8,93a94329,3f64c51e,c57277a6,1ab3fa5c) Z8(503ab9cb,f94e70f5,a7f09f6c,a87e4bef,fe4f4020,d6948b52,fece172a,d702f379) Z8(1c3fee63,34df8b20,33494168,8b9dd91d,4c40a33a,d7288a07,8a79f696,1756d634) Z8(3c5f0b31,c729e0aa,2fa1a54b,348a3b17,36328870,85d047c8,0612643e,b6636185) Z8(f2324a1c,5536076a,69d7f17c,2200b3c2,319b9ae3,234daf4d,36aef9f9,ef89efc1) Z8(ab16409b,f20a6e5d,dab19a6d,50c66bae,21656735,67698a98,1b033370,db924f31) Z8(d922f0f5,05075958,e652804a,745d08e8,c21f3fde,8c062ce3,c259b589,4e8a732f) Z8(f117c882,fe015848,400cfc00,3130e701,3052d9f6,c793c5a2,755419f8,0a9d5502) Z8(0fce6b7d,162e6e28,47e97254,7eb196d3,7d3bf76d,943cfa7f,3cb604a6,da3a261f) Z8(e8ee8b23,f462e026,5cb2f727,18ca874f,1b55bcd4,61259e84,8a57afd3,1dedd69b) Z8(14246e90,c6d415ba,70ab2f55,e3fd231f,99c4d8d6,fb5db361,59d7338a,341b6c81) Z8(20ab4f9f,d7c55a29,fc66530b,b2f16db8,be2c0bfe,ed1ad15e,e1bc6398,aa0ae62a) Z8(6f27ec33,2b6cd269,bc90c7e2,5eacd843,0cd9e15f,1f4e7c2a,f3cc4a1d,ac46b084) Z8(ed9c5298,1d3c5168,fffebb46,a6e8474a,2b7c78e3,4c84abda,70b8e8b1,b537a129) Z8(a4333141,358f6440,7e523acc,29c4ed1d,073d6a58,66cd7dd3,918d712b,3669dcd3) Z8(13389eb2,f53da46d,652b375c,918a67e0,65c43747,5c835e16,f7f59f9b,8f005d5e) },{ Z8(caa9ebf9,46a6fa1e,9a1d2159,233b0652,ee628099,69d65f65,ff5c3234,0d666169) Z8(dd9c8030,90556008,9f51a964,6f525981,e4a99a03,4dcf13cc,565d6e14,ced12c7b) Z8(079ebd88,59a1b35f,b63acf13,93c39fdf,d3c672e1,27931a0b,c0856df6,9f634266) Z8(1c46e066,6eccc075,3a8ac484,0b5dbb16,597c785a,81232417,d3f7cf1f,41ee6129) Z8(2530dabe,4aab6a6c,68755d93,c2f13e15,e5a3fc63,1b123ac2,8dba2742,238d3932) Z8(e2e2e172,ee219830,db17415c,34e71889,875e2dc2,95d39e4e,4247165e,79713423) Z8(649ba08e,08bb9737,06ee76d2,b6d3ee08,3266b144,e5b901eb,ba77cd50,448a0b31) Z8(b4cbba8a,a2f90020,415414dc,b4e5f910,2311ea59,646aab04,ab2aadf8,d2613ca2) Z8(2ff6b548,588f2ea1,245b60af,f4a8f0ba,cb5cfbdb,a4c50c64,bdacc078,288a4838) Z8(1308b298,6388af30,1195faa7,e4c6a1e4,87525493,e91458f8,693f3896,d29bc367) Z8(d1e2242e,822c4988,1f3f3fad,5701e2f6,bebbb0be,b920dc6e,eb0c6321,9ddf478d) Z8(2fb2b8d7,b4e5505b,50fe8007,2bc31c76,7c589af8,f6f1ee80,b0e1ee96,47f4f3ce) Z8(7cea0cfc,533af2a5,85341ef0,70b0223a,80dc3524,061a3edf,b8f94ee6,82e7e4e6) Z8(9f5f54c7,71d88859,2190a1d2,05e268d5,00fdf85d,fc13bd23,ec9b9356,f1b765b3) Z8(8f8cf5e3,f0222aa6,3610ce00,28ddd939,489a74c1,39696ee0,f2239d7e,c2016017) Z8(5d7b3e86,eaf70f03,fc4c446a,879f91b0,2bdfe01c,e7d3d270,81e2c773,95ac8cc7) Z8(0f2476cd,3ea57fe0,9fc8cdd2,307f9223,2342e027,892aebb8,b97e806e,366dbce1) Z8(8031c786,2c6b9f78,7a945eda,f38ae0f4,f78a32f8,18c4f393,847186f6,94ac72c9) },{ Z8(24670f4d,02a0a08f,39df702d,0fc067de,d901eb1e,c0ef55d1,68c85800,ba36deb1) Z8(91ca6f7c,aadadbe8,0d8ec179,85e4ac59,68a34de0,aa88127d,b0b7f482,bb61ffd2) Z8(03e97a24,8498cad4,de246ca1,4d6c46e1,a996d6e9,7225cc34,60890de6,b1d31d9e) Z8(c99a2d3d,b1c5e1a2,4c0ce241,84ef3c9e,b13028cb,8f72e807,a55cc595,78622acf) Z8(d0724d8c,cf1ec0f4,38be4361,57c61852,7224e8a5,5ed5ee2c,14d6a055,ff98c821) Z8(e8be5554,714e7555,d0089960,3e1f1de3,d737fcde,11d45cf3,ca64c72a,8a3b3257) Z8(2a92e475,502109f5,bedb90d7,08f7c667,31621080,115994ab,7aa96dc2,92111a4f) Z8(8d19f6d5,d5eaa43e,5bff1466,b730cbac,59ce4b61,c145f8be,e8a01235,3cfacb4a) Z8(f3029a17,05cbfe88,52e42f61,e1d2dab9,0651cedd,98af6fa0,91a11324,ee325539) Z8(2e256220,9eecc1b2,c1da5150,d69ee95c,2956324b,fa8efa39,d92c97a1,4f323d2e) Z8(9fa951a6,424db729,84c425b0,b74ca036,3bc4bd8d,0e7fc493,b149ad1c,d8587110) Z8(7148c1f1,91046d27,920cc78c,19c2cc7f,52d964c1,024d57b8,65f2e2b3,0985a16d) Z8(d7f3fe6d,e9f6db11,73487793,c15ea1d6,b4be7f02,0adedf90,819207ed,0b06e5da) Z8(7d21f692,5bdd041e,4cba4c83,bc691f62,3b94dd3a,14f7f1bf,d109b4da,1915baa8) Z8(ba8b333e,1c17f075,d4659f64,e2a9aa48,8de7acd4,13e21b1c,414e4f4e,662f8be6) Z8(abc86191,5309fce9,017c94b2,09ad0a86,3f57e262,f5fcf696,efd79475,fa404335) Z8(1408e1ac,e9e70d29,9c44fa81,098e55dd,966bda9c,11620ae2,b74ad88f,4ccdbfe6) Z8(753afee4,77874d1e,17489d5c,dae46f06,204ff3bc,4226f8e2,71bdda20,9a2f80e6) },{ Z8(bf71a78f,5b1e4424,45e8da61,d7794c76,f1d08a8e,ae252e1b,e1a44146,2206224d) Z8(ab93237e,0fcaafb7,25b2e28e,ef5b18d0,acfd56c0,4ac984b8,89722222,bfbd0133) Z8(9dc6ad9f,60ed7ef6,12dffcd0,24d106f6,d7cc504e,6522b0da,173d9dd5,82b75419) Z8(4285c92f,530c6698,51a5ade8,52a7ed65,f3c32ec5,4a7799eb,9e3537a4,219ceba9) Z8(08d6163d,d971199e,87230a41,0433bd8e,070e92a1,749ab22d,19a4ebe3,aed3c015) Z8(59f85a75,eefdd797,6e0e8f11,f637dd5b,41aa1ad4,488e307c,3b733549,91269719) Z8(91e20cd3,f9eecb93,a4a4725b,51d5d9d6,d7eeb7b2,1fdaee7e,2220005f,db72044f) Z8(7f7f7bbb,5385b977,49b1f19a,684e49b0,35ab617e,715d6c46,5cc1c3b1,a7c238b7) Z8(b2907ef7,fc1cc7bd,80f5d2c3,b3849b69,137aacd6,57a04b81,1f0b7eaa,cbc2dc59) Z8(be3bba7e,9f55df17,cfed2a38,a9066d08,103a9f3f,07700e56,4d7e5bcf,a2a43890) Z8(fec4600c,90cd0a59,fbfdf4b8,7d7dac05,5e34ed9e,ce2717bb,3b3db166,ab2b962f) Z8(e1f164e5,091566ff,525e5db0,d1493d6a,b040214d,5d90f330,3b04ea5c,f41795c3) Z8(28dfce48,6d73c74f,0ce42dd5,831d9e30,a8f80416,d8e0721f,7242edfc,9c612494) Z8(c3042cc5,737a72ac,b7db2e30,848969e5,641da4e8,9e27dfe2,933a9c73,860a4995) Z8(adbb3d2d,513a89b0,73b3663e,81dbab57,2a41de06,d6d4b3dc,554f4806,aa5a1c26) Z8(4af39e72,0923152a,e1938457,288fe6e2,7254f5f5,520959d1,8f8c0c5f,e34916fc) Z8(2c6123c8,149416e9,ed899dbd,4a8dcdfb,67674a8b,2837a0dd,77858f46,db768830) Z8(1c6f4dfb,00a35bc2,c801acaa,9d743d1b,4f0701df,f8b49264,f4b7a1ec,9f89fdc4) },{ Z8(93509d04,cd71ae7b,d06818b9,52d2eb12,fdefabae,9bbd75ee,6d5e3167,cae73a03) Z8(7434b0f7,268e89b7,94e80b50,2429278a,926fd0ae,44d2d95b,91d066db,71403d6a) Z8(5ca291a0,7e7f1458,3727360f,abe159e4,247316f7,6d1fe37d,86cdca07,b4a17cbe) Z8(182855ec,8d8f00c6,b1c83f4c,938dd336,4eb320ac,a231bb29,38d22e80,2f683dd7) Z8(ca40b8b7,fafa267a,1e7ddce3,32728915,7865152c,3e57c6c8,9d99366f,7c34709e) Z8(699290cc,97a9c409,c8953f2b,72627157,a454d35a,faac58fa,714ccaf2,3809da3c) Z8(d8120dd9,96a3edfe,39774c28,931e6883,c6529741,73d9145f,5d62f06d,dc5219da) Z8(f42c2da0,eaa87b5a,2611f11f,69eaa3e1,9c8f7d83,84f4a554,b3dfee1b,59fcc270) Z8(2c04baa6,d65c1157,680f31a6,641b0d81,2905d14d,9cfd13e6,dc4f2b6a,6ec9e0eb) Z8(5ce11aa1,4bbcd467,a9b1095f,9ddd2112,7b3c79d7,f04ed3e3,dc9096e5,463d3b51) Z8(7c28368e,4bbb0da4,fd4c5eed,6662f43c,e10d9b4e,c302f329,dc72ef8d,6de147ec) Z8(a9f7abf8,d6bf3110,0ccd58af,731bde7b,a60ed4d9,5ca3d94e,55810690,7e55306f) Z8(9395b890,9d3195c8,163c6169,2bc8d87d,12696146,1f0ae4d7,cce7f1a5,0fe94456) Z8(56b73170,11bb7e56,dd42ea3c,6c7e06a4,dfb0e026,d38bf4d1,e7830c60,b8bf8797) Z8(94f0b08d,40e12c45,02bba5b4,47ca52c1,19dab12e,a2a213f2,acbe8170,9bd5a95f) Z8(d3bec7b9,fc9e6b9a,e0a3faa2,c4c7dc64,44030fce,79d89bd1,830a6228,4ff82399) Z8(5480f6ce,c8ea0ca4,e782285a,91742ccc,d3d024b3,5762206e,933cb84f,a7f7b7db) Z8(8cc4ef3a,21486665,eeb2b9e7,e3f08689,457dac9e,19a87f2a,34f70924,a4bc7d19) },{ Z8(a03eb72e,d9368608,6b4c73f8,031234b8,19edcc2f,01bb895a,aa302aa2,d4dc4c45) Z8(0ef99efa,35ffd32e,dde0e6a6,cb27bb6c,db9f1a4e,6d2a791b,ec534613,b5949222) Z8(aa6fa2d1,7d6f9ade,6a50397c,a6be69bf,a7fc5a93,11bae4d6,37daf598,1782288a) Z8(fdf3dc6a,73942899,c88596a1,7297a9ae,a4d081e8,e170d9c8,714bdcfa,efdda0d5) Z8(efbee69d,24e34fda,42c3160a,c46a8be5,7bd5d4a6,c20bbfdb,aa7f5d28,24679728) Z8(a7af2265,2ff2e66e,bdee6ebd,d6b35be1,dd2ac650,cebb8f76,2edd164d,a06a7db2) Z8(32a067be,11f8c0f7,5db87ad3,3870fbcc,a23c9e5a,75b79aa3,188bd284,2ea67748) Z8(056e8948,61d5fa0f,07218ebd,afb653eb,967a414a,2b083fd3,80a769b3,f980b296) Z8(736e92bd,c6c1d5e8,bbcfe8fc,e9abd652,7372b315,5bdd9c0d,6c65babd,286530b2) Z8(55c295e0,2a9782cc,26d7c0a0,53b08878,d8e95072,dca0a169,fd97b189,03b7ee94) Z8(ca574678,679b1684,b34e6146,94de4fc8,a0afc792,9fd6e8b9,054455e4,e673f0d6) Z8(8912e931,2c4514bc,53362120,9f7f541e,f25f778a,8427c0eb,43e1bff9,d7f0b290) Z8(4b4a8a2f,b8ca42fb,7e38a883,3448ff3d,8fc49fde,736dd663,08359d39,be5493a1) Z8(687a822a,bf21bb60,73d0f571,be0ce6bb,3a39586d,290cb3f1,ee1496b0,070f6a00) Z8(9f6a76a0,653349b5,f9c485b7,6dd6c325,aaa7fbfe,3a2d3b95,9ba8ac1e,dfe2b9aa) Z8(dacd8e0f,6562fa07,e2420702,dfad7e18,1179cbb8,49d000d6,3e230bf1,43055731) Z8(06151b1b,85c67da6,f8431ede,72eb259f,0562adec,ff7ad99b,36a1ca19,45931d74) Z8(7dbf5c4d,094f003a,e427bf1c,f9971655,be7933f5,916a84b5,4830f5c8,a9c7abdc) },{ Z8(56b9327a,1e7d0c89,6beb050a,62ca6465,cf242693,ed36df44,7947869d,3b094874) Z8(5d1f1a54,f1d36093,9e8ff5fd,11dd61f9,c4e1872e,a870a1fe,6d280e17,164b1f6c) Z8(55572869,e1891a5f,551fe6db,7dc645df,ebfa1bca,1af04ea1,a9f01fd9,504eb5ca) Z8(e70840f3,dc6aef95,96e11c06,eef8735f,446ab3ee,c3cabac5,fae55182,75130e86) Z8(37411a3d,f79fd06b,fdc37e2b,4d43cb52,519daf63,fd6e787a,45b0eb5c,1eb68214) Z8(e544698c,2a2a5156,67700e30,571938ac,3ed096da,3b1c301e,69fb9d4b,0a13d78c) Z8(3851c046,a48a755d,8143e64b,55e5e5d9,3d43f6f5,cb91a2e9,1589fd23,cfb56e0c) Z8(ffbe4f1d,c83db4bd,83d1e710,285a2fc8,b3b70ff8,cfcbea38,69328618,7e65025b) Z8(05e3a039,c2cc249e,46708836,fd5b6e0c,e8d8d9a3,1b6aa661,43789d88,435f61e5) Z8(ae0435fd,719ebec9,53d25fff,d6a33c5f,bd480f81,a6981a83,1199e32b,60bf09a9) Z8(13bf4f14,c69467b3,e63b0ef7,cba22b38,7f8caebb,58a0c723,5b7edd8f,767a6b1c) Z8(042fca7e,dfc91d62,9e8c71b1,000d2465,49cfb845,34afd431,6987a3f9,d71a5f17) Z8(9f8a9e4d,4e104e71,4b2c13f9,d02f596d,1c1d2b2f,8b2ca273,aca3f091,e937dff3) Z8(e1ca194b,9d25c580,4e860c94,8e44c949,d3add568,bb8a7001,dc8dee1f,aa2fceb6) Z8(ae8e3598,7abcd96f,28dddb18,071683af,2c6bbf0e,2c93ae4c,71edac57,528380db) Z8(11bd84c6,e789f8cc,1c30d8b6,51029433,b115d3e3,711d77d0,48b5f4cf,11709982) Z8(c53c2cdf,5307ed4b,3b746c2d,3fd6f785,dd439af3,c6586fe1,eef1f3d7,95ee0fd1) Z8(c44fdd30,04407947,43effe26,03742b46,3e52070a,14725e2f,b4d8c080,aeac4c38) },{ Z8(69687098,7cba0a6d,4a0fd7c7,1c121b55,faf85bed,ef924902,fe0d1809,919599fc) Z8(64faa5dd,fa9c88fa,b0dd77b9,55511c16,95c9d16e,cbbac66a,2806f7fe,907e49f4) Z8(ac40690f,36633250,82503344,a9f404d2,048e3a5f,24883c92,41ffe3cf,a5258399) Z8(cd1c5b0c,4cf5572d,2a4bbc76,f53713bf,db657b07,7ae8ccd6,8cbb3586,e363fcbd) Z8(2742dfc9,afb801e1,a22e736a,fe2ebe08,08a54e2d,d482fd81,f80aff48,58e9e4ba) Z8(d00d1732,4508e6a0,a8ca6ddc,2586e09c,ad6a4509,fba08869,5b7de948,36179b8d) Z8(8612107b,37d6e406,6c01b1a9,e1e782ab,f2ad2ad2,9063979e,e28e0080,7c7cc766) Z8(f263d679,51119cc0,7df43885,62774128,f13cbe5f,e6943b41,ec5a406b,c6052de0) Z8(b782cc0e,7f8bb5b6,38c308e2,1dd640e8,f5537c30,d9a6690f,f976485a,cf2746d1) Z8(41ba378b,78955a98,fd0c4a66,3088b314,778d28a8,e62f8cf1,795fdc40,9df90e12) Z8(3d30ac25,90f93abb,37f1a623,92eb7cbe,5521edeb,4d340cf8,c0740a13,dfffac20) Z8(bbece057,d34625a7,a88c1547,05f9583a,b7ceb3b7,ad9251ee,805fad37,a50d6e7f) Z8(c44a2c77,9599abe9,6a8e49ff,e0bb5841,f8747207,1b633b02,c8a3507d,066b1b54) Z8(91646d1c,2b102d1b,dba8181c,891c085f,d02d7ed6,a63f48c7,bb54ccf8,a9bb7822) Z8(46788739,0fbfabb1,29467761,ed94393a,6b0ed4de,43a1aa2b,11261990,038c1815) Z8(b50e83d9,5df74865,4f199b2a,d7161160,feed62cc,da352cba,a57f54e5,4d9b0fde) Z8(d039ae93,4785f476,9e977afb,0cfdc69c,fca71d8c,70c045a9,ef498a57,43ac8c5f) Z8(409dcd1e,751e5dec,0783f6fe,e469ff28,4462f939,59014174,1f043691,b36b31c9) },{ Z8(9d11d977,e7381d15,9128302d,2e6b7838,3c4245ce,41b82fd8,374806db,379b4c9a) Z8(cd90de89,f6837c1d,47a36b9c,dfd491f0,f97b789e,0a076168,dd69125a,12fa3f90) Z8(3a8f9a03,a93885f8,e724d190,18b029b4,f372b625,b06ce708,e9ba4420,d03950a2) Z8(73b0ce2e,70bc8beb,49618b75,40aed9d4,f68fe7d2,9d315cdf,44ae4246,ef790370) Z8(3ee5dd8d,f17685d6,5aba4314,5d17b033,95a6f5b3,d5b79ce9,a5eb0431,df4dce26) Z8(90ce8ca3,72b88846,8cfddfb2,07d9719f,93998c9c,8e22b3e6,7c29621c,12186d8c) Z8(1df6340d,a78d5279,7479133b,0e623580,61acbee6,33dc3029,0a546345,38cd6542) Z8(9536db06,c54c1409,f8663f10,f18f4ca7,ba6a6cc8,e880352d,5e6d7d76,ffb5cfa7) Z8(bcfb2f08,f4428521,5abf6f4f,cfe4cadf,a56d056a,3ddd3354,5a4f43ea,276f11cb) Z8(5925de0e,4c6f36cb,a1e219f3,4c64cc00,c5a9d03a,55aa46fa,9e8a169f,b847f6cd) Z8(fa231cbd,4b9e90f0,f6c8679d,68e875d9,908c1548,b3527466,9212e000,73a96eb6) Z8(ec3bfa51,6c25ae97,2c737115,29ff348d,fc470980,6a36a59e,c8521a32,7088ecdc) Z8(ddf84780,f4ad6779,062bdf11,11fd8071,8df67aca,5662675d,a96198d8,b3d2aa71) Z8(8c064a69,7d90fa2d,e47d2110,582ea46c,c1776a0b,1adce0bd,03fec39c,5d9a6842) Z8(d542c019,baa246e3,3973153e,71452f3b,de1b70dc,8db35060,3bad774e,f51d7e62) Z8(952a0849,8817ff1d,9d2b4cea,f67a0a71,4e757ad2,146cd2b2,38a6203d,b4ed0b1b) Z8(945e8cf3,38257e41,4380781c,e8c53e21,2668272c,49c49ec7,cec98182,4655f065) Z8(64cae530,a012155f,14c79a80,3d7aecc1,10a4443d,cb2da552,c2319e73,b8053e2b) },{ Z8(d4b5d264,c86bb317,ef343f9f,79eea9de,420d4daf,bbcb7c11,18ccfc25,b5c4ff16) Z8(48c55b66,39a321ee,e661ff05,3d736972,60035f89,dd26e538,8ee379b9,a3e834cc) Z8(e635a236,ba9ab0cf,1723bb20,05b3bd89,7821fddb,e098e4d3,c3548295,e542f0d5) Z8(b417aeda,c453d481,23a3fe7e,05fc797a,f6de812b,ab0350df,c193ed33,0a63b55c) Z8(00e12381,324ce0a1,6d76f461,6edd5b4a,7bb92665,c1f5e3e4,bf0ecafb,f7b2f662) Z8(b0ce7993,30ce6feb,653f3ff3,d5bb2d2b,c5c260bf,e879c25a,4132b999,db7ac3e9) Z8(934389e3,dc6491f5,958c9ca1,530ae175,e3aea9ba,ee2bf50d,ed7fd728,073e4805) Z8(7a5a5889,84c600ab,c6ce8979,c703ffe6,bfe3333f,1b4d4722,7fb2cf44,6915020b) Z8(06a345b8,1f7ec658,cfb4e3eb,4fbf14bd,e6079781,12a0c6ef,e7b58794,9943fbca) Z8(aff9091c,1d3364b2,e9d284eb,3350ba39,3139c9df,a4d17630,8ba5e0b1,57c89ab6) Z8(18002c16,c9f0f2c2,5ca234af,bcee6155,c9c655ac,c88e0381,658325a0,9b74aa27) Z8(84857775,7f50b381,a690cae8,3ce32547,8dbd3fd4,48a17fa7,d6569a4f,0200153c) Z8(c6289c74,6ef14fd7,ed96088a,1509884c,804e33b4,29ebbb8f,27d37352,07eb95e0) Z8(2dd460a0,5b6b1b96,a8d35f9f,eb9c3f18,0107dc6d,31e63e04,0e2d33be,99d94270) Z8(f356ab87,0a219e0b,cc0383a4,4c5c1cdb,cbbaa179,5bcae903,7c9c6fd7,f52a7a4f) Z8(a5597967,922f0c49,5f4676d7,9cabf63b,943f8efd,92583a04,1c7b8bec,483c3161) Z8(c4c3c40d,994e9987,5d58da8a,920ba34f,d050067c,d4140c7b,569845f3,010c85fc) Z8(5514a995,231796bb,5ba4ab8a,13fab81f,e80fb290,d4113006,e98af280,bc7b5dea) },{ Z8(81de9d80,03b223de,d039c61d,7e1350a3,b41e3854,03b24867,53bd5c8f,fb52b21d) Z8(d0352a8e,6840e2ca,fa0842ae,5aec252b,c481027d,cc6e5e2c,081494ce,df91ecce) Z8(6f14423e,3d41b0e0,21675e1c,9858334a,b27653c3,6ac4c295,7a237820,af22dfbc) Z8(d4f409c0,4f5b0586,a5df172b,b2265cdb,f0489f92,158b5a06,243d98b2,4cc4b98f) Z8(74d35428,2e7ca208,af3560e8,3a876c71,1906e550,f27dbb63,f29cc6f7,29d810a0) Z8(1d789cc5,100a91f2,ca8da484,752caa9e,f3bcfb8d,e0595b00,5dff6ba8,8a0a2f02) Z8(cc782240,6f32870a,69b3ffad,a5a0ba2a,83b5cac7,57bf2cd5,e92290f7,c9152cc4) Z8(2935b365,eff21108,1247bfc8,8c077778,cb031e91,a68f9b3c,1869a20f,4f453917) Z8(aa4ab122,8b4e7dbc,8d412247,d033efbd,c10198af,ed731db8,ea108367,7a5ec9f2) Z8(72955ae5,fe2bb72b,af465492,d52c0a2f,35715140,552085c6,57dbb962,4a151a44) Z8(f341c314,87d3e68a,0bc84da5,3d9a69b8,9edaf68f,e366fd35,5cd6f003,8312631b) Z8(5f7d4df9,2b6a2964,38d67dd8,6c52004c,fc3ec8a9,1ad0721b,b501bcfe,da3a9b2e) Z8(e6234172,6ac6cf92,9043c38d,4f79b74a,bd49a944,da866c15,80b9acc1,8d70fc6b) Z8(ee113e6e,823eca41,d001e26e,c8957830,896bb351,6ada4790,e7a9eedd,a7cde098) Z8(03e0aa20,c09c3cec,c458a36c,c05d176f,952dd883,89da2be4,3a7a01f3,154423cf) Z8(69689b35,16e76528,1cd1ca1d,7398e294,a3ea8816,ff22073b,d98c6dc4,b3824d04) Z8(990563e3,dfe86b83,ac95ccb6,3ad03636,485bc5c2,a34ac5cf,51a62f57,44ffa53c) Z8(a10b2d25,37081467,aef436f6,d58ee867,6e92fa24,89dd62c4,ac526640,c0ce85b8) },{ Z8(bbeb1a29,4328117c,71cafe1f,018db6f2,92f225fb,c63681ef,15fb04e8,190e1926) Z8(a1c167c9,ea706133,8f8cd082,9e1ee94d,5a757c2d,7363dd22,e52d76b0,d3689e8a) Z8(48da8ace,b17bc881,6a589d4f,18cb5df7,75e2bce0,21cdbd1e,145d4827,1582e3c4) Z8(b401684e,9b6c077d,938ef323,29f687b9,5992d78c,bd85681d,086382e0,8a42abfb) Z8(31cba5c6,932f0f49,1424a207,1686df35,6000be26,3e246d4c,951ead5c,cc5453a3) Z8(080f85e0,be042309,78646572,dd51462c,8c6bee70,345e8209,4b896e0a,8c271488) Z8(422b194d,8dda6cfa,4a55ba5d,349af5a2,3d52055d,72acdb4a,adea6229,9ae13f52) Z8(2768f61c,06b3b391,4fb50b78,a62e0fc7,4d648251,4b8f850c,77b35dda,56286bbd) Z8(5be2596c,1061a783,4108d8e9,6ea5ef1f,1586930c,cf230192,b7b74435,fd232313) Z8(74a5434d,b8e58b49,4bcfe2f1,f6a831ab,1c8ae45b,0a4d1589,4de3471d,50097313) Z8(db216163,c3fd9a75,bc33fada,36e724b5,a50c86a3,68e3b607,e3c507d1,9df08637) Z8(17dd6bff,c4ccafdf,60e232ce,d9f546bc,79be3645,73135e62,a934eacb,59b99cb4) Z8(050c17ba,45e804e0,c304867d,ed957369,2d101f73,261bbf2d,bff69efd,b89bf286) Z8(b80109d4,bfc84e09,0b27532c,2adb86cc,d9e7ca85,2bd3c648,677c770c,860a284c) Z8(b444f7c2,192de355,84bd6d21,47db6fe3,0f64a8a2,94b53592,e4a4ac8a,9ead20cc) Z8(317ce959,951dcb80,6781f28f,ff54b364,c29c132a,974f5c21,5162ea6a,a7f99074) Z8(d28d2f5a,098b6ca9,0006bc9a,24ed1b16,f8463c22,a068eb0c,45c51352,b0fd5694) Z8(4f97d1fa,fe669d99,0039834e,4da621b6,bc9e0221,8cb43d10,bf8fbd54,c4ffaffa) }}; const mp_limb_t arb_atan_tab22[1 << ARB_ATAN_TAB22_BITS][ARB_ATAN_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(4c3ac38b,589e430c,2e6f7f91,c289fc70,145bf0df,0c3692f7,d6d8b040,44316380) Z8(97514b37,acaf17b3,e68a3c04,aea607e9,0af2544d,a32eeb07,b2b1aef0,946e52b4) Z8(da8596e6,053e0c45,8d91efb1,5144f76b,fa04c6a8,f3e43dc7,b0f0210e,7cdcd4e4) Z8(61ad9354,e72b4529,ef37577b,0cb3aafd,9c58b4c3,47084c92,be5e5c3a,ee4aa6e2) Z8(4b611117,7e1d9b3d,32f71430,25bc6bce,2393e8fe,002712a0,2aa40e92,945a21f0) Z8(cb630373,523772df,11736138,a787e495,23ecb6b9,ac043bec,1f2271d3,1edf1f3d) Z8(aeea9d29,68d4bb7f,8422da7c,43fbcbe0,e0a4e899,f619a8c7,fe226c86,b5a79402) Z8(9c10cd25,934e6a41,32343fbd,d045f200,ee64bebd,d7c5c12f,1d92696c,f1e08b1c) Z8(bb5d5de5,ab349bf0,a981dd9e,b0a71162,e70e4b44,4fc25e00,c44aee66,ac2167fa) Z8(a2782a18,65ccf04b,cc496f57,e7cbaf79,60590c07,bf2a9ed6,00a2d3c2,3bbbb56e) Z8(5a0931fa,1e84a88b,bf2fff8d,701fc319,72d9426c,7938c11f,3c4ae4c8,c84a5619) Z8(d39a5056,091885e3,935ee0b3,81274c2e,305ee653,acfde487,aaaeb9e8,41b1b0e3) Z8(df2eb4bc,f561157c,bef75039,c749b113,9b48b9f1,1b23e5bc,8a9432db,c4908409) Z8(179a1615,951f23f8,e072d33a,92994444,27c90056,5ab92363,0cd49ba5,0a457c22) Z8(239a43d0,bd6ac569,76e5ec3c,69f53efc,a7ebb12e,0caf2808,c0833015,e7a6cf90) Z8(2e7623fa,fe89590f,b553a459,50993e96,761acc15,5f6fe436,817c1b8a,f9aad29d) Z8(b8be4cc8,9468017e,67ffc46a,de2b462e,19a9e4ad,3a2371fa,7f3e659f,c0779364) Z8(5d60ee69,3ce83591,aaca1311,5f34dbc3,019fbcea,76e52e5a,aaaab777,003ffffe) },{ Z8(9bedac36,43075603,4bb8bf7f,1ea43d28,154f9e79,c51923d0,a5a00164,8d686a29) Z8(649d74e8,5d5cc7d9,6e986087,90389910,daa6a9a2,37da4ec8,d6351b74,ab869941) Z8(96516bdf,a8a2b71d,09f324e6,0dfc688d,7dc2b99f,8176b932,d5d53190,5ca44af3) Z8(06931603,e65496e9,8d269b5f,de7baf5b,b8c330ac,87a6ffa7,628d559e,916374b4) Z8(9a3ac382,f44dfeb1,febf70cf,401fdd32,66dc98a5,85757b7e,45a915a1,a4eb4b42) Z8(3fd4fc68,ef18a159,f975996d,158185b5,b8bc74e3,645e9bac,944515c3,76a76402) Z8(87dc6843,39cab1ee,297d2d77,4694b2d9,9aa8b29b,0bb2f763,405b73d6,642a741c) Z8(f2ee1d87,8a6d93e4,1b2e9ae3,06409eef,e63dbbee,a1b6db59,ae8fc52d,99203cc2) Z8(56a8437a,4604d946,5f8340bb,3f01e677,da2cc547,fbeb7bc7,5e54d5c5,64227064) Z8(f709e2f7,c79d77a5,d5cacaea,4df0d3c7,13e9f587,84b7dc60,81258b44,dd551780) Z8(e57682ea,5ac9e292,3e1d5210,25193aea,2bf9cc03,0a4a1daf,a7e38aac,a6890ea3) Z8(af9d01f3,944cb339,cc4a248d,2e2bf769,fbff8a90,2fa2e20a,9e2a2a72,3bfee575) Z8(ec6dbbc5,31f1fecf,813ced72,65709531,72d05b30,d4d4506f,cdd85c10,0d03883b) Z8(0562becc,a57ffeb5,897d5508,ed6fc4c6,ecd9f279,f73020e7,97dd9372,1338279e) Z8(07b0cbb1,4712c611,84c13ae1,67a9377c,fd9b98ec,a19e148d,f0406b86,5b9a202b) Z8(39aaef44,4d58fbf1,c4aa0ac1,4ee6d3d1,0fe0de91,230b2353,c47d28b1,7c68126f) Z8(a99a8d6d,ea07c22b,7ea6d959,e21904e9,35b13873,3c7b60c1,3dd3db79,891139d5) Z8(2d83ee26,ec67783a,ee23880b,e8f2409f,ab02251c,a5ca6ade,5556eeee,007ffff5) },{ Z8(4ba337dd,2c84cf1e,10eb2839,c33dd7c4,ebc43e3b,53e53828,cde9d09c,190654af) Z8(978ceca8,3ee0f584,c4e567ff,96dbf230,e5096eff,c19cb26d,b0f8d900,ceb877c8) Z8(2deb188a,359d6340,40d651e9,87f79203,4993d399,e170b48f,28ae712f,eae4743c) Z8(82f4e87c,e180b305,bfb449d4,d0b80a68,19a9b1ad,d6a333a3,ffe6f933,a601497e) Z8(51044de6,d028e9e5,12329400,da647a36,e34520a3,789c9d86,4ded2f71,333c1b25) Z8(40fd461b,9d57015c,8cc55d88,d9b25dcd,a4517127,2d0a24bb,df317366,58e42916) Z8(e8059189,9abf7e95,7a548854,34e8c574,437ddff2,d15b1dcd,90cd22fd,5613bb20) Z8(c495962a,23e7136d,90a61ccd,4397b6ac,039dd1d8,a79ca9da,86407e47,05dd44e4) Z8(9c0b0539,34c6d856,392f05cb,c61a881e,1d77ea22,90bd6222,bc065656,61f3b1a5) Z8(9c80c546,422affb2,e9bf8115,7105555b,347bd856,e28870bf,d775a863,b6d27de7) Z8(6b8078c4,9425acd4,9713191a,f59cc5c9,7eef1c39,b96712d5,9d3d3138,6600aeab) Z8(9013cdf3,da8ba674,1f3926f0,04096d05,a51a892f,2ca79b29,31161fb1,df6fc111) Z8(57d002c8,443264c8,d39ff304,9adb5c8c,16ec2085,6ca3ba0b,1f4cac86,f0536d3f) Z8(6bed9b5c,609c7a5a,ae25519f,aec4da62,627a7277,feb6de1c,fc1dae44,a80bfef4) Z8(0c09028d,57b3dba4,3aafff35,317c6588,469f17bf,f92cb860,21b7659b,d7b76314) Z8(029d5f04,df5b5676,39d6a99f,a80ca45e,4d42e4ae,00794eaa,d4aec58e,3e86e62b) Z8(00cc16e9,13ea12ff,30aeee8c,0e650304,02c3837b,90537f6e,dc05eaab,11f9f434) Z8(13a47a91,1cbb4c1a,a60ce5c4,8de69489,b3ea592d,84b1adb7,000c2661,00bfffdc) },{ Z8(597cfe73,379da73b,7161b809,3a1ff32e,e0ad98c5,81edea8d,261fbdd3,0babf3b7) Z8(18bda01a,4a06c9b0,821cb75c,1c5fe7c0,cee30ac5,e4608bee,304a7202,6a9c2057) Z8(8c18e53b,1a526cd1,6bc9dd0c,9a576c17,e106a689,7f4b6e46,203d8270,55926b22) Z8(3184a312,b7e286f2,de6f380d,e8e62ba0,86a3a22b,5711d770,12f1e361,01320723) Z8(9e96bccc,e83db15e,1d8edd1c,3b58402a,ad2a9828,a333325b,40d9261c,a27169a3) Z8(3b4b20e2,d9c2829f,1c5d63fb,c86869cf,2b028aaf,7bfb9efa,3da1e364,0856adf9) Z8(0743fcea,2a294770,94fde202,4bdd8012,615c2eed,6cf3ce5c,47596024,ca0119af) Z8(0a327790,211106ce,5018c972,263b2d2e,d9e5b140,35372f36,fba6dba9,0a3c54e6) Z8(5a9ef78e,eb194e74,fae531d6,bb6d6e0b,1af8cc3e,07e2cf6d,9487ea80,65a53ff2) Z8(21fc3fc3,0f0dd7c1,81583f10,b0f0cd49,cc9d442d,ac5a5c34,632bdc8b,4c18f2e8) Z8(6d32d099,b8775468,f04bccfe,21089cba,5f926a97,88d187b9,cd63c70d,8422b529) Z8(7b30cc41,223ce80e,9e17a8ba,04efb441,5712e797,be91d30c,2bd45592,bbe7680b) Z8(85473f30,f5ee39d0,2113fa09,4d949394,cc27dff4,68231593,e1eea31c,1dbc2268) Z8(54558210,39fb69f4,7ae4394e,410db23b,5770748e,0d8d2ec4,7e81c1b2,4ea62293) Z8(3af5c0b4,9a115f45,ec11d7b4,2d6732a5,5ed283bc,d6e151bb,39ce0b47,f92cf817) Z8(cd97455b,5b5bc45c,81eea5ec,0c132116,1e51bd83,4346f7fe,d429a60f,1191d908) Z8(800f56c0,471a535c,67be3ae1,d89ebbe4,6126f5a9,d62450d6,f625cdfb,6d688680) Z8(2682bef6,892248ad,eb9bc957,167c18ba,6b6d4f7e,4bb12afb,aaddddb9,00ffffaa) },{ Z8(fbb161b1,b0d88060,50cb27fc,5ae76d53,34d9cdb9,e1ae7dc7,dd7263f0,b43684d6) Z8(a0cc7fd2,319fd4a6,ca8511e6,deb9dad5,71f93e35,bc65973b,cc988c26,13794bd9) Z8(f4bef158,06b5bf8a,4be5aeff,ffc2a83b,1c1bc001,1ddd065c,59700d73,afbe1c8a) Z8(b6d8a5e8,483fff54,1f1ae1fc,84d4de8f,59c38a2c,d0c4ae5f,005ad885,5ceed779) Z8(70e5491b,64baeff9,df2076dd,f8e27954,8479a34e,bfca5a94,9a8a53bf,f591c7f7) Z8(59be928c,f446cd15,a10df36c,1634c942,004243c6,c937b8ec,9b50888a,58ba94a9) Z8(32360941,78a576b2,28cc9148,fd3cc2fa,5dbc8c69,ec3aefab,30c720be,36cd5192) Z8(ded1dde7,1a083b32,1efc5044,c2ac7d7f,11409098,e5a2be84,e648f509,82169dae) Z8(711193dd,d2fc15fd,cb664dc6,145be7b5,7e0b5455,400ff96f,8ac04539,d0ead211) Z8(e1bf3403,2dcebb29,6100902c,e88dd068,59e1eec5,28c7f787,4e134ca9,1ea743e5) Z8(d4fc04d5,b1a61bb4,30eec069,de9b1f33,977721dd,619b6b8d,6aed6049,6c3074dd) Z8(988b5b2d,0f495cd9,c883dda1,0baaafb2,03e88aab,d0f5c4e7,d29b5a7e,7be81e16) Z8(1f9fbac7,cbe3a562,cd046c9c,3abbdac1,4327855d,65928de4,73739a86,e45a53cd) Z8(63f0e93d,c69a9bed,a977cc16,77a131dc,076676ff,3dd80a59,ea9d8fbe,26528b0b) Z8(dc29c5ae,f99599a4,bb355c76,2682e045,4745e126,5c9f1839,a0e75bbb,284e400d) Z8(59ee623b,4d501f3a,819aecc9,fb53b338,b1fe043d,157e0c67,6d2bb5b0,586f9859) Z8(ec6453f4,80cf258f,904dc9eb,706af9d2,a67e846f,2eb0dad9,6dd89d52,0b0bfd53) Z8(37af3ca8,05728e6c,73bb5b5d,23a27b81,70ba3778,f34dd408,55f194a6,013fff59) },{ Z8(fd10d3e8,38481fc6,511cf624,873c413f,d182aaac,95c8ef13,88afab4f,94671d5b) Z8(f0f2fdc9,c8f2705d,a4bd4f9a,7baa8f29,ea8edd6c,a45879f5,94e28846,5686c6cf) Z8(7587b9ad,557255c9,8c8486c4,95938901,49ba4a9c,61622fc5,836ef927,f28b7918) Z8(2472be05,a653a100,6063b2db,a2ca6bd3,d49d21cd,6cf700b0,dca9400f,31be1c3b) Z8(3e9516b1,32eb3e21,bb096877,a17db57a,475f4a56,92b2d8e0,9573179d,740dea57) Z8(83e7b98e,d5f9ffec,83f1e256,c6399eea,31ede81b,3a7fed5f,068c1e15,caddaced) Z8(9ce3b566,02dabfab,c6a21c8b,d2a18f66,2f04ab39,184c6f50,b1c5cc66,6fbfc0f9) Z8(5e693776,df42bd4f,399bf17a,41d745c0,f605656d,a61de96a,f7db0137,7e4b597a) Z8(48e36a01,0a35d984,47e7e4cd,647b9219,6a51e59a,484a71f2,3f6a4f3f,eb58c969) Z8(f8d1d9ee,3e2fab62,c66a2ed2,231878cf,9adcbf3e,9f205f84,f6bddf45,0ff184af) Z8(d37aa099,9c5e6b26,992735ba,280cb451,d2c50437,49775b41,6d6f710e,6c157c6c) Z8(97f35aed,9ea98724,6e07ae2c,005cedd5,ee3f607e,70cd801a,67731644,b3db2bb8) Z8(65619d3f,33dc763a,371c01ea,db4f972d,9431546b,01992e40,8a754610,7bda23d6) Z8(5c2259ba,93b27323,050bfbb4,84a37025,27158537,7f81d867,4c58b5c7,5c6d38dc) Z8(df9180a4,2a756324,c5bb8cf1,2ede8624,9d72ea85,79f21f43,d7850047,65326389) Z8(9079f6a5,febc831f,19898b99,f4aa7989,9d954b47,0b60183f,08ef2aa6,4390605f) Z8(4d558e16,6d4934de,67e6cc80,6b11e270,6880033c,39898cad,14990381,390de9a0) Z8(aa95847f,fffe925f,e10f8420,e6ed4f55,6554277a,f5a48e14,0184ca5b,017ffee0) },{ Z8(1c06e14d,0977dbbb,5c024c1a,dcb8a471,71ac83bc,df11a1b3,c84ad3e9,21db78fa) Z8(e8a1dae5,4e4f20d5,fb306a58,3161c870,a76f0f81,92482eaf,88e5ef4f,8006f2d7) Z8(67d46863,648cc92c,98ae9aa9,f60522fd,894e1a07,829ba5a8,c7848407,4708c4f2) Z8(6a69313d,20d10594,1c871b79,90fd2fe6,e5c634c6,826e1948,ae865e68,d7df32ef) Z8(cabf91ca,e234e718,aaec26be,5fddfa55,66c7a700,6f06f33b,0a48a724,2603e8e4) Z8(f1f8ba3a,714336a3,dac43033,c0dd4395,baad45ce,178834e0,343906fa,7360d769) Z8(42fec8bd,7b9e99ca,f2a89908,869a188f,19bee08f,ae829c30,f5e7b0ad,01bf5f6b) Z8(979a4d6b,cd912274,f4e69450,8025fae4,d1523590,61479f14,cdffaa58,ed3e0ade) Z8(cee07b99,b6b8607a,0e2a37f5,c9003513,5c5b1bd4,10482c5f,ebb2bb23,7d6a2d60) Z8(48ddddd3,3a1a6288,45043226,11304a61,2d64dcd1,f8d58b11,57be5cb0,fa7df975) Z8(718f4a48,b7329679,5b1c1103,a48fd81b,92335be3,4af2581b,0a5d4d02,16eeb9d2) Z8(32fddd81,6c8efba2,1b0fb995,bdd91267,982a8c43,07eaeee3,4cdccd26,68b7650d) Z8(d0d5d532,60042540,f34f418e,c2f40057,f8ceded1,5352e866,d9d42742,7790bdb6) Z8(bb5906b7,3ed2985c,2071a482,116f714e,7f8dde9a,2c218425,d022ab2b,3aec6f58) Z8(72b65661,e4e1f096,a9bf513c,bd8d1fae,749658a6,428fabba,c0d98374,978179c6) Z8(76ef6186,cfe88f7f,22b3146f,a1e12f19,b0b8b8e5,0b76fa9c,d284fe11,75568631) Z8(e9d37d9f,6a336edf,3f571815,585f8329,42708cf3,047a654a,2520be19,cc79624c) Z8(88bebd94,5d86ebe1,42b0a214,9707a91b,51014a14,115ebef0,adf2fd16,01bffe36) },{ Z8(4d85dc0a,a6dc1eea,1f3a67a0,10b2f1fb,2583a620,48620e76,9c22105f,1bb7fc18) Z8(a01357f2,697dde67,7f734338,1cb72a74,9d1a818a,fbd7bfa3,1a724a11,ef1ad0c6) Z8(89041575,a477f825,8454266a,04c7ef02,3542a1ba,0cb3481c,5e8c9101,49b4b9bf) Z8(1a21494b,650fc756,f00b65a8,f97d0d48,2533ca6c,aedc2fdc,308d5da4,03bc13c5) Z8(022506a1,d95d6cae,88d53058,4e2b023f,e404b581,afe67619,5e22efa6,9977d687) Z8(835d954e,0177b581,d54193d5,baa332bc,51e4dc40,266ae108,b9431a4b,2db28206) Z8(e15bb3c1,c13177f9,14d56e6b,89a11d66,4a29bf3e,75059b2a,c581c13b,2f4a818b) Z8(0e915d5e,439c7cc6,573fab37,5d9849b8,a33d71dd,a597fec9,c3b2a35f,40937fad) Z8(f61e4af8,ac419889,19c07b15,fa721865,fa7036f9,52e18aac,658d41fa,df3c97d5) Z8(313808c1,d2cf1b46,f99d3a01,cc5c3ca8,b252df70,7204b3ba,c051e0cd,392b3098) Z8(9738f427,0f5a9a1e,48675880,03771975,fbb04ad3,909aa1d4,91a98c39,cdf3ce38) Z8(7dc9d9e6,f04c738e,c3864cbe,ecc9fd7c,9264ed7f,b16e183a,e52e7233,bd2cf82d) Z8(b820558c,404c0c0e,9a3bc518,8669deec,21fb1229,627ee732,a0eb8973,734d0bc8) Z8(6cf49dc6,6861e60a,a673c2ff,f02e59af,86eca529,df4e09f2,2cb9e9ef,a3a35b72) Z8(008e3b18,74ccbb9e,3d292a84,d1b302d1,f0be452b,b3d2479c,0ad25a2c,e42f251a) Z8(200683fb,db904cc4,058e5fb7,ef3494c9,6a4c8504,913b2c3d,76d996be,0141ac6c) Z8(d79ae2a7,570f29f8,9717e1e5,cc7790ed,ac4a4e52,6f9cb7c5,28bc8f59,2111d081) Z8(cfdd9ca1,3507a2ae,2e345e00,8ed0ad40,f77cc15e,d00c46a3,5bbba972,01fffd55) },{ Z8(e82cb716,42843d62,cb116f3a,6e868e30,a785c566,8d0d996e,9548fa94,aea1a658) Z8(e5d38270,c02b0f19,a0919373,814e9ce1,3edf6835,6a8a141e,a51f9816,a2dfebc4) Z8(f82b2043,d5733d5f,1c052ede,2345e5b7,c5c5beda,b2eda711,22cbf7b0,bd36b2d7) Z8(1c7b8031,1c37ce3d,0c8fdc6f,2076bd56,d9dc5fce,e557a48d,e648b5e0,64a75040) Z8(2ca70aba,cfa67b49,61787355,34fceb0b,6b16253b,ee890f44,d2c379a6,f919b4ad) Z8(5fdc1ce1,be16dbf7,de7fd3cc,250c3382,5770ef52,c027286e,39681789,f1b49943) Z8(e37a1725,21742fcf,9445e986,a1bc191c,0a34c5d6,8c9a6b27,5489d0c9,e2f24d9f) Z8(590a4856,73b3f649,cd5321e2,1dfebce6,6c63392b,3d320045,acc787d8,7f40f969) Z8(99a3f92a,dccc1497,e38691dd,192b6cdb,81b61cd4,c614d3d4,b9ed7ce6,23f8e67e) Z8(d8013d19,b2a54100,21ea8498,8e200de8,9745e6f2,557e29f8,a98a63e3,55330167) Z8(6d0edeca,761c3e96,9346cbb2,e13e5cd3,8c3c84f9,6dba3620,c7aff681,db932ed6) Z8(02554026,d9e6def3,90f2892d,51611976,00c4ff9a,c3b34701,e2a05a68,0155987b) Z8(14d30207,5a1146b7,9817dc4e,933e3673,b1661c73,7bf17dc6,9c8845bf,d368ac00) Z8(1955ad29,953388af,3fd9cecd,ef64b84c,aa2da777,504719d9,fa54317a,e6313ed4) Z8(eea053e1,7639974c,9bd9a0d9,70d3ce3b,3daace08,69b79d52,9cf9a9dc,7f14ae11) Z8(ae2ec4d3,17cdbceb,b1d50b4b,ddd422ce,85002815,6c05271e,a30f3002,9e92dd1f) Z8(e26472a2,97c6b76e,7fd8b3e2,e5aa24a1,00e53690,1d5f9418,8da3e630,9b48bd4b) Z8(942c718a,374a5235,b0f73f19,fa0e96ca,e7445f8c,9241c90a,0b88497f,023ffc34) },{ Z8(799429f7,51f95d7e,c76741c5,6a76c1f2,6dacd0a9,27ef6a5e,730b5d47,17cc4220) Z8(188d607c,c013b0cd,e0379807,20943db6,a59c72ad,596ee848,aee8dacc,bbd30b78) Z8(1dc2891a,548ed7ea,a2eab166,20d98903,1084122b,816c79d1,5ec42564,77ebb378) Z8(a78ec0f8,2e286f8e,54720db0,61f76c2f,9f6da730,065334db,6a937cbd,f5f40d3a) Z8(426add38,a0f0562d,1dc5bb8e,0f3c87b9,60ecf72f,8a5e8ead,6cb78dd9,be8297b4) Z8(85fceca2,9bde0940,e3b265db,56e431a0,0ce4a87f,26dd3b3d,8e35d7a6,cdf17b50) Z8(da3aa6df,950c5f6e,94dbc54d,724b1dc9,12240029,5ce1637e,fcda3e75,067dfb35) Z8(97cfba6d,0529bc77,0a29fc37,d555b44f,89537731,d83dc9a6,e86c953c,8ecb78d3) Z8(d80dbd44,fa82451a,b571b3e7,a87c2713,18c83f8c,3dd63795,40e8949e,620c403c) Z8(1fee70e2,08ac5c99,b12fd821,965d85aa,6d539f15,af30e1ec,202974be,2362e8cf) Z8(7d7a7ad1,a9aef317,ac113798,62185019,d2c1a221,3051c707,88b5d996,579a366e) Z8(1a3465db,0584cd3c,cfc3c69d,548bcd44,922abdcf,6836e4ad,dca94254,3b3c454d) Z8(b448b8d2,92c4ccef,ffd1cde5,81423eb3,601c19b4,25aa030e,8d7917b5,00014b8c) Z8(fac868c7,2de4edab,a8fe5614,f17bcd3b,e2dc4e55,967f6649,9b2814d4,92700f98) Z8(a807ba06,215b0f8c,b51b13f1,babcd156,9797ed3a,7d4aa545,ff9ab225,8b8ded4d) Z8(56d54bc1,de62fde5,5022dc95,8c978b8d,ddfbeec5,13f6d091,f0b42ae3,2b43fa17) Z8(8d6c31bc,cff9ed71,1878e684,e3658292,cd72853c,21eff0ee,ab8b29dd,f100c5ba) Z8(4d6b813b,f9ee8e47,bb897f82,a8308d4c,c7316148,e4c649bf,be32537a,027ffaca) },{ Z8(51c56eab,f95e4c2a,ddfc0614,3e2603e7,b4ee83ea,95dcc62d,92bf8b9d,1ba44761) Z8(0d687ce3,12dfd462,0f77a6e5,c7dafa04,5ef3fd04,4342605c,0830cfd4,21d2df16) Z8(c7d13425,7878d398,78ad1a9b,0830b105,7f4b94e7,109ef33f,cc22261c,8d96bdf5) Z8(ffbc376a,1aa7b283,7199f73f,174d4bc8,dbbf9b24,f0d316ab,82b21681,749b28c4) Z8(0f2adbd2,a99c29fc,fe9b96d9,a96e9dfd,1d4fa34c,bcbb3a60,ab57f649,21d1d78e) Z8(0742e599,34a1980b,e5de04b2,122eeb87,fbf51593,0322225b,45a33e82,9494d0fa) Z8(56da10cc,574a8f75,90325d1a,7e532a5b,c30898b9,d37a92c4,d0bd7484,98cf8c91) Z8(52b96d8a,e342f5d7,ce464ed8,36be66d7,944e5c74,c142bd17,079d1d9e,d3d942b3) Z8(1e7141f2,1c6ee0fd,f023ff96,973b0ac4,4c929898,24f9067d,49a8a6d3,c062382f) Z8(15ceace3,7cd55282,6535a9bb,86f67bfb,0e469d5b,6333395e,987be969,c316ba6a) Z8(4cbb2aed,4940ec1a,4353bdff,5294acfa,0ebaa3b3,76b7a732,ab90d608,eaffbdfe) Z8(8dc9fdb3,330ed6f3,2ade712c,016f8511,c9cc1d59,a058037c,6b92dafe,2f05b03b) Z8(f5f7ad29,4ec97288,839a4bc4,1810ae8e,d9bc04fe,9cdcb5a0,ac6b66f0,838231a2) Z8(f2bdba63,fa4fb1fe,b5393020,0f8a9173,448fdd87,f8cf4638,a5597fc6,6f3b2244) Z8(1d0c1a39,1d9d2d2f,61fcfb87,6f69d3b3,069e3af0,18a16c99,efea7754,8f86cc37) Z8(a2b8c630,42f5164f,d873908d,805511ea,de014b32,89ca6a72,a50cfcc0,bd5f96a0) Z8(0b56de89,f1e88be4,d1146cc2,1a924279,adf1cbb4,bef5e800,dc33eb63,387f996e) Z8(bdcfc2aa,742f884a,1560136c,d57628e7,889f0cac,e32e892c,74c9383b,02bff911) },{ Z8(201bd14a,eff8890c,adbbb07c,a28e45fb,5a1a2fa6,2c1333a7,79ea6175,90df79c1) Z8(801f8a6e,2529752a,657d750b,a56b0f98,83ac6435,5f19096b,c21a870f,4806e371) Z8(c8e97191,ddc2c188,aa4b5ce2,fa0221b8,85817bf6,27f64448,ac894c45,58f7d61a) Z8(d2a8936e,aa2833fc,5a78c1bc,67e94e2f,2613404d,7fa00c04,be9207c7,f0d53868) Z8(1132ef71,40cb5cbe,b19f9a18,715bacae,9a2582ad,c6e8b7ed,cbc9a536,02d5fa80) Z8(ab581b6c,3c885861,658d679d,1a845f1a,eb1e329b,ed95bc68,f3426207,b4116a67) Z8(f9a9a417,3ae22d7e,c93091ff,459112cf,f41fa810,4d232459,8da126ce,752be3d0) Z8(73d46c12,8731f12d,8bb19001,e48e1730,4ee967e4,747363e2,244e08be,67321426) Z8(2dd5bdb2,ef5b06f6,10b72e21,2b010046,a0f90f42,6f471d9f,aed3d46d,21570189) Z8(31c42796,ef251929,9b653c08,fcb3d0a5,45f37ee8,06d7974d,67cd0fbb,2ae7bf89) Z8(7370ceca,3d607348,a9e82b35,450fe13e,07913242,f18310b8,38e91c22,55abfa2f) Z8(4dec2bca,a2ee6e07,12749eaf,da331ae5,0d994e9d,e886336f,23a45bb6,1f923a52) Z8(9771ab9a,e022cf09,62f855d7,263bb438,e39493ac,6bd77c8e,8f134c18,6abd2ca6) Z8(bc3be294,747954a4,74a09b8b,af71a2e5,b48dce8d,7ccd7678,468db96f,1fdc0c22) Z8(b8e8522e,5d2ba527,a82fdfd3,67a84b26,eb872af1,fc322c69,20b02d00,d831dfc6) Z8(79a6b951,37a3cc03,1b0ec73b,6e3997bc,536a51be,495f74c1,19eedcf7,2fc62b7a) Z8(61e8f518,1b37431d,e4186302,46af6bbf,91294bed,9e608b5c,ebea3e47,dc4ab848) Z8(ac4d1fad,14db0e87,1beddd8e,6f3b42e4,ee5a5b71,6d7f457b,30986134,02fff700) },{ Z8(b1a84a9d,ccfb28d4,f587a2ae,56863549,b2e28627,d1294e42,4ca3dad6,d3b80ef9) Z8(8e722d84,0a6e7dca,25b6ec28,9573eafe,c662dfb5,5df27175,c47336c2,85132fab) Z8(49375382,1698e762,9581c05f,9c37f0c3,7e63ec08,37ed0f91,efa38d72,b88ed975) Z8(327abfad,bc05d149,9c7a407b,f5c140ff,c210ac0b,b8f655c5,f944a7ea,13daf2c7) Z8(965cf2a2,0d785122,f3358d75,89ba3be1,01e47d16,830fb084,95a11b35,3b6245e1) Z8(d64e065b,7c9a40f5,01f91118,318415d5,49eb8c56,04689742,2bfb1dec,a4b94a95) Z8(f6925c86,05f164cc,094b378b,55c56cd5,c80064c0,d7f53eeb,b0498516,fd60e440) Z8(372b223c,7efe8fa8,9b774a0a,9cdec2c9,96d1b365,ea2399a0,ee2dd54b,fdae04b4) Z8(44f148f9,b0c504be,eaa601bd,65c00a4f,15834805,57507203,9e74318d,d70335c9) Z8(0dadd1bc,f26a73d4,56ef7ec2,364d8ff0,11a52643,bd8a44d2,b1f1cbf3,8961f3e7) Z8(39d4423c,d08f7ddb,320ca849,2136cefc,3b03f85d,4144115e,d8e22229,274a1652) Z8(ececb9de,4ba56dec,f05f6dab,3496c70c,41bb5c07,4ed24b23,fdb7e845,94bd37f9) Z8(f6323669,a76dfb8c,c1882866,aa17f72b,0f83234b,9d7ad04f,591d2ce0,9f314178) Z8(43e3f901,2a3cbc36,c99f803c,1975d500,3f20a178,d51c455a,175a6e91,a346cbcc) Z8(02355bd8,0e441e1d,5b0da1ee,a613e878,a983dd01,59213c20,0063eb8e,3cb52136) Z8(3c45f04c,88d7d182,0b7c9674,b42bd4b4,5bc76805,091a648a,0ec0b20f,16755843) Z8(b5982ce4,6557672f,898331f7,4d9a9ec6,f429f000,e6d06d0d,78f17b4c,da242f67) Z8(be45603b,d2d478ee,9448ef1c,a09cf833,e5f06c5c,f7d17680,f32d2e02,033ff48e) },{ Z8(72a1d06f,797da9be,41211a0c,6cda1e5a,b3488a4a,cf4bb633,52cbb27f,ce67eabe) Z8(5613cf73,a617da4b,534181b4,929826ec,e11206aa,a9fb70c1,8fb3e5cd,ef38f539) Z8(5501343b,9b74e80c,4d84c161,6af4ce60,6f22f31c,b276ee91,6ef259bd,74d5ab80) Z8(b8ccfb0b,dc5e2330,9130a75a,584201dd,8b7b2ccc,304a1ff2,957ab04e,d86a75ee) Z8(eea45471,a8116355,674e1f36,6e22e8c5,0bf26a54,7246f080,a3b7dda5,9cc6d1e7) Z8(ecd6baf5,60f64b6d,15b40ffa,670b30d2,bb982e29,579822d6,c3f5a7d5,08de2e88) Z8(1dcdc82e,0e3227aa,08518b25,79b1f072,a2f7fc8a,c0ade699,d7b7c898,ad68d7ab) Z8(61d5bb1e,76f5881e,0a7e8923,8cb8e29a,bc8d76a8,582684c5,9f1f3729,9eb70fc8) Z8(11620594,f7827fe1,f02af1ea,eaeb069e,fc553b52,a229b832,3e49299a,01ca6187) Z8(47289e9b,6dc9cb85,0620eccd,68907b96,cbeb27d2,c3261a7e,c1b38216,5ae1cf73) Z8(ab3853ff,3acb9395,1036aa98,9ed946f1,8b6c0f6b,d5cc0ae3,b0e65e0e,1a97ef53) Z8(2ec1ef6f,8fb85d32,3f117484,98ae0940,1384ecb2,4132032a,5898b3f4,8e535073) Z8(c034935c,307f65c0,56c5f16b,54f27620,f9759dbd,fbf88415,77a00884,4ead9382) Z8(4321c3ac,95e1e225,beb1dabd,54545666,cd43d528,8dce1061,0f1e38f7,36606aea) Z8(915e7ee4,0724064a,bc99091d,d5e732a5,259f3573,5709a267,c0ca2734,91bed9e4) Z8(d80f3ef1,3ca4b79a,a1f29c20,dfcf51e9,32a042f3,3dac8ac0,e44f6154,8e2e008f) Z8(36d072ef,8604f609,12af1ec7,32c7662d,dac8d266,fcd56e68,e8d5015d,49b47cce) Z8(a4ea260e,691b2df3,a5fca0c2,cdd99404,a280ac9d,bc7cc8ac,be5cf188,037ff1b5) },{ Z8(32e2315d,6c33f3da,e3188649,ba5439a2,7d659795,bae33a8f,7314f9cd,9be01595) Z8(d7ef8be2,91ad2a0a,0963d4e8,aa2a1ba9,e18ca1b1,03358791,6d7bb0c2,22dfdc44) Z8(5d1e4f33,26c70b3f,7cfb803f,3f761880,f1de9e86,e41ead01,17803001,6ea09e07) Z8(eda0fb11,e4692b50,be0faeb3,802c0e1d,c2de2a90,e230b605,44b6c7c5,1038ce86) Z8(d1f6f2d8,54949a0c,39b8ab7d,a35e5284,0fab8329,edcff4f3,d2138fd3,646e837e) Z8(06e77206,6e7d569a,9e3354ea,8e3022ad,47cf37c8,bc71fbb1,b099aec4,fd4dce4a) Z8(2afb2659,998a4306,7eef7df4,ac1413f6,bb02d433,a0ef3503,e752e295,66a623dd) Z8(15facec7,e73dd08a,8ce85435,39add92f,d629d81e,777aa2b8,96090ace,2770166b) Z8(057abeac,00d0fea0,22af57eb,b37999af,8d8a07cd,e9ba0bf6,ca92a40c,59bec8bc) Z8(db00cbb5,076f75f1,59703a5b,94873c3c,6a6ab48a,7f73570a,90a8be21,1462e580) Z8(67373d91,6d34100a,63b18a05,71e50054,e6ec016b,9d1eef3d,b5e31cac,1940278c) Z8(f6243c2b,6d45d47b,928b82e4,56ca6706,faf48387,3cf95d7c,ef30ee13,66a3a06e) Z8(2548daf6,59440124,60b05375,e6f2c48d,bbe85479,364a2e36,66ed7bf7,bea95d3f) Z8(dacb608a,47857dab,de8c417b,06ddb0d3,86b21a2f,714ad65e,38a99183,5c1792b8) Z8(07751005,c0b8c271,ee1e8c34,d31a7425,8da2bfb1,7b751cc7,30835929,28bac49b) Z8(74b0bf1a,de9d6a11,15ae46f0,bd500d07,a0ba3311,2be2f296,8ba3630c,942e29e0) Z8(54c7413e,82ec6f86,0cd301de,3416968e,35656ac3,6253a758,c36a9506,d5ea2575) Z8(a06c7118,714811d7,faefb2be,6b813772,28379e10,1afcf83b,944aee79,03bfee6c) },{ Z8(c5d23ccf,fa1f45e6,dd495329,97325086,54471806,e38b8215,3d73b6b5,2a9ac341) Z8(3970522c,59179e46,5c753163,9abb4a76,60bd6c93,88c74150,2d45ac1d,fcfe35fc) Z8(7a387ac0,eb478320,65f471c1,a3b0d91a,75e5f8d7,096187d4,a7fe71eb,75a7271b) Z8(919af827,32dfff81,dd5324e2,869b37ce,3238d0b5,6ed8e518,304e2b35,6f4ffcec) Z8(d01a6bb8,2dd472ca,4b46b010,80b8f7b0,e82dbd28,7c6cc4e8,6544b249,a5d1156b) Z8(0c9b5827,77daa870,cfd9ec54,57e18e4a,b744b58d,f3af61c2,66935699,5a37a5e8) Z8(ec45182a,92046bb9,958fe975,bc32c463,724b41da,9e6a5931,6744b551,1d3473be) Z8(d028171c,c0ab3320,c4f59600,a696784b,21b31a1d,8ceac018,2dedd785,e8442116) Z8(b644db65,ba518587,7a9eaf28,c6e86b31,0cb71720,24ada163,56092d1f,a04c4631) Z8(ae851e0b,8c60d5a5,b0a89396,f7971333,69757db2,61e7a559,cdaea213,03fbead1) Z8(8593e21a,20d55ec5,053cfe2e,dca0bed7,de7b9074,53f5499d,235556fe,327dfdad) Z8(55f77979,a135ea12,02884e9a,002ef887,7caed13e,fe95301c,9018bc85,5dd8d34a) Z8(a63cfa35,0eacb307,16165f2a,b4a664d8,f810cee4,ddbfe9d9,ef005830,d8f16fbc) Z8(1b39d84f,ac4b5c16,12b36b15,6bb299fe,7e09d162,2bf68274,55020e16,76b2b560) Z8(5c915954,5f541040,9ac2c06e,10b26dca,73ae8ebd,91eaae16,0160f86d,23a6e613) Z8(0e32643a,2ca72839,aeca2042,14146677,76e749a9,729da52d,33f7b6b8,88b319a9) Z8(4df9c218,85a1b8fb,797ad494,bcabe016,286e9ba4,68d09936,858d1e57,a36a1de9) Z8(c9d5872e,81a57e00,0437bbd1,2083bd97,0057dd81,ef9e3159,776e5356,03ffeaab) },{ Z8(3adeca2f,b99ff895,bff9ff1f,d0d2b2d6,016bd791,315780b4,15fe8765,4566bb0b) Z8(cee8d832,ec979256,04c61e36,ba8b234d,abf760b3,96a68005,65dc9c12,99b8c5d2) Z8(53e1d154,0b1409cd,325878b7,6772b60f,90ed8dbc,ad4ef485,31d9bc91,69d09a27) Z8(32f0b03d,aeb4c77d,e96f75e3,8674c92a,57c7788a,0d545e40,5c66d269,49161ca5) Z8(a860f739,765a24d4,e78ae172,8c6ca493,b6fedefb,f51d8969,8fc4533e,5bc0786b) Z8(0e52eb26,487e21dd,f6bdf85c,d065ad13,f78e17e1,3eb16cb7,0465b3a1,d4b6e295) Z8(983d4f77,b304fcb2,7facc9ce,affc0579,1142a96b,973cd5f5,c2fead06,12f55b13) Z8(4981b8e0,e1fc065b,54fbe82a,74f06731,45455ad7,57e9ed15,3674b65d,44a63633) Z8(ccad9899,e7b66125,21bc4e28,1bdaf1bd,908e4ddb,4b165fbb,5eedf6b3,22981f8c) Z8(d631a99f,1d63186f,e7e41ff4,db559e4a,73a37f9b,a294293c,96d97ba5,bb53f161) Z8(f8dfbfe7,6831d090,98e393ba,47cebcbd,16f8b35a,b7b0264e,b8987f0f,7f33aa78) Z8(0f12df40,eac06e0e,e4f62be6,c77ac5f4,b46f37eb,f6ecc54a,66b19807,1e2610b1) Z8(1fbba4e8,4812a31d,46bee989,4551093c,5f48884d,289aef8f,ad8aa374,cddf680f) Z8(58c2f361,a4eaa9ee,b87b8807,e9e43a12,521de08a,c1d52b69,66d96ac2,752d4a48) Z8(ec4fb6f5,17a0764a,eb80aa06,629fa87a,c25d79f2,81d604b0,e5731704,1f00a5ff) Z8(a87c7cbe,90422c16,7783495a,99a226c8,d462537b,b2a75bc5,35e8f086,b8033fb7) Z8(67a2a273,9e04354b,ddc02a44,5d2310c8,b5c43031,cec3545f,56638f85,155cec92) Z8(9f9f6c77,4fbb4c02,b0cd4223,5d4759ef,77d83d6f,b1fb39d2,6a9835d4,043fe66a) },{ Z8(bb243cb9,58c43562,d256cc0f,64b77e8f,27a97f9f,d644dad5,4bb98a41,cffc6e19) Z8(e477c2d2,5667207b,89d9d8b1,eb65accc,b4a687c5,3d815f5f,2e31708d,50170f37) Z8(09b329a0,25063c66,dc7c752b,29a5809f,791edca2,fbbd22dc,13130613,820affeb) Z8(3b1438b9,68a28215,a14105f7,3399ec21,9a58b199,0c61170e,d816b5f4,47999358) Z8(86d91ca8,c893035d,cbe95375,db5fb8c4,e6b86391,bb828830,b1df9e4c,8dc8408d) Z8(35283cbd,74b8bf79,bc758098,7214c793,e0be50b7,9717c248,8a522c0a,dbbc989a) Z8(02683b39,9b78356d,19eb3514,ffeccd17,a6211a68,a90dcd2c,16a7ad68,bad8b6c5) Z8(c7a1c444,c1262f13,6bd59060,fc082052,41b28a5a,3f89ebaf,f6f2b543,f289577f) Z8(2164e7f3,c83a1303,4f2e4187,49ff9d98,30055bcc,b31be9d8,62cc853b,d6068019) Z8(a63c159a,5c7832df,3f64d147,88fb44b7,2d978dcc,6d2ee3e7,cc494cd9,d2ffba05) Z8(4377b259,a867d837,321039fa,270926a0,d6af6377,115a15b0,88399880,204d2b90) Z8(7d031123,5da7d59d,6bc65d00,95599d0f,89fad8bc,d7929d6b,5dfefa62,da34fc0e) Z8(c94244ca,03be8be0,4dffbbb4,048524a4,7fdd6121,d1d9ba23,419b38f1,9db6046f) Z8(bd065f46,5a70edff,fbba45e0,a28d7e79,1aeb1ec0,1cd68b6f,ff7d461a,633e2249) Z8(6ee25835,db456f5c,287540ca,971ef3b0,07cf13fe,6b0b652b,f9e8796e,6913b7d6) Z8(ac048f29,d57ec4b4,d55b6669,81731286,0d9a9b76,9761f966,1ba71959,a66ecdf4) Z8(2429ddc7,711a1e15,4e073a6a,b1822d32,7b31a20e,aebb5520,4f6adbce,4184e96f) Z8(f0186c5b,50fd2a58,ad420164,c635d0c0,22589687,2a7dd9a8,70f98d8c,047fe1a1) },{ Z8(2fac125e,3ef49e64,0adf0866,d7b0de0f,d5d83f70,22764f85,368b23db,f9cbd377) Z8(094607a7,6979f164,c9871228,7913d572,30ecf645,b5c68461,da61e082,46ca700d) Z8(a8fec524,f5fd0219,7b141f40,c1735e13,56900064,fd7a8629,6685c3ac,da1cc0ba) Z8(06f667d5,3c9e706a,9c9aedbb,c78f3971,1866606f,215e0c6c,47be03c1,45b302fd) Z8(78085a54,306a06d9,490ca52e,7fe3d0f6,88f93575,a2ed8b0c,da662739,e68bf85c) Z8(60d0f6f5,b78ce427,c744edfd,a68d20c2,bc4908b4,9efd8a2a,9f9b3887,80bdce6d) Z8(89fcc7cd,8a8572ab,905efda2,b77266e5,5a3e6f29,71e3a904,f5ebe55e,a363e9d0) Z8(d29baf72,3cd22205,6b30edb7,8878d4ea,68ad0e07,d0444452,e61f0e1b,ce060016) Z8(52b0b692,8ba4a908,14a4b521,84fd7f6b,c15962eb,fafc582c,f118fd32,b6b42db2) Z8(0abb2570,b3cfa3a7,4a86f93a,cf4c4ab6,757358a2,de35b249,fb4ec06c,a799055a) Z8(4a9d0c8b,db07e928,b17cf1ac,207e5f55,d946f65e,53e73e23,035c8a41,3fb9a351) Z8(7c104171,bf3c32a9,452aad98,811cde96,81239d55,5505f88a,c2316e3e,75961b5d) Z8(b2c3cfbc,8d95e0b0,fe722b39,39d842f2,99f596ac,fcd7df51,c4facdbe,18eafc80) Z8(92ff8f8b,abd6baf6,3a67ee95,156c6cb6,f789216e,ad7260fa,66ceccc1,99528ac6) Z8(80c3ce0f,c92ce642,8cd53a56,581bc2dd,ad86de12,46da1f18,95648532,6280f112) Z8(87ebad8e,0afc7854,872963a4,41d2796e,29236c66,8ac918e8,1e60490d,22627877) Z8(ade1d246,6685704c,4bfff2d8,4c2aa947,5b1fc2a0,ae81c5c0,e2cd515a,b4877a03) Z8(6740a755,6a85bbe7,789d30eb,1716f7ae,7caa3c94,915ead9d,8e292e02,04bfdc48) },{ Z8(357b6e00,d7477168,ffbf79e1,d80303ea,7e25c7d2,d50a6b33,21ae51dd,369aaa33) Z8(d58ae635,c2d0c1fe,9cf98dca,801bc0a2,cb7d716e,bb1fca70,f24ab64f,b56e4d7c) Z8(81e67cff,26fda7f3,c7fe035a,0e8062a0,5d317464,9185f3a1,61e19e19,99d91bc2) Z8(09630080,18496ac8,5e8aa1a8,c5a3652b,51f1b235,54840fc1,2962674c,52e66367) Z8(eaf6a40a,f8ea25b3,f6e3bfb2,12bdb05e,e67a3039,07ef6f45,9f9570cd,6b318f9a) Z8(bba8a21c,69064e01,fce0bc08,69d41340,4ab5589f,1adf9943,8de73d6d,131e37c9) Z8(92d4cdf4,720e640f,d40fd7b4,ef3de4b1,d6c12708,a01fe5d9,48d8d796,5afbde99) Z8(e83d1e42,7e889466,e3e86c0f,423136b6,dea6b1f3,7996a5ff,fb2f39ff,113b9c48) Z8(dbce0aab,386589b8,973eb260,a45539ee,2a2664ba,1466b0cc,b04b4377,42e1f3d7) Z8(bcafb4e6,1cded802,551ca696,79710fbb,e4321824,95699d79,21904744,1c401e68) Z8(8ba66f0e,dacd509e,7e7219c6,c784dc98,022312b5,7cce849d,e8e1f8a8,8a97eb2c) Z8(df14e3fe,1c8b4e7f,d2f1fe83,cbc8e2fa,b48bcfa9,f35a3d4a,d36a4b88,26b87417) Z8(86f17fe6,bba7734b,e16ff983,d0cb80d8,f5faddc5,48de4c5a,16cd2fc5,8426fa49) Z8(6ba2f910,2d78107c,bfa83c40,b7ed83f7,0e3780b0,2639c501,87d9d2b2,1a1f512c) Z8(f40fd2a1,41bdffd5,b047f860,5dc8f473,7f8f37ff,01e6c7a9,73ffa102,8162c588) Z8(1630b0bb,4026240c,c4092aeb,0c309045,064705eb,0f1cd47c,8afd68c7,5eef6576) Z8(a5a0cb92,6b52a899,206a0785,3293c311,165a6a5a,734d22a1,c5de3191,38d13644) Z8(a3132784,56335a58,5200eb10,fd306b02,04d3fd27,ec153c93,c629bfed,04ffd657) },{ Z8(1b37a109,4c741da9,62be53b1,29857ef1,d8836613,02209fcc,7d7dad24,c0e0126f) Z8(772f725a,023e304f,3f0559a0,e9f04104,7eae3245,900ecee8,43a2b014,126aea90) Z8(cc6a79fa,e761bfe4,a1fa3289,297f034f,61c9b891,db9791e1,1a4ef4bc,119f5c00) Z8(4c2eae1f,d72655a6,70110431,8efb90e2,1c842ecc,7889beda,ea3c57a2,6cce55bb) Z8(b8cabe34,25457d55,8b125d5f,40700934,0fe2cae6,a4f79a04,4dd0173a,0ef60c4c) Z8(c17823b3,7ada7ea2,941c5b73,7ea6eb17,8a189f7e,61cac60b,6ad2c5f3,1af99dfd) Z8(7c885507,75963d0a,954fcbbb,2a588f25,b4258dac,7cddaba5,613e1692,a647ec09) Z8(da1bce35,d4289b40,9418f4d3,00d873c6,7f7c755f,dc7e13ea,aa586a4e,6cefb51d) Z8(3b6ab31f,fe772295,8de44df9,6943bcc1,cbad2798,ee3913a8,16cf5004,9199010b) Z8(3c57cd12,395307e2,a876895b,69cc159a,70360a67,1d133a0d,9ea81825,0254e2da) Z8(5f437279,84d1fd65,8af906ae,6606eb88,daec1255,036bcef3,e368c82a,4f81291e) Z8(7bd87ada,1bfde5d4,01ca2f21,433c48ac,380e44a6,59525113,c9729e47,b7153c82) Z8(719d4913,ec4bbc6d,25c82079,87c9c2d3,97552557,1935c1fe,ea08a105,06c21204) Z8(1042a1f5,92828623,8dd0a97f,e5d8177d,bdb36f87,923080f7,cf09774a,3a71d773) Z8(e2b84f77,0dcbb857,c649d71e,cc2d2010,890158e4,0c12e8f3,23a7350f,3501b9ea) Z8(3454fa21,23b5e71e,054558ea,ed883750,09360fb6,59bc4083,fde667f7,ff958aa4) Z8(a0022a28,ac4bd96d,3b96de34,8e70e458,05a7ddc9,c187777c,3a6ef621,408c816d) Z8(27f35719,3113a239,97804f17,346e447d,5e67fcde,80c3c078,1d6fb9b0,053fcfc7) },{ Z8(a3dd82da,c4a58200,75aa9df5,149013b1,0d27a6b0,ee7ab0c9,6e7b98c4,361467a5) Z8(5c08ac11,81891170,87710766,cbd7564c,da35d1ef,ef092632,794843d7,18efe96e) Z8(0616a61b,96ca9566,565871d9,aea2d522,0626fa7a,3675f869,e56c9bb7,4952673d) Z8(1481ecb6,5a49bd1d,4435098a,1df0c58b,807719e9,349e4508,e96a16ab,88cf836d) Z8(df2b6853,fa47c1e0,5c74e231,baa5d1b2,a4d7dcab,da2652a7,acf1741e,f0ef58a4) Z8(968e3193,65760971,64f13e81,657aec63,af66a0ce,0ff913ca,68ad18b2,8419c801) Z8(69d83638,e22c18f2,f17acefc,f78acdba,51d37d9f,be8018f5,74f426c6,c32a4fab) Z8(3d433984,58469568,89352405,96bca865,c31c27a6,ab92490a,183f7435,ffcf35a7) Z8(84334840,b3d8e7da,dcebb2f8,283fca3d,75e6879d,0bf54ea7,e973b22e,81f427f9) Z8(4acd40c1,5341fd08,22cda7e6,75378161,569d95a0,42dd3a65,8acf4e13,635fde00) Z8(99371a7b,53505836,f6d2adef,aca482bb,192c74c5,8c81a434,11eb41cc,3ed5fbc5) Z8(0a984323,4b21cfb5,720b7075,be0dbb60,c33ed93f,91db8d83,dfa93cce,9231c3aa) Z8(662651d5,abbb7fb7,9c9ce619,15994cc7,ced8eaaf,35dab621,416ff3d3,03e404bd) Z8(dc10a0b5,b4d429e7,05c48c6b,b2b1c0e3,9c46edcb,f0c7c134,1999eb01,16235aba) Z8(a9834481,e49354a1,0971e973,52663b86,e872c250,76e498cc,700f5646,9fc1c4a2) Z8(a30945ae,10fce887,a7c9c969,1b39e93d,d7848d83,9953a1a8,7ed78f81,0e750e2d) Z8(ca493297,9f8a2497,89de5339,28aa0326,6745f7f8,f3b26ea3,fa49fb7c,28cc560b) Z8(60388160,8547e715,eebbf5d1,b6816f35,dd45b49a,39eb873e,98e756ff,057fc88e) },{ Z8(b285a5ed,3012bd04,e9fe7fdb,8873c510,f5ae677b,551862f2,30e519b3,f7addd99) Z8(0caccdcf,09f24c26,daa8ec81,954a11d1,b51aa7ef,889e5394,8b35112f,573d65a3) Z8(ba3b29cd,5fef924f,62a77bf9,a4ed4470,388d2f2e,71b9de91,65aa6716,568b671d) Z8(c32cd7d3,1fed2b99,a80eec13,4680ded2,8af3a42b,8ddfaeb0,15480db9,b3ec201d) Z8(ecfc1963,5fd00e43,2776fe50,65cc31c4,bedc459a,568f4ffd,5bf84e58,3e4a711a) Z8(c1c3abf1,58d913da,0cc3134a,b0fc2255,960a8e15,35249a2d,f1ef74c2,d476f18f) Z8(d8075023,d177a153,7444baa0,fa864fd3,e7abf7ba,cb05bf61,68e5f94a,7268a070) Z8(fefb826d,2ee32117,207fb3b3,98540bec,667ac32a,b1a46b79,93db8d43,cd8fb2ca) Z8(592d704a,b306a8fa,0d27f499,c994862b,ba45f652,45607cce,d9cad278,e870f65e) Z8(a75162f4,e8b62d1b,29c89100,c33f54d5,98b3f259,4ef60f9f,9cefa6a3,d84c6a58) Z8(af3c30da,9fb1348c,56d16a72,4cc7feda,86a6a0fd,737c5b29,8d789534,b1c8537a) Z8(a97cffae,2b81249d,83ddb4ed,875c496a,baefc4d6,c93fdba6,ee3f6bdc,8f637e7a) Z8(f423d15a,08c1652f,6c0631af,22c4d465,2dd974c0,927f2274,8bbda94c,ae643d1a) Z8(8fc2eca8,d9155a63,02abf0b4,c26632f0,5bcef349,fc0afe06,50cf1ddb,5314b56d) Z8(0b74f656,4b2b5653,be6c48e1,d1f35e2f,c4625d77,88bcffda,dad65bc7,e2037a10) Z8(f6966053,0b28aa3a,c244473a,69fe80a1,f23205aa,fd4b5486,4ce057ec,3e76388c) Z8(c74498de,de34c365,ef91291c,d6619c5b,dacc2446,4c20e2d4,f9fd17c4,9103a3c5) Z8(00ba93c5,d36a21e8,ae41b20d,a0fe8c19,99dda021,d79f0ff9,3dfa8fa7,05bfc0a6) },{ Z8(b5c0eb7c,579ca0e3,2694520e,3afbc453,5b63ca88,ccca81c0,ec061d81,12f0195b) Z8(037c96ea,314b8920,6d20b3fe,fe9ccd1f,a12953ef,da4a102b,6c4db481,c65b95ab) Z8(becea825,6d7e626c,352056be,57145de0,2a2e6f25,26b78dc7,8ff922c9,2a074823) Z8(524c3653,70a2263c,8ec61b0d,2bfc4fbc,7b81b885,ae39230a,6e2933c9,1bd43546) Z8(65795e46,cd764058,55076d09,85425eda,3fa9886d,bc11cf75,8f215a3f,d859da2e) Z8(da120739,a86942f3,f4239769,eb7fcdea,cc5e1d73,1a215f21,98fe599c,e2178184) Z8(98fb7868,d6db832e,24d2750f,7789827e,82276096,d954089c,16751c08,22b2c657) Z8(48be0521,7e4ae8ae,fc8e93cc,19eb0799,5d21bcf3,1cb671cf,2de3ccf4,da4466d6) Z8(7bef1e02,0e1233e5,9263d673,d5af6167,59bc8aef,c99f3ae6,780a7a89,5f9e11a5) Z8(06256d8d,44ee053b,e0305c59,4769e465,797241b7,07a3da37,68d87636,cf01c2a4) Z8(03429f3f,0edc22ac,05bfb0b1,70402b19,abd6330e,386d3678,13b4a790,03d3a77e) Z8(a9920273,2fbf0922,82ec5131,dd41abab,d53baeb9,7ffba57e,64757239,c11c919c) Z8(370159b6,d5a2d402,c7357931,4d69172c,0e17a3f7,77b67ec3,b0d6927e,11a5a9b7) Z8(60c951d8,32c8e705,fdb98ba8,2b7386cc,6e3e369f,a8325b8d,8fb6d774,af62cb7c) Z8(4bd894eb,d4e9b6d1,24482382,b1895ceb,7f2f16f7,2fb71700,1f631d03,bb62218f) Z8(4a4828f3,91b8b8cd,58df9fbd,d0b48247,68f3ffb1,31ab0386,416c483e,03476e6a) Z8(a08edf4a,83a73639,cba0219c,a9c8faab,c0bef870,36a7ad69,89a224cf,6e211e53) Z8(4ac30913,c49cd215,6aaedaa2,8dd4fb81,cab5251b,ce7603f5,12970d6b,05ffb806) },{ Z8(50c4fbd9,987ffac3,91340029,6817d2f3,4f283f8b,5382ddfe,e5ee4b7c,77c585e7) Z8(17a94e3c,33fd42c7,42f78ef4,cbc94418,3cf3dd2a,0b3fca9a,4c318654,3f898d48) Z8(8715b44b,d5877fe3,282afc50,955a1fc9,60b49dea,7dd4a4b6,79962b82,810a3dd1) Z8(0906771b,1ecd5874,6f08275c,1fbb6ec5,beb2eeef,c18b9bc0,36dd6378,4a538f42) Z8(563f3034,ff4d0a3f,9f73cbb7,cbdfae45,0191b1d4,f8381e14,3ce0716c,277c8641) Z8(ad3a299d,6bcf004b,cb4f55a2,faf0dd44,a82b3850,0080730f,d588a73b,2f96c0eb) Z8(85fce25f,8bd13b24,f9178912,00e41207,b92fe104,15963528,c6fe40f2,da514790) Z8(8f49d371,3bae1ff7,00edbf94,a18a4973,2ba1587b,57eae314,0ae1da80,36ea1c47) Z8(4ec42b4c,9f647ca4,0dcf02f6,cf49dba2,0125a7bc,941f852d,8c63593a,5f34d9cb) Z8(5e586512,920926bd,a51bbb64,c72cd960,77f6da1a,30a0c288,c2fb448f,27c00a5e) Z8(2a789f65,5db5b68c,e06704af,ba08a2fa,2054b0c2,84006e67,fe44b37f,8fc2e2c4) Z8(367d9c1c,7b63ffcc,18db755b,421adc93,7bf0bdb6,63b8d371,dfae3f69,9c120115) Z8(170094d0,491a1e40,2269ed58,009290df,4eb0358c,20bbabfc,19f4c72a,8d09c183) Z8(39ead666,f886c964,ef99f5d3,e6183b47,63edb2fe,72b5d327,17c5e6df,c241ad53) Z8(6e9b1003,39318494,964e1916,eef1130f,78559e7e,6917bc77,de1a46ba,335820d0) Z8(ed160381,a322e8ae,8456882a,12ce1be3,1f8a0067,44613164,b9a44bb7,e7a82de7) Z8(264e6ebe,9643837c,10b7e9aa,ff14c300,83a4de0d,5d0a42a0,0cc1db88,116d06e1) Z8(16e25ccb,b02d0983,c1f2745b,cfc148ba,1dfc186c,b7bcd1e4,1d3420e4,063faea6) },{ Z8(5f019016,219c1074,1df3e259,68b66bf5,f30042db,18b6bae4,49b1c96b,33bfecd3) Z8(31d441bb,1dd7e63b,a1b0399e,a89c90ce,d633b582,3332b363,ae0a26f4,efc9b074) Z8(d1a901f5,20d98a33,d91245d0,1ff97fb3,43e7156b,c32718db,539bc9f6,f4730630) Z8(513ce058,d6703257,98ec2a75,855d8040,c871b225,61167c6b,d62543d3,b118acfb) Z8(c6613515,0e7823f4,4c1401fb,79f2e305,5bed8ec4,2ae583f2,70cc463b,4d1869d0) Z8(9674c68f,422f492f,7ae9f885,fb9e1282,e11c5b4a,334f97be,5731e40c,76e32ab8) Z8(bd00ca18,d3a56e03,fbcf34c0,b6a076ca,242908c8,fd27746d,de278a43,96c2dfc7) Z8(b3d9dbdc,14ccd47f,8aaefbec,ec18d8ee,7e86ec4f,2898a6fa,7ec7064e,71c84305) Z8(4027d59d,aa54e477,df413ae8,e71195e5,ed06442e,bd505024,747425ef,0c31e0b6) Z8(f4274386,aa7a2d3f,69a9caed,29394477,ec7ecf4d,a824e8ab,abc8ba6d,02b38e18) Z8(3ee2c42b,aff3e7b9,1612edfc,3e9c21b8,8266076b,3498e402,10f4e41a,276c0bf5) Z8(d5a77fd6,1acfcad8,e71c4cc2,02e74438,bc106753,94716603,16b69f33,c7f503e5) Z8(ebe5c144,e88fe751,ad0c04e3,a8fe6592,718ff5cc,11a42234,abe6e6a0,a959ee2f) Z8(735be253,3ebc83db,d37814d4,14a109f5,aaaf16ab,0ab38c90,5bd39ee3,67aa8c30) Z8(f78b1f67,4eae3376,8c839fb9,5c16b554,590131bf,f461c39f,09e2443e,40cd0f54) Z8(5fd2a988,d91f27d7,d65b2e19,c136aca6,f480b68e,a0bee130,cea58b15,51cf3dbb) Z8(f8a5eabf,0f50389a,20c790a6,89dfac06,6d97eafb,418d65d8,9a930eee,99ba6cf8) Z8(d587b7fc,b334e186,95881d72,1acbf031,241d2edb,39b5f02a,64d8b567,067fa47e) },{ Z8(eec32fa3,7295d7f8,6c5436ca,fd98edd7,5f279989,e6d365c3,2849a72e,b18853ec) Z8(aede2557,5b09ea80,b2770abf,49a62223,9dab2720,fe50a0b1,151d5572,6ff00c47) Z8(1dda672f,97cab425,2f754b13,77acdb8a,cc18de68,193279be,1a1f08aa,96bd7d44) Z8(fd6a5457,f9041905,ab3e8a30,64a22282,2aeeb06b,9a81bbae,df87c710,070f729e) Z8(5db9eccc,4f11f5af,4c839d79,e86acff7,b1933f72,7532ca5e,b2370f41,7b2331f3) Z8(8245ce02,138468f7,58f2b3d2,b561ab3c,46cfe7a9,438d8a69,65574616,56e797ad) Z8(b38c9a6f,9a0ebaf0,8407b54f,78dd776f,08eb0645,71696a60,917b8fb0,943b438c) Z8(e492ceb3,a278e238,3d752242,75e57bbe,a75c76f5,3c2fa324,5e65aa1e,97216976) Z8(1ece6590,f29da766,79db2e1b,f11fff18,6102ca42,c134368f,afb1379c,6a166f02) Z8(5fdacb42,36796508,fc4968f0,3ffc0001,fdec7f58,c272233a,10750cba,f081c472) Z8(a9ef9cd4,40173012,37667b8e,c3c07752,d9817e04,54fa911c,0d063b35,47852285) Z8(2e5404a8,65d04d14,1f535d55,7b36210d,63f442a6,c988b08e,c45663f3,88dd8247) Z8(82ecddb3,e9bee6b8,5026b483,79fda580,b0ab361b,d4de84d7,0451d0c7,e9388786) Z8(4a6e210e,2eb8f836,413a53a1,7c045676,5c00d006,a0abf8bd,4efc21b6,e5f3f8f9) Z8(f5e5fc91,65e874e9,a60924bf,e5d0b7c1,31c1f0f1,d8a0caa7,60b47f9c,560b5d2d) Z8(98510280,ec7a0a8c,1fe55b20,51dcd4bf,ad72d7f3,ecb64828,3ab13479,169a05c0) Z8(aca003a4,9d5b12d9,94833f87,03563a2e,e19453ae,c1904a26,41b6eb9d,162da9b6) Z8(73d4c5db,f0baf8ef,4d90b4ab,86b2975c,67c365a9,5245904a,f12143d9,06bf9986) },{ Z8(eb73e32a,e9776273,dfc4212b,4fefe213,3444b97e,1151c398,61751a23,5e34df5c) Z8(d3c4e74a,3bb9e57e,6b44fc0b,ca31edfe,d2abd98a,23c6c3b4,b7d9ac57,7be543c3) Z8(39f923fe,76e35d5b,a1b40b94,2c20895f,57da5e81,484361c2,9a14a667,db44afb7) Z8(943d8629,eeada88a,debfd6f6,7b017751,c869b16f,a17a0077,6acc387f,5239b268) Z8(e5d484e8,dade4b16,3618096e,df71b5af,17af77dd,728f1230,8ca247f8,26555446) Z8(ec781f53,6677dae6,789a30e7,492b63b5,3461a0fa,90de1588,1451dd6f,de0722b2) Z8(649f781b,cd212c67,571c458f,ce2606a7,96004fda,dbd92fc4,990370ca,56e8361e) Z8(6dcabaa9,7d9eff18,80505c45,e12f637a,18c0fb65,67e6168c,29eca98d,e24bd478) Z8(2889c108,ff2782d0,d4e9d760,48eac1e3,55388d31,8eae9263,6d0b5a78,decc8d32) Z8(b0831db2,b1ae6c27,97a0e87b,69f654dc,e8607b43,18a71388,bbb98ef1,77084e9f) Z8(971438c0,31afbd9b,4f42e2b9,28d09d7a,274f6b0a,7894b09d,2bff7a65,ca308546) Z8(102329d1,bd6c0770,038ff935,ea17fd9c,3d1322b3,4ff9a1e5,ad96f958,941e3c41) Z8(852d74e1,10aaee12,a0fa4cc2,8ca46c05,ef91508d,1de68177,725c24ef,d76f9ee0) Z8(0b17be43,f9a89e76,3fbc02fa,d5d610a0,6d146eaa,96a67692,bb2c5dfb,d0bfb2d5) Z8(7d494f99,e01a7e5f,e618eeef,171b8ab6,d3bb7f1c,3b9819c6,a746ed67,909620dd) Z8(c463a76d,66c5bfa9,1953ea86,bb158401,57790b4d,542c01af,aa4b08a1,232e5f59) Z8(c468bf81,d7aa9735,a501ca08,8750f3a2,175e84fc,c64cbc9c,549887da,63253408) Z8(02ffdb3c,9aaafeff,6171a4ba,cb479a5c,f7f8cafc,f209c454,ca45c470,06ff8db7) },{ Z8(fc4ac5fc,068a1d4b,e7049be7,9e8686d1,67fa6559,1b1a7430,c5725f5a,88b5a43a) Z8(6ba88cab,1061ddde,7abbf96a,bc61a48c,1b161929,134ef839,344406c9,4702ba7f) Z8(4e50ff7f,a4729a23,0ba4538c,9d29e633,c896074c,312bd5a0,f6b23bb3,1af31896) Z8(762d056a,7954f5f7,e583facd,7bc92fb1,dd28d540,da7b8091,d0d0158b,a77bb664) Z8(973ec44f,94c743bc,78ea7125,52dbf317,be6f2c40,e42c0e89,899f43a1,124da656) Z8(65b5095f,8b37a110,43139bb6,2700fe0b,fb8447fe,60ea6372,550abc21,6ba87095) Z8(382c25f4,13b6646c,ec480554,f4e5a689,3c8f61ab,c63ede62,48dd4bdd,37620db5) Z8(682104f5,16a89707,5cc2d0a0,60655c96,e86671e0,14131f98,0bfe8664,d1445ccb) Z8(d2ba7764,4c260093,845177ca,4dc6c4da,d3a9c6c4,f450d21c,6960ced8,100af5a6) Z8(198d2b7f,9972dda6,5e457bd4,8f747d9f,ec467303,105ded70,3dc55218,992e2c54) Z8(c287bc3d,e21f7b82,c1989272,c2932c7c,09dc4949,272dc3cf,54045353,f6844f01) Z8(b62a653a,ea7314a6,30792202,d0117905,69f5e4c4,d174554e,b27947f0,bf0b8fa8) Z8(1f672cff,5a5a66b2,58542a57,b024ad3a,a7da2f0e,abc553a7,220efca2,4a2dc1ec) Z8(6b93e3a2,21efe994,f0a50664,d822ca7e,9e234b54,fd987f45,f358709f,a4645c46) Z8(12fb69d1,a074e864,f5399d0d,36213cf7,d3db347c,4695fde3,7db6946f,43bef286) Z8(82965bdb,e42a8399,1f6ee879,e23822d4,400f6435,e6e7ba12,c0cd3bea,5733d623) Z8(807ea90d,ba5c03fc,3cc6598b,2c56337d,887b3d84,5a362872,3e8ce8d1,dc455f1c) Z8(3e99f474,74d31e56,33106f77,93b78b49,7f3c8f18,d9b0abfd,f91f9f4f,073f8108) },{ Z8(e7768546,d74b0c38,8251b4dd,a3a0021b,c0f2d4e3,25fd4030,af99c465,1a541fb5) Z8(1fe3a6f9,f864581a,6f34419f,c09a089c,c3120e69,304c41cd,3a4c10bd,b544dd56) Z8(7b1fdf28,4861b8e2,7865b5f6,4dbddef9,48fcd5c4,43eba614,00a6308d,fe490ed0) Z8(cb94bf89,b2f34afd,cf05479d,52e4df18,ebd578f0,79cae900,7a3b99e1,b1da613c) Z8(908f6e6a,593f60a9,f3e84abc,71819373,da7642f6,d94fd3eb,244f3d42,7e181c67) Z8(f2038dd9,920d5ed8,2b15048a,9638be57,dc48f01e,537a62d8,44727a6c,64c70c44) Z8(b016a924,04413454,906c5231,4f80ba6b,33dc9142,0b2bc661,2c2aba75,d3f44dc8) Z8(a142473b,d0d9e1c9,8f2b72aa,18b99743,b4147915,e71c88ad,5dc8d7e3,94702d94) Z8(d701b66f,7f2d2ec2,77fd5cdc,9e363121,1e999424,c25b82bf,b6ea8d97,cec7824f) Z8(4793a956,e42cf060,ae488c61,c1155744,7d36f600,ef040a05,a7ecb775,3dd6eb7d) Z8(3e6589f3,6a2a5328,e037fa8a,88375d37,3f7db920,a629ae86,0c453efd,8de464e2) Z8(8b5fb864,45b166de,5e3c8c5c,a4caa98a,50b1c488,62688239,0ef01fd6,e001e459) Z8(594f14a8,b2448a61,0630eec3,47bbc1d8,4409ac6c,33c3f641,dea86bad,5a677af4) Z8(328076d8,c7bc28bb,710493c1,dc9246b2,a2a5513f,607c7e1e,62770d2c,1b53196e) Z8(ccdb79ee,2c51ff40,e17423e5,2a81eeae,9b6efa75,1a348e97,2558c9b7,67e7fdf7) Z8(fc969415,2ae52e85,b0cdac18,8e382878,317a599c,60e4cf68,db12349e,ca802f7a) Z8(f49319e8,9628d9c7,1dcade2d,524f9ef3,7100c8f7,b2c591c7,035e6af4,f6c92c85) Z8(ba400398,fad0ec5b,9e27e419,23db8ae7,eaf583f9,af541bee,872f9bf1,077f7372) },{ Z8(926247b6,5986f7dc,1a33a430,031ee945,3e7c1aa5,7fb85212,4b38a11c,f8fdf1a7) Z8(44f79c13,5a959041,a6b5d13d,fd7b000b,ba52d82d,842cbeaf,3250ea36,dda8f0ab) Z8(8ca884f5,80a630cc,2e7c90f8,62974711,d0aad592,05539fef,985273e8,f8215946) Z8(9080d4f3,afe6c0c8,1ac44ee8,479a2857,6a0d0a6a,2841bed2,fed2c5ce,15356cf0) Z8(0045008c,4ef171bc,1d6c9a2a,6b1bfbb8,8018a487,bd45a564,ab29f3cc,48f658af) Z8(56dafb27,d23bb071,9692c8fa,1c3f0d96,02628bbe,1a22f673,b5f911d4,9ff8a20e) Z8(673a54e6,7081f071,9d54449f,9735bd88,e2b036bc,c67d3643,625aa681,0d82bc9e) Z8(67297f43,c53dc131,c8608cb5,cc5a667d,1d452aac,6d3b7967,dbd6237b,02f02562) Z8(76beb762,673dfdf3,a7e9852b,06042cbf,954b3dae,6d10cdff,18187b9c,0e0d45ba) Z8(66bd6bb3,d8bc2e3a,5bead3f8,c3cf5108,a11d1999,a8e3926b,a3ccb7fd,92aa6555) Z8(179479eb,4dcc5c8c,56f25b9a,44efaad9,c25d383d,a991f8da,feb85f9c,879051cf) Z8(4a2d4607,e85ada87,0cc7e524,f9a9a5bf,9d12510c,e8fabc46,62dbf5f8,3945f05e) Z8(7f5cc6c4,59a15b94,9469a706,8a35d84b,4330e8f3,ecf9e02c,b1c0e63d,87123d46) Z8(85249d47,bdbb7177,e4c16c79,c50d545c,5569cd8a,abf8b1f1,c9cfb824,8df4cb9e) Z8(86785dbd,a36963e6,9d6c1eb0,df75e90d,43d8a56a,d49b651c,4b091a9f,14d4f048) Z8(3ddcfa3d,5e3fceb7,be08f27a,b3c09fac,73b1ef47,c96e2715,e6a83ed5,596e4d23) Z8(bd5dd2e7,67fc724d,5ebae2bf,d635b446,682bf0ac,3da7f72b,901bb0d0,7fd76470) Z8(1016ad6e,9f4ebac7,26604410,67555f4a,07bc06ce,45be4112,7ea3cf61,07bf64ec) }}; arb-2.22.1/arb/atan_taylor_naive.c000066400000000000000000000035021417376376500167740ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_atan_taylor_naive(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int alternating) { ulong k; mp_ptr s, t, x1, x2, u; mp_size_t nn = xn + 1; if (N == 0) { flint_mpn_zero(y, xn); error[0] = 0; return; } if (N == 1) { flint_mpn_copyi(y, x, xn); error[0] = 0; } s = flint_malloc(sizeof(mp_limb_t) * nn); t = flint_malloc(sizeof(mp_limb_t) * nn); u = flint_malloc(sizeof(mp_limb_t) * 2 * nn); x1 = flint_malloc(sizeof(mp_limb_t) * nn); x2 = flint_malloc(sizeof(mp_limb_t) * nn); flint_mpn_zero(s, nn); flint_mpn_zero(t, nn); flint_mpn_zero(u, 2 * nn); flint_mpn_zero(x1, nn); flint_mpn_zero(x2, nn); /* x1 = x */ flint_mpn_copyi(x1 + 1, x, xn); /* x2 = x * x */ mpn_mul_n(u, x1, x1, nn); flint_mpn_copyi(x2, u + nn, nn); /* s = t = x */ flint_mpn_copyi(s, x1, nn); flint_mpn_copyi(t, x1, nn); for (k = 1; k < N; k++) { /* t = t * x2 */ mpn_mul_n(u, t, x2, nn); flint_mpn_copyi(t, u + nn, nn); /* u = t / (2k+1) */ mpn_divrem_1(u, 0, t, nn, 2 * k + 1); if (alternating & k) mpn_sub_n(s, s, u, nn); else mpn_add_n(s, s, u, nn); } flint_mpn_copyi(y, s + 1, xn); error[0] = 2; flint_free(s); flint_free(t); flint_free(u); flint_free(x1); flint_free(x2); } arb-2.22.1/arb/atan_taylor_rs.c000066400000000000000000000714701417376376500163270ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* See verify_taylor.py for code to generate tables and proof of correctness */ #define TMP_ALLOC_LIMBS(size) TMP_ALLOC((size) * sizeof(mp_limb_t)) #define ODD_RECIPROCAL_TAB_SIZE 256 #if FLINT_BITS == 64 const mp_limb_t odd_reciprocal_tab_numer[ODD_RECIPROCAL_TAB_SIZE] = { UWORD(13835020108241056725), UWORD(4611673369413685575), UWORD(2767004021648211345), UWORD(1976431444034436675), UWORD(1537224456471228525), UWORD(1257729100749186975), UWORD(1064232316018542825), UWORD(922334673882737115), UWORD(813824712249473925), UWORD(728158953065318775), UWORD(658810481344812225), UWORD(601522613401785075), UWORD(553400804329642269), UWORD(512408152157076175), UWORD(477069658904864025), UWORD(446290971233582475), UWORD(419243033583062325), UWORD(395286288806887335), UWORD(373919462384893425), UWORD(354744105339514275), UWORD(337439514835147725), UWORD(321744653680024575), UWORD(307444891294245705), UWORD(294362129962575675), UWORD(43378025254434585), UWORD(41676926224848915), UWORD(40104212027684805), UWORD(38645877044859903), UWORD(37289881359075345), UWORD(36025817584191435), UWORD(34844643237168765), UWORD(33738464086782455), UWORD(32700357499496841), UWORD(31724227424884995), UWORD(30804684600975285), UWORD(29936947006581615), UWORD(18078521432946975), UWORD(17596427528068389), UWORD(17139377462404275), UWORD(16705469172216825), UWORD(16292988451915175), UWORD(15900386320543725), UWORD(15526259583589755), UWORD(15169334075921025), UWORD(14828450164102575), UWORD(14502550160495925), UWORD(14190667361345475), UWORD(34099971069969189), UWORD(33396878882959515), UWORD(32722194461081545), UWORD(32074230214327455), UWORD(31451429627641485), UWORD(30852354777591171), UWORD(30275675249038065), UWORD(29720158271991495), UWORD(29184659924748405), UWORD(28668117271213035), UWORD(70414222249896525), UWORD(69210560331094875), UWORD(68047357636454625), UWORD(66922607923455375), UWORD(65834435436895125), UWORD(64781084469904803), UWORD(63760909911323625), UWORD(62772368672388375), UWORD(61814011898764125), UWORD(60884477885248875), UWORD(59982485620282225), UWORD(22849011931010265), UWORD(22520249169412995), UWORD(22200813010981605), UWORD(21890312129709135), UWORD(21588376789989009), UWORD(21294657377880315), UWORD(21008823050660445), UWORD(20730560493698055), UWORD(20459572774826185), UWORD(11592603279646389), UWORD(11444926804746435), UWORD(11300965461290505), UWORD(11160580797175095), UWORD(11023641155491965), UWORD(10890021262698123), UWORD(10759601846378385), UWORD(10632269280149055), UWORD(10507915253480645), UWORD(3812050066792275), UWORD(3768483780314649), UWORD(3725902042683975), UWORD(3684271852262925), UWORD(3643561666050075), UWORD(3603741319973025), UWORD(3564781954351695), UWORD(3526655944144725), UWORD(3489336833624675), UWORD(56769492397408245), UWORD(56181207502098315), UWORD(55604989989256281), UWORD(55040472324390735), UWORD(54487301748266205), UWORD(53945139541815795), UWORD(53413660334507265), UWORD(52892551453194999), UWORD(52381512308719685), UWORD(7543627748528235), UWORD(7472124167973465), UWORD(7401963377663855), UWORD(7333107904383261), UWORD(7265521656416595), UWORD(7199169860467585), UWORD(7134019002001815), UWORD(7070036768800005), UWORD(827619730851221), UWORD(820327927055175), UWORD(813163491011025), UWORD(806123114465475), UWORD(799203602753325), UWORD(792401869963935), UWORD(785714934352425), UWORD(779139913981275), UWORD(1317621181161285), UWORD(1306776562386295), UWORD(1296108998611713), UWORD(1285614188906355), UWORD(1275287970521565), UWORD(1265126313385935), UWORD(1255125314861145), UWORD(1245281194744587), UWORD(30567046059275355), UWORD(30331007093566665), UWORD(30098585583271135), UWORD(29869699000888845), UWORD(29644267310316099), UWORD(29422212873534705), UWORD(29203460361463815), UWORD(28987936668759285), UWORD(438859621842675), UWORD(435667915502001), UWORD(432522298783575), UWORD(429421780512725), UWORD(426365397733275), UWORD(423352214710425), UWORD(420381321975615), UWORD(417451835411325), UWORD(22634811266652585), UWORD(22479245553479715), UWORD(22325803604309205), UWORD(22174442223941007), UWORD(22025119380682145), UWORD(21877794167433435), UWORD(21732426764327565), UWORD(21588978402846855), UWORD(19609694213279247), UWORD(19481943762378405), UWORD(19355847038997315), UWORD(19231372138424985), UWORD(19108487971406295), UWORD(18987164238254509), UWORD(18867371403943755), UWORD(18749080674138465), UWORD(9266890993958325), UWORD(9209510863964775), UWORD(9152836950955761), UWORD(9096856296821475), UWORD(9041556258542925), UWORD(8986924498672575), UWORD(8932948976158025), UWORD(8879617937494395), UWORD(552205768818165), UWORD(548947917674695), UWORD(545728281793905), UWORD(542546192687235), UWORD(539400997367309), UWORD(536292057901215), UWORD(533218750979145), UWORD(17071036886667995), UWORD(16974317130936165), UWORD(16878687175268919), UWORD(16784128703698785), UWORD(16690623808413555), UWORD(16598154978450045), UWORD(16506705088761615), UWORD(16416257389645113), UWORD(912010168967625), UWORD(907067024420375), UWORD(902177175232125), UWORD(897339764104875), UWORD(892553952029649), UWORD(887818917801375), UWORD(883133857549125), UWORD(29941527972993945), UWORD(29785175346503115), UWORD(29630447162884917), UWORD(29477318236978535), UWORD(29325763901569905), UWORD(29175759994144995), UWORD(29027282844047565), UWORD(28880309260027071), UWORD(1449018065980485), UWORD(1441754817529455), UWORD(1434564020434545), UWORD(1427444596015515), UWORD(1420395486899389), UWORD(1413415656496935), UWORD(1406504088494505), UWORD(592554335551395), UWORD(589684823030565), UWORD(586842968461743), UWORD(584028373888785), UWORD(581240648953755), UWORD(578479410716445), UWORD(575744283479015), UWORD(433241218467057), UWORD(431211985593675), UWORD(429201673306525), UWORD(427210018209975), UWORD(425236761774825), UWORD(423281650226435), UWORD(421344434435925), UWORD(2623079648743785), UWORD(2611183595915015), UWORD(2599394956655805), UWORD(2587712282693307), UWORD(2576134151674545), UWORD(2564659166589135), UWORD(2553285955207365), UWORD(210505107582315), UWORD(209579810406129), UWORD(208662612111135), UWORD(207753406829605), UWORD(206852090530995), UWORD(205958560982265), UWORD(205072717709223), UWORD(3779907202434825), UWORD(3763788195174975), UWORD(3747806079696525), UWORD(3731959119528675), UWORD(3716245607446449), UWORD(3700663864857575), UWORD(3685212241204725), UWORD(4501257379467765), UWORD(4482618632554855), UWORD(4464133607265969), UWORD(4445800409700195), UWORD(4427617176940685), UWORD(4409582076423615), UWORD(4391693305322505), UWORD(355589942551207), UWORD(354158997108345), UWORD(352739522170035), UWORD(351331380364965), UWORD(349934436506655), UWORD(348548557550193), UWORD(347173612549995), UWORD(6291002587483845), UWORD(6266380268159055), }; const mp_limb_t odd_reciprocal_tab_denom[ODD_RECIPROCAL_TAB_SIZE] = { UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(13835020108241056725), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(2125523237467294665), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(1319732064605129175), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(3239497251647072955), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(8097635558738100375), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(3130314634548406305), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(1796853508345190295), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(659484661555063575), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(10842973047904974795), UWORD(1576618199442401115), UWORD(1576618199442401115), UWORD(1576618199442401115), UWORD(1576618199442401115), UWORD(1576618199442401115), UWORD(1576618199442401115), UWORD(1576618199442401115), UWORD(1576618199442401115), UWORD(186214439441524725), UWORD(186214439441524725), UWORD(186214439441524725), UWORD(186214439441524725), UWORD(186214439441524725), UWORD(186214439441524725), UWORD(186214439441524725), UWORD(186214439441524725), UWORD(317546704659869685), UWORD(317546704659869685), UWORD(317546704659869685), UWORD(317546704659869685), UWORD(317546704659869685), UWORD(317546704659869685), UWORD(317546704659869685), UWORD(317546704659869685), UWORD(7855730837233766235), UWORD(7855730837233766235), UWORD(7855730837233766235), UWORD(7855730837233766235), UWORD(7855730837233766235), UWORD(7855730837233766235), UWORD(7855730837233766235), UWORD(7855730837233766235), UWORD(119808676763050275), UWORD(119808676763050275), UWORD(119808676763050275), UWORD(119808676763050275), UWORD(119808676763050275), UWORD(119808676763050275), UWORD(119808676763050275), UWORD(119808676763050275), UWORD(6541460456062597065), UWORD(6541460456062597065), UWORD(6541460456062597065), UWORD(6541460456062597065), UWORD(6541460456062597065), UWORD(6541460456062597065), UWORD(6541460456062597065), UWORD(6541460456062597065), UWORD(5980956735050170335), UWORD(5980956735050170335), UWORD(5980956735050170335), UWORD(5980956735050170335), UWORD(5980956735050170335), UWORD(5980956735050170335), UWORD(5980956735050170335), UWORD(5980956735050170335), UWORD(2974672009060622325), UWORD(2974672009060622325), UWORD(2974672009060622325), UWORD(2974672009060622325), UWORD(2974672009060622325), UWORD(2974672009060622325), UWORD(2974672009060622325), UWORD(2974672009060622325), UWORD(186093344091721605), UWORD(186093344091721605), UWORD(186093344091721605), UWORD(186093344091721605), UWORD(186093344091721605), UWORD(186093344091721605), UWORD(186093344091721605), UWORD(5991933947220466245), UWORD(5991933947220466245), UWORD(5991933947220466245), UWORD(5991933947220466245), UWORD(5991933947220466245), UWORD(5991933947220466245), UWORD(5991933947220466245), UWORD(5991933947220466245), UWORD(334707732011118375), UWORD(334707732011118375), UWORD(334707732011118375), UWORD(334707732011118375), UWORD(334707732011118375), UWORD(334707732011118375), UWORD(334707732011118375), UWORD(11407722157710693045), UWORD(11407722157710693045), UWORD(11407722157710693045), UWORD(11407722157710693045), UWORD(11407722157710693045), UWORD(11407722157710693045), UWORD(11407722157710693045), UWORD(11407722157710693045), UWORD(575260172194252545), UWORD(575260172194252545), UWORD(575260172194252545), UWORD(575260172194252545), UWORD(575260172194252545), UWORD(575260172194252545), UWORD(575260172194252545), UWORD(243539831911623345), UWORD(243539831911623345), UWORD(243539831911623345), UWORD(243539831911623345), UWORD(243539831911623345), UWORD(243539831911623345), UWORD(243539831911623345), UWORD(184127517848499225), UWORD(184127517848499225), UWORD(184127517848499225), UWORD(184127517848499225), UWORD(184127517848499225), UWORD(184127517848499225), UWORD(184127517848499225), UWORD(1151531965798521615), UWORD(1151531965798521615), UWORD(1151531965798521615), UWORD(1151531965798521615), UWORD(1151531965798521615), UWORD(1151531965798521615), UWORD(1151531965798521615), UWORD(95358813734788695), UWORD(95358813734788695), UWORD(95358813734788695), UWORD(95358813734788695), UWORD(95358813734788695), UWORD(95358813734788695), UWORD(95358813734788695), UWORD(1765216663537063275), UWORD(1765216663537063275), UWORD(1765216663537063275), UWORD(1765216663537063275), UWORD(1765216663537063275), UWORD(1765216663537063275), UWORD(1765216663537063275), UWORD(2165104799523994965), UWORD(2165104799523994965), UWORD(2165104799523994965), UWORD(2165104799523994965), UWORD(2165104799523994965), UWORD(2165104799523994965), UWORD(2165104799523994965), UWORD(176017021562847465), UWORD(176017021562847465), UWORD(176017021562847465), UWORD(176017021562847465), UWORD(176017021562847465), UWORD(176017021562847465), UWORD(176017021562847465), UWORD(3202120317029277105), UWORD(3202120317029277105), }; #else const mp_limb_t odd_reciprocal_tab_numer[ODD_RECIPROCAL_TAB_SIZE] = { UWORD(1673196525), UWORD(557732175), UWORD(334639305), UWORD(239028075), UWORD(185910725), UWORD(152108775), UWORD(128707425), UWORD(111546435), UWORD(98423325), UWORD(88062975), UWORD(79676025), UWORD(72747675), UWORD(66927861), UWORD(12806255), UWORD(11923065), UWORD(11153835), UWORD(10477845), UWORD(9879111), UWORD(9345105), UWORD(60902835), UWORD(57931965), UWORD(55237455), UWORD(52782457), UWORD(50536395), UWORD(48473685), UWORD(3267715), UWORD(3144405), UWORD(3030063), UWORD(2923745), UWORD(2824635), UWORD(6310395), UWORD(6110065), UWORD(5922063), UWORD(5745285), UWORD(5578755), UWORD(33304425), UWORD(32391975), UWORD(31528189), UWORD(30709275), UWORD(29931825), UWORD(18208955), UWORD(17770185), UWORD(17352063), UWORD(16953165), UWORD(16572195), UWORD(28280835), UWORD(27672645), UWORD(27090063), UWORD(26531505), UWORD(25995515), UWORD(1157205), UWORD(1134735), UWORD(1113121), UWORD(1092315), UWORD(1442445), UWORD(1416455), UWORD(1391385), UWORD(1367187), UWORD(590359), UWORD(580437), UWORD(570843), UWORD(561561), UWORD(2146173), UWORD(2112375), UWORD(2079625), UWORD(2047875), UWORD(2570805), UWORD(2532719), UWORD(2495745), UWORD(2459835), UWORD(1016015), UWORD(1001805), UWORD(987987), UWORD(974545), UWORD(3580965), UWORD(3533535), UWORD(3487345), UWORD(3442347), UWORD(4172637), UWORD(4120151), UWORD(4068969), UWORD(4019043), UWORD(1608711), UWORD(1589445), UWORD(1570635), UWORD(1552265), UWORD(5544525), UWORD(5481159), UWORD(5419225), UWORD(5358675), UWORD(6330885), UWORD(6261695), UWORD(6194001), UWORD(6127755), UWORD(2396095), UWORD(2371005), UWORD(2346435), UWORD(2322369), UWORD(8119797), UWORD(8038191), UWORD(7958209), UWORD(7879803), UWORD(9128493), UWORD(9040295), UWORD(8953785), UWORD(8868915), UWORD(3405815), UWORD(3374133), UWORD(3343035), UWORD(3312505), UWORD(11389725), UWORD(11287575), UWORD(11187241), UWORD(11088675), UWORD(12648405), UWORD(12538895), UWORD(12431265), UWORD(12325467), UWORD(4665519), UWORD(4626477), UWORD(4588083), UWORD(4550321), UWORD(15437253), UWORD(15312255), UWORD(15189265), UWORD(15068235), UWORD(16973565), UWORD(16840439), UWORD(16709385), UWORD(16580355), UWORD(6202855), UWORD(6155685), UWORD(6109227), UWORD(6063465), UWORD(73983), UWORD(73437), UWORD(72899), UWORD(77283), UWORD(76725), UWORD(76175), UWORD(80655), UWORD(80085), UWORD(79523), UWORD(84099), UWORD(83517), UWORD(82943), UWORD(87615), UWORD(87021), UWORD(86435), UWORD(91203), UWORD(90597), UWORD(89999), UWORD(94863), UWORD(94245), UWORD(93635), UWORD(98595), UWORD(97965), UWORD(97343), UWORD(102399), UWORD(101757), UWORD(101123), UWORD(106275), UWORD(105621), UWORD(104975), UWORD(110223), UWORD(109557), UWORD(108899), UWORD(114243), UWORD(113565), UWORD(112895), UWORD(118335), UWORD(117645), UWORD(116963), UWORD(122499), UWORD(121797), UWORD(121103), UWORD(126735), UWORD(126021), UWORD(125315), UWORD(131043), UWORD(130317), UWORD(129599), UWORD(135423), UWORD(134685), UWORD(133955), UWORD(139875), UWORD(139125), UWORD(138383), UWORD(144399), UWORD(143637), UWORD(142883), UWORD(148995), UWORD(148221), UWORD(147455), UWORD(153663), UWORD(152877), UWORD(152099), UWORD(158403), UWORD(157605), UWORD(156815), UWORD(163215), UWORD(162405), UWORD(161603), UWORD(168099), UWORD(167277), UWORD(166463), UWORD(173055), UWORD(172221), UWORD(171395), UWORD(178083), UWORD(177237), UWORD(176399), UWORD(183183), UWORD(182325), UWORD(181475), UWORD(188355), UWORD(187485), UWORD(186623), UWORD(193599), UWORD(192717), UWORD(191843), UWORD(198915), UWORD(198021), UWORD(197135), UWORD(204303), UWORD(203397), UWORD(202499), UWORD(209763), UWORD(208845), UWORD(207935), UWORD(215295), UWORD(214365), UWORD(213443), UWORD(220899), UWORD(219957), UWORD(219023), UWORD(226575), UWORD(225621), UWORD(224675), UWORD(232323), UWORD(231357), UWORD(230399), UWORD(238143), UWORD(237165), UWORD(236195), UWORD(244035), UWORD(243045), UWORD(242063), UWORD(249999), UWORD(248997), UWORD(248003), UWORD(256035), UWORD(255021), UWORD(254015), UWORD(262143), UWORD(261117), }; const mp_limb_t odd_reciprocal_tab_denom[ODD_RECIPROCAL_TAB_SIZE] = { UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(1673196525), UWORD(345768885), UWORD(345768885), UWORD(345768885), UWORD(345768885), UWORD(345768885), UWORD(345768885), UWORD(2375210565), UWORD(2375210565), UWORD(2375210565), UWORD(2375210565), UWORD(2375210565), UWORD(2375210565), UWORD(166653465), UWORD(166653465), UWORD(166653465), UWORD(166653465), UWORD(166653465), UWORD(384934095), UWORD(384934095), UWORD(384934095), UWORD(384934095), UWORD(384934095), UWORD(2364614175), UWORD(2364614175), UWORD(2364614175), UWORD(2364614175), UWORD(2364614175), UWORD(1474925355), UWORD(1474925355), UWORD(1474925355), UWORD(1474925355), UWORD(1474925355), UWORD(2573555985), UWORD(2573555985), UWORD(2573555985), UWORD(2573555985), UWORD(2573555985), UWORD(116877705), UWORD(116877705), UWORD(116877705), UWORD(116877705), UWORD(157226505), UWORD(157226505), UWORD(157226505), UWORD(157226505), UWORD(69072003), UWORD(69072003), UWORD(69072003), UWORD(69072003), UWORD(268271625), UWORD(268271625), UWORD(268271625), UWORD(268271625), UWORD(341917065), UWORD(341917065), UWORD(341917065), UWORD(341917065), UWORD(143258115), UWORD(143258115), UWORD(143258115), UWORD(143258115), UWORD(533563785), UWORD(533563785), UWORD(533563785), UWORD(533563785), UWORD(655104009), UWORD(655104009), UWORD(655104009), UWORD(655104009), UWORD(265437315), UWORD(265437315), UWORD(265437315), UWORD(265437315), UWORD(959202825), UWORD(959202825), UWORD(959202825), UWORD(959202825), UWORD(1145890185), UWORD(1145890185), UWORD(1145890185), UWORD(1145890185), UWORD(452861955), UWORD(452861955), UWORD(452861955), UWORD(452861955), UWORD(1599600009), UWORD(1599600009), UWORD(1599600009), UWORD(1599600009), UWORD(1871341065), UWORD(1871341065), UWORD(1871341065), UWORD(1871341065), UWORD(725438595), UWORD(725438595), UWORD(725438595), UWORD(725438595), UWORD(2517129225), UWORD(2517129225), UWORD(2517129225), UWORD(2517129225), UWORD(2896484745), UWORD(2896484745), UWORD(2896484745), UWORD(2896484745), UWORD(1105728003), UWORD(1105728003), UWORD(1105728003), UWORD(1105728003), UWORD(3782126985), UWORD(3782126985), UWORD(3782126985), UWORD(3782126985), UWORD(4294311945), UWORD(4294311945), UWORD(4294311945), UWORD(4294311945), UWORD(1618945155), UWORD(1618945155), UWORD(1618945155), UWORD(1618945155), UWORD(19901427), UWORD(19901427), UWORD(19901427), UWORD(21252825), UWORD(21252825), UWORD(21252825), UWORD(22664055), UWORD(22664055), UWORD(22664055), UWORD(24136413), UWORD(24136413), UWORD(24136413), UWORD(25671195), UWORD(25671195), UWORD(25671195), UWORD(27269697), UWORD(27269697), UWORD(27269697), UWORD(28933215), UWORD(28933215), UWORD(28933215), UWORD(30663045), UWORD(30663045), UWORD(30663045), UWORD(32460483), UWORD(32460483), UWORD(32460483), UWORD(34326825), UWORD(34326825), UWORD(34326825), UWORD(36263367), UWORD(36263367), UWORD(36263367), UWORD(38271405), UWORD(38271405), UWORD(38271405), UWORD(40352235), UWORD(40352235), UWORD(40352235), UWORD(42507153), UWORD(42507153), UWORD(42507153), UWORD(44737455), UWORD(44737455), UWORD(44737455), UWORD(47044437), UWORD(47044437), UWORD(47044437), UWORD(49429395), UWORD(49429395), UWORD(49429395), UWORD(51893625), UWORD(51893625), UWORD(51893625), UWORD(54438423), UWORD(54438423), UWORD(54438423), UWORD(57065085), UWORD(57065085), UWORD(57065085), UWORD(59774907), UWORD(59774907), UWORD(59774907), UWORD(62569185), UWORD(62569185), UWORD(62569185), UWORD(65449215), UWORD(65449215), UWORD(65449215), UWORD(68416293), UWORD(68416293), UWORD(68416293), UWORD(71471715), UWORD(71471715), UWORD(71471715), UWORD(74616777), UWORD(74616777), UWORD(74616777), UWORD(77852775), UWORD(77852775), UWORD(77852775), UWORD(81181005), UWORD(81181005), UWORD(81181005), UWORD(84602763), UWORD(84602763), UWORD(84602763), UWORD(88119345), UWORD(88119345), UWORD(88119345), UWORD(91732047), UWORD(91732047), UWORD(91732047), UWORD(95442165), UWORD(95442165), UWORD(95442165), UWORD(99250995), UWORD(99250995), UWORD(99250995), UWORD(103159833), UWORD(103159833), UWORD(103159833), UWORD(107169975), UWORD(107169975), UWORD(107169975), UWORD(111282717), UWORD(111282717), UWORD(111282717), UWORD(115499355), UWORD(115499355), UWORD(115499355), UWORD(119821185), UWORD(119821185), UWORD(119821185), UWORD(124249503), UWORD(124249503), UWORD(124249503), UWORD(128785605), UWORD(128785605), UWORD(128785605), UWORD(133430787), UWORD(133430787), }; #endif void _arb_atan_taylor_rs(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int alternating) { mp_ptr s, t, xpow; mp_limb_t new_denom, old_denom, c; slong power, k, m; TMP_INIT; TMP_START; if (N >= ODD_RECIPROCAL_TAB_SIZE) { flint_printf("_arb_atan_taylor_rs: N too large!\n"); flint_abort(); } if (N <= 2) { if (N == 0) { flint_mpn_zero(y, xn); error[0] = 0; } else if (N == 1) { flint_mpn_copyi(y, x, xn); error[0] = 0; } else { t = TMP_ALLOC_LIMBS(3 * xn); /* x * (1 - x^2 / 3) */ /* higher index ---> */ /* t = | | x^2 (lo) | x^2 (hi) | */ mpn_sqr(t + xn, x, xn); /* t = | x^3 (lo) | x^3 (hi) | x^2 (hi) | */ mpn_mul_n(t, t + 2 * xn, x, xn); /* y = x - x^3 / 3 */ mpn_divrem_1(t, 0, t + xn, xn, 3); if (alternating) mpn_sub_n(y, x, t, xn); else mpn_add_n(y, x, t, xn); error[0] = 3; } } else { /* Choose m ~= sqrt(num_terms) (m must be even, >= 2) */ m = 2; while (m * m < N) m += 2; /* todo: merge allocations */ xpow = TMP_ALLOC_LIMBS((m + 1) * xn); s = TMP_ALLOC_LIMBS(xn + 2); t = TMP_ALLOC_LIMBS(2 * xn + 2); /* todo: 1 limb too much? */ /* higher index ---> */ /* | ---xn--- | */ /* xpow = | | (x^2)^m | (x^2)^(m-1) | ... | (x^2)^2 | x^2 | */ #define XPOW_WRITE(__k) (xpow + (m - (__k)) * xn) #define XPOW_READ(__k) (xpow + (m - (__k) + 1) * xn) mpn_sqr(XPOW_WRITE(1), x, xn); mpn_sqr(XPOW_WRITE(2), XPOW_READ(1), xn); for (k = 4; k <= m; k += 2) { mpn_mul_n(XPOW_WRITE(k - 1), XPOW_READ(k / 2), XPOW_READ(k / 2 - 1), xn); mpn_sqr(XPOW_WRITE(k), XPOW_READ(k / 2), xn); } flint_mpn_zero(s, xn + 1); /* todo: skip one nonscalar multiplication (use x^m) when starting on x^0 */ power = (N - 1) % m; for (k = N - 1; k >= 0; k--) { c = odd_reciprocal_tab_numer[k]; new_denom = odd_reciprocal_tab_denom[k]; old_denom = odd_reciprocal_tab_denom[k+1]; /* change denominators */ if (new_denom != old_denom && k < N - 1) { /* hack when s is negative: add 1 to get a positive number */ if (alternating && (k % 2 == 0)) s[xn] += old_denom; /* multiply by new denominator */ s[xn + 1] = mpn_mul_1(s, s, xn + 1, new_denom); /* divide by old denominator */ mpn_divrem_1(s, 0, s, xn + 2, old_denom); if (s[xn + 1] != 0) { flint_printf("bad division!\n"); flint_abort(); } /* subtract 1 */ if (alternating && (k % 2 == 0)) s[xn] -= new_denom; } if (power == 0) { /* sub/add c * x^0 -- only top limb is affected */ if (alternating & k) s[xn] -= c; else s[xn] += c; /* Outer polynomial evaluation: multiply by (x^2)^m */ if (k != 0) { mpn_mul(t, s, xn + 1, XPOW_READ(m), xn); flint_mpn_copyi(s, t + xn, xn + 1); } power = m - 1; } else { if (alternating & k) s[xn] -= mpn_submul_1(s, XPOW_READ(power), xn, c); else s[xn] += mpn_addmul_1(s, XPOW_READ(power), xn, c); power--; } } /* finally divide by denominator and multiply by x */ mpn_divrem_1(s, 0, s, xn + 1, odd_reciprocal_tab_denom[0]); mpn_mul(t, s, xn + 1, x, xn); flint_mpn_copyi(y, t + xn, xn); /* error bound (ulp) */ error[0] = 2; } TMP_END; } arb-2.22.1/arb/atanh.c000066400000000000000000000014301417376376500143660ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_atanh(arb_t z, const arb_t x, slong prec) { if (arb_is_zero(x)) { arb_zero(z); } else { arb_t t; arb_init(t); arb_sub_ui(t, x, 1, prec + 4); arb_div(t, x, t, prec + 4); arb_mul_2exp_si(t, t, 1); arb_neg(t, t); arb_log1p(z, t, prec); arb_mul_2exp_si(z, z, -1); arb_clear(t); } } arb-2.22.1/arb/bell_fmpz.c000066400000000000000000000175641417376376500152640ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "flint/double_extras.h" #include "arb.h" /* \sum_{k=0}^{a-1} \frac{k^n}{k!} */ /* b = a * \frac{(a-1)^n}{(a-1)!} */ /* assumes n > 0, a >= 0 */ static void lower_bound(mag_t bound, const fmpz_t a, const fmpz_t n) { arb_t t, u; slong wp; if (fmpz_is_zero(a)) { mag_zero(bound); return; } wp = 10 + fmpz_bits(n); arb_init(t); arb_init(u); /* decreasing condition: a * (a-1)^n < a^n */ arb_set_fmpz(t, a); arb_pow_fmpz(t, t, n, wp); arb_set_fmpz(u, a); arb_sub_ui(u, u, 1, wp); arb_pow_fmpz(u, u, n, wp); arb_mul_fmpz(u, u, a, wp); if (arb_lt(u, t)) { arb_gamma_fmpz(t, a, wp); arb_div(t, u, t, wp); arb_get_mag(bound, t); } else { mag_inf(bound); } arb_clear(t); arb_clear(u); } /* b^n [ ((b+1)/b)^n ((b+2)/b)^n ] --- [ 1 + ----------- + ----------- + .... ] b! [ (b+1) (b+1)(b+2) ] */ static void upper_bound(mag_t bound, const fmpz_t b, const fmpz_t n) { arb_t t, u; slong wp; wp = 10 + 2 * fmpz_bits(n); arb_init(t); arb_init(u); /* decreasing condition: (1+1/b)^n / (b+1) < 1 */ /* geometric series factor: 1 + t^2 + t^3 + ... = 1/(1-t) */ arb_one(t); arb_div_fmpz(t, t, b, wp); arb_add_ui(t, t, 1, wp); arb_pow_fmpz(t, t, n, wp); arb_set_fmpz(u, b); arb_add_ui(u, u, 1, wp); arb_div(t, t, u, wp); arb_one(u); arb_sub(u, u, t, wp); if (arb_is_positive(u)) { arb_set_fmpz(t, b); arb_pow_fmpz(t, t, n, wp); arb_div(t, t, u, wp); arb_set_fmpz(u, b); arb_add_ui(u, u, 1, wp); arb_gamma(u, u, wp); arb_div(t, t, u, wp); arb_get_mag(bound, t); } else { mag_inf(bound); } arb_clear(t); arb_clear(u); } /* approximate; need not give a correct bound, but should be accurate so that we find near-optimal cutoffs (we compute correct bounds elsewhere) */ static void _arb_bell_mag(fmpz_t mmag, const fmpz_t n, const fmpz_t k) { if (fmpz_cmp_ui(k, 1) <= 0) { fmpz_set(mmag, k); } else if (fmpz_bits(n) < 50) { double dn, dk, z, u, lg; dn = fmpz_get_d(n); dk = fmpz_get_d(k); z = dk + 1.0; u = 1.0 / z; lg = 0.91893853320467274178 + (z-0.5)*log(z) - z; lg = lg + u * (0.08333333333333333 - 0.00277777777777777778 * (u * u) + 0.00079365079365079365079 * ((u * u) * (u * u))); u = (dn * log(dk) - lg) * 1.4426950408889634074 + 1.0; fmpz_set_d(mmag, u); } else { arb_t t, u; arf_t bound; slong prec; arb_init(t); arb_init(u); arf_init(bound); prec = 10 + 1.1 * fmpz_bits(n); arb_log_fmpz(t, k, prec); arb_mul_fmpz(t, t, n, prec); arb_set_fmpz(u, k); arb_add_ui(u, u, 1, prec); arb_lgamma(u, u, prec); arb_sub(t, t, u, prec); arb_const_log2(u, prec); arb_div(t, t, u, prec); arf_set_mag(bound, arb_radref(t)); arf_add(bound, arb_midref(t), bound, prec, ARF_RND_CEIL); arf_get_fmpz(mmag, bound, ARF_RND_CEIL); arb_clear(t); arb_clear(u); arf_clear(bound); } } void arb_bell_find_cutoffs(fmpz_t A, fmpz_t B, fmpz_t M, fmpz_t Mmag, const fmpz_t n, slong prec) { fmpz_t a, amag, b, bmag, m, mmag, w, wmag, Amag, Bmag; fmpz_init(a); fmpz_init(amag); fmpz_init(b); fmpz_init(bmag); fmpz_init(m); fmpz_init(mmag); fmpz_init(w); fmpz_init(wmag); fmpz_init(Amag); fmpz_init(Bmag); if (fmpz_bits(n) < 53 && 0) { double dn = fmpz_get_d(n); fmpz_set_d(M, dn / d_lambertw(dn)); _arb_bell_mag(Mmag, n, M); } else { /* do ternary search for M */ fmpz_zero(a); fmpz_mul_ui(b, n, 2); fmpz_zero(amag); fmpz_zero(bmag); while (_fmpz_sub_small(b, a) > 4) { fmpz_sub(m, b, a); fmpz_tdiv_q_ui(m, m, 3); fmpz_mul_2exp(w, m, 1); fmpz_add(m, a, m); fmpz_add(w, a, w); _arb_bell_mag(mmag, n, m); _arb_bell_mag(wmag, n, w); if (fmpz_cmp(mmag, wmag) < 0) { fmpz_swap(a, m); fmpz_swap(amag, mmag); } else { fmpz_swap(b, w); fmpz_swap(bmag, wmag); } } fmpz_set(M, a); fmpz_set(Mmag, amag); } /* bisect for A */ fmpz_zero(a); fmpz_zero(amag); fmpz_set(b, M); fmpz_set(bmag, Mmag); while (_fmpz_sub_small(b, a) > 4) { fmpz_sub(m, b, a); fmpz_tdiv_q_2exp(m, m, 1); fmpz_add(m, a, m); _arb_bell_mag(mmag, n, m); /* mmag < Mmag - p */ if (_fmpz_sub_small(mmag, Mmag) < -prec) { fmpz_swap(a, m); fmpz_swap(amag, mmag); } else { fmpz_swap(b, m); fmpz_swap(bmag, mmag); } } fmpz_set(A, a); fmpz_set(Amag, amag); /* bisect for B */ fmpz_set(a, M); fmpz_set(amag, Mmag); fmpz_mul_ui(b, n, 2); fmpz_zero(bmag); while (_fmpz_sub_small(b, a) > 4) { fmpz_sub(m, b, a); fmpz_tdiv_q_2exp(m, m, 1); fmpz_add(m, a, m); _arb_bell_mag(mmag, n, m); /* mmag < Mmag - p */ if (_fmpz_sub_small(mmag, Mmag) < -prec || fmpz_sgn(mmag) <= 0) { fmpz_swap(b, m); fmpz_swap(bmag, mmag); } else { fmpz_swap(a, m); fmpz_swap(amag, mmag); } } fmpz_set(B, a); fmpz_set(Bmag, amag); fmpz_clear(a); fmpz_clear(amag); fmpz_clear(b); fmpz_clear(bmag); fmpz_clear(m); fmpz_clear(mmag); fmpz_clear(w); fmpz_clear(wmag); fmpz_clear(Amag); fmpz_clear(Bmag); } void arb_bell_fmpz(arb_t res, const fmpz_t n, slong prec) { fmpz_t a, b, m, mmag, c; arb_t t; mag_t bound; if (fmpz_sgn(n) < 0) { arb_zero(res); return; } if (fmpz_fits_si(n)) { slong nn = fmpz_get_si(n); /* compute exactly if we would be computing at least half the bits of the exact number */ if (nn < 50 || prec > 0.5 * nn * log(0.7*nn / log(nn)) * 1.442695041) { fmpz_init(a); arith_bell_number(a, nn); arb_set_round_fmpz(res, a, prec); fmpz_clear(a); return; } } fmpz_init(a); fmpz_init(b); fmpz_init(m); fmpz_init(mmag); fmpz_init(c); arb_init(t); mag_init(bound); arb_bell_find_cutoffs(a, b, m, mmag, n, 1.03 * prec + fmpz_bits(n) + 2); /* cutoff: n > 2^12 * prec^2 */ fmpz_set_ui(c, prec); fmpz_mul_ui(c, c, prec); fmpz_mul_2exp(c, c, 12); if (fmpz_cmp(n, c) > 0) arb_bell_sum_taylor(res, n, a, b, mmag, prec + 2); else arb_bell_sum_bsplit(res, n, a, b, mmag, prec + 2); lower_bound(bound, a, n); arb_add_error_mag(res, bound); upper_bound(bound, b, n); arb_add_error_mag(res, bound); arb_const_e(t, prec + 2); arb_div(res, res, t, prec); fmpz_clear(a); fmpz_clear(b); fmpz_clear(m); fmpz_clear(mmag); fmpz_clear(c); arb_clear(t); mag_clear(bound); } void arb_bell_ui(arb_t res, ulong n, slong prec) { fmpz_t t; fmpz_init(t); fmpz_set_ui(t, n); arb_bell_fmpz(res, t, prec); fmpz_clear(t); } arb-2.22.1/arb/bell_sum_bsplit.c000066400000000000000000000043501417376376500164560ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void bsplit(arb_t P, arb_t Q, const fmpz_t n, const fmpz_t a, const fmpz_t b, slong prec) { fmpz_t t; fmpz_init(t); fmpz_sub(t, b, a); if (fmpz_sgn(t) <= 0) { arb_zero(P); arb_one(Q); } else if (fmpz_cmp_ui(t, 20) < 0) { slong steps, k; arb_t u; arb_init(u); arb_zero(P); arb_one(Q); steps = fmpz_get_si(t); for (k = steps - 1; k >= 0; k--) { fmpz_add_ui(t, a, k); arb_set_round_fmpz(u, t, prec); arb_pow_fmpz(u, u, n, prec); arb_addmul(P, Q, u, prec); if (!fmpz_is_zero(t)) arb_mul_fmpz(Q, Q, t, prec); } arb_clear(u); } else { fmpz_t m; arb_t P1, Q2; fmpz_init(m); arb_init(P1); arb_init(Q2); fmpz_add(m, a, b); fmpz_tdiv_q_2exp(m, m, 1); bsplit(P1, Q, n, a, m, prec); bsplit(P, Q2, n, m, b, prec); arb_mul(Q, Q, Q2, prec); arb_addmul(P, P1, Q2, prec); fmpz_clear(m); arb_clear(P1); arb_clear(Q2); } fmpz_clear(t); } void arb_bell_sum_bsplit(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, slong prec) { if (fmpz_cmp(a, b) >= 0) { arb_zero(res); } else { slong wp; arb_t P, Q; wp = _fmpz_sub_small(b, a); wp = FLINT_BIT_COUNT(FLINT_ABS(wp)); wp = prec + fmpz_bits(n) + fmpz_bits(a) + wp; arb_init(P); arb_init(Q); bsplit(P, Q, n, a, b, wp); arb_div(res, P, Q, wp); if (!fmpz_is_zero(a)) { arb_gamma_fmpz(P, a, wp); arb_div(res, res, P, wp); } arb_set_round(res, res, prec); arb_clear(P); arb_clear(Q); } } arb-2.22.1/arb/bell_sum_taylor.c000066400000000000000000000130601417376376500164710ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "arb_poly.h" /* tuning parameter */ #define RADIUS_BITS 3 void _arb_bell_sum_taylor(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, slong tol) { fmpz_t m, r, R, tmp; mag_t B, C, D, bound; arb_t t, u; slong wp, k, N; if (_fmpz_sub_small(b, a) < 5) { arb_bell_sum_bsplit(res, n, a, b, mmag, tol); return; } fmpz_init(m); fmpz_init(r); fmpz_init(R); fmpz_init(tmp); /* r = max(m - a, b - m) */ /* m = a + (b - a) / 2 */ fmpz_sub(r, b, a); fmpz_cdiv_q_2exp(r, r, 1); fmpz_add(m, a, r); fmpz_mul_2exp(R, r, RADIUS_BITS); mag_init(B); mag_init(C); mag_init(D); mag_init(bound); arb_init(t); arb_init(u); if (fmpz_cmp(R, m) >= 0) { mag_inf(C); mag_inf(D); } else { /* C = exp(R * |F'(m)| + (1/2) R^2 * (n/(m-R)^2 + 1/(m-R))) */ /* C = exp(R * (|F'(m)| + (1/2) R * (n/(m-R) + 1)/(m-R))) */ /* D = (1/2) R * (n/(m-R) + 1)/(m-R) */ fmpz_sub(tmp, m, R); mag_set_fmpz(D, n); mag_div_fmpz(D, D, tmp); mag_one(C); mag_add(D, D, C); mag_div_fmpz(D, D, tmp); mag_mul_fmpz(D, D, R); mag_mul_2exp_si(D, D, -1); /* C = |F'(m)| */ wp = 20 + 1.05 * fmpz_bits(n); arb_set_fmpz(t, n); arb_div_fmpz(t, t, m, wp); fmpz_add_ui(tmp, m, 1); arb_set_fmpz(u, tmp); arb_digamma(u, u, wp); arb_sub(t, t, u, wp); arb_get_mag(C, t); /* C = exp(R * (C + D)) */ mag_add(C, C, D); mag_mul_fmpz(C, C, R); mag_exp(C, C); } if (mag_cmp_2exp_si(C, tol / 4 + 2) > 0) { _arb_bell_sum_taylor(res, n, a, m, mmag, tol); _arb_bell_sum_taylor(t, n, m, b, mmag, tol); arb_add(res, res, t, 2 * tol); } else { arb_ptr mx, ser1, ser2, ser3; /* D = T(m) */ wp = 20 + 1.05 * fmpz_bits(n); arb_set_fmpz(t, m); arb_pow_fmpz(t, t, n, wp); fmpz_add_ui(tmp, m, 1); arb_gamma_fmpz(u, tmp, wp); arb_div(t, t, u, wp); arb_get_mag(D, t); /* error bound: (b-a) * C * D * B^N / (1 - B), B = r/R */ /* ((b-a) * C * D * 2) * 2^(-N*RADIUS_BITS) */ /* ((b-a) * C * D * 2) */ mag_mul(bound, C, D); mag_mul_2exp_si(bound, bound, 1); fmpz_sub(tmp, b, a); mag_mul_fmpz(bound, bound, tmp); /* N = (tol + log2((b-a)*C*D*2) - mmag) / RADIUS_BITS */ if (mmag == NULL) { /* estimate D ~= 2^mmag */ fmpz_add_ui(tmp, MAG_EXPREF(C), tol); fmpz_cdiv_q_ui(tmp, tmp, RADIUS_BITS); } else { fmpz_sub(tmp, MAG_EXPREF(bound), mmag); fmpz_add_ui(tmp, tmp, tol); fmpz_cdiv_q_ui(tmp, tmp, RADIUS_BITS); } if (fmpz_cmp_ui(tmp, 5 * tol / 4) > 0) N = 5 * tol / 4; else if (fmpz_cmp_ui(tmp, 2) < 0) N = 2; else N = fmpz_get_ui(tmp); /* multiply by 2^(-N*RADIUS_BITS) */ mag_mul_2exp_si(bound, bound, -N * RADIUS_BITS); mx = _arb_vec_init(2); ser1 = _arb_vec_init(N); ser2 = _arb_vec_init(N); ser3 = _arb_vec_init(N); /* estimate (this should work for moderate n and tol) */ wp = 1.1 * tol + 1.05 * fmpz_bits(n) + 5; /* increase precision until convergence */ while (1) { /* (m+x)^n / gamma(m+1+x) */ arb_set_fmpz(mx, m); arb_one(mx + 1); _arb_poly_log_series(ser1, mx, 2, N, wp); for (k = 0; k < N; k++) arb_mul_fmpz(ser1 + k, ser1 + k, n, wp); arb_add_ui(mx, mx, 1, wp); _arb_poly_lgamma_series(ser2, mx, 2, N, wp); _arb_vec_sub(ser1, ser1, ser2, N, wp); _arb_poly_exp_series(ser3, ser1, N, N, wp); /* t = a - m, u = b - m */ arb_set_fmpz(t, a); arb_sub_fmpz(t, t, m, wp); arb_set_fmpz(u, b); arb_sub_fmpz(u, u, m, wp); arb_power_sum_vec(ser1, t, u, N, wp); arb_zero(res); for (k = 0; k < N; k++) arb_addmul(res, ser3 + k, ser1 + k, wp); if (mmag != NULL) { if (_fmpz_sub_small(MAG_EXPREF(arb_radref(res)), mmag) <= -tol) break; } else { if (arb_rel_accuracy_bits(res) >= tol) break; } wp = 2 * wp; } /* add the series truncation bound */ arb_add_error_mag(res, bound); _arb_vec_clear(mx, 2); _arb_vec_clear(ser1, N); _arb_vec_clear(ser2, N); _arb_vec_clear(ser3, N); } mag_clear(B); mag_clear(C); mag_clear(D); mag_clear(bound); arb_clear(t); arb_clear(u); fmpz_clear(m); fmpz_clear(r); fmpz_clear(R); fmpz_clear(tmp); } void arb_bell_sum_taylor(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, slong prec) { _arb_bell_sum_taylor(res, n, a, b, mmag, prec + 5); } arb-2.22.1/arb/bernoulli_fmpz.c000066400000000000000000000026021417376376500163240ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_bernoulli_fmpz(arb_t res, const fmpz_t n, slong prec) { if (fmpz_cmp_ui(n, UWORD_MAX) <= 0) { if (fmpz_sgn(n) >= 0) arb_bernoulli_ui(res, fmpz_get_ui(n), prec); else arb_zero(res); } else if (fmpz_is_odd(n)) { arb_zero(res); } else { arb_t t; slong wp; arb_init(t); wp = prec + 2 * fmpz_bits(n); /* zeta(n) ~= 1 */ arf_one(arb_midref(res)); mag_one(arb_radref(res)); mag_mul_2exp_si(arb_radref(res), arb_radref(res), WORD_MIN); /* |B_n| = 2 * n! / (2*pi)^n * zeta(n) */ arb_gamma_fmpz(t, n, wp); arb_mul_fmpz(t, t, n, wp); arb_mul(res, res, t, wp); arb_const_pi(t, wp); arb_mul_2exp_si(t, t, 1); arb_pow_fmpz(t, t, n, wp); arb_div(res, res, t, prec); arb_mul_2exp_si(res, res, 1); if (fmpz_fdiv_ui(n, 4) == 0) arb_neg(res, res); arb_clear(t); } } arb-2.22.1/arb/bernoulli_poly_ui.c000066400000000000000000000050761417376376500170400ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_bernoulli_poly_ui(arb_t res, ulong n, const arb_t x, slong prec) { arb_t s, t, c, x2; ulong m, k; int negate; if (n == 0) { arb_one(res); return; } if (n == 1) { arb_mul_2exp_si(res, x, 1); arb_sub_ui(res, res, 1, prec); arb_mul_2exp_si(res, res, -1); return; } /* small integer x */ if (arb_is_int(x) && arf_cmpabs_ui(arb_midref(x), n) < 0 && n < WORD_MAX) { if (arf_sgn(arb_midref(x)) >= 0) { m = arf_get_si(arb_midref(x), ARF_RND_DOWN); negate = 0; } else { m = UWORD(1) - arf_get_si(arb_midref(x), ARF_RND_DOWN); negate = n % 2; } arb_init(t); arb_zero(res); /* todo: use a dedicated power sum function */ for (k = 1; k < m; k++) { arb_ui_pow_ui(t, k, n - 1, prec); arb_add(res, res, t, prec); } arb_mul_ui(res, res, n, prec); arb_bernoulli_ui(t, n, prec); arb_add(res, res, t, prec); if (negate) arb_neg(res, res); arb_clear(t); return; } /* assuming small n simplifies the code that follows */ if (n >> (FLINT_BITS / 2) || !arb_is_finite(x)) { arb_indeterminate(res); return; } arb_init(s); arb_init(t); arb_init(c); arb_init(x2); arb_mul(x2, x, x, prec); /* s = x^2 - x n / 2 */ arb_mul_ui(s, x, n, prec); arb_mul_2exp_si(s, s, -1); arb_sub(s, x2, s, prec); /* c = n (n-1) / 2; s = s + c / 6 */ arb_set_ui(c, n * (n - 1)); arb_mul_2exp_si(c, c, -1); arb_div_ui(t, c, 6, prec); arb_add(s, s, t, prec); for (k = 4; k <= n; k += 2) { /* c = binomial(n,k) */ arb_mul_ui(c, c, (n + 1 - k) * (n + 2 - k), prec); arb_div_ui(c, c, k * (k - 1), prec); /* s = s x^2 + b_k c */ arb_mul(s, s, x2, prec); arb_bernoulli_ui(t, k, prec); arb_addmul(s, t, c, prec); } if (n >= 3 && n % 2) arb_mul(s, s, x, prec); arb_swap(res, s); arb_clear(s); arb_clear(t); arb_clear(c); arb_clear(x2); } arb-2.22.1/arb/bernoulli_ui.c000066400000000000000000000020531417376376500157650ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "bernoulli.h" void arb_bernoulli_ui(arb_t b, ulong n, slong prec) { if (n < bernoulli_cache_num) { arb_set_fmpq(b, bernoulli_cache + n, prec); } else { int use_frac; use_frac = (n < BERNOULLI_SMALL_NUMER_LIMIT) || (n % 2 != 0); if (!use_frac && n < UWORD_MAX / 1000) use_frac = (prec > bernoulli_global_prec(n)); if (use_frac) { fmpq_t t; fmpq_init(t); bernoulli_fmpq_ui(t, n); arb_set_fmpq(b, t, prec); fmpq_clear(t); } else { arb_bernoulli_ui_zeta(b, n, prec); } } } arb-2.22.1/arb/bernoulli_ui_zeta.c000066400000000000000000000023001417376376500170030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_zeta_inv_ui_euler_product(arb_t z, ulong s, slong prec); void arb_bernoulli_ui_zeta(arb_t b, ulong n, slong prec) { slong wp, piwp; arb_t t, u; if (n < 10 || n % 2 != 0) flint_abort(); wp = prec + 8; piwp = wp + 2*FLINT_BIT_COUNT(n); arb_init(t); arb_init(u); /* |B_n| = 2 * n! / (2*pi)^n * zeta(n) */ arb_fac_ui(b, n, piwp); arb_const_pi(t, piwp); arb_mul_2exp_si(t, t, 1); arb_pow_ui(t, t, n, piwp); if (n > 0.7 * wp) { arb_zeta_ui_asymp(u, n, wp); arb_mul(b, b, u, wp); } else { arb_zeta_inv_ui_euler_product(u, n, wp); arb_mul(t, t, u, wp); } arb_div(b, b, t, prec); arb_mul_2exp_si(b, b, 1); if (n % 4 == 0) arb_neg(b, b); arb_clear(t); arb_clear(u); } arb-2.22.1/arb/bin.c000066400000000000000000000017661417376376500140570ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_bin_ui(arb_t x, const arb_t n, ulong k, slong prec) { if (k == 0) { arb_one(x); } else if (k == 1) { arb_set_round(x, n, prec); } else { arb_t t, u; arb_init(t); arb_init(u); arb_sub_ui(t, n, k - 1, prec); arb_rising_ui(t, t, k, prec); arb_fac_ui(u, k, prec); arb_div(x, t, u, prec); arb_clear(t); arb_clear(u); } } void arb_bin_uiui(arb_t x, ulong n, ulong k, slong prec) { arb_t t; arb_init(t); arb_set_ui(t, n); arb_bin_ui(x, t, k, prec); arb_clear(t); } arb-2.22.1/arb/can_round_mpfr.c000066400000000000000000000026301417376376500162720ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int mpfr_round_p(mp_srcptr, mp_size_t, mpfr_exp_t, mpfr_prec_t); int arb_can_round_arf(const arb_t x, slong prec, arf_rnd_t rnd) { return arb_can_round_mpfr(x, prec, arf_rnd_to_mpfr(rnd)); } int arb_can_round_mpfr(const arb_t x, slong prec, mpfr_rnd_t rnd) { if (!arb_is_finite(x)) { return 0; } else if (mag_is_zero(arb_radref(x))) { return 1; } else if (arf_is_zero(arb_midref(x))) { return 0; } else { slong e, bits; mp_size_t n; mp_srcptr d; e = _fmpz_sub_small(ARF_EXPREF(arb_midref(x)), MAG_EXPREF(arb_radref(x))); if (e < prec) return 0; /* The relative exponent could be tiny (in which case _fmpz_sub_small has clamped it). Looking just past the end will be enough. */ bits = arb_bits(x); e = FLINT_MIN(e, FLINT_MAX(bits, prec) + 10); ARF_GET_MPN_READONLY(d, n, arb_midref(x)); return mpfr_round_p(d, n, e, prec + (rnd == MPFR_RNDN)); } } arb-2.22.1/arb/ceil.c000066400000000000000000000016631417376376500142170ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_ceil(arb_t z, const arb_t x, slong prec) { if (!arb_is_finite(x)) { arb_indeterminate(z); } else if (arb_is_exact(x)) { arf_ceil(arb_midref(z), arb_midref(x)); mag_zero(arb_radref(z)); arb_set_round(z, z, prec); } else { arf_t a, b; arf_init(a); arf_init(b); arb_get_interval_arf(a, b, x, prec); arf_ceil(a, a); arf_ceil(b, b); arb_set_interval_arf(z, a, b, prec); arf_clear(a); arf_clear(b); } } arb-2.22.1/arb/chebyshev_t2_ui.c000066400000000000000000000023201417376376500163540ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_chebyshev_t2_ui(arb_t a, arb_t b, ulong n, const arb_t x, slong prec) { int i; arb_set_round(a, x, prec); arb_one(b); if (n <= 1) { if (n == 0) arb_swap(a, b); return; } for (i = FLINT_BIT_COUNT(n - 1) - 1; i >= 0; i--) { if (((n - 1) >> i) & 1) { arb_mul(b, b, a, prec); arb_mul_2exp_si(b, b, 1); arb_sub(b, b, x, prec); arb_mul(a, a, a, prec); arb_mul_2exp_si(a, a, 1); arb_sub_ui(a, a, 1, prec); } else { arb_mul(a, a, b, prec); arb_mul_2exp_si(a, a, 1); arb_sub(a, a, x, prec); arb_mul(b, b, b, prec); arb_mul_2exp_si(b, b, 1); arb_sub_ui(b, b, 1, prec); } } } arb-2.22.1/arb/chebyshev_t_ui.c000066400000000000000000000024371417376376500163030ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_chebyshev_t_ui(arb_t y, ulong n, const arb_t x, slong prec) { int i, r; if (n <= 1) { if (n == 0) arb_one(y); else arb_set_round(y, x, prec); return; } count_trailing_zeros(r, n); if ((n >> r) == 1) { arb_mul(y, x, x, prec); arb_mul_2exp_si(y, y, 1); arb_sub_ui(y, y, 1, prec); r -= 1; } else { /* we only need one value, so break out final iteration */ arb_t t, u; arb_init(t); arb_init(u); arb_chebyshev_t2_ui(t, u, (n >> (r + 1)) + 1, x, prec); arb_mul(t, t, u, prec); arb_mul_2exp_si(t, t, 1); arb_sub(y, t, x, prec); arb_clear(t); arb_clear(u); } for (i = 0; i < r; i++) { arb_mul(y, y, y, prec); arb_mul_2exp_si(y, y, 1); arb_sub_ui(y, y, 1, prec); } } arb-2.22.1/arb/chebyshev_u2_ui.c000066400000000000000000000024361417376376500163650ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_chebyshev_u2_ui(arb_t a, arb_t b, ulong n, const arb_t x, slong prec) { int i; arb_t t, u; if (n == 0) { arb_one(a); arb_zero(b); return; } arb_set_round(a, x, prec); arb_mul_2exp_si(a, a, 1); arb_one(b); if (n == 1) return; arb_init(t); arb_init(u); for (i = FLINT_BIT_COUNT(n) - 2; i >= 0; i--) { arb_add(t, a, b, prec); arb_sub(u, a, b, prec); if ((n >> i) & 1) { arb_submul(b, x, a, prec); arb_mul(a, a, b, prec); arb_neg(a, a); arb_mul_2exp_si(a, a, 1); arb_mul(b, t, u, prec); } else { arb_submul(a, x, b, prec); arb_mul(b, a, b, prec); arb_mul_2exp_si(b, b, 1); arb_mul(a, t, u, prec); } } arb_clear(t); arb_clear(u); } arb-2.22.1/arb/chebyshev_u_ui.c000066400000000000000000000021151417376376500162750ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_chebyshev_u_ui(arb_t y, ulong n, const arb_t x, slong prec) { arb_t a, b; if (n <= 1) { if (n == 0) { arb_one(y); } else { arb_set_round(y, x, prec); arb_mul_2exp_si(y, y, 1); } return; } arb_init(a); arb_init(b); arb_chebyshev_u2_ui(a, b, n / 2, x, prec); if (n % 2 == 0) { arb_add(y, a, b, prec); arb_sub(b, a, b, prec); arb_mul(y, y, b, prec); } else { arb_submul(b, a, x, prec); arb_mul(y, a, b, prec); arb_mul_2exp_si(y, y, 1); arb_neg(y, y); } arb_clear(a); arb_clear(b); } arb-2.22.1/arb/clear.c000066400000000000000000000014531417376376500143660ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* The clear methods are not defined as inlines since this inflates the code size. We inline the content manually here to avoid function call overhead. */ void arb_clear(arb_t x) { ARF_DEMOTE(arb_midref(x)); if (COEFF_IS_MPZ(ARF_EXP(arb_midref(x)))) _fmpz_clear_mpz(ARF_EXP(arb_midref(x))); if (COEFF_IS_MPZ(MAG_EXP(arb_radref(x)))) _fmpz_clear_mpz(MAG_EXP(arb_radref(x))); } arb-2.22.1/arb/const_apery.c000066400000000000000000000017731417376376500156330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "hypgeom.h" void arb_const_apery_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t; arb_init(t); hypgeom_init(series); fmpz_poly_set_str(series->A, "3 77 250 205"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "6 0 0 0 0 0 -1"); fmpz_poly_set_str(series->Q, "6 32 320 1280 2560 2560 1024"); prec += 4 + FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, prec, prec); arb_mul_ui(t ,t, 64, prec); arb_div(s, s, t, prec); hypgeom_clear(series); arb_clear(t); } ARB_DEF_CACHED_CONSTANT(arb_const_apery, arb_const_apery_eval) arb-2.22.1/arb/const_catalan.c000066400000000000000000000020151417376376500161040ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "hypgeom.h" void arb_const_catalan_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t; arb_init(t); hypgeom_init(series); fmpz_poly_set_str(series->P, "5 32 160 288 224 64"); fmpz_poly_set_str(series->Q, "5 225 3240 14904 23328 11664"); fmpz_poly_set_str(series->A, "3 411 976 580"); fmpz_poly_set_str(series->B, "5 1 5 9 7 2"); prec += FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, prec, prec); arb_mul_ui(t, t, 450, prec); arb_div(s, s, t, prec); hypgeom_clear(series); arb_clear(t); } ARB_DEF_CACHED_CONSTANT(arb_const_catalan, arb_const_catalan_eval) arb-2.22.1/arb/const_e.c000066400000000000000000000016411417376376500147310ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "hypgeom.h" void arb_const_e_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t; arb_init(t); hypgeom_init(series); fmpz_poly_set_str(series->A, "1 1"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "1 1"); fmpz_poly_set_str(series->Q, "2 0 1"); prec += FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, prec, prec); arb_div(s, s, t, prec); hypgeom_clear(series); arb_clear(t); } ARB_DEF_CACHED_CONSTANT(arb_const_e, arb_const_e_eval) arb-2.22.1/arb/const_euler.c000066400000000000000000000177421417376376500156320ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "hypgeom.h" #include "arb_hypgeom.h" typedef struct { arb_t P; arb_t Q; arb_t T; arb_t C; arb_t D; arb_t V; } euler_bsplit_struct; typedef euler_bsplit_struct euler_bsplit_t[1]; static void euler_bsplit_init(euler_bsplit_t s) { arb_init(s->P); arb_init(s->Q); arb_init(s->T); arb_init(s->C); arb_init(s->D); arb_init(s->V); } static void euler_bsplit_clear(euler_bsplit_t s) { arb_clear(s->P); arb_clear(s->Q); arb_clear(s->T); arb_clear(s->C); arb_clear(s->D); arb_clear(s->V); } static void euler_bsplit_1_merge(euler_bsplit_t s, euler_bsplit_t L, euler_bsplit_t R, slong wp, int cont) { arb_t t, u, v; arb_init(t); arb_init(u); arb_init(v); if (cont) arb_mul(s->P, L->P, R->P, wp); arb_mul(s->Q, L->Q, R->Q, wp); arb_mul(s->D, L->D, R->D, wp); /* T = LP RT + RQ LT*/ arb_mul(t, L->P, R->T, wp); arb_mul(v, R->Q, L->T, wp); arb_add(s->T, t, v, wp); /* C = LC RD + RC LD */ if (cont) { arb_mul(s->C, L->C, R->D, wp); arb_addmul(s->C, R->C, L->D, wp); } /* V = RD (RQ LV + LC LP RT) + LD LP RV */ arb_mul(u, L->P, R->V, wp); arb_mul(u, u, L->D, wp); arb_mul(v, R->Q, L->V, wp); arb_addmul(v, t, L->C, wp); arb_mul(v, v, R->D, wp); arb_add(s->V, u, v, wp); arb_clear(t); arb_clear(u); arb_clear(v); } static void euler_bsplit_1(euler_bsplit_t s, slong n1, slong n2, slong N, slong wp, int cont) { if (n2 - n1 == 1) { arb_set_si(s->P, N); /* p = N^2 */ arb_mul(s->P, s->P, s->P, wp); arb_set_si(s->Q, n1 + 1); /* q = (k + 1)^2 */ arb_mul(s->Q, s->Q, s->Q, wp); arb_set_si(s->C, 1); arb_set_si(s->D, n1 + 1); arb_set(s->T, s->P); arb_set(s->V, s->P); } else { euler_bsplit_t L, R; slong m = (n1 + n2) / 2; euler_bsplit_init(L); euler_bsplit_init(R); euler_bsplit_1(L, n1, m, N, wp, 1); euler_bsplit_1(R, m, n2, N, wp, 1); euler_bsplit_1_merge(s, L, R, wp, cont); euler_bsplit_clear(L); euler_bsplit_clear(R); } } static void euler_bsplit_2(arb_t P, arb_t Q, arb_t T, slong n1, slong n2, slong N, slong wp, int cont) { if (n2 - n1 == 1) { if (n1 == 0) { arb_set_si(P, 1); arb_set_si(Q, 4 * N); arb_set_si(T, 1); } else { arb_si_pow_ui(P, 1 - 2*n1, 3, wp); arb_neg(P, P); arb_set_si(Q, 32 * n1); arb_mul_ui(Q, Q, N, wp); arb_mul_ui(Q, Q, N, wp); } arb_set(T, P); } else { arb_t P2, Q2, T2; slong m = (n1 + n2) / 2; arb_init(P2); arb_init(Q2); arb_init(T2); euler_bsplit_2(P, Q, T, n1, m, N, wp, 1); euler_bsplit_2(P2, Q2, T2, m, n2, N, wp, 1); arb_mul(T, T, Q2, wp); arb_mul(T2, T2, P, wp); arb_add(T, T, T2, wp); if (cont) arb_mul(P, P, P2, wp); arb_mul(Q, Q, Q2, wp); arb_clear(P2); arb_clear(Q2); arb_clear(T2); } } static void atanh_bsplit(arb_t s, ulong c, slong a, slong prec) { arb_t t; hypgeom_t series; hypgeom_init(series); arb_init(t); fmpz_poly_set_ui(series->A, 1); fmpz_poly_set_coeff_ui(series->B, 0, 1); fmpz_poly_set_coeff_ui(series->B, 1, 2); fmpz_poly_set_ui(series->P, 1); fmpz_poly_set_ui(series->Q, c * c); arb_hypgeom_infsum(s, t, series, prec, prec); arb_mul_si(s, s, a, prec); arb_mul_ui(t, t, c, prec); arb_div(s, s, t, prec); arb_clear(t); hypgeom_clear(series); } static ulong next_smooth(ulong n) { ulong t, k; for (k = n; ; k++) { t = k; while (t % 2 == 0) t /= 2; while (t % 3 == 0) t /= 3; while (t % 5 == 0) t /= 5; if (t == 1) return k; } } static void arb_log_ui_smooth(arb_t s, ulong n, slong prec) { ulong m, i, j, k; arb_t t; m = n; i = j = k = 0; while (m % 2 == 0) { m /= 2; i++; } while (m % 3 == 0) { m /= 3; j++; } while (m % 5 == 0) { m /= 5; k++; } if (m != 1) flint_abort(); arb_init(t); prec += FLINT_CLOG2(prec); atanh_bsplit(s, 31, 14*i + 22*j + 32*k, prec); atanh_bsplit(t, 49, 10*i + 16*j + 24*k, prec); arb_add(s, s, t, prec); atanh_bsplit(t, 161, 6*i + 10*j + 14*k, prec); arb_add(s, s, t, prec); arb_clear(t); } void arb_const_euler_eval(arb_t res, slong prec) { euler_bsplit_t sum; arb_t t, u, v, P2, T2, Q2; slong bits, wp, wp2, n, N, M; bits = prec + 10; n = 0.086643397569993163677 * bits + 1; /* log(2) / 8 */ /* round n to have many trailing zeros, speeding up arithmetic, and make it smooth to allow computing the logarithm cheaply */ if (n > 256) { int b = FLINT_BIT_COUNT(n); n = next_smooth((n >> (b-4)) + 1) << (b-4); } else { n = next_smooth(n); } /* As shown in the paper, it is sufficient to take N >= alpha n + 1 where alpha = 3/W(3/e) = 4.970625759544... */ { fmpz_t a; fmpz_init(a); fmpz_set_ui(a, n); fmpz_mul_ui(a, a, 4970626); fmpz_cdiv_q_ui(a, a, 1000000); fmpz_add_ui(a, a, 1); N = fmpz_get_ui(a); fmpz_clear(a); } M = 2 * n; wp = bits + 2 * FLINT_BIT_COUNT(n); wp2 = bits/2 + 2 * FLINT_BIT_COUNT(n); euler_bsplit_init(sum); arb_init(P2); arb_init(T2); arb_init(Q2); arb_init(t); arb_init(u); arb_init(v); /* Compute S0 = V / (Q D), I0 = 1 + T / Q */ euler_bsplit_1(sum, 0, N, n, wp, 0); /* I0 = T / Q */ arb_add(sum->T, sum->T, sum->Q, wp); /* Compute S0 / I0 = V / (D T) */ arb_mul(t, sum->T, sum->D, wp); arb_div(res, sum->V, t, wp); /* Compute K0 (actually I_0(2n) K_0(2n)) = T2 / Q2 */ euler_bsplit_2(P2, Q2, T2, 0, M, n, wp2, 0); /* Compute K0 / I^2 = Q^2 * T2 / (Q2 * T^2) */ arb_set_round(t, sum->Q, wp2); arb_mul(t, t, t, wp2); arb_mul(t, t, T2, wp2); arb_set_round(u, sum->T, wp2); arb_mul(u, u, u, wp2); arb_mul(u, u, Q2, wp2); arb_div(t, t, u, wp2); arb_sub(res, res, t, wp); /* subtract log(n) */ arb_log_ui_smooth(u, n, wp); arb_sub(res, res, u, wp); /* add error bound 24 exp(-8n) */ { mag_t b; mag_init(b); /* exp(-8) < 737690121 * 2^-41 */ mag_set_ui_2exp_si(b, 737690121, -41); mag_pow_ui(b, b, n); mag_mul_ui(b, b, 24); mag_add(arb_radref(res), arb_radref(res), b); mag_clear(b); } arb_clear(P2); arb_clear(T2); arb_clear(Q2); arb_clear(t); arb_clear(u); arb_clear(v); euler_bsplit_clear(sum); } ARB_DEF_CACHED_CONSTANT(arb_const_euler_brent_mcmillan, arb_const_euler_eval) extern const mp_limb_t arb_hypgeom_gamma_tab_limbs[]; void arb_const_euler(arb_t res, slong prec) { if (prec < ARB_HYPGEOM_GAMMA_TAB_PREC - 16) { slong exp; mp_size_t n; n = ARB_HYPGEOM_GAMMA_TAB_PREC / FLINT_BITS; /* just reading the table is known to give the correct rounding */ _arf_set_round_mpn(arb_midref(res), &exp, arb_hypgeom_gamma_tab_limbs + n, n, 0, prec, ARF_RND_NEAR); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp); /* 1/2 ulp error */ _fmpz_set_si_small(MAG_EXPREF(arb_radref(res)), exp - prec); MAG_MAN(arb_radref(res)) = MAG_ONE_HALF; } else { arb_const_euler_brent_mcmillan(res, prec); } } arb-2.22.1/arb/const_glaisher.c000066400000000000000000000020551417376376500163030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "acb_poly.h" void arb_const_glaisher_eval(arb_t y, slong prec) { acb_struct z[2]; acb_t s, a; slong wp; acb_init(z + 0); acb_init(z + 1); acb_init(s); acb_init(a); wp = prec + 20; /* directly evaluating at s = -1 is slightly faster than evaluating at s = 2 */ acb_set_si(s, -1); acb_one(a); _acb_poly_zeta_cpx_series(z, s, a, 0, 2, wp); arb_one(y); arb_div_ui(y, y, 12, wp); arb_sub(y, y, acb_realref(z + 1), wp); arb_exp(y, y, wp); acb_clear(z + 0); acb_clear(z + 1); acb_clear(s); acb_clear(a); } ARB_DEF_CACHED_CONSTANT(arb_const_glaisher, arb_const_glaisher_eval) arb-2.22.1/arb/const_khinchin.c000066400000000000000000000045771417376376500163130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" void arb_const_khinchin_eval_param(arb_t s, ulong N, ulong M, slong prec) { arb_t t, u, h; arb_ptr pows; slong k, n; arb_init(t); arb_init(u); arb_init(h); if (N < 2) flint_abort(); /* if (M < 0) flint_abort(); */ pows = _arb_vec_init(N - 2); /* sum of logarithms */ arb_zero(s); for (k = 2; k < N; k++) { arb_set_ui(t, k - 1); arb_div_ui(t, t, k, prec); arb_log(t, t, prec); arb_set_ui(u, k + 1); arb_div_ui(u, u, k, prec); arb_log(u, u, prec); arb_mul(t, t, u, prec); arb_sub(s, s, t, prec); } /* alternating harmonic numbers */ arb_one(h); /* powers */ for (k = 0; k < N - 2; k++) arb_one(pows + k); /* sum of zetas */ for (n = 1; n <= M; n++) { /* zeta(2n,N) / n */ arb_zeta_ui(t, 2 * n, prec); arb_sub_ui(t, t, 1, prec); for (k = 0; k < N - 2; k++) { arb_div_ui(pows + k, pows + k, (k + 2) * (k + 2), prec); arb_sub(t, t, pows + k, prec); } arb_div_ui(t, t, n, prec); arb_mul(t, t, h, prec); arb_add(s, s, t, prec); /* forward h by two */ arb_set_ui(u, 2 * n); arb_mul_ui(u, u, 2 * n + 1, prec); arb_inv(u, u, prec); arb_sub(h, h, u, prec); } /* error bound 1/N^(2M) */ arb_set_ui(t, N); arb_pow_ui(t, t, 2 * M, MAG_BITS); arb_inv(t, t, MAG_BITS); arb_add_error(s, t); arb_log_ui(t, 2, prec); arb_div(s, s, t, prec); arb_exp(s, s, prec); _arb_vec_clear(pows, N - 2); arb_clear(t); arb_clear(u); arb_clear(h); } void arb_const_khinchin_eval(arb_t K, slong prec) { ulong N, M; prec += 10 + 2 * FLINT_BIT_COUNT(prec); /* heuristic */ N = pow(prec, 0.35); M = (prec * 0.69314718055994530942) / (2 * log(N)); arb_const_khinchin_eval_param(K, N, M, prec); } ARB_DEF_CACHED_CONSTANT(arb_const_khinchin, arb_const_khinchin_eval) arb-2.22.1/arb/const_log10.c000066400000000000000000000024441417376376500154310ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "hypgeom.h" static void atanh_bsplit(arb_t s, ulong c, slong a, slong prec) { arb_t t; hypgeom_t series; hypgeom_init(series); arb_init(t); fmpz_poly_set_ui(series->A, 1); fmpz_poly_set_coeff_ui(series->B, 0, 1); fmpz_poly_set_coeff_ui(series->B, 1, 2); fmpz_poly_set_ui(series->P, 1); fmpz_poly_set_ui(series->Q, c * c); arb_hypgeom_infsum(s, t, series, prec, prec); arb_mul_si(s, s, a, prec); arb_mul_ui(t, t, c, prec); arb_div(s, s, t, prec); arb_clear(t); hypgeom_clear(series); } void arb_const_log10_eval(arb_t s, slong prec) { arb_t t; arb_init(t); prec += FLINT_CLOG2(prec); atanh_bsplit(s, 31, 46, prec); atanh_bsplit(t, 49, 34, prec); arb_add(s, s, t, prec); atanh_bsplit(t, 161, 20, prec); arb_add(s, s, t, prec); arb_clear(t); } ARB_DEF_CACHED_CONSTANT(arb_const_log10, arb_const_log10_eval) arb-2.22.1/arb/const_log2.c000066400000000000000000000031361417376376500153510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "hypgeom.h" void arb_const_log2_hypgeom_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t; arb_init(t); hypgeom_init(series); fmpz_poly_set_str(series->A, "1 1"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "2 0 -1"); fmpz_poly_set_str(series->Q, "2 4 8"); prec += FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, prec, prec); arb_mul_ui(s, s, 3, prec); arb_mul_2exp_si(t, t, 2); arb_div(s, s, t, prec); hypgeom_clear(series); arb_clear(t); } ARB_DEF_CACHED_CONSTANT(arb_const_log2_hypgeom, arb_const_log2_hypgeom_eval) void arb_const_log2(arb_t res, slong prec) { if (prec < ARB_LOG_TAB2_LIMBS * FLINT_BITS - 16) { slong exp; /* just reading the table is known to give the correct rounding */ _arf_set_round_mpn(arb_midref(res), &exp, arb_log_log2_tab, ARB_LOG_TAB2_LIMBS, 0, prec, ARF_RND_NEAR); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp); /* 1/2 ulp error */ _fmpz_set_si_small(MAG_EXPREF(arb_radref(res)), exp - prec); MAG_MAN(arb_radref(res)) = MAG_ONE_HALF; } else { arb_const_log2_hypgeom(res, prec); } } arb-2.22.1/arb/const_log_sqrt2pi.c000066400000000000000000000012001417376376500167410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_const_log_sqrt2pi(arb_t t, slong prec) { arb_const_pi(t, prec + 2); arb_mul_2exp_si(t, t, 1); arb_log(t, t, prec); arb_mul_2exp_si(t, t, -1); } ARB_DEF_CACHED_CONSTANT(arb_const_log_sqrt2pi, _arb_const_log_sqrt2pi) arb-2.22.1/arb/const_pi.c000066400000000000000000000033461417376376500151210ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "hypgeom.h" void arb_const_pi_chudnovsky_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t, u; arb_init(t); arb_init(u); hypgeom_init(series); fmpz_poly_set_str(series->A, "2 13591409 545140134"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "4 5 -46 108 -72"); fmpz_poly_set_str(series->Q, "4 0 0 0 10939058860032000"); prec += FLINT_CLOG2(prec) + 5; arb_hypgeom_infsum(s, t, series, prec, prec); arb_rsqrt_ui(u, 640320, prec); arb_mul(s, s, u, prec); arb_mul_ui(t, t, 640320 / 12, prec); arb_div(s, t, s, prec); hypgeom_clear(series); arb_clear(t); arb_clear(u); } ARB_DEF_CACHED_CONSTANT(arb_const_pi_chudnovsky, arb_const_pi_chudnovsky_eval) void arb_const_pi(arb_t res, slong prec) { if (prec < ARB_PI4_TAB_LIMBS * FLINT_BITS - 16) { slong exp; /* just reading the table is known to give the correct rounding */ _arf_set_round_mpn(arb_midref(res), &exp, arb_pi4_tab, ARB_PI4_TAB_LIMBS, 0, prec, ARF_RND_NEAR); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), 2 + exp); /* 1/2 ulp error */ _fmpz_set_si_small(MAG_EXPREF(arb_radref(res)), 2 + exp - prec); MAG_MAN(arb_radref(res)) = MAG_ONE_HALF; } else { arb_const_pi_chudnovsky(res, prec); } } arb-2.22.1/arb/const_sqrt_pi.c000066400000000000000000000010711417376376500161630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_const_sqrt_pi(arb_t t, slong prec) { arb_const_pi(t, prec + 2); arb_sqrt(t, t, prec); } ARB_DEF_CACHED_CONSTANT(arb_const_sqrt_pi, _arb_const_sqrt_pi) arb-2.22.1/arb/contains.c000066400000000000000000000037121417376376500151160ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains(const arb_t x, const arb_t y) { arf_t t; arf_t u; arf_t xr, yr; arf_struct tmp[4]; int left_ok, right_ok; if (arb_is_exact(y)) return arb_contains_arf(x, arb_midref(y)); if (arf_is_nan(arb_midref(y))) return arf_is_nan(arb_midref(x)); arf_init(t); arf_init(u); arf_init_set_mag_shallow(xr, arb_radref(x)); arf_init_set_mag_shallow(yr, arb_radref(y)); /* fast check */ arf_sub(t, arb_midref(x), xr, MAG_BITS, ARF_RND_CEIL); arf_sub(u, arb_midref(y), yr, MAG_BITS, ARF_RND_FLOOR); left_ok = arf_cmp(t, u) <= 0; /* exact check */ if (!left_ok) { arf_init_set_shallow(tmp + 0, arb_midref(x)); arf_init_neg_mag_shallow(tmp + 1, arb_radref(x)); arf_init_neg_shallow(tmp + 2, arb_midref(y)); arf_init_set_mag_shallow(tmp + 3, arb_radref(y)); arf_sum(t, tmp, 4, MAG_BITS, ARF_RND_DOWN); left_ok = arf_sgn(t) <= 0; } /* fast check */ arf_add(t, arb_midref(x), xr, MAG_BITS, ARF_RND_FLOOR); arf_add(u, arb_midref(y), yr, MAG_BITS, ARF_RND_CEIL); right_ok = (arf_cmp(t, u) >= 0); /* exact check */ if (!right_ok) { arf_init_set_shallow(tmp + 0, arb_midref(x)); arf_init_set_mag_shallow(tmp + 1, arb_radref(x)); arf_init_neg_shallow(tmp + 2, arb_midref(y)); arf_init_neg_mag_shallow(tmp + 3, arb_radref(y)); arf_sum(t, tmp, 4, MAG_BITS, ARF_RND_DOWN); right_ok = arf_sgn(t) >= 0; } arf_clear(t); arf_clear(u); return left_ok && right_ok; } arb-2.22.1/arb/contains_arf.c000066400000000000000000000025561417376376500157530ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains_arf(const arb_t x, const arf_t y) { if (arf_is_nan(y)) { return arf_is_nan(arb_midref(x)); } else if (arf_is_nan(arb_midref(x))) { return 1; } else if (arb_is_exact(x)) { return arf_equal(arb_midref(x), y); } else { arf_t t; arf_struct tmp[3]; int result; arf_init(t); /* y >= xm - xr <=> 0 >= xm - xr - y */ arf_init_set_shallow(tmp + 0, arb_midref(x)); arf_init_neg_mag_shallow(tmp + 1, arb_radref(x)); arf_init_neg_shallow(tmp + 2, y); arf_sum(t, tmp, 3, MAG_BITS, ARF_RND_DOWN); result = (arf_sgn(t) <= 0); if (result) { /* y <= xm + xr <=> 0 <= xm + xr - y */ arf_init_set_mag_shallow(tmp + 1, arb_radref(x)); arf_sum(t, tmp, 3, MAG_BITS, ARF_RND_DOWN); result = (arf_sgn(t) >= 0); } arf_clear(t); return result; } } arb-2.22.1/arb/contains_fmpq.c000066400000000000000000000032161417376376500161400ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains_fmpq(const arb_t x, const fmpq_t y) { if (fmpz_is_one(fmpq_denref(y)) || !arb_is_finite(x)) { return arb_contains_fmpz(x, fmpq_numref(y)); } else { arf_t t, xm, xr, ym; arf_struct tmp[3]; int result; arf_init(t); arf_init(xm); arf_init(xr); arf_init(ym); /* To compare x with p/q, compare qx with p. */ arf_mul_fmpz(xm, arb_midref(x), fmpq_denref(y), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_mag(xr, arb_radref(x)); arf_mul_fmpz(xr, xr, fmpq_denref(y), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_fmpz(ym, fmpq_numref(y)); /* y >= xm - xr <=> 0 >= xm - xr - y */ arf_init_set_shallow(tmp + 0, xm); arf_init_neg_shallow(tmp + 1, xr); arf_init_neg_shallow(tmp + 2, ym); arf_sum(t, tmp, 3, 30, ARF_RND_DOWN); result = (arf_sgn(t) <= 0); if (result) { /* y <= xm + xr <=> 0 <= xm + xr - y */ arf_init_set_shallow(tmp + 1, xr); arf_sum(t, tmp, 3, 30, ARF_RND_DOWN); result = (arf_sgn(t) >= 0); } arf_clear(t); arf_clear(xm); arf_clear(xr); arf_clear(ym); return result; } } arb-2.22.1/arb/contains_fmpz.c000066400000000000000000000011171417376376500161470ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains_fmpz(const arb_t x, const fmpz_t y) { int ans; arf_t t; arf_init(t); arf_set_fmpz(t, y); ans = arb_contains_arf(x, t); arf_clear(t); return ans; } arb-2.22.1/arb/contains_int.c000066400000000000000000000022241417376376500157650ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains_int(const arb_t x) { if (arf_is_int(arb_midref(x))) { return 1; } else if (!arb_is_finite(x)) { return arb_contains_zero(x); } else if (arb_is_exact(x)) { return 0; } else if (mag_cmp_2exp_si(arb_radref(x), -1) >= 0) /* radius >= 1/2 */ { return 1; } else { /* radius is < 1/2, so it's enough to test the two integers bracketing the midpoint */ arf_t t; int res; arf_init(t); arf_floor(t, arb_midref(x)); res = arb_contains_arf(x, t); if (!res) { arf_ceil(t, arb_midref(x)); res = arb_contains_arf(x, t); } arf_clear(t); return res; } } arb-2.22.1/arb/contains_interior.c000066400000000000000000000036221417376376500170310ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains_interior(const arb_t x, const arb_t y) { arf_t t; arf_t u; arf_t xr, yr; arf_struct tmp[4]; int left_ok, right_ok; if (arf_is_nan(arb_midref(x)) || arb_is_exact(x) || !arb_is_finite(y)) return 0; arf_init(t); arf_init(u); arf_init_set_mag_shallow(xr, arb_radref(x)); arf_init_set_mag_shallow(yr, arb_radref(y)); /* fast check */ arf_sub(t, arb_midref(x), xr, MAG_BITS, ARF_RND_CEIL); arf_sub(u, arb_midref(y), yr, MAG_BITS, ARF_RND_FLOOR); left_ok = arf_cmp(t, u) < 0; /* exact check */ if (!left_ok) { arf_init_set_shallow(tmp + 0, arb_midref(x)); arf_init_neg_mag_shallow(tmp + 1, arb_radref(x)); arf_init_neg_shallow(tmp + 2, arb_midref(y)); arf_init_set_mag_shallow(tmp + 3, arb_radref(y)); arf_sum(t, tmp, 4, MAG_BITS, ARF_RND_DOWN); left_ok = arf_sgn(t) < 0; } /* fast check */ arf_add(t, arb_midref(x), xr, MAG_BITS, ARF_RND_FLOOR); arf_add(u, arb_midref(y), yr, MAG_BITS, ARF_RND_CEIL); right_ok = (arf_cmp(t, u) > 0); /* exact check */ if (!right_ok) { arf_init_set_shallow(tmp + 0, arb_midref(x)); arf_init_set_mag_shallow(tmp + 1, arb_radref(x)); arf_init_neg_shallow(tmp + 2, arb_midref(y)); arf_init_neg_mag_shallow(tmp + 3, arb_radref(y)); arf_sum(t, tmp, 4, MAG_BITS, ARF_RND_DOWN); right_ok = arf_sgn(t) > 0; } arf_clear(t); arf_clear(u); return left_ok && right_ok; } arb-2.22.1/arb/contains_mpfr.c000066400000000000000000000011161417376376500161360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains_mpfr(const arb_t x, const mpfr_t y) { int ans; arf_t t; arf_init(t); arf_set_mpfr(t, y); ans = arb_contains_arf(x, t); arf_clear(t); return ans; } arb-2.22.1/arb/contains_si.c000066400000000000000000000011041417376376500156020ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_contains_si(const arb_t x, slong y) { int ans; arf_t t; arf_init(t); arf_set_si(t, y); ans = arb_contains_arf(x, t); arf_clear(t); return ans; } arb-2.22.1/arb/cot.c000066400000000000000000000010641417376376500140630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_cot(arb_t y, const arb_t x, slong prec) { arb_t u; arb_init(u); arb_sin_cos(y, u, x, prec + 4); arb_div(y, u, y, prec); arb_clear(u); } arb-2.22.1/arb/cot_pi.c000066400000000000000000000015001417376376500145460ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_cot_pi(arb_t y, const arb_t x, slong prec) { if (!arb_is_finite(x)) { arb_indeterminate(y); } else if (arb_is_int_2exp_si(x, -1)) { if (arb_is_int(x)) arb_indeterminate(y); else arb_zero(y); } else { arb_t u; arb_init(u); arb_sin_cos_pi(y, u, x, prec + 4); arb_div(y, u, y, prec); arb_clear(u); } } arb-2.22.1/arb/coth.c000066400000000000000000000022211417376376500142270ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_coth(arb_t y, const arb_t x, slong prec) { arb_t t, u; int sign = arf_sgn(arb_midref(x)) < 0; arb_init(t); arb_init(u); arb_mul_2exp_si(t, x, 1); if (!sign) arb_neg(t, t); if (arf_cmpabs_2exp_si(arb_midref(x), 1) > 0) { /* coth(x) = 1 + 2 exp(-2x) / (1 - exp(-2x)) */ arb_exp(t, t, prec + 4); arb_sub_ui(u, t, 1, prec + 4); arb_div(y, t, u, prec + 4); arb_mul_2exp_si(y, y, 1); arb_sub_ui(y, y, 1, prec); } else { /* coth(x) = (exp(2x) + 1) / (exp(2x) - 1) */ arb_expm1(t, t, prec + 4); arb_add_ui(y, t, 2, prec + 4); arb_div(y, y, t, prec); } if (!sign) arb_neg(y, y); arb_clear(t); arb_clear(u); } arb-2.22.1/arb/csc.c000066400000000000000000000010021417376376500140360ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_csc(arb_t res, const arb_t x, slong prec) { arb_sin(res, x, prec + 4); arb_inv(res, res, prec); } arb-2.22.1/arb/csc_pi.c000066400000000000000000000010571417376376500145400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson Copyright (C) 2017 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_csc_pi(arb_t res, const arb_t x, slong prec) { arb_sin_pi(res, x, prec + 4); arb_inv(res, res, prec); } arb-2.22.1/arb/csch.c000066400000000000000000000024121417376376500142140ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_csch(arb_t res, const arb_t x, slong prec) { if (arb_contains_zero(x) || !arb_is_finite(x)) { arb_indeterminate(res); } else if (arf_cmpabs_2exp_si(arb_midref(x), 0) > 0) { arb_t t; arb_init(t); if (arf_sgn(arb_midref(x)) > 0) { arb_neg(t, x); arb_exp(t, t, prec + 4); arb_mul(res, t, t, prec + 4); arb_sub_ui(res, res, 1, prec + 4); arb_div(res, t, res, prec); arb_neg(res, res); } else { arb_exp(t, x, prec + 4); arb_mul(res, t, t, prec + 4); arb_sub_ui(res, res, 1, prec + 4); arb_div(res, t, res, prec); } arb_mul_2exp_si(res, res, 1); arb_clear(t); } else { arb_sinh(res, x, prec + 4); arb_inv(res, res, prec); } } arb-2.22.1/arb/digamma.c000066400000000000000000000050111417376376500146710ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "arb.h" void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec); void arb_gamma_stirling_eval(arb_t s, const arb_t z, slong nterms, int digamma, slong prec); void arb_digamma(arb_t y, const arb_t x, slong prec) { int reflect; slong r, n, wp; arb_t t, u, v; if (arb_is_exact(x)) { const arf_struct * mid = arb_midref(x); if (arf_is_special(mid)) { arb_indeterminate(y); return; } else if (arf_is_int(mid)) { if (arf_sgn(mid) < 0) { arb_indeterminate(y); return; } else if (arf_cmpabs_ui(mid, 30 + prec / 2) < 0) { fmpq_t h; arb_init(t); fmpq_init(h); /* should change to fmpq_harmonic_ui when flint upgrades */ arith_harmonic_number(h, arf_get_si(mid, ARF_RND_DOWN) - 1); arb_set_fmpq(y, h, prec + 2); arb_const_euler(t, prec + 2); arb_sub(y, y, t, prec); arb_clear(t); fmpq_clear(h); return; } } } wp = prec + FLINT_BIT_COUNT(prec); arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 1, wp); arb_init(t); arb_init(u); arb_init(v); /* psi(x) = psi((1-x)+r) - h(1-x,r) - pi*cot(pi*x) */ if (reflect) { arb_sub_ui(t, x, 1, wp); arb_neg(t, t); arb_cot_pi(v, x, wp); arb_const_pi(u, wp); arb_mul(v, v, u, wp); arb_rising2_ui(y, u, t, r, wp); arb_div(u, u, y, wp); arb_add(v, v, u, wp); arb_add_ui(t, t, r, wp); arb_gamma_stirling_eval(u, t, n, 1, wp); arb_sub(y, u, v, wp); } else { arb_add_ui(t, x, r, wp); arb_gamma_stirling_eval(u, t, n, 1, wp); arb_rising2_ui(y, t, x, r, wp); arb_div(t, t, y, wp); arb_sub(y, u, t, prec); } arb_clear(t); arb_clear(u); arb_clear(v); } arb-2.22.1/arb/div.c000066400000000000000000000221351417376376500140620ustar00rootroot00000000000000/* Copyright (C) 2014, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_div_arf(arb_t z, const arb_t x, const arf_t y, slong prec) { mag_t zr, ym; int inexact; if (arf_is_special(y) || !arb_is_finite(x)) { if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x)) && arf_is_finite(y) && !arf_is_zero(y)) { /* inf / finite nonzero = inf */ arf_div(arb_midref(z), arb_midref(x), y, prec, ARF_RND_DOWN); mag_zero(arb_radref(z)); } else if (arb_is_finite(x) && arf_is_inf(y)) { /* finite / inf = 0 */ arb_zero(z); } else if (!arf_is_nan(arb_midref(x)) && mag_is_inf(arb_radref(x)) && arf_is_finite(y) && !arf_is_zero(y)) { /* [+/- inf] / finite nonzero = [+/- inf] */ arb_zero_pm_inf(z); } else { arb_indeterminate(z); } } else if (mag_is_zero(arb_radref(x))) { inexact = arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); else mag_zero(arb_radref(z)); } else { mag_init(ym); mag_init(zr); arf_get_mag_lower(ym, y); mag_div(zr, arb_radref(x), ym); inexact = arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_swap(arb_radref(z), zr); mag_clear(ym); mag_clear(zr); } } static void arb_div_wide(arb_t z, const arb_t x, const arb_t y, slong prec) { mag_t a, b, t, u; mag_init(t); arb_get_mag_lower(t, y); if (mag_is_zero(t)) { arb_indeterminate(z); } else if (arf_is_zero(arb_midref(x))) { mag_div(arb_radref(z), arb_radref(x), t); arf_zero(arb_midref(z)); } else { if (arf_cmpabs_mag(arb_midref(x), arb_radref(x)) >= 0) { /* [a,b] / [t,u] = [a/u, b/t] [a,b] / -[t,u] = -[a/u, b/t] -[a,b] / [t,u] = -[a/u, b/t] -[a,b] / -[t,u] = [a/u, b/t] */ mag_init(a); mag_init(b); mag_init(u); arb_get_mag_lower(a, x); arb_get_mag(b, x); arb_get_mag(u, y); mag_div_lower(a, a, u); mag_div(b, b, t); if ((arf_sgn(arb_midref(x)) < 0) ^ (arf_sgn(arb_midref(y)) < 0)) { arb_set_interval_mag(z, a, b, prec); arb_neg(z, z); } else { arb_set_interval_mag(z, a, b, prec); } mag_clear(a); mag_clear(b); mag_clear(u); } else { /* [-a,b] / [t,u] = [-a/t, b/t] [-a,b] / -[t,u] = [-b/t, a/t] */ mag_init(a); mag_init(b); arb_get_mag(b, x); arf_get_mag_lower(a, arb_midref(x)); mag_sub(a, arb_radref(x), a); if ((arf_sgn(arb_midref(x)) < 0) ^ (arf_sgn(arb_midref(y)) < 0)) mag_swap(a, b); mag_div(a, a, t); mag_div(b, b, t); arb_set_interval_neg_pos_mag(z, a, b, prec); mag_clear(a); mag_clear(b); } } mag_clear(t); } void arb_div(arb_t z, const arb_t x, const arb_t y, slong prec) { int inexact; slong acc, xacc, yacc; if (mag_is_zero(arb_radref(y))) { arb_div_arf(z, x, arb_midref(y), prec); } else if (arf_is_zero(arb_midref(y))) /* anything / 0 = nan */ { arb_indeterminate(z); } else if (ARB_IS_LAGOM(x) && ARB_IS_LAGOM(y)) /* fast case */ { /* both finite, both midpoint and radius of y not special */ yacc = MAG_EXP(arb_midref(y)) - ARF_EXP(arb_radref(y)); xacc = arb_rel_accuracy_bits(x); acc = FLINT_MIN(xacc, yacc); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); if (acc <= 20) { arb_div_wide(z, x, y, prec); } else { mag_t t, u, v; mag_init(t); /* no need to free */ mag_init(u); mag_init(v); /* (x*yrad + y*xrad)/(y*(y-yrad)) <= (1+eps) (x*yrad + y*xrad)/y^2 <= (1+eps) (x*yrad/y^2 + y*xrad/y^2) <= (1+eps) ((x/y)*yrad/y + xrad/y) <= (1+eps) ((x/y)*yrad + xrad)/y */ /* t = y */ arf_get_mag_lower(t, arb_midref(y)); inexact = arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); /* u = x/y */ arf_get_mag(u, arb_midref(z)); /* v = (x/y)*yrad + xrad */ MAG_MAN(v) = MAG_MAN(arb_radref(x)); MAG_EXP(v) = MAG_EXP(arb_radref(x)); mag_fast_addmul(v, arb_radref(y), u); /* v = v / y */ mag_div(arb_radref(z), v, t); /* correct for errors */ MAG_MAN(t) = MAG_ONE_HALF + (MAG_ONE_HALF >> 16); MAG_EXP(t) = 1; mag_fast_mul(arb_radref(z), arb_radref(z), t); if (inexact) arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } } else if (!arb_is_finite(y)) { /* finite / inf = 0 */ if (arf_is_inf(arb_midref(y)) && mag_is_finite(arb_radref(y)) && arb_is_finite(x)) arb_zero(z); else arb_indeterminate(z); } else if (!arb_is_finite(x)) { if (arb_contains_zero(y) || arf_is_nan(arb_midref(x))) { arb_indeterminate(z); } else { /* +/- inf / finite nonzero = +/- inf */ if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) { arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARF_RND_DOWN); mag_zero(arb_radref(z)); } else if (!arf_is_nan(arb_midref(x)) && mag_is_inf(arb_radref(x))) { arb_zero_pm_inf(z); } else { arb_indeterminate(z); } } } else { yacc = arb_rel_accuracy_bits(y); xacc = arb_rel_accuracy_bits(x); acc = FLINT_MIN(xacc, yacc); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); if (acc <= 20) { arb_div_wide(z, x, y, prec); } else { mag_t zr, xm, ym, yl, yw; mag_init_set_arf(xm, arb_midref(x)); mag_init_set_arf(ym, arb_midref(y)); mag_init(zr); mag_init(yl); mag_init(yw); /* (|x|*yrad + |y|*xrad)/(|y|*(|y|-yrad)) */ mag_mul(zr, xm, arb_radref(y)); mag_addmul(zr, ym, arb_radref(x)); arb_get_mag_lower(yw, y); arf_get_mag_lower(yl, arb_midref(y)); mag_mul_lower(yl, yl, yw); mag_div(zr, zr, yl); inexact = arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_swap(arb_radref(z), zr); mag_clear(xm); mag_clear(ym); mag_clear(zr); mag_clear(yl); mag_clear(yw); } } } void arb_div_si(arb_t z, const arb_t x, slong y, slong prec) { arf_t t; arf_init_set_si(t, y); /* no need to free */ arb_div_arf(z, x, t, prec); } void arb_div_ui(arb_t z, const arb_t x, ulong y, slong prec) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ arb_div_arf(z, x, t, prec); } void arb_div_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) { arf_t t; if (!COEFF_IS_MPZ(*y)) { arf_init_set_si(t, *y); /* no need to free */ arb_div_arf(z, x, t, prec); } else { arf_init(t); arf_set_fmpz(t, y); arb_div_arf(z, x, t, prec); arf_clear(t); } } void arb_fmpz_div_fmpz(arb_t z, const fmpz_t x, const fmpz_t y, slong prec) { int inexact; inexact = arf_fmpz_div_fmpz(arb_midref(z), x, y, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); else mag_zero(arb_radref(z)); } void arb_ui_div(arb_t z, ulong x, const arb_t y, slong prec) { arb_t t; arb_init(t); arb_set_ui(t, x); arb_div(z, t, y, prec); arb_clear(t); } arb-2.22.1/arb/div_2expm1_ui.c000066400000000000000000000027551417376376500157610ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_div_2expm1_ui(arb_t y, const arb_t x, ulong n, slong prec) { if (n < FLINT_BITS) { arb_div_ui(y, x, (UWORD(1) << n) - 1, prec); } else if (n < 1024 + prec / 32 || n > WORD_MAX / 4) { arb_t t; fmpz_t e; arb_init(t); fmpz_init_set_ui(e, n); arb_one(t); arb_mul_2exp_fmpz(t, t, e); arb_sub_ui(t, t, 1, prec); arb_div(y, x, t, prec); arb_clear(t); fmpz_clear(e); } else { arb_t s, t; slong i, b; arb_init(s); arb_init(t); /* x / (2^n - 1) = sum_{k>=1} x * 2^(-k*n)*/ arb_mul_2exp_si(s, x, -n); arb_set(t, s); b = 1; for (i = 2; i <= prec / n + 1; i++) { arb_mul_2exp_si(t, t, -n); arb_add(s, s, t, prec); b = i; } /* error bound: sum_{k>b} x * 2^(-k*n) <= x * 2^(-b*n - (n-1)) */ arb_mul_2exp_si(t, x, -b*n - (n-1)); arb_abs(t, t); arb_add_error(s, t); arb_set(y, s); arb_clear(s); arb_clear(t); } } arb-2.22.1/arb/dot.c000066400000000000000000000744121417376376500140730ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* We need uint64_t instead of mp_limb_t on 32-bit systems for safe summation of 30-bit error bounds. */ #include /* The following macros are found in FLINT's longlong.h, but the release version is out of date. */ /* x86 : 64 bit */ #if (GMP_LIMB_BITS == 64 && defined (__amd64__)) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addq %8,%q2\n\tadcq %6,%q1\n\tadcq %4,%q0" \ : "=r" (sh), "=&r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "rme" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "rme" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "rme" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subq %8,%q2\n\tsbbq %6,%q1\n\tsbbq %4,%q0" \ : "=r" (dh), "=&r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "rme" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "rme" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "rme" ((mp_limb_t)(sl))) \ #endif /* x86_64 */ /* x86 : 32 bit */ #if (GMP_LIMB_BITS == 32 && (defined (__i386__) \ || defined (__i486__) || defined(__amd64__))) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ __asm__ ("addl %8,%k2\n\tadcl %6,%k1\n\tadcl %4,%k0" \ : "=r" (sh), "=r" (sm), "=&r" (sl) \ : "0" ((mp_limb_t)(ah)), "g" ((mp_limb_t)(bh)), \ "1" ((mp_limb_t)(am)), "g" ((mp_limb_t)(bm)), \ "2" ((mp_limb_t)(al)), "g" ((mp_limb_t)(bl))) \ #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ __asm__ ("subl %8,%k2\n\tsbbl %6,%k1\n\tsbbl %4,%k0" \ : "=r" (dh), "=r" (dm), "=&r" (dl) \ : "0" ((mp_limb_t)(mh)), "g" ((mp_limb_t)(sh)), \ "1" ((mp_limb_t)(mm)), "g" ((mp_limb_t)(sm)), \ "2" ((mp_limb_t)(ml)), "g" ((mp_limb_t)(sl))) \ #endif /* x86 */ #if !defined(add_sssaaaaaa2) #define add_sssaaaaaa2(sh, sm, sl, ah, am, al, bh, bm, bl) \ do { \ mp_limb_t __t, __u; \ add_ssaaaa(__t, sl, (mp_limb_t) 0, al, (mp_limb_t) 0, bl); \ add_ssaaaa(__u, sm, (mp_limb_t) 0, am, (mp_limb_t) 0, bm); \ add_ssaaaa(sh, sm, ah + bh, sm, __u, __t); \ } while (0) #define sub_dddmmmsss2(dh, dm, dl, mh, mm, ml, sh, sm, sl) \ do { \ mp_limb_t __t, __u; \ sub_ddmmss(__t, dl, (mp_limb_t) 0, ml, (mp_limb_t) 0, sl); \ sub_ddmmss(__u, dm, (mp_limb_t) 0, mm, (mp_limb_t) 0, sm); \ sub_ddmmss(dh, dm, mh - sh, dm, -__u, -__t); \ } while (0) #endif void mpfr_mulhigh_n(mp_ptr rp, mp_srcptr np, mp_srcptr mp, mp_size_t n); void mpfr_sqrhigh_n(mp_ptr rp, mp_srcptr np, mp_size_t n); /* Add ((a * b) / 2^MAG_BITS) * 2^exp into srad*2^srad_exp. Assumes that srad_exp >= exp and that overflow cannot occur. */ #define RAD_ADDMUL(srad, srad_exp, a, b, exp) \ do { \ uint64_t __a, __b; \ slong __shift; \ __a = (a); \ __b = (b); \ __shift = (srad_exp) - (exp); \ if (__shift < MAG_BITS) \ (srad) += (((__a) * (__b)) >> (MAG_BITS + __shift)) + 1; \ else \ (srad) += 1; \ } while (0) /* mag_set_ui_2exp_si but assumes no promotion can occur. Do we need this? */ void mag_set_ui_2exp_small(mag_t z, ulong x, slong e) { _fmpz_demote(MAG_EXPREF(z)); if (x == 0) { MAG_EXP(z) = 0; MAG_MAN(z) = 0; } else { slong bits; mp_limb_t overflow; count_leading_zeros(bits, x); bits = FLINT_BITS - bits; if (bits <= MAG_BITS) { x = x << (MAG_BITS - bits); } else { x = (x >> (bits - MAG_BITS)) + 1; overflow = x >> MAG_BITS; bits += overflow; x >>= overflow; } MAG_EXP(z) = bits + e; MAG_MAN(z) = x; } } /* Sets rad to (Aerr 2^Aexp + Berr 2^Bexp + Cerr 2^Cexp) 2^(-MAG_BITS). Assumes that overflow cannot occur. */ static void add_errors(mag_t rad, uint64_t Aerr, slong Aexp, uint64_t Berr, slong Bexp, uint64_t Cerr, slong Cexp) { slong shift; if (Aerr && Berr) { if (Aexp >= Bexp) { shift = Aexp - Bexp; if (shift < 64) Aerr = Aerr + (Berr >> shift) + 1; else Aerr = Aerr + 1; } else { shift = Bexp - Aexp; if (shift < 64) Aerr = Berr + (Aerr >> shift) + 1; else Aerr = Berr + 1; Aexp = Bexp; } } else if (Berr) { Aerr = Berr; Aexp = Bexp; } if (Aerr && Cerr) { if (Aexp >= Cexp) { shift = Aexp - Cexp; if (shift < 64) Aerr = Aerr + (Cerr >> shift) + 1; else Aerr = Aerr + 1; } else { shift = Cexp - Aexp; if (shift < 64) Aerr = Cerr + (Aerr >> shift) + 1; else Aerr = Cerr + 1; Aexp = Cexp; } } else if (Cerr) { Aerr = Cerr; Aexp = Cexp; } #if FLINT_BITS == 64 mag_set_ui_2exp_small(rad, Aerr, Aexp - MAG_BITS); #else mag_set_d(rad, Aerr * (1.0 + 1e-14)); mag_mul_2exp_si(rad, rad, Aexp - MAG_BITS); #endif } static void mulhigh(mp_ptr res, mp_srcptr xptr, mp_size_t xn, mp_srcptr yptr, mp_size_t yn, mp_size_t nn) { mp_ptr tmp, xxx, yyy; slong k; ARF_MUL_TMP_DECL; ARF_MUL_TMP_ALLOC(tmp, 2 * nn); xxx = tmp; yyy = tmp + nn; mpn_copyi(xxx + nn - FLINT_MIN(xn, nn), xptr + xn - FLINT_MIN(xn, nn), FLINT_MIN(xn, nn)); mpn_copyi(yyy + nn - FLINT_MIN(yn, nn), yptr + yn - FLINT_MIN(yn, nn), FLINT_MIN(yn, nn)); for (k = 0; k < nn - xn; k++) xxx[k] = 0; for (k = 0; k < nn - yn; k++) yyy[k] = 0; if (xptr == yptr && xn == yn) mpfr_sqrhigh_n(res, xxx, nn); else mpfr_mulhigh_n(res, xxx, yyy, nn); ARF_MUL_TMP_FREE(tmp, 2 * nn); } void _arb_dot_addmul_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, mp_srcptr yptr, mp_size_t yn, int negative, flint_bitcnt_t shift) { slong shift_bits, shift_limbs, term_prec; mp_limb_t cy; mp_ptr sstart, tstart; mp_size_t tn, nn; shift_bits = shift % FLINT_BITS; shift_limbs = shift / FLINT_BITS; /* shift term_prec (discarded bits) |--------------------|--------------| | t[tn-1] | ... | t[0] | Term [ s[n-1] | s[n-2] | ... | s[0] ] Sum */ /* Upper bound for the term bit length. The actual term bit length could be smaller if the product does not extend all the way down to s. */ term_prec = sn * FLINT_BITS - shift; /* The mulhigh error relative to the top of the sum will be bounded by nn * 2^(-shift) * 2^(-FLINT_BITS*nn). One extra limb ensures that this is <1 sum-ulp. */ term_prec += FLINT_BITS; nn = (term_prec + FLINT_BITS - 1) / FLINT_BITS; /* Sanity check; must conform to the pre-allocated memory! */ if (nn > sn + 2) { flint_printf("nn > sn + 2\n"); flint_abort(); } /* Use mulhigh? */ if (term_prec >= MUL_MPFR_MIN_LIMBS * FLINT_BITS && term_prec <= MUL_MPFR_MAX_LIMBS * FLINT_BITS && xn * FLINT_BITS > 0.9 * term_prec && yn * FLINT_BITS > 0.9 * term_prec) { mulhigh(tmp, xptr, xn, yptr, yn, nn); tstart = tmp + nn; tn = nn; serr[0]++; } else { if (xn > nn || yn > nn) { if (xn > nn) { xptr += (xn - nn); xn = nn; } if (yn > nn) { yptr += (yn - nn); yn = nn; } serr[0]++; } tn = xn + yn; ARF_MPN_MUL(tmp + 1, xptr, xn, yptr, yn); tstart = tmp + 1; } if (shift_bits != 0) { tstart[-1] = mpn_rshift(tstart, tstart, tn, shift_bits); tstart = tstart - 1; tn++; } while (tstart[0] == 0) { tstart++; tn--; } if (shift_limbs + tn <= sn) { /* No truncation of the term. */ sstart = sum + sn - shift_limbs - tn; nn = tn; } else { /* The term is truncated. */ sstart = sum; tstart = tstart - (sn - shift_limbs - tn); nn = sn - shift_limbs; serr[0]++; } /* Likely case. Note: assumes 1 extra (dummy) limb in sum. */ if (shift_limbs <= 1) { if (negative) sstart[nn] -= mpn_sub_n(sstart, sstart, tstart, nn); else sstart[nn] += mpn_add_n(sstart, sstart, tstart, nn); } else { if (negative) { cy = mpn_sub_n(sstart, sstart, tstart, nn); mpn_sub_1(sstart + nn, sstart + nn, shift_limbs, cy); } else { cy = mpn_add_n(sstart, sstart, tstart, nn); mpn_add_1(sstart + nn, sstart + nn, shift_limbs, cy); } } } void _arb_dot_add_generic(mp_ptr sum, mp_ptr serr, mp_ptr tmp, mp_size_t sn, mp_srcptr xptr, mp_size_t xn, int negative, flint_bitcnt_t shift) { slong shift_bits, shift_limbs, term_prec; mp_limb_t cy, err; mp_ptr sstart, tstart; mp_size_t tn, nn; shift_bits = shift % FLINT_BITS; shift_limbs = shift / FLINT_BITS; term_prec = sn * FLINT_BITS - shift; term_prec += FLINT_BITS; nn = (term_prec + FLINT_BITS - 1) / FLINT_BITS; err = 0; if (xn > nn) { xptr += (xn - nn); xn = nn; err = 1; } tn = xn; if (shift_bits == 0) { mpn_copyi(tmp, xptr, tn); tstart = tmp; } else { tmp[0] = mpn_rshift(tmp + 1, xptr, tn, shift_bits); tstart = tmp; tn++; } while (tstart[0] == 0) { tstart++; tn--; } if (shift_limbs + tn <= sn) { /* No truncation of the term. */ sstart = sum + sn - shift_limbs - tn; nn = tn; } else { /* The term is truncated. */ sstart = sum; tstart = tstart - (sn - shift_limbs - tn); nn = sn - shift_limbs; err = 1; } serr[0] += err; /* Likely case. Note: assumes 1 extra (dummy) limb in sum. */ if (shift_limbs <= 1) { if (negative) sstart[nn] -= mpn_sub_n(sstart, sstart, tstart, nn); else sstart[nn] += mpn_add_n(sstart, sstart, tstart, nn); } else { if (negative) { cy = mpn_sub_n(sstart, sstart, tstart, nn); mpn_sub_1(sstart + nn, sstart + nn, shift_limbs, cy); } else { cy = mpn_add_n(sstart, sstart, tstart, nn); mpn_add_1(sstart + nn, sstart + nn, shift_limbs, cy); } } } void arb_dot(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) { slong i, j, nonzero, padding, extend; slong xexp, yexp, exp, max_exp, min_exp, sum_exp; slong xrexp, yrexp, srad_exp, max_rad_exp; int xnegative, ynegative, inexact; mp_size_t xn, yn, sn, alloc; flint_bitcnt_t shift; arb_srcptr xi, yi; arf_srcptr xm, ym; mag_srcptr xr, yr; mp_limb_t xtop, ytop; mp_limb_t xrad, yrad; mp_limb_t serr; /* Sum over arithmetic errors */ uint64_t srad; /* Sum over propagated errors */ mp_ptr tmp, sum; /* Workspace */ ARF_ADD_TMP_DECL; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) arb_zero(res); else { arb_mul(res, x, y, prec); if (subtract) arb_neg(res, res); } return; } else if (len <= 0) { arb_set_round(res, initial, prec); return; } } /* Number of nonzero midpoint terms in sum. */ nonzero = 0; /* Terms are bounded by 2^max_exp (with WORD_MIN = -infty) */ max_exp = WORD_MIN; /* Propagated error terms are bounded by 2^max_rad_exp */ max_rad_exp = WORD_MIN; /* Used to reduce the precision. */ min_exp = WORD_MAX; /* Account for the initial term. */ if (initial != NULL) { if (!ARB_IS_LAGOM(initial)) { arb_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(initial); xr = arb_radref(initial); if (!arf_is_special(xm)) { max_exp = ARF_EXP(xm); nonzero++; if (prec > 2 * FLINT_BITS) min_exp = ARF_EXP(xm) - ARF_SIZE(xm) * FLINT_BITS; } if (!mag_is_special(xr)) max_rad_exp = MAG_EXP(xr); } /* Determine maximum exponents for the main sum and the radius sum. */ for (i = 0; i < len; i++) { xi = x + i * xstep; yi = y + i * ystep; /* Fallback for huge exponents or non-finite values. */ if (!ARB_IS_LAGOM(xi) || !ARB_IS_LAGOM(yi)) { arb_dot_simple(res, initial, subtract, x, xstep, y, ystep, len, prec); return; } xm = arb_midref(xi); ym = arb_midref(yi); xr = arb_radref(xi); yr = arb_radref(yi); /* (xm+xr)(ym+yr) = xm ym + [xr ym + xm yr + xr yr] */ if (!arf_is_special(xm)) { xexp = ARF_EXP(xm); if (!arf_is_special(ym)) { yexp = ARF_EXP(ym); max_exp = FLINT_MAX(max_exp, xexp + yexp); nonzero++; if (prec > 2 * FLINT_BITS) { slong bot; bot = (xexp + yexp) - (ARF_SIZE(xm) + ARF_SIZE(ym)) * FLINT_BITS; min_exp = FLINT_MIN(min_exp, bot); } if (!mag_is_special(xr)) { xrexp = MAG_EXP(xr); max_rad_exp = FLINT_MAX(max_rad_exp, yexp + xrexp); if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xexp + yrexp); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yrexp); } } else { if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xexp + yrexp); } } } else /* if y = 0, something can happen only if yr != 0 */ { if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xexp + yrexp); if (!mag_is_special(xr)) { xrexp = MAG_EXP(xr); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yrexp); } } } } else /* if x = 0, something can happen only if xr != 0 */ { if (!mag_is_special(xr)) { xrexp = MAG_EXP(xr); if (!arf_is_special(ym)) { yexp = ARF_EXP(ym); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yexp); } if (!mag_is_special(yr)) { yrexp = MAG_EXP(yr); max_rad_exp = FLINT_MAX(max_rad_exp, xrexp + yrexp); } } } } /* The midpoint sum is zero. */ if (max_exp == WORD_MIN) { /* The sum is exactly zero. */ if (max_rad_exp == WORD_MIN) { arb_zero(res); return; } prec = 2; } else { /* Reduce precision based on errors. */ if (max_rad_exp != WORD_MIN) prec = FLINT_MIN(prec, max_exp - max_rad_exp + MAG_BITS); /* Reduce precision based on actual sizes. */ if (min_exp != WORD_MAX) prec = FLINT_MIN(prec, max_exp - min_exp + MAG_BITS); prec = FLINT_MAX(prec, 2); } /* Extend sum so that we can use two's complement addition. */ extend = FLINT_BIT_COUNT(nonzero) + 1; /* Extra bits to improve accuracy (optional). */ padding = 4 + FLINT_BIT_COUNT(len); /* Number of limbs. */ sn = (prec + extend + padding + FLINT_BITS - 1) / FLINT_BITS; /* Avoid having to make a special case for sn = 1. */ sn = FLINT_MAX(sn, 2); /* Exponent for the main sum. */ sum_exp = max_exp + extend; /* We need sn + 1 limb for the sum (sn limbs + 1 dummy limb for carry or borrow that avoids an extra branch). We need 2 * (sn + 2) limbs to store the product of two numbers with up to (sn + 2) limbs, plus 1 extra limb for shifting the product. */ alloc = (sn + 1) + 2 * (sn + 2) + 1; ARF_ADD_TMP_ALLOC(sum, alloc) tmp = sum + (sn + 1); /* Sum of propagated errors. */ srad_exp = max_rad_exp; srad = 0; /* Set sum to 0 */ serr = 0; for (j = 0; j < sn + 1; j++) sum[j] = 0; if (initial != NULL) { xm = arb_midref(initial); xr = arb_radref(initial); if (!arf_is_special(xm)) { mp_srcptr xptr; xexp = ARF_EXP(xm); xn = ARF_SIZE(xm); xnegative = ARF_SGNBIT(xm); shift = sum_exp - xexp; if (shift >= sn * FLINT_BITS) { serr++; } else { xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); _arb_dot_add_generic(sum, &serr, tmp, sn, xptr, xn, xnegative ^ subtract, shift); } } if (!mag_is_special(xr)) { xrad = MAG_MAN(xr); xrexp = MAG_EXP(xr); shift = srad_exp - xrexp; if (shift < 64) srad += (xrad >> shift) + 1; else srad++; } } for (i = 0; i < len; i++) { xi = x + i * xstep; yi = y + i * ystep; xm = arb_midref(xi); ym = arb_midref(yi); xr = arb_radref(xi); yr = arb_radref(yi); /* The midpoints of x[i] and y[i] are both nonzero. */ if (!arf_is_special(xm) && !arf_is_special(ym)) { xexp = ARF_EXP(xm); xn = ARF_SIZE(xm); xnegative = ARF_SGNBIT(xm); yexp = ARF_EXP(ym); yn = ARF_SIZE(ym); ynegative = ARF_SGNBIT(ym); exp = xexp + yexp; shift = sum_exp - exp; if (shift >= sn * FLINT_BITS) { /* We may yet need the top limbs for bounds. */ ARF_GET_TOP_LIMB(xtop, xm); ARF_GET_TOP_LIMB(ytop, ym); serr++; } #if 0 else if (xn == 1 && yn == 1 && sn == 2 && shift < FLINT_BITS) /* Fastest path. */ { mp_limb_t hi, lo, out; xtop = ARF_NOPTR_D(xm)[0]; ytop = ARF_NOPTR_D(ym)[0]; umul_ppmm(hi, lo, xtop, ytop); out = lo << (FLINT_BITS - shift); lo = (lo >> shift) | (hi << (FLINT_BITS - shift)); hi = (hi >> shift); serr += (out != 0); if (xnegative ^ ynegative) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], hi, lo); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], hi, lo); } else if (xn == 2 && yn == 2 && shift < FLINT_BITS && sn <= 3) { mp_limb_t x1, x0, y1, y0; mp_limb_t u3, u2, u1, u0; x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; xtop = x1; ytop = y1; nn_mul_2x2(u3, u2, u1, u0, x1, x0, y1, y0); u0 = (u0 != 0) || ((u1 << (FLINT_BITS - shift)) != 0); u1 = (u1 >> shift) | (u2 << (FLINT_BITS - shift)); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); if (sn == 2) { serr += (u0 || (u1 != 0)); if (xnegative ^ ynegative) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], u3, u2); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], u3, u2); } else { serr += u0; if (xnegative ^ ynegative) sub_dddmmmsss2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); else add_sssaaaaaa2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); } } #endif else if (xn <= 2 && yn <= 2 && sn <= 3) { mp_limb_t x1, x0, y1, y0; mp_limb_t u3, u2, u1, u0; if (xn == 1 && yn == 1) { xtop = ARF_NOPTR_D(xm)[0]; ytop = ARF_NOPTR_D(ym)[0]; umul_ppmm(u3, u2, xtop, ytop); u1 = u0 = 0; } else if (xn == 2 && yn == 2) { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; xtop = x1; ytop = y1; nn_mul_2x2(u3, u2, u1, u0, x1, x0, y1, y0); } else if (xn == 1) { x0 = ARF_NOPTR_D(xm)[0]; y0 = ARF_NOPTR_D(ym)[0]; y1 = ARF_NOPTR_D(ym)[1]; xtop = x0; ytop = y1; nn_mul_2x1(u3, u2, u1, y1, y0, x0); u0 = 0; } else { x0 = ARF_NOPTR_D(xm)[0]; x1 = ARF_NOPTR_D(xm)[1]; y0 = ARF_NOPTR_D(ym)[0]; xtop = x1; ytop = y0; nn_mul_2x1(u3, u2, u1, x1, x0, y0); u0 = 0; } if (sn == 2) { if (shift < FLINT_BITS) { serr += ((u2 << (FLINT_BITS - shift)) != 0) || (u1 != 0) || (u0 != 0); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { serr += (u2 != 0) || (u1 != 0) || (u0 != 0); u2 = u3; u3 = 0; } else /* FLINT_BITS < shift < 2 * FLINT_BITS */ { serr += ((u3 << (2 * FLINT_BITS - shift)) != 0) || (u2 != 0) || (u1 != 0) || (u0 != 0); u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } if (xnegative ^ ynegative) sub_ddmmss(sum[1], sum[0], sum[1], sum[0], u3, u2); else add_ssaaaa(sum[1], sum[0], sum[1], sum[0], u3, u2); } else if (sn == 3) { if (shift < FLINT_BITS) { serr += ((u1 << (FLINT_BITS - shift)) != 0) || (u0 != 0); u1 = (u1 >> shift) | (u2 << (FLINT_BITS - shift)); u2 = (u2 >> shift) | (u3 << (FLINT_BITS - shift)); u3 = (u3 >> shift); } else if (shift == FLINT_BITS) { serr += (u1 != 0) || (u0 != 0); u1 = u2; u2 = u3; u3 = 0; } else if (shift < 2 * FLINT_BITS) { serr += ((u2 << (2 * FLINT_BITS - shift)) != 0) || (u1 != 0) || (u0 != 0); u1 = (u3 << (2 * FLINT_BITS - shift)) | (u2 >> (shift - FLINT_BITS)); u2 = (u3 >> (shift - FLINT_BITS)); u3 = 0; } else if (shift == 2 * FLINT_BITS) { serr += (u2 != 0) || (u1 != 0) || (u0 != 0); u1 = u3; u2 = 0; u3 = 0; } else /* 2 * FLINT_BITS < shift < 3 * FLINT_BITS */ { serr += ((u3 << (3 * FLINT_BITS - shift)) != 0) || (u2 != 0) || (u1 != 0) || (u0 != 0); u1 = (u3 >> (shift - 2 * FLINT_BITS)); u2 = 0; u3 = 0; } if (xnegative ^ ynegative) sub_dddmmmsss2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); else add_sssaaaaaa2(sum[2], sum[1], sum[0], sum[2], sum[1], sum[0], u3, u2, u1); } } else { mp_srcptr xptr, yptr; xptr = (xn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(xm) : ARF_PTR_D(xm); yptr = (yn <= ARF_NOPTR_LIMBS) ? ARF_NOPTR_D(ym) : ARF_PTR_D(ym); xtop = xptr[xn - 1]; ytop = yptr[yn - 1]; _arb_dot_addmul_generic(sum, &serr, tmp, sn, xptr, xn, yptr, yn, xnegative ^ ynegative, shift); } xrad = MAG_MAN(xr); yrad = MAG_MAN(yr); if (xrad != 0 && yrad != 0) { xrexp = MAG_EXP(xr); yrexp = MAG_EXP(yr); RAD_ADDMUL(srad, srad_exp, (xtop >> (FLINT_BITS - MAG_BITS)) + 1, yrad, xexp + yrexp); RAD_ADDMUL(srad, srad_exp, (ytop >> (FLINT_BITS - MAG_BITS)) + 1, xrad, yexp + xrexp); RAD_ADDMUL(srad, srad_exp, xrad, yrad, xrexp + yrexp); } else if (xrad != 0) { xrexp = MAG_EXP(xr); RAD_ADDMUL(srad, srad_exp, (ytop >> (FLINT_BITS - MAG_BITS)) + 1, xrad, yexp + xrexp); } else if (yrad != 0) { yrexp = MAG_EXP(yr); RAD_ADDMUL(srad, srad_exp, (xtop >> (FLINT_BITS - MAG_BITS)) + 1, yrad, xexp + yrexp); } } else { xrad = MAG_MAN(xr); yrad = MAG_MAN(yr); xexp = ARF_EXP(xm); yexp = ARF_EXP(ym); xrexp = MAG_EXP(xr); yrexp = MAG_EXP(yr); /* (xm+xr)(ym+yr) = xm ym + [xm yr + ym xr + xr yr] */ if (yrad && !arf_is_special(xm)) { ARF_GET_TOP_LIMB(xtop, xm); RAD_ADDMUL(srad, srad_exp, (xtop >> (FLINT_BITS - MAG_BITS)) + 1, yrad, xexp + yrexp); } if (xrad && !arf_is_special(ym)) { ARF_GET_TOP_LIMB(ytop, ym); RAD_ADDMUL(srad, srad_exp, (ytop >> (FLINT_BITS - MAG_BITS)) + 1, xrad, yexp + xrexp); } if (xrad && yrad) { RAD_ADDMUL(srad, srad_exp, xrad, yrad, xrexp + yrexp); } } } xnegative = 0; if (sum[sn - 1] >= LIMB_TOP) { mpn_neg(sum, sum, sn); xnegative = 1; } if (sum[sn - 1] == 0) { slong sum_exp2; mp_size_t sn2; sn2 = sn; sum_exp2 = sum_exp; while (sn2 > 0 && sum[sn2 - 1] == 0) { sum_exp2 -= FLINT_BITS; sn2--; } if (sn2 == 0) { arf_zero(arb_midref(res)); inexact = 0; } else { inexact = _arf_set_round_mpn(arb_midref(res), &exp, sum, sn2, xnegative ^ subtract, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp + sum_exp2); } } else { if (sn == 2) inexact = _arf_set_round_uiui(arb_midref(res), &exp, sum[1], sum[0], xnegative ^ subtract, prec, ARF_RND_DOWN); else inexact = _arf_set_round_mpn(arb_midref(res), &exp, sum, sn, xnegative ^ subtract, prec, ARF_RND_DOWN); _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp + sum_exp); } /* Add the three sources of error. Final rounding error = inexact * 2^(exp + sum_exp - prec) 0 <= inexact <= 1 Arithmetic error = serr * 2^(sum_exp - sn * FLINT_BITS) 0 <= serr <= 3 * n Propagated error = srad * 2^(srad_exp - MAG_BITS) 0 <= srad <= 3 * n * MAG_BITS We shift the first two by MAG_BITS so that the magnitudes become similar and a reasonably accurate addition can be done by comparing exponents without normalizing first. */ add_errors(arb_radref(res), inexact << MAG_BITS, exp + sum_exp - prec, ((uint64_t) serr) << MAG_BITS, sum_exp - sn * FLINT_BITS, srad, srad_exp); ARF_ADD_TMP_FREE(sum, alloc); } arb-2.22.1/arb/dot_fmpz.c000066400000000000000000000074771417376376500151360ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_dot_fmpz(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const fmpz * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i, ssize, size, tmp_size; mp_ptr ztmp; fmpz v; ulong av, al; unsigned int bc; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) arb_zero(res); else { arb_mul_fmpz(res, x, y, prec); if (subtract) arb_neg(res, res); } return; } else if (len <= 0) { arb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); tmp_size = 0; for (i = 0; i < len; i++) { v = y[i * ystep]; MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; if (v == 0) { ARF_XSIZE(arb_midref(t + i)) = 0; ARF_EXP(arb_midref(t + i)) = ARF_EXP_ZERO; } else if (!COEFF_IS_MPZ(v)) { av = FLINT_ABS(v); count_leading_zeros(bc, av); ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = av << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, v < 0); } else { __mpz_struct * z = COEFF_TO_PTR(v); ssize = z->_mp_size; size = FLINT_ABS(ssize); av = z->_mp_d[size - 1]; count_leading_zeros(bc, av); if (size == 1) { ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = av << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, ssize < 0); } else if (size == 2) { al = z->_mp_d[0]; ARF_EXP(arb_midref(t + i)) = 2 * FLINT_BITS - bc; if (bc != 0) { av = (av << bc) | (al >> (FLINT_BITS - bc)); al = al << bc; } ARF_NOPTR_D(arb_midref(t + i))[0] = al; ARF_NOPTR_D(arb_midref(t + i))[1] = av; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(2, ssize < 0); } else { if (bc != 0) { tmp_size += size; /* use to flag tmp where we need tmp storage */ MAG_MAN(arb_radref(t + i)) = bc; } ARF_EXP(arb_midref(t + i)) = size * FLINT_BITS - bc; ARF_PTR_D(arb_midref(t + i)) = z->_mp_d; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(size, ssize < 0); } } } if (tmp_size != 0) { ztmp = TMP_ALLOC(sizeof(mp_limb_t) * tmp_size); for (i = 0; i < len; i++) { bc = MAG_MAN(arb_radref(t + i)); if (bc != 0) { size = ARF_SIZE(arb_midref(t + i)); mpn_lshift(ztmp, ARF_PTR_D(arb_midref(t + i)), size, bc); ARF_PTR_D(arb_midref(t + i)) = ztmp; ztmp += size; } MAG_MAN(arb_radref(t + i)) = 0; } } arb_dot(res, initial, subtract, x, xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/arb/dot_precise.c000066400000000000000000000044411417376376500156000ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_dot_precise(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) { arf_ptr A, B; arf_t t, u; slong i; int inexact; if (len <= 0) { if (initial == NULL) arb_zero(res); else arb_set_round(res, initial, prec); return; } A = flint_calloc(len + (initial != NULL), sizeof(arf_struct)); B = flint_calloc(3 * len + 1 + (initial != NULL), sizeof(arf_struct)); for (i = 0; i < len; i++) { arb_srcptr xp = x + i * xstep; arb_srcptr yp = y + i * ystep; arf_mul(A + i, arb_midref(xp), arb_midref(yp), ARF_PREC_EXACT, ARF_RND_DOWN); if (subtract) arf_neg(A + i, A + i); arf_init_set_mag_shallow(t, arb_radref(xp)); arf_init_set_mag_shallow(u, arb_radref(yp)); arf_mul(B + 3 * i, t, u, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(B + 3 * i + 1, t, arb_midref(yp), ARF_PREC_EXACT, ARF_RND_DOWN); arf_abs(B + 3 * i + 1, B + 3 * i + 1); arf_mul(B + 3 * i + 2, u, arb_midref(xp), ARF_PREC_EXACT, ARF_RND_DOWN); arf_abs(B + 3 * i + 2, B + 3 * i + 2); } if (initial != NULL) { arf_set(A + len, arb_midref(initial)); arf_set_mag(B + 3 * len + 1, arb_radref(initial)); } inexact = arf_sum(arb_midref(res), A, len + (initial != NULL), prec, ARF_RND_DOWN); if (inexact) arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec); else mag_zero(arb_radref(res)); arf_set_mag(B + 3 * len, arb_radref(res)); arf_sum(A, B, 3 * len + 1 + (initial != NULL), 3 * MAG_BITS, ARF_RND_UP); arf_get_mag(arb_radref(res), A); for (i = 0; i < len + (initial != NULL); i++) arf_clear(A + i); for (i = 0; i < 3 * len + 1 + (initial != NULL); i++) arf_clear(B + i); flint_free(A); flint_free(B); } arb-2.22.1/arb/dot_si.c000066400000000000000000000034561417376376500145660ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_dot_si(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const slong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; slong v; ulong av; unsigned int bc; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) arb_zero(res); else { arb_mul_si(res, x, y[0], prec); if (subtract) arb_neg(res, res); } return; } else if (len <= 0) { arb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { v = y[i * ystep]; if (v == 0) { ARF_XSIZE(arb_midref(t + i)) = 0; ARF_EXP(arb_midref(t + i)) = ARF_EXP_ZERO; } else { av = FLINT_ABS(v); count_leading_zeros(bc, av); ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = av << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, v < 0); } MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(res, initial, subtract, x, xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/arb/dot_simple.c000066400000000000000000000021121417376376500154300ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_dot_simple(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) { slong i; if (len <= 0) { if (initial == NULL) arb_zero(res); else arb_set_round(res, initial, prec); return; } if (initial == NULL) { arb_mul(res, x, y, prec); } else { if (subtract) arb_neg(res, initial); else arb_set(res, initial); arb_addmul(res, x, y, prec); } for (i = 1; i < len; i++) arb_addmul(res, x + i * xstep, y + i * ystep, prec); if (subtract) arb_neg(res, res); } arb-2.22.1/arb/dot_siui.c000066400000000000000000000052311417376376500151150ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void arf_shallow_set_siui(arf_t res, ulong vhi, ulong vlo) { int negative; unsigned int bc; negative = ((slong) vhi) < 0; if (negative) { vhi = -vhi - (vlo != 0); vlo = -vlo; } if (vhi == 0) { if (vlo == 0) { ARF_XSIZE(res) = 0; ARF_EXP(res) = ARF_EXP_ZERO; } else { count_leading_zeros(bc, vlo); ARF_EXP(res) = FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, negative); } } else if (vlo == 0) { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vhi << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, negative); } else { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; if (bc == 0) ARF_NOPTR_D(res)[1] = vhi; else ARF_NOPTR_D(res)[1] = (vhi << bc) | (vlo >> (FLINT_BITS - bc)); ARF_XSIZE(res) = ARF_MAKE_XSIZE(2, negative); } } void arb_dot_siui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; ulong vhi, vlo; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) arb_zero(res); else { arf_t t; arf_shallow_set_siui(t, y[1], y[0]); arb_mul_arf(res, x, t, prec); if (subtract) arb_neg(res, res); } return; } else if (len <= 0) { arb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { vlo = y[2 * i * ystep]; vhi = y[2 * i * ystep + 1]; arf_shallow_set_siui(arb_midref(t + i), vhi, vlo); MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(res, initial, subtract, x, xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/arb/dot_ui.c000066400000000000000000000033731417376376500145660ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_dot_ui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; ulong v; unsigned int bc; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) arb_zero(res); else { arb_mul_ui(res, x, y[0], prec); if (subtract) arb_neg(res, res); } return; } else if (len <= 0) { arb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { v = y[i * ystep]; if (v == 0) { ARF_XSIZE(arb_midref(t + i)) = 0; ARF_EXP(arb_midref(t + i)) = ARF_EXP_ZERO; } else { count_leading_zeros(bc, v); ARF_EXP(arb_midref(t + i)) = FLINT_BITS - bc; ARF_NOPTR_D(arb_midref(t + i))[0] = v << bc; ARF_XSIZE(arb_midref(t + i)) = ARF_MAKE_XSIZE(1, 0); } MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(res, initial, subtract, x, xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/arb/dot_uiui.c000066400000000000000000000047731417376376500151310ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void arf_shallow_set_uiui(arf_t res, ulong vhi, ulong vlo) { unsigned int bc; if (vhi == 0) { if (vlo == 0) { ARF_XSIZE(res) = 0; ARF_EXP(res) = ARF_EXP_ZERO; } else { count_leading_zeros(bc, vlo); ARF_EXP(res) = FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, 0); } } else if (vlo == 0) { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vhi << bc; ARF_XSIZE(res) = ARF_MAKE_XSIZE(1, 0); } else { count_leading_zeros(bc, vhi); ARF_EXP(res) = 2 * FLINT_BITS - bc; ARF_NOPTR_D(res)[0] = vlo << bc; if (bc == 0) ARF_NOPTR_D(res)[1] = vhi; else ARF_NOPTR_D(res)[1] = (vhi << bc) | (vlo >> (FLINT_BITS - bc)); ARF_XSIZE(res) = ARF_MAKE_XSIZE(2, 0); } } void arb_dot_uiui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) { arb_ptr t; slong i; ulong vhi, vlo; TMP_INIT; /* todo: fast fma and fmma (len=2) code */ if (len <= 1) { if (initial == NULL) { if (len <= 0) arb_zero(res); else { arf_t t; arf_shallow_set_uiui(t, y[1], y[0]); arb_mul_arf(res, x, t, prec); if (subtract) arb_neg(res, res); } return; } else if (len <= 0) { arb_set_round(res, initial, prec); return; } } TMP_START; t = TMP_ALLOC(sizeof(arb_struct) * len); for (i = 0; i < len; i++) { vlo = y[2 * i * ystep]; vhi = y[2 * i * ystep + 1]; arf_shallow_set_uiui(arb_midref(t + i), vhi, vlo); MAG_EXP(arb_radref(t + i)) = 0; MAG_MAN(arb_radref(t + i)) = 0; } arb_dot(res, initial, subtract, x, xstep, t, 1, len, prec); TMP_END; } arb-2.22.1/arb/doublefac_ui.c000066400000000000000000000014021417376376500157130ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_doublefac_ui(arb_t res, ulong n, slong prec) { if (n % 2 == 0) { arb_fac_ui(res, n / 2, prec); arb_mul_2exp_si(res, res, n / 2); } else { arb_t t; arb_init(t); arb_doublefac_ui(t, n - 1, prec + 5); arb_fac_ui(res, n, prec + 5); arb_div(res, res, t, prec); arb_clear(t); } } arb-2.22.1/arb/dump_file.c000066400000000000000000000012141417376376500152370ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "arb.h" int arb_dump_file(FILE* stream, const arb_t x) { int nwrite; char* data = arb_dump_str(x); nwrite = fputs(data, stream); if (nwrite == EOF) return nwrite; flint_free(data); return 0; } arb-2.22.1/arb/dump_str.c000066400000000000000000000015221417376376500151320ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" #include "arf.h" #include "mag.h" char * arb_dump_str(const arb_t x) { char * mid; char * mag; size_t res_len; char * res; mid = arf_dump_str(arb_midref(x)); mag = mag_dump_str(arb_radref(x)); res_len = strlen(mid) + 1 + strlen(mag); res = (char*)flint_malloc(res_len + 1); strcpy(res, mid); strcat(res, " "); strcat(res, mag); flint_free(mid); flint_free(mag); return res; } arb-2.22.1/arb/euler_number_fmpz.c000066400000000000000000000027051417376376500170210ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_euler_number_fmpz(arb_t res, const fmpz_t n, slong prec) { if (fmpz_cmp_ui(n, UWORD_MAX) <= 0) { if (fmpz_sgn(n) >= 0) arb_euler_number_ui(res, fmpz_get_ui(n), prec); else arb_zero(res); } else if (fmpz_is_odd(n)) { arb_zero(res); } else { arb_t t; fmpz_t m; slong wp; arb_init(t); fmpz_init(m); wp = prec + 2 * fmpz_bits(n); /* beta(n) ~= 1 */ arf_one(arb_midref(res)); mag_one(arb_radref(res)); mag_mul_2exp_si(arb_radref(res), arb_radref(res), WORD_MIN); /* |E_n| = 2 n! beta(n+1) / (pi/2)^(n+1) */ fmpz_add_ui(m, n, 1); arb_gamma_fmpz(t, m, wp); arb_mul(res, res, t, wp); arb_const_pi(t, wp); arb_mul_2exp_si(t, t, -1); arb_pow_fmpz(t, t, m, wp); arb_div(res, res, t, prec); arb_mul_2exp_si(res, res, 1); if (fmpz_fdiv_ui(n, 4) == 2) arb_neg(res, res); arb_clear(t); fmpz_clear(m); } } arb-2.22.1/arb/euler_number_ui.c000066400000000000000000000356051417376376500164670ustar00rootroot00000000000000/* Copyright (C) 2016, 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "acb_dirichlet.h" #if FLINT64 #define ARB_EULER_NUMBER_TAB_SIZE 25 #else #define ARB_EULER_NUMBER_TAB_SIZE 15 #endif static const ulong arb_euler_number_tab[] = { 1, 1, 5, 61, 1385, 50521, 2702765, 199360981, #if FLINT64 UWORD(19391512145), UWORD(2404879675441), UWORD(370371188237525), UWORD(69348874393137901), UWORD(15514534163557086905) #endif }; static double arb_euler_number_mag(double 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; } void arb_euler_number_ui_beta(arb_t res, ulong n, slong prec) { slong pi_prec; arb_t t; const signed char chi[4] = {0, 1, 0, -1}; pi_prec = prec + 2 * FLINT_BIT_COUNT(n); arb_init(t); /* |E_n| = 2 n! beta(n+1) / (pi/2)^(n+1) */ arb_const_pi(t, pi_prec); arb_mul_2exp_si(t, t, -1); arb_pow_ui(t, t, n + 1, pi_prec); _acb_dirichlet_euler_product_real_ui(res, n + 1, chi, 4, 1, prec); arb_mul(res, res, t, prec); arb_fac_ui(t, n, pi_prec); /* todo: prec should be enough */ arb_div(res, t, res, prec); arb_mul_2exp_si(res, res, 1); if (n % 4 == 2) arb_neg(res, res); arb_clear(t); } #define LOW_MASK ((UWORD(1) << (FLINT_BITS / 2)) - 1) typedef struct { ulong n; ulong ninv; ulong F; } nmod_redc_t; static void nmod_redc_init(nmod_redc_t * rmod, nmod_t mod) { ulong n, ninv2; int bits; n = mod.n; rmod->n = n; rmod->F = (UWORD(1) << (FLINT_BITS / 2)); NMOD_RED(rmod->F, rmod->F, mod); /* Newton's method for 2-adic inversion */ ninv2 = -n; /* already correct mod 8 */ for (bits = 3; bits < FLINT_BITS / 2; bits *= 2) ninv2 = 2*ninv2 + n * ninv2 * ninv2; rmod->ninv = ninv2 & LOW_MASK; } static __inline__ ulong nmod_redc_fast(ulong x, ulong n, ulong ninv2) { ulong y = (x * ninv2) & LOW_MASK; ulong z = x + (n * y); return z >> (FLINT_BITS / 2); } static __inline__ ulong nmod_redc(ulong x, ulong n, ulong ninv2) { ulong y = nmod_redc_fast(x, n, ninv2); if (y >= n) y -= n; return y; } static ulong nmod_redc_mul_fast(ulong a, ulong b, nmod_redc_t rmod) { return nmod_redc_fast(a * b, rmod.n, rmod.ninv); } static ulong nmod_redc_mul(ulong a, ulong b, nmod_redc_t rmod) { return nmod_redc(a * b, rmod.n, rmod.ninv); } static ulong nmod_to_redc(ulong x, nmod_t mod, nmod_redc_t rmod) { return nmod_mul(x, rmod.F, mod); } static ulong nmod_from_redc(ulong x, nmod_redc_t rmod) { return nmod_redc(x, rmod.n, rmod.ninv); } ulong nmod_redc_pow_ui(ulong a, ulong exp, nmod_redc_t rmod) { ulong x; while ((exp & 1) == 0) { a = nmod_redc_mul(a, a, rmod); exp >>= 1; } x = a; while (exp >>= 1) { a = nmod_redc_mul(a, a, rmod); if (exp & 1) x = nmod_redc_mul(x, a, rmod); } return x; } ulong euler_mod_p_powsum_1(ulong n, ulong p) { slong j; ulong s, t; nmod_t mod; if (n % 2 == 1) return 0; n = n % (p - 1); if (n == 0) return UWORD_MAX; nmod_init(&mod, p); s = 1; for (j = 3; j <= p - 2; j += 2) { t = nmod_pow_ui(j, n, mod); s = nmod_sub(t, s, mod); } if (p % 4 == 1) s = nmod_neg(s, mod); s = nmod_add(s, s, mod); return s; } ulong euler_mod_p_powsum_noredc(ulong n, ulong p, const unsigned int * divtab) { unsigned int * pows; slong i, N, horner_point; ulong s, t, z; ulong v2n, power_of_two; nmod_t mod; TMP_INIT; if (n % 2 == 1) return 0; n = n % (p - 1); if (n == 0) return UWORD_MAX; N = p / 4; nmod_init(&mod, p); TMP_START; pows = TMP_ALLOC(sizeof(unsigned int) * (N / 3 + 1)); s = z = 0; /* Evaluate as a polynomial in 2^n */ power_of_two = 1; while (power_of_two * 2 <= N) power_of_two *= 2; horner_point = 1; v2n = nmod_pow_ui(2, n, mod); for (i = 1; i <= N / 3; i += 2) { if (divtab[i] == 1) t = nmod_pow_ui(i, n, mod); else t = nmod_mul(pows[divtab[i]], pows[divtab[i + 1]], mod); pows[i] = t; s = nmod_add(s, t, mod); if (i == horner_point) { while (i == horner_point && power_of_two != 1) { z = nmod_add(s, nmod_mul(v2n, z, mod), mod); power_of_two /= 2; horner_point = N / power_of_two; if (horner_point % 2 == 0) horner_point--; } } } /* Same as above, but here we don't need to write the powers. */ for ( ; i <= N; i += 2) { if (divtab[i] == 1) t = nmod_pow_ui(i, n, mod); else t = nmod_mul(pows[divtab[i]], pows[divtab[i + 1]], mod); s = nmod_add(s, t, mod); if (i == horner_point) { while (i == horner_point && power_of_two != 1) { z = nmod_add(s, nmod_mul(v2n, z, mod), mod); power_of_two /= 2; horner_point = N / power_of_two; if (horner_point % 2 == 0) horner_point--; } } } s = nmod_add(s, nmod_mul(v2n, z, mod), mod); if (p % 4 == 3) s = nmod_neg(s, mod); t = nmod_inv(nmod_pow_ui(4, p - n - 2, mod), mod); s = nmod_mul(s, t, mod); TMP_END; return s; } ulong euler_mod_p_powsum_redc(ulong n, ulong p, const unsigned int * divtab) { unsigned int * pows; slong i, N, horner_point; ulong s, t, z; ulong v2n, power_of_two; nmod_t mod; nmod_redc_t rmod; TMP_INIT; if (n % 2 == 1) return 0; n = n % (p - 1); if (n == 0) return UWORD_MAX; N = p / 4; nmod_init(&mod, p); nmod_redc_init(&rmod, mod); TMP_START; pows = TMP_ALLOC(sizeof(unsigned int) * (N / 3 + 1)); s = z = 0; /* Evaluate as a polynomial in 2^n */ power_of_two = 1; while (power_of_two * 2 <= N) power_of_two *= 2; horner_point = 1; v2n = nmod_redc_pow_ui(nmod_to_redc(2, mod, rmod), n, rmod); for (i = 1; i <= N / 3; i += 2) { if (divtab[i] == 1) t = nmod_redc_pow_ui(nmod_to_redc(i, mod, rmod), n, rmod); else t = nmod_redc_mul(pows[divtab[i]], pows[divtab[i + 1]], rmod); pows[i] = t; s += t; if (i == horner_point) { while (i == horner_point && power_of_two != 1) { NMOD_RED(s, s, mod); z = nmod_add(s, nmod_redc_mul(v2n, z, rmod), mod); power_of_two /= 2; horner_point = N / power_of_two; if (horner_point % 2 == 0) horner_point--; } } } /* Same as above, but here we don't need to write the powers. */ for ( ; i <= N; i += 2) { if (divtab[i] == 1) t = nmod_redc_pow_ui(nmod_to_redc(i, mod, rmod), n, rmod); else t = nmod_redc_mul_fast(pows[divtab[i]], pows[divtab[i + 1]], rmod); s += t; if (i == horner_point) { while (i == horner_point && power_of_two != 1) { NMOD_RED(s, s, mod); z = nmod_add(s, nmod_redc_mul(v2n, z, rmod), mod); power_of_two /= 2; horner_point = N / power_of_two; if (horner_point % 2 == 0) horner_point--; } } } NMOD_RED(s, s, mod); s = nmod_add(s, nmod_redc_mul(v2n, z, rmod), mod); s = nmod_from_redc(s, rmod); if (p % 4 == 3) s = nmod_neg(s, mod); t = nmod_inv(nmod_pow_ui(4, p - n - 2, mod), mod); s = nmod_mul(s, t, mod); TMP_END; return s; } ulong euler_mod_p_powsum(ulong n, ulong p, const unsigned int * divtab) { if (p < (UWORD(1) << (FLINT_BITS / 2 - 1))) return euler_mod_p_powsum_redc(n, p, divtab); else return euler_mod_p_powsum_noredc(n, p, divtab); } static void divisor_table_odd(unsigned int * tab, slong len) { slong i, j; tab[0] = 0; for (i = 1; i < len; i += 2) { tab[i] = 1; tab[i + 1] = i; } for (i = 3; i < len; i += 2) { for (j = 3; j <= i && i * j < len; j += 2) { tab[i * j] = j; tab[i * j + 1] = i; } } } #define TIMING 0 #define DEBUG 0 static void _fmpz_crt_combine(fmpz_t r1r2, fmpz_t m1m2, const fmpz_t r1, const fmpz_t m1, const fmpz_t r2, const fmpz_t m2) { fmpz_invmod(m1m2, m1, m2); fmpz_mul(m1m2, m1m2, m1); fmpz_sub(r1r2, r2, r1); fmpz_mul(r1r2, r1r2, m1m2); fmpz_add(r1r2, r1r2, r1); fmpz_mul(m1m2, m1, m2); fmpz_mod(r1r2, r1r2, m1m2); } static void tree_crt(fmpz_t r, fmpz_t m, mp_srcptr residues, mp_srcptr primes, slong len) { if (len == 0) { fmpz_zero(r); fmpz_one(m); } else if (len == 1) { fmpz_set_ui(r, residues[0]); fmpz_set_ui(m, primes[0]); } else { fmpz_t r1, m1, r2, m2; fmpz_init(r1); fmpz_init(m1); fmpz_init(r2); fmpz_init(m2); tree_crt(r1, m1, residues, primes, len / 2); tree_crt(r2, m2, residues + len / 2, primes + len / 2, len - len / 2); _fmpz_crt_combine(r, m, r1, m1, r2, m2); fmpz_clear(r1); fmpz_clear(m1); fmpz_clear(r2); fmpz_clear(m2); } } void arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha) { slong i, bits, mod_bits, zeta_bits, num_primes; ulong p; mp_ptr primes, residues; mag_t primes_product; unsigned int * divtab_odd; fmpz_t M; #if TIMING double t1, t2; #endif if (n % 2 != 0) { fmpz_zero(num); return; } if (n < ARB_EULER_NUMBER_TAB_SIZE) { if (n % 4 == 0) fmpz_set_ui(num, arb_euler_number_tab[n / 2]); else fmpz_neg_ui(num, arb_euler_number_tab[n / 2]); return; } if (alpha < 0) { if (n < 2000) alpha = 0.0; else if (n < 6000) alpha = 0.002 + 1.0e-5 * (n - 2000); else if (n < 90000) alpha = -0.132 + 0.02 * log(n); else alpha = FLINT_MIN(0.0085 * log(n), 0.11); } #if TIMING t1 = clock(); #endif bits = arb_euler_number_mag(n) + 2; mod_bits = bits * alpha; zeta_bits = bits - mod_bits; num_primes = 0; mag_init(primes_product); mag_one(primes_product); for (p = 5; mag_cmp_2exp_si(primes_product, mod_bits) < 0; p = n_nextprime(p, 1)) { if (n % (p - 1) != 0) { mag_mul_ui_lower(primes_product, primes_product, p); num_primes++; } } #if DEBUG printf("\nn = %lu, bits = %lu, num_primes = %ld\n", n, bits, num_primes); #endif primes = flint_malloc(sizeof(mp_limb_t) * num_primes); residues = flint_malloc(sizeof(mp_limb_t) * num_primes); for (p = 5, i = 0; i < num_primes; p = n_nextprime(p, 1)) { if (n % (p - 1) != 0) { primes[i] = p; i++; } } if (num_primes == 0) { divtab_odd = NULL; } else { p = primes[num_primes - 1]; divtab_odd = flint_malloc(sizeof(unsigned int) * (p / 4 + 2)); divisor_table_odd(divtab_odd, p / 4 + 1); } #if TIMING t2 = clock(); printf("init time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); printf("num_primes = %ld\n", num_primes); #endif for (i = 0; i < num_primes; i++) { #if TIMING if (i % 10000 == 0) printf("%ld / %ld\n", i, num_primes); #endif residues[i] = euler_mod_p_powsum(n, primes[i], divtab_odd); } #if TIMING t2 = clock(); printf("mod time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); printf("start CRT\n"); t1 = clock(); #endif fmpz_init(M); tree_crt(num, M, residues, primes, num_primes); fmpz_mod(num, num, M); if (n % 4 == 2) { fmpz_sub(num, M, num); fmpz_neg(num, num); } #if TIMING printf("end CRT\n"); t2 = clock(); printf("CRT time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); t1 = clock(); #endif if (zeta_bits > 0) { slong prec; arb_t b; fmpz_t t; arb_init(b); fmpz_init(t); for (prec = zeta_bits + 10; ; prec += 32) { arb_euler_number_ui_beta(b, n, prec); arb_sub_fmpz(b, b, num, prec); arb_div_fmpz(b, b, M, prec); if (arb_get_unique_fmpz(t, b)) { fmpz_addmul(num, t, M); break; } flint_printf("euler: n = %wu, bits = %wd, mod = %wd, zeta = %wd: get_unique_fmpz failed!\n", n, bits, mod_bits, zeta_bits); } arb_clear(b); fmpz_clear(t); } #if TIMING printf("end zeta\n"); t2 = clock(); printf("zeta time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); #endif flint_free(primes); flint_free(residues); flint_free(divtab_odd); fmpz_clear(M); mag_clear(primes_product); } void arb_fmpz_euler_number_ui(fmpz_t res, ulong n) { arb_t x; double mag; if (n % 2 != 0) { fmpz_zero(res); return; } if (n < ARB_EULER_NUMBER_TAB_SIZE) { if (n % 4 == 0) fmpz_set_ui(res, arb_euler_number_tab[n / 2]); else fmpz_neg_ui(res, arb_euler_number_tab[n / 2]); return; } if (n < 2000) { mag = arb_euler_number_mag(n); arb_init(x); arb_euler_number_ui_beta(x, n, mag + 5); if (!arb_get_unique_fmpz(res, x)) { flint_printf("arb_fmpz_euler_number_ui: unexpected inaccuracy\n"); flint_abort(); } arb_clear(x); } else { arb_fmpz_euler_number_ui_multi_mod(res, n, -1.0); } } void arb_euler_number_ui(arb_t res, ulong n, slong prec) { double mag; if (n % 2 != 0) { arb_zero(res); return; } if (n < ARB_EULER_NUMBER_TAB_SIZE) { arb_set_ui(res, arb_euler_number_tab[n / 2]); if (n % 4 == 2) arb_neg(res, res); arb_set_round(res, res, prec); return; } mag = arb_euler_number_mag(n); if (prec > 0.9 * mag) { fmpz_t t; fmpz_init(t); arb_fmpz_euler_number_ui(t, n); arb_set_round_fmpz(res, t, prec); fmpz_clear(t); } else { arb_euler_number_ui_beta(res, n, prec + 5); arb_set_round(res, res, prec); } } arb-2.22.1/arb/exp.c000066400000000000000000000505011417376376500140720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define TMP_ALLOC_LIMBS(__n) TMP_ALLOC((__n) * sizeof(mp_limb_t)) #define MAGLIM(prec) FLINT_MAX(128, 2 * (prec)) void arb_exp_arf_huge(arb_t z, const arf_t x, slong mag, slong prec, int minus_one) { arb_t ln2, t, u; fmpz_t q; slong wp; arb_init(ln2); arb_init(t); arb_init(u); fmpz_init(q); wp = prec + mag + 10; arb_const_log2(ln2, wp); arb_set_arf(t, x); arb_div(u, t, ln2, wp); arf_get_fmpz(q, arb_midref(u), ARF_RND_DOWN); arb_submul_fmpz(t, ln2, q, wp); arb_exp(z, t, prec); arb_mul_2exp_fmpz(z, z, q); if (minus_one) arb_sub_ui(z, z, 1, prec); arb_clear(ln2); arb_clear(t); arb_clear(u); fmpz_clear(q); } /* |x| >= 2^expbound */ static void arb_exp_arf_overflow(arb_t z, slong expbound, int negative, int minus_one, slong prec) { if (!negative) { arf_zero(arb_midref(z)); mag_inf(arb_radref(z)); } else { /* x <= -2^expbound ==> 0 < exp(x) <= 2^(-2^expbound) */ fmpz_t t; fmpz_init(t); fmpz_set_si(t, -1); fmpz_mul_2exp(t, t, expbound); arf_one(arb_midref(z)); mag_one(arb_radref(z)); arb_mul_2exp_fmpz(z, z, t); if (minus_one) arb_sub_ui(z, z, 1, prec); fmpz_clear(t); } } static void arb_exp_arf_fallback(arb_t z, const arf_t x, slong mag, slong prec, int minus_one) { /* reduce by log(2) if needed, but avoid computing log(2) unnecessarily at extremely high precision */ if (mag > 64 || (mag > 8 && prec < 1000000)) arb_exp_arf_huge(z, x, mag, prec, minus_one); else if (prec < 19000) arb_exp_arf_rs_generic(z, x, prec, minus_one); else arb_exp_arf_bb(z, x, prec, minus_one); } void arb_exp_arf(arb_t z, const arf_t x, slong prec, int minus_one, slong maglim) { if (arf_is_special(x)) { if (minus_one) { if (arf_is_zero(x)) arb_zero(z); else if (arf_is_pos_inf(x)) arb_pos_inf(z); else if (arf_is_neg_inf(x)) arb_set_si(z, -1); else arb_indeterminate(z); } else { if (arf_is_zero(x)) arb_one(z); else if (arf_is_pos_inf(x)) arb_pos_inf(z); else if (arf_is_neg_inf(x)) arb_zero(z); else arb_indeterminate(z); } } else if (COEFF_IS_MPZ(ARF_EXP(x))) { if (fmpz_sgn(ARF_EXPREF(x)) > 0) { /* huge input */ arb_exp_arf_overflow(z, maglim, ARF_SGNBIT(x), minus_one, prec); } else { /* |exp(x) - (1 + x)| <= |x^2| */ fmpz_t t; int inexact; fmpz_init(t); fmpz_mul_2exp(t, ARF_EXPREF(x), 1); inexact = arf_add_ui(arb_midref(z), x, minus_one ? 0 : 1, prec, ARB_RND); mag_one(arb_radref(z)); mag_mul_2exp_fmpz(arb_radref(z), arb_radref(z), t); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); fmpz_clear(t); } } else { slong exp, wp, wn, N, r, wprounded, finaln; fmpz_t n; mp_ptr tmp, w, t, u, finalvalue; mp_limb_t p1, q1bits, p2, q2bits, error, error2; int negative, inexact; TMP_INIT; exp = ARF_EXP(x); negative = ARF_SGNBIT(x); /* handle tiny input */ /* |exp(x) - 1| <= 2|x| */ if (!minus_one && exp < -prec - 4) { arf_one(arb_midref(z)); mag_set_ui_2exp_si(arb_radref(z), 1, exp + 1); return; } /* |exp(x) - (1 + x)| <= |x^2| */ else if (exp < (minus_one ? -prec - 4 : -(prec / 2) - 4)) { inexact = arf_add_ui(arb_midref(z), x, minus_one ? 0 : 1, prec, ARB_RND); mag_set_ui_2exp_si(arb_radref(z), 1, 2 * exp); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); return; } /* handle huge input */ if (exp > maglim) { arb_exp_arf_overflow(z, maglim, negative, minus_one, prec); return; } /* Absolute working precision (NOT rounded to a limb multiple) */ wp = prec + 8; if (minus_one && exp <= 0) wp += (-exp); /* Number of limbs */ wn = (wp + FLINT_BITS - 1) / FLINT_BITS; /* Precision rounded to a number of bits */ wprounded = FLINT_BITS * wn; /* Don't be close to the boundary (to allow adding adding the Taylor series truncation error without overflow) */ wp = FLINT_MAX(wp, wprounded - (FLINT_BITS - 4)); /* Too high precision to use table -- use generic algorithm */ if (wp > ARB_EXP_TAB2_PREC) { arb_exp_arf_fallback(z, x, exp, prec, minus_one); return; } TMP_START; tmp = TMP_ALLOC_LIMBS(4 * wn + 3); w = tmp; /* requires wn+1 limbs */ t = w + wn + 1; /* requires wn+1 limbs */ u = t + wn + 1; /* requires 2wn+1 limbs */ /* reduce modulo log(2) */ fmpz_init(n); if (_arb_get_mpn_fixed_mod_log2(w, n, &error, x, wn) == 0) { /* may run out of precision for log(2) */ arb_exp_arf_fallback(z, x, exp, prec, minus_one); fmpz_clear(n); TMP_END; return; } /* err(w) translates to a propagated error bounded by err(w) * exp'(x) < err(w) * exp(1) < err(w) * 3 */ error *= 3; /* Table-based argument reduction (1 or 2 steps) */ if (wp <= ARB_EXP_TAB1_PREC) { q1bits = ARB_EXP_TAB1_BITS; q2bits = 0; p1 = w[wn-1] >> (FLINT_BITS - q1bits); w[wn-1] -= (p1 << (FLINT_BITS - q1bits)); p2 = 0; } else { q1bits = ARB_EXP_TAB21_BITS; q2bits = ARB_EXP_TAB21_BITS + ARB_EXP_TAB22_BITS; p1 = w[wn-1] >> (FLINT_BITS - q1bits); w[wn-1] -= (p1 << (FLINT_BITS - q1bits)); p2 = w[wn-1] >> (FLINT_BITS - q2bits); w[wn-1] -= (p2 << (FLINT_BITS - q2bits)); } /* |w| <= 2^-r */ r = _arb_mpn_leading_zeros(w, wn); /* Choose number of terms N such that Taylor series truncation error is <= 2^-wp */ N = _arb_exp_taylor_bound(-r, wp); if (N < 60) { /* Evaluate Taylor series */ _arb_exp_taylor_rs(t, &error2, w, wn, N); /* Taylor series evaluation error */ error += error2; /* Taylor series truncation error */ error += UWORD(1) << (wprounded-wp); } else /* Compute cosh(a) from sinh(a) using a square root. */ { /* the summation for sinh is actually done to (2N-1)! */ N = (N + 1) / 2; /* Evaluate Taylor series for sinh */ _arb_sin_cos_taylor_rs(t, u, &error2, w, wn, N, 1, 0); error += error2; error += UWORD(1) << (wprounded-wp); /* 1 + sinh^2, with wn + 1 limbs */ mpn_sqr(u, t, wn); u[2 * wn] = 1; /* cosh, with wn + 1 limbs */ mpn_sqrtrem(w, u, u, 2 * wn + 1); /* exp = sinh + cosh */ t[wn] = w[wn] + mpn_add_n(t, t, w, wn); /* Error for cosh */ /* When converting sinh to cosh, the error for cosh must be smaller than the error for sinh; but we also get 1 ulp extra error from the square root. */ error2 = error + 1; /* Error for sinh + cosh */ error += error2; } if (wp <= ARB_EXP_TAB1_PREC) { if (p1 == 0) { finalvalue = t; finaln = wn + 1; } else { /* Divide by 2 to get |t| <= 1 (todo: check this?) */ mpn_rshift(t, t, wn + 1, 1); error = (error >> 1) + 2; mpn_mul_n(u, t, arb_exp_tab1[p1] + ARB_EXP_TAB1_LIMBS - wn, wn); /* (t + err1 * ulp) * (u + err2 * ulp) + 1ulp = t*u + (err1*u + err2*t + t*u*ulp + 1) * ulp note |u| <= 1, |t| <= 1 */ error += 4; finalvalue = u + wn; finaln = wn; /* we have effectively divided by 2^2 -- todo use inline function */ fmpz_add_ui(n, n, 2); } } else { if (p1 == 0 && p2 == 0) { finalvalue = t; finaln = wn + 1; } else { /* Divide by 2 to get |t| <= 1 (todo: check this?) */ mpn_rshift(t, t, wn + 1, 1); error = (error >> 1) + 2; mpn_mul_n(u, arb_exp_tab21[p1] + ARB_EXP_TAB2_LIMBS - wn, arb_exp_tab22[p2] + ARB_EXP_TAB2_LIMBS - wn, wn); /* error of w <= 4 ulp */ flint_mpn_copyi(w, u + wn, wn); /* todo: avoid with better alloc */ mpn_mul_n(u, t, w, wn); /* (t + err1 * ulp) * (w + 4 * ulp) + 1ulp = t*u + (err1*w + 4*t + t*w*ulp + 1) * ulp note |w| <= 1, |t| <= 1 */ error += 6; finalvalue = u + wn; finaln = wn; /* we have effectively divided by 2^3 -- todo use inline function */ fmpz_add_ui(n, n, 3); } } /* The accumulated arithmetic error */ mag_set_ui_2exp_si(arb_radref(z), error, -wprounded); /* Set the midpoint */ if (!minus_one) { inexact = _arf_set_mpn_fixed(arb_midref(z), finalvalue, finaln, wn, 0, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else { _arf_set_mpn_fixed(arb_midref(z), finalvalue, finaln, wn, 0, finaln * FLINT_BITS, ARB_RND); } arb_mul_2exp_fmpz(z, z, n); if (minus_one) arb_sub_ui(z, z, 1, prec); TMP_END; fmpz_clear(n); } } /* todo: min prec by MAG_BITS everywhere? */ void arb_exp_wide(arb_t res, const arb_t x, slong prec, slong maglim) { mag_t t, u; mag_init(t); mag_init(u); if (arf_cmpabs_2exp_si(arb_midref(x), 20) < 0 && mag_cmp_2exp_si(arb_radref(x), 20) < 0) { if (arf_is_zero(arb_midref(x))) { if (mag_cmp_2exp_si(arb_radref(x), -10) < 0) { mag_expm1(arb_radref(res), arb_radref(x)); arf_one(arb_midref(res)); } else { mag_expinv_lower(t, arb_radref(x)); mag_exp(u, arb_radref(x)); arb_set_interval_mag(res, t, u, prec); } } else if (arb_contains_zero(x)) { arf_get_mag_lower(t, arb_midref(x)); mag_sub(t, arb_radref(x), t); arf_get_mag(u, arb_midref(x)); mag_add(u, arb_radref(x), u); if (arf_sgn(arb_midref(x)) > 0) { mag_expinv_lower(t, t); mag_exp(u, u); arb_set_interval_mag(res, t, u, prec); } else { mag_expinv_lower(u, u); mag_exp(t, t); arb_set_interval_mag(res, u, t, prec); } } else if (arf_sgn(arb_midref(x)) < 0) { arb_get_mag(t, x); arb_get_mag_lower(u, x); mag_expinv_lower(t, t); mag_expinv(u, u); arb_set_interval_mag(res, t, u, prec); } else { arb_get_mag_lower(t, x); arb_get_mag(u, x); mag_exp_lower(t, t); mag_exp(u, u); arb_set_interval_mag(res, t, u, prec); } } else { /* use arb_exp_arf for accurate argument reduction */ arf_t q; arf_init(q); arf_set_mag(q, arb_radref(x)); arf_add(q, q, arb_midref(x), MAG_BITS, ARF_RND_CEIL); arb_exp_arf(res, q, FLINT_MIN(prec, MAG_BITS), 0, maglim); arb_get_mag(arb_radref(res), res); arf_zero(arb_midref(res)); arf_clear(q); } mag_clear(t); mag_clear(u); } void arb_exp(arb_t res, const arb_t x, slong prec) { slong maglim = MAGLIM(prec); if (mag_is_zero(arb_radref(x))) { arb_exp_arf(res, arb_midref(x), prec, 0, maglim); } else if (mag_is_inf(arb_radref(x))) { if (arf_is_nan(arb_midref(x))) arb_indeterminate(res); else arb_zero_pm_inf(res); } else if (arf_is_special(arb_midref(x))) { if (arf_is_zero(arb_midref(x))) arb_exp_wide(res, x, prec, maglim); else if (arf_is_nan(arb_midref(x))) arb_indeterminate(res); else /* infinity +/- finite */ arb_exp_arf(res, arb_midref(x), prec, 0, 1); } else /* both finite, non-special */ { slong acc, mexp, rexp; mexp = ARF_EXP(arb_midref(x)); rexp = MAG_EXP(arb_radref(x)); if (COEFF_IS_MPZ(rexp)) rexp = (fmpz_sgn(ARF_EXPREF(arb_radref(x))) < 0) ? COEFF_MIN : COEFF_MAX; if (COEFF_IS_MPZ(mexp)) mexp = (fmpz_sgn(MAG_EXPREF(arb_midref(x))) < 0) ? COEFF_MIN : COEFF_MAX; if (mexp < -prec && rexp < -prec) { arb_get_mag(arb_radref(res), x); mag_expm1(arb_radref(res), arb_radref(res)); arf_one(arb_midref(res)); return; } acc = -rexp; acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); if (acc < 20 && (rexp >= 0 || mexp <= 10)) { /* may evaluate at endpoints */ arb_exp_wide(res, x, prec, maglim); } else { /* exp(a+b) - exp(a) = exp(a) * (exp(b)-1) */ mag_t t, u; mag_init_set(t, arb_radref(x)); mag_init(u); arb_exp_arf(res, arb_midref(x), prec, 0, maglim); mag_expm1(t, t); arb_get_mag(u, res); mag_addmul(arb_radref(res), t, u); mag_clear(t); mag_clear(u); } } } void arb_expm1(arb_t res, const arb_t x, slong prec) { slong maglim = MAGLIM(prec); if (mag_is_zero(arb_radref(x))) { arb_exp_arf(res, arb_midref(x), prec, 1, maglim); } else if (mag_is_inf(arb_radref(x))) { if (arf_is_nan(arb_midref(x))) arb_indeterminate(res); else arb_zero_pm_inf(res); } else if (arf_is_special(arb_midref(x))) { if (arf_is_zero(arb_midref(x))) { if (mag_cmp_2exp_si(arb_radref(x), -10) < 0) { mag_expm1(arb_radref(res), arb_radref(x)); arf_zero(arb_midref(res)); } else { arb_exp_wide(res, x, prec, maglim); arb_sub_ui(res, res, 1, prec); } } else if (arf_is_nan(arb_midref(x))) arb_indeterminate(res); else /* infinity +/- finite */ arb_exp_arf(res, arb_midref(x), prec, 1, 1); } else /* both finite, non-special */ { if (arf_cmpabs_2exp_si(arb_midref(x), 3) < 0 && mag_cmp_2exp_si(arb_radref(x), -3) < 0) { mag_t t, u, one; slong acc, mexp, rexp; mexp = ARF_EXP(arb_midref(x)); rexp = MAG_EXP(arb_radref(x)); if (COEFF_IS_MPZ(rexp)) rexp = (fmpz_sgn(ARF_EXPREF(arb_radref(x))) < 0) ? COEFF_MIN : COEFF_MAX; if (COEFF_IS_MPZ(mexp)) mexp = (fmpz_sgn(MAG_EXPREF(arb_midref(x))) < 0) ? COEFF_MIN : COEFF_MAX; acc = FLINT_MIN(mexp, 0) - rexp; acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); /* [exp(a+b) - 1] - [exp(a) - 1] = exp(a) * (exp(b)-1) */ mag_init_set(t, arb_radref(x)); mag_init(u); mag_init(one); mag_one(one); if (arf_sgn(arb_midref(x)) >= 0) { arb_exp_arf(res, arb_midref(x), prec, 1, maglim); arb_get_mag(u, res); mag_add(u, u, one); } else { arb_exp_arf(res, arb_midref(x), prec, 1, maglim); arb_get_mag_lower(u, res); mag_sub(u, one, u); } mag_expm1(t, t); mag_addmul(arb_radref(res), t, u); mag_clear(t); mag_clear(u); mag_clear(one); } else { arb_exp(res, x, prec); arb_sub_ui(res, res, 1, prec); } } } void arb_exp_invexp(arb_t res, arb_t res2, const arb_t x, slong prec) { slong maglim = MAGLIM(prec); if (arf_is_special(arb_midref(x)) || mag_is_special(arb_radref(x))) { /* [c +/- 0] */ if (arf_is_finite(arb_midref(x)) && mag_is_zero(arb_radref(x))) { arb_exp_arf(res, arb_midref(x), prec, 0, maglim); arb_inv(res2, res, prec); } /* [nan +/- ?] */ else if (arf_is_nan(arb_midref(x))) { arb_indeterminate(res); arb_indeterminate(res2); } /* [c +/- inf] */ else if (mag_is_inf(arb_radref(x))) { arb_zero_pm_inf(res); arb_zero_pm_inf(res2); } /* [+inf +/- c] */ else if (arf_is_pos_inf(arb_midref(x))) { arb_pos_inf(res); arb_zero(res2); } /* [-inf +/- c] */ else if (arf_is_neg_inf(arb_midref(x))) { arb_zero(res); arb_pos_inf(res2); } else { arb_t t; arb_init(t); arb_neg(t, x); arb_exp_wide(res, x, prec, maglim); arb_exp_wide(res2, t, prec, maglim); arb_clear(t); } } else /* both finite, non-special */ { slong acc, mexp, rexp; mexp = ARF_EXP(arb_midref(x)); rexp = MAG_EXP(arb_radref(x)); if (COEFF_IS_MPZ(rexp)) rexp = (fmpz_sgn(ARF_EXPREF(arb_radref(x))) < 0) ? COEFF_MIN : COEFF_MAX; if (COEFF_IS_MPZ(mexp)) mexp = (fmpz_sgn(MAG_EXPREF(arb_midref(x))) < 0) ? COEFF_MIN : COEFF_MAX; if (mexp < -prec && rexp < -prec) { arb_get_mag(arb_radref(res), x); mag_expm1(arb_radref(res), arb_radref(res)); arf_one(arb_midref(res)); arb_set(res2, res); return; } acc = -rexp; acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); if (acc < 20 && (rexp >= 0 || mexp <= 10)) { /* may evaluate at endpoints */ arb_t t; arb_init(t); arb_neg(t, x); arb_exp_wide(res, x, prec, maglim); arb_exp_wide(res2, t, prec, maglim); arb_clear(t); } else { /* exp(a+b) - exp(a) = exp(a) * (exp(b)-1) */ mag_t t, u; mag_init_set(t, arb_radref(x)); mag_init(u); arb_exp_arf(res, arb_midref(x), prec, 0, maglim); arb_inv(res2, res, prec); mag_expm1(t, t); arb_get_mag(u, res); mag_addmul(arb_radref(res), t, u); arb_get_mag(u, res2); mag_addmul(arb_radref(res2), t, u); mag_clear(t); mag_clear(u); } } } arb-2.22.1/arb/exp_arf_bb.c000066400000000000000000000101561417376376500153670ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* Determine N such that the error is bounded by 2^-prec when summing the Taylor series of exp(x) up to term x^N inclusive. We choose an N with many trailing zeros to improve efficiency of the binary splitting. */ static slong bs_num_terms(slong mag, slong prec) { slong N; N = _arb_exp_taylor_bound(mag, prec); /* Convert from N exclusive to N inclusive. */ N--; if (N > 10000) while (N % 128 != 0) N++; if (N > 1000) while (N % 16 != 0) N++; if (N > 100) while (N % 2 != 0) N++; return N; } void arb_exp_arf_bb(arb_t z, const arf_t x, slong prec, int minus_one) { slong k, iter, bits, r, mag, q, wp, N; slong argred_bits, start_bits; flint_bitcnt_t Qexp[1]; int inexact; fmpz_t t, u, T, Q; arb_t w; if (arf_is_zero(x)) { if (minus_one) arb_zero(z); else arb_one(z); return; } if (arf_is_special(x)) { flint_abort(); } mag = arf_abs_bound_lt_2exp_si(x); /* We assume that this function only gets called with something reasonable as input (huge/tiny input will be handled by the main exp wrapper). */ if (mag > 200 || mag < -2 * prec - 100) { flint_printf("arb_exp_arf_bb: unexpectedly large/small input\n"); flint_abort(); } if (prec < 100000000) { argred_bits = 16; start_bits = 32; } else { argred_bits = 32; start_bits = 64; } /* Argument reduction: exp(x) -> exp(x/2^q). This improves efficiency of the first iteration in the bit-burst algorithm. */ q = FLINT_MAX(0, mag + argred_bits); /* Determine working precision. */ wp = prec + 10 + 2 * q + 2 * FLINT_BIT_COUNT(prec); if (minus_one && mag < 0) wp += (-mag); fmpz_init(t); fmpz_init(u); fmpz_init(Q); fmpz_init(T); arb_init(w); /* Convert x/2^q to a fixed-point number. */ inexact = arf_get_fmpz_fixed_si(t, x, -wp + q); /* Aliasing of z and x is safe now that only use t. */ /* Start with z = 1. */ arb_one(z); /* Bit-burst loop. */ for (iter = 0, bits = start_bits; !fmpz_is_zero(t); iter++, bits *= 2) { /* Extract bits. */ r = FLINT_MIN(bits, wp); fmpz_tdiv_q_2exp(u, t, wp - r); /* Binary splitting (+1 fixed-point ulp truncation error). */ mag = fmpz_bits(u) - r; N = bs_num_terms(mag, wp); _arb_exp_sum_bs_powtab(T, Q, Qexp, u, r, N); /* T = T / Q (+1 fixed-point ulp error). */ if (*Qexp >= wp) { fmpz_tdiv_q_2exp(T, T, *Qexp - wp); fmpz_tdiv_q(T, T, Q); } else { fmpz_mul_2exp(T, T, wp - *Qexp); fmpz_tdiv_q(T, T, Q); } /* T = 1 + T */ fmpz_one(Q); fmpz_mul_2exp(Q, Q, wp); fmpz_add(T, T, Q); /* Now T = exp(u) with at most 2 fixed-point ulp error. */ /* Set z = z * T. */ arf_set_fmpz(arb_midref(w), T); arf_mul_2exp_si(arb_midref(w), arb_midref(w), -wp); mag_set_ui_2exp_si(arb_radref(w), 2, -wp); arb_mul(z, z, w, wp); /* Remove used bits. */ fmpz_mul_2exp(u, u, wp - r); fmpz_sub(t, t, u); } /* We have exp(x + eps) - exp(x) < 2*eps (by assumption that the argument reduction is large enough). */ if (inexact) arb_add_error_2exp_si(z, -wp + 1); fmpz_clear(t); fmpz_clear(u); fmpz_clear(Q); fmpz_clear(T); arb_clear(w); /* exp(x) = exp(x/2^q)^(2^q) */ for (k = 0; k < q; k++) arb_mul(z, z, z, wp); if (minus_one) arb_sub_ui(z, z, 1, wp); arb_set_round(z, z, prec); } arb-2.22.1/arb/exp_arf_rs_generic.c000066400000000000000000000076151417376376500171320ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_exp_taylor_sum_rs_generic(arb_t res, const arb_t x, slong N, slong prec) { arb_t s; mag_t err; arb_init(s); mag_init(err); arb_get_mag(err, x); mag_exp_tail(err, err, N); if (N <= 2) { if (N == 0) arb_zero(res); else if (N == 1) arb_one(res); else if (N == 2) arb_add_ui(res, x, 1, prec); arb_add_error_mag(res, err); } else { arb_ptr tpow; slong j, k, m, M, tp, xmag; mp_limb_t c, d, chi, clo; xmag = arf_abs_bound_lt_2exp_si(arb_midref(x)); /* Convert to order as a series in x^2. */ M = N / 2; m = n_sqrt(M); /* not intended (and not 32-bit safe...) */ if (M > 30000) { flint_abort(); } tpow = _arb_vec_init(m + 1); arb_mul(s, x, x, prec); _arb_vec_set_powers(tpow, s, m + 1, prec); arb_zero(s); c = 1; j = (M - 1) % m; for (k = M - 1; k >= 0; k--) { tp = prec - 2 * k * (-xmag) + 10; tp = FLINT_MAX(tp, 2); tp = FLINT_MIN(tp, prec); d = (2 * k) * (2 * k + 1); if (k != 0) { umul_ppmm(chi, clo, c, d); if (chi != 0) { arb_div_ui(s, s, c, tp); c = 1; } } arb_addmul_ui(s, tpow + j, c, tp); if (k != 0) { c *= d; if (j == 0) { arb_mul(s, s, tpow + m, tp); j = m - 1; } else { j--; } } } arb_div_ui(s, s, c, prec); arb_mul(s, s, x, prec); arb_add_error_mag(s, err); /* exp = sinh + sqrt(1 + sinh^2) */ arb_mul(res, s, s, prec); arb_add_ui(res, res, 1, prec); arb_sqrt(res, res, prec); arb_add(res, res, s, prec); _arb_vec_clear(tpow, m + 1); } mag_clear(err); arb_clear(s); } void arb_exp_arf_rs_generic(arb_t res, const arf_t x, slong prec, int minus_one) { slong q, xmag, wp, k, N; arb_t t; if (arf_is_zero(x)) { if (minus_one) arb_zero(res); else arb_one(res); return; } xmag = arf_abs_bound_lt_2exp_si(x); /* 1 + x + O(x^2) */ /* We don't really need to worry too much about degenerate input because the main exp function already takes care of it. */ if (xmag < -prec - 4) { mag_t t; mag_init(t); arf_get_mag(t, x); mag_exp_tail(t, t, 2); arb_set_arf(res, x); arb_add_ui(res, res, minus_one ? 0 : 1, prec); arb_add_error_mag(res, t); mag_clear(t); return; } arb_init(t); /* generic tuning value */ q = 4.5 * pow(prec, 0.2); q = FLINT_MAX(q, 6); /* adjust to magnitude */ q = FLINT_MAX(0, xmag + q); wp = prec + 10 + 2 * q + 2 * FLINT_BIT_COUNT(prec); if (minus_one && xmag < 0) wp += (-xmag); /* t = x/2^q */ arf_mul_2exp_si(arb_midref(t), x, -q); N = _arb_exp_taylor_bound(xmag - q, wp); arb_exp_taylor_sum_rs_generic(t, t, N, wp); /* exp(x) = exp(x/2^q)^(2^q) */ for (k = 0; k < q; k++) arb_mul(t, t, t, wp); if (minus_one) arb_sub_ui(t, t, 1, wp); arb_set_round(res, t, prec); arb_clear(t); } arb-2.22.1/arb/exp_sum_bs_powtab.c000066400000000000000000000125541417376376500170240ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* When splitting [a,b) into [a,m), [m,b), we need the power x^(m-a). This function computes all the exponents (m-a) that can appear when doing binary splitting with the top-level interval [0,n), assuming that we always choose m = a + floor((b-a)/2), and that the case b-a = 2 is inlined. */ slong _arb_compute_bs_exponents(slong * tab, slong n) { slong a, b, aa, /* ab, */ ba, bb, length; if (n == 1) { tab[0] = 1; return 1; } if (n == 2 || n == 3 || n == 4) { tab[0] = 1; tab[1] = 2; return 2; } if (n == 6) { tab[0] = 1; tab[1] = 2; tab[2] = 3; return 3; } /* first binary splitting call */ a = n >> 1; b = n - (n >> 1); tab[0] = a; length = 1; for (;;) { /* split a -> aa, ab and b -> ba, bb */ aa = a >> 1; /* ab = a - aa; */ ba = b >> 1; bb = b - ba; tab[length] = ba; length++; /* at length 3, we split into 2, 1 (and maybe also 2, 2) */ if (ba == 3) { tab[length] = 2; tab[length + 1] = 1; length += 2; break; } /* stop if we have reached 1, or if at 2 and the length is a power of 2 (in which case we never reach 1) */ if (ba == 1 || (ba == 2 && (n & (n-1)) == 0)) break; /* if left and right lengths are different, also add the right length */ if (aa != ba && aa != 1) { tab[length] = aa; length++; } a = aa; b = bb; } /* we always include x^1 in the table, even if the binary splitting terminates at step length 2 */ if (tab[length-1] != 1) { tab[length] = 1; length++; } /* reverse table */ for (a = 0; a < length / 2; a++) { b = tab[a]; tab[a] = tab[length - a - 1]; tab[length - a - 1] = b; } return length; } /* just do a linear search */ slong _arb_get_exp_pos(const slong * tab, slong step) { slong i; for (i = 0; ; i++) { if (tab[i] == step) return i; if (tab[i] == 0) { flint_printf("ERROR: exponent %wd not in table!\n", step); flint_abort(); } } } static void bsplit(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const slong * xexp, const fmpz * xpow, flint_bitcnt_t r, slong a, slong b) { int cc; if (b - a == 1) { count_trailing_zeros(cc, (a + 1)); fmpz_set_ui(Q, (a + 1) >> cc); *Qexp = r + cc; fmpz_set(T, xpow); } else if (b - a == 2) { fmpz_mul_ui(T, xpow, a + 2); fmpz_mul_2exp(T, T, r); fmpz_add(T, T, xpow + 1); count_trailing_zeros(cc, (a + 2)); fmpz_set_ui(Q, (a + 2) >> cc); *Qexp = r + cc; count_trailing_zeros(cc, (a + 1)); fmpz_mul_ui(Q, Q, (a + 1) >> cc); *Qexp += r + cc; } else { slong step, m, i; flint_bitcnt_t Q2exp[1]; fmpz_t Q2, T2; step = (b - a) / 2; m = a + step; fmpz_init(Q2); fmpz_init(T2); bsplit(T, Q, Qexp, xexp, xpow, r, a, m); bsplit(T2, Q2, Q2exp, xexp, xpow, r, m, b); fmpz_mul(T, T, Q2); fmpz_mul_2exp(T, T, *Q2exp); /* find x^step in table */ i = _arb_get_exp_pos(xexp, step); fmpz_addmul(T, xpow + i, T2); fmpz_clear(T2); fmpz_mul(Q, Q, Q2); *Qexp = *Qexp + *Q2exp; fmpz_clear(Q2); } } void _arb_exp_sum_bs_powtab(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) { slong * xexp; slong length, i; fmpz * xpow; /* compute the powers of x that will appear (at least x^1) */ xexp = flint_calloc(2 * FLINT_BITS, sizeof(slong)); length = _arb_compute_bs_exponents(xexp, N); xpow = _fmpz_vec_init(length); xpow[0] = *x; /* create shallow copy of x */ /* build x^i table */ for (i = 1; i < length; i++) { if (xexp[i] == 2 * xexp[i-1]) { fmpz_mul(xpow + i, xpow + i - 1, xpow + i - 1); } else if (xexp[i] == 2 * xexp[i-2]) /* prefer squaring if possible */ { fmpz_mul(xpow + i, xpow + i - 2, xpow + i - 2); } else if (xexp[i] == 2 * xexp[i-1] + 1) { fmpz_mul(xpow + i, xpow + i - 1, xpow + i - 1); fmpz_mul(xpow + i, xpow + i, xpow); } else if (xexp[i] == 2 * xexp[i-2] + 1) { fmpz_mul(xpow + i, xpow + i - 2, xpow + i - 2); fmpz_mul(xpow + i, xpow + i, xpow); } else { flint_printf("power table has the wrong structure!\n"); flint_abort(); } } bsplit(T, Q, Qexp, xexp, xpow, r, 0, N); fmpz_init(xpow + 0); /* don't free the shallow copy of x */ _fmpz_vec_clear(xpow, length); flint_free(xexp); } arb-2.22.1/arb/exp_sum_bs_simple.c000066400000000000000000000026631417376376500170210ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void bsplit(fmpz_t P, fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, slong r, slong a, slong b, int cont) { if (b - a == 1) { fmpz_set(P, x); fmpz_set_ui(Q, a + 1); *Qexp = r; fmpz_set(T, P); } else { slong m; flint_bitcnt_t Q2exp[1]; fmpz_t P2, Q2, T2; m = a + (b - a) / 2; fmpz_init(P2); fmpz_init(Q2); fmpz_init(T2); bsplit(P, T, Q, Qexp, x, r, a, m, 1); bsplit(P2, T2, Q2, Q2exp, x, r, m, b, 1); fmpz_mul(T, T, Q2); fmpz_mul_2exp(T, T, *Q2exp); fmpz_addmul(T, P, T2); fmpz_mul(Q, Q, Q2); *Qexp = *Qexp + *Q2exp; if (cont) fmpz_mul(P, P, P2); fmpz_clear(P2); fmpz_clear(Q2); fmpz_clear(T2); } } void _arb_exp_sum_bs_simple(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) { fmpz_t P; fmpz_init(P); bsplit(P, T, Q, Qexp, x, r, 0, N, 0); fmpz_clear(P); } arb-2.22.1/arb/exp_tab.c000066400000000000000000003203441417376376500147250ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #if FLINT_BITS == 64 #define Z2(a,b) UWORD(0x ## b ## a) #else #define Z2(a,b) UWORD(0x ## a), UWORD(0x ## b) #endif #define Z8(a,b,c,d,e,f,g,h) Z2(a,b), Z2(c,d), Z2(e,f), Z2(g,h), const mp_limb_t arb_exp_tab1[ARB_EXP_TAB1_NUM][ARB_EXP_TAB1_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,80000000) },{ Z8(ff554e0d,eaf5c2fa,5c67ff57,abee91b9,020d348f,e82f3725,fafa1201,575bd293) Z8(d0372a42,1eb90105,8676076f,de780649,3554f733,45152169,5aabbbe9,80804015) },{ Z8(7539dd57,e5a39b83,5319c8f5,32a6326f,421fa89a,c54f1230,b416c333,da17fb32) Z8(c0482614,80ab44b0,ed70fa46,37b1c91e,39b44e99,1931c15e,00222d86,810100ab) },{ Z8(e184c3b3,c58f8dbc,34da4bae,bbc6f344,767a5698,39c05a2d,27d75440,28927bad) Z8(2c5d5be9,a747371f,0ac8a0c5,b2d88edc,773b6516,6ca08d0e,b103b504,81824241) },{ Z8(c5f3a3dc,73f545e0,3415b128,87330d08,9ab33afe,5993a7fc,8b7f018c,67380747) Z8(5ec2eb5c,835210e4,a313b765,b790820f,822735a2,5c3259f4,aef1c8bd,8204055a) },{ Z8(2aff18d3,8a31a8cd,bcf94f83,66a19fd1,42d9b6fe,41da9652,16a3dd96,1a75fc21) Z8(12a99dec,c67acf4e,181af4d3,277b532d,6f1fc743,6d0fbdc3,bd1036e1,82864a77) },{ Z8(31ae8d90,71b06712,3048b19c,41ae308a,8b915b5a,6e3f14ae,271261f8,88ab6a8b) Z8(c8bf2dd3,173a4446,46104e0a,42bd2733,4adbb70d,2b2cebaf,2086e8a7,8309121b) },{ Z8(b08d6622,76f0ab8c,58614061,045cf4ca,0746e9f4,dab69d5e,fa9674f0,8a9a605e) Z8(0ba1fc43,a77c428f,30830a66,3f64c60c,cf3484c2,ed9945c8,a104277d,838c5cc7) },{ Z8(fa5e04c3,15a1b025,58c8cf5e,600ffa90,36da5eed,ab7e698e,f9e9a1cc,5c7720f2) Z8(fb0c3076,89fef98b,92234035,55280bc2,d4064bd3,05e841d5,893f64c7,84102b00) },{ Z8(314b6b0b,17b00bf5,348c1c57,d271ab7d,078067ed,fa493689,52d00e27,e9f872a7) Z8(762265a9,3720d66e,93c2ba38,5d17bac3,d6fbe6b7,2277b709,a77c8498,84947d49) },{ Z8(a6eee1fe,4f2e618a,0226a8f9,f2486800,eff57f8e,e7c949d8,a10f6f11,4bbc4e57) Z8(c20d2769,76b3175a,ca7bc0b3,9fafcc07,cd8d8884,2e60e7ca,4e0fac0a,85195427) },{ Z8(16a47ce9,2eca70dd,e5764424,ff05f601,635e0cc2,23c7725c,f8f02447,1a1a8833) Z8(910f86ab,3c5dbada,098d739d,fc17f52c,90afe905,7d6e234f,53e19398,859eb01e) },{ Z8(65f03ae8,26407119,96d943f0,58531dfb,6e386d7b,b69f8894,731f1fee,ea9a7502) Z8(369fd391,b283022a,043be481,ed3ac5a3,2594af50,967f31eb,14f45e14,862491b4) },{ Z8(b4f0d23e,e311637b,bcd99b4e,a18be517,5e3be3ee,6a86a3c1,c8a332d5,ca7a8250) Z8(c230356f,e1e4cf30,c1f52eda,622fd1b2,54712710,735b6853,72e8f4b3,86aaf96e) },{ Z8(09376634,f971d411,543de67f,26853de0,f9928040,c4230144,d85cd08a,4db3ffb7) Z8(4e94081c,7fe48459,68805db6,7d8b029e,1a0e0eae,9209beb6,d584e8b9,8731e7d3) },{ Z8(1ae82c51,3b513f8f,b8290d66,5c8bc828,44537ddb,34c177b5,a4a9bef4,c9cf2a83) Z8(0f8c48ac,a744e4ad,011547f0,ef77ad79,168701d1,b966251a,2b38db4b,87b95d6b) },{ Z8(c3ec7771,94d3ccf6,c5428436,44a1b430,410caf75,56f32f75,25d7aa18,d2f4ee1c) Z8(ef3fcf23,624bec06,c3e1237c,dd14aaba,12e4d4a8,d8d00cf1,e9a76bea,88415abb) },{ Z8(ad201cba,c49b7467,b12d3cff,78069023,19b293f5,4db3c62e,5f44189a,67cd64ec) Z8(fc907294,01e1487f,bc51f747,435c4a97,d9bcd368,f1794615,0e2cae21,88c9e04e) },{ Z8(6f450efa,c116b6e5,74dd3a44,cca4c182,091da1a2,82551654,3e65c65a,ad53eca0) Z8(74774a1b,fe2d70f4,ff6a7549,0d22651b,1e4256f6,7f0e6253,1e6626ed,8952eeaa) },{ Z8(9d4df7d7,4e574c75,6ace1e5e,f042a379,87e05013,a19ff4aa,0f7388c7,97a469e8) Z8(fea4349a,e01bcb46,31b11be1,ab7a48af,296927f1,5d2b5d3a,28bb5264,89dc8659) },{ Z8(45827151,eb233b9f,eae73603,eb8227f1,2e4df3ca,ff06158c,1283deec,a0867b97) Z8(8c3d07ab,c4c607fb,252590b5,3204d2b5,13ce2f05,af50ce37,c4e6b22a,8a66a7e4) },{ Z8(7b6f9498,a77871cb,c7852dba,944762a9,a8660859,e16afa51,0e7d6158,d5cc78d5) Z8(01f1c868,59c88bc8,15d3244e,4630d03b,089acf68,d9d7f8b7,147f6537,8af153d7) },{ Z8(bcff94a1,ecce7623,4ad6897f,17b55cd9,e25e4701,3bf5f538,c3d5aece,096ae22d) Z8(7d2ef735,13e29881,a01809dc,f6e2ba5f,82cae079,23b72aa5,c3834979,8b7c8aba) },{ Z8(f6ee0cee,17a6b464,9439ddb4,c1e11367,99080f5f,9736e366,27094655,03a51f82) Z8(628f06e9,6956229c,4767396f,1a3777e4,d3079a98,22c48dd2,08e1a7db,8c084d1b) },{ Z8(754c3938,74e5fa46,a3e485cd,73e7aae1,ca779092,27bd225f,2e1dfd17,f7da756c) Z8(f503d876,04261d08,ea6c3274,f3da3da8,40755e14,9e8c66dd,a7066b44,8c949b83) },{ Z8(3e4aefad,273c6da4,faa8f661,ae7879f5,1fd1563f,00f3c053,2f1c87bd,165e8af7) Z8(cf420806,78113051,ea50abec,90b2581c,a3ee97c2,20c13e5d,ec65e30e,8d217680) },{ Z8(0a32b41d,4539d082,52aca6e8,8099986f,71474f4f,e9ec3d99,a5004eb6,1ca3fda5) Z8(ced96c90,1a6ec938,d9e848ce,956773bc,00eedaab,f5c92a52,b4091181,8daede9f) },{ Z8(55c90bc5,41896020,fc1c67ef,7959583b,a49ae8a4,b4dd8211,59b34efb,3a95d5dd) Z8(1d84535d,c29e27c5,b1707447,5c5e1c92,1ebff081,ebf3e989,661a86f0,8e3cd46d) },{ Z8(e1ce068b,eb9216a2,ac1983f1,ad8bffb6,441648fe,f480be00,7bfe9766,705792c8) Z8(c4a424c8,f0946cb9,6a39122f,7629b2da,06c3015f,ac7a4d32,f873c9e8,8ecb5877) },{ Z8(0e9e3fa5,1a51d8f4,4c56a1f9,9d172707,b0dbab91,f76bd471,c90d28e9,884d09ab) Z8(e52992c8,68922f7d,25f11282,9701baa4,6808fb4e,1689123e,ef2b4d19,8f5a6b4d) },{ Z8(4b3208f7,b04edb2a,93ec95f7,3168b6e9,dcd7c570,000aab51,20b212a2,b4da6405) Z8(48a7a6d6,83b4124f,8eb396a0,c57d8298,e625fbf5,92485a20,5d22f376,8fea0d7e) },{ Z8(827a03ef,c230bac2,2c4330b7,3025da31,65c99270,7fabbc3a,a1605373,9ff86ee1) Z8(b3009532,21637b8e,330b7a67,6b488058,62ec47c2,e00df647,e4972327,907a3f98) },{ Z8(12b5ae61,0a584fe3,ef3e2399,178072e9,2ce1e182,4ef19144,3a8af5bb,bc3b803a) Z8(8118966c,bbb5b0f2,54ab82be,3c5f8642,7035c6a1,76b441c2,b7ae67ce,910b022d) },{ Z8(7afef92e,647f369d,7f9733ad,0cced069,6823001d,9c5901b3,83ed1e44,e2a422ac) Z8(50bbe330,83e9c1c6,c38f6f71,7f068e1b,dc0e7861,1369dfa1,9909a4b9,919c55cd) },{ Z8(16306395,56ad1e1c,b994ac18,18a8ef2d,c1d2a98b,a4794333,7f783bf5,b286404a) Z8(46779a79,be9e8a03,8c6d328f,bbebe950,5d77d732,ad38f205,dc54d790,922e3b09) },{ Z8(a4e8f4ce,71ebfa13,298ff3dc,e974b9d0,3de2fc9c,e0a935be,e51fa743,4eb040f3) Z8(3127f9b0,02421d87,dfae293a,0a70cd55,1411f170,8efecda2,66d86c10,92c0b274) },{ Z8(804c447e,d3ba6d91,0539ddb4,735d22d7,a7e1c9d0,14c5c9eb,1238e6a3,daba3c05) Z8(6f959d26,77d59047,6356c038,6763c7e8,4d070592,eb986004,b00b215a,9353bc9f) },{ Z8(c77449f0,38db74d5,a5f626bd,a5e257df,4cd4abcc,0183ea35,cf30482f,2251c46d) Z8(eb8d48c3,bfda9858,1fa50b25,d8069a7a,123ea059,d1a4052c,c224817b,93e75a1e) },{ Z8(169e5bb7,491ab6f9,fbf113a9,0af845a0,a903e47f,097985c0,0bfadb52,bd2a6016) Z8(b3113bb9,2a497a4a,fac69782,8a84bd5b,0097199a,f667f4e7,3aafebac,947b8b85) },{ Z8(a1517ce4,da86c052,47a67561,127cfaa5,97acb08f,f0a615e4,b0bd87e1,7fd15f21) Z8(64c595de,523cc7ad,d839cdfc,7f38f6e0,36a250bc,622d53a9,4b2031ed,95105167) },{ Z8(06557e3f,751a929f,8482b781,38f8d82d,5dbb18d1,fae289c7,0dba2b34,5ed19617) Z8(9bcb9778,d23a6bec,30f5450e,32a17622,cebec9a5,9bb3e062,b963ca80,95a5ac59) },{ Z8(54bc32de,dca7cbd1,fa03b236,5742f008,3db0b97e,1139e905,34b639ff,1a3ecb2f) Z8(52322710,c73ea90f,a4c2e759,8fff291b,3f6365b2,8449c43b,e07995e9,963b9cf1) },{ Z8(e1836a48,4916fbf3,407b6cd6,bd3577d4,06021fe6,9bc4fd30,b8d6f8c6,129d3a7e) Z8(f5557d0f,a2e2151a,801f08da,c3cd4cba,c2d11ea9,aa8ec61f,b10639f5,96d223c5) },{ Z8(9f929cb0,6dcac6ad,8e9f7724,12a2ab4b,908a440d,873d4b3f,3095135d,fc8afd92) Z8(f9d0e418,f1fe1c91,0381d908,ba2d8fc6,557ecedf,6efaa729,b1ea126e,9769416b) },{ Z8(16d41b76,5c56ee07,28a91c78,043e61f8,db2401d3,1d97ef3c,deb5ff7e,b6576877) Z8(35d5059d,d53a4794,764049f1,7458999f,7ffaabe3,eae44b1a,00d7b805,9800f67b) },{ Z8(be072c3c,ac83c46d,959ce10f,43441db1,aa0c6342,ba62c3b0,18b5bd1a,876f4af1) Z8(6eddc485,16620f72,f2e0ce50,90cf4044,e85fca95,21031f3a,52eb1e16,9899438b) },{ Z8(817cb6c9,000d8da1,3cd8ceda,19c9d6ec,db5aafbf,5e9350cd,facf6daf,f14adb6e) Z8(ca068ef0,7c50e649,8eb31936,1138b433,6c669095,953687e2,f54147c9,99322934) },{ Z8(7f8681bd,a190226b,ab4cd129,f7ea201c,4e5c013b,f7875ad0,99180921,1037c2d5) Z8(ac49b2cd,e784b424,f946e585,09873a27,aa22abbf,00c890e9,cd909545,99cba810) },{ Z8(87dd346f,ca85cf4b,24f1a452,34a88b53,1f7f1004,106e57b6,b021cf84,c73b9006) Z8(f1746808,230db4ad,8982478c,84735853,e33249a2,7062465b,5ac1a96a,9a65c0b8) },{ Z8(7c356e5b,69f8fa96,61870a99,0218d591,c193a385,1f1178c0,72e52501,1838941b) Z8(8f3d9be3,ed1e350d,89c119eb,9825b216,42499fc6,b181912f,b588e8ce,9b0073c5) },{ Z8(7fce8e79,aacb0e93,50656c98,684a0b97,71876338,802ef47b,3d49eb12,a5125c28) Z8(767e8763,fcbea459,701a030f,003bd2ff,40c3f393,8e72d00e,9100927a,9b9bc1d3) },{ Z8(8cb76164,fe6f09f1,9d9a6be9,30465f7b,4e482369,d3bc15e3,fae79f6a,3ec82d9c) Z8(14cc934d,bbf08610,aa8561dd,cb3f51e0,a2421e19,f19c3f91,3b437311,9c37ab7d) },{ Z8(bfaca379,4e6d26bc,9c5575c6,c0a76f8b,0db855fb,61d5796c,543e31d7,6f57b6c2) Z8(65ade5b9,b33ee3c5,4af46af4,a664dd10,1f83baa8,a34f397a,9e0832fb,9cd4315e) },{ Z8(5343d148,917c5a3c,784a2c1b,17208f4e,580c1157,b66197f0,84a4e5e5,f2be6712) Z8(e3e54163,d50253bf,5b379167,5e949a45,68a13ed6,f053f9e9,3f3d4024,9d715414) },{ Z8(17b4041f,64422b57,61e5daa6,8dbd78cb,1bebc754,6f402c61,f9500c8d,7df63d8d) Z8(131e9c0a,8f17dc02,3cde0202,49163414,55f56fbb,23008f4c,41a553fd,9e0f143b) },{ Z8(c35785e2,59c303e2,9062700a,dca43d16,12921e02,fe633e4e,2befee40,026a748a) Z8(87157ad4,47d49796,4632b2ec,26cb8d19,f105db8f,54e37937,65749645,9ead7271) },{ Z8(c19b29c7,6cfcc965,dd49750a,b76abdf7,0e8b6bdf,24273cf6,9a601d51,3db9cdea) Z8(bcef8461,23cf2474,10a259ca,abbb03b0,6028ab6b,bbdee020,08ee5d51,9f4c6f55) },{ Z8(84d3305f,1f0b6a6d,1b9ab692,283a8898,8cd868f5,679f512e,9254b255,82688a79) Z8(9158803a,f77aff77,f3e06dbe,71b89421,23395b71,3302d860,29038c5a,9fec0b85) },{ Z8(8081867d,b3a9f222,963b9eb0,63b978e2,04087ce0,1bccb9f8,c852f980,10d56a7f) Z8(5e1e3971,2b4e1fbe,1843151e,38c74d96,0b13df6a,5d846bf1,61f19078,a08c47a1) },{ Z8(d050d184,b70aa630,5254e219,c6a02b1f,65c7414f,1ffddbc0,0fe8bcda,99de91fa) Z8(b3c417d3,7d818b4e,2a2453a9,8fb39f57,3edd5bd3,60dccd8e,efe1fcf2,a12d2449) },{ Z8(57a2bf8c,ae521fcc,3830945e,e70f392e,33e630f2,f68ce37d,f707fb5d,07513ea2) Z8(3d7e35d1,c3227bed,e7ffff90,f4863dfc,2de9f407,d268bc65,af8ac771,a1cea21f) },{ Z8(a4c8c38e,a0b70a4e,c96b775a,8682fdab,cfb17d82,98e413c1,e7ef511d,5aa8151a) Z8(628d2955,703beeaf,7e431481,0575cf69,2d052d45,14cc604f,1ecf24c7,a270c1c4) },{ Z8(0d5d6bf1,51b067ac,be11f968,194e0145,85a1a23d,29a60e29,57b50061,87c1134a) Z8(58a206e7,3d297046,6c39d9a3,d806948c,002d9c0c,01ec63b3,5d6106da,a31383d9) },{ Z8(bc1b92f0,3f6626af,b238a27a,d6d622fb,f94f17a3,587ea5ae,575c9ede,057687ba) Z8(32bc5fcc,9083444b,ed3bd302,28b3b225,40fb8b02,5f7a6a31,2d633c69,a3b6e902) },{ Z8(a772363f,99ce2eb2,234be1dd,ec5ac020,1ae273a9,752a6f2f,2726e6e9,d7a1733b) Z8(ad3105f5,4c9f4678,25df1585,621c438b,d55f29a7,3de1db4d,f40c333b,a45af1e1) },{ Z8(219c31b6,e2541f1e,78978091,4fb7d16b,3c3ec0c6,a6c44f11,ad73099f,4c13f79d) Z8(94ca321c,833de234,dee34bcf,01bc6d00,67b0c196,03d2f032,ba495d61,a4ff9f1c) },{ Z8(bb2ef4f1,eaac6b84,4f9a068e,9564270e,ab604d4e,b560c83c,0ecea96e,70a5c5b3) Z8(36600374,fd5dd7d4,89c129a9,3a8c127e,0da79996,8bbdaddb,2d633a32,a5a4f157) },{ Z8(2514571f,3cd1cc8e,158ec169,7111606a,806a5823,c906bd59,4983c976,47b76cb9) Z8(d0348007,247af92a,5a45697e,1dee1c48,cf7ec6b3,5c459492,9fa203a4,a64ae936) },{ Z8(2ac7794e,bf9234a6,c6ed3c3d,ed3c2f22,a7d6b5e8,7fd92b25,9651497d,a76a206d) Z8(c80754aa,46dce364,269b57ef,185380d5,b893501c,a911f650,08f3009d,a6f18761) },{ Z8(57eef36a,63207fc0,0cdbe74d,06c43422,91691488,cf7b1dfe,aec4e707,cd984500) Z8(73d90acf,48332cb5,8c1d9119,ca532c8f,bd79f735,6e5ebba2,078e7cf3,a798cc7d) },{ Z8(a8d90bbd,67cd5b27,fcd6ad1d,cf92d187,e7089b51,4642889e,88956982,989e9224) Z8(80f0a7d3,bc45bfd6,4841384b,dd6a7226,f4c94954,9f568761,e09e67ae,a840b931) },{ Z8(691ce8ac,084ffa21,9b84ce94,ac1c87c9,5160d359,75b0eca6,10323324,42ac231f) Z8(1bb14c86,f107450a,a00346de,b2c85576,95fa5152,058a4a10,80e59844,a8e94e27) },{ Z8(c97ced2b,9252f7d8,54edb8e6,be3dd628,903aa117,6c601d5a,7b001fd3,478824b9) Z8(f71cf53f,37a84887,9bfa0a11,63232c3e,1b4fdb27,16cc14c9,7d67bb65,a9928c06) },{ Z8(3f6b1089,2699b00c,07f942ff,92eeb622,d9519893,2973ee69,0a611937,890715a8) Z8(a7224245,5a7d4043,7767446d,b4b68282,8d9a2790,ae4c0000,1411e811,aa3c7378) },{ Z8(7cb3e50a,e7c812c8,883f5cc1,2d14a344,c9ce881b,20a31109,56a1b834,4fac9001) Z8(b6b300bf,2c801f4a,9f7503d9,1869b661,7d3d3eef,3e16eba5,2c63dd93,aae70526) },{ Z8(77a829e1,b6c9c698,26b2c32d,f7d3ef20,5322ee94,b32bb84e,c8f8d16f,02791934) Z8(61469e7a,89bf3407,05d72e21,ff467b72,7a67af60,b700649a,5819eb0a,ab9241bb) },{ Z8(376d95d8,2a9a13cb,a16dc12a,9f52a62f,19664d65,d093d678,1a6ffd80,57b8dd22) Z8(66f6b422,e0a88471,229ddf14,c41ae021,936f2fa0,0e93c017,d3d7813b,ac3e29e2) },{ Z8(02d381e1,7b409c7f,bdea298b,b92c2681,c2eba22e,d4c21cda,fede402e,64081a64) Z8(8b5df900,db9d64ef,ad610a61,4cd9ad3e,4e7ea423,f4e529b5,87d26f3a,aceabe48) },{ Z8(9fc8f4c0,2b0942c6,11477286,06a69fa7,ad2fbc2c,058674cb,b1baf450,00afdae8) Z8(d5f92df3,02073979,07497710,128f49c2,758c0621,f7029f01,087ecab8,ad97ff99) },{ Z8(3b1568da,6f7e9a5d,0422f959,167c8c05,44050549,57afe5b6,9905d851,4114af9f) Z8(8d5baaec,5af88d9f,301f5a37,ca8dfde8,2d487eac,f6574e6a,973b847d,ae45ee81) },{ Z8(21a2a36d,f17c3a2c,3117f371,d3f72e33,0320c24c,777680b6,0137a911,355f7545) Z8(a117c185,f10196af,06799385,4ed96178,baa201e1,89923298,22ffa9da,aef48bb0) },{ Z8(650ade4a,233ec3c6,de91b76f,85497a73,e1872922,58f93e38,db66cc5e,1b76e360) Z8(99fcad3e,a9db5fee,4b4356ed,7da9479d,80234b29,888bbb41,490853ac,afa3d7d3) },{ Z8(7066a29d,0fdd6ba5,6c06e9f3,f7926909,4f515cce,67ec0ce6,becba3dd,75cf511f) Z8(7951b9c6,344f7ee5,800cffe5,7c495d57,235a5bdf,b23e8de5,558743aa,b053d39a) },{ Z8(53611bc7,a2a396ea,86af9e9e,9b7a80a0,71268ee6,ecab3f4d,6c1cb63f,6085ef16) Z8(c51a55f1,b98ba908,bdbbb9be,fe0dbfe0,ba5c4a72,0a2d9197,445230a5,b1047fb5) },{ Z8(8fad4018,5ae2d7b9,f7f18239,9be0d73f,29eea2f2,52f0b251,6e600e8b,d51cf072) Z8(6ec54367,ab07e2b9,6a080a77,e8761421,919e1311,39863ee4,c192c269,b1b5dcd4) },{ Z8(76c382d4,1fef9f82,34284925,05d482d1,10ede4e6,1b7cbda2,bc011498,99632470) Z8(c1a410fb,0939b1b4,3ca22fc7,afd98530,5f4349e6,eff23f44,2a773dfa,b267ebaa) },{ Z8(be33f83e,df21cc24,b91267f3,1081074f,15cd8019,8610cc02,a7392963,4258d268) Z8(9ae43567,8ba807f4,3714a029,1a0cfe1b,b3b75152,f05f75fc,8de3e2d0,b31aace7) },{ Z8(8bbf44c8,85983612,897cfac7,4001a9dd,fa35ca10,cac843d5,632d4d9f,1e0f0786) Z8(29bf636e,c469f099,42ceca33,46889a12,44f6b321,270a46f6,ad24f9c8,b3ce213f) },{ Z8(c179dd79,38b3f2dd,acf98ab1,0a586b38,672286d3,5a180e4e,54cdaf0f,d6388aaf) Z8(63a9bd88,d965ecd5,9de09776,5c9b5313,1bd3a598,d7cc0829,fca1967e,b4824965) },{ Z8(e44feb9a,29246239,a798a8ac,ff341603,bde555f2,aa4ac4ed,fbf75a6e,594e1852) Z8(f7f38c36,8c21801f,201a37d4,f799b2ba,d79b334d,a617b15f,a48f0bca,b537260e) },{ Z8(03490f37,65b6fb6e,b3bbc065,1aabcce5,b140e45f,c20d3cd7,5e9b2243,1a5c9215) Z8(55bf4cdc,c70dce6d,03e23eae,7bdce92f,62d0201f,eb29c6ae,81a513fc,b5ecb7ee) },{ Z8(6c71a6d4,f0b3ba83,0927b792,cfa1d2e1,8a3900ca,7044b6d9,d7c75558,d85d5858) Z8(1cbdeef5,0f9e0080,f8eaa509,86c75f59,8abd8d81,82bed727,25d2ada9,b6a2ffbb) },{ Z8(d2df0f17,e063510a,29437ad6,8e2c9000,225e25dd,8570a015,76551a36,43a0e83d) Z8(4d9524ae,8ae4888d,6e708486,ae77b3d8,5f9881bf,eb266eee,d8f3ada4,b759fe2a) },{ Z8(84008514,a05e484a,a4f17cc6,555450d6,757db26c,2a215c08,4a50b7b9,ba4012d9) Z8(f932ef45,4b298f88,392a69a3,0b27e884,a8612550,4abfbe36,998706ef,b811b3f4) },{ Z8(255bbad9,6ed11c6b,a413528c,3ec953a3,d3cbfe23,dbc114d1,4dbccc9e,5dda1e7d) Z8(b53b9a74,8bcd340c,5d073a51,4c8d3b25,7e43200b,a2da2b5a,1d65c942,b8ca21d0) },{ Z8(09654589,0db5b545,8c7f382a,0ff0ec27,1ef6fed7,e5558551,7b22393b,07544852) Z8(b6348584,0bbb2fb6,2345f6e2,eed6a4b6,5293db52,2e9742c7,d27ad6fb,b9834875) },{ Z8(293ea004,58100d98,00085c4b,a07fd77e,a8de6b88,7c2d5e61,fdb5ea59,e61ceb40) Z8(39d43d41,dc36bb78,9a5c6dbe,bc7d210f,849202e2,a3c5b2cd,df7b5311,ba3d289e) },{ Z8(ef137b40,279b1b9f,866ed6d1,14422eea,b334c658,96ef9504,b0f85f3b,f34797c0) Z8(4d472771,f8a43914,cfb4ac07,e07c46d5,8b43d3b0,c3bef2ad,249fc7df,baf7c305) },{ Z8(69ad3147,5d11f017,fc192280,8f7099bd,5fdf95c7,03341526,d64a50aa,3f674b05) Z8(f31b6828,d714ee7e,0d62d01b,77988166,94e852b1,631b93a6,3c5e0768,bbb31863) },{ Z8(1d6ed728,8b559e90,8dec75b6,d72618d8,65ad5298,305d7b9d,e28d3a60,d41f0180) Z8(c2b57ae5,780d7ac5,3fd2a29c,d40951a0,c73174c7,c895c116,7c23c5dc,bc6f2974) },{ Z8(2f4c05bb,92347f7f,e5a037f6,7c174c9f,e8513ce1,fef211a5,129a16b9,d32b2556) Z8(272a5656,f8cd4f6a,e4a416f4,bbe4009d,97ac8074,fdaedb70,f511ef19,bd2bf6f4) },{ Z8(a5438062,23df2039,b2b55b65,95074e6b,2c9a40d7,cfd3958a,7bc40647,da302301) Z8(3c25c931,09e080d4,06ec548b,c58ce2d6,7892eb7d,66a51b20,74b8b7d9,bde981a1) },{ Z8(0abb7e52,f73f5764,0b625d0a,d6efa031,0c8d5878,dc7d4a96,7c4925c4,fd3867e6) Z8(b71acd5b,9c553c28,cebbd558,d4f938bc,64a51aff,b2f97f72,85d46b50,bea7ca37) },{ Z8(92c74438,e7d09610,3fa58221,282465e7,12219033,2a1b41f5,1c64c1f8,ff7d43b9) Z8(93034bfe,6fb21abd,7f40ff4d,45422ccf,13425149,f435b5cb,710af5fd,bf66d175) },{ Z8(19c092f5,20a81315,8711865a,92f265e5,cf26b468,a2fa5bf5,34812af1,4e2c2982) Z8(a9e20ce6,90ca9c65,e1347404,65aa4053,44a5ecea,65cddb8c,3daa2e5d,c026981a) },{ Z8(83977506,9c00bc7d,ebc08671,dee69b9a,de44e88f,ca6c1ea3,672ec0db,1260dc86) Z8(272afe61,f2e1a444,44b59fdb,f63c0079,ead13e0a,2ee3bdea,b266dc47,c0e71ee5) },{ Z8(25028178,12037413,9ccb1c5b,63f490eb,5e9dd556,07573da0,c5837f50,1e1938dc) Z8(16dc603b,f98ed4cb,6d1ae251,093817ad,c6f57226,255944c2,561c7fb4,c1a86698) },{ Z8(03209717,f54802d2,aecbd04d,590e7f5b,fc2d0809,2c7df221,b2d2bb18,7a70191f) Z8(7c006bc0,91414899,ce7fed4a,a6ed6ae3,7ed294cc,5906c6b5,708dd7a9,c26a6ff3) },{ Z8(ea842a56,c052e96e,5fd77ccd,e87b8c0a,40ad1bc5,8c9037cf,a54d79b3,c870f8ad) Z8(ae299105,ef42b65a,3b6732a5,973c231f,52ad1394,ee10dd0a,0b262a0a,c32d3bb9) },{ Z8(423989dc,5d433de4,29d10404,655dfd06,bd089ac0,6bb5a8dc,b784184a,9aeaa364) Z8(e4a7f061,a56401d4,0c2ba283,c85f615a,635cf646,8e40acf6,f1bb4d17,c3f0caab) },{ Z8(a88dbe14,3925e22d,4c08737e,01c27c77,54e39070,27fccb82,50fbc815,90255f7d) Z8(0ebce480,5ba28aa2,237f4260,c3921216,4fd72211,7aea431b,b350734e,c4b51d8f) },{ Z8(9e450251,61d15c1c,dc0d05d5,ff20755a,f755fdbe,9c9bce2f,e1699c41,70ba4947) Z8(14d71b3d,6c746eae,383f2aa8,8141ffcb,91b2c2a2,0b574ecb,a2d9ba83,c57a3528) },{ Z8(437c3383,9fe16284,87de5042,dca079a4,03810d69,72c15684,c963000a,568ecb75) Z8(76b0c25c,3b076185,85527ef9,89bf1067,298885f7,26da076c,d8007ee1,c640123b) },{ Z8(151d2ddf,0a8e114c,cc3c2a74,b13cb635,d3ccef25,7ae5552d,8f55ce41,1321420e) Z8(6c72fdcc,2dfb9c08,0455c310,05155289,6baaabd4,0d9d1247,2fe872a7,c706b58f) },{ Z8(d5a7b8e8,3bbd8b4b,2214cd3a,43680dbf,557b21fb,3a339f99,17becf72,1b970557) Z8(d972e9d4,9838fb2a,67d26a4c,dc7cadf3,2fec566b,87fa9e46,4df57b59,c7ce1fe9) },{ Z8(f5435eee,fde1152c,e5596792,319a3ade,e329f528,f3fc39d7,792c15e3,5e12a3b0) Z8(6582ecf2,bc54ce32,67c1b712,c6c05fbf,bb81f492,599f6200,9c925538,c8965211) },{ Z8(e913bbd9,f54fe18c,cb7e4ad4,a807353e,4d5452b6,f2f6fe4b,993fe5a7,f9fefdef) Z8(e44ba29f,b393e307,eab2bd1f,8c19dc51,f9e4fa85,9bfe7ce9,4df7fdb9,c95f4cd0) },{ Z8(5667fb6c,6d21a0d6,c54c352c,c5260037,547abbfe,232e0da3,32576260,fb3baf37) Z8(92db93c5,6e9b22ab,bd9f7b87,6f0f2e74,65e90818,6aa2343e,5cf5e5d3,ca2910ee) },{ Z8(c57bef96,54de87bb,2052188b,7a330b85,3bc84734,9ab35c73,6d59fed7,dca7c99f) Z8(606a12ca,a8bf2b0a,b22a658b,ced25507,6754c87e,13b3e6e3,8dbaecdc,caf39f35) },{ Z8(5c7c1499,f2175128,b346a805,f9062eea,2fee8a52,df560f89,9993625f,2bb5dc26) Z8(d3a18680,a6301f3d,aed07ede,a504e461,567f34e6,c7ac2852,6e9f24c9,cbbef870) },{ Z8(5966214d,8a064fcd,f110f4ea,9fad9313,9b3b39b1,9323c576,2124bce1,46bc0986) Z8(a95d0bfe,e6ff9d1a,a996a9b9,54110fd9,74501497,8c7b829a,58ee609b,cc8b1d6a) },{ Z8(07a18560,c3ef438c,37565596,1c58ae4d,8fd3518e,a80aec8e,f238fa41,285141af) Z8(2ef8594b,cf0e9eb2,814e8f01,10974eb3,9248af3d,02a5b3d6,71b38db6,cd580eef) },{ Z8(2a8c2876,45019444,2adbebf2,53ba4954,ff8cd094,48f8284f,c5b98d99,2d30379f) Z8(1894f13c,4d189b4b,acc0a03b,ad33b8eb,4911dd65,55bd1e4f,aa84d8ff,ce25cdcc) },{ Z8(5bc36a9f,a874ce15,3a2c3bfd,02df602a,3d883ed1,b2e00161,7fa54fb2,563dc448) Z8(fef27101,0d5e303f,906a6f06,40c5d596,683cc396,7d6b5edd,c250a086,cef45acf) },{ Z8(711bea89,8404537b,1915acda,85fa2772,eb0f9700,76b4e01d,b19cc4de,3114031b) Z8(a1a512b4,0ffc163e,78c9882c,ee329dc2,0cc0f4e8,c0bf5eb9,462b3282,cfc3b6c7) },{ Z8(b0e2dcec,331084dd,1a094645,4eda5811,bad48876,bd2934dc,3ee5134f,6994dd65) Z8(a40efc98,06f83937,8809cb09,4b966d51,f7f1dbb5,3ad18943,921d5a79,d093e282) },{ Z8(622ab504,8708889e,9fe8f468,f393e2b2,2bf84aac,06f7b439,fdd4fcb3,0e443d49) Z8(3e8ea209,f911e058,8ba8f1c1,313b9041,baa4f7c3,edf4e0e1,d1f3bd56,d164ded1) },{ Z8(8e469c5f,b7b55c63,f4034825,b093d0f9,33c1b323,9625d23f,c09b8904,75d96488) Z8(a29020e5,42809947,9e14fbe2,b479f315,33c49361,c1a04dbc,020f054e,d236ac86) },{ Z8(15b12f49,ae19ba80,7b30f91d,a4f6acc6,cb8acc8b,9f376dfb,d4891710,177ab93c) Z8(31b3f966,e225fe48,0985a3ac,fb28f8b6,6f99fcd8,96ff7d5b,f034de4b,d3094c70) },{ Z8(4c856c5b,c45abd1b,3e4cc7b3,9f296296,827726a4,e7f0620e,29cfed99,570d38f2) Z8(586d2d29,a2d24860,9b15bb7e,4ab78332,330ffbb1,70aed201,3c61c3c7,d3dcbf65) },{ Z8(a14f9d6a,40af76b3,515a0721,3ff55e30,759d6670,d619ffb6,67792471,afecebe6) Z8(6df80c69,b7f73291,7632f559,fc19a230,a5750dbe,7b8b0556,599ba0d9,d4b10636) },{ Z8(7072207b,d5c66a4d,3f2d55f5,e8d9a37e,e43bfe85,196dc33e,fcb13687,f08ab0bc) Z8(7adacc42,5d4fc5e1,9fa9ac90,127b6b1e,d1ee3708,98b41492,8ec5434d,d58621b8) },{ Z8(a0b8389b,e3207f39,c24cb421,281ff827,7ac3d886,572605d0,4546c334,7b11f3dc) Z8(08669b56,87ffa2a7,87d1bd8b,2cd600ba,23f3b4e3,dbec9f0a,f772a298,d65c12c0) },{ Z8(445257e5,76d9efd9,dffaef61,d8f2f8b5,8fc0be5d,ced4f11c,6c5f3e88,56c3922a) Z8(8dd82973,59b92b63,f65578d4,ca749d1e,34383c6f,455be61b,84bdfb7f,d732da25) },{ Z8(835536d5,7fd2073b,17e535c4,4ef89b06,d68462e7,c2fb173e,65dff318,a2e069e3) Z8(bf6a39ef,c330c68d,fc9aab78,b9fbe8a3,4ced89db,d269ea89,fe1dc13f,d80a78bc) },{ Z8(c8116b07,39ca0c02,f7c5b7af,67d64641,52b0ff0f,ba977b87,3e7a148a,0c762a19) Z8(a928b9d5,8a36598b,b3f54253,1296e7a0,5c4b6c12,d6f38c3a,023b651c,d8e2ef5f) },{ Z8(56f34986,2fd5634e,8cfd88fb,1a084931,047b3ef1,887ca7cc,13914ed8,39b591b4) Z8(edf5bf0a,e2a71844,e704fea6,f615c6cd,1541ab5f,6670eb83,07caf517,d9bc3ee4) },{ Z8(fe0506a0,b3067371,cf018213,72f6bb3d,6262875e,a2831ae7,34757798,89f5fab6) Z8(a1e4145a,282b6931,17422c96,9e98652b,2c633a72,6bdb6d0d,5e6392b5,da966825) },{ Z8(bfcb8b97,eb2bf6f3,6a46367e,ad7a57f4,2134ae0d,f4ebbd12,8ac88ec8,ea7034b9) Z8(361b8b87,06ec1807,2a4d9a0b,6a186b0f,26322c0d,e72b8224,2f58c2aa,db716bfd) },{ Z8(ed51cca0,530b7d9c,2572b460,9a5dd026,fbe79755,592d97f4,7e666ebe,bce614e8) Z8(0c1e853a,d9488fb3,059b1481,bea17eeb,dec15a0d,a0298edf,7e94963f,dc4d4b46) },{ Z8(8e3f8906,e4640745,fd385368,2d8ea59f,7e9bdc35,f1dbab2d,9ef3d999,f88abaa1) Z8(c4808eee,d320c45a,381a9084,aa3a07c9,1ae0267b,7809cf1c,2b72af4b,dd2a06dd) },{ Z8(a6680edb,d1d16fc1,d75e8251,3d141627,69e6208d,77c35997,3cf79993,f2559850) Z8(1c201ba4,06ac6190,c4ee08d7,5ea8023c,aa5379a5,5de1cc2e,f19c1fa4,de079f9d) },{ Z8(75a0f478,68892404,1bc1112c,7818cd8e,cd8924ee,bfdc1acf,3f7c0f4c,392264f1) Z8(29c1d42c,f5a6e5bb,090d1f26,2067d94b,ac3689ee,c577aa70,69e424d9,dee61666) },{ Z8(b71e5c8c,9110d3ee,a97299c0,a22bb82c,c3f668c9,cde4401e,5cd7debc,ca0b27a4) Z8(b7cabf62,9e19db65,33aa2029,531313a2,29ea9705,5c392a65,0b25c11a,dfc56c15) },{ Z8(ba3c0b7b,c3ada609,5e23b131,8a058f3a,e3d34978,e671ef70,b8baf4c3,028a03d9) Z8(e4b48c89,92a2a7af,f3f4f547,ba617fe1,211002f5,955289dd,2b223221,e0a5a189) },{ Z8(dde01da1,004700f5,c8cc79fb,729892df,88c5c57d,5c237235,08d06681,18ac2663) Z8(0b862160,d3753405,2fa6c011,278ae0a7,9ce12dfa,83e55b19,ff60470b,e186b7a2) },{ Z8(617e0c5c,a2932f56,0e918760,6df7d9c0,65bb64e3,ae2bb304,3b1be63a,e7182eb4) Z8(d49dced0,1ccf1070,591cbf2a,ddbf01b5,a7115f8c,5945c89f,9e0c95ee,e268af43) },{ Z8(00a6dd83,e2fbbaef,c91ddb68,94372e22,522ab689,066dbfdb,dd326c06,7ea73811) Z8(f3b36886,33c03b67,382c3c69,fd90856c,134e32db,bcea731e,feda9219,e34b894c) },{ Z8(4b7067f0,e72f5e86,2c5f93ca,c69a0c3c,6b455326,dc6e8131,5f6c1d72,4e2bd082) Z8(ded6f346,6e7007ca,3d97c538,8fafb8d8,40027983,14610330,fbe683dd,e42f46a1) },{ Z8(23ebb2cb,6a0c4c6d,5e0ee797,5cb61333,d55639ac,d91f066b,879dffca,84aab7d2) Z8(09ed5c25,30c7327a,7746098d,d1ceeadd,da21eba3,b3208b98,529862b6,e513e826) },{ Z8(0bb5eb72,38e0aff6,47d6f8ef,8a0b23f8,9baf3bd7,2e6c4c75,58d9c85c,5c88230d) Z8(bff85dd1,7f7f2762,792b8628,f82a1033,96307c24,cc7bd34b,a48792ce,e5f96ebe) },{ Z8(9a542785,bfbe8dec,114166c1,ff42e769,4b368972,2beee4db,8c2ec9a3,35eae14a) Z8(2791c9b2,252c5298,f75d74e1,29134679,b400bd2a,e54173ad,785f86a1,e6dfdb50) },{ Z8(db658566,aa327d20,00a4d724,d588e59a,29e4861d,9bfd1668,512e501a,069b2197) Z8(cd31d2dd,7f2f51cd,6f678cca,583cd3bb,eccc4bb2,66c74a26,3ac545bf,e7c72ec2) },{ Z8(a190daf4,67d57aa6,6310798b,e2ca630c,2ae050b8,47ce4920,f9c612e8,4830d47d) Z8(350d0125,e8d606e1,38ba9955,ca63d36b,c2057bdc,da32f09e,3f3dd981,e8af69fb) },{ Z8(44ef9bfb,aa8a5cb4,c716215a,0f05d516,55c4c08c,e574ecd1,f62179a6,ed3c15f7) Z8(b2ea1871,23ddfc67,e54bd2eb,ca67acd8,4e2bd4f7,38caabe9,c115a0a7,e9988de3) },{ Z8(94a550a9,81186b21,73c4fd9b,fb717032,47f11980,4a01d815,94fa9b64,d558324d) Z8(1efa0239,2110bcae,5e35a24c,99ccbbf1,8696a5eb,a4fa676c,e4488ab0,ea829b64) },{ Z8(eb269c97,a19fd787,94f01cd4,545bcbf3,68d55890,df4c30f8,2c57784f,d94633d6) Z8(15239b43,5af32341,427b591d,4b0053d1,89153eb8,c77fd14b,b66b3bf1,eb6d9368) },{ Z8(dfe791e5,3d83d656,8b2d5eab,54e27e3a,6aaaf7b5,4b013a86,9838a4c1,526665e9) Z8(8cf2cacd,f994bfb7,62fb38ab,200c0692,a9c876d7,f4e061f0,2f951b38,ec5976da) },{ Z8(efdfd5b7,bea7aa27,d8c27f3e,ff9487a9,aeab4d1f,53b5d9b3,8d82d4b0,1e0e261a) Z8(385b54b9,7e395189,a20fd7f7,113f105c,47a42e7f,28e4f590,334b49fa,ed4646a5) },{ Z8(8a333813,1230ba36,70f1847f,2391a770,ae9af36f,fe997902,82b91346,1e07350a) Z8(aa17224a,9e8da19f,e9a45daa,d96fdcd1,e7d22466,d05987ce,916c87e7,ee3403b6) },{ Z8(62c86a25,66a2f427,2f60a29b,e80b2fdf,272e61fc,d8363b33,cfe1effc,51acdd2d) Z8(2c2a932d,a14067fc,050387f0,ca170f74,b6d52de2,44bd8397,071e02e5,ef22aefc) },{ Z8(602a9113,7a19eb5c,cb948e42,da909450,80c29fa2,8d28fb42,b8ba990e,56eb6cd1) Z8(2022a7e4,654f064b,85d0692e,64bdddb7,474db8f4,c9eaded3,3fb9143f,f0124964) },{ Z8(dfa0b15e,5453c30e,5fb79ce9,d394ba5a,88a8cf05,c67f83c4,42e76677,d78ae111) Z8(8c4f102e,65fcf44b,466bbe3a,c48418b3,12f35e84,cb00cf6b,d5b9ec1b,f102d3de) },{ Z8(fc5da659,e2c3f169,788963ee,861838cc,66d38d7b,549c574d,7c677430,2df90375) Z8(a0eaf3e7,37720269,7a93e758,944e1508,8c3dbdbc,02133a23,53af2c05,f1f44f5c) },{ Z8(2d5651d6,60fd715f,5cb2cb47,474f34ae,4ba4ff34,dba6d630,569c069f,d3957af6) Z8(517eb975,60edfbfd,182a7ae3,412646d9,dd47dc64,2542fa88,352a7191,f2e6bcce) },{ Z8(2e48c039,7f2369d2,af5b0a59,2982d668,5ba9f2b5,f31a1ab1,c3804243,47303c7d) Z8(ff996f4f,a28a2e1a,e4a41c5c,e3883793,d554bf61,a3f5bc94,e7b1d205,f3da1d26) },{ Z8(43c830a9,a6f5e7bb,b5816fcd,621f9b8f,b3f452ba,c0a32cba,f8169db9,5e768a9e) Z8(42a3cc44,47c4dcd9,4adde0a0,0a71d023,af6dcc17,efe744e9,cbb247f1,f4ce7159) },{ Z8(e5576823,543c4d65,abb50a5c,58f1b00b,5add5a29,7a7930dc,2a2e8894,01086ac1) Z8(055677e5,26f9b9a9,391809ca,2c4aa001,822689a6,bfc2a480,357313b0,f5c3ba5b) },{ Z8(d9d78745,2834630b,29c68f56,24644130,1c59be74,cb1a9027,0ab6e51c,9956a0e3) Z8(e0372057,d8960c5c,36404c21,5c03bf58,fed26645,abd8e26f,6e0a0fc3,f6b9f920) },{ Z8(99cbe8af,7f6fff2c,df34ce76,34b7685c,5e881ac5,c64bc3a1,9d4f1392,49155312) Z8(20ee71e3,66e5e571,6eb5ce24,40fbff04,cf6bfb78,796514df,b450f9fd,f7b12e9f) },{ Z8(861e6582,cd574dd5,14cd6868,6de97581,5b1f5d5c,265ed135,1535c340,01badaad) Z8(a2b0b4fc,3a7353f2,0c46c5f5,18755d2e,e0d3c9d5,5d9ca530,3ddbb270,f8a95bd0) },{ Z8(fa7189c6,3e60f494,5744dd78,b9d57c90,2a825301,14879d63,c399f431,ea42f6f8) Z8(214345a5,301cae1e,ebb86660,4b4ce3b2,1241192b,778e87aa,37ef7116,f9a281aa) },{ Z8(57c184cb,fd04a089,b207417a,8702866c,814b82b9,a510ed0f,3183b9ec,e48fe6cc) Z8(66066779,a0249dd4,3841bbd3,48f4753e,3b84c167,b68e7a57,c87af32b,fa9ca126) },{ Z8(16046cbc,50469526,81ef72aa,ff2e5326,e9295725,0204a6a1,5e43bd18,de07a97b) Z8(1985f4ba,94bc8820,fc38d27b,4bbd74ca,a2011b23,5a9adff8,0f0fa131,fb97bb40) },{ Z8(77c1c18b,795349da,8ec50e53,3e6d7856,f2258d3b,06fe377a,fda373ea,6d802008) Z8(59bb9bcd,3e7a7c1e,34a0f83b,60a464ae,5dd07b84,34d57a94,25dbae94,fc93d0f1) },{ Z8(031ca474,5026dbeb,7ce0bd44,f1f05b66,8c7b4b71,bca71107,488da9fd,a4ee473e) Z8(4c035694,e706cad6,eb3df6e9,71da10dd,a0e8a6a4,c7ca1e1b,22a533ef,fd90e336) },{ Z8(8e8e7f80,6a93691c,9db6f5a0,f3fb6332,c0c7dee3,1cd658c8,e1e5ce66,b6cd35dd) Z8(4749b4fd,d2a0a1dd,ad8263b1,12708a7a,32cb9121,61db6846,17c644e9,fe8ef30c) },{ Z8(56c08660,8943b13c,712a870c,b5d43da7,f9593285,b23ada82,7d7c915c,9ecde802) Z8(408864d5,d5780f49,ebee8587,e45235ee,ce1767a0,47c599e3,152a029f,ff8e0171) }}; const mp_limb_t arb_exp_tab21[ARB_EXP_TAB21_NUM][ARB_EXP_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,80000000) },{ Z8(4472c0f8,ace594d6,d38928a3,84790964,d113c005,f40c26ae,e6ddfd26,266822bf) Z8(ec3f47eb,2a8046fd,5fa366ab,686490a3,2d01a1d7,ef5202db,6190ef2b,bf300bde) Z8(29265764,53b7e301,8e705924,17a70134,8bde9ebb,6d71a7f3,294c4962,223416ec) Z8(f1e37dc1,7e973faa,ea015a21,cf66072e,bc0b2f32,0acf95a1,1f0d8b39,a713c29a) Z8(0a60ad4e,6e75a6b8,1eaafd6d,4340c7a1,34ad65b0,be61ef54,1ba5d160,e86c0152) Z8(947de038,971cdb56,6d6e060d,dd8f81d9,ffe742c3,41b4b7e6,342b3c29,76773d80) Z8(128d01f7,a26bd8b4,8c9cac7c,41caf690,ddab72e7,0236b793,c45295af,03bf738a) Z8(831a9c0d,05e1fe7f,15aa0d83,1877fa3d,5ae8db63,53c56952,49fc922e,0696cab8) Z8(583bba53,0c9efe9f,dc50cc91,046244a4,fde437d4,82fad707,f07f57b8,221fa97b) Z8(d4111811,fa7701dd,e292844e,d9c759f4,65bbeddb,eb0302f6,71f59074,6a05f80c) Z8(78bcb929,f58f419f,fbe25010,04e7ccfc,3ea91626,0cf5286c,d0bafad2,db353db4) Z8(4e0732af,e5b2867a,e76e3108,b248a16f,96528658,e05d25b6,274beb73,e7de0309) Z8(5e6ed9c6,a69d6d23,3a96cd53,d03c7a63,c5058bf2,22a3bfb7,718d90be,6ab2a3f8) Z8(ff164d22,d354c736,c36a9c62,d25988ae,2688ed67,79fa4a09,c2443036,2c6f96d6) Z8(f4bf2315,51b4eee8,a769bdd8,22e6a4f4,9e083efa,5d23675f,50864a14,e957d4f1) Z8(035d4369,afe73add,9080cf85,3ae83f20,8d50af3d,1da61115,1330bbcb,491de178) Z8(fa5e04c3,15a1b025,58c8cf5e,600ffa90,36da5eed,ab7e698e,f9e9a1cc,5c7720f2) Z8(fb0c3076,89fef98b,92234035,55280bc2,d4064bd3,05e841d5,893f64c7,84102b00) },{ Z8(663190da,ec073363,c3078b85,be25dd09,468d4ae3,14a8e07f,b304a9eb,de679fb7) Z8(4df4ae3e,119af2b1,87144778,dcf515b8,582b6aa2,517a2265,1176c096,7065504e) Z8(3d5fb6eb,bfa73cc7,a6b2ecc1,88a77afa,36280d05,a313360e,829f0ad5,c04233bf) Z8(cec1eca7,a097712b,226d9f48,d8c1857e,2714fb65,872e1b7f,df6201dc,bd114bfd) Z8(d64c72f5,f022f720,17efdab6,817cc779,1d2a0fc6,da54a3ed,db3f4e4b,bcab01a1) Z8(80620f05,bb2a4a0f,fa590326,f99d2179,1c8e0f0d,6fecaa60,4eb31827,4faa1f6d) Z8(ba890381,01a5e678,6c78c1aa,c287c738,57170015,61df12d6,6dfc9df4,5e47c53b) Z8(b43fbde3,4f3cbb04,ac900d46,7078a04b,b394a032,7e475caf,345e7a8c,b303df64) Z8(30db834b,1223c104,b9b489b9,2d25413d,402617a3,f0b6eb7c,e376fbf1,aaf5acd4) Z8(fe2babfa,ea8dca4d,a2c45b39,de03b6b2,316aec27,62d8eed9,15c4fd2b,4a4d27bb) Z8(41185619,45dc863a,f4633175,04cbbeed,e6884f97,d255e81a,5bc64cfd,58a2b00a) Z8(d755be8b,7112ba07,087b8447,3c58d622,cc5d00d6,910512f7,1540051d,f742087a) Z8(ed61440f,7d090cbb,75f6498b,ff9fd1b7,2ce07430,12418e67,a5381697,a76d34ba) Z8(9aa28205,4a072607,0a4ffad4,33a2b1ac,7aebec0b,36401fad,d2804c04,da9d9f61) Z8(8f5f8ae2,868e17be,d23d522e,de0fd4c0,b4bfe3ab,6979ba38,733f0a61,bf9407bf) Z8(5603de1a,f907a318,1273996a,02aaf44f,c38ccd92,f8300a73,c363e9a8,7a3bad21) Z8(c3ec7771,94d3ccf6,c5428436,44a1b430,410caf75,56f32f75,25d7aa18,d2f4ee1c) Z8(ef3fcf23,624bec06,c3e1237c,dd14aaba,12e4d4a8,d8d00cf1,e9a76bea,88415abb) },{ Z8(68c67282,f96bc683,edda9c98,6544adbe,be69e504,200459bd,238b11ad,7a4edca8) Z8(da99f3e2,c8d1b034,4b4e8cbb,520693eb,b1a98c20,e5fae2f9,6e67dcfb,9cb77549) Z8(a26114da,85780704,0a481621,35ebda27,27febffe,f7572d9d,cedcfad0,318f5174) Z8(ce074442,9d2f705a,64584661,cda21342,16e918af,d5a3cc14,104b15c6,3cf2ea83) Z8(c852b2c8,78699c02,ad8a5369,a3d5fa3c,09afd1a5,e706fda5,fbbbf834,648ff2d1) Z8(71b88079,a8f8eaf6,1a4004d0,50d68062,8c5e3814,ead64902,3ba8f8e1,bda1a3fc) Z8(10caf856,01919667,b6365de4,3c2c6888,121f461e,c6808726,d31b9259,e3ce6dbf) Z8(fc1e6b7b,e1d97687,f009cc7f,2e0e5211,0f9c046e,d9667624,f759ceed,78831f71) Z8(639b614d,7bfd43c4,9eec0516,f7d64f58,fea38871,f36b6110,62b0772c,f6d6a6ca) Z8(522c01b8,9fe913d5,f63bae53,f01d3bc2,bd109add,42e23021,711a64e1,c31adf80) Z8(234fc039,f2ba9071,d8549781,03047762,d3c77555,50951ec3,17eb37f9,fa20784a) Z8(f54f05a3,7524922b,09291e7f,3666f742,478f27e9,c6edfb2b,4d556278,6cefcad4) Z8(eded82a3,c9af04e8,50ef9f0b,06853a72,c4ad2a5e,c6342bfe,eff2d99a,861fb104) Z8(5f7891b5,ac9105f8,83a1fbd0,a839466d,35d23e04,26f74405,0725886c,e33b7a65) Z8(c7d4d902,cb987c53,424f268d,27bf1365,e7a26f92,ba5e9359,c130deea,02f4ac98) Z8(ab82e878,98e8a0e2,6ea0ac35,a8b532bc,3fe97008,fea35eca,da991560,f4979020) Z8(754c3938,74e5fa46,a3e485cd,73e7aae1,ca779092,27bd225f,2e1dfd17,f7da756c) Z8(f503d876,04261d08,ea6c3274,f3da3da8,40755e14,9e8c66dd,a7066b44,8c949b83) },{ Z8(ad250250,b2b19bcc,d9a7ab01,027dc694,2b2b4565,1c90126a,99696df2,20b11da7) Z8(45574cc3,823ba074,d51b00e3,35bd43c3,5650494f,804ced10,84e29133,a5edb1b7) Z8(cd59d5b7,3be8972a,cab67074,f21c925e,2ac75f56,970b15eb,37d9d833,3a902a26) Z8(2265a024,1a548db7,48b7dc78,8594921f,cfd11b44,5ad2f3c1,cfb2c1a5,757a20f3) Z8(76626895,c732f9ee,e0954098,25694b1d,bc1ab3ad,702f50e0,c7533e91,3a6e7181) Z8(a1d596f0,c7378638,3e20bb16,22f1cc82,134e1641,df9a324d,1538e1b8,1512023c) Z8(31df0feb,4ceee8d2,42b5f394,1d1cca2d,16fd9fcf,24590bcd,e50cdc3a,647c72c6) Z8(a322e9ab,67ee8abe,9851c48b,ea26f1a8,25f95443,cbf050fb,64280c6d,00cef364) Z8(93aee173,a743f1a5,8fd71bfd,9bfaf183,a6904146,90751199,26f3eca7,27302dff) Z8(a022d18e,0baa833a,ea46f860,fb4d570f,2fb14f7a,f140557b,f5674789,dce13872) Z8(3dcaadb1,e602af16,822b265a,85906b98,45e53547,4d294592,6b3c804a,42bb1493) Z8(dda641dd,221553ab,b97c6bdc,346c48fa,6ec00e6d,2a29949d,0c4cf137,a37c1fa5) Z8(578454aa,aa502868,74e6da75,a404b34d,a0e328d4,20618ccf,4dfa5b0e,a2242795) Z8(cd72b010,673e8eab,08bc7029,c032cff9,bf81b9e1,6b6de0d0,683d80c4,64fdbeee) Z8(fca37ef6,6b910290,f941c428,e725e5cf,492ae8ec,9bb7089d,7f8d4e68,a87b83f2) Z8(43d3e4f4,e0fca75c,53588b0c,ea6f9d21,f88e5662,3d723db7,15b27cdd,73ae406c) Z8(12b5ae61,0a584fe3,ef3e2399,178072e9,2ce1e182,4ef19144,3a8af5bb,bc3b803a) Z8(8118966c,bbb5b0f2,54ab82be,3c5f8642,7035c6a1,76b441c2,b7ae67ce,910b022d) },{ Z8(5cabe6fa,d179ab66,515b5f8f,572b9a31,90ef1f02,ec806ab5,db964747,ede41227) Z8(231f9219,ed090e66,595b04a8,29b11881,ca88eacc,f3a1f938,a6060f5e,430a6294) Z8(00bf388a,6f09b6e9,b5c1aa40,1448fb78,7b0af18a,80ae580a,2e540e4f,211a5104) Z8(9ec0791d,428bf47d,ffd3ce2b,84597174,af222380,3df1d306,0c3e20f4,372fd639) Z8(f1ae630d,80fa1315,579ebebb,55709b21,f5bb2c16,97e38a49,834694b1,377d32d6) Z8(31f46924,d0fc002e,cc51fc44,24a390eb,413ca80b,9f14c78b,14ae98cf,f37f7d81) Z8(818d0a3c,623d6c32,577b7671,cc441196,65bba68b,eedded17,a4638368,e63b818b) Z8(84068640,57acb3b0,abca19ae,444c11e9,4ffd32bd,9634df59,66f1e083,99a37a02) Z8(3ca2812a,ef36dbbd,604f5295,069b804e,66475ad2,4720f755,d7672c96,488247b8) Z8(f35192b7,4d13b8b6,3fc161f1,efd82a73,0d1dc805,5cb9d24f,7cba6dc1,80239192) Z8(258d3964,87da5dde,4f20af74,b795651b,3941d2cf,dfe12607,a334494d,97930939) Z8(05b58dda,ae01caee,fcfbca51,3eeedd34,065185d5,2769cb9e,ce04ef35,c90f0711) Z8(e3fbc9c1,b5522ed3,02ac1fd3,114642f1,ec8da0ad,03790ccc,e29b6b69,12fd74fb) Z8(3bc19829,b70e2461,44883b8b,9e0adb76,47bb9f9b,003378e4,cd435926,85b1f94b) Z8(827f8d06,46af0dde,eeac3f95,72937d7d,9a81fd57,075bdb50,1ce7bbcc,486cab49) Z8(83caf092,8bd21cb7,99ebc909,b4a66dbb,3082ca7c,bea710ca,dc44f8b4,fde78c8a) Z8(06557e3f,751a929f,8482b781,38f8d82d,5dbb18d1,fae289c7,0dba2b34,5ed19617) Z8(9bcb9778,d23a6bec,30f5450e,32a17622,cebec9a5,9bb3e062,b963ca80,95a5ac59) },{ Z8(a7747307,b263d7bf,f3bbc444,7d4dafad,6448214e,95325cae,376ee95c,6781c13a) Z8(2302b794,f39751a7,64b4f8e2,b9059243,2b32f391,b23943e0,efa7d4ef,6c965f30) Z8(a24f7390,3d06da7b,3c4811cd,e62626ce,122907ce,ae9ad95a,a7fbfb98,a87d8c47) Z8(989b4afb,988f60bf,b9c4c827,625b4b00,b1a977c1,4bda3b4a,fea563e7,ccece089) Z8(dee28cbf,2c155fcb,4aeca5ba,30d9a97f,9658e5e0,8624e00b,0ced991c,e0c2f0e9) Z8(a406a085,d35b1d45,ece36f6c,ff68d8bc,aa5192e5,b5896d80,5b332c6b,f7008f70) Z8(b250ccc4,a5202613,8aeddc9e,970cc1c1,4d9e01f2,2504b4f1,474f2c08,90b46ca2) Z8(049941eb,7bc557bf,a5272ac6,f965d7a0,25876a8d,c91e267f,faffefc2,69f0f737) Z8(18021930,54737195,98a94f67,9e73cff9,ccd69b30,06dbb997,b9f58e33,2b4fb23a) Z8(ad6f797d,4d800fe6,74b76750,02e31c52,162a7cac,9fb0b597,d04fc79c,ccf697c4) Z8(7c1b9f7d,010c1c56,d5962de7,49f3473f,4a30db25,db6c82a3,3b5d3f80,484327fd) Z8(0ad2ea9f,10f7b15a,26748eff,59b7d126,881a9fb2,c3b05b02,8b47b139,12c9bd77) Z8(461a3119,00e643ba,e5fd4f20,90533b85,579c7b44,8da537da,40bc7123,d787fbe8) Z8(7602b554,b3a42a9e,0e72c101,2d78f585,d4714450,a1b0faf5,7faa00d5,636f1626) Z8(50ed39d0,8a041948,5b21cced,4089dc6f,3ac6acae,c3e820f5,d1d7bc89,51f95440) Z8(7c3c9db1,54cdfb44,d6549541,305c4433,53c202cc,cbe54b73,d6e5985d,0a6fe368) Z8(87dd346f,ca85cf4b,24f1a452,34a88b53,1f7f1004,106e57b6,b021cf84,c73b9006) Z8(f1746808,230db4ad,8982478c,84735853,e33249a2,7062465b,5ac1a96a,9a65c0b8) },{ Z8(6e0137c6,7e9ec2dd,40876348,aff4a4e6,d4d74ef3,a8e84f52,a24e5464,95bc503d) Z8(9c5820e6,533ddb67,b2072ec7,96375acc,6ac8febc,973f4a46,60d20630,037e5dae) Z8(ecd84645,da68605e,6b7d54c4,4add14c4,31bd6547,48554320,10453b5f,648fb89d) Z8(c623bb02,cf74ea28,d5c3eeb6,e4021b88,43e4f9df,7d838e47,739da2fd,b1a3ef19) Z8(279e226c,62fce404,3d2bbc23,cd633e8d,31e97787,2558a943,a8b8baac,4bfa3798) Z8(6fc0d47d,d10f1501,1b14636f,db76d741,61e13ae5,ee29deab,eb765bc2,2b6d4968) Z8(76982060,6509ab31,5fd2cff1,1eb6b4f9,bd798b5a,c6ca6b20,7490bd6f,ede574a3) Z8(17df092d,2d0a0263,ea489c01,113d9c34,0f1586db,66eac017,c7400e7f,1f0a0e08) Z8(4d71957c,491cbc27,8717de76,15b9f5d9,13483331,1bf88ca0,554a2ec8,11fc9915) Z8(fb46903d,ef5ab40b,5a1d36f3,b5793cfd,96b2b718,0f732eaa,21bb88b5,f3b66917) Z8(d9c9f788,413d743e,92c24a92,f988382e,af1b1ae7,172f46d7,0eae6361,7e6dfe3a) Z8(63ae03d6,1386760f,45415014,7b694f56,5ba5be11,ea5ff8e4,e723bb41,d6296f14) Z8(f60eb550,ea165b7b,c34de712,85639ab1,1ac4b161,d155eba0,ffd05f23,5043cf23) Z8(bf2a9513,dafcef28,5928410c,7bc38168,1d25c9c2,691e581f,576e5e1e,338cf4b7) Z8(3e30966f,167a3620,a907cd8a,beb23729,26cccbef,53dfb869,cca84510,19f36644) Z8(c9d86da4,48649402,b45bcb24,606f4232,dc65b97a,f40934e1,a79d84aa,a4a01bab) Z8(c19b29c7,6cfcc965,dd49750a,b76abdf7,0e8b6bdf,24273cf6,9a601d51,3db9cdea) Z8(bcef8461,23cf2474,10a259ca,abbb03b0,6028ab6b,bbdee020,08ee5d51,9f4c6f55) },{ Z8(838671aa,1f05d0e3,ad4ea3dc,9bf8077b,58989b32,52cfcaae,8af24eb8,0c878390) Z8(44035afc,6c1408ab,3726813a,e76cfa8e,b6a0aad4,8d53a88b,c2812d6a,0e00db83) Z8(3e698770,b7fd3be7,5dc7e479,6dc6c98c,ed34df17,455d961e,9155c658,e1c8698e) Z8(4bf286ac,24269055,695a602b,e865d36b,09e93f24,1315633b,1c288d2d,f6bb157c) Z8(3a2957c0,97bcadbd,6cadd3ce,ad2b4cbe,16fb89aa,d4c7d3f1,6e72c1c7,af8633ba) Z8(1a197df4,a1b06662,fdf8d498,452c01ed,d945d3d1,28495196,864fef00,fbc9289c) Z8(fe37995e,e007d3f6,945b7a36,63bce255,82c32eba,4de7264f,23dd2638,874d75b4) Z8(6f214afc,a65f9a35,cc4ab581,253b7e11,53d42480,b15847a4,5df84b11,005143e9) Z8(920c48d8,e7b7e41e,86cb71a2,782ae3e0,4272c1c6,dacc80e2,16af710b,86d480c6) Z8(1128c53c,10218be2,da220c09,0afea2cc,8360d574,2df81fae,84e134ec,4b81452f) Z8(6f4d256e,7dd84295,8a84a02b,7ad0e2d0,844b41cc,b98f815d,11e67040,45d61734) Z8(bce26466,f226abed,3bf34f67,8e6627e4,7ff2d454,aab4c5d4,64d5eb6b,62be3d32) Z8(b8618842,68240c00,ae51c231,003094ed,476ecfb4,c45cbc80,ba9af2cc,3924ddab) Z8(f7275d84,daf4aff3,d09f2ec7,730402ac,e55c75ee,eeabab38,cb1b394a,8defcc39) Z8(f2e4e81f,7e6e4823,3ac63698,0e206f35,48d0da57,f869338a,d5210729,16dfbe98) Z8(3e52f4aa,03b77b05,314da9ff,a1944500,e6b16fb1,6d65c0df,111d967c,2179bd1f) Z8(a772363f,99ce2eb2,234be1dd,ec5ac020,1ae273a9,752a6f2f,2726e6e9,d7a1733b) Z8(ad3105f5,4c9f4678,25df1585,621c438b,d55f29a7,3de1db4d,f40c333b,a45af1e1) },{ Z8(d2b46f84,30bd288a,38681f0c,7e781609,b55f5463,1bc8ed50,c28195a0,7d0c0ade) Z8(14fe717b,36cac6ac,2225370e,2490ec4b,b724f070,81da1125,b38ffc51,d3ae1939) Z8(3934b13c,99211f3d,6d047b7e,6b720612,6339f1c5,cbd511e9,96c855d2,f8881261) Z8(99625e46,af3351b2,5022da7c,f088d8a8,eeeae21f,d3d2d461,c85882bf,2210ac39) Z8(1946bbff,f20cff9b,761440ad,e993b034,98dc8502,8415159d,5521f628,e05f9c04) Z8(7729f7ef,455a6ead,7a95138a,591788bd,f53aa567,133f7fcc,b3a2520d,a83137c5) Z8(8aa762c3,ef7e01e8,c86e5226,1d24d7fb,6024af78,8231ee0d,8453756a,e901cbab) Z8(c56b1e4b,8c6e2d3b,50dd5c8d,4b53db8d,06646510,acb7446a,395d8caf,62b4316e) Z8(5fd0b782,16ba37d9,f2db093a,0e80fa17,fb853a7d,13962c24,0e2574f3,46d755aa) Z8(c7f10c04,21b8b83e,078e2b6c,30745a95,5109b876,7b7b9206,99866ae3,98e58624) Z8(692915e8,a9b4548a,298481ab,68433778,5a1001e5,35c98119,60e90d11,fe1e05a7) Z8(b9775cda,f8470cad,03cb771d,822d8edd,35a0ac81,2cba7b5b,ab4fe314,407568b7) Z8(5f857862,02c96b1a,76048b83,cee0b207,78d57501,ae12e365,fa69fbba,2239e111) Z8(95c0816a,538754d7,5aebb1b5,cce79b35,74670b2f,fc72a059,85ac8c60,72cef602) Z8(cbce3d2d,9f711a4f,38fa3bc2,3ce6f4b5,f2445f0c,fc6cd81b,26683265,64e538d7) Z8(9d948367,0ca2a33e,b802b316,58493cc9,59eaf52d,bb322854,7e9f6ba8,8409c85d) Z8(c97ced2b,9252f7d8,54edb8e6,be3dd628,903aa117,6c601d5a,7b001fd3,478824b9) Z8(f71cf53f,37a84887,9bfa0a11,63232c3e,1b4fdb27,16cc14c9,7d67bb65,a9928c06) },{ Z8(a4964057,ec884b28,114fc8bb,f021ca10,64897b26,7672b612,76d10d02,5970f204) Z8(b2d0a91a,4bfe67b7,9d99a02c,38540e7b,0d4b2713,e3ea890d,43f8fba3,a1303002) Z8(55c617b5,b1bb0a65,89246a15,57e7104b,f54650db,c35392f8,17ec157d,97ac8991) Z8(594523df,f8f3c9cb,a2b38e1d,0357ad12,a23e773e,12ca3b81,be5cd906,532d946e) Z8(5696e684,7d8b2cd7,4acca3d2,7b0ec753,33f0e384,2630884c,f6b3a85b,ccadec62) Z8(ee31006a,370406ab,25d329cd,a1acda6f,fbd43348,de1ca3c7,c36dc313,d56bf82b) Z8(1c984c44,65a949e3,be88b2f1,31dbffe3,dd32512c,30b206c6,c0313f42,6682dd8e) Z8(33d7e0ad,021cba95,7483b413,ac623b65,f921784f,589f5702,b02b3a21,b9d312d2) Z8(3ba91944,bfc1481a,9f021d18,edaca1d6,8e624ae8,058c2dcc,91ed5f8f,319c223d) Z8(7862d041,bb10348a,6077d933,8f3832c2,8f7fefcb,5f86cdf3,cf995fb4,090e8930) Z8(1fd3b022,045de0d2,ecec83bc,b7e647e9,5f417fdf,d939f4a2,d1eb52ca,73f4acf5) Z8(a09fea67,e91a42c0,4af88551,d4a89cc1,43880051,ea92f7d6,3c249d12,511c705e) Z8(67e93ba2,76936bda,61aabaa4,e1c512b9,f7e0f1c2,99003d25,7c82e143,a1974b7c) Z8(714d64bf,86fa1d98,74b9734f,8c49507e,8a202f19,113292a2,35c9da6f,fe2981e6) Z8(dc857b8e,2fd6ecc7,e506300b,e75eaf72,a6768732,a17f76fd,2e8f8294,9eaf5e40) Z8(4283134a,29d0b8fa,8f0cd8f3,5596a8be,c3a1f0a3,9ae59493,79a94f5b,860095ab) Z8(21a2a36d,f17c3a2c,3117f371,d3f72e33,0320c24c,777680b6,0137a911,355f7545) Z8(a117c185,f10196af,06799385,4ed96178,baa201e1,89923298,22ffa9da,aef48bb0) },{ Z8(1b2ec916,638de591,6984dbb7,ca18f75e,f3beb614,11380dc9,04022e30,db611dc4) Z8(ee0174ca,43a35301,431802bf,fdca5896,1396377a,4c936e59,3438241d,3c3fe616) Z8(72c4f055,92c26e6d,1ddcb0ef,0d4d59b4,d92f851f,550045a3,58afb2c3,1e5f2365) Z8(9905fea0,a5b51815,c47dd465,9c5c3d6e,351698ff,7338bc76,438cbf93,51b50191) Z8(f1468229,b4713f2b,7044ff21,85179194,9ac70f56,4ab8b0b8,7036a809,de97cbe2) Z8(3125a1cc,48387b92,cb7e5eda,42534b6d,07866feb,7b3b8169,2e321fba,365ca9fd) Z8(1f2b25a0,f848bb53,6809e4ed,f9d3701a,316c93ad,26640e07,e65af86a,5bf309fa) Z8(813f4f09,eb5fb79b,d938e9bb,f4427c45,cf4e0e64,2bace9dd,7cd0eb3f,c9a0f457) Z8(6d7dbbf7,9c32d4a3,feb375e4,99f6ddb2,b578f4ae,0f8b0563,8a699379,ec0f798b) Z8(ccef01d6,fc67342a,c50f9be0,72f3946f,6b42e631,37f86258,67e905f1,3b93b9ff) Z8(0418a2d1,1a76ce29,aa2ff320,f5088b87,6d5728e8,7834d79f,d7bdbb32,17104888) Z8(c0ba5d18,0ed52157,65dd8582,fcaff87a,e2dc21b7,6054d04c,e864dd0b,6988c8ca) Z8(5fd98a39,f5f0ef47,12ca8387,5596afd4,df5e70df,0a5e66e0,8062c986,c701487c) Z8(f2d59cf5,3479cf66,94f274c5,9768fd5b,ff4286c5,216cad0d,52bee7bd,02ba4973) Z8(40b5b5c9,d044a2ba,4806a01b,8280d398,ad5092b4,0947ff58,d0cca23d,0cb5f9d9) Z8(b17e7875,e62d1c17,28e5b9dd,07c2076b,8aceff1e,c3370fa1,0395b732,fdf7a6b2) Z8(c179dd79,38b3f2dd,acf98ab1,0a586b38,672286d3,5a180e4e,54cdaf0f,d6388aaf) Z8(63a9bd88,d965ecd5,9de09776,5c9b5313,1bd3a598,d7cc0829,fca1967e,b4824965) },{ Z8(65ee45af,0f6acb9e,b2126e08,298dd305,455d5c75,dfac734e,41bdd19a,c9166ce2) Z8(1053c8d5,0a845e95,8b3a7199,7700c0b7,44374e56,5c5d4527,5084233b,019ed2d5) Z8(d0d21da2,eee619de,e9fb68d5,3793b9b7,cf8e806d,99d067be,e75f3e36,982ace53) Z8(06001cfa,f8605034,9dfd12a2,f15ad8b5,82964c6e,b2f9d5db,32e7798f,059a5cd2) Z8(dea7624d,ef223dff,f40c4e0d,8f51440a,7e8ca7a3,e4c17346,69e57852,2f50162a) Z8(a8beadbd,31cbda14,38edc6e3,2d999ab1,3ba2d93b,bd1bcb0e,b4e5810b,b9c6ff6f) Z8(13c74624,3ee389ea,60d8977a,a1809ed3,03b5f80e,5ef0274a,fcddc8f7,2206d2c2) Z8(84eba86c,31cc8db5,f790d0a4,59601d55,ffd5645d,609c5790,9ef16bd6,0da05b27) Z8(4b1ce83a,e45f7132,4e345055,e0adbee0,5637aabb,3a322aed,d9c143a7,a337b7bd) Z8(07cdd6df,62e309a3,b68da19a,97409397,b29e9e7b,9e1c1104,e43c490b,f8979960) Z8(43602559,8f32ec65,01444a29,45758e57,3213055b,d2d91697,a6fa5849,bc2ac3f6) Z8(c2efd543,d16c021d,0315032d,5f877688,61a1acec,697b908e,eafd5895,4a0d2abc) Z8(695aed3f,e27bcb49,11358d0b,7a52a53b,cedfda5b,15eb8c62,c7176746,9116b300) Z8(bdc42f5c,b90c0078,7a9a18f3,edf0914f,00b51778,eaef7a43,77766e97,4f94fad7) Z8(e4f4cf70,992b4536,f0ecf2ba,59bff5f6,6b4f489f,f1cb5821,5eebc284,07b1a2cd) Z8(4fef1c97,5d19b55f,f5533e47,ba40e37a,d7eb7a4c,95b7392e,57c9548a,fc5086c7) Z8(293ea004,58100d98,00085c4b,a07fd77e,a8de6b88,7c2d5e61,fdb5ea59,e61ceb40) Z8(39d43d41,dc36bb78,9a5c6dbe,bc7d210f,849202e2,a3c5b2cd,df7b5311,ba3d289e) },{ Z8(f9e0a6c3,3728272f,e449c333,4b0fe2d7,db94d5da,ab8c380c,f68113ff,c2f404a1) Z8(d833cb73,256667b2,3a602316,e2a9f674,64e70789,0daaab79,7092500a,c94bf7a0) Z8(7136fec9,20f2098e,369c8d79,98b1d039,d61babb0,cde93958,c53b2da1,c33f5cbf) Z8(6debb999,41820414,35c5b44a,bb935c15,53058854,ca2fb6c1,627868af,0eec5354) Z8(483d5512,1db1bcf4,3e8d0786,40a1574d,a4e3429b,b8ce84f6,a161dfb7,db88f99b) Z8(7098135d,74d172ac,26f5d593,c4acc4ba,debb859b,6979ec0f,78e843d4,f066dfb7) Z8(f6a8b8f1,2473703a,54426661,823d9527,f676f109,f1de5fa8,ef09f853,ff9ec293) Z8(80e44f9e,4434ef55,96c793d0,10efaf4f,818d1a94,924ade81,6a4917be,4d57040b) Z8(a0a377bb,67c2b431,84cd034e,13c78218,ecb974f1,67c264c5,54f01fae,3534a968) Z8(9eb24e12,510a365a,fda9df63,b02e9bec,78e3a6c2,b4283940,f874a1b8,58821af3) Z8(f088e8ca,94a75aeb,7552e028,0721f882,e3c7c0c2,2dac9902,b7df8e3d,304e9b3d) Z8(8e741d64,e06d9e2f,b6ca0d1a,1120c1ed,b47c4ddb,85ab2dc5,19a541cd,d3311d94) Z8(6531a155,da4d065f,50b3c08a,6776d622,f2590832,a832d4c9,2d23c870,cf3adb73) Z8(87532caa,ef740b61,fca0bff7,89adfa2e,f30fca77,bd9f8164,8e2efe3a,5d485896) Z8(e7c37807,946aaaf4,f581a76f,b08a9831,01c8b3c3,66534496,de021214,ad5263b5) Z8(73f03d69,150b7d82,ca85a628,635fd7ee,2ce538a4,3eb6bd64,8d0d244e,f5837509) Z8(19c092f5,20a81315,8711865a,92f265e5,cf26b468,a2fa5bf5,34812af1,4e2c2982) Z8(a9e20ce6,90ca9c65,e1347404,65aa4053,44a5ecea,65cddb8c,3daa2e5d,c026981a) },{ Z8(61be0eb8,e651d3f6,d679921b,ca09671c,fe34bf4b,ade102f9,e13c5f6c,cbfbccc7) Z8(8f46177e,9cfc90d3,e21843c6,daa62d1c,eafb32a9,bbc807ad,94288ee8,d9908d53) Z8(34ae79e1,939e7ac1,093610e5,70939cfa,90cc37b4,a93eab9b,73f6bff9,b07a8222) Z8(be6d0ce6,694567fc,aca45ea0,fb4bdf1c,9e1654f9,da4b9160,5ce57964,8e9bad6b) Z8(2e7bafb5,6a5310a6,bb1a379c,73d41d5f,2da421ff,c45a842e,eb55af74,ebcdba7f) Z8(0c0a8530,87cbc05f,1d281b33,84c94c3f,8eb2308c,f853b7f9,d4a9c6b6,973127b2) Z8(f6177b21,2f904eca,85d39d6a,62aa7d46,4c23e123,225ae47d,3dcdf6d5,321d4f33) Z8(c3947054,be387fc9,433857a6,246bb28b,cbc845c2,3cf14568,d543994a,aca0bc8a) Z8(aef1301f,e5d18851,dd5afc18,edb47aac,d49e7a39,af268585,f8d92693,2557a13f) Z8(3ae3f368,723296de,ebd6db7a,25fe8618,342db1fa,4b0ca909,30bac8c3,acfb44c1) Z8(d52e7c8a,d60017fe,c90f2bbd,822bf511,2f472d20,f9d734a9,56718f59,c4c6278f) Z8(90352934,63461720,f41fe3e9,bc2079c8,7e588cfa,7a58f385,5f28a6a8,18e1fc59) Z8(650adaba,f901763e,56555b1d,2f509df8,d83ba633,a45cc144,91151f45,38ba2aa3) Z8(bf436eeb,e00d876e,5ee555fb,28fe59cb,41f98955,12c792e1,7896939f,832f5c36) Z8(bf7c6ee8,973b1a0f,9080aa89,42be23ce,382a3c3b,a2605858,a5728cb0,baadefb7) Z8(2732dfaa,ac033acd,5b4d67ba,54c516a4,1cb680b7,0059efcb,a9af4f4d,6383c9a5) Z8(437c3383,9fe16284,87de5042,dca079a4,03810d69,72c15684,c963000a,568ecb75) Z8(76b0c25c,3b076185,85527ef9,89bf1067,298885f7,26da076c,d8007ee1,c640123b) },{ Z8(270a8172,63bf2b93,7e8df0ef,bf941d60,e530eb25,9541919e,e87e9b21,5798a025) Z8(a917df75,872c3c4e,e03c00ec,789ec9f0,4ad2bfe9,a1975362,42ac1b87,f7c038fd) Z8(187bbef4,24de78c9,ed72761a,76c519ec,020980ab,067a8e12,a9ece040,6049681c) Z8(4127164d,20247744,cd6d4c2e,b7d00a0d,62fc0b58,d0cfed18,b403ff6e,d4abc91a) Z8(3b4706ed,9f7a0d04,2d367a2f,48cd8034,57b774d5,3efa19db,16711959,a8209a61) Z8(5e8e73b7,2c969a6c,e805e11f,2e5dae10,ea0693a9,3af46528,dc3a09f4,9fcb138b) Z8(ec6ff269,646fe2d4,1962b3e1,330ff86a,863b8e9b,78318221,8d5ed1e5,50658e99) Z8(6dfa9624,335e9e7f,970adb15,f5d9f55f,b0e1fbee,4ec9b90e,32a93baf,68417ef5) Z8(7dad6036,da880015,59e97d79,4016f463,e4bd2aee,87f64327,e3e63e8b,07b55154) Z8(35e7a585,7e18bb10,c158d6a6,8d58fb14,4946fec7,04fd1930,b4f02bc3,b526181e) Z8(e70a7253,ffa01207,80bc7800,4e5242bf,52e459eb,46e09afe,7ec59dd7,40fd84db) Z8(12c90beb,89465382,417721d8,aadca513,5065a477,74f67256,e4cfd881,d42620ca) Z8(024837c5,38c1a7aa,1ef0b9f1,26fd0610,1fdc913b,ff25e331,7010f215,b0653a69) Z8(c5bc20c6,d0b0e7e1,6155fd64,da6336e5,23284d68,59097308,e0e76850,fd82fa91) Z8(8db617c4,51897822,1420e083,a7748dd2,79c3cd5f,ec21455e,35ba93d5,38b813ab) Z8(16438341,bc004859,f6825f8d,f49a43a3,fc55a1d9,f2ee3831,d77d3d22,70156847) Z8(5966214d,8a064fcd,f110f4ea,9fad9313,9b3b39b1,9323c576,2124bce1,46bc0986) Z8(a95d0bfe,e6ff9d1a,a996a9b9,54110fd9,74501497,8c7b829a,58ee609b,cc8b1d6a) },{ Z8(21ccd371,1811e030,3e23072c,a2d85c44,05fdd6f3,3938b2c8,858221a7,a8bd12e3) Z8(a2ff10fb,b6c3c0d0,c18212a6,c14749e8,c7e37196,6554dee8,6dc429c0,21f9e06f) Z8(ec221ede,98087e85,55e5a672,0fc4f105,ba9a6217,b6681b4c,b7c42015,a0ea443a) Z8(938ae244,ee42f239,2b73ee96,40e60b45,3f5e5b7e,1c176c51,5b6a2517,1918499a) Z8(2821152f,ae6e9aa7,c5a39b5f,06f94f80,559fdd29,d92e9663,cf4d10a2,beebc316) Z8(1c07e9b9,25e160bf,9d24900c,adda9119,b12aaabe,9600c2b7,09a66771,56d9a725) Z8(cabb5696,b5f80047,638fa0af,dae20a2a,7367f3d1,fbbbc117,1910c09e,140e74f4) Z8(a2d59952,73c0ab7a,0c63ea8a,109b93ea,bb19f494,257befeb,656c97fa,aa2619fc) Z8(0fa4756d,8a0e3254,ddaf19bb,d9bf40ff,3a2d521f,e9dc6988,1aecc34d,6f81f37d) Z8(69c4967e,9f3eeaf4,f48c6651,b664d355,44fea0c5,6a4f7dfc,724415fd,25d8c7f3) Z8(5a1c4846,3ef4a8f0,44e5fd91,004b0328,bf4f439a,3ad1ee72,b5cc193d,9aba21db) Z8(ad451031,6568e829,c0bed5ae,3a0b062f,8750590b,41550eab,c275450b,4061b2d0) Z8(6609defe,4342dc3a,2a1591b4,412553e8,a78c9e86,3c6abdb2,7ac68743,a020887f) Z8(be1f3951,93b72e2e,6506f4fc,7e62bae3,b45099fc,9bfbcb4f,49c110f8,c879f711) Z8(a8f673a1,a43fb5be,a12fdf27,3849b815,f073e973,c4ea5040,08857fec,d4ab26b0) Z8(a27e3fa6,e944e88e,99f90c2d,06da7bcc,980e9378,3e7c99a1,7ef1ed9c,fa0039d7) Z8(15b12f49,ae19ba80,7b30f91d,a4f6acc6,cb8acc8b,9f376dfb,d4891710,177ab93c) Z8(31b3f966,e225fe48,0985a3ac,fb28f8b6,6f99fcd8,96ff7d5b,f034de4b,d3094c70) },{ Z8(80a05e5f,f3544a62,55e37677,8ddc0e3a,cfb456ad,e544886f,7fdaa502,ca4395c4) Z8(34b29f89,df5f2c97,f0de0314,c564217c,c8083b73,3369964d,a7fc6697,986f1b18) Z8(1f79fca6,3344944b,4915ea85,6f9dcbf0,cdd1d752,1f9c6da5,a564f1e0,efb40b7a) Z8(22350a9e,49e5b3e5,7815ca9c,f04ee5c6,2f37a2e7,811e329b,8e71bb59,8cd7509d) Z8(35c83360,60b1732b,01e6d50a,962000de,1dfca017,23217d42,dc04173f,94003db6) Z8(f8fbe098,f669faf6,f59a087a,80deba90,f623731f,90cbebe1,b8222a3d,b6c412e1) Z8(94fb765a,6418176d,1c05122e,cdde2c83,671cf705,6f56914c,040d3aa5,22eab24c) Z8(77b36c15,b13a82a5,80dd0865,d060990b,713c4a1d,4f3f9ec1,74728e07,05ed7e11) Z8(201c8998,7b230c98,361a7053,ec3272f5,5adc02bb,469aaada,33be4ea9,f74d81a8) Z8(bd98340a,813750a4,2b18b0cb,87f83865,a7f9eee9,2ccb9278,4ed7dc45,21bfea51) Z8(6a8c9502,ae697d68,fa6bca27,3500d96a,edddeb2c,694beac7,84310df8,e4778b21) Z8(505290e6,395dea94,e07226cc,057bf97f,341d675e,48dfdba0,3b8b403f,a6c4c42c) Z8(92945bdd,3afb5b98,803f4f27,28fe724d,d3fb68db,750332e9,cf928f15,34b4b6b2) Z8(9be24a1c,e88eb1fe,c521f501,fabb5d8c,6c0d5db5,5dbc73e1,99a00edc,0bf0861f) Z8(f74f974c,c6ccf774,947e32f4,1c218554,a4c4ec0b,48cf41bb,0fdf399c,d24b5217) Z8(11a9a881,1c971000,c154e3d9,6b85eaef,7662a2f5,ec2647a7,1de839a1,ae16b6d8) Z8(56f34986,2fd5634e,8cfd88fb,1a084931,047b3ef1,887ca7cc,13914ed8,39b591b4) Z8(edf5bf0a,e2a71844,e704fea6,f615c6cd,1541ab5f,6670eb83,07caf517,d9bc3ee4) },{ Z8(8d5f7261,37be4539,14df0eab,83afe377,d1c51655,662d2c83,93a57ce3,e9510e50) Z8(eabc008f,adf6caee,62eda27b,dc264e6b,967b5ef1,3e607305,68a6a3e7,d3510c8b) Z8(8db82fac,d2e691e5,985e4d6b,12cdb909,698b165d,053c6ed4,8b8b640d,b9293be7) Z8(9d2eab19,cd8a62fa,41456141,d4c8ccba,5e2341a6,a20b5b2a,a8c96d01,0208cba0) Z8(0d57a8b8,80568840,a07d3259,319523ae,82bd3212,2d043569,b7e846e3,2d573a17) Z8(7cefb368,ae9d4303,27ccfde7,628bacb4,252efe11,5cfe1c86,c2465722,ae434b94) Z8(269beff3,2a04faa1,1dbf75b9,eeb09f8a,876e24dd,d6f3866b,424f19c5,aa190f64) Z8(e22b5222,2e545485,0a2b7d8b,1e8a1ae9,fb0114f6,b48e3f92,ee519ef5,95509203) Z8(68f15421,c7661510,743be95a,55a90c8a,49889202,e99e4a8e,ebc7df6d,8ce73e34) Z8(04a5f6cd,f2c3d6b1,6c75d69e,0e304f67,ccf41f64,24fbe67b,29c7f10e,53969ccf) Z8(b0682c13,bd842146,c4c34cfa,7ce11275,2f7969e8,90457343,c36ed54d,be1a3124) Z8(cb0f3e4b,1621316e,a6cc4717,55a524e5,3b8371af,8d55caae,ecc4f45b,b6e1224b) Z8(605ae292,601eef99,941c8c45,467e3248,2c860827,46fcc2d4,ce52c4c1,aa2093bf) Z8(f2979c71,df3d14ce,a8ed9f95,dbb6ef87,e55f721c,3561f7df,21a38e78,b87d5cef) Z8(fdeb5c9f,6ef28ced,ad6d4c00,de308ec7,677c669a,8b728db6,316975f8,2c8c94d9) Z8(6ca413ba,7addfe58,34f34bab,cc19b4ab,32652f53,a50aeeb7,9d364237,6c582d87) Z8(ba3c0b7b,c3ada609,5e23b131,8a058f3a,e3d34978,e671ef70,b8baf4c3,028a03d9) Z8(e4b48c89,92a2a7af,f3f4f547,ba617fe1,211002f5,955289dd,2b223221,e0a5a189) },{ Z8(baeeb8c1,128cef58,ba7f942a,e65ef4ac,f7b79f8d,b82aefaf,43ffd1bc,dc25ea55) Z8(b6ccbd98,2f986ea4,4e531bdf,e55fc6bb,31805a07,844cf625,9abbf13e,12d4a658) Z8(263e8d95,d3b98b37,a157bf90,d900b06b,0055615c,16b44a15,c8ec2b79,10be82cc) Z8(6f63467b,3020774b,51d506ca,3ae1b2fb,33ccd710,190a030b,79782791,32fde290) Z8(a4b86904,707dbac9,ca931244,60a08c27,0a5eff60,34f0d8f8,e70bb8fc,a94cec4f) Z8(1ef05590,5354d234,af425800,e63f4544,183395d5,94eb5fc7,6b39c237,2f3a76de) Z8(a24dc62c,7e70b37d,df2ff06e,cdefcf36,7d4e16aa,c75481ce,34138b3b,00216423) Z8(dfa9df37,3dfc9b17,b046393e,07771c1f,b7f2722a,d8cd3967,e452a3de,e092a181) Z8(236cc06c,cd2a22b1,366ff258,0b2f1b15,cb42ce82,1dbe4e2c,e99bc3f1,b1cd2a48) Z8(e769d6cc,ca5aeced,62ba1d30,c4eff7a6,4a370669,3a78fd3a,d188f373,7ff67499) Z8(e06bb75e,47c0be2a,49297daf,a06b505d,2d2b13f5,eed97c3c,cce16066,fdcd8b2d) Z8(3c3c079a,21de1d11,9986fa28,ebb8ea8d,68e90c73,c2cc3444,7e72a548,e546e3f0) Z8(5eed1740,9da3e636,d783cc4e,29e82e50,53180a9a,8957aa41,1a07c75d,9370c4a3) Z8(0c4ee88e,18f68a7d,2b2aea5f,e3dcc29f,2933108e,53fdd7e8,8b1c66ed,b3a6eb3f) Z8(18123ce0,08ecd916,352b1db3,1a6d7ebc,992433d7,28919550,1f7db2ce,eb7478a7) Z8(25875c97,ba347e64,f4bfe641,21cbb79e,fe0c2bfd,d6e29af6,f1aee623,1ffec2f4) Z8(db658566,aa327d20,00a4d724,d588e59a,29e4861d,9bfd1668,512e501a,069b2197) Z8(cd31d2dd,7f2f51cd,6f678cca,583cd3bb,eccc4bb2,66c74a26,3ac545bf,e7c72ec2) },{ Z8(e18b56ef,fe51009d,3dd362a4,60aba5f1,a26d15a2,b0b9cb4e,7fb8be09,a9f4030f) Z8(5a0754fa,48ad536d,648aea5e,d0271473,c8365a7a,8237bc10,f25c1df3,fc853cb9) Z8(74164830,d4a43f8a,3ec2eac7,7c37b50d,006d53f2,4be1e169,7d3f1fa9,b0396c9d) Z8(2df9e91d,d57bfbca,e861f5c8,52a23747,4a37955f,85ad71ab,c941fbe2,e70a9865) Z8(27428c6a,d867f61e,0b9a2554,b6b88e9c,ec908a79,269e7382,f5d530c5,4b4fb007) Z8(059edd44,d0bba717,39a3e029,116ad07c,1006a950,24b58952,ac287e74,e360e497) Z8(93b3c35d,e2f89ae1,8086df6e,f68ba6c0,afd23d15,6f56d274,5bfb532f,fedbb739) Z8(cbb97fad,1635ae5b,290c17dc,d8d84745,7ed11e22,b91f9ea0,7d1d46dd,676c60d9) Z8(dd54ac85,42856816,5a8c6b41,d148645f,8fcd4b8c,0ddabc39,5c0aaa71,ca7afd36) Z8(ace3c2fc,9af92087,c7da0e88,008db6a5,d6bd5668,e431bafd,0fac8985,a2d6cfca) Z8(123726a6,a5dcf637,cdbefde5,5b82f6fb,80196e71,56b9e3e3,89546a80,9b796d40) Z8(190be91f,0b7dc058,ad30761a,c97b4bb0,3c02b914,29686197,c6b78493,3f96591f) Z8(8d444313,5951cca9,6ac9b84b,6c42c723,78850c15,9d3d66fc,614fb520,d0b4b7df) Z8(8c521fc7,01d20075,9d8807b1,ad57e08d,f600fddd,52478101,1438b841,d267a988) Z8(c980b619,7ed83649,d6b32881,a3361838,e6d7e6ce,a8645a94,e2a9572a,1081d83d) Z8(b674c92f,2592823a,e317ca56,063f1c70,a12838f3,e4d6d8ff,f996f242,56341fad) Z8(62c86a25,66a2f427,2f60a29b,e80b2fdf,272e61fc,d8363b33,cfe1effc,51acdd2d) Z8(2c2a932d,a14067fc,050387f0,ca170f74,b6d52de2,44bd8397,071e02e5,ef22aefc) },{ Z8(51d29ed1,eb1c805e,ca64500a,438701a0,b39428de,dfb18f9f,fcdf1ab0,0a837378) Z8(23af7d34,5524aabb,2a36c8b9,88a6cd75,57b463b3,1469f859,cfd9f515,975e389a) Z8(27afadfb,0f74ce1a,6a2285aa,68b66b3d,4634b9ce,76b2d5f4,3ce74a70,a56555f6) Z8(3f9dfad4,ba5ab9bc,e11fff90,66c2f716,decad2b6,c339bb7f,65b6add0,ecd36dad) Z8(a4c141ff,bdcff26b,dbb94b8c,c47651a4,77ec0e04,797e487d,b1c18e80,d08ab3c9) Z8(be98a02c,f1c73a7d,1a5c5fd0,0abaeaef,3d73b07a,9a9e0bc2,04d5a3bc,83dda469) Z8(9835e0ce,2bf4dd82,f7681dd4,470f9998,9c7b4fab,d1f9c56a,49bfefb8,1ff2254a) Z8(c8a86731,921fd0cc,f8b4b5ff,ff51b106,01a963d9,742a8eb1,c9cad826,cbbe90d2) Z8(05f53be7,b2daa55c,9872fa6d,483280d2,d2b6b00f,399c5be3,91cf8fb6,a93c6b60) Z8(8dd877d6,af0d48d2,4b4d04a4,19167770,6286e71c,fe56f3e4,c6c4faa5,c69db1ae) Z8(859f80bf,70a13ded,f24f18cd,84514e38,f77aa802,ab2030c7,ff97ecf1,3b2f575d) Z8(d100b799,587cdfec,4f867f2d,7fdea26c,e6c5dcd5,31507573,9e65c54c,631d04de) Z8(847c31c8,3f65c927,9e3954b8,092eafbc,cfd90fc0,630a8c0e,bdc7bfdb,87b6ee33) Z8(e149bd2a,45e52513,b918055d,df0b9079,c5f8fa19,7e568a0e,73c6cebe,2fcca9ad) Z8(9a5a4cae,0ff31493,f79356f4,556f85af,f9327526,0e72064c,cc0ca4e9,d3890053) Z8(b256d2aa,8e0bea85,19363ff2,63321e2c,9cc676ac,2ff05f80,6f42273a,0b99819f) Z8(d9d78745,2834630b,29c68f56,24644130,1c59be74,cb1a9027,0ab6e51c,9956a0e3) Z8(e0372057,d8960c5c,36404c21,5c03bf58,fed26645,abd8e26f,6e0a0fc3,f6b9f920) },{ Z8(08501603,683caee5,742696cd,05d080b8,8e0078e9,8f30358e,8783ae7d,be2ac4c7) Z8(787b52d7,100d9b64,8c009439,0e7ae058,7035c9b4,94647330,bfbea8dd,06de228c) Z8(0d9b2256,f7759b21,510b5176,cb126e78,5d597b62,e48f7347,bc4b8c8d,21256cdb) Z8(733f08c6,5da01e31,5226aadf,44d5c2d1,94eba949,d3de45f5,33b247f4,5ec369d7) Z8(80e03828,c3805408,6cd2cae9,e0d56b47,2dc4ccc9,3e1890c1,f1db4994,86ecd96e) Z8(e43b0a87,3501b90b,6fd9de40,2e542da8,77d07733,d3235c22,e978e17b,6a6023b5) Z8(9f6e4736,651b28b5,94025a03,d1f0ba06,c77a627f,750a036a,6a4cd2cc,bbbb30b9) Z8(255fe91c,dc9b2962,9733ff0d,2c36d720,df47d512,ecac88e6,36f754e3,058dc86b) Z8(722d5007,908a9be7,0e618051,f9c40ffe,30cc5362,f7cb9de2,7454b97b,7332ff02) Z8(6b808f4d,f8aa64e5,d4f3b5a5,97ad4a64,df36e995,86aacd70,e54d5679,c3bb4d1c) Z8(24459835,912e8b4c,4ff40fd2,dd5136b6,d5e2e7dd,4b8900b5,74cb6d49,53bbe7c9) Z8(8e4f9cf0,e6971b76,c838b45d,ec21b17c,c78988a5,1d36f9a2,981c0c39,3f1f3ce1) Z8(1ef3b30b,512ed7a4,b68885df,59957a80,c1ff7f98,6f685d1b,e7632f69,04088e1d) Z8(4d49eb70,69fb4f22,84060732,de88d2ea,e7a8865c,b3664e87,79c635ee,3d6618e9) Z8(4af3b029,3e49bc7f,2036566b,44f0f5e5,27138b02,06132e38,d5c63bb6,6ac69456) Z8(ba01e911,27bc2083,4d6b3332,475f36c9,32083e4e,01d7c09d,8bd1891e,cbc7b1d9) Z8(8e8e7f80,6a93691c,9db6f5a0,f3fb6332,c0c7dee3,1cd658c8,e1e5ce66,b6cd35dd) Z8(4749b4fd,d2a0a1dd,ad8263b1,12708a7a,32cb9121,61db6846,17c644e9,fe8ef30c) }}; const mp_limb_t arb_exp_tab22[ARB_EXP_TAB22_NUM][ARB_EXP_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,80000000) },{ Z8(03b8b0fb,acc1e74f,d3401986,545cd9de,d54ae904,d6e786bd,ffe88931,52d43454) Z8(df46d3da,c07b2995,19f6f3fa,ffdf5aaa,0531dac6,8ed0aac1,e4c26f9e,aaa7016f) Z8(7eb44608,fef9bd87,09b26d00,16480a1e,9445a7bb,ddadd016,b31ae70c,59b6d5a2) Z8(7ba583e0,34361d34,bc8207d0,a1866c76,d32ca01f,fa81adad,b6819ef6,28042fdc) Z8(ea00267f,6451a464,2e8f1318,bc3aa440,765278c5,6f64c3ae,947ba912,63d54b04) Z8(6e60845d,b88376ff,eba6fd41,1db0d07f,db881ee2,d219f2c4,25f7340c,343c60ac) Z8(56f37f93,dcfeed59,82ece08e,46eec10c,bb758db3,e8c0fac7,ecd6ceec,005d849d) Z8(56e70113,ac3d06ed,7d145cda,67a7c824,27b378ac,8737e92f,01a44cab,5f14bc43) Z8(f1cb53c0,abdcec42,db59fbf2,7a29199b,2a333c5a,5420f425,c92d28cb,a470ff3e) Z8(76d83042,0b85cdd9,a1e8f5d8,9749698a,91592982,d84a78bb,4e33ed6f,550eff7e) Z8(b6abab11,5cc94f7e,4d2b7e8e,243b1703,4eb45f36,eeec3817,16c7e29a,4f971829) Z8(bbcc3012,a0ad1d3d,203fd476,4401471b,b9efb83c,d305d47e,197192e0,3e35f637) Z8(0ffcad45,41c2e455,44228877,56f2ed4c,d4e2f9fc,d513cbdc,462b44c0,7790f00e) Z8(0dd744dc,0796aa70,638f0f03,ff6036a9,00fb04b3,942c3e42,6f1c5388,537bdfab) Z8(12324781,8d21cc97,9c6ffd76,f4589007,0bc1b3fc,6fb370a5,3bea4f42,24d1b86b) Z8(b14d4e1c,07836c20,9cac0191,aa0ed669,670949a1,3806abc5,d84e903b,6ebc201b) Z8(c24c77cf,47f7c7bf,a452e423,d8e0ac63,f87cb252,86dec92d,851cc1a9,d0e18717) Z8(927372a0,2c6f8635,a2d3aa12,2a408ea8,37493bd5,f1c73674,555aaaee,80200400) },{ Z8(79777d59,324ee7e4,c1f44d16,8b34cd9f,93f10143,3d7fa0bb,207e9f96,4eb09eb5) Z8(48a27810,fa30f046,a73e0198,48e18ac4,28a8cee1,d784c3bf,294e0a9e,50ab3912) Z8(b21065c5,6d4cc4b2,074642ad,bacb1ec0,aeaab3f7,fa98fd22,e8ab030f,c1f49749) Z8(df519b31,8f1c0721,2efed010,65396edd,987bb849,36cfb318,8239d916,40bcf1a2) Z8(465188b0,3720f304,0b522bc3,283bea2c,0537f7c6,e2e24da4,3c78808e,e19afda9) Z8(9253dfde,a5b09543,8134b17d,51ce9636,f09b366b,d3aca3c0,5e908566,22e69369) Z8(7edb6bb4,eb30c804,598a9843,4d3c8b19,9769062b,68373103,173dce18,c1b322a5) Z8(47230b6d,8ba117dd,df088141,420f9e4e,d0e989bc,330e8c04,fd956672,57202737) Z8(a826393e,54b55414,66ebc0d1,dd44292a,63c6da41,dc1b9aee,b72b443b,c63599af) Z8(e749f0c3,e601e3ee,3ea0e3ae,e2299adf,80923f15,bfbf7faa,ad3f0f50,3b6f7d14) Z8(fed4cad9,72621213,141d166a,47ae7cd8,fd30674d,602ed8ce,45a0a2d2,38657f1b) Z8(cf3a85b7,ce49f688,b054e223,66396d44,4e245cca,b40a4f0d,89101048,3262b09a) Z8(edcb136c,2934446f,7d93a205,6f8e8424,8fafb37e,b45546c7,f4b07cc4,f890f91f) Z8(c7864953,1d1527d5,5ca0fb6d,4c0c50ab,d7cfe8a0,182e7ff0,601488a1,1def11e9) Z8(1b981f50,8ef3e807,09eba861,ab7b0576,7b75d98a,a333d8fd,3ce9ffaf,aca016a6) Z8(b915d148,b8db52f5,17ffd9e0,72df3a87,79e5a00c,3bc3ee67,51a377d1,9a670745) Z8(3f06f65d,04eb1d5c,ffafd365,049b2d7e,abf3b2ab,3fd7dc72,ffdcdd75,51f84a84) Z8(75d2909c,a202d35f,0abf4e86,cdd724d1,b97a6479,3ea0eade,ab000889,80401002) },{ Z8(96ba8909,0a0201da,6ed13830,26d70be1,87c7d74c,fdcc1a5a,5d6c1ae3,d576b23f) Z8(333b2ecd,31f713e3,5ee91c12,33d3b703,ad02e4a3,fc4344a9,bad77f34,40c468b2) Z8(a0b6f069,530a4eaf,a548d6db,6aeccbd4,53756048,d3e8b488,fe236b24,bb00951d) Z8(391b5fe4,7ea88ebf,10da122a,5602e9b2,30578cd8,a3569a69,e33ba09a,5067833c) Z8(3554d397,5ec36aa5,2b62b6de,a6a480ec,b85acb7c,5083b319,881ee588,7c5d6130) Z8(652e7695,8b95687d,f28b5482,037bbe66,ce9d701d,8913b8fe,897a6907,1a93d7f3) Z8(04bbe10a,71994759,9ac66383,a96afa3b,b9007797,ebfd954d,e06e88b6,59ed00d5) Z8(8eb679de,1a713099,6a55f947,0ecfe69c,443c1f30,9518b45c,3b275771,c5d04dfe) Z8(d3b1bea8,5daf81b8,8a15cd9c,a3014e82,f8d75f6f,d9cc25b9,424bd20c,05d84e59) Z8(5c4aaac9,fa70dfd6,8e770b4b,456fdc7d,1389e418,c721ed84,16cac398,af7d57a7) Z8(09e626b5,eba1e359,752f5f2f,5581a201,81362ddf,5821752e,fd92fe29,41c3748b) Z8(0abfd98a,f5a282f6,1aa40602,f354ebb5,66d9ea67,8cfc4b6d,5b5ebcf4,a6de9de5) Z8(8e3c8af0,e114a7f6,4c890bea,175a5a91,b2a853dd,709be027,27dedfc7,f86c485d) Z8(3eba10f2,8e401074,9aab0272,05a23bf2,c0f792a4,92d98eda,993f8c6d,adfee4ea) Z8(d0287f28,b6166d0c,107a6442,30f735b1,4871dd86,571a0d3c,6ae61f4b,2c8c8e89) Z8(f6ac196c,d81dafcf,4a3e7b5e,d898b6fc,f12ca26e,e57ebc9c,559d824f,64a80fb6) Z8(950fc9d0,3a554359,ced464f4,20889b29,096b7204,74f41faf,2ba5710f,a2283a1d) Z8(8c205922,9076afe4,65854e0f,0295b6a4,fe4d3866,e744a71e,01b040d4,80602409) },{ Z8(7dcb51e0,afe482ff,beefc606,1727322b,3e7b8164,760019d7,bbeb20ac,cc3e8676) Z8(6b8e430b,6ea24846,ab34686e,c6cf51b9,4bcae1d2,dcc70373,b8a2dc3a,e8e83af0) Z8(16bc987d,c58ed487,883868a7,4cf8cf36,d455dbbc,bcd3d67b,f0f70284,861d86c9) Z8(da0d9c7e,fe3bef24,c611ec14,f29b8087,b375e50a,695e5b19,ab1a7127,9b14d5cc) Z8(b5d0c1af,560079fb,8a72bd06,5aab4d29,3be6cc65,a1d5034d,1c8899d9,6cb4d5ac) Z8(c1eb02f2,078231d0,24447b99,9f851217,78a2b54e,1f74581e,32de2c25,254076b6) Z8(7b44413c,264694bf,4a441c3c,831e8276,2dde6ddb,56b0a084,d411a8a2,3842b59f) Z8(3afb6bf8,c004a0bf,dd425c46,a0705ace,0cbb5961,0b434b89,ca901fa3,633bb34e) Z8(3c232ed5,3e125cb8,2dff1684,66cd4af9,64cb8957,0c08696f,cbc025e1,20489d4f) Z8(90965566,084d2e55,8ec6511c,014a3737,411de64c,48b5440b,ce857dc2,6798da7e) Z8(c9f79aac,5c4347fe,11bda442,07d6aec7,3a9f0fce,81d2a25b,4a830e45,a82f082a) Z8(b4e946ef,840e7dc4,f577a676,2163a215,47dec8d1,0bef4d19,d9cb6ed3,b41876a2) Z8(eba0499a,f9db521b,6d007e01,425c65b0,e039bca1,0d8fe45e,f6c1ec9e,56db3f34) Z8(78873748,bfd44117,63ea747f,730ad69e,78773929,102c4e83,a7dadc36,3203e971) Z8(4aadf7ae,54067aaf,edadcbca,1a6765cd,afe9f0f9,e9b19b90,607bce29,302fd653) Z8(7e9a3473,9f1da49a,3c7ac797,db39e59d,40a811bc,56a00d37,57bda725,f96e18cc) Z8(ff554e0d,eaf5c2fa,5c67ff57,abee91b9,020d348f,e82f3725,fafa1201,575bd293) Z8(d0372a42,1eb90105,8676076f,de780649,3554f733,45152169,5aabbbe9,80804015) },{ Z8(b98d7006,b5b3fbb6,165a494d,79d6bc5d,29cfac64,92feec94,97e5370f,6d1ca01e) Z8(5c522f84,d210c6b9,8cee0836,9eda3628,27088025,d21c28da,0ba2b06e,04723d37) Z8(335a65af,9c618969,d0feae89,450ee3ed,a771d4f9,b06a52cd,d816f0f4,1d2d0604) Z8(86e1465c,1f6d9be4,070b89c6,0dfb88ea,8436ef7b,9281ad38,010bb79b,2384dbdb) Z8(14dd2291,6721df7a,1c499979,fc3665ef,42a57710,7d1d8a06,95790c22,1cc2328f) Z8(22be2038,8a0fb0cd,ab58c444,c76d32c7,07eff20a,8cd98047,80e2679a,c80df062) Z8(a11c935a,720750bc,7b1b1610,29128604,cce1b2b2,d97f58c9,1fc0c68e,7be8f196) Z8(c80c2a1b,8abf3276,7df23c87,bd87b4ee,ec440f3a,e60abb69,4fd0f901,46c8ed21) Z8(e9486783,02cd26ad,bf97459c,201a0ec7,5f34c72e,29c68c6f,bb13d0f8,a7bde7ba) Z8(739bfb7e,e289e191,792fdee1,047fad5f,8a77bdf1,68981ca8,53085631,ba579ae2) Z8(6b95c253,7b18951e,311870d8,e57d8f45,a92e2515,8213e7b0,1b65ce52,a312ef01) Z8(ed23063a,daaa0ba3,3fcbd91e,852b188a,656a480f,59cac7d7,cef1a6a2,5e442d15) Z8(16b0a205,a994d0b5,822195ee,0a933ebc,43d3b558,103198b8,89547d21,b83f64ef) Z8(4621214e,f0151b40,6737186d,aebdc6f0,6303391a,545005bb,74f57df6,48797ab2) Z8(58d785ff,a4382f53,d4236916,f1c815cc,9315fffc,e1a88ec7,82d4f891,f7d5195f) Z8(11f95baa,02756770,3d520122,5d4887e0,2a36f587,b0e56390,1266f519,b6dce1f2) Z8(323bbc7e,f5a060e2,c08f5456,17afdf77,9e1a904a,b2d81cf7,6d090151,2086d001) Z8(6675accc,5a6653bd,bb3124d1,005dce48,8a236bc9,10cc773a,b7b34203,80a06429) },{ Z8(876449d4,d160da90,5421bd7d,75fd8893,df1deda8,0341607a,693f4fb9,145c68e7) Z8(822b563e,cd1b4db0,a7f6df89,4e23e157,da783068,4fa1773b,d05cad09,5cc1f398) Z8(d070f00c,d5ac1209,a779fb81,77c9a42f,abb859d1,8442e79c,09ed46af,bb00315c) Z8(62ef4dad,dc2b30d2,58da2832,7e1d08f8,b88ad558,bfe88a71,fc9b7af8,dd4b9e1b) Z8(2a281f3a,c4b33f96,03a47424,8791f75b,bbe20701,1ba2b6c8,d34305c4,8fc42106) Z8(963ebff7,dc0d20ea,fe63c1f9,0dfcd3c6,66aaf8bc,a0cb48ec,5baca9b2,c3f5dab7) Z8(c94fca3c,87dda06b,19ea53f9,ea2d14c2,7c152da6,eb07491b,5bba393b,0072f2d6) Z8(c1974a90,fdbf4ce3,f7078ed0,fcabb990,9c43a4c9,6e89e546,ed9f5e83,f03cca77) Z8(dfc078fb,fcaca9bc,9f8e6e81,873c470e,7a2b803f,5aa34b9a,1accce33,fc68c38c) Z8(11f98354,88faed69,0fe0b7cb,7a36f41c,ca43c732,80707aca,2d16bb98,6785623d) Z8(12bd7a0f,701d93e2,efff4a35,11c43ee3,7e24eca0,14511eb3,e037b4dc,776fa1c8) Z8(27b1e111,aff342f2,e4724dcc,d5d3e43b,e2d7b859,6bc4df58,5849f2a2,11ac6b0f) Z8(870cb740,4f259c37,c76d4124,f163ba54,22e246e3,ba1578f9,0a45343f,f457859a) Z8(2645b431,07d2a7bd,89037290,139fc90c,7b181e29,5a380c43,838096db,5640bfab) Z8(79306d2d,03c45a17,f9876699,8c8b05d8,d3cdee15,971e09c4,f25d48e3,0b68d496) Z8(e1fab982,1787d098,f188e595,995fefa1,584689db,35c7fd88,f23d2ea5,824255ec) Z8(c166e477,29edd062,c32c5dd0,da211698,317fb710,ad10b872,d60190ed,39ff5341) Z8(9d17e8cf,617ada6e,e72f240b,3e5babe1,8cb02cd4,6f2ac8f5,1b081ba0,80c09048) },{ Z8(a3dfa477,c368c35d,d93f73fb,756097fd,fe57f5d2,35be3fb3,78a495f6,a312dea7) Z8(3bb5baa7,0d8c9e3c,6f201a87,91e0bd0d,13fd5b7c,d80423ef,bd1c637b,f2499b83) Z8(becc8dac,70c67401,83b79255,153c94e8,5dba29b2,13156b4d,30254812,e0ff64f8) Z8(852eaace,3446bd94,7d548730,16ccdd80,096a20e1,c0d6e945,e902a956,2f76ec70) Z8(e02f9897,6308fe2f,0dd10bcd,ac2e9091,587742d4,bf8f8ae0,5c603f15,d2aaa214) Z8(fe0fe206,76b2186e,e12a7a24,dd2b5436,8d94c75d,a709743f,ee4a81cc,96661b18) Z8(0a15823f,481b77b3,bd9b5384,6c3f0452,b692cbf9,66b3ce69,b1a75866,05dde90e) Z8(70df257e,9ef089ce,9afa121c,349e69ec,7e08e525,75980dd4,02a689dc,9dbc0f0c) Z8(eae1bef0,15e6cb71,214e45c1,878bb12f,65543f98,443ee3fd,6bebb3d2,b3eaaded) Z8(239df50b,ecd712ab,62bc26a9,602a70dd,2a3ec602,490f62c8,b6fb7278,c0941599) Z8(bb4eb9e5,15e60885,c5915803,bc94f8de,442e36c7,99ed9ed5,606ad26d,d51960ce) Z8(28fabcce,31d140fb,497dd53f,2a9e2f10,85a40ab3,875b51c8,299dc08c,bd3a461e) Z8(f94ae2e1,355c4ef8,fed5148a,73adaabf,154300fd,f0ef0823,8b47e192,069213e6) Z8(b04ba7c7,1b4bf38a,80fb00b4,c72bc3c6,be0bbaff,61d8ad29,011815b6,87588ca3) Z8(425292ca,9434b431,c12ced51,f1fbb9d6,5438b7c3,13f5aa78,8bd7513f,2c21dd0d) Z8(a0b2c935,70c14292,010e1846,45d21566,ccdfba4d,830dc518,aba1a73b,929081e0) Z8(8b6cf8a9,11379c60,9a856970,61c1063f,2bf40597,2adeaf85,74f1ea78,30a77885) Z8(38836f06,73456987,c9fbf71c,39440b0d,54bcea20,05a8f6f4,876c31a5,80e0c472) },{ Z8(a8796b29,e3146dc2,da57855c,62ce77fd,3779d1e4,308f4161,d15a1693,aa2c8dce) Z8(ee1520d7,8b87ef5a,1841e2a8,8b2c36b1,02c5a31b,770250fb,8df9f077,d74ead8d) Z8(181f86be,961314ad,0da43554,6c93044f,87a37ac9,c741ead9,16811e2b,1a7be856) Z8(866e3b84,b91d7ee8,d1255f92,eece105d,134e24f7,615a74a7,2d622752,467f9226) Z8(e51834cc,02a8b55c,055ddeb6,2bb89474,61e476fb,89847470,cdd8b056,514d2940) Z8(52857201,6d138082,636d6d05,c57ad739,d07e2557,fcf12555,f0338dc9,53e4a014) Z8(e07b2f98,934a3f14,e35da48c,6f014cdb,b2d2fa76,c196d7d0,a344a63e,7433b760) Z8(cd0a1d47,af676703,4fa5d1b5,15aedd21,a1f8dd6e,ead13665,bc4ebeec,778d918c) Z8(1983cfd5,38612de4,6211907e,a0ddca2a,ddffbccd,97b2ba3d,798870d8,911e3d8a) Z8(63d272ce,a1669237,3cde1e66,e48e57a2,a736f4cd,6c8e2cbc,ea882254,98af7d0a) Z8(ad739eca,00e13832,39e45865,cae16345,b98ac2a2,63c6eac0,1b59b8a1,ed2017db) Z8(ccdb5948,738b27ed,49717e93,d445d6b8,46170ffb,df4a43b7,d2c4a89b,9027befb) Z8(5907e8c7,2c41d63a,49763d4a,7a4de3df,69e739d4,87761aab,77625f6c,19ef7768) Z8(f8f807c5,9e81e94c,56514cff,086d6e12,6f0b865d,3635093c,b7e89818,0ef496cb) Z8(87b8045f,70354a50,63c1c10b,9e1d7c31,3b980664,be11a20e,acf362c3,c6f3052c) Z8(629f2ad6,61385b46,41aa6ddf,899d9bb7,ec8ca2de,ab3f0217,8b5719dc,4f7c3670) Z8(7539dd57,e5a39b83,5319c8f5,32a6326f,421fa89a,c54f1230,b416c333,da17fb32) Z8(c0482614,80ab44b0,ed70fa46,37b1c91e,39b44e99,1931c15e,00222d86,810100ab) },{ Z8(9b44642c,88d0a465,9639800d,2c7bf51f,6ab0a132,c424f54c,477ceac5,051995d4) Z8(4a0ce5f3,74a34fb2,818bb94b,3ccaff2a,1c0ad802,7c212272,2cf0d435,5f9c1350) Z8(1423fc00,377fa1cc,f1d6aa97,89801e2a,3fc57ace,5bc41912,3ecc5086,d97aff60) Z8(1f296160,7d0d9025,24f19d1e,9f011b15,daa9b8d3,3584c647,aa631166,47d8cd70) Z8(d611b62f,a5e36f5d,80f7b669,2e7ccea1,ed63a9b9,8f73ae1c,b5f54ea7,ed615a81) Z8(e2fff9e1,641afea7,14f63a22,244ab1a4,b7c46e2e,c41719ec,b7d6046e,71466069) Z8(045707a5,3c5b3e43,fc9698ad,a4f5c5e5,be19e211,710403d8,f257f196,c2dc8a2e) Z8(db5ebda6,bcd9f996,062dfea4,bb2630a3,cf4d2895,877033eb,d99e9b57,d3d37db2) Z8(3378cec8,a14e9058,78239db3,5adbc5ca,bf0a8418,11c6b024,7adfead3,8ba6c77a) Z8(7f34eb5a,7ff0fb69,c03aa1b7,c2d4d5d5,1808c29d,9be23085,ae2b3162,82ddfe10) Z8(3b746f99,dcd79b99,75985ee3,211d0cc3,3c3e30d7,376ed5bd,8a32966e,6ecd5eae) Z8(90f55019,959f4cf1,b757ae7d,18dae0be,eb3ab86f,fb542985,ab5df6ff,7a3bc2bd) Z8(06226acb,7de75f0a,524e0f07,07f23d14,0f05a071,c410886c,be4bcb7a,56bc5407) Z8(9c517ffd,e568b9b5,19087a8c,fae75b32,d5a33c2e,67027fa5,0f0da047,2c7a3334) Z8(91aac57b,598ae445,c2037f76,b4afadf2,117d1f02,5ed25fef,4d769636,04b5c182) Z8(dd27e750,e25cd4a9,533de42b,43550a76,745c0d85,1e0f36fd,52317ca5,065167cb) Z8(75ba4125,255fe84a,a06671fa,7f02085e,89b05461,d9dd34f1,dc40d87e,50030415) Z8(3be9afc7,ebda4c44,787e1e24,ea9841df,5f58b8b4,b8e40caf,88ed997e,812144f3) },{ Z8(eae7d2ba,a65ace27,7421702d,d3ab3f6a,4060ed3d,9ac89280,76c8b395,c43c36f0) Z8(aada5941,9d7c547f,2db058a0,1186c214,c3431891,4904dba9,515b5351,e9ed78da) Z8(e5e2de1d,aff0ca47,5275d5d6,6eae7b01,4aade5da,481af666,67053986,e8455da5) Z8(3e04618d,f1a445e2,cd7d2e03,51530a37,f1a12066,9d095b91,e154faf9,c8c2067f) Z8(5844bc8d,a12aabd6,c2fc1fcc,735ad5a2,1124fd62,0ea80907,ee235be2,36675f98) Z8(b4cc20b3,a9394fed,b5f764af,c305e1b1,b1cd56b4,4631ab6a,4d86f14b,4c03e297) Z8(9271e275,cf281d36,d1f64d30,87378a2e,53bd6dbd,b1786908,bfe1705d,151ee252) Z8(eaaef7a8,2efb4332,4652e89e,689098c0,7d95d46b,f90d9f69,54203e6e,9f078095) Z8(7f50e25e,04f719de,f0ddb34d,6726df44,54671db1,fe3899dd,18456418,e54b2636) Z8(a397bc8c,77fb827e,1a7ee325,fe4d8ecc,0500a2da,d7b91238,b722424f,defc0239) Z8(69fdbed4,f1c0e9b2,b2c963d4,b8912f2f,a56fb980,f79fa0ae,9fd8cbbf,a96d5d1e) Z8(b8aea754,31ba8cd7,d7ac44c2,af14a7e9,93d764a9,89696410,aebfddba,7a2ed169) Z8(0446d73c,83baa27d,1d230fdc,fba9e0f7,1fdfb76b,9fdb20a7,2566a061,ab48799e) Z8(69856f90,5bddf9ab,8f4c1833,e1c62b01,e39cf184,35e68c2e,fa8c14a1,1b6d4504) Z8(ed468922,2d938c7d,726e077a,15b804b0,080b09ef,d38d917b,ad8a0b28,d2293204) Z8(776e0db9,7fd8e20c,4bc7a8f4,47ffe2fd,45c82265,5b7067a6,56496d7f,d1eb63d5) Z8(91887fd4,dd226606,3770e3ec,392f1ec5,f87dbd1a,02b9035e,99db343b,a0694db2) Z8(2bc9060f,935e8d78,4ad9c50e,cfcda14e,ea8ed3a5,f6e18da0,261300cb,8141914e) },{ Z8(d7364855,2ee1ab21,bd0aa6e9,458e6c6b,4a061bcf,a42a849b,d0deb679,6e69d256) Z8(0f230353,464626f6,31f4b27c,ecdb2d96,ebcf951f,980ce525,3fea3291,61d4ca5b) Z8(76273a48,43028386,d35a9f24,bd362a41,f3186eb6,ec3f78f4,6eb43637,36425260) Z8(137aa6fd,90aebe4d,c4cdd569,c42d8e66,828ccf5c,bb08c3fa,8d41571b,6d7379ab) Z8(14e9b5a8,c4b8b869,dba77522,2a9f6e70,2f2b1266,5f892a3e,11f67fee,64091a08) Z8(7a77f1ed,a912e48f,97b0c5ba,098e79a3,f03104d9,8eea6418,9fc54fd2,7833af06) Z8(e61dc994,01ecc6f4,80a0fd77,288a928f,c4e12a92,54b020f7,3b85398c,9c51901d) Z8(ce561e3b,fa80ea98,8d9ee41d,76c12646,4b0ca2e7,9cc08df0,54f4d2ed,88bd2fad) Z8(bc99a598,79a37904,872a65bd,0239221a,6ea3dc85,3aa1c48e,790f9456,a66f938e) Z8(b0550da2,582b3bd6,127c464b,ce26d6e3,60ef5f08,9d721a27,cc5a0317,36dcdc91) Z8(5a33db41,af781864,75c68190,0a66973e,dd4d5d5f,be6f5456,168d9634,9bfada3a) Z8(2568e432,e2517323,7b188af4,c83e67e5,810bce71,fd188822,3d00c42f,d04f59be) Z8(c5757798,62d5047c,579efde6,7424fd60,b7f59932,a6c77fa4,94048add,389a0ba1) Z8(ed7000c0,c5178ce2,1b329880,165bd84f,24d79a78,8f8616f1,acf3ee94,88dd67cc) Z8(3b2c9467,7acf6e04,6f49a5f0,9ce6a71c,940a522e,d83476a1,f003ca5a,74da201b) Z8(5f05c74f,c0244bc7,c85bc158,02b7720f,d34cfed5,fe4fee6b,44c79cd9,b5e12a2d) Z8(27e52fe7,9e44fc62,d4ba047e,43610f64,833e86b0,6a6d4547,e1a7d729,e56a8251) Z8(0621de9e,8e58f35c,624fa028,f36f4285,78b1fca3,312da001,dc580ff1,8161e5bc) },{ Z8(a797fc05,ed2c1058,52fd11fa,1b69ccc2,550e1536,bffd3b50,09383d92,960c78f4) Z8(97184206,1de8d5e7,2eaa7799,f849fe64,27237145,73077250,c9a39bf7,da24716b) Z8(2b7cbc20,451729b3,77bd6226,0285c0b1,f6396a08,2058a990,e7058179,2f9b1173) Z8(5ce5c978,8997b953,e8b409b7,61f00eea,a17ed452,47ec3a09,33a8c843,c7ff9332) Z8(83172643,250c2bdf,57b3d321,82a8b247,b89dae9d,917ba498,138b4cfd,94deeaee) Z8(4de4a07c,f5cf87fd,4871815e,6e88a019,67c41fe2,0117e892,748c83a1,5ba0c9f0) Z8(3edaafd8,c4baf24e,8925e199,c259b6f1,ff1dfd75,f8ec78ed,9d32b19f,712c17eb) Z8(cc020e56,0e989f58,d1e05fc7,1a49ad4a,74bed6cb,ef3828a4,46bafec4,f147f0f9) Z8(786cfeaa,f6d5f9dc,4dc8f9c2,f87b8843,b69a4857,500435cf,f5d7474a,b97e81c2) Z8(4e087777,a1940bd7,3d26f9a0,59ec5272,db8c43a3,af88dea2,903a4e53,36b44570) Z8(3b7cf73b,53ac611b,7cd6066e,7f6a00e1,67d881ea,92f924b9,7709f4b9,f4190070) Z8(16ef7da3,726352fa,b4ef3d6c,7cb32b0e,ecc8ec8b,14373e75,cca65cc7,33b9c5d4) Z8(9a9b0e12,5d9db1ae,d71c4040,cf7708b8,cf259000,1729624a,55d3b7b6,69dd460f) Z8(e506f674,345f055d,d0b25a59,0254428f,f2aa4515,02a8fe83,188930a6,88852926) Z8(0c45fd4a,804736fb,01266cb9,82a7e8a7,7d7c0530,78a0a066,63d4e24e,579bd6d1) Z8(32e29ab0,96018922,3d7e2d0e,ccc873b6,b8424c1f,96721938,11038824,5690efa3) Z8(e184c3b3,c58f8dbc,34da4bae,bbc6f344,767a5698,39c05a2d,27d75440,28927bad) Z8(2c5d5be9,a747371f,0ac8a0c5,b2d88edc,773b6516,6ca08d0e,b103b504,81824241) },{ Z8(b6b2e345,083aab3a,0370f2b3,f5f00b41,3c0bd179,1dd24370,ac734e9b,8c6485e3) Z8(8d7f3ff1,ca53cbd9,a94f1132,13282d8c,f7cad936,e6e5f515,c17ff691,597d3667) Z8(2b8dcaac,9b60d5b1,5ae67a9d,b54757ce,7b3acfaa,36e1f86d,317ef412,b0ec177f) Z8(329c3436,9b001756,bf604645,7d3c3a26,3f333dbc,ebce539f,77f710a3,6f8f85b7) Z8(5067f841,8dbc42a3,fccf573a,f3c60dea,bff8f850,9536a633,1204600a,258c8c5e) Z8(61a59c1c,2a665414,bfbb97e7,a7583da9,1ca86fe8,edecb502,d7b6cfb7,fca4c5dc) Z8(b4d98521,4179fb62,11c4ab51,bb3b5b77,ceca66c0,d48543e9,61b4edb2,40f1976b) Z8(f5ddd958,c6f78d7f,1a9898ed,8af1599d,8d0ae389,94446855,a96f470c,03bdfe26) Z8(117bc3c3,05b55684,cff638eb,02015c9f,3e889ad9,f0766372,73c81b7e,cd9d72cd) Z8(d7af280c,6b1468e3,035035d2,5c1c8720,e6f25e14,f3b00aa9,1ac6995c,4dfb6ceb) Z8(30722e4b,02fc7fc9,84dc9945,dcdfffaf,ebeb85c4,8ae82921,64f1d1b0,2fceb67b) Z8(b83d9189,edc48646,ec26611c,f4df18a5,dbdca73a,c91b235d,a6595762,3a9b93bb) Z8(132f08f9,f8a1a6c5,0f45b6d5,8e33de1b,644b58e6,f56cc7b6,f551bfd4,ac8e1dea) Z8(8177f678,41af1566,024d7683,a48d82d4,55c2e0dc,f02284a6,0806eb20,7099f572) Z8(cf0d5207,10dc7c33,867fc15a,4055f8eb,719ddca0,6668cf3a,853e4a6a,affd4d86) Z8(4cc51bb5,2f5bf4e3,ae5badb2,7eb1f8ee,e094bee7,e3b709fe,41e97c82,b0be9a7f) Z8(0049424f,827ace8b,9497714c,e41a9ef5,492259de,f7aa3f29,490ac49e,a81645b6) Z8(65389168,6f49f169,309dc853,4b98f7c5,41291ccf,c3f40700,a9de4002,81a2a6de) },{ Z8(f2a378ea,aed8a7f0,9153fcaa,9884805a,aa95e9ad,bb801e9a,c31ecfac,cbd5dd2b) Z8(bf9b866e,9acd87d2,812696b9,8dc9c9af,18680d91,52c0ea58,a80f82be,1a3ff42f) Z8(6b9d5261,52bd4c6e,1261afa0,a4accde5,68c97455,52e8975f,f96821ca,bd1681d4) Z8(7c98df5e,dcbd639a,43ea19ac,995fc067,cbac828f,dfd650ca,63b0b208,9b70c739) Z8(a5a59e91,dec4eb57,07b6a482,f0af1718,fe019ac7,22dad00b,f78ca9ce,bda01e3f) Z8(715c9e0b,95587ad6,1de13094,43971eb3,b6a5d450,64b7e695,4f5e0c0a,cf5eda21) Z8(a4953eda,851de1f4,095aaa47,87ff198f,edb10927,0af23076,4b35826f,ad8604c6) Z8(62b61918,196e15d9,c0d5a94c,c2c13859,f78b36eb,5db64d23,4a908ea2,932210ff) Z8(55455c6a,742a33c6,fdc9202b,a7a3b16e,2fb1dff8,7ff65ebf,bc01b1cd,5ab9d339) Z8(95df7eb9,ddce6909,29a70002,b85507bc,ece61430,c0a7c4e8,e1760707,14112492) Z8(c75b1093,11b1f911,fb5218f7,eb1ff380,ce1ca8ba,b95f7afa,0706931c,d877e8a3) Z8(02ed299e,fe917d57,63c2ad11,dbe4158b,0fbb8f3a,5e32964f,2e6559d6,1243928f) Z8(8553db7f,20822c90,765b235f,848d9ff7,1f664406,a5f3edc2,0d856bc5,549cfaa5) Z8(03dddd0d,78940cdf,900c7b3b,444d21b8,9416c26f,0cb61af0,9d27218e,bc84d704) Z8(8aff03b1,b74a53eb,6bd545df,b9fba566,5f855c3d,748dcf48,99131457,9e8cf2fb) Z8(2e7351b6,a00f23b0,55e7927e,8a9d8be9,1d442a6a,5e982988,a1d6b849,36ac3852) Z8(887a8095,348c06bd,bbe82afc,4c41eb1a,3067d30f,a451cf48,5ecc3e13,500c58fa) Z8(0702f6df,363e1ae2,05336697,74d18ad0,7b91b34f,ecee20bc,cd31832c,81c31395) },{ Z8(644a5b7a,d54e5f0b,58172664,055d45c2,a30660ab,4355819f,62995fc5,48577a43) Z8(0c96f0bb,c48ec7a3,a657ed31,5b666192,59bb1769,380e76d9,7b1d8a02,2cce7c11) Z8(3de804c2,6bc40f1c,594e5cc5,64931cd1,20351026,742a07b1,b8f23c10,971f5f74) Z8(7474aa33,6dd1f749,f270abc2,3e3bb963,c9b1179b,6cafe989,a3fecb53,13e6b0e6) Z8(686c5b82,97e868cf,e8a69709,c812eaa7,04d6a234,a0b50542,412b9a9e,663d66e5) Z8(e898539b,297ad6c7,82338a1b,ddf423cc,8650503a,2c287f5a,29e582e6,59042c0d) Z8(38f82e17,a85406a9,bc9b15a1,e8d90ef4,003f0c18,727e85cf,47a29a63,ddaa3f7d) Z8(507a07bd,7a1c8d5c,53aa43c0,b43ed106,c05e9764,f05f9ec0,7e08c67d,98617342) Z8(418be56a,43e99e24,94c8455f,2b2ce5b1,185f4d79,0b87b7de,c3c61753,8e3b217f) Z8(ff0b33a3,5a0f0c4e,9954a97f,ea96cdf7,188a9aee,74dda751,76efd0e6,2bf76fac) Z8(470f72d6,4819d357,9e827f02,cfa52b18,283bb979,1fb47237,b9444b03,3074af1e) Z8(7fab6540,10a02e63,c253c1f8,490062e6,54e55650,4e7d22d5,e332410f,6f6b3e3a) Z8(3cf6417e,f29222fc,d047cb4d,625fa907,ec4b0a67,672a6456,2b70862a,241bf265) Z8(ff197dc1,b319f892,1af6cae9,9c0710f9,8946050a,78daa081,7d0a45ec,022908ef) Z8(e0ca1571,4e651f68,7e57768a,5d6bae01,d1fb166d,3df4d923,f3266ccd,704db470) Z8(6b1da9b1,ffdad025,24016f48,3fa8dc93,0644964c,3d4295e6,26e8f0ea,77cc8f7a) Z8(c0c4c470,b08a6de0,4e753411,2bfe9043,0a3f93af,2aea30ed,94122288,75291556) Z8(2dbbfd58,2fe48208,0ab1afbd,bf59fe83,13400594,d5b08a04,21c8f36b,81e38869) },{ Z8(d16674c1,1fc45418,70b145bc,d83df8ff,a3cf6778,ba2104ec,ae7f471c,a57d127f) Z8(508676b4,14963b4b,a47f2858,26965363,153a0051,c3be57f8,6408b5a7,2ea16d1e) Z8(ca695540,6b4a26fb,1b1c3809,b5da16ff,6bdff499,f774d8a8,43b67ab1,fcee0fc6) Z8(16573041,96421e83,ebde35fe,7e3e2ea8,46952e9b,34581df7,3aedc016,0c627da2) Z8(9cca9f9d,875a4a44,8674e0bb,66752056,01026b4a,05352d88,01f4cb81,c0bd2910) Z8(2320eb2d,2e342aaf,547c94a4,860f8b7d,136c2434,95aca993,11d6afbf,107a2453) Z8(9defd156,20a81825,765a42b8,061e2718,ecb2dafb,54dd3bdd,2f604396,e8b9ed53) Z8(bb8f191f,7742df31,467f5fc7,b4b14130,1e87eb61,9a6cfe89,df10cc82,633c803f) Z8(183d1fb4,3effc9c2,bcce8cf8,c9e3e3ee,cdfc7677,bb623a00,366dd0ef,2cb8c198) Z8(b94eac8b,cbf0108e,ae06bd64,3cffe2ec,6547d251,9d710f4f,ad591fb0,b1555ef2) Z8(4957efc9,071d4dfd,552035aa,f4c815bc,233f615f,46638da1,2d1bce3e,e4454e60) Z8(92476aa9,08b9d822,e3162676,3c691e29,5bc1a96b,212c98f3,dabbd643,d4f7b0a2) Z8(2d68d5e1,81002d0d,b4a6f876,05ec7e19,c4b75a76,a365f59f,26b5a4d9,a5bcdb24) Z8(5c00cfa5,e1a5595b,5ad30790,37963044,a3b59148,e090cca5,e1927066,265006c2) Z8(b8ae1f0d,a6b00339,38c43b0b,a2958699,4eedf015,2c697553,f353ffbe,75f95222) Z8(1d1dbaf8,5bb77ec2,11ce0e90,13386ad8,020e152f,0dacbe85,6a0a98f7,ff5a92e5) Z8(c5f3a3dc,73f545e0,3415b128,87330d08,9ab33afe,5993a7fc,8b7f018c,67380747) Z8(5ec2eb5c,835210e4,a313b765,b790820f,822735a2,5c3259f4,aef1c8bd,8204055a) },{ Z8(fdb38672,2beb4833,5bb41c60,a34ad856,01a926f2,6b3fcd6e,33c99129,415a345a) Z8(be853c81,937fc249,d80eafc4,4e9c911b,b807e7ac,0b3ff259,5a46b3e4,f64d713e) Z8(f4dff790,6dbbd9bd,cec370da,18ab1cb2,76acee5d,d4f11124,1f40d0b1,19ef40d3) Z8(376b3cd9,c0dd9c15,eb9698c4,34700413,c4a9f7c6,c9461372,921fd079,93acf5b0) Z8(d5887018,2a03e341,047de939,539ea136,abbe1307,b799e229,0d628357,06debc14) Z8(6eacf169,bd82960e,ad1098e4,0cf8d9c6,14aa8905,be84726a,651814b6,564a320b) Z8(8c0d28a2,fa642808,f232acf8,778af593,bd3fe252,cda7db55,2442a8b6,6fb35cf7) Z8(e63494c3,39a0c283,004a2fab,98a6b60f,146bb3b8,bff7cbf5,d6c9cee1,efdf9491) Z8(2912988a,08851904,9755f353,1ee6559c,f6a2c02a,5c3f5f73,e86a8bb5,964a0c55) Z8(0bf3cffe,da86b33e,a250a1f7,9a6f5d46,f5edbfd8,9b9f83b1,83e7a3d1,06f28697) Z8(e491529b,39391700,a0abfca5,a051c16a,433d05cc,fcdfec42,b51ed08d,b6ab962e) Z8(08d20fbd,e73f67af,d2d7c292,97e24dd3,5a6e4430,59642f9f,f8d12c75,d7f473f0) Z8(62bbab54,fa1abe8f,1c30d39e,eea7094d,07ee0e95,90eba736,96a75c85,7f6ec54d) Z8(0203eb4b,f71f6d5b,237443c7,9f2430ed,26d18a79,589e5298,bd2b2659,2ebff4fe) Z8(4f83574c,65ce3c36,078fbd92,6273cf32,831560cd,0299b487,6e514ddd,93fd55cd) Z8(4526652e,271744a2,a0e77dd8,dd7b028f,827729bb,1f05a407,04b7427c,6e129a69) Z8(429fec82,801ee10a,f6a9aac8,76e5c351,57aae403,7cc454b4,ecb75c28,5ff6a41f) Z8(db1d13b3,0935066f,201ac12c,d41e3f1e,ad10d664,21eb3356,7c7b1ea9,82248a6c) },{ Z8(21c50bc3,8c3e8e21,e1a11201,ebbfbdc3,0d35ece8,f20ccbf3,8c98022a,21a7a856) Z8(3d4b5ea1,6e1d2a4a,d659e91d,55aa0459,a42048fb,22458351,5fd2fccb,a480015c) Z8(6ffe5b2f,2c420ead,39e5f441,4c5a89d1,4b899739,3777042a,d0aec0ce,98107791) Z8(7c9f170f,344012e1,59e20536,22f12046,d3a410a5,464069f7,eedc72e4,4eb0e99f) Z8(81048ac5,4e8bf849,8f8ec237,5847883a,80f46a9a,2c242596,1f900e03,f690836e) Z8(ed3d12fe,3cf00394,004e9f21,64bd7275,28513c07,addb0971,e3e93c33,b01721bd) Z8(5a884e20,b1a56630,dca32bf1,57aaaae6,e5da1ae6,39b3d115,4cdddc30,0806989f) Z8(859129c1,752946b9,457fbd39,e6ff0508,e226850a,69be91b7,0d7f79d6,24f32968) Z8(da50be74,71eebebd,dc1bd182,8316a8a6,8e5382e9,5ea14cd3,7d34e98c,c667a4cd) Z8(2af65e23,2e317f40,746adb1f,bb078b3f,3fc9ec79,03c8276e,b32ab453,f809bc4c) Z8(c7f38b1b,b12720e9,29515f72,879be706,75fcb72a,b655507d,c45a94e4,926816d9) Z8(dfd0a304,5df02a1c,3e3645d7,3f99297e,d5000b64,b68259b1,1bc3622b,b86c1b29) Z8(0ee498ca,a0eec360,45a7351d,3acc7b37,c9a93c6d,bdd2e22c,a5fd43ec,5edea46b) Z8(c21b85c7,87344390,5b01076e,dde36644,5a6e6eb5,1297e062,da8c612d,bc4ddb06) Z8(f0ed37d2,8683f81c,d2ff0612,4d1099b1,85971d71,b1cc30af,402107b6,7f23589f) Z8(4f301e78,49615c0e,61f5c723,a78ced96,acef391d,30d8dc9f,f22c1f05,028c72db) Z8(e2e30744,ec068324,d03fd1ac,76691784,ace96036,bafe2ad1,555feb97,effd7135) Z8(d6d47369,e55bd24f,8b08e05f,0da8747a,c0313422,7db70ff8,92b614bd,824517a0) },{ Z8(3e773d17,edf5e690,9a37330a,2acc12df,0a907372,7388f12c,e7a41922,8857a695) Z8(57e7fecc,0b094566,19cc8db1,0e333739,07c5e468,218d021c,450ce036,70ef875c) Z8(42c3f8e7,bea7363c,0e3518e7,541b658f,a1ac6b95,ea6f3ba9,b6f2a4bf,46764eff) Z8(a30f6bc4,46d9f746,45a3b1f1,132a448a,e5f345c7,428504ec,a41e6c86,eccfaf88) Z8(c15caf04,19ae818a,57838a21,e983816b,c8c16ddc,796b3ca8,cf3c15a0,81100558) Z8(2ec1fe2c,23efaaaa,e79f2a8b,869ee81e,465eeb65,5bba71fe,c8779cd7,f98a3d2b) Z8(09e49c1a,c31b6adb,1bfaa582,a43c07cb,0e0897f9,8f451158,4619945e,8e92b854) Z8(705e55f9,f47ffbda,5b4e9122,0df68e78,6b193f36,b8dc02ad,c663a2a8,3e1aa720) Z8(8ee6881a,28d02705,28674865,932459b2,2f1bdb80,caaf7242,1f95f583,4c044c01) Z8(89ba9460,26630c17,b05c634c,207adb5c,0ce568a5,c23f5fde,10840ab9,e054c67a) Z8(32e4e333,481c96cb,e29bd222,78344cb7,589017da,04fea1ed,6337342e,6a6d2af9) Z8(12259a79,6cfdf755,7c922241,44cfd362,240de068,424f1f28,04980385,40d8bda2) Z8(8f3cece2,39dda308,d07731b2,3057910d,5cabbc15,ae74908f,88fd32d8,9470ece2) Z8(83432267,c27f4978,02e79d4a,42f58a03,b3c5ba95,21deba9d,2ec04c78,ac98040c) Z8(0218cf09,9a4ebfb2,1cc69ad8,c003b3dc,0a814256,2cf34132,969f4073,166c8be5) Z8(e8228347,11cd77c7,3022789b,4cadc159,5fa27a7f,12959880,87320a27,bbcaa038) Z8(5bac95e4,b88cc0c8,2ba5fbe3,763680d3,2b493129,70271c08,7eaa638b,709d69a0) Z8(dd02df39,df1da265,55f54621,fa774885,fc6b810d,8dfa8233,fa75ef14,8265acf8) },{ Z8(cfb6a4b7,79868402,dd0b4183,57ab98aa,307ea3c7,b1cd04c3,38b0250f,1565159b) Z8(138fa9e7,d98917f1,f294cf3d,750a0450,0266e7db,f952b9ec,ed196761,955301d8) Z8(46e7e8b8,02d57180,1f1417d1,b662177e,498f9098,460b029e,c713239c,8f49ae55) Z8(207c192b,53e44dc2,6c10c4c2,56631d8c,283d9202,347f878e,b666ebc0,19e2db81) Z8(965bc8cf,b4e50910,a17caa08,2c4d3efe,1e214ec1,011a76d0,de9015c0,f8ccf792) Z8(e3530687,6d173b8f,d1263d63,011f4615,397b979f,9904baaa,50d5b0df,cfa9ccc2) Z8(7484eaa2,83b58cd1,d464a65a,8dc5aa96,53c2ff5f,bebbc3b0,1e484214,486162dd) Z8(6980f5c2,9503b2db,32598ba2,e5da5e4d,f08d14b6,3e6b4318,4b3db22d,4a234613) Z8(60f230d6,1a3bc490,b5c67788,0ebdbd15,8c0cbf9a,f8218c41,c182e230,cef1090e) Z8(22550aa6,e84cf987,aab3f0ef,41930bbf,923a7859,0b23e0e4,1dfd3871,91e72774) Z8(a6e661df,112ffe98,7142ae71,7643bea6,02e6626a,529ac862,c35fa443,a4ee0a26) Z8(8710d918,a2827dda,5e50440c,56c6bf6d,d7976cd9,890a75c6,6386bdfb,575b581d) Z8(0ba10c08,fb2c4ee9,7a332bbb,53ae2485,394856f3,8ca8f664,2536bc28,8898dc3d) Z8(b310e0dd,6f185f89,d16861f3,2c1ced51,5aa60c53,fb8e929c,3ffe6029,0239390a) Z8(e3283544,d8d7011f,6b6f7f12,e968f51f,ed940fd8,498e3afa,333d89f5,a9f92576) Z8(839344f1,6e5a1eb7,4f4ed6d3,327b954b,d77698bc,0100a125,b18c0688,295f01bf) Z8(2aff18d3,8a31a8cd,bcf94f83,66a19fd1,42d9b6fe,41da9652,16a3dd96,1a75fc21) Z8(12a99dec,c67acf4e,181af4d3,277b532d,6f1fc743,6d0fbdc3,bd1036e1,82864a77) },{ Z8(ddf6d755,e4d98143,5ec1a861,6b369367,51a3a2bd,71feb549,b4f585e0,3e4af603) Z8(24855537,ac0a2d70,0ce3d6e2,5b7e5d08,2429e1c3,df135ffc,02961f0f,61e2a0dd) Z8(1e64a319,18ab7c59,1ff14ee8,907e6988,22c73999,d5b31998,9ac480ea,194398aa) Z8(6c99b7f9,535000e6,5b06f0af,e34458fc,7d625dfd,5eed6434,988a3e98,741689e0) Z8(897cb4c8,808c75b1,74dfc6a0,f0ba82a9,e2fad3a5,73b437c6,2f8555d1,d45f1e9f) Z8(744dce29,2a536caa,4cc95a8a,2cba0937,67b7fd18,916c2c14,072ae087,7b997ad3) Z8(b6146823,0e4c8340,794696d1,d142a9a6,1868d765,06a040b4,117e357c,0f60d2d4) Z8(3dfbc0b2,98f17a1a,47573957,ec6e4f6f,d515ea44,5831cc96,38a43956,b6004e38) Z8(10d99e20,43b0a8f5,cd6e6401,814d2920,2af06e7c,aa50f86e,df33795e,300531ed) Z8(00afdf7c,b75bc911,2139c83d,eb62bf54,afaa5402,eb8e6f13,bb730380,4daa0a1b) Z8(a830e4d6,5e5bb2c0,87b0e73e,5e856bd7,c9556ca8,decdcb73,50ccc014,70afba46) Z8(78e711db,72db03ab,e61da296,c186641e,362bb9aa,f39262aa,aef64d9b,833a0eb2) Z8(d7b20033,46b2e2c1,9f39e686,d1e58688,09b39e37,d8700cc9,9ee68d8a,62981a4f) Z8(a9f16297,6cace8e3,b2faa647,265a69f8,60ea4cd4,182fc2b1,1f414eac,2c9a532d) Z8(048138ef,4e500068,2c337898,095d1073,0b848d2a,c940f571,3b4007f2,3f787cf0) Z8(a6f97b1d,c01ded7e,ff1bf5bc,487557df,ac309e81,055b977f,8267aafe,3f28a6d4) Z8(5f34335e,a67e86fa,7c4f0aeb,7b51a154,6d94a7c4,edd97eaf,bbf4584e,2b954d25) Z8(aee04add,777733ab,730d2e1b,fd10c339,1b7f162b,8a053b35,e45cdb05,82a6f01e) },{ Z8(9e34a0e5,8e45316c,145b1d88,62b5e62a,82fbce12,de3840f4,e35de3a7,796743e3) Z8(ebdf75a6,86354660,0a862449,6ee64b13,184f2697,afa9fe7c,4e07ed8e,3627b59b) Z8(52bb4c61,504ffa38,3700f1cc,c424dc10,da6bb3b6,93abb790,3498b498,00aa8ad5) Z8(7ebade2a,60dc8b7b,a0551175,d55bca3d,04a255c3,d9a10dfc,3f9ebb66,9b913191) Z8(e6e3464b,eea61d97,9104aa7a,01df9cc7,fc13f975,99dbe485,7662b1e6,7d32a1d7) Z8(43479ba4,7de0efb5,82852a42,1e2e5c83,ac66f9aa,3c803982,a1d0f842,742d7098) Z8(90a3d729,fcb7d261,53ebcbee,e7fb86b2,9578b1f7,89632790,cc9f282a,c77922ef) Z8(88df3361,042deb9e,d4836f52,b45fc470,8349a661,85034e4b,beef064f,6f42975b) Z8(27c7c075,48b4d677,a852f205,1a89a9e2,f08f2517,982b56de,d4db0b07,d00fbf73) Z8(c42b2498,b0ec1a84,9ab08f9d,2286e67d,34429b26,b5e4d1f3,18cfcc46,d81b15fd) Z8(9b0794b8,2bf83ee3,9bff509c,d1917416,d3108b26,c3a4c0d1,1fd50966,727809b6) Z8(b0bf3c8d,64bb003b,62881a53,26d73bdc,aafd090e,9647ed58,51b2b0e9,f7800126) Z8(02f0f9e9,8aa0733d,28e3aa21,4f929c38,d40ac272,68721029,df6a8e28,9a5e372f) Z8(3576be30,c5c235bc,c44d86ff,0634547e,69dc2175,796e10b6,ba53cdb1,c87d17b2) Z8(0d008731,0166fa9a,1dabe1c2,05a53ed4,522dcd79,19417174,b0c77883,05fff956) Z8(77f38f97,d5994dd4,86032022,e0d52031,590ee22e,e670b2fe,75c019ab,d94cf216) Z8(cd4aaa03,2fe6b924,17ba3ff0,3abb9ae9,6c682b0a,504683c4,ebc85240,ef886d81) Z8(27f8a0ac,611a20a8,724def7f,cb17a122,36b9b9ef,27b74b84,7ab650ae,82c79df0) },{ Z8(9f715264,9972a371,5d4bbffb,7a82d0c5,a1fae488,53fe2822,250332c7,12b97f9e) Z8(c311069b,42172a47,6c395440,4092b214,f48d5c6d,08bcf068,02aa3405,6a381784) Z8(4f7a20c3,e64cba7e,747c1269,a53abc16,6df0a83b,d02a3ade,b9ab2684,d6eaaf8d) Z8(cf6a9b8c,43e41d53,aaedac06,66cfd836,83067c05,58b15cca,2e269c8c,0033e097) Z8(c960e09d,011c2126,f741b105,06a2a2ae,5068c9db,c2899b37,89db5786,b100fa9e) Z8(49557465,3c47cc42,ea6335cb,7540d371,a8a57c79,86c9fe04,b1577217,a67a701d) Z8(f53beb0b,09a08713,a8cd6c49,83ccb07b,40638038,1554ceb3,facf2b44,326a9ef8) Z8(6c3b601a,4ae1122f,7761bed0,2ec9cfdf,0c33bf6e,fd552f2e,165b63d9,c28ed506) Z8(c5b9d307,f8cc90ba,57245268,662110ac,58b5589a,b72f6333,2e9e3bb1,0e44e718) Z8(25f24108,3b405e5d,73448f43,34b596f5,ae3ca19a,692c6dc0,fcfdf3c5,af33f8ac) Z8(dd5589d7,fcebf18b,44565e00,020361dd,7fd7c944,99489a5f,d129eaf7,572d27f0) Z8(f33aca3b,86a6a777,047cc3ae,ac19b6da,878c189c,d765e51a,4491feaf,f02ee6ec) Z8(def28fb1,354a5570,c56fd08e,46aab18c,da2bec1c,006c89c1,2ef18f02,6a8fbf4e) Z8(c528001a,9b0a4292,77d124e2,4bc7ad22,4c8d38bf,c3729c40,452c5c87,9597e913) Z8(d54dc4e4,d4dc3e55,e552812c,2fd14e33,2081e22d,3cfb445b,c36d1f11,7172459e) Z8(70f4fc44,b271a394,d6e7d2e9,2965eef3,4c0de317,cbb43e06,97ca7899,15a8bdeb) Z8(314e9ce2,b4ab7ec9,1d815e30,afb761e4,205a7b1e,47de6859,e507a4a9,17833d99) Z8(0fecfc67,070bad1e,3b4d5cb5,ee149c78,c80bb990,044e73d0,8af9b3fa,82e853ee) },{ Z8(73d413c0,1f7ae3a4,7465c0d1,d85ff896,82ac87c1,ca95f0ae,9a0e974e,a2cf8b7b) Z8(9205133d,70d164fb,5cd8de28,2e81a632,1a9cf417,d777f8c9,dc03afb1,48d1e5c0) Z8(2752d29e,0ed2b6c8,fd1339de,bae71a1d,b53389e3,bb75cfce,5087e807,e446a3da) Z8(b0ae23ac,57afbb56,e60bd9f8,892a2ff4,5f36e9cf,05a77471,72687356,feb5700c) Z8(8d0377be,ebfa08aa,adbb7f5a,e0aea97d,37fa388b,74d2ee0b,08e60e8b,e86cf117) Z8(6f191153,a067b921,a2ca0879,5591ea0c,03c00a9b,13efb251,c8ecd6f4,69b3c825) Z8(4e81d490,b7481d78,7af2fe3d,8ea037a7,3c6be65a,d660397b,28af8be4,a7af5f53) Z8(42f4b91d,a43ae952,3fabbec3,e5f52d10,e9528fd4,fff9b9cb,a962dfb4,a622fbec) Z8(530fadd1,0011160c,144e5a8b,307cdabb,ea727153,d9b468cb,323e5e55,b689f138) Z8(cc9de433,6f322e7d,dd09e610,77ab3333,dc63db3d,3a346df4,fd40d479,6154e47e) Z8(9970326b,2d7b71c4,4b2168ca,4237fbb5,ee7e7fbe,9871cbc8,2c903f67,b25d78ca) Z8(95d9ce14,e2c17570,00735ae3,11b746ac,de90d49a,8dedd5b1,2dcf2605,20f10c0b) Z8(17af7c51,95bd9bdf,7fca9d79,45a03b9e,b43fa719,dc491d17,523a99b1,b7b59f58) Z8(05f6785e,cd97db3e,0591ff15,988ef51e,3617e492,8c484f33,133b7351,b74eab9f) Z8(bbb01b1a,afaca1cd,0b96ab99,0f0b9793,cb2e9683,86d0f570,5b6f9e63,222e2c7c) Z8(985e4c0b,4ef1bdca,a6ed00d9,86ac418e,d32506de,a3d2f307,bbbf864b,0c38e828) Z8(31ae8d90,71b06712,3048b19c,41ae308a,8b915b5a,6e3f14ae,271261f8,88ab6a8b) Z8(c8bf2dd3,173a4446,46104e0a,42bd2733,4adbb70d,2b2cebaf,2086e8a7,8309121b) },{ Z8(3f8c1df1,e4322c82,94a6483f,97ae87f3,ea89ccd3,610040b3,08ee1d83,390d58ce) Z8(1b053e8e,d32bcdfb,4f4e847b,06d91cdc,64c56d11,c3158e31,d1574064,944539ef) Z8(f8ef7352,ac8d28d8,4d3e8af2,38aecf89,291765a1,70ef1b6d,102d664f,59bb3eba) Z8(41d68f52,88d2d42c,7d7ddbf8,b1ab14e6,1aea0781,750e33c3,acd4c566,892e3925) Z8(110302c4,432eaf53,c21746c0,8ed70838,034ec83c,733f5327,efa8cf7e,60799031) Z8(b9d6bc2f,c3067ec1,5fa0ce80,2c52d965,0e0c2c4f,c109a004,f3173aad,3ead62c3) Z8(67b410a2,6f5959f9,9c721f9a,dd0a972b,d8565384,a90e780e,8f0d0709,9a3225ea) Z8(8a760ca1,cc19b08d,2687812c,389f1184,cfd447d0,17164516,c0baa1c5,f39f1f79) Z8(da652b2c,36b5dd25,9bd6afa3,b3dc511e,0a60a879,42abf824,02687364,0b50e4d4) Z8(6a703a69,306020a3,b5f21bc8,9465b928,3a2b8c92,162c334e,18692e26,2210d4e1) Z8(5a688353,11731406,a6488979,39e5785d,573733da,a9516a53,313f06e0,bc561397) Z8(aec0abb9,3211ad6a,0ab470f5,5a4d7b75,9a55dee8,16b241c3,99514d86,81793655) Z8(bbc0247b,127a5542,34ec3dce,c1a6a9fd,27ad1dff,9b95eda7,2654ff36,f42f9ec1) Z8(3dd6f891,5fbb500f,0e68477b,c73d801e,9dc26d66,13b9b242,e9ab98cf,3a023dc8) Z8(e92114de,6cb7b2ff,45ebf158,6aec3697,f1cc372c,ffed27c0,4701d314,8df1bf98) Z8(e845fd5b,77311012,663bb5a9,93cf0bb8,da38d0d2,c2aa570c,57324a12,c0999c31) Z8(3a5b6d14,bbf8c2e2,b5ba21a6,d36859be,7dcc8112,2675cf97,5a170b76,b165739b) Z8(f1070c4b,c64a4de6,838c37bb,2d051cd5,e3f800e1,f3561b31,4740bac8,8329d878) },{ Z8(c34eb12c,905e975e,127ca3b5,e234dcde,f8000483,773640d7,a5e657f5,0668391d) Z8(ac46031a,228f3da4,97e0eb8b,21ab198e,e86ca9e9,9852bfd4,975b4acc,81cac866) Z8(3f99d704,88256372,c493168e,c0d41eb8,fe9e0eb3,9407d438,59b1f289,a7467702) Z8(23a85c95,0b187e48,b47db0d4,54a7adec,27110129,8bc68e90,20a5ccf6,d26f9e99) Z8(4f32d150,8a7faff3,e4c921bf,1ef10b20,a2adc345,14e7f308,7c7dd77c,22b5e4b1) Z8(abc25196,052d6ad0,981a0055,034fc6a0,26ab493f,12ca3f77,aabcdf85,61253c29) Z8(a386e3bd,3e9dfbf2,528b1c95,1734209f,0fdecc2a,5cf85d9e,2f301463,ead330e4) Z8(ff80fd77,4329ffbf,be094b8b,1e6c163e,67c6478b,cb30bf55,8cd6b9ae,063d0e2b) Z8(f19ba52a,b1225cc7,d84b2bc0,1f53ef95,83fd8a3c,1777b7aa,a17a76a1,fb3cef0d) Z8(d1722162,863183f3,5263a314,9d0efb8f,574010e6,51ff61f0,947f6721,0cd353e0) Z8(6519bae1,b30d556b,71da75d5,d1120156,a48e6459,bd58c0f7,f08ef6dc,6a7722be) Z8(3938742d,74ca530c,130b800b,c2295540,2c8056b6,6592025d,14311f60,5d393b5b) Z8(831a1977,a892829b,3cfc046f,2303de25,e592056c,a4b3b3e1,96d940f2,c6c01fec) Z8(2ec5801b,46cb55a8,02f7eff5,037b792a,b78f86fa,09cc8011,4cde211c,3635f154) Z8(3bcd4bbb,0096cf1c,3084f14a,7a4957fd,de43ae23,7e3fb84f,57e3fe17,e0e8ba01) Z8(7b4121ad,4f3deace,4be99716,7a413e43,fd200b07,4dbe9978,fb5979c7,1d0544e1) Z8(04bd9cf5,053a80d2,e357ac36,e3143be3,d405dc9e,bc80b9b7,86c177cd,cc475afb) Z8(05136fed,b05103c1,8f0e13de,b1fbb029,5ba79cff,2c5b7894,0b8cff86,834aa708) },{ Z8(10840286,3344252e,c62725c7,fbc55b14,fa5072b6,7d68fa8c,3a0822e6,9ca0d28f) Z8(ee51e8b5,a454badb,1b89eaff,9e5d04a2,f4baa9e8,eb0b78f6,d95382c9,c76224b3) Z8(15a8a55a,5e053a74,f4f1072c,1f1ef6e7,fe91b150,6cf51e7b,ff45ccc0,67c7a0b7) Z8(664f174e,b3cedada,f02e0599,2e9c1b3f,67268103,07e82992,57ad2723,d2f204ba) Z8(85f67903,ccaf64f1,93de39c1,c36b9307,db95b313,b175e1b2,a623be7c,e659cf05) Z8(1f159e3b,9acb138a,d8448b76,2221e262,73090d86,6cd994ff,54e0dfc1,3f290c0c) Z8(2787b53e,57e66134,bd7fbcdd,7ed1d8a3,dbc81f2f,bf8756dc,38bfb7a3,f34e9651) Z8(616a8a4d,f7a97e47,5d803dcf,a559ef08,4dcf9dd8,f98effd6,0da29bc7,c9b65924) Z8(46ff5391,81c79f42,3804cfee,1369f16b,3b441aa4,c5385f68,b8901d61,a83102d6) Z8(7914b5cc,2ea4acc2,0dd3e939,364416ab,d2e84eef,2b8e000e,1457469c,fd9f7102) Z8(aa26647f,fdc15186,62322cb0,7ecd4175,377cc543,174ec0e8,56389e3e,1d56555e) Z8(740d707d,2cd606b1,2965ff8d,ffa0c334,2d01d6c0,0f17b9b8,8b979a2a,88b77400) Z8(cdee758d,c640d768,0f9d7005,d69d15aa,a14aa456,bcf6e661,4361a1d0,dd2df57d) Z8(1fb36886,128882f8,154bee83,2de36d34,49030bbb,9ec414d7,9d4d7b7b,55ee77a4) Z8(757c4992,b1f8c839,43f1570f,f6f832f2,f1688e13,52f077af,95e8c092,1bbf64a0) Z8(84c38992,7fbbb6fb,63759b1d,f6d3dbeb,5eec379a,95fba491,c96e64e8,cde4e7d3) Z8(f6019f17,65ffbbfa,a7c65176,b0bd9b51,2a7f9aee,a1a8b2f2,76b7ddfb,96a6b277) Z8(1d28664e,394cf091,ce2e513f,0e041143,64edccbd,7bdaa85c,7a54b5df,836b7dcc) },{ Z8(de41663a,99ebab9e,a6ac30df,d06c8e5c,9f4bdb0c,36098828,754bc75a,654c728f) Z8(d3b735cb,4f1f7f10,4952b0d6,74f2031f,0ef0700f,91d0812b,3bab0ed3,203a54b4) Z8(b9fe8670,d483f6c2,fab02170,9c894aca,90833137,7cfd9ac6,891a7f91,ab90b004) Z8(e43818f5,d2965197,fe34ef38,a46dd584,bb9a7588,93635323,af40f0d1,ec72ff86) Z8(cdada7de,e6d77f3a,8f1ac358,330d9994,d9012617,d9026dea,91641d65,5c7c8778) Z8(cbc6a1b9,e02af9c6,33b8aee9,78269a91,8bff3930,bd4b644e,ce20e423,f3bf8bc5) Z8(815975d4,cdec5ac1,6181f6ff,a87eeff6,715fa20f,f3dbcfba,1e70d689,9f48653b) Z8(428c9366,5f550b5f,726a4ff6,75671b0a,29aff8d4,034c6e1a,40369684,bf9bfb51) Z8(40fa121c,c9e0f6e5,7180d3a6,639abb6b,affccb58,d35a2cc0,37b621fd,4b6dce9d) Z8(ea9820e0,fc53df1c,a9163ad0,4de0c220,3c3f5aaa,9f40d5bd,9e0047f2,beb6f5ff) Z8(382c983a,ec2b7ead,df9af3e0,a91aea59,ca7e6b6e,21e3bf08,04e9b52a,2395a6d3) Z8(b86c0de0,a53aa038,101a324c,055b0d93,cf396c79,07bddc64,4e63f0d0,25bd4763) Z8(1b8aeb13,554a0c62,e4b5c2df,4ef3a8c4,48a43578,f0c6b8d4,5efe56c6,5224d534) Z8(b616f25a,ecd8dfa7,4773c333,5e2336f8,7b17b005,7a0c4566,a5c5c63a,c3ac242f) Z8(570fd17c,f1e1d9b3,c7da6177,dfa9a67a,c681fc71,fcc4ff78,7d3f729b,c94ced0b) Z8(59b3da90,b00249ee,870dbe26,044679c6,78f3b93a,13d691d1,12faab31,531a9fe9) Z8(b08d6622,76f0ab8c,58614061,045cf4ca,0746e9f4,dab69d5e,fa9674f0,8a9a605e) Z8(0ba1fc43,a77c428f,30830a66,3f64c60c,cf3484c2,ed9945c8,a104277d,838c5cc7) },{ Z8(670b6f10,dbc446dd,d3954564,eb1122e2,bc7f17b6,e04ab0e4,c8c9e19b,b10c5e44) Z8(05d5920a,fcb4ea0a,8a18441f,e5e98b1f,7062ff81,96a76cea,85196240,d1801f17) Z8(e477b581,0012a52a,5993c8d3,4f1d0cf7,b84ef443,de5df3d7,75bfae21,a4695f77) Z8(77223e50,d7858f4e,9c2ea463,873eb49b,b9dc7b95,949515b1,fce9102d,fe909358) Z8(1ce16e0b,c5322b1f,250bb958,4d3f7c5e,0041bbfd,5f498731,13e877b5,b7c836ae) Z8(5e32e0b3,2adf7bb2,c8b941df,26b88261,a06b4fc7,dcc9b37c,edbf19ba,e2c0aa44) Z8(8a90f2f5,12e9a338,e2e061bd,20c49b13,72c9f7e2,3bac46e2,11c5e32a,8be03cfa) Z8(9a75f681,6d54be1c,811efadc,8ee37b5d,254b880b,6b28d48c,16d55b9d,5426affc) Z8(6e8c9949,b54ac27f,780a3017,99fa1cac,7e88716e,a8eb803d,66381ce4,f5782a33) Z8(f80f0163,01385e91,a51888d4,f6319343,fd6aeb59,d4e8b19e,865e46f9,2a6b2c64) Z8(129cb795,b3d73a67,cb148868,c219b304,df5cc89b,3df449b7,6508b16d,4468435e) Z8(511203a4,47a40d3d,182e9cc6,6a63a0c0,d67ecfe6,fd101365,7a76c65c,8b4f4de7) Z8(76469065,a732e2bd,23a0e573,b4c0da5c,3791a7f9,50602810,9fe9839e,3e0d053e) Z8(b793c856,a26daf3a,0d124ee1,cd80439a,9e5f1556,1ac73bf8,03f534ff,ca68f1d6) Z8(00c0a4ef,5dafece0,1e90086d,f5483978,f625ba36,a5f78e71,9aa514db,5f4738e9) Z8(f46fd33b,003bfff4,6bb9cdbf,4ef637b6,cc3b93a0,1e357509,7a71463f,04758447) Z8(7d17438a,b33ce5e8,0f41c670,4a4cfb89,a9867bac,7aaa01f4,d66c8f57,2153dcb0) Z8(aea6dd81,4a153cb2,2f3c452a,7aed07ea,1ac6253f,b84b3c94,8d8b0989,83ad43fb) },{ Z8(15f79984,82e633cf,42fdc5ff,daf04198,d677761e,9bf9da32,aa495f79,bb45a080) Z8(1862e2d4,e37bea61,2f78ec3e,d48fea60,728257c0,66c0bd11,3e551602,ce8aeb6a) Z8(3f27cd8e,39e1af4a,6380535c,d0271f82,3fe19e7c,ab0a5467,693e8deb,c39435fe) Z8(16982fce,4468bf44,af704a39,8e77d97b,c3e46abe,52faffc0,6269fa1a,36e0f307) Z8(43f90176,dc3b5d52,641915a4,62844894,2d09adb2,5f48b72e,cb2d9e47,196ec667) Z8(272527b5,2847c160,ceb2c6da,a3122105,2fc9e25d,6b6517f8,42178292,1a2e34a0) Z8(b675b8a7,5da754e3,91a07155,71f1f29c,b37e91d4,9ea78fcb,df5201fc,ed7dbc76) Z8(161348bb,709f41c7,394c7f1a,f19950e4,34356def,cb64e1b9,368a6967,d9c64ee2) Z8(c766e14a,2a415c73,76ea0ee8,6fd4ae07,a975e709,6d0f1884,889fbf08,5fc4fdf6) Z8(cbfaadef,1cf057f9,a0948ffb,1d4af9b1,a41090b9,4ee66a5e,9dc96ae2,b6fcba5a) Z8(fc4d3696,fdeaaf7a,108d77f6,670adff6,0337411b,ec968529,00d69769,6baa9ef2) Z8(f8842548,79c1ad91,3c5ce97e,3bb4ff1b,07931255,5a37e1c2,12f7c7ce,46050794) Z8(457fd26f,3803f4a7,29f9d8dd,ad6c4e5d,f8432d51,79d77b93,673b83b6,b23f682d) Z8(504d71e3,9841f102,b00446a1,9fdea7f9,ae5b7d29,780c0eb4,1811851f,c981e0fb) Z8(05cdddcb,4766e0e8,9abff3f9,f1ee1b24,38a11570,bc8aa198,2c8e9bf3,de798f84) Z8(9422f785,b11e300e,83a93790,e6a38105,36b7cbcc,fe581a20,46bcd3e6,cd3c6130) Z8(c33732f1,e32670a7,fa9542b2,c885dba8,638b96bf,0cd6f265,48f34e84,6f8a790d) Z8(e4cf116e,f92cd86c,1ea56221,98c33887,924302f7,39112059,4e5c9d89,83ce336a) },{ Z8(980a6d14,45b265b0,927d1ebf,982633ab,0bad903f,f824647c,64791718,feb25b07) Z8(ba9e2173,313f6ad2,215fb159,cb53805a,54f4c674,ad2e7ab8,f2e583dd,d5af9385) Z8(6db3c27c,60919709,a0a1dfd5,39ef44d9,ca194999,ee7f2d59,bf910ca2,09a3bccd) Z8(310d9f7e,76560e3e,14d0d050,f88e67b4,1376e14a,e2d058a3,fa9f3a4a,474edff1) Z8(a7d74daf,6c637128,3b5a3115,19aadb37,b8eedc41,acb2f943,9ea33b84,4f465104) Z8(af96a84f,acdb6210,78723e4a,6cdd9743,bf97656f,4e1b63b3,bb475cd6,324fe765) Z8(f9fe83f1,5a58c09a,583b8ab1,666b63e2,f04b3a5f,962a18a5,11aec1e8,15814857) Z8(cbeaeff9,d0deccf3,336aed3d,f5cd32b9,54c0561a,5cd6723f,dc69ba6a,f0f161df) Z8(2b718884,a6b416d0,3465bdae,151de167,f023c71c,88deaf97,e1d438d2,f81f4c9e) Z8(001bf582,01c3d0a5,a163750d,259d7c59,32f3629c,2e48b09d,4610b706,cc2ad7c5) Z8(bc19d6d0,a8f8bf96,30ec3190,9bbc4bda,98576ff0,c630dc4b,128f36c8,0cb87b4a) Z8(81b78882,119850ab,33d3ae36,4e85426e,8a84d83d,063d0e81,f4a8357f,a01196df) Z8(7b0bba13,09ae65c6,986ad834,fd0535e5,8d108d10,bc9c5cc0,103ecbff,fbe03879) Z8(41643aa5,d2eb49c4,661cce39,bcf3134f,4131119e,57c0ea21,9b8fac86,1cc07da2) Z8(3229416d,ec45cad3,121f4b23,386b4f13,5c1236be,8d8e84d5,ceaa823a,f87d396a) Z8(3b8f3b04,b98d2785,6b39013d,414a26e1,6e4708c0,1582cd67,680379f4,c750387f) Z8(3ff6a04e,fac0f617,19c31758,9c3d1729,51d3f338,bc414a7f,2a31b689,90223629) Z8(0d371e0d,232759e7,95cc9009,6f7c685d,8bc8b40e,27bc7157,f26fd248,83ef2b15) }}; arb-2.22.1/arb/exp_taylor_bound.c000066400000000000000000000054061417376376500166570ustar00rootroot00000000000000/* Copyright (C) 2013, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define TABSIZE 256 /* bounds for log2(1/n!) */ static const short rec_fac_bound_2exp_si_tab[TABSIZE] = { 0, 0, -1, -2, -4, -6, -9, -12, -15, -18, -21, -25, -28, -32, -36, -40, -44, -48, -52, -56, -61, -65, -69, -74, -79, -83, -88, -93, -97, -102, -107, -112, -117, -122, -127, -132, -138, -143, -148, -153, -159, -164, -169, -175, -180, -186, -191, -197, -202, -208, -214, -219, -225, -231, -237, -242, -248, -254, -260, -266, -272, -278, -284, -289, -295, -302, -308, -314, -320, -326, -332, -338, -344, -350, -357, -363, -369, -375, -382, -388, -394, -401, -407, -413, -420, -426, -433, -439, -446, -452, -458, -465, -472, -478, -485, -491, -498, -504, -511, -518, -524, -531, -538, -544, -551, -558, -564, -571, -578, -585, -591, -598, -605, -612, -619, -626, -632, -639, -646, -653, -660, -667, -674, -681, -688, -695, -702, -709, -716, -723, -730, -737, -744, -751, -758, -765, -772, -779, -786, -793, -801, -808, -815, -822, -829, -836, -844, -851, -858, -865, -872, -880, -887, -894, -901, -909, -916, -923, -931, -938, -945, -952, -960, -967, -975, -982, -989, -997, -1004, -1011, -1019, -1026, -1034, -1041, -1049, -1056, -1064, -1071, -1078, -1086, -1093, -1101, -1108, -1116, -1123, -1131, -1139, -1146, -1154, -1161, -1169, -1176, -1184, -1192, -1199, -1207, -1214, -1222, -1230, -1237, -1245, -1253, -1260, -1268, -1276, -1283, -1291, -1299, -1306, -1314, -1322, -1329, -1337, -1345, -1353, -1360, -1368, -1376, -1384, -1391, -1399, -1407, -1415, -1423, -1430, -1438, -1446, -1454, -1462, -1470, -1477, -1485, -1493, -1501, -1509, -1517, -1525, -1532, -1540, -1548, -1556, -1564, -1572, -1580, -1588, -1596, -1604, -1612, -1620, -1628, -1636, -1644, -1652, -1660, -1668, -1675 }; static __inline__ slong rec_fac_bound_2exp_si(slong n) { if (n < TABSIZE) { return rec_fac_bound_2exp_si_tab[n]; } else { mag_t t; mag_init(t); mag_rfac_ui(t, n); /* todo: check for overflow */ return MAG_EXP(t); } } slong _arb_exp_taylor_bound(slong mag, slong prec) { slong i; /* assume x <= 1/4 */ if (mag > -2) { flint_printf("_arb_exp_taylor_bound: too large input %wd\n", mag); flint_abort(); } for (i = 1; ; i++) { if (mag * i + rec_fac_bound_2exp_si(i) < -prec - 1) return i; } } arb-2.22.1/arb/exp_taylor_naive.c000066400000000000000000000025661417376376500166560ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_exp_taylor_naive(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N) { ulong k; mp_ptr s, t, u, v; mp_size_t nn = xn + 1; if (N == 0) { flint_mpn_zero(y, xn + 1); error[0] = 0; return; } s = flint_malloc(sizeof(mp_limb_t) * (nn + 1)); t = flint_malloc(sizeof(mp_limb_t) * nn); v = flint_malloc(sizeof(mp_limb_t) * nn); u = flint_malloc(sizeof(mp_limb_t) * 2 * nn); /* s = 1 */ flint_mpn_zero(s, nn); s[nn] = 1; /* t = v = x */ flint_mpn_zero(t, nn); flint_mpn_copyi(t + 1, x, xn); flint_mpn_copyi(v, t, nn); for (k = 1; k < N; k++) { s[nn] += mpn_add_n(s, s, t, nn); /* t = t * x / (k + 1) */ mpn_mul_n(u, t, v, nn); flint_mpn_copyi(t, u + nn, nn); mpn_divrem_1(t, 0, t, nn, k + 1); } flint_mpn_copyi(y, s + 1, xn + 1); error[0] = 2; flint_free(s); flint_free(t); flint_free(u); flint_free(v); } arb-2.22.1/arb/exp_taylor_rs.c000066400000000000000000000742241417376376500162000ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* See verify_taylor.py for code to generate tables and proof of correctness */ #define TMP_ALLOC_LIMBS(size) TMP_ALLOC((size) * sizeof(mp_limb_t)) #define FACTORIAL_TAB_SIZE 288 #if FLINT_BITS == 64 ARB_DLL const mp_limb_t factorial_tab_numer[FACTORIAL_TAB_SIZE] = { UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(1216451004088320000), UWORD(405483668029440000), UWORD(101370917007360000), UWORD(20274183401472000), UWORD(3379030566912000), UWORD(482718652416000), UWORD(60339831552000), UWORD(6704425728000), UWORD(670442572800), UWORD(60949324800), UWORD(5079110400), UWORD(390700800), UWORD(27907200), UWORD(1860480), UWORD(116280), UWORD(6840), UWORD(380), UWORD(20), UWORD(1), UWORD(169958063987712000), UWORD(7725366544896000), UWORD(335885501952000), UWORD(13995229248000), UWORD(559809169920), UWORD(21531121920), UWORD(797448960), UWORD(28480320), UWORD(982080), UWORD(32736), UWORD(1056), UWORD(33), UWORD(1), UWORD(405179306820288000), UWORD(11576551623436800), UWORD(321570878428800), UWORD(8691104822400), UWORD(228713284800), UWORD(5864443200), UWORD(146611080), UWORD(3575880), UWORD(85140), UWORD(1980), UWORD(45), UWORD(1), UWORD(129210868410624000), UWORD(2749167412992000), UWORD(57274321104000), UWORD(1168863696000), UWORD(23377273920), UWORD(458377920), UWORD(8814960), UWORD(166320), UWORD(3080), UWORD(56), UWORD(1), UWORD(13431688016947200), UWORD(231580827878400), UWORD(3925098777600), UWORD(65418312960), UWORD(1072431360), UWORD(17297280), UWORD(274560), UWORD(4290), UWORD(66), UWORD(1), UWORD(51698307350592000), UWORD(760269225744000), UWORD(11018394576000), UWORD(157405636800), UWORD(2216980800), UWORD(30791400), UWORD(421800), UWORD(5700), UWORD(76), UWORD(1), UWORD(166872705665702400), UWORD(2139393662380800), UWORD(27080932435200), UWORD(338511655440), UWORD(4179156240), UWORD(50965320), UWORD(614040), UWORD(7310), UWORD(86), UWORD(1), UWORD(4900933563926400), UWORD(55692426862800), UWORD(625757605200), UWORD(6952862280), UWORD(76405080), UWORD(830490), UWORD(8930), UWORD(95), UWORD(1), UWORD(10385445095625600), UWORD(107066444284800), UWORD(1092514737600), UWORD(11035502400), UWORD(110355024), UWORD(1092624), UWORD(10712), UWORD(104), UWORD(1), UWORD(20632508204394240), UWORD(194646303815040), UWORD(1819124334720), UWORD(16843743840), UWORD(154529760), UWORD(1404816), UWORD(12656), UWORD(113), UWORD(1), UWORD(38823716505974400), UWORD(337597534834560), UWORD(2910323576160), UWORD(24874560480), UWORD(210801360), UWORD(1771440), UWORD(14762), UWORD(122), UWORD(1), UWORD(69746158460160000), UWORD(562469019840000), UWORD(4499752158720), UWORD(35712318720), UWORD(281199360), UWORD(2196870), UWORD(17030), UWORD(131), UWORD(1), UWORD(120384786168259200), UWORD(905148768182400), UWORD(6754841553600), UWORD(50035863360), UWORD(367910760), UWORD(2685480), UWORD(19460), UWORD(140), UWORD(1), UWORD(1346749373249280), UWORD(9484150515840), UWORD(66322730880), UWORD(460574520), UWORD(3176376), UWORD(21756), UWORD(148), UWORD(1), UWORD(1961463552048000), UWORD(13076423680320), UWORD(86598832320), UWORD(569729160), UWORD(3723720), UWORD(24180), UWORD(156), UWORD(1), UWORD(2802505908948480), UWORD(17737379170560), UWORD(111555843840), UWORD(697224024), UWORD(4330584), UWORD(26732), UWORD(164), UWORD(1), UWORD(3935446603320960), UWORD(23707509658560), UWORD(141961135680), UWORD(845006760), UWORD(5000040), UWORD(29412), UWORD(172), UWORD(1), UWORD(5440248896544000), UWORD(31265798256000), UWORD(178661704320), UWORD(1015123320), UWORD(5735160), UWORD(32220), UWORD(180), UWORD(1), UWORD(7413519413139840), UWORD(40733623149120), UWORD(222588104640), UWORD(1209717960), UWORD(6539016), UWORD(35156), UWORD(188), UWORD(1), UWORD(9970981685683200), UWORD(52478850977280), UWORD(274758382080), UWORD(1431033240), UWORD(7414680), UWORD(38220), UWORD(196), UWORD(1), UWORD(13250183553129600), UWORD(66920118955200), UWORD(336282004800), UWORD(1681410024), UWORD(8365224), UWORD(41412), UWORD(204), UWORD(1), UWORD(17413448982209280), UWORD(84531305738880), UWORD(408363795840), UWORD(1963287480), UWORD(9393720), UWORD(44732), UWORD(212), UWORD(1), UWORD(22651084881532800), UWORD(105846191035200), UWORD(492307865280), UWORD(2279203080), UWORD(10503240), UWORD(48180), UWORD(220), UWORD(1), UWORD(29184853478054400), UWORD(131463303955200), UWORD(589521542400), UWORD(2631792600), UWORD(11696856), UWORD(51756), UWORD(228), UWORD(1), UWORD(37271720825539200), UWORD(162050960111040), UWORD(701519307840), UWORD(3023790120), UWORD(12977640), UWORD(55460), UWORD(236), UWORD(1), UWORD(47207892014680320), UWORD(198352487456640), UWORD(829926725760), UWORD(3458028024), UWORD(14348664), UWORD(59292), UWORD(244), UWORD(1), UWORD(59333143654512000), UWORD(241191640872000), UWORD(976484376000), UWORD(3937437000), UWORD(15813000), UWORD(63252), UWORD(252), UWORD(1), UWORD(284751785364480), UWORD(1121070021120), UWORD(4396353024), UWORD(17173254), UWORD(66822), UWORD(259), UWORD(1), UWORD(334679402201760), UWORD(1282296560160), UWORD(4894261680), UWORD(18609360), UWORD(70490), UWORD(266), UWORD(1), UWORD(391698294099840), UWORD(1461560798880), UWORD(5433311520), UWORD(20123376), UWORD(74256), UWORD(273), UWORD(1), UWORD(456592291848000), UWORD(1660335606720), UWORD(6015708720), UWORD(21717360), UWORD(78120), UWORD(280), UWORD(1), UWORD(530208485286480), UWORD(1880171933640), UWORD(6643717080), UWORD(23393370), UWORD(82082), UWORD(287), UWORD(1), }; ARB_DLL const mp_limb_t factorial_tab_denom[FACTORIAL_TAB_SIZE] = { UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(2432902008176640000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(3569119343741952000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(13776096431889792000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(5943699946888704000), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(765606216965990400), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(3463786592489664000), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(12849198336259084800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(426381220061596800), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(997002729180057600), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(2166413361461395200), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(4425903681681081600), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(8578777490599680000), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(15890791774210214400), UWORD(189891661628148480), UWORD(189891661628148480), UWORD(189891661628148480), UWORD(189891661628148480), UWORD(189891661628148480), UWORD(189891661628148480), UWORD(189891661628148480), UWORD(189891661628148480), UWORD(292258069255152000), UWORD(292258069255152000), UWORD(292258069255152000), UWORD(292258069255152000), UWORD(292258069255152000), UWORD(292258069255152000), UWORD(292258069255152000), UWORD(292258069255152000), UWORD(439993427704911360), UWORD(439993427704911360), UWORD(439993427704911360), UWORD(439993427704911360), UWORD(439993427704911360), UWORD(439993427704911360), UWORD(439993427704911360), UWORD(439993427704911360), UWORD(649348689547958400), UWORD(649348689547958400), UWORD(649348689547958400), UWORD(649348689547958400), UWORD(649348689547958400), UWORD(649348689547958400), UWORD(649348689547958400), UWORD(649348689547958400), UWORD(941163059102112000), UWORD(941163059102112000), UWORD(941163059102112000), UWORD(941163059102112000), UWORD(941163059102112000), UWORD(941163059102112000), UWORD(941163059102112000), UWORD(941163059102112000), UWORD(1341847013778311040), UWORD(1341847013778311040), UWORD(1341847013778311040), UWORD(1341847013778311040), UWORD(1341847013778311040), UWORD(1341847013778311040), UWORD(1341847013778311040), UWORD(1341847013778311040), UWORD(1884515538594124800), UWORD(1884515538594124800), UWORD(1884515538594124800), UWORD(1884515538594124800), UWORD(1884515538594124800), UWORD(1884515538594124800), UWORD(1884515538594124800), UWORD(1884515538594124800), UWORD(2610286159966531200), UWORD(2610286159966531200), UWORD(2610286159966531200), UWORD(2610286159966531200), UWORD(2610286159966531200), UWORD(2610286159966531200), UWORD(2610286159966531200), UWORD(2610286159966531200), UWORD(3569757041352902400), UWORD(3569757041352902400), UWORD(3569757041352902400), UWORD(3569757041352902400), UWORD(3569757041352902400), UWORD(3569757041352902400), UWORD(3569757041352902400), UWORD(3569757041352902400), UWORD(4824681079766486400), UWORD(4824681079766486400), UWORD(4824681079766486400), UWORD(4824681079766486400), UWORD(4824681079766486400), UWORD(4824681079766486400), UWORD(4824681079766486400), UWORD(4824681079766486400), UWORD(6449852618650022400), UWORD(6449852618650022400), UWORD(6449852618650022400), UWORD(6449852618650022400), UWORD(6449852618650022400), UWORD(6449852618650022400), UWORD(6449852618650022400), UWORD(6449852618650022400), UWORD(8535224069048476800), UWORD(8535224069048476800), UWORD(8535224069048476800), UWORD(8535224069048476800), UWORD(8535224069048476800), UWORD(8535224069048476800), UWORD(8535224069048476800), UWORD(8535224069048476800), UWORD(11188270407479235840), UWORD(11188270407479235840), UWORD(11188270407479235840), UWORD(11188270407479235840), UWORD(11188270407479235840), UWORD(11188270407479235840), UWORD(11188270407479235840), UWORD(11188270407479235840), UWORD(14536620195355440000), UWORD(14536620195355440000), UWORD(14536620195355440000), UWORD(14536620195355440000), UWORD(14536620195355440000), UWORD(14536620195355440000), UWORD(14536620195355440000), UWORD(14536620195355440000), UWORD(72042201697213440), UWORD(72042201697213440), UWORD(72042201697213440), UWORD(72042201697213440), UWORD(72042201697213440), UWORD(72042201697213440), UWORD(72042201697213440), UWORD(87016644572457600), UWORD(87016644572457600), UWORD(87016644572457600), UWORD(87016644572457600), UWORD(87016644572457600), UWORD(87016644572457600), UWORD(87016644572457600), UWORD(104583444524657280), UWORD(104583444524657280), UWORD(104583444524657280), UWORD(104583444524657280), UWORD(104583444524657280), UWORD(104583444524657280), UWORD(104583444524657280), UWORD(125106287966352000), UWORD(125106287966352000), UWORD(125106287966352000), UWORD(125106287966352000), UWORD(125106287966352000), UWORD(125106287966352000), UWORD(125106287966352000), UWORD(148988584365500880), UWORD(148988584365500880), UWORD(148988584365500880), UWORD(148988584365500880), UWORD(148988584365500880), UWORD(148988584365500880), UWORD(148988584365500880), }; #else ARB_DLL const mp_limb_t factorial_tab_numer[FACTORIAL_TAB_SIZE] = { UWORD(479001600), UWORD(479001600), UWORD(239500800), UWORD(79833600), UWORD(19958400), UWORD(3991680), UWORD(665280), UWORD(95040), UWORD(11880), UWORD(1320), UWORD(132), UWORD(12), UWORD(1), UWORD(19535040), UWORD(1395360), UWORD(93024), UWORD(5814), UWORD(342), UWORD(19), UWORD(1), UWORD(165765600), UWORD(7893600), UWORD(358800), UWORD(15600), UWORD(650), UWORD(26), UWORD(1), UWORD(24165120), UWORD(863040), UWORD(29760), UWORD(992), UWORD(32), UWORD(1), UWORD(60233040), UWORD(1771560), UWORD(50616), UWORD(1406), UWORD(38), UWORD(1), UWORD(2961840), UWORD(74046), UWORD(1806), UWORD(43), UWORD(1), UWORD(4669920), UWORD(103776), UWORD(2256), UWORD(48), UWORD(1), UWORD(7027800), UWORD(140556), UWORD(2756), UWORD(53), UWORD(1), UWORD(10182480), UWORD(185136), UWORD(3306), UWORD(58), UWORD(1), UWORD(14295960), UWORD(238266), UWORD(3906), UWORD(63), UWORD(1), UWORD(19545240), UWORD(300696), UWORD(4556), UWORD(68), UWORD(1), UWORD(26122320), UWORD(373176), UWORD(5256), UWORD(73), UWORD(1), UWORD(34234200), UWORD(456456), UWORD(6006), UWORD(78), UWORD(1), UWORD(44102880), UWORD(551286), UWORD(6806), UWORD(83), UWORD(1), UWORD(635970), UWORD(7482), UWORD(87), UWORD(1), UWORD(728910), UWORD(8190), UWORD(91), UWORD(1), UWORD(830490), UWORD(8930), UWORD(95), UWORD(1), UWORD(941094), UWORD(9702), UWORD(99), UWORD(1), UWORD(1061106), UWORD(10506), UWORD(103), UWORD(1), UWORD(1190910), UWORD(11342), UWORD(107), UWORD(1), UWORD(1330890), UWORD(12210), UWORD(111), UWORD(1), UWORD(1481430), UWORD(13110), UWORD(115), UWORD(1), UWORD(1642914), UWORD(14042), UWORD(119), UWORD(1), UWORD(1815726), UWORD(15006), UWORD(123), UWORD(1), UWORD(2000250), UWORD(16002), UWORD(127), UWORD(1), UWORD(2196870), UWORD(17030), UWORD(131), UWORD(1), UWORD(2405970), UWORD(18090), UWORD(135), UWORD(1), UWORD(2627934), UWORD(19182), UWORD(139), UWORD(1), UWORD(2863146), UWORD(20306), UWORD(143), UWORD(1), UWORD(3111990), UWORD(21462), UWORD(147), UWORD(1), UWORD(3374850), UWORD(22650), UWORD(151), UWORD(1), UWORD(3652110), UWORD(23870), UWORD(155), UWORD(1), UWORD(3944154), UWORD(25122), UWORD(159), UWORD(1), UWORD(4251366), UWORD(26406), UWORD(163), UWORD(1), UWORD(4574130), UWORD(27722), UWORD(167), UWORD(1), UWORD(4912830), UWORD(29070), UWORD(171), UWORD(1), UWORD(5267850), UWORD(30450), UWORD(175), UWORD(1), UWORD(5639574), UWORD(31862), UWORD(179), UWORD(1), UWORD(6028386), UWORD(33306), UWORD(183), UWORD(1), UWORD(6434670), UWORD(34782), UWORD(187), UWORD(1), UWORD(6858810), UWORD(36290), UWORD(191), UWORD(1), UWORD(7301190), UWORD(37830), UWORD(195), UWORD(1), UWORD(7762194), UWORD(39402), UWORD(199), UWORD(1), UWORD(8242206), UWORD(41006), UWORD(203), UWORD(1), UWORD(8741610), UWORD(42642), UWORD(207), UWORD(1), UWORD(9260790), UWORD(44310), UWORD(211), UWORD(1), UWORD(9800130), UWORD(46010), UWORD(215), UWORD(1), UWORD(10360014), UWORD(47742), UWORD(219), UWORD(1), UWORD(10940826), UWORD(49506), UWORD(223), UWORD(1), UWORD(11542950), UWORD(51302), UWORD(227), UWORD(1), UWORD(12166770), UWORD(53130), UWORD(231), UWORD(1), UWORD(12812670), UWORD(54990), UWORD(235), UWORD(1), UWORD(13481034), UWORD(56882), UWORD(239), UWORD(1), UWORD(14172246), UWORD(58806), UWORD(243), UWORD(1), UWORD(14886690), UWORD(60762), UWORD(247), UWORD(1), UWORD(15624750), UWORD(62750), UWORD(251), UWORD(1), UWORD(16386810), UWORD(64770), UWORD(255), UWORD(1), UWORD(66306), UWORD(258), UWORD(1), UWORD(67860), UWORD(261), UWORD(1), UWORD(69432), UWORD(264), UWORD(1), UWORD(71022), UWORD(267), UWORD(1), UWORD(72630), UWORD(270), UWORD(1), UWORD(74256), UWORD(273), UWORD(1), UWORD(75900), UWORD(276), UWORD(1), UWORD(77562), UWORD(279), UWORD(1), UWORD(79242), UWORD(282), UWORD(1), UWORD(80940), UWORD(285), UWORD(1), UWORD(82656), UWORD(288), }; ARB_DLL const mp_limb_t factorial_tab_denom[FACTORIAL_TAB_SIZE] = { UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(479001600), UWORD(253955520), UWORD(253955520), UWORD(253955520), UWORD(253955520), UWORD(253955520), UWORD(253955520), UWORD(253955520), UWORD(3315312000), UWORD(3315312000), UWORD(3315312000), UWORD(3315312000), UWORD(3315312000), UWORD(3315312000), UWORD(3315312000), UWORD(652458240), UWORD(652458240), UWORD(652458240), UWORD(652458240), UWORD(652458240), UWORD(652458240), UWORD(1987690320), UWORD(1987690320), UWORD(1987690320), UWORD(1987690320), UWORD(1987690320), UWORD(1987690320), UWORD(115511760), UWORD(115511760), UWORD(115511760), UWORD(115511760), UWORD(115511760), UWORD(205476480), UWORD(205476480), UWORD(205476480), UWORD(205476480), UWORD(205476480), UWORD(344362200), UWORD(344362200), UWORD(344362200), UWORD(344362200), UWORD(344362200), UWORD(549853920), UWORD(549853920), UWORD(549853920), UWORD(549853920), UWORD(549853920), UWORD(843461640), UWORD(843461640), UWORD(843461640), UWORD(843461640), UWORD(843461640), UWORD(1250895360), UWORD(1250895360), UWORD(1250895360), UWORD(1250895360), UWORD(1250895360), UWORD(1802440080), UWORD(1802440080), UWORD(1802440080), UWORD(1802440080), UWORD(1802440080), UWORD(2533330800), UWORD(2533330800), UWORD(2533330800), UWORD(2533330800), UWORD(2533330800), UWORD(3484127520), UWORD(3484127520), UWORD(3484127520), UWORD(3484127520), UWORD(3484127520), UWORD(53421480), UWORD(53421480), UWORD(53421480), UWORD(53421480), UWORD(64144080), UWORD(64144080), UWORD(64144080), UWORD(64144080), UWORD(76405080), UWORD(76405080), UWORD(76405080), UWORD(76405080), UWORD(90345024), UWORD(90345024), UWORD(90345024), UWORD(90345024), UWORD(106110600), UWORD(106110600), UWORD(106110600), UWORD(106110600), UWORD(123854640), UWORD(123854640), UWORD(123854640), UWORD(123854640), UWORD(143736120), UWORD(143736120), UWORD(143736120), UWORD(143736120), UWORD(165920160), UWORD(165920160), UWORD(165920160), UWORD(165920160), UWORD(190578024), UWORD(190578024), UWORD(190578024), UWORD(190578024), UWORD(217887120), UWORD(217887120), UWORD(217887120), UWORD(217887120), UWORD(248031000), UWORD(248031000), UWORD(248031000), UWORD(248031000), UWORD(281199360), UWORD(281199360), UWORD(281199360), UWORD(281199360), UWORD(317588040), UWORD(317588040), UWORD(317588040), UWORD(317588040), UWORD(357399024), UWORD(357399024), UWORD(357399024), UWORD(357399024), UWORD(400840440), UWORD(400840440), UWORD(400840440), UWORD(400840440), UWORD(448126560), UWORD(448126560), UWORD(448126560), UWORD(448126560), UWORD(499477800), UWORD(499477800), UWORD(499477800), UWORD(499477800), UWORD(555120720), UWORD(555120720), UWORD(555120720), UWORD(555120720), UWORD(615288024), UWORD(615288024), UWORD(615288024), UWORD(615288024), UWORD(680218560), UWORD(680218560), UWORD(680218560), UWORD(680218560), UWORD(750157320), UWORD(750157320), UWORD(750157320), UWORD(750157320), UWORD(825355440), UWORD(825355440), UWORD(825355440), UWORD(825355440), UWORD(906070200), UWORD(906070200), UWORD(906070200), UWORD(906070200), UWORD(992565024), UWORD(992565024), UWORD(992565024), UWORD(992565024), UWORD(1085109480), UWORD(1085109480), UWORD(1085109480), UWORD(1085109480), UWORD(1183979280), UWORD(1183979280), UWORD(1183979280), UWORD(1183979280), UWORD(1289456280), UWORD(1289456280), UWORD(1289456280), UWORD(1289456280), UWORD(1401828480), UWORD(1401828480), UWORD(1401828480), UWORD(1401828480), UWORD(1521390024), UWORD(1521390024), UWORD(1521390024), UWORD(1521390024), UWORD(1648441200), UWORD(1648441200), UWORD(1648441200), UWORD(1648441200), UWORD(1783288440), UWORD(1783288440), UWORD(1783288440), UWORD(1783288440), UWORD(1926244320), UWORD(1926244320), UWORD(1926244320), UWORD(1926244320), UWORD(2077627560), UWORD(2077627560), UWORD(2077627560), UWORD(2077627560), UWORD(2237763024), UWORD(2237763024), UWORD(2237763024), UWORD(2237763024), UWORD(2406981720), UWORD(2406981720), UWORD(2406981720), UWORD(2406981720), UWORD(2585620800), UWORD(2585620800), UWORD(2585620800), UWORD(2585620800), UWORD(2774023560), UWORD(2774023560), UWORD(2774023560), UWORD(2774023560), UWORD(2972539440), UWORD(2972539440), UWORD(2972539440), UWORD(2972539440), UWORD(3181524024), UWORD(3181524024), UWORD(3181524024), UWORD(3181524024), UWORD(3401339040), UWORD(3401339040), UWORD(3401339040), UWORD(3401339040), UWORD(3632352360), UWORD(3632352360), UWORD(3632352360), UWORD(3632352360), UWORD(3874938000), UWORD(3874938000), UWORD(3874938000), UWORD(3874938000), UWORD(4129476120), UWORD(4129476120), UWORD(4129476120), UWORD(4129476120), UWORD(16974336), UWORD(16974336), UWORD(16974336), UWORD(17575740), UWORD(17575740), UWORD(17575740), UWORD(18191184), UWORD(18191184), UWORD(18191184), UWORD(18820830), UWORD(18820830), UWORD(18820830), UWORD(19464840), UWORD(19464840), UWORD(19464840), UWORD(20123376), UWORD(20123376), UWORD(20123376), UWORD(20796600), UWORD(20796600), UWORD(20796600), UWORD(21484674), UWORD(21484674), UWORD(21484674), UWORD(22187760), UWORD(22187760), UWORD(22187760), UWORD(22906020), UWORD(22906020), UWORD(22906020), UWORD(23639616), UWORD(23639616), }; #endif void _arb_exp_taylor_rs(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N) { mp_ptr s, t, xpow; mp_limb_t new_denom, old_denom, c; slong power, k, m; TMP_INIT; TMP_START; if (N >= FACTORIAL_TAB_SIZE - 1) { flint_printf("_arb_exp_taylor_rs: N too large!\n"); flint_abort(); } if (N <= 3) { if (N <= 1) { flint_mpn_zero(y, xn); y[xn] = N; error[0] = 0; } else if (N == 2) { flint_mpn_copyi(y, x, xn); y[xn] = 1; error[0] = 0; } else { /* 1 + x + x^2 / 2 */ t = TMP_ALLOC_LIMBS(2 * xn); mpn_sqr(t, x, xn); mpn_rshift(t + xn, t + xn, xn, 1); y[xn] = mpn_add_n(y, x, t + xn, xn) + 1; error[0] = 2; } } else { /* Choose m ~= sqrt(num_terms) (m must be even, >= 2) */ /* TODO: drop evenness assumption since we don't have sign issues here? */ /* TODO: then just need to fix power construction below... */ m = 2; while (m * m < N) m += 2; /* todo: merge allocations */ xpow = TMP_ALLOC_LIMBS((m + 1) * xn); s = TMP_ALLOC_LIMBS(xn + 2); t = TMP_ALLOC_LIMBS(2 * xn + 2); /* todo: 1 limb too much? */ /* higher index ---> */ /* | ---xn--- | */ /* xpow = | | x^m | x^(m-1) | ... | x^2 | x | */ #define XPOW_WRITE(__k) (xpow + (m - (__k)) * xn) #define XPOW_READ(__k) (xpow + (m - (__k) + 1) * xn) flint_mpn_copyi(XPOW_READ(1), x, xn); mpn_sqr(XPOW_WRITE(2), XPOW_READ(1), xn); for (k = 4; k <= m; k += 2) { mpn_mul_n(XPOW_WRITE(k - 1), XPOW_READ(k / 2), XPOW_READ(k / 2 - 1), xn); mpn_sqr(XPOW_WRITE(k), XPOW_READ(k / 2), xn); } flint_mpn_zero(s, xn + 1); /* todo: skip one nonscalar multiplication (use x^m) when starting on x^0 */ power = (N - 1) % m; for (k = N - 1; k >= 0; k--) { c = factorial_tab_numer[k]; new_denom = factorial_tab_denom[k]; old_denom = factorial_tab_denom[k+1]; /* change denominators */ if (new_denom != old_denom && k < N - 1) { mpn_divrem_1(s, 0, s, xn + 1, old_denom); } if (power == 0) { /* add c * x^0 -- only top limb is affected */ s[xn] += c; /* Outer polynomial evaluation: multiply by x^m */ if (k != 0) { mpn_mul(t, s, xn + 1, XPOW_READ(m), xn); flint_mpn_copyi(s, t + xn, xn + 1); } power = m - 1; } else { s[xn] += mpn_addmul_1(s, XPOW_READ(power), xn, c); power--; } } /* finally divide by denominator */ mpn_divrem_1(y, 0, s, xn + 1, factorial_tab_denom[0]); /* error bound (ulp) */ error[0] = 2; } TMP_END; } arb-2.22.1/arb/fac.c000066400000000000000000000011051417376376500140230ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_fac_ui(arb_t x, ulong n, slong prec) { fmpz_t t; fmpz_init(t); fmpz_set_ui(t, n); fmpz_add_ui(t, t, 1); arb_gamma_fmpz(x, t, prec); fmpz_clear(t); } arb-2.22.1/arb/fib.c000066400000000000000000000042711417376376500140410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* Fibonacci numbers using binary powering. D. Takahashi, "A fast algorithm for computing large Fibonacci numbers", Information Processing Letters 75 (2000) 243–246 */ void arb_fib_fmpz(arb_t f, const fmpz_t n, slong prec) { arb_t t, u; slong wp, sign, i; if (fmpz_sgn(n) < 0) { fmpz_t m; fmpz_init(m); fmpz_neg(m, n); arb_fib_fmpz(f, m, prec); if (fmpz_is_even(m)) arb_neg(f, f); fmpz_clear(m); return; } if (fmpz_cmp_ui(n, 4) <= 0) { ulong x = fmpz_get_ui(n); arb_set_ui(f, x - (x > 1)); return; } wp = ARF_PREC_ADD(prec, 3 * fmpz_bits(n)); arb_init(u); arb_init(t); arb_set_ui(f, UWORD(1)); arb_set_ui(u, UWORD(1)); sign = -1; for (i = fmpz_flog_ui(n, UWORD(2)) - 1; i > 0; i--) { arb_mul(t, f, f, wp); arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul(f, f, f, wp); arb_mul_2exp_si(f, f, 1); arb_submul_ui(f, t, 3, wp); arb_sub_si(f, f, 2 * sign, wp); arb_mul_ui(u, t, 5, wp); arb_add_si(u, u, 2 * sign, wp); sign = 1; if (fmpz_tstbit(n, i)) { arb_set(t, f); arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul_2exp_si(t, t, 1); arb_add(u, f, t, wp); sign = -1; } } if (fmpz_tstbit(n, 0)) { arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul(f, f, u, wp); arb_sub_si(f, f, sign, prec); } else { arb_mul(f, f, u, prec); } arb_clear(u); arb_clear(t); } void arb_fib_ui(arb_t f, ulong n, slong prec) { fmpz_t t; fmpz_init_set_ui(t, n); arb_fib_fmpz(f, t, prec); fmpz_clear(t); } arb-2.22.1/arb/floor.c000066400000000000000000000016671417376376500144300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_floor(arb_t z, const arb_t x, slong prec) { if (!arb_is_finite(x)) { arb_indeterminate(z); } else if (arb_is_exact(x)) { arf_floor(arb_midref(z), arb_midref(x)); mag_zero(arb_radref(z)); arb_set_round(z, z, prec); } else { arf_t a, b; arf_init(a); arf_init(b); arb_get_interval_arf(a, b, x, prec); arf_floor(a, a); arf_floor(b, b); arb_set_interval_arf(z, a, b, prec); arf_clear(a); arf_clear(b); } } arb-2.22.1/arb/fma.c000066400000000000000000000077621417376376500140540ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_fma_arf(arb_t res, const arb_t x, const arf_t y, const arb_t z, slong prec) { mag_t ym; int inexact; if (arb_is_exact(x)) { inexact = arf_fma(arb_midref(res), arb_midref(x), y, arb_midref(z), prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(res), arb_radref(z), arb_midref(res), prec); else mag_set(arb_radref(res), arb_radref(z)); } else if (ARB_IS_LAGOM(res) && ARB_IS_LAGOM(x) && ARF_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_t tm; mag_fast_init_set_arf(ym, y); *tm = *arb_radref(z); mag_fast_addmul(tm, ym, arb_radref(x)); *arb_radref(res) = *tm; inexact = arf_fma(arb_midref(res), arb_midref(x), y, arb_midref(z), prec, ARB_RND); if (inexact) arf_mag_fast_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec); } else { mag_t tm; mag_init(tm); mag_init_set_arf(ym, y); mag_set(tm, arb_radref(z)); mag_addmul(tm, ym, arb_radref(x)); mag_set(arb_radref(res), tm); inexact = arf_fma(arb_midref(res), arb_midref(x), y, arb_midref(z), prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec); mag_clear(tm); mag_clear(ym); } } void arb_fma(arb_t res, const arb_t x, const arb_t y, const arb_t z, slong prec) { mag_t zr, xm, ym; int inexact; if (arb_is_exact(y)) { arb_fma_arf(res, x, arb_midref(y), z, prec); } else if (arb_is_exact(x)) { arb_fma_arf(res, y, arb_midref(x), z, prec); } else if (ARB_IS_LAGOM(res) && ARB_IS_LAGOM(x) && ARB_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(xm, arb_midref(x)); mag_fast_init_set_arf(ym, arb_midref(y)); mag_fast_init_set(zr, arb_radref(z)); mag_fast_addmul(zr, xm, arb_radref(y)); mag_fast_addmul(zr, ym, arb_radref(x)); mag_fast_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_fma(arb_midref(res), arb_midref(x), arb_midref(y), arb_midref(z), prec, ARF_RND_DOWN); if (inexact) arf_mag_fast_add_ulp(zr, zr, arb_midref(res), prec); *arb_radref(res) = *zr; } else { mag_init_set_arf(xm, arb_midref(x)); mag_init_set_arf(ym, arb_midref(y)); mag_init_set(zr, arb_radref(z)); mag_addmul(zr, xm, arb_radref(y)); mag_addmul(zr, ym, arb_radref(x)); mag_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_fma(arb_midref(res), arb_midref(x), arb_midref(y), arb_midref(z), prec, ARF_RND_DOWN); if (inexact) arf_mag_add_ulp(arb_radref(res), zr, arb_midref(res), prec); else mag_set(arb_radref(res), zr); mag_clear(zr); mag_clear(xm); mag_clear(ym); } } void arb_fma_ui(arb_t res, const arb_t x, ulong y, const arb_t z, slong prec) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ arb_fma_arf(res, x, t, z, prec); } void arb_fma_si(arb_t res, const arb_t x, slong y, const arb_t z, slong prec) { arf_t t; arf_init_set_si(t, y); /* no need to free */ arb_fma_arf(res, x, t, z, prec); } void arb_fma_fmpz(arb_t res, const arb_t x, const fmpz_t y, const arb_t z, slong prec) { arf_t t; if (!COEFF_IS_MPZ(*y)) { arf_init_set_si(t, *y); /* no need to free */ arb_fma_arf(res, x, t, z, prec); } else { arf_init(t); arf_set_fmpz(t, y); arb_fma_arf(res, x, t, z, prec); arf_clear(t); } } arb-2.22.1/arb/fprint.c000066400000000000000000000017051417376376500146020ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_fprint(FILE * file, const arb_t x) { arf_fprint(file, arb_midref(x)); flint_fprintf(file, " +/- "); mag_fprint(file, arb_radref(x)); } void arb_fprintd(FILE * file, const arb_t x, slong digits) { arf_fprintd(file, arb_midref(x), FLINT_MAX(digits, 1)); flint_fprintf(file, " +/- "); mag_fprintd(file, arb_radref(x), 5); } void arb_fprintn(FILE * file, const arb_t x, slong digits, ulong flags) { char * s = arb_get_str(x, digits, flags); flint_fprintf(file, "%s", s); flint_free(s); } arb-2.22.1/arb/gamma.c000066400000000000000000000156761417376376500143760ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "arb_hypgeom.h" #include "bernoulli.h" /* todo: move/cleanup helper functions */ void acb_gamma_bound_phase(mag_t bound, const acb_t z) { arf_t x, y, t, u; int xsign; slong prec; arf_init(x); arf_init(y); arf_init(t); arf_init(u); prec = MAG_BITS; /* first compute x, y such that |arg(z)| <= arg(x+yi) */ /* argument increases with smaller real parts */ arf_set_mag(x, arb_radref(acb_realref(z))); arf_sub(x, arb_midref(acb_realref(z)), x, prec, ARF_RND_FLOOR); xsign = arf_sgn(x); if (xsign >= 0) /* argument increases away from the real axis */ arb_get_abs_ubound_arf(y, acb_imagref(z), prec); else /* argument increases closer to the real axis */ arb_get_abs_lbound_arf(y, acb_imagref(z), prec); if (arf_is_zero(y)) { if (xsign > 0) mag_one(bound); else mag_inf(bound); } else { if (xsign >= 0) { /* compute upper bound for t = y / (sqrt(x^2 + y^2) + x) */ arf_mul(t, x, x, prec, ARF_RND_DOWN); arf_mul(u, y, y, prec, ARF_RND_DOWN); arf_add(t, t, u, prec, ARF_RND_DOWN); arf_sqrt(t, t, prec, ARF_RND_DOWN); arf_add(t, t, x, prec, ARF_RND_DOWN); arf_div(t, y, t, prec, ARF_RND_UP); } else { /* compute upper bound for t = (sqrt(x^2 + y^2) - x) / y */ arf_mul(t, x, x, prec, ARF_RND_UP); arf_mul(u, y, y, prec, ARF_RND_UP); arf_add(t, t, u, prec, ARF_RND_UP); arf_sqrt(t, t, prec, ARF_RND_UP); arf_sub(t, t, x, prec, ARF_RND_UP); arf_div(t, t, y, prec, ARF_RND_UP); } /* compute upper bound for sqrt(1 + t^2) */ arf_mul(t, t, t, prec, ARF_RND_UP); arf_add_ui(t, t, 1, prec, ARF_RND_UP); arf_sqrt(t, t, prec, ARF_RND_UP); arf_get_mag(bound, t); } arf_clear(x); arf_clear(y); arf_clear(t); arf_clear(u); } /* 2 |B_{2n}| G(2n+k-1) / (G(k+1) G(2n+1)) |z| (T |z|^{-1})^(2n+k) TODO: CHECK n >= 1 ? */ void acb_gamma_stirling_bound(mag_ptr err, const acb_t z, slong k0, slong knum, slong n) { mag_t c, t, u, v; slong i, k; if (arb_contains_zero(acb_imagref(z)) && arb_contains_nonpositive(acb_realref(z))) { for (i = 0; i < knum; i++) mag_inf(err + i); return; } mag_init(c); mag_init(t); mag_init(u); mag_init(v); /* t = lower bound for |z| */ acb_get_mag_lower(t, z); /* v = upper bound for |z| */ acb_get_mag(v, z); /* c = upper bound for 1/(cos(arg(z)/2) |z|) */ acb_gamma_bound_phase(c, z); mag_div(c, c, t); /* numerator: 2 B_{2n} gamma(2n+k-1) |z| */ mag_bernoulli_div_fac_ui(err, 2 * n); mag_mul_2exp_si(err, err, 1); mag_fac_ui(u, 2 * n + k0 - 2); mag_mul(err, err, u); mag_mul(err, err, v); /* denominator gamma(k+1) gamma(2n+1) */ mag_rfac_ui(t, k0); mag_mul(err, err, t); /* multiply by c^(2n+k) */ mag_pow_ui(t, c, 2 * n + k0); mag_mul(err, err, t); for (i = 1; i < knum; i++) { /* recurrence factor: c * (2n+k-2) / k */ k = k0 + i; mag_mul(err + i, err + i - 1, c); mag_mul_ui(err + i, err + i, 2 * n + k - 2); mag_div_ui(err + i, err + i, k); } mag_clear(c); mag_clear(t); mag_clear(u); mag_clear(v); } void arb_gamma_stirling_bound(mag_ptr err, const arb_t x, slong k0, slong knum, slong n) { acb_t z; acb_init(z); acb_set_arb(z, x); acb_gamma_stirling_bound(err, z, k0, knum, n); acb_clear(z); } void arb_gamma_stirling_coeff(arb_t b, ulong k, int digamma, slong prec) { fmpz_t d; fmpz_init(d); BERNOULLI_ENSURE_CACHED(2 * k); arb_set_round_fmpz(b, fmpq_numref(bernoulli_cache + 2 * k), prec); if (digamma) fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * k), 2 * k); else fmpz_mul2_uiui(d, fmpq_denref(bernoulli_cache + 2 * k), 2 * k, 2 * k - 1); arb_div_fmpz(b, b, d, prec); fmpz_clear(d); } void arb_gamma_stirling_eval(arb_t s, const arb_t z, slong nterms, int digamma, slong prec) { arb_t b, t, logz, zinv, zinv2; mag_t err; slong k, term_prec; double z_mag, term_mag; arb_init(b); arb_init(t); arb_init(logz); arb_init(zinv); arb_init(zinv2); arb_log(logz, z, prec); arb_inv(zinv, z, prec); nterms = FLINT_MAX(nterms, 1); arb_zero(s); if (nterms > 1) { arb_mul(zinv2, zinv, zinv, prec); z_mag = arf_get_d(arb_midref(logz), ARF_RND_UP) * 1.44269504088896; for (k = nterms - 1; k >= 1; k--) { term_mag = bernoulli_bound_2exp_si(2 * k); term_mag -= (2 * k - 1) * z_mag; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); if (prec > 2000) { arb_set_round(t, zinv2, term_prec); arb_mul(s, s, t, term_prec); } else arb_mul(s, s, zinv2, term_prec); arb_gamma_stirling_coeff(b, k, digamma, term_prec); arb_add(s, s, b, term_prec); } if (digamma) arb_mul(s, s, zinv2, prec); else arb_mul(s, s, zinv, prec); } /* remainder bound */ mag_init(err); arb_gamma_stirling_bound(err, z, digamma ? 1 : 0, 1, nterms); mag_add(arb_radref(s), arb_radref(s), err); mag_clear(err); if (digamma) { arb_neg(s, s); arb_mul_2exp_si(zinv, zinv, -1); arb_sub(s, s, zinv, prec); arb_add(s, s, logz, prec); } else { /* (z-0.5)*log(z) - z + log(2*pi)/2 */ arb_one(t); arb_mul_2exp_si(t, t, -1); arb_sub(t, z, t, prec); arb_mul(t, logz, t, prec); arb_add(s, s, t, prec); arb_sub(s, s, z, prec); arb_const_log_sqrt2pi(t, prec); arb_add(s, s, t, prec); } arb_clear(t); arb_clear(b); arb_clear(zinv); arb_clear(zinv2); arb_clear(logz); } void arb_gamma_fmpq(arb_t y, const fmpq_t x, slong prec) { arb_hypgeom_gamma_fmpq(y, x, prec); } void arb_gamma_fmpz(arb_t y, const fmpz_t x, slong prec) { arb_hypgeom_gamma_fmpz(y, x, prec); } void arb_gamma(arb_t y, const arb_t x, slong prec) { arb_hypgeom_gamma(y, x, prec); } void arb_rgamma(arb_t y, const arb_t x, slong prec) { arb_hypgeom_rgamma(y, x, prec); } void arb_lgamma(arb_t y, const arb_t x, slong prec) { arb_hypgeom_lgamma(y, x, prec); } arb-2.22.1/arb/get_abs_lbound_arf.c000066400000000000000000000014161417376376500170760ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_get_abs_lbound_arf(arf_t u, const arb_t x, slong prec) { arf_t t; arf_init_set_mag_shallow(t, arb_radref(x)); if (arf_sgn(arb_midref(x)) > 0) { arf_sub(u, arb_midref(x), t, prec, ARF_RND_DOWN); } else { arf_add(u, arb_midref(x), t, prec, ARF_RND_DOWN); arf_neg(u, u); } if (arf_sgn(u) < 0) arf_zero(u); } arb-2.22.1/arb/get_abs_ubound_arf.c000066400000000000000000000013011417376376500171000ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_get_abs_ubound_arf(arf_t u, const arb_t x, slong prec) { arf_t t; arf_init_set_mag_shallow(t, arb_radref(x)); if (arf_sgn(arb_midref(x)) < 0) arf_sub(u, arb_midref(x), t, prec, ARF_RND_UP); else arf_add(u, arb_midref(x), t, prec, ARF_RND_UP); arf_abs(u, u); } arb-2.22.1/arb/get_fmpz_mid_rad_10exp.c000066400000000000000000000045261417376376500176130ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* todo: make arb_pow_fmpz automatic */ void _arb_10_pow_fmpz(arb_t res, const fmpz_t m, slong prec) { slong bits = fmpz_bits(m); if (bits < 128) { arb_set_ui(res, 10); arb_pow_fmpz_binexp(res, res, m, prec + 2 * bits); } else { arb_const_log10(res, prec + bits); arb_mul_fmpz(res, res, m, prec + bits); arb_exp(res, res, prec + bits); } } void arb_get_fmpz_mid_rad_10exp(fmpz_t mid, fmpz_t rad, fmpz_t exp, const arb_t x, slong n) { fmpz_t e, m; arb_t t, u; arf_t r; slong prec; int roundmid, roundrad; if (!arb_is_finite(x) || arb_is_zero(x)) { fmpz_zero(mid); fmpz_zero(rad); fmpz_zero(exp); return; } /* We compute m such that x * 10^m ~= 10^(n+5). If x = 2^e then m = (n+5) - e*log(2)/log(10). */ fmpz_init(e); fmpz_init(m); arb_init(t); arb_init(u); arf_init(r); if (arf_cmpabs_mag(arb_midref(x), arb_radref(x)) > 0) fmpz_set(e, ARF_EXPREF(arb_midref(x))); else fmpz_set(e, ARF_EXPREF(arb_radref(x))); prec = fmpz_bits(e); prec = FLINT_MAX(prec, FLINT_BIT_COUNT(n)) + 15; arb_const_log2(t, prec); arb_const_log10(u, prec); arb_div(t, t, u, prec); arb_mul_fmpz(t, t, e, prec); arb_neg(t, t); arb_add_ui(t, t, n + 5, prec); arf_get_fmpz(m, arb_midref(t), ARF_RND_FLOOR); fmpz_neg(exp, m); prec = n * 3.32192809488736 + 30; if (fmpz_sgn(m) >= 0) { _arb_10_pow_fmpz(t, m, prec); arb_mul(t, x, t, prec); } else { fmpz_neg(m, m); _arb_10_pow_fmpz(t, m, prec); arb_div(t, x, t, prec); } roundmid = arf_get_fmpz_fixed_si(mid, arb_midref(t), 0); arf_set_mag(r, arb_radref(t)); roundrad = arf_get_fmpz_fixed_si(rad, r, 0); fmpz_add_ui(rad, rad, roundmid + roundrad); fmpz_clear(e); fmpz_clear(m); arb_clear(t); arb_clear(u); arf_clear(r); } arb-2.22.1/arb/get_interval_arf.c000066400000000000000000000012041417376376500166050ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_get_interval_arf(arf_t a, arf_t b, const arb_t x, slong prec) { arf_t r; arf_init_set_mag_shallow(r, arb_radref(x)); arf_sub(a, arb_midref(x), r, prec, ARF_RND_FLOOR); arf_add(b, arb_midref(x), r, prec, ARF_RND_CEIL); } arb-2.22.1/arb/get_interval_fmpz_2exp.c000066400000000000000000000041701417376376500177540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_get_interval_fmpz_2exp(fmpz_t a, fmpz_t b, fmpz_t exp, const arb_t x) { if (!arb_is_finite(x)) { printf("arb_get_interval_fmpz_2exp: expected finite input\n"); flint_abort(); } else if (arb_is_exact(x)) { arf_get_fmpz_2exp(a, exp, arb_midref(x)); fmpz_set(b, a); } else if (arf_is_zero(arb_midref(x))) { arf_t t; arf_init_set_mag_shallow(t, arb_radref(x)); arf_get_fmpz_2exp(b, exp, t); fmpz_neg(a, b); } else { arf_t rad; fmpz_t tmp; slong shift; flint_bitcnt_t aval, bval; fmpz_init(tmp); arf_get_fmpz_2exp(a, exp, arb_midref(x)); arf_init_set_mag_shallow(rad, arb_radref(x)); arf_get_fmpz_2exp(b, tmp, rad); shift = _fmpz_sub_small(exp, tmp); if (FLINT_ABS(shift) >= WORD_MAX / 2) { printf("arb_get_interval_fmpz_2exp: too large shift\n"); flint_abort(); } if (shift >= 0) { fmpz_mul_2exp(a, a, shift); fmpz_set(exp, tmp); } else fmpz_mul_2exp(b, b, -shift); fmpz_sub(tmp, a, b); fmpz_add(b, a, b); fmpz_swap(tmp, a); if (fmpz_is_zero(a)) { aval = fmpz_val2(b); } else if (fmpz_is_zero(b)) { aval = fmpz_val2(a); } else { aval = fmpz_val2(a); bval = fmpz_val2(b); aval = FLINT_MIN(aval, bval); } if (aval > 0) { fmpz_add_ui(exp, exp, aval); fmpz_tdiv_q_2exp(a, a, aval); fmpz_tdiv_q_2exp(b, b, aval); } fmpz_clear(tmp); } } arb-2.22.1/arb/get_interval_mpfr.c000066400000000000000000000013771417376376500170140ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_get_interval_mpfr(mpfr_t a, mpfr_t b, const arb_t x) { arf_t r, t; arf_init(t); arf_init_set_mag_shallow(r, arb_radref(x)); arf_sub(t, arb_midref(x), r, mpfr_get_prec(a), ARF_RND_FLOOR); arf_get_mpfr(a, t, MPFR_RNDD); arf_add(t, arb_midref(x), r, mpfr_get_prec(b), ARF_RND_CEIL); arf_get_mpfr(b, t, MPFR_RNDU); arf_clear(t); } arb-2.22.1/arb/get_lbound_arf.c000066400000000000000000000011031417376376500162420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_get_lbound_arf(arf_t u, const arb_t x, slong prec) { arf_t t; arf_init_set_mag_shallow(t, arb_radref(x)); arf_sub(u, arb_midref(x), t, prec, ARF_RND_FLOOR); } arb-2.22.1/arb/get_mag_lower.c000066400000000000000000000050561417376376500161160ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static __inline__ void _arb_get_mag_lower(mag_t z, const arf_t mid, const mag_t rad) { if (arf_is_special(mid) || mag_is_special(rad)) { if (mag_is_zero(rad)) { arf_get_mag_lower(z, mid); } else if (arf_is_inf(mid) && mag_is_finite(rad)) { mag_inf(z); } else { mag_zero(z); } } else { slong shift, fix; shift = _fmpz_sub_small(MAG_EXPREF(mid), MAG_EXPREF(rad)); /* mid < rad */ if (shift < 0) { mag_zero(z); } else { mp_limb_t m, xm, rm; ARF_GET_TOP_LIMB(xm, mid); xm = xm >> (FLINT_BITS - MAG_BITS); if (shift <= MAG_BITS) rm = (MAG_MAN(rad) >> shift) + 1; else rm = 1; m = xm - rm; if (shift > 1) /* more than one bit cancellation not possible */ { fix = !(m >> (MAG_BITS - 1)); m <<= fix; MAG_MAN(z) = m; _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(mid), -fix); } else if (rm < xm && m > (1 << (MAG_BITS - 4))) /* not too much cancellation */ { fix = MAG_BITS - FLINT_BIT_COUNT(m); m <<= fix; MAG_MAN(z) = m; _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(mid), -fix); } else { arf_t t; arf_init(t); arf_set_mag(t, rad); if (arf_sgn(mid) > 0) { arf_sub(t, mid, t, MAG_BITS, ARF_RND_DOWN); } else { arf_add(t, mid, t, MAG_BITS, ARF_RND_DOWN); arf_neg(t, t); } if (arf_sgn(t) <= 0) mag_zero(z); else arf_get_mag_lower(z, t); arf_clear(t); } } } } void arb_get_mag_lower(mag_t z, const arb_t x) { _arb_get_mag_lower(z, arb_midref(x), arb_radref(x)); } arb-2.22.1/arb/get_mag_lower_nonnegative.c000066400000000000000000000046531417376376500205150ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static __inline__ void _arb_get_mag_lower_nonnegative(mag_t z, const arf_t mid, const mag_t rad) { if (arf_sgn(mid) < 0) { mag_zero(z); } else if (arf_is_special(mid) || mag_is_special(rad)) { if (mag_is_zero(rad)) { arf_get_mag_lower(z, mid); } else if (arf_is_pos_inf(mid) && mag_is_finite(rad)) { mag_inf(z); } else { mag_zero(z); } } else { slong shift, fix; shift = _fmpz_sub_small(MAG_EXPREF(mid), MAG_EXPREF(rad)); /* mid < rad */ if (shift < 0) { mag_zero(z); } else { mp_limb_t m, xm, rm; ARF_GET_TOP_LIMB(xm, mid); xm = xm >> (FLINT_BITS - MAG_BITS); if (shift <= MAG_BITS) rm = (MAG_MAN(rad) >> shift) + 1; else rm = 1; m = xm - rm; if (shift > 1) /* more than one bit cancellation not possible */ { fix = !(m >> (MAG_BITS - 1)); m <<= fix; MAG_MAN(z) = m; _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(mid), -fix); } else if (rm < xm && m > (1 << (MAG_BITS - 4))) /* not too much cancellation */ { fix = MAG_BITS - FLINT_BIT_COUNT(m); m <<= fix; MAG_MAN(z) = m; _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(mid), -fix); } else { arf_t t; arf_init(t); arf_set_mag(t, rad); arf_sub(t, mid, t, MAG_BITS, ARF_RND_DOWN); if (arf_sgn(t) <= 0) mag_zero(z); else arf_get_mag_lower(z, t); arf_clear(t); } } } } void arb_get_mag_lower_nonnegative(mag_t z, const arb_t x) { _arb_get_mag_lower_nonnegative(z, arb_midref(x), arb_radref(x)); } arb-2.22.1/arb/get_mpn_fixed_mod_log2.c000066400000000000000000000106471417376376500176770ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define TMP_ALLOC_LIMBS(__n) TMP_ALLOC((__n) * sizeof(mp_limb_t)) /* Compute wn-limb fixed-point number w, a number of ulps error, and an exponent q such that x = (w + xi * error) - q * log(2) where 0 <= w < log(2) and |xi| <= 1. Returns 0 if unsuccessful (high enough precision for log(2) to be available) and 1 if successful. Assumes nonspecial x; its exponent must not be an mpz. Error analysis: We first set n = |x| - e1 d = log(2) - e2 where 0 <= e1, e2 <= 1 ulp are the errors resulting from truncating to fixed-point numbers (note that the value of log(2) is correctly rounded). Next, we compute q, r such that 0 <= r < d and q*d + r = n (this is just integer division with remainder, done exactly). The real number we want to approximate is r_exact = |x| - q * log(2). The approximation r satisfies |r_exact - r| = |(|x| - q * log(2)) - (n - q * d)| = ||x| - q * log(2) - (|x| - e1) + q * (log(2) - e2)| = |e1 - q * e2| <= (q + 1) ulp. We select the working precision so that (q + 1) ulp is at most 1 ulp in the target precision. It is sufficient to use tn extra limbs where (q + 1) <= 2^(FLINT_BITS * tn). Note that q + 1 <= n / d + 1 <= |x| * 1.5 + 1 < 2^(exp+2). So it is sufficient to choose tn = ceil((exp+2)/FLINT_BITS). Now we round the result to the final precision: w = r - e3. This can add 1 more ulp of error, so the error may be 2 ulp. Finally, if x < 0, we correct the sign by setting,x = log(2) - x, q = -(q+1). This adds 1 more ulp (from the approximation of log(2)), for a total of 3 ulp. */ int _arb_get_mpn_fixed_mod_log2(mp_ptr w, fmpz_t q, mp_limb_t * error, const arf_t x, mp_size_t wn) { mp_srcptr xp; mp_size_t xn; int negative; slong exp; ARF_GET_MPN_READONLY(xp, xn, x); exp = ARF_EXP(x); negative = ARF_SGNBIT(x); if (exp <= -1) { /* todo: just zero top */ flint_mpn_zero(w, wn); *error = _arf_get_integer_mpn(w, xp, xn, exp + wn * FLINT_BITS); if (!negative) { fmpz_zero(q); } else { if (wn > ARB_LOG_TAB2_LIMBS) return 0; mpn_sub_n(w, arb_log_log2_tab + ARB_LOG_TAB2_LIMBS - wn, w, wn); *error += 1; /* log(2) has 1 ulp error */ fmpz_set_si(q, -1); } return 1; /* success */ } else { mp_ptr qp, rp, np; mp_srcptr dp; mp_size_t qn, rn, nn, dn, tn, alloc; TMP_INIT; tn = ((exp + 2) + FLINT_BITS - 1) / FLINT_BITS; dn = wn + tn; /* denominator */ nn = wn + 2 * tn; /* numerator */ qn = nn - dn + 1; /* quotient */ rn = dn; /* remainder */ if (dn > ARB_LOG_TAB2_LIMBS) return 0; TMP_START; alloc = qn + rn + nn; qp = TMP_ALLOC_LIMBS(alloc); rp = qp + qn; np = rp + rn; dp = arb_log_log2_tab + ARB_LOG_TAB2_LIMBS - dn; /* todo: prove that zeroing is unnecessary */ flint_mpn_zero(np, nn); _arf_get_integer_mpn(np, xp, xn, exp + dn * FLINT_BITS); mpn_tdiv_qr(qp, rp, 0, np, nn, dp, dn); if (!negative) { flint_mpn_copyi(w, rp + tn, wn); *error = 2; } else { if (mpn_add_1(qp, qp, qn, 1)) { /* I believe this cannot happen (should prove it) */ flint_printf("mod log(2): unexpected carry\n"); flint_abort(); } mpn_sub_n(w, dp + tn, rp + tn, wn); *error = 3; } /* read the exponent */ while (qn > 1 && qp[qn-1] == 0) qn--; if (qn == 1) { if (!negative) fmpz_set_ui(q, qp[0]); else fmpz_neg_ui(q, qp[0]); } else { fmpz_set_mpn_large(q, qp, qn, negative); } TMP_END; return 1; } } arb-2.22.1/arb/get_mpn_fixed_mod_pi4.c000066400000000000000000000055361417376376500175310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define TMP_ALLOC_LIMBS(__n) TMP_ALLOC((__n) * sizeof(mp_limb_t)) int _arb_get_mpn_fixed_mod_pi4(mp_ptr w, fmpz_t q, int * octant, mp_limb_t * error, const arf_t x, mp_size_t wn) { mp_srcptr xp; mp_size_t xn; slong exp; ARF_GET_MPN_READONLY(xp, xn, x); exp = ARF_EXP(x); if (exp <= -1) { flint_mpn_zero(w, wn); *error = _arf_get_integer_mpn(w, xp, xn, exp + wn * FLINT_BITS); *octant = 0; if (q != NULL) fmpz_zero(q); return 1; } else if (exp == 0) { mp_srcptr dp; if (wn > ARB_PI4_TAB_LIMBS) return 0; flint_mpn_zero(w, wn); *error = _arf_get_integer_mpn(w, xp, xn, exp + wn * FLINT_BITS); dp = arb_pi4_tab + ARB_PI4_TAB_LIMBS - wn; if (mpn_cmp(w, dp, wn) < 0) { *octant = 0; if (q != NULL) fmpz_zero(q); } else { *octant = 1; if (q != NULL) fmpz_one(q); mpn_sub_n(w, w, dp, wn); mpn_sub_n(w, dp, w, wn); *error += 2; } return 1; } else { mp_ptr qp, rp, np; mp_srcptr dp; mp_size_t qn, rn, nn, dn, tn, alloc; TMP_INIT; tn = ((exp + 2) + FLINT_BITS - 1) / FLINT_BITS; dn = wn + tn; /* denominator */ nn = wn + 2 * tn; /* numerator */ qn = nn - dn + 1; /* quotient */ rn = dn; /* remainder */ if (dn > ARB_PI4_TAB_LIMBS) return 0; TMP_START; alloc = qn + rn + nn; qp = TMP_ALLOC_LIMBS(alloc); rp = qp + qn; np = rp + rn; dp = arb_pi4_tab + ARB_PI4_TAB_LIMBS - dn; flint_mpn_zero(np, nn); _arf_get_integer_mpn(np, xp, xn, exp + dn * FLINT_BITS); mpn_tdiv_qr(qp, rp, 0, np, nn, dp, dn); *octant = qp[0] % 8; if (*octant % 2 == 0) { flint_mpn_copyi(w, rp + tn, wn); *error = 2; } else { mpn_sub_n(w, dp + tn, rp + tn, wn); *error = 3; } if (q != NULL) { /* read the exponent */ while (qn > 1 && qp[qn-1] == 0) qn--; if (qn == 1) fmpz_set_ui(q, qp[0]); else fmpz_set_mpn_large(q, qp, qn, 0); } TMP_END; return 1; } } arb-2.22.1/arb/get_rand_fmpq.c000066400000000000000000000040541417376376500161060ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_get_rand_fmpq(fmpz_t num, fmpz_t den, flint_rand_t state, const fmpz_t den_mult, const arb_t x) { fmpz_t a, b, exp; fmpz_init(a); fmpz_init(b); fmpz_init(exp); arb_get_interval_fmpz_2exp(a, b, exp, x); if (COEFF_IS_MPZ(*exp)) { flint_printf("exception: arb_get_rand_fmpq: too large exponent\n"); flint_abort(); } if (*exp >= 0) { fmpz_mul_2exp(a, a, *exp); fmpz_mul_2exp(b, b, *exp); } /* generate random integer in [a*den, b*den] */ fmpz_mul(a, a, den_mult); fmpz_mul(b, b, den_mult); fmpz_add_ui(b, b, UWORD(1)); fmpz_sub(b, b, a); /* return one endpoint with high probability (used for stress testing rounding) */ if (n_randint(state, 6) == 0) { if (n_randint(state, 2)) fmpz_zero(num); else fmpz_sub_ui(num, b, UWORD(1)); } else { fmpz_randtest_mod(num, state, b); } fmpz_add(num, num, a); fmpz_set(den, den_mult); if (*exp < 0) fmpz_mul_2exp(den, den, -(*exp)); fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); } void arb_get_rand_fmpq(fmpq_t q, flint_rand_t state, const arb_t x, slong bits) { /* there is only one rational */ if (arb_is_exact(x)) { arf_get_fmpq(q, arb_midref(x)); return; } /* pick a denominator */ fmpz_randbits(fmpq_denref(q), state, n_randint(state, bits + 1)); fmpz_abs(fmpq_denref(q), fmpq_denref(q)); if (fmpz_is_zero(fmpq_denref(q))) fmpz_one(fmpq_denref(q)); _arb_get_rand_fmpq(fmpq_numref(q), fmpq_denref(q), state, fmpq_denref(q), x); fmpq_canonicalise(q); } arb-2.22.1/arb/get_str.c000066400000000000000000000302221417376376500147430ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "arb.h" #define RADIUS_DIGITS 3 char * _arb_condense_digits(char * s, slong n) { slong i, j, run, out; char * res; res = flint_malloc(strlen(s) + 128); /* space for some growth */ out = 0; for (i = 0; s[i] != '\0'; ) { if (isdigit(s[i])) { run = 0; for (j = 0; isdigit(s[i + j]); j++) run++; if (run > 3 * n) { for (j = 0; j < n; j++) { res[out] = s[i + j]; out++; } out += flint_sprintf(res + out, "{...%wd digits...}", run - 2 * n); for (j = run - n; j < run; j++) { res[out] = s[i + j]; out++; } } else { for (j = 0; j < run; j++) { res[out] = s[i + j]; out++; } } i += run; } else { res[out] = s[i]; i++; out++; } } res[out] = '\0'; res = flint_realloc(res, strlen(res) + 1); flint_free(s); return res; } /* Format (digits=d, exponent=e) as floating-point or fixed-point. Reallocates the input and mutates the exponent. */ void _arb_digits_as_float_str(char ** d, fmpz_t e, slong minfix, slong maxfix) { slong i, n, alloc, dotpos; /* do nothing with 0 or something non-numerical */ if (!((*d)[0] >= '1' && (*d)[0] <= '9')) return; n = strlen(*d); fmpz_add_ui(e, e, n - 1); /* fixed-point or integer format */ /* we require e < n - 1; otherwise we would have to insert trailing zeros [todo: could allow e < n, if printing integers without radix point] */ if (fmpz_cmp_si(e, minfix) >= 0 && fmpz_cmp_si(e, maxfix) <= 0 && fmpz_cmp_si(e, n - 1) < 0) { slong exp = *e; /* 0.000xxx */ if (exp < 0) { /* 0. + (-1-exp) zeros + digits + null terminator */ alloc = 2 + (-1-exp) + n + 1; *d = flint_realloc(*d, alloc); /* copy in reverse order, including null terminator */ for (i = n; i >= 0; i--) (*d)[2 + (-1-exp) + i] = (*d)[i]; for (i = 0; i < 2 + (-1-exp); i++) (*d)[i] = (i == 1) ? '.' : '0'; } else /* xxx.yyy --- must have dotpos < n - 1 */ { dotpos = exp + 1; alloc = n + 2; /* space for . and null terminator */ (*d) = flint_realloc(*d, alloc); /* copy fractional part in reverse order, including null */ for (i = n; i >= dotpos; i--) (*d)[i + 1] = (*d)[i]; (*d)[dotpos] = '.'; } } else { /* format as xe+zzz or x.yyye+zzz */ alloc = n + 1 + 2 + fmpz_sizeinbase(e, 10) + 1; *d = flint_realloc(*d, alloc); /* insert . */ if (n > 1) { /* copy fractional part in reverse order */ for (i = n; i >= 1; i--) (*d)[i + 1] = (*d)[i]; (*d)[1] = '.'; } (*d)[n + (n > 1)] = 'e'; if (fmpz_sgn(e) >= 0) { (*d)[n + (n > 1) + 1] = '+'; } else { (*d)[n + (n > 1) + 1] = '-'; fmpz_neg(e, e); } fmpz_get_str((*d) + n + (n > 1) + 2, 10, e); /* writes null byte */ } } /* Rounds a string of decimal digits (null-terminated). to length at most n. The rounding mode can be ARF_RND_DOWN, ARF_RND_UP or ARF_RND_NEAR. The string is overwritten in-place, truncating it as necessary. The input should not have a leading sign or leading zero digits, but can have trailing zero digits. Computes shift and error such that int(input) = int(output) * 10^shift + error exactly. */ void _arb_digits_round_inplace(char * s, flint_bitcnt_t * shift, fmpz_t error, slong n, arf_rnd_t rnd) { slong i, m; int up; if (n < 1) { flint_printf("_arb_digits_round_inplace: require n >= 1\n"); flint_abort(); } m = strlen(s); if (m <= n) { *shift = 0; fmpz_zero(error); return; } /* always round down */ if (rnd == ARF_RND_DOWN) { up = 0; } else if (rnd == ARF_RND_UP) /* round up if tail is nonzero */ { up = 0; for (i = n; i < m; i++) { if (s[i] != '0') { up = 1; break; } } } else /* round to nearest (up on tie -- todo: round-to-even?) */ { up = (s[n] >= '5' && s[n] <= '9'); } if (!up) { /* simply truncate */ fmpz_set_str(error, s + n, 10); s[n] = '\0'; *shift = m - n; } else { int digit, borrow, carry; /* error = 10^(m-n) - s[n:], where s[n:] is nonzero */ /* i.e. 10s complement the truncated digits */ borrow = 0; for (i = m - 1; i >= n; i--) { digit = 10 - (s[i] - '0') - borrow; if (digit == 10) { digit = 0; borrow = 0; } else { borrow = 1; } s[i] = digit + '0'; } if (!borrow) { flint_printf("expected borrow!\n"); flint_abort(); } fmpz_set_str(error, s + n, 10); fmpz_neg(error, error); /* add 1 ulp to the leading digits */ carry = 1; for (i = n - 1; i >= 0; i--) { digit = (s[i] - '0') + carry; if (digit > 9) { digit = 0; carry = 1; } else { carry = 0; } s[i] = digit + '0'; } /* carry-out -- only possible if we started with all 9s, so now the rest will be 0s which we don't have to shift explicitly */ if (carry) { s[0] = '1'; *shift = m - n + 1; } else { *shift = m - n; } s[n] = '\0'; /* truncate */ } } void arb_get_str_parts(int * negative, char **mid_digits, fmpz_t mid_exp, char **rad_digits, fmpz_t rad_exp, const arb_t x, slong n, int more) { fmpz_t mid, rad, exp, err; slong good; flint_bitcnt_t shift; if (!arb_is_finite(x)) { *negative = 0; fmpz_zero(mid_exp); *mid_digits = flint_malloc(4); if (arf_is_nan(arb_midref(x))) strcpy(*mid_digits, "nan"); else strcpy(*mid_digits, "0"); fmpz_zero(rad_exp); *rad_digits = flint_malloc(4); strcpy(*rad_digits, "inf"); return; } fmpz_init(mid); fmpz_init(rad); fmpz_init(exp); fmpz_init(err); /* heuristic part */ if (!more) { good = arb_rel_accuracy_bits(x) * 0.30102999566398119521 + 2; n = FLINT_MIN(n, good); } arb_get_fmpz_mid_rad_10exp(mid, rad, exp, x, FLINT_MAX(n, 1)); *negative = arf_sgn(arb_midref(x)) < 0; fmpz_abs(mid, mid); *mid_digits = fmpz_get_str(NULL, 10, mid); *rad_digits = NULL; /* Truncate further so that 1 ulp error can be guaranteed (rigorous part) Note: mid cannot be zero here if n >= 1 and rad != 0. */ if (n >= 1 && !(more || fmpz_is_zero(rad))) { slong lenmid, lenrad, rem; *rad_digits = fmpz_get_str(NULL, 10, rad); lenmid = strlen(*mid_digits); lenrad = strlen(*rad_digits); if (lenmid > lenrad) { /* we will truncate at n or n-1 */ good = lenmid - lenrad; /* rounding to nearest can add at most 0.5 ulp */ /* look at first omitted digit */ rem = ((*mid_digits)[good]) - '0'; if (rem < 5) rem = rem + 1; else rem = 10 - rem; /* and include the leading digit of the radius */ rem = rem + ((*rad_digits)[0] - '0') + 1; /* if error is <= 1.0 ulp, we get to keep the extra digit */ if (rem > 10) good -= 1; n = FLINT_MIN(n, good); } else { n = 0; } /* todo: avoid recomputing? */ flint_free(*rad_digits); } /* no accurate digits -- output 0 +/- rad */ if (n < 1) { fmpz_add(rad, rad, mid); fmpz_zero(mid); strcpy(*mid_digits, "0"); /* must have space already! */ } else { _arb_digits_round_inplace(*mid_digits, &shift, err, n, ARF_RND_NEAR); fmpz_add_ui(mid_exp, exp, shift); fmpz_abs(err, err); fmpz_add(rad, rad, err); } /* write radius */ if (fmpz_is_zero(rad)) { *rad_digits = fmpz_get_str(NULL, 10, rad); fmpz_zero(rad_exp); } else { *rad_digits = fmpz_get_str(NULL, 10, rad); _arb_digits_round_inplace(*rad_digits, &shift, err, RADIUS_DIGITS, ARF_RND_UP); fmpz_add_ui(rad_exp, exp, shift); } fmpz_clear(mid); fmpz_clear(rad); fmpz_clear(exp); fmpz_clear(err); } char * arb_get_str(const arb_t x, slong n, ulong flags) { char * res; char * mid_digits; char * rad_digits; int negative, more, skip_rad, skip_mid; fmpz_t mid_exp; fmpz_t rad_exp; slong condense; if (arb_is_zero(x)) { res = flint_malloc(2); strcpy(res, "0"); return res; } more = flags & ARB_STR_MORE; condense = flags / ARB_STR_CONDENSE; if (!arb_is_finite(x)) { res = flint_malloc(10); if (arf_is_nan(arb_midref(x))) strcpy(res, "nan"); else strcpy(res, "[+/- inf]"); return res; } fmpz_init(mid_exp); fmpz_init(rad_exp); arb_get_str_parts(&negative, &mid_digits, mid_exp, &rad_digits, rad_exp, x, n, more); if ((flags & ARB_STR_NO_RADIUS) && mid_digits[0] == '0') { fmpz_add_ui(rad_exp, rad_exp, strlen(rad_digits)); res = flint_malloc(fmpz_sizeinbase(rad_exp, 10) + 4); res[0] = '0'; res[1] = 'e'; if (fmpz_sgn(rad_exp) >= 0) { res[2] = '+'; fmpz_get_str(res + 3, 10, rad_exp); } else { fmpz_get_str(res + 2, 10, rad_exp); } } else { skip_mid = mid_digits[0] == '0'; skip_rad = (rad_digits[0] == '0') || ((flags & ARB_STR_NO_RADIUS) && !skip_mid); _arb_digits_as_float_str(&mid_digits, mid_exp, -4, FLINT_MAX(6, n - 1)); _arb_digits_as_float_str(&rad_digits, rad_exp, -2, 2); if (skip_rad) { res = flint_malloc(strlen(mid_digits) + 2); if (negative) strcpy(res, "-"); else strcpy(res, ""); strcat(res, mid_digits); } else if (skip_mid) { res = flint_malloc(strlen(rad_digits) + 7); strcpy(res, "[+/- "); strcat(res, rad_digits); strcat(res, "]"); } else { res = flint_malloc(strlen(mid_digits) + strlen(rad_digits) + 9); strcpy(res, "["); if (negative) strcat(res, "-"); strcat(res, mid_digits); strcat(res, " +/- "); strcat(res, rad_digits); strcat(res, "]"); } } if (condense) res = _arb_condense_digits(res, condense); flint_free(mid_digits); flint_free(rad_digits); fmpz_clear(mid_exp); fmpz_clear(rad_exp); return res; } arb-2.22.1/arb/get_ubound_arf.c000066400000000000000000000011021417376376500162520ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_get_ubound_arf(arf_t u, const arb_t x, slong prec) { arf_t t; arf_init_set_mag_shallow(t, arb_radref(x)); arf_add(u, arb_midref(x), t, prec, ARF_RND_CEIL); } arb-2.22.1/arb/get_unique_fmpz.c000066400000000000000000000046401417376376500165020ustar00rootroot00000000000000/* Copyright (C) 2012, 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_get_unique_fmpz(fmpz_t z, const arb_t x) { if (!arb_is_finite(x)) { return 0; } else if (arb_is_exact(x)) { /* x = b*2^e, e >= 0 */ if (arf_is_int(arb_midref(x))) { /* arf_get_fmpz aborts on overflow */ arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN); return 1; } else { return 0; } } /* if the radius is >= 1, there are at least two integers */ else if (mag_cmp_2exp_si(arb_radref(x), 0) >= 0) { return 0; } /* there are 0 or 1 integers if the radius is < 1 */ else { fmpz_t a, b, exp; int res; /* if the midpoint is exactly an integer, it is what we want */ if (arf_is_int(arb_midref(x))) { /* arf_get_fmpz aborts on overflow */ arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN); return 1; } fmpz_init(a); fmpz_init(b); fmpz_init(exp); /* if the radius is tiny, it can't be an integer */ arf_bot(a, arb_midref(x)); if (fmpz_cmp(a, MAG_EXPREF(arb_radref(x))) > 0) { res = 0; } else { arb_get_interval_fmpz_2exp(a, b, exp, x); if (COEFF_IS_MPZ(*exp)) { flint_printf("arb_get_unique_fmpz: input too large\n"); flint_abort(); } if (*exp >= 0) { res = fmpz_equal(a, b); if (res) { fmpz_mul_2exp(a, a, *exp); fmpz_mul_2exp(b, b, *exp); } } else { fmpz_cdiv_q_2exp(a, a, -(*exp)); fmpz_fdiv_q_2exp(b, b, -(*exp)); res = fmpz_equal(a, b); } if (res) fmpz_set(z, a); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); return res; } } arb-2.22.1/arb/hurwitz_zeta.c000066400000000000000000000017311417376376500160360ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "acb.h" void arb_hurwitz_zeta(arb_t res, const arb_t s, const arb_t z, slong prec) { if (!arb_contains_si(s, 1) && (arb_is_positive(z) || (arb_is_int(z) && arb_is_int(s) && arb_is_nonpositive(s)))) { acb_t a, b, c; acb_init(a); acb_init(b); acb_init(c); acb_set_arb(a, s); acb_set_arb(b, z); acb_hurwitz_zeta(c, a, b, prec); arb_set(res, acb_realref(c)); acb_clear(a); acb_clear(b); acb_clear(c); } else { arb_indeterminate(res); } } arb-2.22.1/arb/hypot.c000066400000000000000000000015171417376376500144440ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_hypot(arb_t z, const arb_t x, const arb_t y, slong prec) { if (arb_is_zero(y)) { arb_abs(z, x); } else if (arb_is_zero(x)) { arb_abs(z, y); } else { arb_t t; arb_init(t); /* TODO: use arb_fmma */ arb_mul(t, x, x, prec + 4); arb_mul(z, y, y, prec + 4); arb_add(t, t, z, prec + 4); arb_sqrtpos(z, t, prec); arb_clear(t); } } arb-2.22.1/arb/indeterminate.c000066400000000000000000000007531417376376500161320ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_indeterminate(arb_t x) { arf_nan(arb_midref(x)); mag_inf(arb_radref(x)); } arb-2.22.1/arb/inlines.c000066400000000000000000000006441417376376500147420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ARB_INLINES_C #include "arb.h" arb-2.22.1/arb/intersection.c000066400000000000000000000026721417376376500160120ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_intersection(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_t left, right, t, xr, yr; int result; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) { arb_indeterminate(z); return 1; } if (mag_is_inf(arb_radref(x)) && mag_is_inf(arb_radref(y))) { arb_zero_pm_inf(z); return 1; } result = arb_overlaps(x, y); if (result) { arf_init(left); arf_init(right); arf_init(t); arf_init_set_mag_shallow(xr, arb_radref(x)); arf_init_set_mag_shallow(yr, arb_radref(y)); arf_sub(left, arb_midref(x), xr, prec, ARF_RND_FLOOR); arf_sub(t, arb_midref(y), yr, prec, ARF_RND_FLOOR); arf_max(left, left, t); arf_add(right, arb_midref(x), xr, prec, ARF_RND_CEIL); arf_add(t, arb_midref(y), yr, prec, ARF_RND_CEIL); arf_min(right, right, t); arb_set_interval_arf(z, left, right, prec); arf_clear(left); arf_clear(right); arf_clear(t); } return result; } arb-2.22.1/arb/is_finite.c000066400000000000000000000007741417376376500152560ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_is_finite(const arb_t x) { return arf_is_finite(arb_midref(x)) && mag_is_finite(arb_radref(x)); } arb-2.22.1/arb/lambertw.c000066400000000000000000000401201417376376500151070ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/double_extras.h" /* Helper functions to compute W_{-1}(x) on (-1/e,0) in double precision -- just to get a good starting value for the multiprecision code, and not optimized for accuracy. Has underflow problems very close to 0. In part based on d_lambertw in flint/double_extras which implements the principal branch. */ #define ONE_OVER_E ldexp(6627126856707895.0, -54) #define CORRECTION 4.3082397558469466e-17 #define POLY(p, x) d_polyval((p), sizeof(p) / sizeof(double), (x)) static double d_halley(double x, double w) { double t, u, v; t = exp(w); u = 2*w + 2; v = w*t - x; t = w - u*v / (u*t*(w+1) - (w+2)*v); return t; } static const double pol1[11] = { -1.0000000000000000000, 2.3316439815971242034, -1.8121878856393634902, 1.9366311144923597554, -2.3535512018816145168, 3.0668589010506319129, -4.1753356002581771389, 5.8580237298747741488, -8.4010322175239773710, 12.250753501314460424, -18.100697012472442755 }; static const double pol2[4] = { -5.2012020327515463962,-24.075862656446909233, -26.500221957196285366,2.3340178581744999812 }; static const double pol3[4] = { 1.0000000000000000000,0.14831080741950550754, -13.649088405005569258,-18.975103873227202378 }; static const double pol4[5] = { -8.4834127832006526854,634.84191267691313548,-2640.6635889188399862, -12935.640726994524734,-7875.3418281832619890 }; static const double pol5[5] = { 1.0,-121.07185283214167442,1287.5430771188798866, 1550.0693150055578327,-3278.4808321541988073 }; static const double pol6[5] = { -12.169991898228748602,32778.761570863291802,-1.0480461503378867869e7, 4.7898751364090879209e8,-7.802332913704000874e8 }; static const double pol7[5] = { 1.0,-3556.4306263369027831,1.4761527435056145298e6, -9.8425904825010893103e7,7.0373606710750560344e8 }; double d_lambertw_branch1(double x) { double w, u; if (x < -ONE_OVER_E || x >= 0.0) { return D_NAN; } else if (x < -ONE_OVER_E + 1/32.) { w = POLY(pol1, -sqrt((x + ONE_OVER_E) + CORRECTION)); if (x + ONE_OVER_E > 0.0003) w = d_halley(x, w); return w; } else if (x <= -1/4.) { return d_halley(x, POLY(pol2,x) / POLY(pol3,x)); } else if (x < -1/32.) { return d_halley(x, POLY(pol4,x) / POLY(pol5,x)); } else if (x < - 1/1024.) { return d_halley(x, POLY(pol6,x) / POLY(pol7,x)); } else { w = log(-x); u = log(-w); w = (2*w*w*w - 2*(1+(w-1)*w)*u + u*u)/(2*w*w); if (x < -1e-15) w = d_halley(x, w); return d_halley(x, w); } } /* If branch == 0, bounds |W'(x)|. If branch != 0, bounds W_{-1}'(x). For the principal branch: For x >= 0, W'(x) <= 1/(x+1). For x > -1/e, W'(x) < 2 / sqrt(1+e*x). For the -1 branch: |W'(x)| <= 2 / sqrt(1+e*x) + 2/|x|. */ void arb_lambertw_bound_prime(mag_t w, const arb_t x, int branch, slong prec) { arb_t t; mag_t u, v; arb_init(t); mag_init(u); mag_init(v); if (arb_is_nonnegative(x) && branch == 0) { arb_get_mag_lower(w, x); mag_one(u); mag_add_lower(w, w, u); mag_div(w, u, w); } else { arb_const_e(t, prec); arb_mul(t, t, x, prec); arb_add_ui(t, t, 1, prec); arb_get_mag_lower(w, t); mag_rsqrt(w, w); mag_mul_2exp_si(w, w, 1); if (branch != 0) { if (arb_is_negative(x)) { arb_get_mag_lower(u, x); mag_set_ui(v, 2); mag_div(v, v, u); mag_add(w, w, v); } else { mag_inf(w); } } } arb_clear(t); mag_clear(u); mag_clear(v); } /* Given an approximation w for W(x), compute a rigorous error bound. The precomputed value ew = e^w is optional. */ void arb_lambertw_bound_error(mag_t res, const arb_t x, const arf_t w, const arb_t ew, int branch, slong prec) { arb_t r, x2; mag_t m; /* Make sure that we are somewhere on the right branch. */ if ((branch == 0 && arf_cmp_si(w, -1) < 0) || (branch == 1 && arf_cmp_si(w, -1) > 0)) { mag_inf(res); return; } arb_init(r); arb_init(x2); mag_init(m); if (ew != NULL) { arb_set(r, ew); } else { arb_set_arf(r, w); arb_exp(r, r, prec); } /* x2 = w e^w */ arb_mul_arf(x2, r, w, prec); /* r = x2 - x */ arb_sub(r, x2, x, prec); arb_get_mag(m, r); /* x2 = min(x, x+r) (W'(t) is decreasing with t) */ if (branch == 0) { arb_min(x2, x, x2, prec); } else { arb_union(x2, x, x2, prec); } arb_lambertw_bound_prime(res, x2, branch, prec); mag_mul(res, res, m); arb_clear(r); arb_clear(x2); mag_clear(m); } /* Halley iteration: res = w - (w e^w - x) / (e^w (w+1) - (w+2)(w e^w - x) / (2w+2)) If certify is set, writes rigorous error bound to the radius. */ static void arb_lambertw_halley_step(arb_t res, const arb_t x, const arf_t w, int branch, int certify, slong prec) { arf_t t, u, v; arb_t ew; mag_t err; arb_init(ew); arf_init(t); arf_init(u); arf_init(v); mag_init(err); arb_set_arf(ew, w); arb_exp(ew, ew, prec); /* todo: extra precision with large exponents? */ arf_add_ui(u, w, 2, prec, ARF_RND_DOWN); arf_add_ui(v, w, 1, prec, ARF_RND_DOWN); arf_mul_2exp_si(v, v, 1); arf_div(v, u, v, prec, ARF_RND_DOWN); /* v = (w + 2) / (2w + 2) */ arf_mul(t, arb_midref(ew), w, prec, ARF_RND_DOWN); /* t = w e^w */ arf_sub(u, t, arb_midref(x), prec, ARF_RND_DOWN); /* u = w e^w - x */ arf_mul(v, v, u, prec, ARF_RND_DOWN); arf_neg(v, v); arf_add(v, v, t, prec, ARF_RND_DOWN); arf_add(v, v, arb_midref(ew), prec, ARF_RND_DOWN); arf_div(t, u, v, prec, ARF_RND_DOWN); /* t is our new approximation for W */ arf_sub(t, w, t, prec, ARF_RND_DOWN); if (certify) { arb_t et; arb_init(et); /* Inverse: x2 = t e^t. We already have e^w, so compute e^t = e^w e^(t-w). */ arb_set_arf(et, w); arb_sub_arf(et, et, t, prec); arb_neg(et, et); arb_exp(et, et, prec); arb_mul(et, et, ew, prec); arb_lambertw_bound_error(err, x, t, et, branch, prec); arb_clear(et); } arf_swap(arb_midref(res), t); mag_swap(arb_radref(res), err); arb_clear(ew); arf_clear(t); arf_clear(u); arf_clear(v); mag_clear(err); } /* Double precision approximation good for x >= 2^1000, or roughly |x| <= 2^(1000-60) for the -1 branch. */ slong arb_lambertw_initial_asymp1(arf_t res, const arf_t x, int branch, slong prec) { fmpz_t e; double l, ll, h, t2, t3, t4; fmpz_init(e); arf_frexp(res, e, x); l = arf_get_d(res, ARF_RND_DOWN); if (branch) l = -l; l = log(l); l += fmpz_get_d(e) * 0.6931471805599453; ll = l; if (branch) ll = -ll; ll = log(ll); h = 1.0 / l; t2 = ll * (ll - 2) * 0.5; t3 = ll * (6 + ll * (2 * ll - 9)) * (1.0 / 6.0); t4 = ll * (-12 + ll * (36 + ll*(-22 + 3*ll))) * (1.0 / 12.0); l = l - ll + h * (ll + h * (t2 + h * (t3 + t4 * h))); arf_set_d(res, l); fmpz_clear(e); return 50; } /* First terms of asymptotic series, with higher precision, for huge exponents... */ static void _arf_log(arf_t res, const arf_t x, slong prec) { arb_t t; arb_init(t); arb_set_arf(t, x); arb_log(t, t, prec); arf_swap(res, arb_midref(t)); arb_clear(t); } slong arb_lambertw_initial_asymp2(arf_t res, const arf_t x, int branch, slong prec) { arf_t l, ll; slong wp, acc; acc = 2 * fmpz_bits(ARF_EXPREF(x)) - 10; arf_init(l); arf_init(ll); wp = acc + 4; if (branch) { arf_neg(l, x); _arf_log(l, l, wp); arf_neg(ll, l); _arf_log(ll, ll, wp); } else { _arf_log(l, x, wp); _arf_log(ll, l, wp); } arf_div(res, ll, l, wp, ARF_RND_DOWN); arf_sub(res, res, ll, wp, ARF_RND_DOWN); arf_add(res, res, l, wp, ARF_RND_DOWN); arf_clear(l); arf_clear(ll); return acc; } /* Computes initial approximation of W(x). Returns estimated accuracy in bits, clamped between 0 and a reasonable value related to the bit length of the exponent of x; thus the return value plus 2 can be used as a precision. */ slong arb_lambertw_initial(arf_t res, const arf_t x, int branch, slong prec) { if (arf_cmp_d(x, -ONE_OVER_E + 0.001) >= 0) { if (branch == 0) { if (arf_cmpabs_2exp_si(x, -prec) < 0) { arf_set(res, x); return prec; } else if (arf_cmpabs_2exp_si(x, -30) < 0) { slong acc; arf_set(res, x); acc = -arf_abs_bound_lt_2exp_si(res); return FLINT_MIN(acc, prec); } else if (arf_cmpabs_2exp_si(x, 1000) > 0) { if (fmpz_bits(ARF_EXPREF(x)) > 40) return arb_lambertw_initial_asymp2(res, x, branch, prec); else return arb_lambertw_initial_asymp1(res, x, branch, prec); } else { arf_set_d(res, d_lambertw(arf_get_d(x, ARF_RND_DOWN))); return 50; } } else { /* slightly smaller than the double exponent limit since d_lambertw_branch1 is unclever about underflowing */ if (arf_cmpabs_2exp_si(x, -940) < 0) { if (fmpz_bits(ARF_EXPREF(x)) > 40) return arb_lambertw_initial_asymp2(res, x, branch, prec); else return arb_lambertw_initial_asymp1(res, x, branch, prec); } else { arf_set_d(res, d_lambertw_branch1(arf_get_d(x, ARF_RND_DOWN))); return 50; } } } else { /* Expand at -1/e */ static const int coeffs[] = {-130636800,130636800,-43545600,19958400, -10402560,5813640,-3394560,2042589,-1256320}; arb_t v; arf_t s; slong wp, k, acc; /* todo: could change precision dynamically depending on the closeness to -1/e */ wp = 2 * prec + 20; arb_init(v); arf_init(s); arb_const_e(v, wp); arb_mul_arf(v, v, x, wp); arb_add_ui(v, v, 1, wp); arb_mul_2exp_si(v, v, 1); arb_sqrt(v, v, wp); if (branch) arb_neg(v, v); for (k = 8; k >= 0; k--) { arf_mul(s, s, arb_midref(v), wp, ARF_RND_DOWN); arf_add_si(s, s, coeffs[k], wp, ARF_RND_DOWN); } arf_div_si(s, s, -coeffs[0], wp, ARF_RND_DOWN); arf_set(res, s); arb_clear(v); arf_clear(s); /* Due to the arithmetic we should get no more than wp accurate bits */ acc = wp; /* Truncation error is of order v^9 */ if (!arf_is_special(arb_midref(v))) acc = FLINT_MIN(acc, 9 * (-ARF_EXP(arb_midref(v)))); acc = FLINT_MAX(acc, 0); return acc; } } void arb_lambertw(arb_t res, const arb_t x, int flags, slong prec) { slong acc, wp, goal; slong ebits, ebits2; arb_t t, w; mag_t err; int branch; branch = flags & 1; if (!arb_is_finite(x)) { arb_indeterminate(res); return; } if (branch == 1 && !arb_is_negative(x)) { arb_indeterminate(res); return; } if (arb_is_zero(x)) { arb_zero(res); return; } /* Quick estimate of log(x) and log(log(x)). */ ebits = fmpz_bits(ARF_EXPREF(arb_midref(x))); ebits2 = FLINT_BIT_COUNT(ebits) + 2; /* Estimated accuracy goal. */ goal = arb_rel_accuracy_bits(x); goal = FLINT_MAX(goal, 0); goal = FLINT_MIN(goal, prec); /* For huge x, we gain bits from the exponent. */ if (branch == 0 && goal > 0 && arf_cmp_2exp_si(arb_midref(x), 10) > 0) goal = FLINT_MIN(goal + ebits - ebits2, prec); wp = goal + 4; /* Handle huge x directly. For x >= e, |W(x) - (log(x) - log(log(x)))| < 2/log(log(x))/log(x). (J. Inequal. Pure and Appl. Math., 9 (2) (2008), Art. 51). Note W(x) ~= log(x), so relative error is ~= log(log(x)) / log(x)^2. */ if (branch == 0 && arf_cmp_2exp_si(arb_midref(x), 10) > 0 && 2 * ebits - ebits2 > wp) { mag_t l, ll; arb_init(t); mag_init(l); mag_init(ll); arb_log(t, x, wp); arb_log(res, t, FLINT_MAX(wp - ebits + ebits2, 10)); if (arb_is_positive(res)) { arb_get_mag_lower(l, t); arb_get_mag(ll, res); arb_sub(res, t, res, prec); mag_div(l, ll, l); mag_mul_2exp_si(l, l, 1); arb_add_error_mag(res, l); } else { arb_indeterminate(res); } arb_clear(t); mag_clear(l); mag_clear(ll); return; } /* Handle tiny x directly. For k >= 2, |c_k| <= 4^k / 16. */ if (branch == 0 && arf_cmpabs_2exp_si(arb_midref(x), -10) < 0 && ebits > wp / 2) { mag_init(err); arb_get_mag(err, x); mag_mul_2exp_si(err, err, 2); if (ebits > wp) { arb_set_round(res, x, prec); mag_geom_series(err, err, 2); } else { arb_set(res, x); arb_submul(res, res, res, prec); mag_geom_series(err, err, 3); } mag_mul_2exp_si(err, err, -4); arb_add_error_mag(res, err); mag_clear(err); return; } arb_init(t); arb_init(w); mag_init(err); acc = arb_lambertw_initial(arb_midref(w), arb_midref(x), branch, wp); if (acc <= 2) { arb_indeterminate(w); } else if (acc >= wp) { arb_lambertw_bound_error(arb_radref(w), x, arb_midref(w), NULL, branch, FLINT_MAX(acc, 30)); } else { slong k, padding, nextstep, maxstep, *steps; double rate, nearm1; steps = flint_malloc(sizeof(slong) * FLINT_BITS); /* Asymptotically, the Halley iteration triples the number of accurate bits. However, with a very large exponent we need some guard bits (due to evaluating the exponential?). This is heuristic. A better analysis should be possible. */ rate = 2.0 + 1.0 / (1.0 + 0.01 * ebits); padding = 6 * ebits2; /* extra padding near -1/e */ nearm1 = arf_get_d(arb_midref(w), ARF_RND_DOWN); if (fabs(nearm1 + 1.0) < 0.01) { arf_add_ui(arb_midref(t), arb_midref(w), 1, 30, ARF_RND_DOWN); if (arf_is_zero(arb_midref(t))) padding += prec; else { slong ee = -ARF_EXP(arb_midref(t)); padding += FLINT_MIN(FLINT_MAX(2 * ee, 0), prec); } } maxstep = 0; steps[0] = wp; for (k = 1; k < FLINT_BITS; k++) { nextstep = steps[k - 1] / rate + padding; if (nextstep > acc) { steps[k] = nextstep; maxstep = k; } else break; } for (k = maxstep; k >= 0; k--) { arb_lambertw_halley_step(w, x, arb_midref(w), branch, (k == 0), steps[k] + 5); } flint_free(steps); } arb_set_round(res, w, prec); arb_clear(t); arb_clear(w); mag_clear(err); } arb-2.22.1/arb/load_file.c000066400000000000000000000011711417376376500152130ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "arb.h" int arb_load_file(arb_t x, FILE* stream) { int err; err = arf_load_file(arb_midref(x), stream); if (err) return err; err = mag_load_file(arb_radref(x), stream); return err; } arb-2.22.1/arb/load_str.c000066400000000000000000000024051417376376500151050ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" #include "arf.h" #include "mag.h" int arb_load_str(arb_t x, const char* data) { size_t midlen, maglen; char * mid; char * mag; int err = 0; const char* split = strchr(data, ' '); if (split == NULL) { return 1; } split = strchr(split + 1, ' '); if (split == NULL) { return 1; } midlen = (size_t)(split - data); mid = (char*)flint_malloc(midlen + 1); strncpy(mid, data, midlen); mid[midlen] = '\0'; maglen = strlen(data) - midlen - 1; mag = (char*)flint_malloc(maglen + 1); strncpy(mag, split + 1, maglen); mag[maglen] = '\0'; err = arf_load_str(arb_midref(x), mid); if (err) { flint_free(mid); flint_free(mag); return err; } err = mag_load_str(arb_radref(x), mag); flint_free(mid); flint_free(mag); return err; } arb-2.22.1/arb/log.c000066400000000000000000000060561417376376500140650ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_log(arb_t res, const arb_t x, slong prec) { if (arb_is_exact(x)) { arb_log_arf(res, arb_midref(x), prec); } else { /* Let the input be [a-b, a+b]. We require a > b >= 0 (otherwise the interval contains zero or a negative number and the logarithm is not defined). The error is largest at a-b, and we have log(a) - log(a-b) = log(1 + b/(a-b)). */ mag_t t; mag_init(t); arb_get_mag_lower_nonnegative(t, x); if (mag_is_zero(t)) { arf_nan(arb_midref(res)); mag_inf(arb_radref(res)); } else if (mag_is_inf(t)) { arf_pos_inf(arb_midref(res)); mag_zero(arb_radref(res)); } else { slong acc; acc = arb_rel_accuracy_bits(x); acc = FLINT_MIN(acc, prec); acc += fmpz_bits(MAG_EXPREF(t)); if (acc < 20) { mag_t u; mag_init(u); arb_get_mag(u, x); if (mag_cmp_2exp_si(t, 0) >= 0) { mag_log_lower(t, t); mag_log(u, u); arb_set_interval_mag(res, t, u, prec); } else if (mag_cmp_2exp_si(u, 0) <= 0) { mag_neg_log_lower(u, u); mag_neg_log(t, t); arb_set_interval_mag(res, u, t, prec); arb_neg(res, res); } else { mag_neg_log(t, t); mag_log(u, u); arb_set_interval_neg_pos_mag(res, t, u, prec); } mag_clear(u); } else { acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); mag_div(t, arb_radref(x), t); mag_log1p(t, t); arb_log_arf(res, arb_midref(x), prec); mag_add(arb_radref(res), arb_radref(res), t); } } mag_clear(t); } } void arb_log_ui(arb_t z, ulong x, slong prec) { if (x == 2) { arb_const_log2(z, prec); } else if (x == 10) { arb_const_log10(z, prec); } else { arf_t t; arf_init(t); arf_set_ui(t, x); arb_log_arf(z, t, prec); arf_clear(t); } } void arb_log_fmpz(arb_t z, const fmpz_t x, slong prec) { arf_t t; arf_init(t); arf_set_fmpz(t, x); arb_log_arf(z, t, prec); arf_clear(t); } arb-2.22.1/arb/log1p.c000066400000000000000000000026211417376376500143200ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void arb_log1p_tiny(arb_t r, const arb_t z, slong prec) { mag_t b, c; arb_t t; mag_init(b); mag_init(c); arb_init(t); /* if |z| < 1, then |log(1+z) - [z - z^2/2]| <= |z|^3/(1-|z|) */ arb_get_mag(b, z); mag_one(c); mag_sub_lower(c, c, b); mag_pow_ui(b, b, 3); mag_div(b, b, c); arb_mul(t, z, z, prec); arb_mul_2exp_si(t, t, -1); arb_sub(r, z, t, prec); if (mag_is_finite(b)) arb_add_error_mag(r, b); else arb_indeterminate(r); mag_clear(b); mag_clear(c); arb_clear(t); } void arb_log1p(arb_t r, const arb_t z, slong prec) { slong magz; if (arb_is_zero(z)) { arb_zero(r); return; } magz = arf_abs_bound_lt_2exp_si(arb_midref(z)); if (magz < -prec) { arb_log1p_tiny(r, z, prec); } else { if (magz < 0) arb_add_ui(r, z, 1, prec + (-magz) + 4); else arb_add_ui(r, z, 1, prec + 4); arb_log(r, r, prec); } } arb-2.22.1/arb/log_arf.c000066400000000000000000000241361417376376500147140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define TMP_ALLOC_LIMBS(size) TMP_ALLOC((size) * sizeof(mp_limb_t)) /* requires x != 1 */ static void arf_log_via_mpfr(arf_t z, const arf_t x, slong prec, arf_rnd_t rnd) { mpfr_t xf, zf; mp_ptr zptr, tmp; mp_srcptr xptr; mp_size_t xn, zn, val; TMP_INIT; TMP_START; zn = (prec + FLINT_BITS - 1) / FLINT_BITS; tmp = TMP_ALLOC(zn * sizeof(mp_limb_t)); ARF_GET_MPN_READONLY(xptr, xn, x); xf->_mpfr_d = (mp_ptr) xptr; xf->_mpfr_prec = xn * FLINT_BITS; xf->_mpfr_sign = ARF_SGNBIT(x) ? -1 : 1; xf->_mpfr_exp = ARF_EXP(x); zf->_mpfr_d = tmp; zf->_mpfr_prec = prec; zf->_mpfr_sign = 1; zf->_mpfr_exp = 0; mpfr_set_emin(MPFR_EMIN_MIN); mpfr_set_emax(MPFR_EMAX_MAX); mpfr_log(zf, xf, arf_rnd_to_mpfr(rnd)); val = 0; while (tmp[val] == 0) val++; ARF_GET_MPN_WRITE(zptr, zn - val, z); flint_mpn_copyi(zptr, tmp + val, zn - val); if (zf->_mpfr_sign < 0) ARF_NEG(z); fmpz_set_si(ARF_EXPREF(z), zf->_mpfr_exp); TMP_END; } void arb_log_arf_huge(arb_t z, const arf_t x, slong prec) { arf_t t; arb_t c; fmpz_t exp; slong wp; arf_init(t); arb_init(c); fmpz_init(exp); fmpz_neg(exp, ARF_EXPREF(x)); arf_mul_2exp_fmpz(t, x, exp); wp = prec + 4 - fmpz_bits(exp); wp = FLINT_MAX(wp, 4); arb_log_arf(z, t, wp); arb_const_log2(c, prec + 4); arb_submul_fmpz(z, c, exp, prec); arf_clear(t); arb_clear(c); fmpz_clear(exp); } void arb_log_arf(arb_t z, const arf_t x, slong prec) { if (arf_is_special(x)) { if (arf_is_pos_inf(x)) arb_pos_inf(z); else arb_indeterminate(z); } else if (ARF_SGNBIT(x)) { arb_indeterminate(z); } else if (ARF_IS_POW2(x)) { if (fmpz_is_one(ARF_EXPREF(x))) { arb_zero(z); } else { fmpz_t exp; fmpz_init(exp); _fmpz_add_fast(exp, ARF_EXPREF(x), -1); arb_const_log2(z, prec + 2); arb_mul_fmpz(z, z, exp, prec); fmpz_clear(exp); } } else if (COEFF_IS_MPZ(ARF_EXP(x))) { arb_log_arf_huge(z, x, prec); } else { slong exp, wp, wn, N, r, closeness_to_one; mp_srcptr xp; mp_size_t xn, tn; mp_ptr tmp, w, t, u; mp_limb_t p1, q1bits, p2, q2bits, error, error2, cy; int negative, inexact, used_taylor_series; TMP_INIT; exp = ARF_EXP(x); negative = 0; ARF_GET_MPN_READONLY(xp, xn, x); /* compute a c >= 0 such that |x-1| <= 2^(-c) if c > 0 */ closeness_to_one = 0; if (exp == 0) { slong i; closeness_to_one = FLINT_BITS - FLINT_BIT_COUNT(~xp[xn - 1]); if (closeness_to_one == FLINT_BITS) { for (i = xn - 2; i > 0 && xp[i] == LIMB_ONES; i--) closeness_to_one += FLINT_BITS; closeness_to_one += (FLINT_BITS - FLINT_BIT_COUNT(~xp[i])); } } else if (exp == 1) { closeness_to_one = FLINT_BITS - FLINT_BIT_COUNT(xp[xn - 1] & (~LIMB_TOP)); if (closeness_to_one == FLINT_BITS) { slong i; for (i = xn - 2; xp[i] == 0; i--) closeness_to_one += FLINT_BITS; closeness_to_one += (FLINT_BITS - FLINT_BIT_COUNT(xp[i])); } closeness_to_one--; } /* if |t-1| <= 0.5 */ /* |log(1+t) - t| <= t^2 */ /* |log(1+t) - (t-t^2/2)| <= t^3 */ if (closeness_to_one > prec + 1) { inexact = arf_sub_ui(arb_midref(z), x, 1, prec, ARB_RND); mag_set_ui_2exp_si(arb_radref(z), 1, -2 * closeness_to_one); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); return; } else if (2 * closeness_to_one > prec + 1) { arf_t t, u; arf_init(t); arf_init(u); arf_sub_ui(t, x, 1, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(u, t, t, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul_2exp_si(u, u, -1); inexact = arf_sub(arb_midref(z), t, u, prec, ARB_RND); mag_set_ui_2exp_si(arb_radref(z), 1, -3 * closeness_to_one); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); arf_clear(t); arf_clear(u); return; } /* Absolute working precision (NOT rounded to a limb multiple) */ wp = prec + closeness_to_one + 5; /* Too high precision to use table */ if (wp > ARB_LOG_TAB2_PREC) { /* The earlier test for COEFF_IS_MPZ(ARF_EXP(x)) rules out too large exponents for MPFR, except on Windows 64 where MPFR still uses 32-bit exponents. */ if (exp < MPFR_EMIN_MIN || exp > MPFR_EMAX_MAX) { arb_log_arf_huge(z, x, prec); } else { arf_log_via_mpfr(arb_midref(z), x, prec, ARB_RND); arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); } return; } /* Working precision in limbs */ wn = (wp + FLINT_BITS - 1) / FLINT_BITS; TMP_START; tmp = TMP_ALLOC_LIMBS(4 * wn + 3); w = tmp; /* requires wn+1 limbs */ t = w + wn + 1; /* requires wn+1 limbs */ u = t + wn + 1; /* requires 2wn+1 limbs */ /* read x-1 */ if (xn <= wn) { flint_mpn_zero(w, wn - xn); mpn_lshift(w + wn - xn, xp, xn, 1); error = 0; } else { mpn_lshift(w, xp + xn - wn, wn, 1); error = 1; } /* First table-based argument reduction */ if (wp <= ARB_LOG_TAB1_PREC) q1bits = ARB_LOG_TAB11_BITS; else q1bits = ARB_LOG_TAB21_BITS; p1 = w[wn-1] >> (FLINT_BITS - q1bits); /* Special case: covers logarithms of small integers */ if (xn == 1 && (w[wn-1] == (p1 << (FLINT_BITS - q1bits)))) { p2 = 0; flint_mpn_zero(t, wn); used_taylor_series = 0; N = r = 0; /* silence compiler warning */ } else { /* log(1+w) = log(1+p/q) + log(1 + (qw-p)/(p+q)) */ w[wn] = mpn_mul_1(w, w, wn, UWORD(1) << q1bits) - p1; mpn_divrem_1(w, 0, w, wn + 1, p1 + (UWORD(1) << q1bits)); error += 1; /* Second table-based argument reduction (fused with log->atanh conversion) */ if (wp <= ARB_LOG_TAB1_PREC) q2bits = ARB_LOG_TAB11_BITS + ARB_LOG_TAB12_BITS; else q2bits = ARB_LOG_TAB21_BITS + ARB_LOG_TAB22_BITS; p2 = w[wn-1] >> (FLINT_BITS - q2bits); u[2 * wn] = mpn_lshift(u + wn, w, wn, q2bits); flint_mpn_zero(u, wn); flint_mpn_copyi(t, u + wn, wn + 1); t[wn] += p2 + (UWORD(1) << (q2bits + 1)); u[2 * wn] -= p2; mpn_tdiv_q(w, u, 2 * wn + 1, t, wn + 1); /* propagated error from 1 ulp error: 2 atanh'(1/3) = 2.25 */ error += 3; /* |w| <= 2^-r */ r = _arb_mpn_leading_zeros(w, wn); /* N >= (wp-r)/(2r) */ N = (wp - r + (2*r-1)) / (2*r); N = FLINT_MAX(N, 0); /* Evaluate Taylor series */ _arb_atan_taylor_rs(t, &error2, w, wn, N, 0); /* Multiply by 2 */ mpn_lshift(t, t, wn, 1); /* Taylor series evaluation error (multiply by 2) */ error += error2 * 2; used_taylor_series = 1; } /* Size of output number */ tn = wn; /* First table lookup */ if (p1 != 0) { if (wp <= ARB_LOG_TAB1_PREC) mpn_add_n(t, t, arb_log_tab11[p1] + ARB_LOG_TAB1_LIMBS - tn, tn); else mpn_add_n(t, t, arb_log_tab21[p1] + ARB_LOG_TAB2_LIMBS - tn, tn); error++; } /* Second table lookup */ if (p2 != 0) { if (wp <= ARB_LOG_TAB1_PREC) mpn_add_n(t, t, arb_log_tab12[p2] + ARB_LOG_TAB1_LIMBS - tn, tn); else mpn_add_n(t, t, arb_log_tab22[p2] + ARB_LOG_TAB2_LIMBS - tn, tn); error++; } /* add exp * log(2) */ exp--; if (exp > 0) { cy = mpn_addmul_1(t, arb_log_log2_tab + ARB_LOG_TAB2_LIMBS - tn, tn, exp); t[tn] = cy; tn += (cy != 0); error += exp; } else if (exp < 0) { t[tn] = 0; u[tn] = mpn_mul_1(u, arb_log_log2_tab + ARB_LOG_TAB2_LIMBS - tn, tn, -exp); if (mpn_cmp(t, u, tn + 1) >= 0) { mpn_sub_n(t, t, u, tn + 1); } else { mpn_sub_n(t, u, t, tn + 1); negative = 1; } error += (-exp); tn += (t[tn] != 0); } /* The accumulated arithmetic error */ mag_set_ui_2exp_si(arb_radref(z), error, -wn * FLINT_BITS); /* Truncation error from the Taylor series */ if (used_taylor_series) mag_add_ui_2exp_si(arb_radref(z), arb_radref(z), 1, -r*(2*N+1) + 1); /* Set the midpoint */ inexact = _arf_set_mpn_fixed(arb_midref(z), t, tn, wn, negative, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); TMP_END; } } arb-2.22.1/arb/log_base_ui.c000066400000000000000000000117451417376376500155550ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static double _arf_get_mantissa_d(const arf_t x) { mp_srcptr xp; mp_size_t xn; ARF_GET_MPN_READONLY(xp, xn, x); if (xn == 1) return (double) xp[0] * ldexp(1.0, -FLINT_BITS); else return ((double) xp[xn - 1]) * ldexp(1.0, -FLINT_BITS) + ((double) xp[xn - 2]) * ldexp(1.0, -2 * FLINT_BITS); } void arb_log_base_ui(arb_t res, const arb_t x, ulong b, slong prec) { arb_t t; slong xexp, xbits; if (b <= 1) { arb_indeterminate(res); return; } if (arb_is_exact(x) && arf_sgn(arb_midref(x)) > 0) { xbits = arb_bits(x); xexp = ARF_EXP(arb_midref(x)); /* x = 1 */ if (xbits == 1 && ARF_EXP(arb_midref(x)) == 1) { arb_zero(res); return; } /* powers of two */ if ((b & (b - 1)) == 0 && xbits == 1) { fmpz_t e; fmpz_init(e); fmpz_sub_ui(e, ARF_EXPREF(arb_midref(x)), 1); if (b == 2) { arb_set_round_fmpz(res, e, prec); } else { arb_set_fmpz(res, e); arb_div_ui(res, res, FLINT_BIT_COUNT(b) - 1, prec); } fmpz_clear(e); return; } /* check for other exact powers */ if ((b & (b - 1)) != 0 && xbits != 1) { /* exactness is only possible if x is moderate, and an integer */ if (!COEFF_IS_MPZ(xexp) && xbits <= xexp) { ulong b_reduced; int b_exp; /* Write b as (b_reduced)^(1/2^(b_exp)). */ /* More generally, we could look for nth roots, but the result will not be exact when dividing by a non-power-of-two, so that is just a possible optimization at high precision. */ b_reduced = b; b_exp = 0; if (b >= 25 || b == 9) { ulong s, r; s = n_sqrtrem(&r, b_reduced); while (r == 0) { b_reduced = s; b_exp++; s = n_sqrtrem(&r, b_reduced); } } /* x fits a ulong */ if (xexp <= FLINT_BITS) { ulong n, a, hi, v; ARF_GET_TOP_LIMB(v, arb_midref(x)); v >>= (FLINT_BITS - xexp); for (a = b_reduced, n = 1, hi = 0; a <= v && hi == 0; n++) { if (a == v) { arf_set_ui_2exp_si(arb_midref(res), n, -b_exp); mag_zero(arb_radref(res)); arb_set_round(res, res, prec); return; } umul_ppmm(hi, a, a, b_reduced); } } /* general case (if b = 10, first count bits to rule out many non-powers-of-10 -- could perhaps generalize this to other b) */ else if (b_reduced != 10 || (xbits < xexp && xexp < xbits * 2)) { ulong n; double xlog; /* libm.log should be accurate enough since we will certainly have bits(n) << 53. Worst case, we will not get the exact logarithm and fall back to compute an approximate logarithm. */ xlog = _arf_get_mantissa_d(arb_midref(x)); xlog = log(xlog) + xexp * 0.69314718055994530942; xlog = xlog / log(b_reduced); n = (ulong) (xlog + 0.5); if (n >= 2 && fabs(xlog - n) < 0.01) { arb_init(t); arb_ui_pow_ui(t, b_reduced, n, xbits + 10); if (arb_equal(t, x)) { arf_set_ui_2exp_si(arb_midref(res), n, -b_exp); mag_zero(arb_radref(res)); arb_set_round(res, res, prec); arb_clear(t); return; } arb_clear(t); } } } } } /* generic case */ arb_init(t); arb_log(res, x, prec + 3); arb_log_ui(t, b, prec + 3); arb_div(res, res, t, prec); arb_clear(t); } arb-2.22.1/arb/log_hypot.c000066400000000000000000000113721417376376500153050ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void arb_log_abs(arb_t res, const arb_t a, slong prec) { if (arb_is_positive(a)) { arb_log(res, a, prec); } else if (arb_is_negative(a)) { arb_neg(res, a); arb_log(res, res, prec); } else { arb_indeterminate(res); } } static int arf_close_to_one(const arf_t z) { mp_limb_t top; if (ARF_EXP(z) == 0) { ARF_GET_TOP_LIMB(top, z); return (top >> (FLINT_BITS - 4)) == 15; } else if (ARF_EXP(z) == 1) { ARF_GET_TOP_LIMB(top, z); return (top >> (FLINT_BITS - 4)) == 8; } return 0; } void arb_log_hypot(arb_t res, const arb_t a, const arb_t b, slong prec) { slong acc; arb_t x; if (arb_is_zero(b)) { arb_log_abs(res, a, prec); return; } if (arb_is_zero(a)) { arb_log_abs(res, b, prec); return; } if (!arb_is_finite(a) || !arb_is_finite(b)) { if (arf_is_nan(arb_midref(a)) || arf_is_nan(arb_midref(b))) { arb_indeterminate(res); } else if ((!arb_is_finite(a) && !arb_contains_zero(a)) || (!arb_is_finite(b) && !arb_contains_zero(b))) { arb_pos_inf(res); } else { arb_indeterminate(res); } return; } /* a close to 1 -- for accurate arb_log1p */ if (mag_cmp_2exp_si(arb_radref(a), -3) < 0 && mag_cmp_2exp_si(arb_radref(b), -3) < 0 && arf_cmpabs_2exp_si(arb_midref(b), -3) < 0 && arf_close_to_one(arb_midref(a))) { arb_t y; arb_init(x); arb_init(y); if (arf_sgn(arb_midref(a)) > 0) { arb_sub_ui(y, a, 1, prec + 8); arb_mul(x, y, y, prec + 8); arb_addmul(x, b, b, prec + 8); arb_mul_2exp_si(y, y, 1); arb_add(x, x, y, prec + 8); } else { arb_add_ui(y, a, 1, prec + 8); arb_mul(x, y, y, prec + 8); arb_addmul(x, b, b, prec + 8); arb_mul_2exp_si(y, y, 1); arb_sub(x, x, y, prec + 8); } arb_log1p(res, x, prec); arb_mul_2exp_si(res, res, -1); arb_clear(x); arb_clear(y); return; } arb_init(x); /* todo: write an arb_sosq function */ /* todo: for very wide input, we could predict that a^2+b^2 will have low accuracy without computing it and go more quickly to the interval case -- however, a first failed attempt to write such code proved that it's actually somewhat complicated to do... */ arb_mul(x, a, a, FLINT_MAX(MAG_BITS, prec) + 8); arb_addmul(x, b, b, FLINT_MAX(MAG_BITS, prec) + 8); acc = arb_rel_accuracy_bits(x); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); if (acc > 10) { arb_log(res, x, prec); arb_mul_2exp_si(res, res, -1); } else { mag_t t, u, v; mag_init(t); mag_init(u); mag_init(v); arb_get_mag_lower(t, a); arb_get_mag_lower(u, b); if (!arb_contains_zero(x)) acc += fmpz_bits(ARF_EXPREF(arb_midref(x))); if (mag_is_zero(t) && mag_is_zero(u)) { arb_indeterminate(res); } else if (acc < 20) { /* t = lower bound for a^2 + b^2 */ mag_mul_lower(t, t, t); mag_mul_lower(u, u, u); mag_add_lower(t, t, u); /* u = upper bound for a^2 + b^2 */ arb_get_mag(u, x); if (mag_cmp_2exp_si(t, 0) >= 0) { mag_log_lower(t, t); mag_log(u, u); arb_set_interval_mag(res, t, u, prec); } else if (mag_cmp_2exp_si(u, 0) <= 0) { mag_neg_log_lower(u, u); mag_neg_log(t, t); arb_set_interval_mag(res, u, t, prec); arb_neg(res, res); } else { mag_neg_log(t, t); mag_log(u, u); arb_set_interval_neg_pos_mag(res, t, u, prec); } arb_mul_2exp_si(res, res, -1); } else { arb_log(res, x, prec); arb_mul_2exp_si(res, res, -1); } mag_clear(t); mag_clear(u); mag_clear(v); } arb_clear(x); } arb-2.22.1/arb/log_tab.c000066400000000000000000004045051417376376500147140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #if FLINT_BITS == 64 #define Z2(a,b) UWORD(0x ## b ## a) #else #define Z2(a,b) UWORD(0x ## a), UWORD(0x ## b) #endif #define Z8(a,b,c,d,e,f,g,h) Z2(a,b), Z2(c,d), Z2(e,f), Z2(g,h), const mp_limb_t arb_log_log2_tab[ARB_LOG_TAB2_LIMBS] = { Z8(78b63c9f,897a39ce,1e238438,52ab3316,a6c4c60c,062b1a63,e8f70edd,3ea8449f) Z8(26fac51c,6425a415,f95884e0,c5e5767d,8a0e23fa,c0b1b31d,3a49bd0d,85db6ab0) Z8(c8daadd8,175eb4af,a892374e,f07afff3,0dea891e,8f682625,9c38339d,cecb72f1) Z8(ac9f45ae,5f6f7ceb,e76115c0,6c472096,fbbd9d42,972cd18b,bd67c724,0ab111bb) Z8(a0c238b9,473826fd,d24aaebd,61c1696d,2413d5e3,156e0c29,dc4e7487,95184460) Z8(901e646a,d7622658,d7373958,ef2f0ce2,c4e9207c,2ac5b61c,beba7d05,57339ba2) Z8(08391a0c,0060e499,6af50302,62136319,3d0bd2f9,05c128d5,cee886b9,36e02b20) Z8(f3d949f2,0bbb16fa,c9942109,422183ed,8c66d3c5,5e9222b8,6b1ca3cf,61affd44) Z8(9538b982,268a5c1f,fbcf0755,8d6f5177,228a4ef9,a17293d1,731cdc8e,44a02554) Z8(30af889b,96d4e6d3,8f969834,5570b6c6,1ae273ee,7598a195,b365853d,4d162db3) Z8(5064c18b,5f50b518,1b2db31b,078f735d,6c606cb1,ae313cdb,b1e17b9d,955d5179) Z8(17350d2c,0c480a54,5cfe7aa3,074db601,5e148e82,6a9c7f8a,3564a337,25669b33) Z8(d1d6095d,4c1a1e0b,9393514c,cccc4e65,b479cd33,c943e732,db8990e5,17460775) Z8(1400b396,7d2e23de,fc1efa15,ee569d6d,8fe551a2,610d30f8,fb5bfb90,07f4ca11) Z8(0f3fd5c6,da2d97c5,2f20e3a2,655fa187,38303248,f5dfa6bd,9d6548ca,72ce87b1) Z8(7657f74b,256fa0ec,b136603b,b9ea9bc3,317c387e,1acbda11,224ae8c5,3e96ca16) Z8(1169b825,27573b29,c1382144,ed2eae35,4afa1b10,559552fb,6debac98,e7b87620) Z8(8baafa2b,8a0d175b,7298b62d,40f34326,03f2f6af,c9e3b398,d1cf79ab,b17217f7) }; const mp_limb_t arb_log_tab11[1 << ARB_LOG_TAB11_BITS][ARB_LOG_TAB1_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(90d465bf,d4520ee2,9bb0f82e,d99e1b46,facf68d7,e4c4a44a,51bc9855,d122f7ff) Z8(6b5788c3,76702788,f9a073a8,b3db2c3e,1dc282d2,c3769039,b106788f,01fe02a6) },{ Z8(1ef3a140,e808e153,3b4ede62,ba7510a9,8f9f71cc,7841aece,758dcd0b,7a59b490) Z8(77122f83,d140fe05,3ddc5335,eb03be90,6f57aadb,f3db4e9a,1f807c79,03f81516) },{ Z8(31e125ae,9bb5ffe0,140b9e2f,086d1607,45ddab78,67ded6c5,0efcad2b,d0f00eba) Z8(3a835116,96efb673,87466226,53c40a94,5af00773,49fd531c,f56c46aa,05ee46c1) },{ Z8(7cb29271,02127ef4,0f6e3a39,9ce34431,e0a5d2e3,55d9a7ba,ec979e9d,8a38a3ff) Z8(e3673dcd,df6c758f,ddf35ad1,aefae14c,ef229fae,3e3f04f1,9e0cc013,07e0a6c3) },{ Z8(12db1d0e,d5872e70,d45e4a00,5c3e9eb0,48f34c0f,28b7bf29,3fa03b71,747318fe) Z8(a91dfcd4,d0eb0381,f4c603a3,5eb87846,5c8a7235,80ad9015,ff5eafd4,09cf43dc) },{ Z8(5d61ffe8,c6e2905e,afeeec68,457ce7cd,97a6304c,f5c2a876,9f71bf4e,e9b91ebf) Z8(a3a2b779,7d674deb,a89d8cb0,9bf701b2,252c163c,1a7950f7,196e7e23,0bba2c7b) },{ Z8(b0b4ed5d,212b939a,5665b730,6f275dc8,647b0999,766e7cbf,7d96a5a1,1abee2d1) Z8(9e448511,77778bea,fc53dc9e,bce26340,fb66e94a,468a63ec,8cb8df61,0da16eb8) },{ Z8(77e6bc16,9bc35789,e7a9459e,99f0cc1d,85badcca,908722d9,de861006,6172da6b) Z8(96f69849,71851f0a,75b52596,d3474d33,75997898,be64b8b7,08b15330,0f851860) },{ Z8(fe8e2388,8e4540e2,7a5a64e0,8b8cbbc7,7b015b41,0d7918c7,2c6a3b15,8b8cbcb1) Z8(264acee4,37e6cb88,685a6aad,a42905a6,d325e46d,625c173d,a37ae0e8,116536ee) },{ Z8(9e866ba2,9fec8cce,3429d182,68413893,0bbafb1c,69e2cdb8,7bb59c4a,2b83c452) Z8(5d37b037,e6103880,78467950,1a0eca5b,4d137502,99837610,1bd1d092,1341d796) },{ Z8(9de15b17,ed9027ae,f8ee1435,bb355b22,f457addf,3e6b4fb0,e7a295c0,84d7db82) Z8(7aa339ed,96961165,c3e10deb,c9c7e09b,2f91584b,278e686a,06183f69,151b073f) },{ Z8(eed4c843,a047161c,dc5afe2a,fa8c6dd6,644009ed,c1e6a872,ba4a6521,284ac3fe) Z8(34b59afd,812f38a0,087fdf23,50c1ef65,19b640ce,e499b9ed,e56b4b9b,16f0d28a) },{ Z8(c69d37d7,d1080d7c,1025284d,ff89c5d4,5de8d145,cecb8c1d,5115bbde,0ae26ff9) Z8(00e87966,799d33d0,d7c4c4b4,02603e40,edab4357,acb42a65,319b20f5,18c345d6) },{ Z8(427b81cc,48646831,a02b9473,7748a795,ab52ff3b,f726f31b,7818f6b5,ef3f32ca) Z8(2911a622,eab11fa4,d398d01d,9f67e22e,3aa4c79a,0bd22a9c,4ad56365,1a926d3a) },{ Z8(d6fdaaad,f159cd13,edfe76e2,e55d167e,3211078e,f7d0cf3e,b458f0de,87d91901) Z8(bbc664d5,163e7f6c,3772cac1,966af8dc,61b1769d,d617ef81,5bc74315,1c5e548f) },{ Z8(ec0c6459,286a0066,f9a71577,fd2c1f6c,2646cc77,a023f574,cfca2ad7,9e05a342) Z8(ff917c95,dd0897c1,17f6f957,b94ebc40,fe9e155d,ea87ffe1,2af2e5e9,1e27076e) },{ Z8(d8f25186,2c05bc00,cdfa2d56,42245ab7,d807cbc2,630d9164,f63a8eac,8d96c694) Z8(3c82c160,27262536,202ec615,91e2ba81,324e3bfe,2e5199f9,dbeabaaa,1fec9131) },{ Z8(48281841,03ee435a,cbb335eb,043a6981,289698cb,d424a286,d8c48b9f,17139cd6) Z8(8c17ff3a,80c71686,03860ef8,4cb4fd8d,855d1c48,2ee2f481,a11cb2cd,21aefcf9) },{ Z8(2db638f1,f7fe68d8,95174873,964d36ff,e004bec4,1ca388fe,19b53ea7,d04f42b4) Z8(6589e2cd,d406e0e4,32ec12a6,8fd90995,35ce7e77,0c08d1cb,5ecf4052,236e55aa) },{ Z8(c430292d,47b9f129,7a3b264f,6d706ec4,36cd3025,e399a8f6,c81786ff,bdef2e4c) Z8(de50d341,3603f226,7e29fbad,fbc9070f,edf4d109,0bb8e203,3fea4698,252aa5f0) },{ Z8(2e492011,ca484bb6,960168fc,50a7553d,815edc13,727dc7fd,ca360847,3dce1f32) Z8(e20dbc5c,744e54fd,5290329f,f326daa7,627f2e81,9b2d8abc,3d1ee877,26e3f840) },{ Z8(9bffbbee,70f9c3c8,1d45c958,5bf7c41b,0ec2218f,074dbd5a,2aa9b674,1e4be88c) Z8(0372cfc2,0b60281e,f60aa4f8,caf99174,fc3c1882,a7b2a1f0,96fa3ccf,289a56d9) },{ Z8(08278a9d,0cfa87ee,59700ee3,22d074e0,8ae86452,c8651fb1,23162370,7c45f286) Z8(a66f4587,b14f7cda,8aa87317,98c76a88,96334db7,c803adc7,43686f45,2a4dcbc7) },{ Z8(fb5d87b5,ad7848e7,b88a7375,4baeb699,b541268f,97d44cc5,023311f9,edbafdfd) Z8(d928291d,c0acfed6,fdf3e631,d55c7355,424775fc,e7c4140e,4f27a790,2bfe60e1) },{ Z8(63f3206f,c42d57f0,e1505b15,971ceb8a,ac01a942,30ab184d,ae503ade,ff787dae) Z8(968814de,4e8db6cc,8dac1eee,8c960973,74378df6,a8ecb899,33a4391a,2dac1fce) },{ Z8(a6ded1b1,a99801dd,8f0a96aa,257473ac,06b19fb0,4175c8e2,f91588f5,35ca286f) Z8(7969d04f,c62cba07,021656ae,fc2929b1,0c100c8f,c6d65ad4,21b21237,2f571204) },{ Z8(87ccd984,db5f513f,d5c664fa,b8ade2b5,727ee8b2,de8c1375,4d29abb4,83edc1bd) Z8(02e9b86e,8a6cd2cd,eb4ebea2,5704b6b7,932ef5a5,401202fb,41922120,30ff40ca) },{ Z8(46577c95,17b14e86,d8375221,45a5f1ba,77b20123,421b1cf7,978b7d19,9ba61844) Z8(d7f0a39d,13daa19e,71766947,a0bed3cf,712cec4c,8260ea71,e8ad68ec,32a4b539) },{ Z8(b58674cb,1e544a43,07d3dd44,0d91f714,43732b59,d7c1d20a,d4945cea,a048eef8) Z8(c2c7880f,99f2aab1,65bcc380,e36cdb16,33184fc7,6e2360f5,c56ac632,3447783f) },{ Z8(7d1d4ffe,3b6ab9a1,6c95595e,b5322b03,8124d050,b9509e41,adc20980,c52dbae0) Z8(036bf0e3,7622eb26,d50ca14a,69b8b9a5,99eb9767,9cc0326f,017fe5b1,35e7929d) },{ Z8(54f5bfa1,148f89ff,84d501a8,c271e752,7a1bf371,87f65b0b,66f4429f,e6ccfad9) Z8(1118cc85,cbd35203,079ada33,87b948d9,3d53c3c5,f39d121c,5b19ac53,37850ce8) },{ Z8(d75732ea,78383094,c087279f,e9fc85bf,d08de46d,3103360e,7cdd3baa,a192a8fd) Z8(64bfc746,70f133f5,11adc1b1,c765ea74,ff734495,4bb03de5,35344358,391fef8f) },{ Z8(c8b2aae1,47720fb7,b3c62df4,f0d2680e,31c6c7e8,557eeedf,883386a2,d71548c2) Z8(f33a42b8,ccd07cf7,9c69752d,673d12bf,6a00e1e3,221acbf2,9f7722b7,3ab842d6) },{ Z8(d818c8b2,50d400cd,f34e2aee,fa583ed9,4c8d98ef,4047eae8,9f9455af,3c0b4685) Z8(ff22f92b,ba112f83,2fedf2af,729d7880,fd3c2abb,d50fffc3,55e5cbd3,3c4e0edc) },{ Z8(2aa5fc55,51af64df,60784393,56ed2331,e4ebb654,1f3c6b40,82bad112,4ec45e67) Z8(19f5f6a3,a5834a1a,a47c3a3c,a5098683,106429f5,31bca86e,b8b26ca4,3de15b97) },{ Z8(eb00ad03,63a59c53,435a44c6,c58402fb,09140995,c7167255,6589e221,e9c83e0f) Z8(6916ddaa,165f74d5,b22c817b,40584455,29a59412,aa8cd86f,bc7c551a,3f7230da) },{ Z8(5409c55c,7a4aaf89,cff561d8,86dfc9f0,b133b751,86dcddc9,6974da47,2bcb4cfd) Z8(48270514,505da985,efa11c83,7660cbc0,ee95e444,89ef42d7,d341036b,41009652) },{ Z8(b593b0e7,5fdd4e11,5d032b5d,c283489d,bc5a554a,d18ef4d0,4166ef5c,154ca709) Z8(7a329bfb,dde3a1dc,0972de36,e035afbe,c030e28d,cfde8061,ce438d7d,428c9389) },{ Z8(b5e7b48f,d76ad167,9d09ded5,2c0c163b,c40830ce,61dab337,515ef682,eb3fa702) Z8(2e0e2fd5,e31965f6,3912b4d3,e58b9bf1,cc73e14c,7e82ad32,b92b5462,44162fe6) },{ Z8(1638a398,cfef8350,794371e8,85bd4ee8,4c529944,8bc0169b,dc48152f,499727b2) Z8(95940f17,c3c8dc39,3c19f534,067d04a4,1b8b823f,731f55c4,ae98380e,459d72ae) },{ Z8(a0a294d1,06f89ca5,b6c78ecb,8e1fc408,c91d35ce,e412447a,5f4ccf5a,99468d46) Z8(b04fcaa5,4aacab7b,caf5d936,882eeb5e,e3bbc33b,1a39d500,a667ebef,47226305) },{ Z8(4f3def00,13fb881e,a8306d3e,83ed51dd,5648c138,c18a58e8,5b634bb0,03058369) Z8(fbb65f90,e27652ff,8762e747,9aad37a7,750cbd2e,0a14f69d,3de59689,48a507ef) },{ Z8(e769ec0e,d5e2494e,b23188ec,48dad606,db87f307,37f84239,d1fd3cd1,8bc0a13f) Z8(d8b9a5b3,9db59698,15eadf89,8eab2f96,40e58b5a,d24c13f0,7a1a8d7a,4a25684f) },{ Z8(a3830fa5,53c8ac43,ff797e15,519f62aa,8d291024,3f7d530e,20cd5936,f5fc616e) Z8(3164478e,4cf26755,26f15213,77ad6fb2,206cf37b,b3246a14,8474c270,4ba38aeb) },{ Z8(c2614cde,58defae2,55731574,0957c917,ae0ffe68,5ee0ecb5,589a72d3,8bec4a7d) Z8(ccdd5195,7944fcf1,61deaff0,14b01676,3043dca2,159d3fb7,61f55359,4d1f766a) },{ Z8(00562cdb,5bae2934,6ae2a114,cd553bc9,c01a5b18,2ce6ff8d,18383eba,aee32a49) Z8(9d61357a,69bfc8cf,53c8dc26,479dcfc0,34237d6f,bcd735d0,a517a71c,4e993155) },{ Z8(c62bfb2d,187f46b1,9ce225ca,e488f396,34cdee5b,f2e9de81,3727a0cb,c9dd6cfc) Z8(99756243,f2206c95,1a2da0d4,1827d9d9,19298564,3049f7d3,1a9f8ef4,5010c21a) },{ Z8(8f613c57,81891c55,7336c01f,14e48b95,72ff7a30,b092567e,bba85f7d,af120d6e) Z8(a973fc98,b5eeb55c,0b44393c,72cd24c0,f1cd1057,2decdecc,717b09f4,51862f08) },{ Z8(364f586a,031e755c,fdccd96a,b5f790cb,ab6cfc39,4dc65b36,e66f28fb,973e059b) Z8(5b6423f7,6b656878,d2f053f5,53458673,f6191eb9,326527db,dde2836d,52f97e55) },{ Z8(698a8e93,6656eb99,c5bc69cd,7cf05d1a,53d7e4fb,59dd7433,f28d4eb6,530626d4) Z8(eb0a988a,1f9a5c5a,f5c12be2,e9e6af97,abc623a9,24f5833e,b7e0b427,546ab61c) },{ Z8(8667d12d,039642d1,32197790,f694717f,4d975abc,daacd3be,f128ae8a,8cdf71b2) Z8(f884f564,314796aa,3f7be028,b8343319,60bd00f8,6adb2836,1569b152,55d9dc5d) },{ Z8(c3639743,a0a230fb,ba2e3d16,e728a52c,f6d4b0e5,d1272b82,4ca76681,3f984c40) Z8(645143dc,4df9cbb7,29a4bb09,80b4a6b4,fe1159f3,36383dc7,60272942,5746f6fd) },{ Z8(82541b8e,6a800985,828e3253,bc837911,58ca07d9,42a51959,1cfcf075,8f0834da) Z8(512b4182,0b2333cf,5fd12d40,9b157749,0728b9c8,bd7c8a98,e71e54bd,58b20bca) },{ Z8(7083bbd4,bf36d16f,57d3ae92,ce372136,9dbdcdef,2db73e1e,a4096771,47379cb4) Z8(6df3361f,fa9ae616,95996523,eded1c33,8e1a592d,0af84053,6c52bb11,5a1b207a) },{ Z8(23ee0a2b,dd2941c2,44bb4bc0,603b6420,b20273f7,d7723dca,0c449327,fee3c8c7) Z8(bedf033a,856f669f,81f708d9,ab9f4e65,5f0bc0c5,4e4c635c,ae878e30,5b823aa8) },{ Z8(b1351588,1f632a2f,97f25769,e0427ff7,9e14a268,c49b7c7b,4ac65d2a,505d2dc1) Z8(23446f02,bc92784d,a59757bb,dde10dce,4fbde5aa,89314feb,ef401a73,5ce75fda) },{ Z8(9b875c17,bff221be,3ac24dee,576cf484,075b1493,149cdf05,44f4c2aa,5f81d74a) Z8(43109a88,a6f5261c,8fd7bd5e,c32ef183,ed68159f,57691fe9,751e89f0,5e4a957f) },{ Z8(af30b4d9,0b07be72,72aed8b9,43dec3c7,5a917809,a865819e,6f275bc2,a53a2571) Z8(63c82c88,cd067666,1ee8d4b3,0cbfcbf7,95043716,ce979ed2,0abf0d92,5fabe0ee) },{ Z8(0747f86e,1d4c73df,5ae005be,aed557b3,f8ba56fa,41197957,9a2e6f84,1084e7da) Z8(406a94e2,2773d467,80f95ed3,461471f3,676688f0,ec519784,7a2c5d24,610b4768) },{ Z8(d94be1bd,507eaadd,73edae34,778b0d38,f0427892,29843ae0,20267cbf,2fbbd968) Z8(c6f53831,501f739c,0515a31f,c63281b4,f055b3ff,9c620440,05096ad6,6268ce1b) },{ Z8(024507f1,f85983b7,72ea875f,82e96e55,729965bc,2be40c0f,ac124007,e79ccaf5) Z8(95258bac,a0d173fb,5410ee8c,bfcbc0e4,1a29979c,5da755a6,d98b1df8,63c47a1c) },{ Z8(d2b4ba9f,25b0797c,79119b15,35ab3c59,85cf0afd,c8d782d4,7f104da3,8f4da6fa) Z8(3de7f064,319e32cc,0fa1a7e3,9cc25dca,41baba92,337451f4,845beae9,651e5070) },{ Z8(bd1d19ce,ef36c7bb,244db6e1,cfc3fac0,1fc77988,ff4f6e88,5a75462f,129be5cd) Z8(3ffdd7f5,ec7c7be1,251912da,db8e4afa,0c6fdd25,a4bbb11e,5f822b2e,66765604) },{ Z8(febb0e3f,a7e09dc7,5d6f9b5d,752d66d1,b8a073c4,fadca437,9edaebb7,c2df0cb1) Z8(c59e3b60,b38ad78e,4547d7c2,7d20ffb3,01488606,da35d9bd,fe612fca,67cc8fb2) },{ Z8(3ad738fe,faeee814,e0205868,d2abcb73,111baed5,9faad02b,56cb539a,c15be7c7) Z8(fc13c079,03289542,c6bda28d,adea18d6,d3a4b273,f29adc3a,96ec28af,69210243) },{ Z8(181342cf,e875edb0,573447c1,871bbf43,7df08a48,2fb43fcd,adf8a19b,c08704e2) Z8(763554ce,f35aa69b,768c44e9,1fc8ee26,950d7be1,213fd4bc,68212635,6a73b26a) },{ Z8(1daeaf7f,8fe97f1b,98be79c0,2fa2777a,483fe591,731e5306,1468b8c3,3d38c142) Z8(3cb06ae4,84cbd594,83242af8,6824be43,70a030e2,ce112857,1de1ac44,6bc4a4c9) },{ Z8(4064e2d7,77750639,f8dfce5a,0e4e7e63,725e6611,775c37c2,e8c5ff87,f528ac22) Z8(2b96a198,aa8920b1,603cf111,53ab4d08,3878ef20,fbb6aba6,323d8a32,6d13ddef) },{ Z8(86ae07d5,0d2b4651,b7cd15b4,9cb28ef4,524e778b,0b479be1,97b8243a,fc2b97f7) Z8(6133b646,c95f4009,20505b04,73ab4620,bc39ef20,3ec53e23,4c43ed66,6e61625a) },{ Z8(7b6da0b1,a9f31cbc,6cddd596,1210ab02,994646a8,50b64bf2,8b728a55,4d17b0b1) Z8(a905792e,92f74d1e,233b3294,2c1be100,f06b25b5,1874deae,9c6defde,6fad3676) },{ Z8(94468a54,d7b83c67,98048347,0c272ece,a2533c60,82649140,682717c8,9e8a6c59) Z8(f0a1b552,d2bd6d07,4099fe79,18e57d81,69b60bb5,cf052dea,36b535ce,70f75e9f) },{ Z8(aeae65d4,f0706129,810e4f3e,d3f90b7f,a11bc8db,62066c1d,f9ba7754,432551fa) Z8(c97f8e8d,e1e267ea,235b8362,8ecbd4e8,fee6892b,97607bcb,6a6886b0,723fdf1e) },{ Z8(5c1d0e27,6ec32e26,0d5e87c6,baaa4e9f,5046a410,f09f4cae,3e4cab06,ac982b71) Z8(6940f2da,30f2257a,ede56473,19180165,26749c43,f4af2ab4,17cfaded,7386bc2e) },{ Z8(efccd9a7,17c86357,90b72371,2651580b,0abb7696,e57cd327,6915d53c,e48da163) Z8(025705ed,1279aed9,d6e583ff,b4dff5ef,a36fd18a,7b232faf,03af5587,74cbf9f8) },{ Z8(2a826c1a,0333ac1d,ea7efd86,55e66b44,e62627e5,188320b4,24b62912,5a74aeb9) Z8(3363c7fc,50800d47,77ebd803,94cc1824,5110ea50,456e8bb2,28bcf941,760f9c96) },{ Z8(76a1ca55,43a3f551,4518e0fc,0f1e32ef,3e5b508f,8b63c711,7d60fbbe,2451e71d) Z8(5c94d3aa,250ff699,bafcfd59,50684ce6,76e1fe9f,989a9274,071282fb,7751a813) },{ Z8(c257dfed,dbddcce8,03e16c65,af8088bb,d9a1ee03,f819a863,e2671dcb,8b5ae70c) Z8(cdd6a4f1,8750a8ca,c3da432c,07be2ec9,2918d8a8,f63d1655,f1b09872,78922069) },{ Z8(d0dde8c5,a9caba57,0f3da399,19386ee6,ee0ef38a,b9a877bb,946cb64f,b2114303) Z8(1899206a,a956c38f,ee015120,a18e2aa5,ed1bb404,f68dbcf2,5a1e1f8d,79d10987) },{ Z8(9d4179e1,47cd2a96,91996ce0,dd6e9f64,c45b6ee0,64bf71ef,1a908802,ee62d104) Z8(22d5eb97,999b100f,bd8e5113,972fca0e,4e5bfb08,73b94fcd,1a33005d,7b0e6749) },{ Z8(5906267b,9727ebe7,3bffd807,bda7391f,0a0ba86f,9cd3cbbb,669c3df9,c07f81b3) Z8(9dfd6268,ea5ce16b,9ec747b1,64911742,73d75cf5,720ec44c,bc1bb2cd,7c4a3d7e) },{ Z8(8abec40d,2f01653d,2bc13395,6093422f,2840a0bf,4866a344,bddb7177,9ccd0b6b) Z8(829c25b6,769bb433,09381f6e,48299816,34148654,15b0f2db,c0a2b185,7d848fe9) },{ Z8(ed8fd682,4827b3e4,39ca9988,6fb9d4a8,1ce07db2,bcc34caa,592550d9,eb29d0b0) Z8(fa53d65d,34ba102e,4dc7b6e6,cde2ef18,1afec6d4,becf93aa,e3cc7b66,7ebd623d) },{ Z8(9d15cc1e,12704f76,383503a1,8a334b0f,1fc312eb,f921e345,73b2b50d,eee7b8f9) Z8(1790e838,3b38ae3b,8e29866b,379d3ea6,1af246e3,5f40d932,5fd26156,7ff4b821) },{ Z8(67a46987,94062760,e89d878e,3a732eb6,0c759abe,e2af09cf,3605037f,0ba66448) Z8(d7258b51,a25591cf,34ebb89e,4b8b8c4c,3ffe346e,e34aebf7,2e87f634,812a952d) },{ Z8(4136900c,f04505f9,fd9b2fd0,ec760e66,63f372ff,f2039753,16f3e26d,b21e3f7c) Z8(eeafe183,9e3bf732,18e0a7e0,1c88e1e2,3bed4da1,e6080459,4936932f,825efced) },{ Z8(53b65adc,76def4c8,e81a013e,690afdf2,184fb062,23989734,20e6ea98,297156dc) Z8(aa7c2a28,80a11439,210f75ce,a5d75211,b755b2b7,bcb1c488,e6fa0272,8391f2e0) },{ Z8(7ada428f,cc00dcd8,c000a5b4,3b9be86a,5db6f492,7080891d,9daa94e0,978f0a6b) Z8(96240ed5,bde39b4a,389f13c4,3f135a26,1fe03811,fed4a7fa,b9a905c8,84c37a7a) },{ Z8(eac77298,d04a9e2e,5716b0d4,7259863e,dee7403c,9b0099ab,6ea5168f,60e4aff4) Z8(c52fb7f6,90936f50,5d3ed11a,366fbbf3,ffe69b64,c4bdd99e,295415b4,85f39721) },{ Z8(d95cf419,b28d415b,f24b352a,cc6ff342,809d44d5,9401a2c5,7ba5461a,50cba9e1) Z8(f9cabf0a,b3c6badd,430bd090,59ee145b,b1f1a3f7,572ef4b4,8e645fb7,87224c2e) },{ Z8(0eb07925,e5b1269d,ed9b187a,d1d2fd21,3b889e3b,f02ede9f,9f62ab2c,2e64de1d) Z8(945a0a58,a2072c7e,7e4ae138,63e6f990,c8c5f241,1f64d85b,6a64b7ef,884f9cf1) },{ Z8(46e32681,abcee122,2922d148,7967d053,e1370c8f,cf0146bd,779f7757,d9f2a988) Z8(51b63a9a,3451ee15,48cde6bb,c9d5fd40,86a5a24e,0918ce3e,9f7de298,897b8cac) },{ Z8(66b86f42,f9c14cea,33bde7be,fee11155,438d5e9d,e1958c8d,38859b27,50a4b66c) Z8(0e33c3df,26dfe952,1cf1faee,3a330f34,f14054ed,799d1cb2,a6af4d4c,8aa61e97) },{ Z8(d0ece291,32eb4370,23a91da6,5798053d,8fc6853a,2d5aee94,45224e00,21f25c1f) Z8(34f3fab2,5be20076,147c6d48,37d86476,e970d58e,30737d03,c4cd05fe,8bcf55de) },{ Z8(c2eb376c,ef9a8ef1,d7aac1ac,e29dd595,ef6da3e9,de764d2d,66f272b7,80ce3afe) Z8(a3ef0ea2,e98ec9b5,c371d36f,78ea06c2,ef3d5710,e5eebbc0,3e4b7662,8cf735a3) },{ Z8(a482791d,13c9d868,6dfa8df5,b660ecca,7dbcefc9,4eccce8c,02e8f0cc,411af4cc) Z8(8a493f54,81559525,ef8dce37,4c2379b2,e2efc77f,a7c766fd,89e125e4,8e1dc0fb) },{ Z8(28e74d7e,4f6620b1,dd0bf7cf,fdbe964c,deac4090,e678c55e,ab58d60f,6e709121) Z8(5ba0cde2,9a4b1c06,696ad39f,ca4f4817,1e35f2e7,62cd2f9f,820681ef,8f42faf3) },{ Z8(9abaca2d,18da6190,7ab564b6,d1252aec,c7629553,022a6191,c984a22c,e12af53d) Z8(c9110b22,beeaffac,3b527cba,481a9128,fd849e89,81e87bad,955b6c9a,9066e68c) },{ Z8(44f5ae8c,46563067,d9225675,228fec0c,20b70553,37e3a916,53349bf8,f29881dc) Z8(8150f4a5,5a9f0930,5b0c6c60,bcdfcc1f,5240a471,f1b43916,f5fa1416,918986bd) },{ Z8(0075384d,9003f45b,8607f720,d3e059e8,1c66423a,3a28cb9e,ac221819,72804429) Z8(3894e474,feca10f4,01ae8308,50a06eb3,1e710847,21d6d688,c7be59e0,92aade74) },{ Z8(fa1895f4,5558e6af,15fa0ed3,c0dc1d6b,6de19a53,92b0f0fd,a10dfdb1,b09a0aae) Z8(9ec6647e,7437d665,433bbdf4,527d7309,438ffc03,c1f9edcb,4d88d75b,93caf094) },{ Z8(c23e9c20,fa880bc2,44803285,36d6e47d,b25cde63,0c7b750c,e0814130,53a0d1b8) Z8(1d0d3dfd,33a48e4f,6a10aa67,fc1f5596,67db5d0c,e6b65d2e,15845642,94e9bff6) },{ Z8(888c4872,979b5ac4,58797f08,ca3f05b7,6ea286d6,f59eb28a,c7a398d4,f1efd6be) Z8(88043648,2d83ac42,b745196d,a546f842,4f312a40,d4e18dd1,24745dcb,96074f6a) },{ Z8(a599dff0,51789fa5,ec7a3208,9aa1da7d,bf521374,3c526d19,97f074ad,f8a93521) Z8(3f080baf,79b79196,475e2e71,794a2964,0d589296,a10c3491,20134202,9723a1b7) },{ Z8(1304d6c1,db24c695,ceab26fa,4556832d,52740265,879fae51,e748ff9a,d3bc93b7) Z8(636df445,4042089c,8119ba91,0b701333,36cdee18,ac850fab,7885f0fd,983eb99a) },{ Z8(a5640a3c,8297bef5,57cb315a,0dc0b96c,bc7ef3d3,a6b569fe,246215d1,d14142a8) Z8(56157af9,6b3a547a,ddf94bde,ba133462,16b06715,2ab5b3d9,90eb8990,995899c8) },{ Z8(45128ad4,bf91ec4e,35a6ed7e,bad3588c,305274e7,3cf7c12f,366668d1,5e8524f6) Z8(9d8edefe,c765792d,b6be4109,1ddfd382,72757253,5c96c42e,e70e98b7,9a7144ec) },{ Z8(b0a314a7,c8b6db72,3474d5d3,618792f8,c0d05d00,5a8770ef,9d03b869,d14e8265) Z8(2bb4ff77,c110a792,16c364d0,8d986c28,efc8f895,e8124226,3a3dae2e,9b88bdaa) },{ Z8(48fe0250,829512bd,61955f50,2df8d830,3dc6a386,a87f09fa,b57fe9db,bc176f0a) Z8(2170e2c2,41e7a845,00413260,1717c9e7,f8c38f62,221301b6,b150cd4e,9c9f069a) },{ Z8(7bd85e3d,e34b5769,ca04f4bb,2a5f91d4,39c54415,b42d4279,4c9cf538,880cc792) Z8(c90a2c44,29adc2b4,1a54790d,e6d9b959,9b341d6d,76f60c2c,ffe1157c,9db4224f) },{ Z8(a0ce0994,eb29783a,c4b53d6d,97af626a,64671d5b,76ffe838,89dee616,cfe36b8d) Z8(f297662b,0bd03b10,df1ff936,9d96954a,93cf6b80,2131e856,8ab7d520,9ec81353) },{ Z8(6fa22492,9d4d0b6b,045b8bbc,2e916e2d,c5cd1a0d,ed2d7b5a,4f170359,d8c6dbf6) Z8(bba84ce8,71168dc1,4b72b4f9,ecf33acb,5dde6c84,74ea82e5,8b7a12da,9fdadc26) },{ Z8(d6124129,2018ce5c,1df6c2fd,5f29ec91,892e5832,2bdfda46,1bb82762,6471b5af) Z8(2a5e02a7,247c0b84,56f59974,4486ea27,00bbca9c,25e617a3,33957323,a0ec7f42) },{ Z8(82f9c9e0,48f0123e,eafb93f5,4995554c,a3bb3481,72e33343,751d317a,0a091231) Z8(76d75442,e23ae16a,7ce6611a,b774c2fe,70cb6c1b,93dcdb07,ce733bd3,a1fcff17) },{ Z8(1ec278af,031238ab,e66d803f,29c9172a,e5fef460,6124acfc,7750befb,5e241add) Z8(52e7f931,6bdd6ab9,16887279,e59a4980,e39a20ae,5bd9bd99,e2f613e8,a30c5e10) },{ Z8(d6d3d6f1,f8b49e95,50bdc64b,6f85a5ab,052e0cb4,3b248f20,3e6f4167,feea5337) Z8(c4c1348b,6d9c0712,7535ca72,efbe7833,fe84b0c1,af45d980,5446fb9e,a41a9e8f) },{ Z8(369cb411,5c9fdf23,a883d1a7,d83cab84,445c1b43,322aec8e,db555408,23bd3235) Z8(84ebc206,5bf1a66c,af47e744,6f7191d8,61b6316e,3dfa3d37,81f5d811,a527c2ed) },{ Z8(17bc15c2,efad36ce,b966f5f9,f84b0423,42ec4a7e,a85f6dd1,65a33b31,96bb5520) Z8(905668df,1b7a54a6,71eab2c3,1b11377c,37ec33b6,4766e98c,6771cd8b,a633cd7e) },{ Z8(e9bbbb42,0b863a1b,a0c9e024,3ab169cc,c1b47d5a,c1f3168c,0464cdd9,aca74ac1) Z8(2eb5190b,c9ea4c64,f774593d,bd794408,2aee1a18,84c2b22c,badd84e5,a73ec08d) },{ Z8(5463ae30,44a034cf,f48a4b7d,0955efb8,bf4cceff,34a81880,68cf4ff3,ae3a7fb0) Z8(77258b86,ab09e042,9cbb2de3,39ed8a98,b61ed2f2,59d2d85a,0b435a5e,a8489e60) },{ Z8(c1df5ebf,8a7e5bd3,d6775e9f,bbe00b2b,eceb1f55,031e3061,3e381ca3,ca138ee0) Z8(29d4eb53,a388b633,4c39b31e,d0920f6a,97aea7be,be4578ad,de2d5773,a9516932) },{ Z8(b44ebf27,07bdebd9,ba72c6bb,37b0af6e,74fac90f,cc6b9908,e041db14,d82bb3ba) Z8(3fd0d75b,916e796b,4ebab5f9,5d56af71,c1796894,aa145a1e,cca4bd48,aa59233c) },{ Z8(860598be,68a891be,419576de,bdf5913f,71a9ad49,9309a22c,7697b2fe,e4b7faf8) Z8(2e3f55d3,52d39be0,35094514,5631bf5c,fe59cdc1,e310b9b1,9f9cca08,ab5fcead) },{ Z8(12c4fabd,800743a3,a2cbcafc,9f7e13a3,3754421a,dbe424b0,90272b07,cbf0d848) Z8(6848f351,cefc72f5,c446c7b7,601ab2b5,4585513c,9792ec98,6bcc4984,ac656dae) },{ Z8(14f3b1d7,77d02118,d6b30d46,faeab5b9,04f30d08,869cbad3,7b2300e7,0c763464) Z8(5b324a78,7753b3c8,8161ccf7,839e0457,1cd40845,4d552f81,acf967d9,ad6a0261) },{ Z8(409651e0,a0ec4685,0b291788,f5270b8d,11141c98,752dd2fa,066ebca8,ff6f3b30) Z8(ccb86b9a,72812da9,b0db90f8,50ae328e,418af602,b71e2eb8,60bb2467,ae6d8ee3) },{ Z8(6e5357ef,6502ee16,4e559a75,486c32a2,2036cccd,46a4f082,c523dc46,5f3cbd97) Z8(51d2f00f,e6688102,e7a29309,29f04ae4,103ef4c6,b04afe92,20b3ab86,af701549) },{ Z8(4df8fd3f,bbdc25e6,05a0089b,f91ab8af,0ee934fc,bc66fd20,fa3e3768,c5e4901a) Z8(c1549af0,96012a8e,ccaabf0a,17ce375a,76554335,e44ad05a,3c46c653,b07197a2) }}; const mp_limb_t arb_log_tab12[1 << ARB_LOG_TAB12_BITS][ARB_LOG_TAB1_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(0c7e47ed,4b04b13f,e5e46287,7785988e,adc4b604,455be77f,db837e0c,9876d250) Z8(3228bbda,f7b8170b,08a27c47,0dcf437a,809be9c1,56221f77,00155515,0003fff8) },{ Z8(5d3950db,eb8cb58a,5bc2ca6a,2f9fd6b9,795b75ca,f576ffd9,c36eede8,f2added6) Z8(c4b26860,46c08a95,de4647be,6a90d794,2bc2bf0f,c443999e,00aaa6aa,0007ffe0) },{ Z8(df684222,3331882a,5bbccd32,ed548b07,37bf2957,dd4f60be,63e70f62,0c11e6c9) Z8(e4fe2376,1761433d,33f47284,631e94d2,7ea01f6c,c25eceb4,023febc0,000bffb8) },{ Z8(e976cdd1,bd5c2e9e,116cb84f,f6577335,de7bf63a,add50321,e5b794e8,83c3767c) Z8(8222f25f,c9b2e919,8002d083,49c8cd0b,e271ee05,885de026,05551558,000fff80) },{ Z8(8ffd6108,b5f4be26,13bf8e54,580566be,3e42853f,73edc4f2,385d2695,26f78ace) Z8(7c2eb67c,624afcb5,b1195c2e,ead9fd07,6f07f956,6e07f2e5,0a6a0e74,0013ff38) },{ Z8(8397d72e,9cb25d77,08872f77,6259b85d,79f21fa0,fe7e018f,94cff6d6,a6ba5f7e) Z8(6496860f,112126f4,fce97760,ec66a6b4,4fcc8cbf,4ae6f3d7,11febc18,0017fee0) },{ Z8(dd783371,6ebe5d38,e52d4841,07891503,a142f477,c716cde1,a8180ccf,f533be7a) Z8(86f4eca4,a36b3c59,41bf2ab6,05302d4d,867db3af,d625df1d,1c92fd49,001bfe78) },{ Z8(71564207,2e395e6a,648d0b5c,d4954a65,10a5afda,2369cbdd,a5e80ec2,7dcd939c) Z8(5c09d7ac,4e588a36,e5e0fc9e,545eb8e9,b318cb38,06678ad8,2aa6ab11,001ffe00) },{ Z8(a74c1f7b,c8174f2c,4cc3b548,280cd516,fc13a506,be31314c,9f59c45d,72151c08) Z8(9ada2548,b3fa3abb,cee967f2,6704965e,74d6486d,7195f625,3cb99878,0023fd78) },{ Z8(0a8bc7fd,5940caeb,5946eabe,3329656e,197b2784,204f6b19,e73d96eb,e2ce3906) Z8(f3403917,958fda30,07f8f64e,4dd54982,e472577d,acaa1d02,534b928d,0027fce0) },{ Z8(ba15b9c1,9d400eff,63997eef,1f52bf03,b96cd7b8,4e6f8931,72908d79,9584befb) Z8(0731c1c5,a523ed83,746ceba4,481e5b33,9460290d,ab6c51d6,6edc6061,002bfc38) },{ Z8(865897d0,e4422d88,804121a1,f719dc94,0b06bab2,564bce4a,77837236,a2ac2a15) Z8(4b0345d4,0ddb364e,f20ddf24,c18ae3fd,6fe9680e,202d1d41,8febc309,002ffb80) },{ Z8(c67f8e67,c756b402,e95530fa,d96a8508,8b260572,d27384a1,ed01736c,aa92f585) Z8(142fe815,681298a2,2666f5a6,84fdf71e,bea16a3c,db76a4f8,b6f9759c,0033fab8) },{ Z8(96ee51c7,2b4aae3a,37445efc,3528f10b,2447a3a2,262fd12e,8aea37ae,ee8fa41d) Z8(25bfe902,6aa3cc1f,44187b24,fc0ffe45,7dfc3806,2bb69a56,e4852d3a,0037f9e0) },{ Z8(01761986,7a9639e1,83ebcae9,a207aeaf,93202e05,e12a8362,f7ed7dc7,9b5cfe21) Z8(5907d500,08937816,b236f63b,0a6da4ba,2f4485b6,3ce0b154,190e9903,003bf8f9) },{ Z8(88455ab2,2cbec254,033072c1,ac4e6045,5f35b760,d3878b77,f158acdd,453519e9) Z8(a6eb720c,6e34c564,62ef4eb0,8e30d617,2499268e,7809a0a3,5515621f,003ff801) },{ Z8(d6aba998,7285ccad,cb6da537,24bbd3dd,1faaf79f,dde40d3a,a21dbeca,002ff1cb) Z8(dc6eb7a7,da5b99de,a85e4861,d7bec86c,440a6381,e2faab95,99192bbb,0043f6f9) },{ Z8(d575a542,48cdff42,994b5242,fbff851d,e7243654,915506af,2f36d303,5936d46d) Z8(10692284,4e70a24f,51898a1e,9fec675c,2461f0fe,7fbdb689,e599930b,0047f5e1) },{ Z8(af26aa96,52ad5bde,e081969a,48cd173c,ce824ace,d0826b70,62e17050,20a86cd9) Z8(daf119ce,ff749b05,a14a8966,4b07e3b0,5395028d,ac21e68c,3b162f47,004bf4ba) },{ Z8(685dfb6e,8d4c6e65,55162dbf,38f0cd96,104ddebd,f89cfd12,bd249dfa,7640a942) Z8(613f9246,fc8a64a0,058d0887,d9833ed3,83572e9c,8138cce6,9a0e91b0,004ff382) },{ Z8(78ab6fd9,e7933509,c718a462,696a6f1b,1c6a54fd,0b9fd618,4442f2b3,dca8f510) Z8(6c1f25dd,5b91d0e7,db87d3a7,07a40d57,44be78f3,32cc1f40,0302458d,0053f23b) },{ Z8(b557a2c6,cb980ff1,34d846af,b21606e2,60e26967,f35f9cc9,839cfa15,5c829c59) Z8(cbe42378,7018362a,f78f231b,1eccc4c2,e864ee39,6ecbfd17,7670d02c,0057f0e3) },{ Z8(ec6ddbc8,be4b0986,ecfd04b0,cbc438cc,55568294,93488199,7850d920,9eae7246) Z8(c457bd71,4b82fd69,d36c3bcd,3c567cfd,04f2bec8,bcb5c337,f4d9b0e4,005bef7b) },{ Z8(be74810b,d894e323,98edb02e,920c9408,9773d6d9,28e2348d,2fb5401a,00363f50) Z8(f3be6b53,7c709a06,c0ac0e4c,c0ddec2d,127cb9cb,dcf36ddb,7ebc6114,005fee04) },{ Z8(3871e636,405de324,bb58daf4,2ced0f06,6461184f,d371a235,13c5374c,0d89f57e) Z8(c6cde11d,96882352,2916016e,b25c09a2,75a66bb7,28338a43,14985424,0063ec7d) },{ Z8(ad3ad3aa,1f836e0a,485ca611,79290a36,c05b5262,e36f54aa,7aaae2e7,7e4dffc1) Z8(7e20fd0c,942d752f,00b70606,a40a07a5,41fcf393,eeb9b857,b6ecf782,0067eae5) },{ Z8(aeddfa03,238faa80,3a62f688,76f05527,6b941071,0d9112b3,1f81a47a,39cc664c) Z8(68b37ab7,18ca1d62,fddce551,c73608bb,e787e161,d7a7bd14,6639b2aa,006be93e) },{ Z8(f51d41d1,22af678e,14ac3c62,150b3c79,3b137670,e89ac098,071dd1cb,fbcbf077) Z8(67a834f5,6c677666,30a82b21,c3c19825,ec181c9d,403f267d,22fde71f,006fe787) },{ Z8(36633b46,ab056e1c,b4d2a7fd,8372a606,f0f5668f,ffa99523,aab69a6b,86afcf8f) Z8(f922917a,6deb4874,8b04680d,8f944d03,bd69ec18,9b1b81b0,edb8f06d,0073e5bf) },{ Z8(40af2f8e,071c3a37,d3dddbb2,6922123f,dcffcc29,1bad4e7c,9b7da841,9a6e6a11) Z8(084753f8,18476ec7,38f1ec7f,7109e475,95bebffe,cf6523e2,c6ea242d,0077e3e8) },{ Z8(63b45d84,8f388c03,a81dc11e,50993dbb,8f985fba,488cc34c,97294de8,98bbfdbf) Z8(a84e262d,0ed48b36,a7ef8946,7614f608,59255343,97fc86eb,af10d202,007be201) },{ Z8(d4bb4228,566babed,4e690306,d0d98ea2,492e4bba,dd3f9376,02ec7bf0,66e737d1) Z8(12ace6e8,c73356cc,e89a011e,cad8ec22,3e3b1ab1,e29e3a15,a6ac4399,007fe00a) },{ Z8(54920bb5,d39b5c6a,94602541,f62afd99,de32f9e1,9eb075e7,1c008530,07c2308a) Z8(a1e4a056,4fd3b446,3ac46170,66d8d540,01c8c50d,2eff67e2,ae3bbcad,0083de03) },{ Z8(bf1027ca,5ead48b3,ff3f51ce,708c8a5b,fd6dfed4,cc06d25b,7766afcf,a9e9ce8c) Z8(93379645,cf48be75,715ee9c6,75134f09,5134c8da,ede2f177,c63e7b01,0087dbec) },{ Z8(35785e9e,3e942680,e875d7a5,26988f31,a6bb3588,3d8a1f2e,ba07bff1,5095a608) Z8(6b004d41,8fae0503,af5583cb,ac9ee56c,0462a0f8,e0272064,ef33b669,008bd9c5) },{ Z8(fb21f68e,753260fe,8537dd47,e3500179,5c237884,b75c1e8a,1e417876,4b22e850) Z8(000ffc2f,70ef6ef4,846a1e3e,95466fab,ac33691e,75cbef6f,299aa0c3,008fd78f) },{ Z8(75a1dee5,ac4f21b5,4b573dbd,bdb47dc4,37b11727,13d31b84,de086ae3,b78ca501) Z8(6ba71552,fb24c1f1,f6c179cc,8c808eac,e77d05f5,2cf1eb25,75f265fa,0093d548) },{ Z8(2deabd12,63bec9e0,37a6edac,12c1ecc8,2527fd67,8b4d62f5,97a8d5c8,13aeb9bf) Z8(c4241c37,67d35c35,e4cdbc59,76b21c7f,dcefe9d3,f0d1aace,d4ba2c06,0097d2f1) },{ Z8(76ffbe27,b1e95072,49c84b76,e92313df,932d2871,cb9160a9,a902e528,63a4a86e) Z8(3c7c239a,e0a5bd0d,8dfbd4c2,984bca93,2508d67a,78abe286,467112f0,009bd08b) },{ Z8(e5063188,bb5ad7a6,67234eef,800aff74,f5305fa7,57b2808f,c02ba4e9,e7e5cdfa) Z8(f4f87b33,b0574dfc,edf272ee,60d8ba6e,5bd3b58c,a6b20f21,cb9634cb,009fce14) },{ Z8(d1792a4a,f57169c1,8530795c,e830e638,a4ff130d,80b9b11c,345d8133,10861bf4) Z8(c97e1031,b5a4fed7,cc3fd585,53dc4b8e,7eeec422,e6e7bc97,64a8a5bb,00a3cb8e) },{ Z8(4f36714e,1ba838d6,628f13b3,3434af35,61f66e9c,e9376e9b,0d56f2cd,20dfd11b) Z8(e5b72558,af61cbda,d971aec0,12487785,28e9d9f2,8dfc679a,122773f3,00a7c8f8) },{ Z8(933a153a,5a3e565d,21d72452,a23255c7,c22b78d0,04b61a2d,f572a9bd,4f7ff0d9) Z8(6335e23e,c8d3b0ea,f3596f8f,42c370ad,a7cc8928,381dfb11,d491a7b4,00abc651) },{ Z8(75b1a874,0ffd44f2,90adc6b8,62df9624,db40b8fe,6c7aa328,c11e4d1f,5704f32a) Z8(f694e7b8,9585a480,cf0318ef,33bfcaab,d93f316b,27c3ea2c,ac66434f,00afc39b) },{ Z8(e06e5919,2927744d,d60abeec,e630945a,e6f8d6aa,6f7c9599,781a348d,1f5fd896) Z8(6026f361,b151520d,b29c00f3,1aee5793,a386e5e3,a472e7b5,9a244325,00b3c0d5) },{ Z8(de078ae7,480e3d76,fd2bcb45,05f26336,33fa6860,6ba5ca49,1543029c,a7dbafe5) Z8(4e644993,a2b54d41,ada1c113,619cffdd,cf3a3364,59793b5a,9e4a9da9,00b7bdff) },{ Z8(06735d75,24c626a3,422cc204,98c9b76e,e27f608a,9b6f45c6,4e4260c0,6562056f) Z8(4954a379,9eb7a003,18716269,22719505,f24d6892,b4a3b59f,b958435c,00bbbb19) },{ Z8(c4b9be54,ab3b6a5f,e75d1021,85aab5ec,40365daf,008f1701,a6729ae2,9df4c673) Z8(15be5920,d672b536,013b32ce,8d568dc2,09cffdad,44eb4324,ebcc1ed3,00bfb823) },{ Z8(1a6b1ba5,ebc85846,e1a91850,1887f224,63edfd20,0bf7c3ae,9c5fd129,577c039e) Z8(9e1ff4f5,bff5d508,10741031,128f38bf,4c721c74,191b1fef,362514b2,00c3b51e) },{ Z8(1f979973,e2792fa5,08a8dfaf,e765456a,0aa680e1,ccafedc8,5eedcd19,7aabe19a) Z8(978d1afd,e6cdd79f,ba155a9d,cb5e4d97,aca91193,1e6fab78,98e203b0,00c7b208) },{ Z8(83ac4f59,57383936,0d4c8f45,51d4573b,e8e4ee54,d2231c8e,69bf13de,33817b57) Z8(7f1a47ce,20d61862,fee7a1a6,707f3119,6e0ba085,7f2dde13,1481c496,00cbaee3) },{ Z8(5e6bdd6f,8cba337c,fb61b972,25c2e73b,69be5817,fecbecf9,9fbdc30a,e6b7953b) Z8(447782dc,b8c60248,5217ec2a,355d10db,1e43c7af,01336075,a9832a41,00cfabad) },{ Z8(3ae610e7,a927c538,2f2c100c,99c6b780,7ff1e2e1,be1a1eeb,0be27aae,0227f915) Z8(39bade0f,67addee3,ec5cff24,08512895,2eba7d3e,647f4604,5865019e,00d3a868) },{ Z8(c0d31800,a4721cba,e859f70d,ddf2e3c9,a58d5bc3,65471a81,60f772db,7157132d) Z8(283fb5d9,54c9fdca,e82b32cf,078770a2,58eb4ccd,c1b36a9f,21a611b0,00d7a513) },{ Z8(8e146caa,44554af8,9852903c,93e46ed6,e09ea2fb,890a66c3,55883b20,4f2e9654) Z8(ce8136f4,41fd6636,00fbaf66,801f157d,e4198267,e88e748d,05c51b8d,00dba1ae) },{ Z8(c336ac8c,8706d416,d7190699,fd87fa22,b9359862,e3c3a012,da36b5de,0845fc3f) Z8(c4fdd760,d255bfb0,4cb74df3,a7bcaca7,cfeeb85a,be5e7b48,0540da5f,00df9e39) },{ Z8(76fde9b7,fdc4e4af,f1ed4448,a6243802,62664345,d8b98000,6694e0e3,cc1bf9ac) Z8(c480c726,7b62fca9,fdd12923,9b78e3d1,d45b2a53,9c6c53cc,20980364,00e39ab4) },{ Z8(3f8e1951,55bdc61f,e01d5bb1,50552a83,621f646e,9415d382,d7aa2620,60611de5) Z8(02dc658c,e000bbb1,dde4dd76,42a65998,13e32116,ae5f8325,584945ef,00e7971f) },{ Z8(f1317ca8,2cb071c1,1c950730,630ffbe9,e7b9a5c4,0335b8a1,565ed229,aec77f1e) Z8(a6dbc6fb,8084256f,35411485,c6764d7e,4a5a1e5c,509ad7de,acd34b69,00eb937a) },{ Z8(d5a00b9a,2d07b7cd,e8c44bd7,8dad7157,120834e2,2813c281,aba7a595,661255d3) Z8(270a5d03,7895fa76,4ccd48f6,b48862e2,2ee427cf,6e91ab12,1eb4b74f,00ef8fc6) },{ Z8(4e203afb,619decaf,853fd4a7,c26d6e00,55b97354,97da2ecd,0e10dd1b,921079a0) Z8(b81fa0f2,b9b51453,7c1f2e00,fabeadf8,acefaa2e,e115c9ba,ae6c2735,00f38c01) },{ Z8(a668a43f,f83ec6c9,5c9ed99a,d960d82a,182f3c6b,0a5a4916,6cd7c7c8,31a2f869) Z8(1e75ba80,2896dc3d,dab452e3,24699801,84b6ea5e,cc9e06fc,5c7832c6,00f7882d) },{ Z8(0f8ac595,a9a2d75c,a1ff3231,741f2266,cd465675,98c110c8,14c76f39,402f3cf7) Z8(adf9dc5c,ed38e322,31f2f4e0,177d8fa4,d0b6d8bd,ff857818,29576bc2,00fb8449) },{ Z8(f0697e38,b4baf715,3a53ec28,699b4749,cc95af15,d137bfbc,4192b38f,7ed64a06) Z8(5a1a3322,91ba6e33,6d725824,8ccd29dd,da6a5bb4,50435ab4,15885e02,00ff8055) },{ Z8(f2fbe39a,b0a09e7d,ab4d937d,c932ef50,8b1f8a6b,3aba97dc,7eda3fab,f0f5e77c) Z8(3e20633c,0610e9f7,c212c043,3648bfe0,957cc84d,fb9ba627,21898f73,01037c51) },{ Z8(8e0e24c5,41a6b666,4f97b2ba,6ee55299,da164bdd,c6d8c666,e96270f2,11e0d043) Z8(d4bfa049,b832c8d6,acaa8dc6,9d671866,058c42b4,02c8487c,4dd9801f,0107783d) },{ Z8(ddc1e10f,ca511896,f32d8b54,53fbe765,5c0904f4,b1e637d3,c46293f9,7f2b1db5) Z8(0593c102,0da1943f,42704593,eac055ae,bf7d2465,899b0fd7,9af6aa22,010b7419) },{ Z8(609407ed,a94e9ec2,5e6ddebe,fc430e2c,f62e1599,e5cf9a05,16a05246,ed4c214b) Z8(94a725a4,4d4ba377,f58fe6f1,bc7aa84e,a44a49f1,349840f4,095f81b6,010f6fe6) },{ Z8(94059f3e,8464485f,bc962d00,50404911,f1c7192d,7e8a375b,c7ba304b,43799dfe) Z8(f93dd648,603e12ee,37198f3e,bea0bdb4,e02b4ec1,8709db5c,9992752a,01136ba2) },{ Z8(ed8d842c,58edf35e,dab9e859,52826990,b5c2b215,a81db272,28f71d7a,5ecfcb75) Z8(036dce40,d03b94ef,b83a73c1,b747f61c,25d9415d,410b8c18,4c0dece9,0117674f) },{ Z8(8436764f,78504291,aa9dea40,c9869312,08043c08,f84a42e8,8c4f7b86,61a3a120) Z8(f69ba443,afe9215c,453de490,0e432596,0aac3e53,bd8f4f79,21504b75,011b62ec) },{ Z8(853f7ca1,777e550b,0cdea499,d68b3513,20bfb619,9c167cdb,e7eb2269,d7de7f28) Z8(5e33974e,53557268,19a4e1e2,77ee538d,5540a298,505ac2b9,19d7ed6d,011f5e79) },{ Z8(f105959d,9db851db,46444cee,2f7e1d45,e5bb3d85,76bcdaea,6a0eebd3,89c34913) Z8(ac0d8e1d,169adf00,e5a4857f,5493f88f,fd4927c8,a3fd2613,36232987,012359f6) },{ Z8(d203908e,02ca62d3,4f34347e,e2aa8e94,4c7af8fd,e5a7ad41,9d52858e,a2d55b1d) Z8(63d691aa,c506387e,8d073984,9768cf4f,882c3c80,17be100b,76b05097,01275563) },{ Z8(056e4b9d,cb547362,85d30619,0774c3cc,7b76e77d,62feab55,548d2205,c2f25a83) Z8(af1e55b3,c94991fd,965a9e22,bbbb20f2,5b064949,1d84d28b,dbfdad89,012b50c0) },{ Z8(43c0bf69,99519342,d5fa1e25,88a414fc,c298ab06,437c8525,e6ba0238,87d5c579) Z8(0f34341c,9630b883,20673da0,9c847e0c,87a84e42,97b89292,66898566,012f4c0e) },{ Z8(d416551e,e6cef8a5,af4390de,0ca7a65d,bb045932,a09689d9,e7aad825,54bfb4ec) Z8(33815654,ae5ec783,7f40727b,1f120f44,872a5f20,37191316,16d21754,0133474c) },{ Z8(343c1335,c30433ec,9700948f,2e37bb15,5b7d91ff,c57703c4,77ed2379,97f3c2c3) Z8(73ff4d94,a8611edc,eeec0c6f,cf20cd6c,41abf980,d89033cc,ed559c92,01374279) },{ Z8(09091dd8,42208d0e,2ff745c0,900fcd07,a4ad11d9,af23eb6c,7de4f9b6,4b9989aa) Z8(90a20265,2defe197,08c9080e,18f6394d,afe104d1,e2fc2485,ea92487f,013b3d97) },{ Z8(4533ce4b,200d4e60,b0eb1eff,a6dd1f16,73b6e444,ad86fb62,5722681e,57075db5) Z8(357fb684,e444e58f,29be3018,19350e86,50117ab0,a4f24dd2,0f064895,013f38a6) },{ Z8(f3a83285,fef1d22e,3f469677,e72ea369,1038de7d,18e5003d,c99664c8,cacf87fe) Z8(a27038e6,3c826b1b,13003313,6c225df5,953b429a,b27aef90,5b2fc46b,014333a4) },{ Z8(7d0c6591,d8332a29,b302dadc,cb9be321,410944d7,2bcfc6e4,dfe028f9,265b03bd) Z8(3b590bc2,c72671de,687bfb68,759bab55,6411b343,42c5761e,cf8cddb7,01472e92) },{ Z8(e73a7b96,da4c756c,df5ff9c8,117a037f,a5f765ff,dbe54cc2,fc107cd5,b4474cf0) Z8(c499edb6,5ad22684,f01e84a9,cc1fc4ed,9ea46f21,8dd586d6,6c9bb04b,014b2971) },{ Z8(26332e90,fba231d8,08d3adb4,e9a84341,a0b1e214,49b2fd3e,ce035f1d,f5842953) Z8(901e6a3a,63ccf79c,727a81b6,5521fdc1,ac87eff4,2a28c489,32da521a,014f2440) },{ Z8(71e6a2a3,e976e893,168d772e,8f55352a,6125ba6b,77e347bb,0c95d6d1,ae102c35) Z8(a04a112f,660461a5,52edfe67,d5aa24f6,da6d0e16,6a554c9e,22c6d333,01531eff) },{ Z8(d5e7e949,56743794,3db16793,5a355b17,5ddd09cc,53041652,eb004d11,56c39ee6) Z8(97854ceb,495c1afb,39030db5,eb60b1f3,592a2409,baa0ed8c,3cdf3dc6,015719ae) },{ Z8(e16e1f3d,025f9fcb,1929bfa2,9d8bec12,ab8dbab8,1ac7047c,531aab4e,ee875b6e) Z8(33737d75,7bb1028a,82d1dc36,480f5056,91501c47,fe911753,81a19622,015b144d) },{ Z8(4416a069,fc31f39d,ad9e9a29,cf707c8d,b2cce68f,29314e71,f17649b8,db435061) Z8(00d4a03c,a0e610e5,e219d481,69e4b23b,6d7fbf03,ee7386af,f18bdab6,015f0edc) },{ Z8(d87c55fc,65885a99,241478cc,078f0771,2e5d38d8,5e29e3b5,f02e7126,8bc74965) Z8(41089ae5,cd34fd1f,bc0d52f3,b818ca49,2acff685,74dfaba2,8d1c0411,0163095c) },{ Z8(575a3b04,6d8341c5,be54b372,4ef7a209,9d661c04,46ae6e72,acc0f8a7,1b8d1725) Z8(e769cb62,c31f7727,c63b3e1b,c5a28c43,2bb47af2,0c30cc10,54d004e2,016703cc) },{ Z8(012c7add,9a9acd1d,68ebabdc,17fa0b44,19745604,1aef3cc3,5d8b8345,d65ae94a) Z8(785c0766,636cd4c7,89ee9874,6f5ae2f0,36f5696e,1bf8e315,4925c9f9,016afe2c) },{ Z8(d1f287d9,7933958e,5b32f32a,a9591ae6,eb12cd3d,4032326d,6656effc,d5fb7469) Z8(0fdc295f,d3b37d89,6fe06366,920acf95,796bb608,566c3dc1,6a9b3a48,016ef87c) },{ Z8(ccabebb6,d760c7b1,1ab86a22,21073e23,a56ebd93,72024eea,b0b8805c,82e0477b) Z8(6ca3fca0,3a9e6470,13fa14fd,366bdb39,8e5c2ba3,15c5d5eb,b9ae36e3,0172f2bc) },{ Z8(e92b7468,f91fbb7c,b5ec76a4,a150c369,d4073501,0f790d1a,ac10c6f5,7783092b) Z8(983b004b,bcc0b6e5,b08d164f,610d389b,bf72c898,b9a46bc4,36dc9afe,0176eced) },{ Z8(a8aac846,2f645b37,349ad849,8b4ec729,9208251e,16159412,90ab2734,b7e5eb7c) Z8(caacc5c2,54b1db46,bb561c2e,5361e455,9a8aba04,04605edc,e2a43bf3,017ae70d) },{ Z8(96cb638a,faabafc3,0e8ca9f4,16064670,73a2bce7,95165acf,a35e4561,6beb75e0) Z8(f1aded85,903ae028,8d165ca4,2800d1f3,e89c01eb,785a4740,bd82e93a,017ee11e) },{ Z8(53083785,2f7d6353,6717bc37,23d6413e,e25020f7,e7c074ba,fe2117de,d3ac8cb2) Z8(7faafde2,b24fdc38,067c90d5,896910a8,fe56f5a2,b5424f66,c7f66c72,0182db1f) },{ Z8(35b40305,ab118f51,8f80ab48,92ffa364,0e609295,62206c08,35eae090,aea7f360) Z8(46acd659,bd4482f4,2d792fc0,187d0295,4c2739a6,d5584f8b,027c895c,0186d511) },{ Z8(e4586812,8267f186,b664f802,9903520b,324fc988,7180dffd,d2e2b8e7,c724f4f2) Z8(055fdbce,c814fa3e,12b05de7,43763ab0,008badf3,caa4ab34,6d92fddd,018acef2) },{ Z8(c3cc6dd6,78a51015,586a5595,c46c3051,4a14d3ee,97527cf8,4f886a54,f5b8b4e0) Z8(f983e17b,5846fd06,4728876c,3162cbfa,7ce6e1e4,bc29f183,09b781fe,018ec8c4) },{ Z8(91ac9328,3f24c2ff,80665588,901d1d86,15598dfa,3eefcbb9,bfce012c,a3ba4988) Z8(31706441,449fa385,40ebc439,705c8708,4a241fed,630f4107,d767c7ed,0192c285) },{ Z8(f5f17f0c,e417372a,b09692a5,b0f7c682,0ec096e3,8cb94c7d,443f2d9d,7b3122b3) Z8(473030df,e0abfed8,ec606f07,c1a49f5e,27c7f04b,67c36fb0,d7217bfc,0196bc37) },{ Z8(b5a017c6,67e1505d,398efcd9,401068d1,8da15e2d,a8ac79c0,738e3b3a,d23494a1) Z8(3e5b020d,a26fdf99,063009b2,37a4216f,bd401543,bf18f79f,096244a3,019ab5da) },{ Z8(9ce14854,fb9ad100,7cef26b8,46d455b4,8da98fca,570a1785,425fbf6f,09edfedb) Z8(90f3c067,86a00eb5,0f6eed91,747aceb0,62867bbb,075aa978,6ea7c281,019eaf6c) },{ Z8(e2c19157,9434f3ec,e1f9e66b,8032d462,faa4d041,b0872bc5,2a616571,62bda43a) Z8(580bfe3f,75aec43b,f0a26462,d72d1652,626c6772,e55924db,076f9057,01a2a8ef) },{ Z8(55e779aa,d51a3aa5,3e2c93bb,1dda62eb,893f3070,9ba945ba,9b7040b3,dbd4122b) Z8(e640ba32,4bc3e23f,8b567604,7982e2a7,06274260,617117c2,d4374312,01a6a261) },{ Z8(fcbed80f,15e25d10,774d3bfb,a9a3f88a,868dfa18,017af617,5ce0f30c,1c922a28) Z8(8d3502f4,cd19aee6,5120781c,c60ec200,a6feead7,448a455d,d57c69c1,01aa9bc4) },{ Z8(c350c3a9,38ae4f1a,e99d875c,2aeffba6,eae45054,d6409c8f,0fecab7b,56ce31be) Z8(4747edfc,ea66a259,ce670094,ee57448a,f0462344,750f552a,0bbc8d9c,01ae9518) },{ Z8(5871e10a,4808a045,b2bad39d,1ada7eeb,eabb563e,9329dc9d,f878bf3d,f2b07d64) Z8(6593c333,ac5cd41d,ca2d5319,7b5d8bc5,6910e094,53de6ae4,77753203,01b28e5b) },{ Z8(f6efedab,88013657,01f0718b,0e1eba94,2d91f351,47667de4,6a68c633,0dd1e97c) Z8(176e511a,56f7f603,bceedd0b,7a46a98d,4a69a136,19328800,1923d47d,01b6878f) },{ Z8(dc428b95,bef79abf,182edfb8,122b110c,23123d4d,8b3bef01,aa1eda86,fe9452ab) Z8(f2a0c323,68563aeb,8e635f8b,543266ab,9416b5dc,3185b765,f145ecb9,01ba80b2) },{ Z8(d2f30446,a066ddcc,39b9e717,15e9f367,405db65e,2b4f58fd,0525be43,32b68b50) Z8(20ecce05,4a9e0f8f,d51f7739,309e2f1e,3f52763c,9a6c0404,0058ec8f,01be79c7) },{ Z8(fa460a86,6942bea1,8493f488,cd2e702a,43412b1c,b62dfa51,19907817,81af1ecf) Z8(12cc5e38,b6f595a2,1bea4f90,df4cce9d,5c2dbefa,3f673afc,46da4001,01c272cb) },{ Z8(7bb40ea9,22ed3898,e39d6b1c,399ba758,fe53830d,b672f8a0,be0d7aff,21f3a892) Z8(81bdf9b4,5159085b,ebf9c52b,c8a18685,d3aaca0a,56b379ff,c5474d38,01c66bbf) },{ Z8(8f529643,64ea9670,e9cbfb1b,552bc14e,e269a902,77ef4c52,ef2bf716,e0b5a3aa) Z8(903cb0f8,0d8eef1e,a5dd757e,6da264e5,75f77800,be0c8a9a,7c1d7488,01ca64a4) },{ Z8(f14e730b,4363d589,8fcb8fd3,6daa273a,0755651c,934df6ec,f543a503,873828d7) Z8(85fb9975,a832fa14,a063e9b8,c4395d82,e98976c0,576c0b0b,6bda1070,01ce5d79) },{ Z8(77667c69,61052bf8,e5f22c61,4403a1c2,ae9aa9cf,ac609e23,3819a51e,5d96c7f1) Z8(5c2f57be,4b4e13f3,142be1fa,76753283,fd3c5830,65c0655e,94fa7597,01d2563e) },{ Z8(5748ea25,342c8e69,26fd9300,36a2ad59,699004de,dcd12487,5d14cb33,1751acf8) Z8(dcef186a,2d4c6ff0,fb1f13b7,06f93d9b,ccf1a1da,e99c9569,f7fbf2d0,01d64ef3) },{ Z8(538cbbbb,628c87b2,30868ffc,ee809ce2,3a204807,cb3c1dd8,558a2e3b,3b87d7d8) Z8(07b71510,0e752d45,1cc16136,70d0c31c,15952489,fde0be62,955bd11a,01da4799) },{ Z8(c4b271ea,cdef4ed7,8ca00d36,b5f7a740,6c919cb5,5aa90462,4ded25e3,0cfa2376) Z8(30c94590,8392a755,baa9fb98,699d2ddf,02cc804b,345b90b1,6d97539f,01de402f) },{ Z8(2243d44e,bb5a11a4,194c2b5c,98651b98,bd6b9d38,9b405ae3,4cd5b301,7b3f709a) Z8(7f40419f,7ec4adca,7b140cef,6b8c28b3,adff9dc2,f26480b1,812bb7b2,01e238b5) },{ Z8(356b1f60,ec2ee5cf,29868a31,16291d8b,ffd69d70,98e63e9c,1c34017a,f5adccfe) Z8(0a0aa162,843652e0,960f78f0,966ecbc5,73d11909,cd6ecf05,d09634d7,01e6312b) },{ Z8(c33f9f65,e4fac114,15927c6b,3afcfbaf,8798e474,0cbf09f4,4ae7f878,d91d7bdf) Z8(4f9bcbf7,68830083,588d3104,d73dab8f,32891c12,e7956329,5c53fcbb,01ea2992) },{ Z8(2cdbf61c,89ec95d9,339e0db4,b744434d,708140bd,606ce0c7,8e9e5c21,0260a55a) Z8(d9cd3411,3e1d81e3,01ce9e9b,32a7d697,7162f640,4c1f78f6,24e23b3a,01ee21e9) },{ Z8(8c8d9511,04878ca0,8fcfc9ef,2f7f2907,33514767,0ee8e7f0,80be14b0,77d91940) Z8(da35fb25,eededab8,8812028f,2e1d8afb,5e1ddc95,4bfe21bb,2abe165b,01f21a30) },{ Z8(7bdd410a,25b49440,c86c5794,15b29515,64dc2389,69514c55,ccc5fcb9,f1ddfc07) Z8(3d3a2566,2d9c67ac,b2e63012,d400c64e,7ba3a8f2,da429994,6e64ae54,01f61267) },{ Z8(f6725be6,4314e3b5,d71e6baf,2896befc,5e6b55ff,ac21ee8a,fdb1ce5f,7a42502b) Z8(fa5d1c6e,62b187fd,6bac0a8b,70ef0e95,ca0d270c,e88d71b2,f0531d8a,01fa0a8e) }}; const mp_limb_t arb_log_tab21[1 << ARB_LOG_TAB21_BITS][ARB_LOG_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(62755d69,e496938f,05daf00f,5baf03de,e7d47be0,876a8079,f673a2de,42c7eaa7) Z8(7c0dedcf,b951ad59,fb7be050,cdb6b676,c61b4b9a,5c71d0a4,e70de3e1,b2478447) Z8(c7c58559,1947ba58,ed644c21,3a4a3445,45cb0fe7,28872ee9,2b52267a,c6888f9c) Z8(ab77734d,4f53d356,57f7b519,1eec2e2f,486fc6bd,1678ec26,eecd9969,c88799c9) Z8(f6b13852,e1f836bd,79cac542,79ca2220,3edc6351,17e1d8b3,d27618a9,c2141a5f) Z8(323af80c,5d01cc32,3d4c10e1,410d860d,0c975e1e,ed109f87,9495b1ac,6483bfe1) Z8(67c3706b,8b72920a,b906f4ed,463788a7,3af1b218,0f14f335,de1bef77,8540a3f4) Z8(caee6903,f0bfd950,c7661262,a8d061ff,ccdd8781,948d50d9,0c5fc975,d573845b) Z8(d564ebbb,e3d444d4,56901629,6bbdb38c,422a728a,00872128,d70f97be,ecdd781c) Z8(77077723,c7b39aa9,8dd25814,64b3d053,bdc530c5,cac1d2bb,b4bee981,4bcc2822) Z8(638db165,034e5ceb,5911a433,775b6575,6721f58a,1740d6c6,660c9f0c,0afd3039) Z8(2ad6ab1a,8400cdeb,0182f7f2,4eda72ef,278b39ed,9c07347d,e853cd50,29bdf766) Z8(6c5511c1,415cd4cc,3dbea7a3,7fa5d3aa,e1a5772e,e8b45e05,0a4e2e28,1c0e0822) Z8(4785a221,f6b2b036,6bd6a362,c035aad5,2ee8293e,626c2ef2,1bc4d08a,ce921467) Z8(ea801ae8,1cc99aa5,403dd582,93e18189,8bd310a6,750b0863,532b6b9b,5faea913) Z8(8fd1d5f6,48625f86,c1bb60f6,c6ee8bcf,8d212c6b,f6cf9703,38eed29c,ff7bd74c) Z8(7cb29271,02127ef4,0f6e3a39,9ce34431,e0a5d2e3,55d9a7ba,ec979e9d,8a38a3ff) Z8(e3673dcd,df6c758f,ddf35ad1,aefae14c,ef229fae,3e3f04f1,9e0cc013,07e0a6c3) },{ Z8(cdfb11b8,fe5201f7,f83a048c,5ff73ba7,2e3dc08b,0c37df21,a532ebf3,60eafe86) Z8(d274008a,edfe0e06,e2846224,ce94dd65,dbd5db88,fc2a05af,0e14f1c4,acc9fcdf) Z8(136d75e3,db83a653,3209b121,d53c774d,a61d5746,d6d53036,fec4a7d6,7575a44b) Z8(b0dc11c7,33af26db,5b61b49e,119ec434,f811504b,61b2f223,3f704e8a,955d39e7) Z8(64e6504b,3312496e,3312631c,10b84ee5,a70ecef1,e4d50c14,8c65bd71,84016a52) Z8(929c44fb,e842912b,2b44d39d,df8712b5,c81476a3,83cab0ec,a9362560,8ae27c16) Z8(b94a7a5f,3e7e4715,f6324a76,ebfc64cb,2297a345,bdbe51e4,5ddaadec,51b0ed53) Z8(786ab619,2745d1a4,852d3853,354223c2,d12f0e36,ce6586e6,b126e954,355f3293) Z8(72b38100,d61a9908,1eda05b7,2a134f90,6a6eec21,4883f333,7753257d,bfcb2222) Z8(36fa4365,4df3bf39,e3704572,866603a5,321515af,d39a56e3,faa48510,befda077) Z8(5c3586c6,cea9eb88,d5f32769,2ebe437e,550b5ddd,d27eea99,e47e74d9,67cd3330) Z8(eb97c7c8,b48eb540,734ec246,f139c8bb,8e6239d2,c2ec2f61,fc43d0cb,f2a711e3) Z8(6e339208,2f14b1da,18a07a32,86d0d6f3,9fb7dd8e,9da47afc,c2d0065c,8963312b) Z8(89ac698c,c14e8a75,06e51059,c27b07cf,bfd7f245,c3f710ac,9362f430,6596620c) Z8(a5d9c7d8,f85fcf25,b857a365,0fea5d7b,99f1c7fc,3c5c1d2c,980ce36e,8f93e053) Z8(eee9d358,d2692bbc,73d21d72,cce585dd,23c4de58,e0f55844,5f36b22c,68fdf95d) Z8(77e6bc16,9bc35789,e7a9459e,99f0cc1d,85badcca,908722d9,de861006,6172da6b) Z8(96f69849,71851f0a,75b52596,d3474d33,75997898,be64b8b7,08b15330,0f851860) },{ Z8(df4e00a8,b5fc6bd3,cc3754c0,0a06fe58,d751e17c,d238d6fc,20b60484,dff744c6) Z8(2d370598,fb1de605,65edaa94,6e812701,dc868ab5,f60ab60b,e5abf6dc,b14d9ae3) Z8(af48de57,e69cafeb,f65ec92a,311e8b96,bb6f4781,b19ec6fb,c56ac13e,2cce2d63) Z8(ca96729b,b831858b,415c078b,6d7c907c,1186a8dd,90ad91c6,71fb957d,10965a13) Z8(4b298299,027c186b,11cd3add,447f2d77,3290979f,6d147a08,c7b7c4c0,7b30074f) Z8(927fa089,43a3f1d9,c7b381c3,c63c597b,253c2c2e,3b55ae7d,df920c24,8f5d6393) Z8(5bdc4663,1255657a,09f154ab,86822055,21b0a2a2,db007af8,474baede,602f73ef) Z8(44fa340c,e804b8ea,1aed1a12,c922f2e3,75c0e7fe,4ac5c2c3,0d999691,d9ed8684) Z8(75374559,ff1e6e20,2ca7ba23,22ea973f,ccbeb702,a381fd40,2a06c4cb,f2617481) Z8(267d2e7f,9e6f6ef8,bdfe4e5a,91579482,d5e59de0,6536b76c,5d022bc5,f2376bd2) Z8(e5ad0841,b4e492d3,ed3132ce,580e63be,484d1944,e6bfad99,165a8617,94fb6c58) Z8(3d070ae2,301d02ee,9158b783,8a52c359,b33d0cae,0d271308,b04a747f,207e53c7) Z8(ebfbcea9,cb73d940,42b5ad6e,dceb080b,564b47cd,f620ed70,3ddb8b42,a86e6274) Z8(7b3c8a90,e2c24f7b,ff6cec9c,89a563e9,33ca5281,708e4300,b5f4c145,b538c781) Z8(24c08161,7c5f7fe5,844b4bc7,e86d9ee2,7e0904a2,bd843a80,6f047d68,9f1a2e7a) Z8(16743765,88712110,034843cf,1c16f09b,a1760317,3a47054d,e93c9c74,73e8df8a) Z8(eed4c843,a047161c,dc5afe2a,fa8c6dd6,644009ed,c1e6a872,ba4a6521,284ac3fe) Z8(34b59afd,812f38a0,087fdf23,50c1ef65,19b640ce,e499b9ed,e56b4b9b,16f0d28a) },{ Z8(317b6065,79b2bad9,67a7871a,d14e0511,7ae56455,60c3debb,f4c3ca8d,799670d6) Z8(d73b91d1,e5ca501d,945c8783,6c7cca6f,a9012db5,4392849c,6651b13f,75ec938e) Z8(45be3d52,63d0322f,dba7e9a6,a325de16,84fb154c,e6fe1bae,e5428ceb,b0c11587) Z8(bb281c4d,07fec58b,8b1bfb0e,95a86314,f3f82954,0197c872,f36fa170,6ca21d3a) Z8(555452e6,d3233d7c,fd4475e1,ea6023ea,a34a8eeb,cd021f3d,3541dc52,6aa43fc0) Z8(6ec6be59,c4081185,215b5d90,6427f311,13ea7282,f662447d,25605e9b,83b723a4) Z8(fbddc36a,c44638e2,8cc78293,08ce1d1e,b31540e4,e6fee1c8,833ff35d,e3e8d516) Z8(b21fea15,84770c13,d060df97,2cb3453d,17c25ffa,0f2bb1a2,a2c60d16,4c45d546) Z8(a8cb89d6,b41fda65,1364247a,5f3c5ba4,a1f1663f,75af3c47,eaf066a7,ad80912d) Z8(78573307,198be1f1,ec729fcf,23ca0530,f16b0557,9e19b336,f820e4a9,994a06f8) Z8(e5455baa,16517d32,5386e25c,391e4dda,fc7f71bf,831db4c9,cea5c2b2,f4634c2d) Z8(e370dfb2,a0b0be49,a6b48112,4628a890,a8880ee6,eb4db477,c0e4a00c,576133ed) Z8(27a06c7d,afbb1097,cc9021be,2bf402a9,47c43e76,d53a8362,b3997a4a,e634d5c4) Z8(7ae476d2,e2a9cc19,9d0a1ca4,88ae8411,d2d3c05c,375c1b3d,0fc7d00b,e56ad541) Z8(49f361f3,050013c1,7abe8667,b8b91190,48b72758,e91a8c65,1bb0f03a,48c4ea74) Z8(0574e2e7,e2b3fa40,5d60e11c,10568afc,64ae411a,3f5b4ef0,d608e6fb,51dccb81) Z8(ec0c6459,286a0066,f9a71577,fd2c1f6c,2646cc77,a023f574,cfca2ad7,9e05a342) Z8(ff917c95,dd0897c1,17f6f957,b94ebc40,fe9e155d,ea87ffe1,2af2e5e9,1e27076e) },{ Z8(65a865b0,bb152da6,317806a8,161c75a8,88f43e10,22a640a8,aaa1f1d0,d1fad5b3) Z8(1a3eb389,5663f9ab,939fff29,b69fada1,007d7fcc,9992d931,e77e4b72,73722742) Z8(841948e1,b80c404e,22a8cac2,58742129,3d92be47,a38d76ab,d4cb37b2,6e988725) Z8(0783beca,4e799f33,bc4c938d,f495188a,476f2c71,2a4ac5de,9c3d6d46,e73bcf5c) Z8(19dc0066,f19afd1e,8dd2d0d6,644a0695,f533f861,8856fc90,1fad0bd3,ff60b2ec) Z8(cdb39216,16d00cf9,9502fec9,eef85445,c8d783e8,d9ad619d,c3bfa997,931698ff) Z8(bcc64593,e138a38c,e435f79d,8215514a,4bb2fa0d,ca16b0d3,dbbb3dba,991fdce8) Z8(f3a07ce9,a7dab128,015e3077,b08911aa,6f4ae26a,d7d653a5,0b6de163,71e1d39f) Z8(35047ab4,3e9f51b0,a659046c,7f074d39,74e36640,58eb2c9e,62897f98,d43a90ae) Z8(a7048dda,94e91b28,a5475ea1,84a6dcb2,91402160,a9e0a8c3,b0edca41,418247fc) Z8(98da8c0a,3175801f,b9039de6,a2ccfddb,77dc036a,d69b44f4,bf55374d,2b0801b8) Z8(126c2c2b,96132c80,271c28cc,244b0a09,bd38c49b,1dd15fe7,5e7efe43,e5f2303b) Z8(a072ec08,28ca7bf6,0fc24a52,2c7566d0,0480aa8a,c2d8f531,6ad27764,fe8c26e6) Z8(e3ac4442,fc184fe5,1df59f75,1d369a57,c2f3c6cc,de8657a2,fedbdbd5,63b2ae75) Z8(2dd22765,b643e97d,3e3419e6,9b69f799,4636d8cd,5c613b65,51ceb731,0f7ce81d) Z8(9b4ebcd3,1c9f3964,2710c256,d86130b2,3751e986,b3125ba2,0d56204a,4d8af0d6) Z8(c430292d,47b9f129,7a3b264f,6d706ec4,36cd3025,e399a8f6,c81786ff,bdef2e4c) Z8(de50d341,3603f226,7e29fbad,fbc9070f,edf4d109,0bb8e203,3fea4698,252aa5f0) },{ Z8(8a42f529,ccf60cb6,40e39f84,85d2a5df,60d5f1e0,8c1de05f,d0bce7ca,3999d1a6) Z8(501a7b8a,0fdfb2f9,6a746aac,494541b8,8b2ee27c,3404d407,376b79d7,6588ef7e) Z8(52dc645d,acd0f6f0,f01134e5,03cb99d0,47b83307,e60f97d9,df89fd47,f4d99bae) Z8(63a060cf,012d251f,74702a99,68e1c2bf,d5f50870,4f6f220d,dfc3e302,2d6e9aa6) Z8(c0d6d272,f0ab9f1f,31b49779,d8f74cb8,21a62355,767fa66d,6a69981f,eb8fbf0d) Z8(b8650cf0,f010dcfd,bd5c53d4,10d0345c,9f13c00c,cb818633,74edad6d,63b6d616) Z8(dd92ab19,924d5191,e58598be,2708a2e4,cc1accbc,f9f58a4b,02c8ceb5,9178dde1) Z8(125b45e1,fac5c842,01fd4c7b,2f3678cf,4997f646,4ebaab65,745520e0,c20a63fb) Z8(2fa015a1,d762b2c5,f874dcbb,603f423b,0faf2e9a,fabf9572,5fa1e7aa,5b0906f4) Z8(fcf59afd,b1429ee7,ba297f44,d743c796,a0a51fac,dfb4e053,35b52ae8,95eec92e) Z8(688fc4b6,707409fc,0e65f970,f9098331,0dc5f44a,86a302e3,7efa4e7c,9e7ee42b) Z8(d7e2a046,7ac3b84b,00094a7b,20ec2478,6eb2c9cb,d00a1bcf,b1427193,f4080757) Z8(ccb18c9c,c9273566,f170aec8,208b9c36,7237e620,ff3aac31,70b5a44c,f1101f66) Z8(de5f035c,b9178605,ea47f5e6,f09223de,c72c9f3e,21b798a1,5728384a,e8323e47) Z8(6fcb8911,e53f634d,3017511b,d42ac352,5484a0aa,8e3c319f,ccfef3b7,159a0fd6) Z8(7aa0ed67,17dc4f5a,aa0ac9ad,854246d3,c711da9f,3305691d,254cd485,5429f714) Z8(fb5d87b5,ad7848e7,b88a7375,4baeb699,b541268f,97d44cc5,023311f9,edbafdfd) Z8(d928291d,c0acfed6,fdf3e631,d55c7355,424775fc,e7c4140e,4f27a790,2bfe60e1) },{ Z8(73c6e1a8,93afe235,9d494ea9,1bf52b80,d62e60e1,47035b9e,72c0fb22,8e1624e4) Z8(c2e5662c,22c01ec3,e5bc6f1a,ee023290,9f1bb841,f08b56fb,17c637a6,3b160cef) Z8(c2ed0944,322a5e39,e2fbfed0,7a63715f,650c239d,8b9b7d5a,73604294,cdb5e0f8) Z8(1bc73424,c90510b1,42b6361e,a84b9e24,1091c683,8e301383,2bf32614,b3059ee1) Z8(01d167d2,ac75ec17,4a0c8999,3ac897ec,8381fb22,2eb34f3b,eb79ece4,cd1834e8) Z8(b3743993,189fb3ce,02520543,f441fc65,e6b4e2ab,f5b61922,83b84d15,8aede031) Z8(5faa45bc,0494d9d8,d0759bd6,397cd539,705ff257,fce7d4dd,931aadf2,4861df1d) Z8(5da224b4,58470895,a29ade58,333f949c,3d7edbc8,644e319f,a894cd13,da446a9a) Z8(88153598,0d80a7d8,b7ad3eba,15ef3bee,06990f8a,d5d0da41,d424da09,4063e4d1) Z8(2502e78a,1ca0d680,438286a3,647a077c,1c1734cb,e08af200,4d40777b,90a6c97b) Z8(c3e3240f,0f1bc64c,b040ccb5,2115d1b6,c3ac0195,af606fbf,2ffe05df,bfd06902) Z8(a75bf235,75870acd,42ec1f6f,abb7e04a,b8204831,6e96bfdd,029c1d70,419df6c7) Z8(c16c1cf7,73786b50,92cd1c2d,632d7841,ebf529f8,a80404e3,29f5a6f9,4df7dcfe) Z8(2ca9da26,c3a3c4a0,bed0ef07,52dd76c2,4d708681,b2901923,c6b31281,c966639c) Z8(0cd1d47e,3f83a655,e2d1147f,6191fb6f,3ff9a5ea,290cda1e,e439aca7,5dae3ddd) Z8(be635560,362f741f,69c853a0,2bc23c26,f95327dd,190de9f6,dad45f30,38a0bcdc) Z8(46577c95,17b14e86,d8375221,45a5f1ba,77b20123,421b1cf7,978b7d19,9ba61844) Z8(d7f0a39d,13daa19e,71766947,a0bed3cf,712cec4c,8260ea71,e8ad68ec,32a4b539) },{ Z8(7442e81f,1c0a2524,dcaf51ab,3d71af55,577748b6,89f7e90e,f77a92b6,f2f1f423) Z8(f33b7135,e59a5614,351ab91e,9a24cee1,9332a81a,a861180d,b3d5069a,5be9dafc) Z8(8f7f165a,f37e0d9b,559bd4af,0f002992,4f2e1f76,746c8b0e,0d91de20,1ef9a170) Z8(553d662a,0eb53f26,4b8c8048,ce0b6a3f,acbe9997,aa103201,fbbc65b2,dcae61dc) Z8(f5382324,51555fc5,5476ad36,8396fee9,6357e90b,afff62a7,cd8b34e1,bdaa61a9) Z8(47f63b6b,b9f56fc9,05d648a4,99ce2192,e19e98a3,58f814af,ca5165b3,b00bf20e) Z8(c9e3c692,cf8eb5b0,7f4ea3c9,b5c2afaa,2e06e4d3,72238f02,5356ae57,63db5620) Z8(d1cceb12,58b02326,cd306780,78cf94ff,79097406,0dd4de0f,403ac2ee,106a192f) Z8(c1eeb44a,08d5c551,c4f8ff99,4945b599,619c2286,c5405721,aa3fee7e,09b25725) Z8(23be1b4d,29453eef,b586211b,24b7618c,40d02355,8540b973,c02cad20,d7249a7c) Z8(95bb4d99,14cefa6c,0efdced7,9f0195e8,ba5770b3,8395a571,24ac72aa,1de0e914) Z8(38087b12,804f8baf,d53afd59,8c17fdc1,647ec3a5,a14da4aa,320bcc12,87c11fac) Z8(315ae461,d9d2c797,f1e24d9d,6b99ba86,7c9f7fd4,ba0dbde0,e5b396f7,4a5db8ce) Z8(2351dc41,f4ea380f,69d486fe,c6f75450,f8ec637d,502f3dcf,c2d7c7b1,713fe0f4) Z8(1e5824b5,8bf1ceeb,ca54dd54,3c03dcc9,6951da64,58ade5fd,b55167b5,d1333657) Z8(e55f390c,d5380a61,172bfb37,8fdb6776,2eec1e73,89070cdb,c3518a2a,24ef8447) Z8(d75732ea,78383094,c087279f,e9fc85bf,d08de46d,3103360e,7cdd3baa,a192a8fd) Z8(64bfc746,70f133f5,11adc1b1,c765ea74,ff734495,4bb03de5,35344358,391fef8f) },{ Z8(1bcc87dc,0b70b675,7f3526de,2789a6aa,414b81ac,0121876f,8caed35c,b9eccc37) Z8(d4d438e4,0cca6150,35527383,96f82b0b,7319846d,0708a8e9,205a1d1a,eb0af878) Z8(bef4c735,4cf65ab2,30f19eb1,50143a6b,2b698ade,5d24472b,29084537,211b9070) Z8(e4df6647,fd57b4a3,0117514d,b56ad732,dea6b4d7,73a6706a,fdc785da,91668102) Z8(f6341a07,80208eb8,977c75e1,6fcd5445,79093c88,025632ae,ea19dee4,6616c55e) Z8(cb1535bd,3951e433,c3d7f085,8fd2c0fa,5d916a81,a50c2820,5b14dc2a,919b37e3) Z8(91861127,851ff0c7,3e9394e3,ac6e236e,3b4227b4,0e2f521e,3b3ccd2a,2062c180) Z8(e3807e99,fb7d344b,192a4768,f3678619,44c27a29,736ab683,ae45fdbb,00b577c2) Z8(5d9b9b74,7b80c02e,21291b06,cdfbd017,4d577186,97d970e1,ef6cebcd,2950f968) Z8(55745729,e1524696,0370c6ff,3b3ad97c,2c09e208,60d64766,3e63ff51,ce315094) Z8(90ccc188,28979729,d789d9c6,ebc7b9ce,11ce5702,fb2867fe,280ca605,ccd6b82b) Z8(5e629534,6bd9cd81,4c955faa,14636731,c9b403b8,49461317,c95bee9c,44719507) Z8(23deb398,f3621881,588bfea0,9ba4d984,8e0fb150,58d908fb,01fc9c57,c8dc2c3a) Z8(ef611e33,d24e5e70,2d4dee31,aa20da31,e4178b91,6349296b,f0171a8f,8b44cf86) Z8(59392d8d,a8c37f53,de27245d,48396d97,3e4dd588,28d3211a,c355fa60,de70e498) Z8(e3f9c129,91858558,f66faf7f,24b9a3b1,a597a520,5ef28bef,987d6ab4,9c2c4256) Z8(eb00ad03,63a59c53,435a44c6,c58402fb,09140995,c7167255,6589e221,e9c83e0f) Z8(6916ddaa,165f74d5,b22c817b,40584455,29a59412,aa8cd86f,bc7c551a,3f7230da) },{ Z8(4023e70b,1b88c103,b26d88bf,de91eb16,10afadf6,7bb86a7e,9818de83,c924ab5d) Z8(b916bfd9,3a7b8a09,f7ad77a8,ed8d7896,62db8b72,cfcbb9db,8224a768,d347bf06) Z8(a7163d92,30b615bf,e2e004f5,ebeed109,35b3f740,f8655cd7,78964362,4d9ad030) Z8(293cbd6f,dd3367a1,af0e0faa,2068e812,dca2f291,32ffacc3,ceaae415,ef918fb1) Z8(50fca543,3e546ae2,251e1ff6,66f8f53a,32e7e0fb,ae4d2d14,82f4b84b,bd63e7b6) Z8(49fbf67f,57639dff,be268493,d619b7e3,30075d0a,72f1971a,874e1441,4cc6d128) Z8(9403ee8c,251a3e87,8680f3ac,863030c6,ebba47bd,df3cf144,9d093d92,09b89dea) Z8(c629e2fe,d76da74a,1ab732e2,07bdc279,4ecc0dd8,f3cfcee1,54502c15,207e569a) Z8(524ab2bc,e39dc411,6f485072,4ffab833,cd606f18,e9d28e2b,aecd77e7,61bf789c) Z8(57427104,4d5a946b,c67cc941,293d90f1,9b3c372e,69cf285f,f298b398,0e42ebab) Z8(eac6c943,5ae6b18c,958daeb3,d963ae72,426597c8,7bd180fa,b1f1b295,3bfad217) Z8(02518640,8649db8e,bdf73804,24f5f4e0,520c97bd,96ce885f,f9634a0e,d7211bab) Z8(375c2534,6f8ba8fb,00e51956,6db1760c,57cacdce,8b5264da,9fb979e3,dcce1842) Z8(1f5d4383,1dc40f68,622cf0fb,7e30a059,6c3a7803,ec93ab4b,78aedf61,3aa8b636) Z8(3301f889,e00486bd,8ee62377,3b761ba4,552ad70f,54536e14,963e3236,2bb0b135) Z8(6efb6b72,b74ae444,f367e943,f15c1c84,3d9f216f,de538cf3,2214fa29,9733260f) Z8(1638a398,cfef8350,794371e8,85bd4ee8,4c529944,8bc0169b,dc48152f,499727b2) Z8(95940f17,c3c8dc39,3c19f534,067d04a4,1b8b823f,731f55c4,ae98380e,459d72ae) },{ Z8(9ae9d495,f96e9f6d,564e2260,8481c7ac,8806d5df,4a5cf091,1629b65e,4c9c0a05) Z8(e9f6a21a,9fbb6f3e,fba695be,dfa02307,05443e68,ad216579,2ad242ce,b7584b1f) Z8(247b56cf,15eda691,92647eef,6c0c8109,a83b791b,6e61c067,d31669f6,39862d51) Z8(c81dbe77,ca8c09d5,b685d840,eb238ccc,b85834f8,b8509493,0bfbc590,fdecafdd) Z8(aff2b441,743d2c1a,ce4e0c53,825eaab4,4a935e33,1ac16cca,82c0e49c,e6bae41a) Z8(ae00a625,61c11258,25ef48c2,4af2159d,902854bb,05dd8267,2a15421e,a8d3c3fb) Z8(9f60e612,0f26144b,722f0ad7,16e210eb,95577e60,c8a12dd2,e5fc4548,0812d7d9) Z8(2d104dbf,b24d6c2c,5b8496f6,5172b1f5,0cdc9a51,eb7d32cf,4413f2fc,579325f8) Z8(a79cf4b6,55b497a4,029be484,c78b0c4f,277b499e,c61a28ab,c7c05c1f,b06ffcb6) Z8(cbf64eef,4f4fa24a,e9e94d0c,9eed2c7e,bd8d5b21,c1594f22,c288316b,36a89942) Z8(867893f0,7000e7b6,6143c1ef,85b677c0,2aa8b45c,c08c4489,c85dabb9,3186234d) Z8(49fa6233,3480816c,40679b49,dafd513d,d77fe56f,bd5ea8fb,1327cb42,bae01451) Z8(767ce498,cf645102,ca71cbf0,0f2347b0,751ceac2,c5b92fdf,db7ee0c8,d605469d) Z8(c8e9bd28,126ab045,e84e95f3,725cf347,6623566d,9f673ead,1bc9473e,51255aa4) Z8(56548f5a,bf140405,fac38038,a70524cf,8eb79992,57858cfc,ec9786d3,fc108b85) Z8(e7ca878e,8d7338b0,0e1e896f,16ca0ea3,7ebe01ee,1f85c6f1,cac6b8b4,49361936) Z8(a3830fa5,53c8ac43,ff797e15,519f62aa,8d291024,3f7d530e,20cd5936,f5fc616e) Z8(3164478e,4cf26755,26f15213,77ad6fb2,206cf37b,b3246a14,8474c270,4ba38aeb) },{ Z8(0612cb86,ec7a530a,6118ee9e,9c5d9ae0,fdc42cbb,5a1e1e4d,708d4506,a550d48c) Z8(23ed8774,f87f5755,2df9defe,7a6b0c7e,36a1c6bd,9b0167e5,d109e9c8,ba3eefd8) Z8(0953bd9c,f30efb99,53d972f4,60f4c534,8a42c9d0,fcbc3424,06ccf9d2,558dbe51) Z8(a43307fe,7b0c2f06,861a4272,0a3b8cf0,cc5280b4,614370b2,53c9ac43,178f140a) Z8(9c682b3c,9c02ab7e,e44de1b0,357ac4e1,ff4106cd,3c17cf28,25fc64c3,574e1cb0) Z8(c2e6cb15,66aed69b,1839fec5,869112f6,e516b51b,87425856,e142c0e1,4e41fbe0) Z8(6df11bbc,a97fe7e5,281db524,f2da2ba5,7fecfb22,9e7616bb,03f03924,aebc4efa) Z8(6bcb18f1,b461dec4,c3ffb31b,33878157,072fc167,3c408965,f08b14d2,e0289859) Z8(cb9b8391,1d0985b1,4ac58797,82d72e76,0276e6e7,9668cced,1b25d2b1,b86d4230) Z8(5333a1ed,86581d1a,5f645447,fd87291e,d280e810,b68149ea,126139cb,a5b23b80) Z8(191d6455,a7cdf8de,bce50c92,5e93f836,1f127303,acca9acf,57aa7b81,db7a32df) Z8(44b8c1d6,b9cc73f0,5ca7f4ba,2f6cf9a7,825179bb,dbae9a06,a293cee5,10c0ab09) Z8(c16fe031,0f8c5b86,21403f6a,5011f988,18003e8d,62b90fee,9e463976,b496a0fa) Z8(9413c082,43f4dc18,9b61121b,f309b783,8d70f1e1,f744b9cf,918ee64c,dfd70ecf) Z8(cd2654d1,07605ca7,9a6f0420,6a34c984,838f961e,7b6d958f,140597e3,74b377b2) Z8(c8436028,69c032dc,6ba62085,1bb89433,f388281e,e487dc93,5f0fd381,f5d8d696) Z8(8f613c57,81891c55,7336c01f,14e48b95,72ff7a30,b092567e,bba85f7d,af120d6e) Z8(a973fc98,b5eeb55c,0b44393c,72cd24c0,f1cd1057,2decdecc,717b09f4,51862f08) },{ Z8(a5be4884,95bcdffd,4456d8c5,0ebfb467,d25cad0c,eabbc7c9,ec3e5d43,6c8864fa) Z8(ca770307,cb64a632,c97740a2,06a19950,3c33d5d0,ebf39caa,1a26b7d9,d1d66e8b) Z8(d53d53ac,574e3fca,3143be56,b22607a9,d42934c2,5b6aa6bc,f2d46b0c,cfbab6f7) Z8(10658277,16b404b2,d6a87b56,63b3cd53,a0b6c2ec,aba7fa74,ef2c0722,49507f17) Z8(4a8c760b,24789d42,51bb2318,6df722d4,06a277f7,7d0181e5,02cd1134,284ea16a) Z8(b6bcf9c5,7dfd814e,2731a635,fdf614a3,f5890b25,4f5a592c,efb1c44f,33c315b2) Z8(c5c189fd,93d4ee93,0c16265d,be90ccc9,e11c25b7,592270ca,d696a1b5,47c42b36) Z8(83ecd528,dd272f3a,9d914717,a582da3d,90cbd400,1d008fb1,e300d004,5cafee75) Z8(6aba3e20,bcf59fb7,d85d2413,a882113d,038d88c5,3aef9369,95305526,b732e853) Z8(9c154e54,42d120e0,a1f8c0ea,488166bd,323b28ac,235a6caa,b84d91ca,706ea175) Z8(7b00a944,2b20779f,6284b133,d81fe3c2,b6d6e272,06b35a3b,f352355d,12443541) Z8(1b795ac5,210049f9,7bef7e6c,d240a652,0d06d28b,8c9b5922,f2f06c1f,df225399) Z8(58fb50de,898dd82e,be726f5c,978dbd30,c463be4a,8f484142,994d1142,30928e93) Z8(9e365314,d7940428,06dea3a3,4fa5d862,cbc023da,878b590d,d29f97bc,56aab635) Z8(684b86a9,90f1e2ac,451363bb,f4bcee5a,b20901bc,41c87262,d10257f0,19f820cb) Z8(ead41bf4,b7ec04a1,748cdc54,a031f272,939a5f8d,c8625bcb,995a7125,76cc4fc9) Z8(c3639743,a0a230fb,ba2e3d16,e728a52c,f6d4b0e5,d1272b82,4ca76681,3f984c40) Z8(645143dc,4df9cbb7,29a4bb09,80b4a6b4,fe1159f3,36383dc7,60272942,5746f6fd) },{ Z8(148eedbd,d6cd0faf,adb4656a,f6736f6a,3d786d45,a2d092d9,6b9d9d3e,a1e54382) Z8(d42e0e5c,9631785f,0f9ade55,9fbb548f,a4edb9df,4abf39da,239d1c84,21be2772) Z8(095d8ac6,053fcbf5,c12fb3a0,451242ad,193861ed,594ca42c,0fc100e6,bae8ccbe) Z8(4f6f4ec6,d43181ef,891db369,db34811b,fc04d1c6,07e348c3,e2e470f5,b37fd8cc) Z8(2db3c607,df17255c,0257a453,85841a25,f26726a3,06620d61,12472a5c,79b2c903) Z8(a567e591,9f37481a,d7e31276,cb603fb9,56687e6a,e5156aa5,02a6d3c2,a3d22f29) Z8(1bc6bedf,02c7b74d,03b112d7,3aeb204d,2b7408af,6cd1b395,9b18a7ce,9f780e79) Z8(b578544d,600b44ee,7e106ac7,386c0fc7,fe0a230c,8e55e19b,4db33259,b33adaf0) Z8(ff79743b,926c31de,2965d39e,568a8345,9eef4c0e,1a7acf23,701405fb,d3a9912f) Z8(f42ba3ba,d1283956,01e7c515,f7495c2e,b441f146,74c696ea,80876122,9eb2b6a6) Z8(735797ae,cc261104,593c2d80,97f6b16c,ceff3e54,30e5359b,1d2cb12d,a966de2b) Z8(be20ec87,a47b1f62,4b4d7d0c,c5479af5,10def303,e9cc14db,5f752c22,a3647d7c) Z8(0fe37fa0,afbac125,d1a864be,16a84ec3,a4ea46b6,64b47b73,eefa8b3e,17573850) Z8(51083bf2,ce597016,0e401d73,9686e75a,c51bbf3a,6959c938,b98ab20e,3c8a2b37) Z8(1d51abb0,354994b1,c3aa011b,c3bdc1c3,c55f14ef,56f033d7,19f672e9,1220a8b5) Z8(63a1e7af,bfe6ef86,021f561e,7b577405,a6b90d5b,c209c254,ef653efa,9552cddf) Z8(b1351588,1f632a2f,97f25769,e0427ff7,9e14a268,c49b7c7b,4ac65d2a,505d2dc1) Z8(23446f02,bc92784d,a59757bb,dde10dce,4fbde5aa,89314feb,ef401a73,5ce75fda) },{ Z8(82bfc4cd,da827cf4,2bc7431a,388c9aec,9b4592a9,aae22a29,12a167ac,33a320f6) Z8(ab5a21b4,c80b11f9,8c28d4d2,da4840c9,e228818d,4a330ece,555329c9,b97bec3b) Z8(cea22e35,e07e6485,d1ebeb1d,d557826f,f0e0756e,c43eb060,a6e43e14,6fe7fcf7) Z8(b6c13dd7,23bc7ff2,d2e907e3,7c79fd89,a581d91b,44550be9,e41698b8,13996c2d) Z8(54862521,0960d624,455cb796,a94103ed,b260c21f,33e29ce6,7db2571b,37457fde) Z8(ace36dc9,496d9dea,4757bdeb,646f727e,cca2673f,33e3484c,d459bce5,25b3d375) Z8(224c4315,1f1f0a63,82690701,c36d8543,12fdc746,d0b4e277,cf651227,ccd734b4) Z8(4d991f4b,1b82456a,79abd6b4,b8f70481,04c2ec5e,14426231,ffabd88d,fe32a07a) Z8(615c61bc,aa44bbc8,66e6de4b,9ab5a04f,01c53d5a,7e65f583,ffaabbd3,4b921152) Z8(e1fb36ad,b76429bc,73396fb9,49964a84,90634cf8,3cfa893d,63cfbf93,a9a9e551) Z8(22976cf1,f149270f,4e174d5c,db99363c,1bc46f67,e24a10e8,fda6d2f9,9b7103e2) Z8(e1036e90,e9477824,10230f1e,d3845aed,450c052a,9f430e67,98f70e42,5572b165) Z8(f730da65,3369e9e1,a0a55e7c,ea4cdb3f,cb17e86b,0d5ff8dc,2cfeb350,9f1c3739) Z8(899253a6,40ad49b4,1a15170b,882e9896,7d0707b3,b8ac12c5,f4bbd8fe,fef59505) Z8(39be50ab,517142b5,c48fd2df,77fc94ee,d4d65095,5a7d27e6,a9f65bf8,d5a40aee) Z8(122a2c73,a121e9bb,285e0cb4,189c6b4b,67672a39,33da365a,66257014,710925df) Z8(d94be1bd,507eaadd,73edae34,778b0d38,f0427892,29843ae0,20267cbf,2fbbd968) Z8(c6f53831,501f739c,0515a31f,c63281b4,f055b3ff,9c620440,05096ad6,6268ce1b) },{ Z8(d518ce82,81967a53,c2e585a9,11fc9c13,90d51531,33777c8f,6edd6cb5,dc1f5abb) Z8(7f1b2b76,24f7fa19,c6da8632,19312076,1987a8d8,82221bdd,504db726,7de3ff1f) Z8(874c7595,3d97736f,421d107a,c9d06f05,c972cf35,bb3320e9,c0bd6044,3fc6443c) Z8(b3e3b0fe,33b7213b,b93e8867,80f7c1d5,77dae34b,4c624cff,586bb44a,bba9977b) Z8(fb0b45cf,8d2db23c,67c7924f,a610c6ac,63af3267,f13815b3,88c8286c,ffde4210) Z8(ff729161,cdb51bee,fc494b74,a9ab7ff9,ec69c97f,9093fd4c,720d6dd0,6d755fa3) Z8(020b6ebb,e2538ebe,fbde42ca,b570c01b,f81089ee,7660054e,a9143d0b,0d64801b) Z8(52fc9a04,48191187,ccfa8050,b76a6495,521499df,b6deea2d,86f15872,56fae945) Z8(9f0221ac,ed551b42,079995e7,7655d68e,623dda9c,0b90e80c,2f06a19b,79105b41) Z8(54835dd1,d8306462,be049c01,bc9d5dfb,0626bca2,89d92a66,55c334f3,f3301a56) Z8(9ad50e9a,bad11925,b75a4abb,2056e09b,b46fef38,18a778d2,c0439f28,c4e04ed3) Z8(fd52f66f,d67c644e,01d97dda,26bb2f49,034e4eb4,2af51a01,7b24a1a2,3e63e790) Z8(7cbb3aed,7dea9751,b011b985,fc602887,7e1f05d4,4f3f354a,47918598,7ebd6e9d) Z8(c7729534,2febf7fb,cc948b5d,bb8290bf,315c88ff,cc34a61b,8591e5cd,f6afcfa9) Z8(2c999bdc,ef96d5c3,d4efb504,8f0c598b,4073acd0,ef7d1991,dc8b1c82,5dc9b912) Z8(3de66d19,0411cd96,074ba0ac,65209360,cb153ccc,2d139480,fc29e7e0,4839cacb) Z8(febb0e3f,a7e09dc7,5d6f9b5d,752d66d1,b8a073c4,fadca437,9edaebb7,c2df0cb1) Z8(c59e3b60,b38ad78e,4547d7c2,7d20ffb3,01488606,da35d9bd,fe612fca,67cc8fb2) },{ Z8(4ecc6db1,bd5ec72d,fd338a63,ebd5d11b,a679f797,96acf640,3b6df279,18b2e5e4) Z8(9af1ede2,8f2cc3f5,5afe67cc,6e9e26be,1cb5e930,5c04ef1a,9df79d92,30a2ea7e) Z8(086e3dd3,fd9bf950,ea182043,34b7c3fc,e66cd935,09cc9dff,0be9f9da,ea748ad9) Z8(97515e90,b26809b6,d3002447,ab296d10,c54dbbcd,64679114,a9e626ba,72810228) Z8(4ca4f7a1,a9859848,4cf7ca0a,e391c689,c285330a,8f983aea,d0a79444,10238fac) Z8(25312ea6,eabf2a79,5af1ab95,480b7cb6,4c244793,ef80e9b7,e93bc9e6,15d67eac) Z8(2c2a19ae,85ee442c,803a64c4,0392446e,245f4e97,d77b00c1,b6d287c7,2f8866be) Z8(da33dbe6,2a644281,650d862e,e2c83fb4,85d5bbb5,d873ec20,05da4b15,f4b6d7ee) Z8(fbc9dba1,131badbc,cb2c7c6b,40b914c2,f8cf77f1,5df5e00f,72aa8928,15fe600b) Z8(362daf01,812946e5,a086f2b3,2eb11cb2,450d6905,35849d88,ed108287,833bd05e) Z8(f04836db,9f7be5e6,d7947b0a,79a90f0a,884bbdd2,74854d2a,953da278,83925801) Z8(21322ccd,6be2f8d2,d539eef6,03c34130,fb912094,424f5c46,31e1f410,56e1036a) Z8(4717ddec,2f5c415f,353a10ee,af6ee96e,67d15d26,416a4652,8bd9797c,d3675ac0) Z8(c3d61034,58de52b6,274fc551,73b2bca1,05a12faa,a1cb3b59,e195eeb8,8fe6972b) Z8(1c108f1e,bb08f9b9,a30dc088,be3325b8,619e86c5,bf8c4fc3,10cb7431,0e9c77f7) Z8(d881f3fd,8be1ce48,896ef16a,d261ae0d,169001c5,7d4bcaf6,6e210d58,dc89809c) Z8(4064e2d7,77750639,f8dfce5a,0e4e7e63,725e6611,775c37c2,e8c5ff87,f528ac22) Z8(2b96a198,aa8920b1,603cf111,53ab4d08,3878ef20,fbb6aba6,323d8a32,6d13ddef) },{ Z8(e885d03e,38144a48,b95ea356,7ae35eab,aeee916c,13efd21c,eef5256d,e5e3e847) Z8(e676e26b,cb34ac29,6a35723d,34499dc2,26655035,50c2301b,67aa0d35,b7d3b5f9) Z8(1efe2cb4,e6fc1b37,ab37a95f,1e005324,9e5c3eec,e8d9161c,1b23bc40,3df342e0) Z8(aa7acc54,1d6a7e4c,97190090,9c16d47e,597d332f,54206403,f778cb65,b95cc3b9) Z8(ea704649,a2aabf8b,a8ed5a6c,072dfdd2,c6afd217,5ffec54e,9b1669c3,7b54c353) Z8(8fec76d7,73eadf92,0bac9149,339c4324,c33d3147,b1f0295f,94a2cb66,6017e41d) Z8(93c78d25,9f1d6b61,fe9d4793,6b855f54,5c0dc9a7,e4471e04,a6ad5cae,c7b6ac40) Z8(a399d624,b160464d,9a60cf00,f19f29ff,f212e80c,1ba9bc1e,807585dc,20d4325e) Z8(83dd6894,11ab8aa3,89f1ff32,928b6b33,c338450c,8a80ae42,547fdcfd,1364ae4b) Z8(477c369a,528a7dde,6b0c4236,496ec319,81a046aa,0a8172e6,80595a41,ae4934f9) Z8(2b769b33,299df4d9,1dfb9dae,3e032bd0,74aee167,072b4ae3,4958e555,3bc1d228) Z8(7010f624,009f175e,aa75fab3,182ffb83,c8fd874b,429b4954,64179825,0f823f58) Z8(62b5c8c3,b3a58f2e,e3c49b3b,d733750d,f93effa8,741b7bc0,cb672def,94bb719d) Z8(46a3b882,e9d4701e,d3a90dfd,8deea8a0,f1d8c6fb,a05e7b9f,85af8f62,e27fc1e9) Z8(3cb0496a,17e39dd6,94a9baa9,7807b993,d2a3b4c8,b15bcbfa,6aa2cf6a,a2666caf) Z8(cabe7219,aa7014c3,2e57f66f,1fb6ceec,5dd83ce7,120e19b6,86a31455,49df088f) Z8(aeae65d4,f0706129,810e4f3e,d3f90b7f,a11bc8db,62066c1d,f9ba7754,432551fa) Z8(c97f8e8d,e1e267ea,235b8362,8ecbd4e8,fee6892b,97607bcb,6a6886b0,723fdf1e) },{ Z8(a313e03a,7fe87c4b,bb1f8a36,71f3d7bb,bf12d5bc,3faf5bb0,141058a8,3d0a5942) Z8(518f2c01,12f60820,a95ee857,e7c5fddc,f55d8460,7e4c218c,5e62a8eb,2aadfbfe) Z8(9ab9eb79,191b19c2,7426c19c,9f0ce652,6f90267c,92085120,bf82081b,b53be888) Z8(64bfc2c5,67664817,14a03d05,9296860a,6fec3396,ae153f23,97dc02d4,5106d162) Z8(5ff1961b,c03ffbab,9ad9f56b,b6c91591,0abe0158,d60d21c8,152de5de,83dfac63) Z8(920ed65d,b5f7ad1a,278e1f12,893292af,b47e4023,145eae39,1b439331,f857dbba) Z8(bb55e91a,20d1d5d3,f2108d41,a16d24e7,1aa82d34,341e5733,06eeeaf8,5f156d6f) Z8(cb67501d,6f5ee32b,5227b8a3,ecac8858,2343a815,85447114,381841c7,8c5a1bd9) Z8(11b5a2ac,c36fb44b,26739b9f,a069261e,ccacc6bd,5414db3f,a659c718,38db7d63) Z8(8b7da137,2624239b,a174e174,430361a1,383bd252,5d738149,5067ba04,b22dbace) Z8(f70a9561,897b04ad,8d4d7225,4f15241a,097b4d15,eb26636c,a4c21401,2cad8204) Z8(e8eabe38,8b0b198f,75284021,17f4f804,91b08887,ede14962,7768726d,310af974) Z8(eaeeccf6,acff492b,c8b233b7,8330ff7a,1dd6e363,ece3b047,0a618bf4,08209fc9) Z8(511efec1,f13a8271,d3799bb6,7dfd988e,f1347b45,902bb6c7,18f4d9fe,5c4631b6) Z8(d27363b5,e7f6a4e8,8d47586a,9ef6b707,da6574cc,2bd936bd,7497fff1,ed5d9966) Z8(2cd04071,d67af953,7b1dbe1e,3206193d,eeda1b25,0e08ecc4,5b609a0d,b137c429) Z8(76a1ca55,43a3f551,4518e0fc,0f1e32ef,3e5b508f,8b63c711,7d60fbbe,2451e71d) Z8(5c94d3aa,250ff699,bafcfd59,50684ce6,76e1fe9f,989a9274,071282fb,7751a813) },{ Z8(17644fc5,9b93a1b0,f8874d38,5ca3c282,ec1e11bc,19b6f972,ecda9d4a,f09f0ec8) Z8(6ac4ffd1,61edc8bf,183a6dc8,9ab68898,0fa23364,2f1aee3c,01c23d8e,430d7880) Z8(047b4187,0bf19f7a,497125a4,a10e024e,a983dd86,5fd08295,4edb15ed,5cbb0fad) Z8(1482c8d5,f4bd6c61,70d8c377,939afce5,9474807a,d8fa980f,90ef38ee,020d1921) Z8(a7885abc,668060d7,b48fa607,f6793aad,43e69e9d,52e945b1,3f0038fe,62523739) Z8(44200c9c,224cbe38,dd3ff327,39c5894d,bf3439a9,8fe7d1f2,d0655c4a,74ac1c30) Z8(65d7f10d,22a22fb3,3f8c5c0d,e61f7837,b55b3b61,8c48f863,b8eef7a0,71dd8a22) Z8(fe7ed4a2,1be90e08,9f347f11,bdf6b3f4,77d115ad,0c016a2a,8cc01870,e4f97e99) Z8(7e4bcd6e,46b5e8b5,abe2b027,2d08b6d8,c6e583e7,6bb28605,183b14fd,0bf3aee5) Z8(012f1254,db4558f1,151482d5,fd4d6047,30d2ec16,cc4a692f,aae2c7c5,ea8cdcd8) Z8(7972d6ff,b39b623f,14143514,084e6478,7b9c7f0e,44ea33c8,219be255,904d6ba8) Z8(c13e08f2,ab52b0d2,9e111c37,8c4a6702,12e687ff,ae3e2567,bcdc1f05,28a0aa69) Z8(1686eb67,41a7f20b,764eb3f4,33999e1f,224ff157,2208b6cc,bdedb247,e68075d6) Z8(7937f887,10e5f082,ee5b5dc0,85b18370,abf94f24,4768a400,3c7d2844,daab5e05) Z8(ef780e67,2a1a6856,3d02431d,37e5436b,37b62b62,2f6f674a,a513d8ef,72b30c7c) Z8(f6d4df92,578d4775,13b3132f,808c448a,5fba238f,06c62f87,00f56015,2efdbc27) Z8(5906267b,9727ebe7,3bffd807,bda7391f,0a0ba86f,9cd3cbbb,669c3df9,c07f81b3) Z8(9dfd6268,ea5ce16b,9ec747b1,64911742,73d75cf5,720ec44c,bc1bb2cd,7c4a3d7e) },{ Z8(2a845ddc,53856b5c,66f9a838,3972d501,1f858389,f9eae419,39f7cf10,95d52505) Z8(2877bf38,a3a36d4b,0a307098,2e34610d,00baccbf,13e3c694,03fe8f6e,5692b8f7) Z8(08a3267f,20e96ae5,be43777f,c9274ecd,69419601,b4305fc4,c075202e,1130b6fa) Z8(b9f90ca9,6dfd8367,00753cdc,6d46aef6,939e29be,ed483c7d,141e7310,492e58d9) Z8(995e270c,ca0e2e80,3ae3557e,1eaf401a,eab4a5bb,5caff1b9,589053ee,7b91846f) Z8(ded9d692,eb677521,73124140,5c6938da,08595186,552860e0,210f4873,bed733a2) Z8(cedfd939,53296c2e,8d106222,f7736696,a47ec4ab,e7ee9e1d,84966b97,479b4934) Z8(b49883a7,9772993d,e60334ba,3676c920,5384b3b3,c5fab07a,96859997,4e892a11) Z8(77eb2f2c,4adf3a18,5bc37e9e,ac8371b2,909a4a20,7a766c45,7fd42d1f,ab201fb4) Z8(831d2e7b,f5f9d8c7,7321ac0c,e2059eff,3f1184e1,c68f89cb,5e417cda,99e2cf80) Z8(c6177eba,3c338e70,f764708e,97143743,71563b19,3a054dfc,3aa87bf8,1361a0dd) Z8(71d3e5dd,e52fd660,a6d2d83c,93111d1d,a468e40a,0f0c567b,54d8246d,a9d31b31) Z8(befd8d7f,07b01df4,f0602dc5,8e5a3d59,dafd81e9,9c7f447e,80a57de5,a521b433) Z8(7344fd31,7ebcca07,690224f0,cd64f760,6b6541a3,d05f7fb9,9a710c66,8f38bf09) Z8(832c5329,a35b87ed,c70e161d,54dca374,5c191bef,98136998,228b9a7c,33b034fa) Z8(527c1c88,421c64ba,0e899c5e,dba87315,d12e60aa,fc5ba321,3aa6edbd,92d8387e) Z8(67a46987,94062760,e89d878e,3a732eb6,0c759abe,e2af09cf,3605037f,0ba66448) Z8(d7258b51,a25591cf,34ebb89e,4b8b8c4c,3ffe346e,e34aebf7,2e87f634,812a952d) },{ Z8(06942ee7,fb49352d,2a8d0cc3,e34aa125,0bba7986,943b5b4b,63a13742,55b5cb92) Z8(5656bd48,0ac24a37,5b370db6,85adeae6,c288d68d,c5b4a079,b69f6865,f3d092ad) Z8(cd0ab2e7,a167a59e,1dc4fa20,6cf64d1c,4e6de482,a2313c98,a5ffed30,f08759c4) Z8(6f0bcd4b,3bb5e6c7,445a8375,16a024ea,6bd30ca0,4dfa1572,4bdb55ba,284bb4b6) Z8(505f98b6,6050efb9,650c0831,9070ea97,06f9c153,be3a34f1,be0a04bf,6a8281d0) Z8(6e394fbb,91bd2d74,1da4a905,0dd3730b,00543c02,86f641ca,976dcc6c,f12c8347) Z8(fde93225,a699c7a0,88a5c55e,be3edd3a,ab25cad2,5d5ee717,2c543069,f14d5532) Z8(051c8419,cc901d9b,9d5b5fe7,e41da9d3,69d6f9d9,c60a9bcf,29b76588,a340be8c) Z8(47cdab82,a174f5a8,1afdba62,d5923232,042f40db,81402454,19f70842,2690ec6f) Z8(ccda90d9,f1bc4653,aa773bd0,e067632c,f791c1f9,27f2dd9c,4de4199d,8c7a214f) Z8(801a6a45,d1229658,0ae12d17,59752e76,b0ef60f7,9bc52d9c,8ee961da,b9439b01) Z8(e0c3d622,772d2298,a88dfeed,6ce3d7d9,abd65d9a,1642ce78,3c0941af,95c51b7e) Z8(a45ba76a,2da5a7e8,7ca1db44,28542b31,c5e3444b,2479b8ac,fb2affe3,64f24461) Z8(42570c07,1295c415,699ea802,443114d1,0430495c,0390c159,9559b5d9,dc1aa4ea) Z8(768cfdd0,f496e984,4fae3b6b,47c56b1c,892ad429,d897a5f6,f83c0cbd,a68ea386) Z8(435b5000,e6c5c7d6,64ac81c8,75771e5c,2fc37de6,6c6ee371,d232cedb,9a16964d) Z8(eac77298,d04a9e2e,5716b0d4,7259863e,dee7403c,9b0099ab,6ea5168f,60e4aff4) Z8(c52fb7f6,90936f50,5d3ed11a,366fbbf3,ffe69b64,c4bdd99e,295415b4,85f39721) },{ Z8(7a55b3a6,0884782e,3dc8404a,d9cf4a36,553b7571,e416075c,6807d7bc,9842c8b0) Z8(1728f8aa,de19ad6a,6314981d,148fdb5f,c9d46ed8,43627ff2,84def063,1628cad5) Z8(98d2d3f7,e68d0934,a97547a4,6ff4eec6,d970e946,7128bf32,145ed7f3,74875fc1) Z8(f9706e28,89c16e2c,d1a6c2ba,d846f72f,79111a4b,0b53a2b4,4f8611f6,f43d75e7) Z8(91a04e60,ed580b44,38c48ee6,b911c3cb,6298efd8,ec1731d0,f38799a4,14f87e59) Z8(0add0681,20a44665,1e10476a,205f3488,c6b54dbf,e03a6d06,ab942694,fe4dedef) Z8(37d4e24e,790e9d96,a76c58ee,a89cdb4f,adf3dff6,1099a5bd,5746e77c,1297a51a) Z8(3d980404,0d1201eb,91301a9c,ac571657,8039356d,4a156774,30c5d7c0,f092b189) Z8(8d8a37db,25df4b03,0fbe8730,cc1ce410,6413096d,5ba9240e,c565c130,c21f9955) Z8(76f1bd3a,af9d5c09,14ea7562,223e8aab,13510b66,3bc2035e,d28de6ec,7cd6d5fc) Z8(aed8b1ef,bc9cf34a,cbe2db69,fd958e1e,d969e3b6,30604040,7c56ee2c,f95b1bf3) Z8(7cc13ce8,3a1bff9f,31e2f214,bb84f769,e6d03d60,7cfc3eb0,d49f9af8,9881cab5) Z8(f2cac492,e95f231d,13228d07,bbabb40f,949fbe61,1cc6cdce,83f9d06e,fef459c9) Z8(b7659cc3,38df1427,0535991a,ba010bd4,865d555f,4773f79f,5466adfe,5116efc4) Z8(eb7e7987,93522b92,64c3e174,a638a64e,ece17082,d41b7b8c,c956ff98,45e6ae09) Z8(ada29935,3ef83d3e,82d21bbd,ab93fba9,22744691,6d8ee96f,22615dac,1ac85ade) Z8(66b86f42,f9c14cea,33bde7be,fee11155,438d5e9d,e1958c8d,38859b27,50a4b66c) Z8(0e33c3df,26dfe952,1cf1faee,3a330f34,f14054ed,799d1cb2,a6af4d4c,8aa61e97) },{ Z8(e3c15528,236c807d,0dab874e,1f408219,269f5ed2,4e6c0852,123280ab,2bad9542) Z8(60f6597f,79a93405,2a2b7656,9a41ce9e,d3620695,0e5b511b,6c20ad50,db3f2a97) Z8(e8a475d5,0a7d56ff,49552bc9,129961f8,7a2bb12a,cc9a6212,541116bb,dc9ffee5) Z8(21f8521f,08ebc351,dd309d04,0bb846d3,6085ac88,7dca3150,33a6f6ef,3e9909f2) Z8(f6b3982d,f85edfa2,8fa13c63,22a997fb,f34c8477,d2832389,d67b0465,529dea06) Z8(daa7c988,6110a868,99147277,1b9d44cc,0886b408,0d234fea,d3fb2376,36850d27) Z8(9a3199dd,43279462,f597b3e3,32d2d3c3,30b590c8,6e9e14cb,c2dd8740,333448ef) Z8(670692ec,9b0facbe,1750d39b,9274e1d1,891e47bd,9b83076c,387b7772,2b336a99) Z8(48814a92,1cd304ee,637dc1e0,6714331d,8dace375,7fb439f0,f2e3b2db,2d4f42af) Z8(336e9bce,0bff16dc,980ec574,c210e9bc,aff7ee79,558e9f8e,503b03e2,6828ff09) Z8(a0567c33,ff664d7f,f9611712,c09c4133,fa561541,115b4502,a38f8f0b,0c77d4bd) Z8(1c339cfd,bc158193,191c34cc,05887b99,acd2d78b,d675ede8,b3a34ba3,be23cf4e) Z8(8c76f3a4,3dbb2fb5,e466b11d,3e1d9be9,8e25952d,055716c2,33b18531,7556b11b) Z8(6beb61e5,6b063b4a,91b75fb3,b104ad07,cac340a6,816c3628,ee78f524,4bedb09e) Z8(15a83272,ca9b48bf,e9175215,11c9639f,4ce75c87,5ab5fb40,57185e7e,40b57fd4) Z8(a76cf5a4,d8a8b79a,9d52a8d2,462624e8,a4061d22,cc0bd283,4835fb0e,8d902559) Z8(28e74d7e,4f6620b1,dd0bf7cf,fdbe964c,deac4090,e678c55e,ab58d60f,6e709121) Z8(5ba0cde2,9a4b1c06,696ad39f,ca4f4817,1e35f2e7,62cd2f9f,820681ef,8f42faf3) },{ Z8(5f5bc3ab,4e8c870a,03c9252e,97cf41f3,f1ab0711,bf955cee,3f9a547f,15b92c62) Z8(cf35a701,34d7ad12,314ef0de,6276622f,a4b68b54,b626efe4,87b930fd,e36cee9d) Z8(da28d9f2,ea686a5f,322e455f,cd9c08d6,112b023c,a142b8c3,a0475d8c,349fdfeb) Z8(178411ce,34e4465b,2daeb300,e9d98495,4dcfebbb,9bd16f0d,382f974c,e9183222) Z8(bbe21841,7dd9515c,997c29c9,7f081364,855555bd,67b7bc20,f331c08c,eb6e011d) Z8(b7d79e52,bdc5f8ec,b9a59f49,ba7bb456,8b7d898b,5c158380,e6fb1b3e,d12c35b9) Z8(df9e19d4,74a0e04f,e163db89,dc796300,c42b56aa,70558f9a,abdd0bc1,9edd5dfc) Z8(6557dfe5,42ded9c9,cef7cccc,e6a0dd64,9bac9025,05999592,fb467953,19054d40) Z8(cea2374e,c4b7ce07,000e72a3,d69518ca,71ed0936,06507d7e,8ea88946,d4196235) Z8(5178f8ce,8973034a,782e1b46,93e12592,a6cbdc4f,698e0ab9,8b785fdc,891ee384) Z8(0364d351,2b452322,c5c0442c,196063cc,c235e383,9f4a7bb5,3f3deda4,635f32ff) Z8(d53596b6,51401c9a,01e2c856,47a753c1,7201187f,faff35d0,2c671335,326beee8) Z8(496cc78a,4711ccb8,a182684e,1cebc4be,f056ebf5,4e79e17b,b84729e5,6fcd8e03) Z8(a5d19891,e9037e01,b6dc8143,ac14b49e,f889283e,edec3ebc,dcba1e17,dee20df0) Z8(9c6524ee,d4d63910,05070620,63371cde,94f84d7b,7db94b30,a98a103a,7363c8e9) Z8(b8875a80,1bee1cf0,b1566a59,ea62da33,9227176b,6018fd9e,2176bc65,9c63c1e0) Z8(fa1895f4,5558e6af,15fa0ed3,c0dc1d6b,6de19a53,92b0f0fd,a10dfdb1,b09a0aae) Z8(9ec6647e,7437d665,433bbdf4,527d7309,438ffc03,c1f9edcb,4d88d75b,93caf094) },{ Z8(21920b48,5cdae112,c46e5752,6013dbfe,dad4858d,6d4f6f46,abe8e5bd,c4fea923) Z8(dee2af0c,0f1cdaf6,18a5e2a5,0a1f7f4f,f1623d78,8b862fa1,fc40f5a3,3a1d7e62) Z8(ab50da80,37a6f45e,473247e5,b4153104,8a52103d,b5fc3b45,fe95a648,fce2d7a4) Z8(98f2ae0f,607e6dbf,6a29bbc9,a3e162bd,55ebee84,64c68a04,73b0acbd,b213c2a5) Z8(b9194b6f,4097a3a8,12b0e99b,c3518b45,097b323f,59994cf2,20dda2ca,996d1868) Z8(87046418,d084970f,4867acbf,904dfd1e,fb1a3df6,5b5ac31d,c15ddb86,de3e2c18) Z8(ca43cfc3,045f1594,39097da5,bb84db40,7e6cf65f,731e3cb9,c03ed786,fec4305e) Z8(9f23712e,4fd7c8ce,7d082452,91ce9e6e,499eb971,bd9ddb08,9317a137,984c129d) Z8(263ffe79,125b748d,7453b41c,1c4800ed,2500a5aa,b2198dc1,6fdda1f1,ad76bf1f) Z8(7d449ab2,d549c06e,237e4f68,7298234b,92cec2b3,486076aa,e4aad56b,a6fb6e61) Z8(9f311a22,784362ed,693d4874,e683d796,5e2e88ac,ae45997a,dedf9f0b,2e79c66e) Z8(3edbf840,284dac4d,9345e570,6a45894c,4c9e1f79,323e91ad,6748b193,89579216) Z8(60745800,8053d2c3,3036a986,240cb46a,2c2650a9,a5425761,f8630914,8ae84783) Z8(11a72c24,6de33ead,695c5c8e,fe68450a,8e7d75b4,1de3b5b5,b8497d21,6a438720) Z8(548f8846,99aaeec1,c7564f48,91bed8e6,1c925d42,7dbc019e,31248509,852ee7a9) Z8(5bd23e2b,325a1728,a32d0db2,aebd159c,320f43fe,87c74d89,19bef850,7223dd08) Z8(1304d6c1,db24c695,ceab26fa,4556832d,52740265,879fae51,e748ff9a,d3bc93b7) Z8(636df445,4042089c,8119ba91,0b701333,36cdee18,ac850fab,7885f0fd,983eb99a) },{ Z8(21e887d8,2eceebdd,9f23dc7b,366ce595,5675a166,c3a5cb83,41452c76,420bacb6) Z8(251fb00e,e5dd4cb2,d97461ca,332ee1a3,9876d98e,4ee0cc26,68407d0a,8fd9e0db) Z8(23a3765c,9ff90564,eb797c6f,e26ad3e5,8629332f,2ce2a36c,84f819aa,16c6bb86) Z8(ae3e0558,ce00d1ad,a15861ef,4d0d83f3,ab96c4c0,2b3124a1,61f58587,3c6ec6d3) Z8(48505f38,ddbfe9e2,d8a9c922,5cc1ef06,75a663a3,238dfb9f,17318be4,57d44fe7) Z8(98dec9c7,a6629139,c34019fa,3d76e682,1d1ed74c,0bcb3392,2863b978,031b3b13) Z8(7d386dcf,faa94346,15a52e6f,89e817d9,132d945f,cac99645,08cd2cbd,25ad3d1d) Z8(cf590976,7107bd77,2bbf67c6,1cd4fe04,e0d17b91,003521b7,aaa52884,013f8140) Z8(c068dac8,c835f76f,f7227e98,e3b4fb1a,b802e45f,1b90ac77,538d181c,18b1ae23) Z8(1444eb25,46254ffc,622330f4,07517145,7b05e841,d18acdc2,9063fe62,84eb1e89) Z8(71d7f70e,e515744c,b456440a,41e0182a,ca719a6e,67b7c57a,be60b1a7,6d465ecb) Z8(e20b25a0,bd61698b,9dff96db,baf7f6fc,fd776a07,668004d9,93eac8d5,a4196990) Z8(5a498920,186a2fcc,a711662d,8df1b6c7,028fb6c5,b8f3d28b,79992842,aceafe50) Z8(b87edb43,5c42a910,c4da0173,29cfbe83,bc7d2a91,789aa82e,802a5319,7f49b521) Z8(a7d79f40,d8645c21,8be97053,cfaeac71,a43b2af7,b11bed46,c685ef55,452ad576) Z8(d534ac6a,01d333f2,f8f275d8,09df0a3d,8f098f86,32ff3f4a,fc56c332,05ee137d) Z8(48fe0250,829512bd,61955f50,2df8d830,3dc6a386,a87f09fa,b57fe9db,bc176f0a) Z8(2170e2c2,41e7a845,00413260,1717c9e7,f8c38f62,221301b6,b150cd4e,9c9f069a) },{ Z8(495bb6a1,9da09f78,9f94d754,4f6e4b69,e84c5de7,bd6f659d,6657ff6b,cf114edf) Z8(72569cac,0a92502e,fbf53f51,b355ef57,acba50f2,2a8333ea,0422bdc1,d9cdda1c) Z8(16cb8bef,3115810b,97b8e52a,d8d09897,18a0eeab,2f9fabf8,ce4f3e65,5ebfe5ac) Z8(09211728,426c6062,04cb08af,4f032c15,24997ce3,f6727f01,542819fc,9857f958) Z8(f04368f4,de831202,bc3e3f85,29a7c595,c7071b73,a137785a,56535d4e,bd88a3ba) Z8(4768cccd,87aa8bb8,021f9419,4379a18c,ce086223,e98c11fc,3c5ed383,1d8151b2) Z8(cbef354e,b1e2446e,7b2ce694,6b336fc6,26176ec2,e8839451,fc6aeb62,713fd63b) Z8(24c98516,a0c934ae,9a2ae7d0,3039f995,cb1e0de6,c4b3c83c,c72c1b60,67650274) Z8(60f0d5f6,f62ae094,cc929580,bf9b8c27,c3d9fd22,d0d13f2d,d9469019,82c2b266) Z8(7841791e,0175a351,738abd1d,e154bf88,46f6dff7,0f19e3d9,15efe214,ca54b4d3) Z8(30905c34,cfa01392,c6581992,bf587683,6ec75feb,9c3d1e44,e4f011d2,e2c137e7) Z8(355b7181,56cbeffe,d7147b34,b2d32d0a,67cd1259,cc42beab,ad306db4,c625073c) Z8(ae161f4e,57bd5ee8,a1f40723,67f9e30e,fabe85a9,094cf32a,2d451c90,c91b276c) Z8(eac47175,24d6300a,3669125c,8279e510,2a48ec7d,1c63e3eb,4869ad7f,67efb09e) Z8(4af1c092,7b88a4ae,9f449259,cb103655,a9c58734,482aff8e,91dc8438,2efcef6a) Z8(2345a626,d949d7f8,1e779be3,f4fbfad6,fa015b3f,b61aa15b,bf7b720a,6d294f13) Z8(d6124129,2018ce5c,1df6c2fd,5f29ec91,892e5832,2bdfda46,1bb82762,6471b5af) Z8(2a5e02a7,247c0b84,56f59974,4486ea27,00bbca9c,25e617a3,33957323,a0ec7f42) },{ Z8(9ab1da34,c87e3e81,ebe448ed,96e02eba,8c739c68,1eb47c1d,9330fd62,af9a6b1d) Z8(ace02290,f63dfa4a,68333517,2199e668,56d26eeb,9e5f6730,8903b3e1,4e9b2092) Z8(1d0ccf70,034d0486,43041d1b,76cfd831,be20c427,da75f047,d7d2b62c,d712cc72) Z8(f0f348ba,f9676f0e,3a2097fe,a9b7ea9c,5476609f,4fb6ef9a,2e61b2bc,5af9e430) Z8(4247b0b8,146ab745,41fe31ca,da0458b0,15bde2dc,6c5a0809,44780f24,a1652b5a) Z8(d3c69e56,34db62ef,8242dc88,035fb169,c60915a2,ac79484e,d5201f02,55f4022d) Z8(cb008ed8,4c35db85,dfc81573,dce69d09,6caa0c67,a652939b,46d5a928,3068a21e) Z8(2ea4385b,f7966d4a,c780c795,73e00924,e270c79f,ec40202e,93033f0c,0a15da75) Z8(e03f42cf,64d8c55b,6671e69e,1e0685e1,9fe23a89,554cf137,5e4bdfe7,b91998b1) Z8(d05e6f51,c242e4c7,3a6779f8,ca3acb5e,e0b0db2d,b7f9d519,6a109ebe,3872c2e0) Z8(ef10e1d9,373e4acd,cb889d1b,8d33cab0,eea29b4a,1624c779,e365d3e5,2e0ece13) Z8(71c93def,84a3557a,4e83bc17,d2e949fb,b31bb612,199b9b6b,ea6e5b34,55362a56) Z8(399dcf3d,b29c2756,abdaed78,fddf3f7f,11b5c09b,46ec37ae,fa2454ff,148c7b4f) Z8(7173d8ac,5927f1db,fff4a82c,fe69079b,c9846d37,93897d1f,018031c3,42c50043) Z8(4ae4ca08,6dba9a87,2f448d13,47c646fb,5f94fef6,56ed27e8,6bb532fe,2de04fdb) Z8(6361cdc0,0c647874,98d9763a,77281ec0,4a98f47d,e3d6b5db,aa76f580,1899e517) Z8(369cb411,5c9fdf23,a883d1a7,d83cab84,445c1b43,322aec8e,db555408,23bd3235) Z8(84ebc206,5bf1a66c,af47e744,6f7191d8,61b6316e,3dfa3d37,81f5d811,a527c2ed) },{ Z8(80303242,3ce7c135,9ee714a7,6c68f3b1,6cae6ac4,e28f794e,54100294,87f25feb) Z8(d7d6841b,17276cfa,333f3feb,57bbebc3,f3fd7741,d1f98ebd,1067c72d,1b9f8044) Z8(ef23a6ae,f23ffe3f,e7cf0fa3,d0f0088c,3b922041,a5605e73,2e61d366,9eb6cb6a) Z8(3f60c26d,ef735a80,03d7e83f,9cb45651,430b6d34,19387591,a7b18346,a97a9fa0) Z8(69aa0160,1e2852d6,80cc1187,45186f3a,1c5821b7,833f817b,d4bb78e9,9c1005ac) Z8(2cc49ff4,0b5a9641,3745eee8,82824bb8,538089ec,ae68605b,255d053d,61aa7e12) Z8(b52125ce,54d00b90,a0087f7b,b018bbe6,13935138,b5f485c5,d8607716,c3980058) Z8(47e34849,863d86b9,594f47bf,a786818b,9bb8d65c,9b4edbf9,6c818496,02982ed5) Z8(b552b6d3,74ed572c,b898270d,520afb7c,b28a390d,2e3fd36d,1e715463,1e8137b7) Z8(a7cd3b3e,98fe10d8,391807b6,7fa8fab2,4a76e622,7c68fa37,d0312505,4361ac7e) Z8(44c57247,eb91267e,0993defb,7fac0d00,badcfd7a,cce8877c,6cc847ac,4295b4ae) Z8(4963a9de,c5fb10c7,c1ade436,b4e2b8d8,32912d69,e9e0738e,d97d4406,bcf86386) Z8(2e918be6,00a48ef6,4fbe79b5,e542b336,49e21124,e8160d82,27b07cfc,faa91fbb) Z8(e390d654,5ad1d164,77ba8c2c,a898ed7a,9dfb8a63,25905df3,8554ce25,45fc5808) Z8(5da25d23,1b7f6cb7,f5705199,96870e23,3638b665,a8577261,48ea60b9,a98889ef) Z8(e5087839,1688b24f,6295523f,ef59d2cc,9757fd4e,027aab15,52e00e87,e15b4f43) Z8(c1df5ebf,8a7e5bd3,d6775e9f,bbe00b2b,eceb1f55,031e3061,3e381ca3,ca138ee0) Z8(29d4eb53,a388b633,4c39b31e,d0920f6a,97aea7be,be4578ad,de2d5773,a9516932) },{ Z8(153cb58d,9d1f3b57,75530e68,f08e872a,a184c327,af2fe70d,06f64b38,a5440619) Z8(3831eb50,5f738423,be87fdda,06be990d,7c63344b,51edd5b8,d2725e8f,512bbe25) Z8(2e62b328,6e4d892f,24fd156f,b5bf400f,ff26c676,b3987dc0,3953a3a7,8d61146d) Z8(dd206e6d,10ea88dc,684c9812,a160a9e8,547dd5dc,7f61f9c3,2716985f,ab3b272d) Z8(4c07eb13,cb821d1f,8ce5b245,0d09bbe6,96971363,9f8542c7,0bbce0b8,bd4229c7) Z8(496e87e1,2518b9ee,ba6fd008,7fc537dd,1c71268a,03859467,f95b8212,ba3c30cb) Z8(960f5d47,076dcd45,825f3677,3ba0f0e2,e3cad1ac,559cf693,461d7a9e,171d1e06) Z8(19267d02,1f86b8d2,e7b1b333,bf28270e,a0e0a7b7,aaaeb90e,db418488,77793fdf) Z8(f14cd468,d0f2df53,76e1e65a,c6508ec1,2f9e49b4,f5637638,ddd41982,dacfd3dd) Z8(abc5ced5,258af8cd,84816543,e5daeeed,a162f3d0,f3a852c5,485be88b,01730602) Z8(859bd7de,15b7cab2,4ce7f96f,f9ba8f0e,f6d58700,9478f9cc,723551bd,00db20eb) Z8(ffa47cb0,5cc63fdc,bfd0b5df,4bb12429,555ae671,c1c3a260,7487ebb0,1585033c) Z8(b4176022,ed76404c,b0f6d2db,6a119e93,d5e9d3a3,da919a24,e74aff7b,5b8b86df) Z8(e6cfd8b8,4db00763,2ec17c58,39b33119,9d970103,b8c85166,fe40c52f,315885df) Z8(5f9b9466,cf9b5c80,63d5d87c,ca827530,959e83df,43d087a5,72c94eb9,897a6a48) Z8(ace1d88b,bb5cb1da,fab389ef,567cafe4,08b45e3c,0b672174,1e3ee20a,df6cf0db) Z8(14f3b1d7,77d02118,d6b30d46,faeab5b9,04f30d08,869cbad3,7b2300e7,0c763464) Z8(5b324a78,7753b3c8,8161ccf7,839e0457,1cd40845,4d552f81,acf967d9,ad6a0261) }}; const mp_limb_t arb_log_tab22[1 << ARB_LOG_TAB22_BITS][ARB_LOG_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(8b9c1b7b,ba0ac6ef,1a7045fb,4fc1d240,49754d0c,0ee63f28,92ace9ec,61286fdf) Z8(94505634,73d96965,a62f60e0,055c524f,0f70b0a8,971925e7,4dba6d41,1d0343c1) Z8(15184612,1c93c13a,339710c3,7d998d9c,bbdb40ab,b6953722,a7f3cdda,9043605e) Z8(e2baecec,bb52b604,b0cf3c1d,e53a8b19,3c664ac4,309a02e2,37d88a1b,40123301) Z8(3fe22798,db932747,6e1f2190,1539e8aa,1ba538bc,4ce6ebd4,a8e1d420,4c534451) Z8(cae3482a,d5da9d6d,f84d4875,d43ff73b,5be57b4b,2c369b63,30fd2a8c,9a7f805e) Z8(1d148440,23dc7790,d23bd975,b5e01fa9,5a441e62,ecb5474d,1301a31f,b13942a0) Z8(93410acb,a122639e,e9f6f560,a2e52c2a,aa6e8e71,30824fe9,c39edfc8,bfd9acdc) Z8(4c404a85,66a1eeb2,af4c12e3,d317e9d2,ee056799,80e78b52,d0cfec3c,f815825f) Z8(6c410527,9d07dda1,dee67101,2f38e5ce,92c7b4c4,f5bf18b7,0b57d454,2f6457da) Z8(6bde9b31,f2e4d6ea,da57c458,223b7241,1a1ccbb9,54227606,bf840fbd,733b38d9) Z8(b73e7e2c,6030da8b,9a0cdfba,2545acb3,349cfc81,2144dce2,f80ee38a,2e8d392c) Z8(b4be72fe,5aed89a3,a8bd4890,a60c002c,d2d4e3c5,03b09d89,f1da3961,46519661) Z8(22042320,3ef4aab1,04d8021a,49b8e564,460b00ea,a29a7413,7a6aae61,65cfc75e) Z8(86a9a132,e6798564,43affb63,5ae185a4,d8c15808,e44f4657,909380ff,0e08c996) Z8(38603bf8,1685f930,739145b4,8a85d6da,d1f3a988,5634cb94,fcd59644,a77480cf) Z8(88455ab2,2cbec254,033072c1,ac4e6045,5f35b760,d3878b77,f158acdd,453519e9) Z8(a6eb720c,6e34c564,62ef4eb0,8e30d617,2499268e,7809a0a3,5515621f,003ff801) },{ Z8(1820e771,3ec50815,4d4d2810,167213ee,c5cba55b,1a2e2146,4b671030,50a75899) Z8(7f7673b6,b67c591b,cc52f381,090db620,c3a9950f,3907c163,b3c1252f,d37e177b) Z8(570c696c,36d9e7df,6543f7b8,8046e6f9,883b8e6a,f8d8ae4c,e951b6da,16958281) Z8(260ce86d,dd738efb,d169984d,133ac712,460a77ce,063c65f4,6e377198,4b093da1) Z8(7074326f,09c467db,c475f0ee,07a6cde1,048c0ec6,1f4bcf35,4c252858,c0f9fc7d) Z8(967ff841,aa6be419,03c9c381,2f749a85,da7edb91,27b211e0,4da0fcd5,fdafbdbb) Z8(d342c332,38863499,03365b1b,83341d06,3a34c495,5193488e,60347866,4be607f2) Z8(239e8009,bb9acee2,d5c48b5a,d1329eb4,27081c5a,b633247c,32efe299,039b2543) Z8(e23507a2,524d4c4d,17a38fc9,a86222f6,f154207c,da8d25f4,067c135e,3cf9ce0f) Z8(9920a33b,0c29fe68,d50a22e1,623a73fc,7d546db8,920f1c5b,d033bf48,d552bcc9) Z8(98456d70,e245eb3c,fe19736c,4aef3e49,5254e891,7436f3a4,5c0234b9,c2652db3) Z8(a171693c,e5a8d090,4b98cec5,86824650,bc7498e3,7bb06abd,b7e7100b,646687a2) Z8(9f372aaa,aab2bf43,da7f38c0,7c137902,83a15d37,5a707dab,9057134a,3ebc5c52) Z8(0cb55bce,4e7f263d,57c7a3d3,466c9b42,3b7796f8,c43b2902,f125f292,bc58191f) Z8(d718b11c,ffa8b50c,50a4a8e4,b6908ce7,a57f428b,70f430d8,27d5b7aa,495a2bac) Z8(47a4461c,d9327644,5d80eb3a,40cec96c,c5592007,84a8727d,d534ba9b,afa9c34b) Z8(d4bb4228,566babed,4e690306,d0d98ea2,492e4bba,dd3f9376,02ec7bf0,66e737d1) Z8(12ace6e8,c73356cc,e89a011e,cad8ec22,3e3b1ab1,e29e3a15,a6ac4399,007fe00a) },{ Z8(7bd45892,87ef1432,93549182,4e728fff,a17c9125,da83839d,a6de1efb,1d4a0b1f) Z8(1e586971,ece7bad2,0fd32d12,9f11b41b,3657dd9c,b33685d5,7bc0c31d,e8bcac58) Z8(80b3eebf,fab0f545,539ecd49,ee6beb53,30f670e9,d454f238,dbc65ab6,d0af3118) Z8(45a79682,a847a930,938dbc27,bc78ee6c,843f9f24,63431555,a8ba07a4,faa828c9) Z8(33959f27,cb625266,f07a9c49,5ae75939,279a7691,27b5a542,55dc3d88,a05ddb9c) Z8(0f4d7c27,70678ab5,477b4b67,9a89a333,6b725bd3,4291c99b,8b2095fc,268ec52f) Z8(62dac762,7547581f,aaa6ba30,c628bc03,0afff1d9,db3df166,2c75639f,a7b1a6df) Z8(96ae84ad,643a671e,8af38941,c0670dd4,ceb649a7,26523995,e7622e82,37f66b02) Z8(3572e1c0,083ee489,f6b9e6ba,46492d42,3762c6d1,442e03a9,0d4716e6,d684c7f3) Z8(bbc8c4ab,d2e80ad4,78bb6f2a,f4ccb747,e6efad6a,853af45c,98068b82,f9a00236) Z8(093fb52a,551d5ccc,0630c57b,2c74921c,b2b6e3fc,585291c4,8a609eb2,4b1a2568) Z8(944c1d45,1363d727,3937a37e,4c23ba0d,50818dbf,23688c83,8ed17760,1078bd24) Z8(ebe8d2bb,51a8fcbf,08be40b1,e83ffe1b,a6855626,15c0cb36,5dd54d65,a7660cd9) Z8(e6611264,18716941,7f00d1bd,9cb2f10d,9a6ea927,e16e59e0,059da5d3,4f589431) Z8(bdacdedf,7a79a587,3934d586,d54fd545,9c7a1a87,29e3fc75,50e1ce1a,f6a61f85) Z8(98212551,f82a20a4,7ef1937e,38645e42,8689e34d,bbd64d47,a3a3f54c,8d40afbb) Z8(c4b9be54,ab3b6a5f,e75d1021,85aab5ec,40365daf,008f1701,a6729ae2,9df4c673) Z8(15be5920,d672b536,013b32ce,8d568dc2,09cffdad,44eb4324,ebcc1ed3,00bfb823) },{ Z8(159dfc29,0420113d,f0e9b3e6,b7936a46,60530cb1,f5cd5799,d8a0c647,da1edbd5) Z8(1fd5c6c7,989a5d1f,1c1bfb1c,03db7723,88285f8e,c11b6f9d,fb78539b,685d0a7e) Z8(7aee5a5f,9280afe4,cd6de643,3373848f,fa3e66b3,9c96bea8,58aea360,8af4141e) Z8(2e993e91,c92da4df,3621c5f7,2dc22291,bcac49cc,eec45274,a35ff6b7,2f803695) Z8(21deeaec,1edaa6e5,c14426a6,977a092b,3509370a,8b74c1be,b241a9c4,d7c03a18) Z8(dd303505,b20fb3e9,aedb3496,f8ba7565,11d343b9,effc119a,fa42f81c,563f7da4) Z8(cf33ca5b,519232b1,1028b9f1,62b9516c,7e216a4a,359c3a23,f1865ed8,d15cb138) Z8(cf8e12aa,23a2797d,e867994f,e397895a,b54a3b53,70dd7510,6713f112,27ce9645) Z8(65e81ed6,8248dab8,7809567f,591b205e,a19551ba,349e37cf,64252869,45689adf) Z8(09c7e224,c8c909b3,287ab29e,4453ea2d,5195f48f,9751eb89,43905827,71644fac) Z8(e1d514a0,fa29f816,fbbb0296,7da66aff,0fb28fab,a96edf95,39d54a86,fb85b2fa) Z8(2233dba2,4b86566c,e395110e,ea7f2a23,b18e035d,2165e381,52423ede,e85275f1) Z8(5261af84,a1582928,55dd750b,5d0932d4,00bc47c3,ff02871b,db020f7d,7356e4f5) Z8(98e0e51b,0094d420,99eb61d1,afb8deac,90122dc4,b2855ff8,41112acf,3f8c2665) Z8(78983289,ff71220b,0282b5cd,55a3a8c2,da1a5e4c,7813a608,2c5278bd,30120813) Z8(edf7e201,07b4996d,0f632916,d438bb96,430ecb69,82b09d3b,ac79813d,89db3dfe) Z8(f0697e38,b4baf715,3a53ec28,699b4749,cc95af15,d137bfbc,4192b38f,7ed64a06) Z8(5a1a3322,91ba6e33,6d725824,8ccd29dd,da6a5bb4,50435ab4,15885e02,00ff8055) },{ Z8(163a181d,4f6d4e62,917d8eea,77bc891c,1064df82,0c3a465b,ea8fc220,a32f4ca1) Z8(2d0de89f,6582a9ea,59535a94,964628d7,f58350a8,6b1ef5d7,e5d287ed,7e0f3ed4) Z8(e6a9cd8d,16f35a5f,2465edeb,302b9513,0e364757,72c9d4b2,e848099f,6943e817) Z8(13eed651,302bf46c,9aad1e32,5f4b348c,a633111c,003a6c4c,bb2943ab,5761801e) Z8(fcdf642c,a0a1dc2c,9fcb3b43,e8c95255,d1593e22,28775bd5,774dd809,386f3302) Z8(df0ec0bb,6ac0a21f,41e0f6d0,2ef627b7,b7428421,37accab4,b1cf6123,0b69b432) Z8(b7f4ee2e,aaa79e1a,9bc6556e,27af121b,d30dc35b,b0f6c930,84f33ea1,0260d988) Z8(ac8474f2,f616d2d1,b6309807,a8647e3f,483af5c8,6db19849,ef0dd35c,b3853143) Z8(b8dbd4db,d02f15ae,3ea5c588,03447b7e,a3a59810,a655da6a,ae5b2481,331db353) Z8(5cc0976a,37aef47d,d76d23c0,027df6dd,c5672c45,29bb2452,2c43b0e2,44688e57) Z8(8aaa3e93,9b11e25b,51f476a2,4b7d4a20,5e50e8ea,42259149,954dd970,2a2fd89f) Z8(0c4ea5e1,e5e4ca0c,3632ac57,216b8010,ef8929cf,6e81651b,f5e09ae7,089b83e2) Z8(ac9df9c4,52cdcc4e,a28bd8f8,50541114,0b225dc1,0378c3fa,5009627a,98ef6b8d) Z8(cf32a022,f9743e40,8d5dbc36,038cbf8c,e1f6560b,2d51b5ab,5ee8d28a,c29a8350) Z8(3fd2b1e1,c0dfe8b1,02d3005d,94499fd6,7e992b8c,1e00171a,09a45d9d,c77ea17b) Z8(d1256823,1dbd11a0,cba07a73,09d32ece,22b2eab7,40d37dd8,6deb1ebd,3525dc95) Z8(4533ce4b,200d4e60,b0eb1eff,a6dd1f16,73b6e444,ad86fb62,5722681e,57075db5) Z8(357fb684,e444e58f,29be3018,19350e86,50117ab0,a4f24dd2,0f064895,013f38a6) },{ Z8(b6d927ef,2dadc888,915de342,2b4f6ab8,8c0ab401,a89beec6,4d35a509,f1879dbb) Z8(c15674f8,6147567d,81977456,712f397a,10d85abb,e5114af3,c37a9f23,4ff380a7) Z8(0b968932,723778dc,ee888c13,b8923376,eee291f0,79bf0802,6fd1f78d,219ee90d) Z8(b456aadc,f93259cd,e4526f25,68c1f275,7654332b,d667a1bd,a0de82a0,e3c73b24) Z8(86a1cc6e,2b44ac9c,ef0753f4,0a1e1547,b87bb88b,0ab81f39,0a422432,dcd030fe) Z8(bb3435c1,a60fd723,f320ccff,806caec6,15ac24a9,aafedd83,c00972c3,389f689c) Z8(33c6f737,ceb7a640,cbde462d,8520a153,cb8a23cf,d872bcc7,ce23f62a,a5391b84) Z8(47283289,764df5e5,528d20fc,c5dcb614,43c16e02,1d9188db,7f7ebe30,fad8a6b9) Z8(95de8bb5,7ba69284,86b5fca1,485a7070,9404a9b1,ac1aef31,a34a7ada,57e47774) Z8(5c146598,0606f86c,acd4e9e2,4150bcfb,93c99f83,719d0376,bece1034,9bba59a4) Z8(dc51a41f,4e4ea224,b18e5608,66b1ec80,2be01ca1,215340da,797d53e7,3ad0a97e) Z8(6bea07d5,3fb637bc,30a6e3de,66dc519d,2134d5d6,d58d048b,ff690887,616f321a) Z8(4d3f1203,7b69e111,4123d8e6,636baa17,92fc4fb2,e1189a7b,dbb29855,8634c60d) Z8(19ddc4eb,c84544d4,dd160b19,240f1c39,db986bd7,74d1cdc9,5fe65ca8,5daaa81c) Z8(e0cb53c9,6a8f6671,03c41668,2cd38aeb,bc9346ea,73b640e7,b0542801,001d58fd) Z8(c6388d39,48b06b91,373f9fde,d61bb167,705e24db,440d4f96,b197b8ee,6a24d5eb) Z8(96cb638a,faabafc3,0e8ca9f4,16064670,73a2bce7,95165acf,a35e4561,6beb75e0) Z8(f1aded85,903ae028,8d165ca4,2800d1f3,e89c01eb,785a4740,bd82e93a,017ee11e) },{ Z8(cf3a1be4,63afd436,9b560d1d,ab80e16f,7f3ffcef,46e47c32,c1bf0472,f5a9f01a) Z8(0aa50d58,694510a8,ac140b11,b7a0de0b,d773812d,b63e717b,3aa487ec,17d75929) Z8(33f38e01,d03d7d23,7b78605b,9dbd5945,2deca3ef,dacc0972,b66d1fab,5478b89f) Z8(6c8d604e,8ccb6228,56402f4f,6928d694,364ba4dc,b2e31d10,e7b09ed8,fafd3006) Z8(5664e5b5,818130b4,f02a5932,8fcdf74c,878a7fdc,2124693f,4b625ac8,8760d4cc) Z8(fbc3f0a8,d1fdf130,ee3b4bc8,45eb702c,5e2c16d2,87cf864f,22f7526f,7095fddc) Z8(33a6afe4,e3880a59,ed7defd6,ad38cb99,5740ebfc,f9fb8b41,091292ce,670ba3e7) Z8(a4b0fcd0,171ec2ab,da497e07,cab51d6a,06e053c2,113ea9eb,f120900c,a718dd95) Z8(a1cb5819,32258f47,17786fda,0f7d2d89,85c9e03b,0f862316,a4e15b37,41b090c9) Z8(ed376256,2a2d735c,05d62d79,cd168e50,a6104590,8b8b0c50,06390c6f,0ed79ca9) Z8(d1182bca,62af2ec5,9e8841e5,710ba75a,e6242703,1b18c13d,bcf7abd8,e2ed4bec) Z8(3c899785,b2240eb0,8a4b651f,24457964,62fb3bc3,c4b9c61f,4b0ff0af,8eecb46d) Z8(b5d3eaa1,52b1cecb,9303ba6d,8c5fc2fa,d5cd511d,55098de4,523a0262,4251b2eb) Z8(a04e49ee,116b023e,685ecd1c,14afff9b,1a4035ab,16119597,025dcc76,68445587) Z8(2b28244c,95eedce3,175e07a9,00370dfa,0e90654f,40ba428b,637d121e,67a74fb9) Z8(b67900f1,dbb1eb48,150d611f,b9e1f6e3,7b4d80b2,de15aaef,fc7703b0,57afa332) Z8(d2f30446,a066ddcc,39b9e717,15e9f367,405db65e,2b4f58fd,0525be43,32b68b50) Z8(20ecce05,4a9e0f8f,d51f7739,309e2f1e,3f52763c,9a6c0404,0058ec8f,01be79c7) },{ Z8(f74c6678,f18adff2,fb1023d1,43d330a9,72172504,77a952bd,9c101436,ea132020) Z8(42170874,608dc543,c9289710,32ebcd00,94bdc346,6e91ce38,40d63ce7,af60df8e) Z8(e2ed1e8c,3c266550,2bef581b,4561f01b,63c3bf32,9a2cbb2c,f79b969d,aa80fe9c) Z8(cf6229c6,9ed3ae25,88634ae7,ffd42e0b,34757b01,6d861007,a6ffb2b6,aee5359c) Z8(0a3bc158,ba32b75a,63caefe5,c6ae07f3,8a2ebab7,f68b7654,2f3a9881,5180e1ca) Z8(1d54d31d,581407ef,4b015ade,056e88b4,b7a8fdbe,6babc997,dd6832e9,bf1587fb) Z8(99333ac1,f118be70,03184a9f,6a3f6dee,505c3555,39400a4c,c027fb9b,de972cd4) Z8(8c339dd0,eeab66b8,5eeaf63d,c6bb929d,d28a606b,43c9fa43,5fe8a7a0,4cde11f9) Z8(b1665ce0,1c7f56c7,0e667317,b0719165,672ed541,30387ce6,83aa212c,e4e032a3) Z8(efca2425,90ab1fd9,185750d9,0619d3b4,a8d1a3d6,d599d7f3,64e5e121,dcc285e5) Z8(d0e8e0ff,cb814bc3,fd70598f,9e7de4fe,72b836e3,2b028080,d6bfcf44,610920a7) Z8(30184b76,feb4db67,e5429e80,fa6aca84,7cb9a5a1,7db74372,58e7c9ad,d3dd60ae) Z8(21621628,0134ca48,e6f0342a,3eb721d2,3ec22363,4bb47df7,4786d57b,3d7cadc5) Z8(7c5b9ec7,c5288463,b8c4273a,3f88e699,079a8dca,0a8eb3d0,a5ff317c,3fe0603b) Z8(73ae5571,d47d4203,a092519a,d0b1dcd4,96fb141a,5122ffd0,2bbd5a8b,e70bbce7) Z8(af58fd5c,6c15655a,6433c9e0,c200063f,1857063b,31cd8161,a4a5b7cf,52d919ec) Z8(90d465bf,d4520ee2,9bb0f82e,d99e1b46,facf68d7,e4c4a44a,51bc9855,d122f7ff) Z8(6b5788c3,76702788,f9a073a8,b3db2c3e,1dc282d2,c3769039,b106788f,01fe02a6) },{ Z8(b8c5860c,397267a6,7ef0abc5,e5622038,ec948e09,19810aa3,de5e59a0,0e0c98c7) Z8(26e3ae5a,d79f4b3f,5135e8ce,c66db329,373d21fb,68372486,4af5fdad,57fe2d95) Z8(ce696229,64b6a5f6,485f4902,8b406eae,3235f11f,0b73adb3,b36a77d8,5ff1a4b1) Z8(a09da7d7,7e160af8,e23b15b6,f7e81172,7f2a7ead,7ff7cb9c,27632f90,8691f2a6) Z8(2f08871c,b6094941,9416d943,7aedea45,0fe00269,45079252,c92631b3,61f6fcd5) Z8(41f215c9,e6f47d2c,bc205f60,522f0bf1,ae1751e6,23e491d1,aabe85af,a28c04ce) Z8(e80ad76f,5be93559,145d5725,b71d665c,f49a9222,00799f42,d5d96fb1,05534a04) Z8(1ddaae9a,0a8a229f,058ee4ea,58eb20d9,07fdeba5,ce669de4,e3dbd78f,6231fab8) Z8(20297258,305dc65b,10d8aa21,31d07f18,9819d38b,6f279cf4,501bb703,3d19daef) Z8(fa52c1c7,3c7006ab,bbcbe27c,24486e52,6cc7ee13,230e1a64,eacb5a91,c90ed9ee) Z8(49e54cc4,60c05af9,713c4104,1e18f970,26ff4407,2502017d,21c84442,ed0e2bec) Z8(d2fc7e3d,643c1e7e,e63585fd,6a28513a,208430c1,c71220d3,69431665,485bb2b9) Z8(ae0c1056,c119fa70,9972bed4,ec8bff73,28462909,88105262,82ee0c2b,47e23bbf) Z8(dbea93f6,8625c04f,eb5402a3,8739fb3f,6689b965,e78d131b,5a6bb9c5,114d1e5c) Z8(a78c79b9,1f306be1,3e517354,cd92d42e,b9780639,67c24b06,700c45cb,80faf8d7) Z8(6ed6e98c,ee884564,767dfe84,c4f4f91d,3990a056,8d323dc3,9368e92b,fd661d9f) Z8(9e735ce5,f8f7a1ea,f0f7b184,9c5a2157,cd225ee7,4194c38d,2ce8f767,85a6e302) Z8(50649ad5,7296e998,6635feec,de835234,d137f0c6,005b91e4,a332fcbe,023d7bc5) },{ Z8(101c53b4,3d829630,6ebcad81,823f02b6,f244f958,fed52e13,9a379dd5,9a4bb0e2) Z8(a84ce40c,5c64c539,c0ca2ef1,8ecdd6c9,8ebc2450,2482c396,ec135684,eddf7163) Z8(0f1b3df9,bc2eab6f,7d3326c4,45d147b0,6d38b620,3192be60,1179044a,f6aa4857) Z8(ae550026,3f59320d,71a23495,1a6e69e3,7616bc8d,0e6bab10,7a787dd7,20776e7c) Z8(502c17a4,5e2b5aa5,575fea89,7cfa5f61,8d8df309,5a8c5fe6,c7604757,f97b582d) Z8(dfabd473,d8ba4e2d,885a8357,fbd17891,eccffbdd,905fea86,f6e200c1,1cc233b3) Z8(880444c5,c83e0daf,3f91b923,54344dcf,55deef70,6969d05d,046cc493,44b3588e) Z8(c58aee4b,c4290d33,741768c6,aa5d01eb,7f8bda00,f1f0c8dd,851a498f,7cab3b90) Z8(97bf2bcc,a0c3e55a,b5dd5e8d,901d7d4d,e1b1d548,735c2e9e,a7b3b1f6,bf5f2e2e) Z8(047f4fff,a6e76004,43072bcc,f1acbcdc,4801c11a,7de33193,c2cb7421,0245f31d) Z8(eb500fbc,39c66ad4,efcea6d4,329dbb15,ce7675ba,e0e36edb,a36fd2dd,e18de548) Z8(0e87233a,96cbe1c1,0fcc8936,fba39e93,6948f063,105528e3,062639f1,40ccc13c) Z8(e6cab139,f6dc275c,2e524c99,6d928662,2e9e59c5,a6d52198,efbb5be0,3c6cd0bd) Z8(09a56093,077401ef,b9572f11,8ce1b2ab,7a92a7f2,4ee39b9c,8aeec3bb,d6d7d9c3) Z8(f7a4cfb7,7ea40797,2fddf35c,7cd1bcec,2035b46b,e00b16b9,2096ab10,d788faef) Z8(64159550,e5727bab,e2cdccfe,7a6a63ba,297319d8,fd9638dd,a2ea5ad0,284b325f) Z8(574365f0,aab08c0a,25ec4d0f,9f40ea98,1847d7b1,84813e64,6de32fa4,f71570b6) Z8(e4be3a9d,7c01119d,9dc1262e,f80c634d,de2fcda7,006b2f75,a4b4fb1f,027ce52b) },{ Z8(4196f9a2,e30fb5de,d3e7b9f7,b287f0bb,69105445,8761403f,6ee4eba5,cfc563dd) Z8(77aa4c47,fd707a7d,dfb99a17,e0777761,57136bb4,76012367,037a1750,6db92b4d) Z8(15c0309a,452f5710,49e13aa8,06bd4a63,df770d91,254f24c3,665d3855,bbd810c4) Z8(b3358b8f,8b7609b5,786518ff,d2a12dd8,a0fdf770,1c5e71ac,14a8b0f3,f21f4629) Z8(d77e0359,bc579ba0,81c818ae,91b9d38b,d4f5c8b7,6df5831d,38c5c709,0ce9260c) Z8(cc067aec,45d2a310,27dd7f53,da27477a,87086913,09aa0db5,339e1b0d,8061a939) Z8(d94f2ed0,963bc147,a4d23632,976889fc,cf845b6d,c032fb8a,a2c6c2ca,b05c0e8f) Z8(458bdf83,31775d2e,520d90d6,9bcd6617,026f2347,4cc44e95,c5975e8e,ae3acc21) Z8(d4faf8d9,28d77576,05f3f05d,719d430b,7ff285da,b3f7cebb,92277e92,463c542e) Z8(5f916974,7d247364,1449edcb,ea5a0c25,cb9aa604,228861ff,856f6daf,c20b2a68) Z8(9df37f67,97f5d38b,a0932b98,688721d1,1975b416,896752fc,5e9d6aec,264dc1f3) Z8(c2653a20,b9335f07,6a3e80d5,903a8b46,bfd1370d,0bcaee72,1d00f50b,5d2035e3) Z8(9708c722,ed2e7b47,fc8782ce,e169bd8e,b4d437cc,2ab8d583,acbe0b9b,30a3bf6e) Z8(db3ddb70,28bf5060,18ffc702,f7d6224e,00f69171,8fd7f14e,90ce4e3a,8b40175b) Z8(765d5c93,ec0ddf98,d99c8133,531b0e96,3f37e464,a2d8ff7d,4d93820e,b94a41cf) Z8(d81e0c57,5263533b,c575d238,619ecab3,08d7346a,6fa0440f,6674c75b,cd885393) Z8(632ef4a6,98ae2002,90e8733b,da3c76ee,49ef383d,402d5503,29821714,a83d03e1) Z8(fbeab8b2,807f2ca8,5ca35c97,1da2715c,49dc48ef,f585da1b,7d97ca09,02bc3ee0) },{ Z8(d0b37e39,55077455,210009be,e2b1c4ab,08ced6d5,6ae72e97,d3dd639e,bf002655) Z8(543a47ec,6be7899b,c472f09f,8afc05c1,49d16267,e73c772f,19553bb4,c8d5e72a) Z8(a3e310de,ab2ae29e,c36bbf3d,7a92832d,a9d3e652,e0bfb298,8ca41ad0,7c6d1319) Z8(7cdccb3b,f7f5e598,b21c1ad0,94063ec7,ac373bb7,10e825a2,127c9d11,1b23c793) Z8(6fcd5fdb,a2c1b5c3,4b295e7d,25323523,c46ca6f5,456c13f1,19d99bb2,bce65892) Z8(183cf734,a07e8f0a,56e037e7,1b668c2f,0c751774,bc0afb6b,d9005008,72680a84) Z8(4ebec564,23ff5356,6ed8a87f,52d4c1f5,3f5cb7dc,32f39cc9,cfb03e42,9573fab7) Z8(66cdc5e3,372f46ec,4f1ae30a,00dc6f8d,6c025663,14c73859,d8ccb507,3b6540f3) Z8(e84d0bc4,34e7fa7e,0e07bef7,58ac2edf,e005fabc,372cd2bd,e25055e5,bce9ae09) Z8(a9c3a10d,0a134b31,adbf8be1,f1470fa8,26559beb,89d6a6bd,4dc348e6,5c951952) Z8(e8cc46b2,d18b1886,973701dd,5bd9cbb2,05d1abfb,39c54d1c,b1034abb,a22284fc) Z8(176abbfb,45e0a3bf,e339e2f6,2285cfa0,0bf70da4,89aace46,dcbda6af,7eaf6456) Z8(5b13d650,1a6b8da0,6095aa23,9dc6b454,de2c7283,feec24c0,c2fa6baf,5c9cd08b) Z8(3b96f292,e9f06752,b38e0513,dfe4a9f0,fdd1b5cf,fee55cd2,f1f8d569,a7ab9502) Z8(343a8411,a6b19a77,f82a8859,47d3b9b1,5aee030c,c1378fe8,0b81cce4,dd63e040) Z8(cc63bb2b,cfd85012,132d0aed,649cb9d7,a9dbce2a,64525414,33413294,9c844c19) Z8(dbadbe86,6fc8d6b1,960efcda,7e0056db,ca7f55a5,747d1b59,0584b077,44a7494e) Z8(ae46a6f8,4641f6d1,74fc191f,85250c00,0837cd42,a4a25e0b,f0214edb,02fb88eb) },{ Z8(eff6af4e,3d5606aa,c5fac942,a42c374c,13ec96e7,24c140db,4f6cda78,d1dd2504) Z8(58595dfe,8016643c,515f125c,2a494d50,a89a2679,d9d7b9c2,5ccee898,7589b2c1) Z8(679f977b,c771f629,cc7b96ee,5b914f8a,5653924f,21e2fa59,3a5f2a66,7dbcfdcd) Z8(f53014d3,cda718fe,ae2136dc,4f0f8e39,50ca13a8,1a3d1032,b06a3a22,e5a60c5b) Z8(066bc84a,0044d9b6,a2c5e629,88fb3e27,98b8dbea,3bc107f4,f48f580f,904e514b) Z8(d6447ee7,45bbcdc2,d65076cd,f3b7b73b,c9346bc8,057e431e,bf9bc75e,89a2e2a1) Z8(7c11ef2b,8a533e02,6b055ce7,66cf9ebc,5235dcb4,5e4fbcaa,d5c7d05c,4b396450) Z8(b335a482,132127f3,8319dee0,6700a8f9,27390210,5c13845d,d90d8492,ddc50fc4) Z8(bdba0a4c,14690244,897ce501,baaa83f9,e7c6d7b0,fc5e5099,628228d5,3444957f) Z8(d6a92a1c,7961bd2d,8e412736,fb30183d,f7e37cee,15fb8a67,b14f9e92,aa5a35a4) Z8(fae1a714,a697813d,864e1169,b4629ad2,d74d8c76,3a727537,1602cd21,007eafcb) Z8(462bf88b,2cea0067,64d403bb,bcd55cb5,e3696163,71eb4b42,b14d88c8,2276a107) Z8(d5fb57e9,9596bb24,30e8165e,b7e3c80d,fcf3d0f6,1b4ccb77,e16aca76,86a9a505) Z8(e71f8ea2,9d485872,0ababe70,d28d71fd,f9770dda,f6735cd3,99872a63,a066983d) Z8(e17ebc1a,8becd1e7,b87b4cd6,f25102ef,c15694a9,9d699e57,665ccda1,4aa5a87d) Z8(dbf3a9cd,b95e0344,5b753371,8a2308da,3ce19a57,aa00340e,e762bee8,4301145e) Z8(9d19b802,d10bfb83,cef4f601,84fec96c,7f1cdcfd,6d1cbc6c,4befb776,9d779681) Z8(90376023,4369ae1b,b26456ad,01c59be5,d35cb358,327b4256,b8d7b196,033ac355) },{ Z8(029beaf3,0d37bf81,1ca8bdd5,e260e76e,e20637e3,2bd854eb,a14e842e,df992f34) Z8(1274240f,9651b076,d0dad1e2,d9f60637,84709305,de7d5f1b,d6ad8622,43d28a33) Z8(a895711f,3cbacf8f,20c79b7a,4dfb60e4,94f6a6f9,413ba06b,e780106f,66bef67d) Z8(55f7464a,f4a137d2,78d89161,faea4b71,08e14b5c,1444668b,1e114480,27b2b9b7) Z8(c47fb75f,3214a251,9fbea60f,95ce97cf,54c36032,d8514193,4705eb99,97bdbd4a) Z8(a80e0111,f93c18a1,6a392179,da093c31,c9292081,5739c9b6,7e358caa,9304ed03) Z8(16d10b55,6b6fd6e9,2c56e827,036e795e,1fb7cba8,cef092da,79e2c0b8,c44c9987) Z8(49f906a3,ceae3a81,1605c9ff,29c085c4,27a9a54e,1e6d4fb7,0ea49631,9a99cfb7) Z8(08dd32ae,77c14abf,1b68d980,433fbe56,b5839822,1f4333de,e3bc83a2,dae3247b) Z8(bf6f9201,3aa20feb,64ffe483,436f9181,e524b96c,2e2b487c,2d0365b1,dc4f694b) Z8(4370bbd0,711bda19,087e5a88,116e6872,0ec0467e,61fd7533,0fefa186,b3554ea9) Z8(870b745a,6ba096e4,d00b13a1,b1a32b07,725fbf02,47b12e83,0d7f9016,8ab24db7) Z8(58afa49d,e9026dac,9a924d29,f26cf734,acee4a10,58b0206c,026c0348,4b91b19c) Z8(feccb3c1,f0a78d83,af592247,707d135b,16383883,4e34dbd7,d7bbad87,d8ab4330) Z8(9d20b4af,0645d8a2,d1be30ce,eabe0a84,2d6dab57,91844e4c,59898a31,4e265615) Z8(2ba27461,33e75cb7,efc2f3c5,814b9960,b5e0a141,36ce7942,6d806136,e2a795f4) Z8(afb2a2f8,d9685d81,f1aa8f8d,915681b2,1bb6571b,04283df2,8989b1f3,6712e10e) Z8(06d092ca,a2c2bd25,348dd185,50ddd303,2d996bf9,25ef65dc,8e870978,0379ee25) },{ Z8(708ae387,b55a7a9b,49ef93d5,69116798,000e2c98,3e9bfa00,13459641,c5ef2f12) Z8(7dc07e2e,aff93b01,0e9ba971,3ead9875,37a74c01,025d52fa,84fc6774,adb586a6) Z8(1f9e4617,983881bc,d83da580,0350f2ff,42c79fc6,14f447f1,e672b5ea,734e7872) Z8(2a5c24bf,01c697d1,f802fc1a,4084582c,5e09e0a1,f5a1b882,4acc7c26,23b5dbdf) Z8(ea96bbe7,530c75cc,c3fcf5cd,b2912ee8,4383f0ad,ae6e89a5,84970483,46f53baa) Z8(32c9894a,25ab7744,6faa3544,6eecf141,83f44b69,4b2ffe2c,330f25be,09388d0d) Z8(04d46993,feaf32a0,f65251d2,1745d97b,4778e3cd,7bc339bc,78987831,2888eae5) Z8(805a25f7,2674fd22,74e91399,472cfbe1,bfac6b75,fb7ae3fe,7ed88b99,c45baa37) Z8(f9cb2e29,fb285d54,e9ff7f9c,9dd91864,42cd7971,1d8f6ff8,67e36b8a,a44706e4) Z8(2c5185ea,561f5067,37967862,f75de657,189a0dc8,8b7f2526,81a2f042,d7473598) Z8(27805f6b,8e13e378,ef356f48,a0f0d2fc,4c8d7b5b,6d84f28d,97b0509d,64f583df) Z8(21b6ded7,103e2620,dd736b8d,a56a6710,11e7e834,8c5c5968,4ab275f8,8f65844c) Z8(e822602c,39ee80f2,0bcdf4b5,a3371c2e,b7517108,12107baa,d6afa1c5,453dd768) Z8(5a3347f3,61e5a89d,17084b05,7a86a067,9be99417,f6a730c5,f61fd3fb,60618ff4) Z8(a174d99f,189a4320,1c993793,62e36683,45df684c,b94d7380,aca5bb10,9d6e7cef) Z8(dee291d4,5d845d46,aaf61c17,6dd0bc95,acfcce42,ad4d7d1d,d29a2de8,0a1bb837) Z8(c877d8a1,c6b74310,0bef184c,cedfed6b,e92f5d83,52c20e14,9c15cbc2,9b9d4477) Z8(549e114c,dfb437ee,3d630d8b,41f8076f,13ef95d4,078e96cc,22470295,03b90963) },{ Z8(12f0fb45,2e238d06,b7131aab,476a3ec2,9cd09466,9d83c81d,fb5e2123,a4e8be4c) Z8(3705abeb,e3627abf,53fca206,6ef5e0fb,18c6b784,16ca532c,7b4d871b,191be8cc) Z8(cb1faa09,e810f865,f67ac305,bf932bec,eac773dd,44d4e77e,c034c070,ace93e2b) Z8(bd20e950,a4032e9b,d5042dff,f55f468d,45757ccf,ebddf885,cf43d77c,d40a6942) Z8(fbfe4527,709d999f,36bba480,184ed029,832ab1c6,ed7a9c2f,303cf958,8ae45482) Z8(fbf7e39d,04e007a8,0bdf0273,e4649dfd,dbe9b1cf,be1a3085,dbfc44f8,cd84729c) Z8(27829d93,f1d000cb,53e5fcd4,39cec4c8,a6564d3c,f8ab5e90,3d5d1f3e,9ed8b522) Z8(dc7275c2,68de1a34,a2d0c588,f4a4c506,6473b5ee,bb442581,61de378e,93b39a84) Z8(ab01c836,290151e7,750ca86b,e8df1afa,05f75773,8f804956,4f5e26ed,d105e0b6) Z8(f43da505,6db5b10c,3b040bbc,cc940b0d,56c09b7d,dbf2810d,b7a9efa8,749b49a1) Z8(bec9630e,6919a793,07e450d0,9fc08703,c9938310,1a4e9c5e,9466d962,18d10342) Z8(e21176d8,1f5a322d,164d9eee,1114aec3,1950bd23,e4ef4a87,b98347e0,8afb2ee2) Z8(760bc66b,cf609b96,d49db045,d2670a40,ea75a3f7,12d28d79,c817b859,1998272f) Z8(88892133,88a204b3,5c10eaa9,5e523a53,150060ff,368ab0d8,03f8f465,43f674e8) Z8(fe905d57,dbde9f7c,d8363cce,0e897ead,68d7d37e,923da68a,bcfff7d9,d117bb22) Z8(65dc2153,0755b0eb,79a8ae2c,567d103c,5d2a0984,75016251,a1fc017a,15567658) Z8(1ef3a140,e808e153,3b4ede62,ba7510a9,8f9f71cc,7841aece,758dcd0b,7a59b490) Z8(77122f83,d140fe05,3ddc5335,eb03be90,6f57aadb,f3db4e9a,1f807c79,03f81516) },{ Z8(163db538,c9e63567,9b36f943,cda572a4,cd668dbc,ba76e4b4,2367c160,5922694e) Z8(17a206e4,8372326a,f04c6517,5487b9dc,fda97fed,d31b54ef,513698cc,b364d232) Z8(5032acc2,f8d36c20,ebaccfff,140651fb,5cc7d99a,3b2c51cc,a8b44dae,e76772ef) Z8(bcc11679,bde5d0a5,feb96730,1bf0ee82,7e225a13,7bde795c,a2650462,2ebcdf23) Z8(edcf0f34,4adfea10,2fb5c5ef,3c935a2e,f7928110,c7d7690b,6c8ea4f6,b5500cc3) Z8(3cfd3afd,68bd1e69,0fec52ae,2a124356,2d6e9d4f,67ae02b2,03ed0778,49c76c68) Z8(30b3f9d8,2d80b6a5,2432c296,71cd3477,9bd27620,46992920,e0fa9ec8,d6ecf79c) Z8(b236844a,e35a537c,f1ae6d00,a04c0df8,c21abef2,92fbdef3,a431c4e5,e6742218) Z8(b1af2e1f,5d3a25f8,db086156,a0b20b4c,a28f7907,a37187ba,b256c918,74489a93) Z8(9b3b8bd4,0356861a,686c7103,ea439b6b,c2560288,adff468c,232ceb58,6391bfa8) Z8(f7659d64,a7e3f0a5,326a32ce,cd890ea7,94129e90,801efe84,8dbee3a9,afa12271) Z8(b7db7b3d,81fe1c90,cae56407,a93fe924,68869c53,d56d7ceb,9c24180f,d4fc3fc2) Z8(19f24a27,e9e2224b,ddd691c7,45bf49aa,e67480d7,819dcbd1,5a6e7a60,aa22b436) Z8(018b2d45,f9f5f589,72660e3e,c6786ae5,757dcbfd,b891261b,7e47d0c7,8fdd5f2b) Z8(fd551fb2,d992ba3b,7c24b177,9bef23c4,409c8370,b91f9c9f,f502d83a,b619924c) Z8(47667a58,6ffc7355,73c21e85,0fa47c33,06d0903c,f361094b,318979b6,2782afea) Z8(fbaec97f,e97cf293,700a7df2,64ced1d0,e6221780,137e70f1,1ab02780,5412d654) Z8(d664dace,75e6564b,d11ef23c,fd896bd5,01884bdd,63fe7602,2bf321e8,04371146) },{ Z8(cb2f2a01,a705313e,5fdf55e8,22d6376a,c930db99,03e37e8c,0dc9cb66,068e526b) Z8(865a839b,32a75ae7,2c60783f,da801644,7b927779,ceb0f6c5,fe28a7ad,90c11e82) Z8(342e3340,91d86065,aa005a5d,d8420e82,9d7444e9,f2d36854,bda9641d,fe72e425) Z8(feb462af,9086e6de,f34ecf44,10dd5f51,904e453b,f134997d,52616131,f9761f13) Z8(79fa1cec,5d99a6b8,c77017af,e63f7e04,5dd317cc,e261c681,3acaaf15,3a076b9e) Z8(eaab0c5a,24282b35,c7f870f3,668a7525,a8570012,073da901,6f9f23c3,7086f204) Z8(57f45936,5a4b0149,7de91f55,48a4f5c6,9c002a73,0f09c281,ec34ca8e,d69da79e) Z8(8edceaf1,55f55040,1f3097cb,b7cef409,266653a9,81f6e6ec,ec4ec2bb,6d35009e) Z8(1f5bde44,ac3e7cd6,df3347a6,0edd937b,cc53dc51,00db2709,95b3a9a5,0b166442) Z8(be71b186,9aa2fe90,51fbdd97,366f7515,55d61457,31a99cb5,6271f1ff,2f0d705c) Z8(210aa18c,e7f3f0c8,00576a7b,93d4d3c7,2346ed7e,bb383117,6f98d013,406dffcc) Z8(ac260a05,2463f8ca,6e3586a5,424feacc,23f7579a,d2e12243,15dea851,28d36193) Z8(6e639257,efcc04fe,42b682e6,469bdc74,f75b1f81,4f9a092e,056c1963,3f873bc7) Z8(88a1d754,1a746c8b,de923d79,e9a4374d,f3975953,677e7856,3778c00e,c2867aab) Z8(9620c351,0c469a40,32b77b44,0538c5b9,bc112701,92cbdf38,7dd17c14,3ab47239) Z8(7b89aabf,1d697eb0,fe38dbc0,7f73d127,3e584998,b8d9870e,600afc71,551b07c6) Z8(607ea1db,3173312e,f64eea82,e092cba8,b55ba15a,b4f1ab11,900a0b45,a9a2e09e) Z8(284574d6,93caeb7a,3675bcb0,832cfd8b,92038956,5f00ce16,e7baf9b1,0475fdfa) },{ Z8(5ef647c0,fcfdd376,bf892459,43109ea0,fe30f79d,5cf5833c,2d2e5e3b,ac03041b) Z8(1dd2b9fb,4651278e,9c09bc51,c7aa405b,90e43af8,fa19926e,dc3e52a6,af6b454d) Z8(647391f2,38d49352,b6c2cff6,fd2c3a86,f85957c3,0477cca0,f60e0a54,a9e9a8c9) Z8(7eb70030,c989981e,e8d66d44,51292ef8,6750d65b,6f657686,3b90bc8b,fd7f3828) Z8(8865e982,ac90effa,2b87f6eb,41984774,7e23a16e,56a97f6b,44c33e2f,4e82224d) Z8(2dc9a40f,05c3730d,a9d063ab,1a433dc6,7369fc64,af6e68f1,969f56ed,96f60bd9) Z8(b264d59e,e3d5b8d9,a4a76ccd,e629f53a,e0f5701f,5139a7fb,6a9abb26,0212b3ca) Z8(b4511588,ff35e5a3,cbba05a3,a3f627c3,3d7a3f56,621e37ca,ad8e0c00,caee789b) Z8(8d6875ad,7fcd1896,94cbf398,501fef80,d889fbcb,a8422a47,b6070b25,086de5a3) Z8(8af9569f,4bf97366,3cd7791e,b8a70402,496c2e77,7b55c380,7b3b2bb3,703ffc52) Z8(a88f45ed,e7240f1f,7b3f396a,4b0396c9,43919489,53d066d4,8726112d,eb7767c8) Z8(5a48a76b,81faf156,06cb8b9f,4791b794,05d56c93,26aef6dc,65e54c2f,341b07e8) Z8(c0b4c04a,4a4ba8fb,0d820f5d,f86e26a3,b6599623,97ecbc9a,7beecfaa,1950a2ff) Z8(943240eb,0d4d54a6,8a69ca74,5ff52cab,67e3bfc7,843919c6,8c55fc71,174ec48d) Z8(ce7b2024,0a853218,c8d27531,e7fc7f2f,2bd0cf0f,4b8d1c7b,2def3291,b32fcf32) Z8(117fe340,a1d2638c,9ffb5db2,5c69ffb5,ae67236e,c54ae137,cc4d52dd,0959f4d6) Z8(45c6b56b,f257313e,b1d53f87,61373d54,15110193,03613a61,07a331bf,c4863a34) Z8(b2039012,848c59a8,49625011,7c82df98,7cc22aba,341706c3,ed55f0bb,04b4db3b) },{ Z8(da572f0e,4d13621c,0df25a34,deb6adfa,aef523d6,c7e8339e,b7b5a16d,ffecd55a) Z8(8f237bc1,90c186ff,b3a9e548,b0b6d340,10554732,0e670121,2848e9d5,2a2ea741) Z8(283469fa,841871de,7a47fa3d,66c00f27,01629c6b,0d9230cf,479fff97,ded87a3b) Z8(a77b84ae,090db65f,0de4a117,cd42a53b,4e267a96,cf3180eb,a9b88708,1404ce24) Z8(6dab659d,cc82ba27,3daab0bf,4bf045c2,88b1eb48,112d6006,79d10a96,6ef913c7) Z8(65acbe07,bd2a823c,928bd0f7,0546e34c,4a1b8ffc,26f7517e,2803bd1d,0ac1b41a) Z8(bde87922,c84469de,5adbfd36,623f9545,f476644a,545bf5ac,7496442b,abccda54) Z8(5d6a1152,c893bde7,83d4e2e0,7c605fbe,d4fa45a6,6e3769f1,cac10a7e,82e1ea9f) Z8(39d2cecd,9ff0f2d3,8be8d141,ee150b19,a467bcef,86563637,e7b12c0a,16572af8) Z8(c4ec451f,5800bb8c,805a5703,40f171b5,6957541c,70e1884c,296634d7,f32f47a7) Z8(3411b441,2f442b08,a19677b5,1812b213,ee4d8dbb,83321168,fba3e620,8d7fc122) Z8(0b17cac6,bcb66043,dcfbebdf,a9207bdb,97119fdd,b2efc69a,f2c8ae68,bb522ad0) Z8(b63ebb20,e3f4c54e,693379f8,833468ae,bf70c1eb,b138f390,d072f279,59d715d2) Z8(788aef61,d35ee6e8,0a477f1d,98c02bae,d16be46e,f4329ffa,ccb5519b,47b9924f) Z8(8f431474,c47d6abd,12f3f20c,e51848f0,2d195252,70f6e746,af702c79,5b254a6b) Z8(eaef29c7,ef9e707b,4f578e93,052904d5,65414c9a,ac56c268,cd7cf686,8569de73) Z8(eda782f5,dc378bd2,071a1b2d,5553f465,2dc0b3cc,d22e50ca,49277dd9,8a09c0da) Z8(d75476af,933d8902,2677fdbb,83cb8c4d,31790cc6,cd295bf5,d1a95d3b,04f3a910) },{ Z8(8be26c30,4c004b16,60885b96,0cf6bcff,0f4ca146,6a08cd58,4fcdb0aa,933455b7) Z8(4048af18,89d3bc4e,d4307de9,97efa699,caf52d59,b6b5a0dc,8200ad2c,f5d64fa3) Z8(22d48a7b,7bff4b75,f0f4453c,834588a3,133e932e,c7d030e7,57b0a19d,9a95887e) Z8(b0718949,2b7f1660,5eb5d793,d4e19958,53488579,c395f336,71e22dd3,16fafed2) Z8(b1b4e81a,96cb8366,982e77a3,3047a715,602b3d4b,4d28cc14,81a2bd3d,6b6ff906) Z8(3323af07,3952fd0a,043561e6,42005c02,a0dfed4e,80f63d1d,61c756fd,0ad12863) Z8(0d2e735c,0afb0a8f,21fceeab,6d921b1b,3d02d9b9,04ce0734,8b272f79,6d3057da) Z8(5c19fff3,fc1cb332,c999460e,996c0b38,3d6a57ee,3a3df021,39fe54d1,50ed1840) Z8(27f193fb,d6b7a1a9,0c645c96,9eecd4d4,5137e90e,b4f625af,b1eacc4c,d8887af5) Z8(4337cf9c,ca0b141e,3f7d5c72,a4119b7b,9913b724,a5de421c,54dd8c97,c5af7177) Z8(c703b51a,cdc0482e,bf1b21be,ef0f9df2,7acf6b50,08d20648,496fc10b,027caea5) Z8(3d6ed003,a897ad97,d4edc1ec,d52365df,f76e78a9,e269daf5,507d6954,672336da) Z8(eda647d2,666c3a78,70ffea84,0f6b01e0,525dd74e,52bd92cd,1925e3d5,d8be71ba) Z8(81c3ec8a,74c8764f,f35e94eb,bc3c9244,bda4a2fb,081e5f48,b032eab8,315463f9) Z8(4c0a2cd3,9e63f71b,65ba4eed,1503c819,0935dee5,6c78066f,f8f0aa85,e8b2362e) Z8(b1eb8f50,3164ebac,7ba6852f,76eba6b9,b809e8b2,85c8787b,2563496c,305b87dc) Z8(50ac3ed2,7fe25aa9,2b1039f0,5d6119b9,add46a1c,23d48657,cccd0089,56a73e48) Z8(5bb0f2d1,5d7fd0cd,a84d2af2,ce9c3f63,2f94d43a,977d7d29,24077b31,05326781) },{ Z8(fa9e1452,a2ec69b7,5bae3f9c,61ec7219,eb482bd9,8b64adf1,28a84723,bf892b3e) Z8(b6456d75,39759602,3e15c2b8,6ee073da,e8e930ac,15302fa0,13040f46,d97158b3) Z8(ec63dc7d,db395529,8350aec0,094c3256,86625f5b,3edb45c8,cdb1fcca,24008f01) Z8(3e3607ce,357795ae,09ec481c,855b610b,69fad719,4a2064e6,b5059bfc,7770e7a0) Z8(61b2f8f0,79787e04,16954afb,1a574fb2,15e478b5,cfea48de,74a77122,5e123088) Z8(e8a676e9,0a5d0e3c,b54e1ae6,22453cc7,d813363c,c68479f4,00d7ebe5,2c8a7abf) Z8(e0491fef,0b6bc8d9,0a2f4ded,83df8077,c08318dc,e0ef32ee,c1aaee4f,eac99e23) Z8(8b956bd3,f1bc4f9e,cdb2b826,bcbab5ed,ec44b91d,8e9ea535,2e9e5952,b9c6d046) Z8(950488cb,e2d74fa4,fa19545b,ee093e24,55828f38,9a2a123c,8aadae82,e5b08040) Z8(70555df2,06b5c5f6,2250151a,91e9ca97,0762d616,353ef9f7,13323d2d,dc8fee96) Z8(ab1c12d0,c8a798b8,27476727,f3c1d8a1,53858ad7,85778366,a8d83a9a,48198e29) Z8(29a55592,996d76d4,cad3935d,f3ed080a,40e2c534,07fa59a9,5233dc3d,ad30be9a) Z8(9f5a5dd3,0aac91ac,8846c278,7b2fa6ae,b0b1d941,462f0be2,52c7eb05,66a64409) Z8(be777821,5f6b3e5e,9333aafc,5168bfa7,36f15cfa,f2e417fa,43e13869,8880c50c) Z8(bf0180cc,2bed8cd5,abfe3a42,7dbc997d,008d5777,2605ed1f,aaf95e32,7c39f30c) Z8(1f6c0f1b,6ca3476d,eb2146bb,b58a3edc,74632ab4,b2265f98,88dda7ea,6d713b17) Z8(dce9c5af,765b8ffa,511e98db,6c1c5d87,3cba5864,315c9ec0,b228bcac,d667ed58) Z8(14f71a2e,1c790cd7,457d1ef0,955d55e7,de4c2c17,ef493c13,6e34e224,05711694) },{ Z8(bb56b016,2e4d0c17,bf87ec44,3b1fdaa7,d843b80a,39ae3e1b,0f5bcec9,5bd542ee) Z8(0f73888a,8b197062,f39470b6,d8d3b857,a9916e98,2c4cb001,a22ad515,7c7c4a8f) Z8(3cab01c8,7b443457,9caefa58,4c75e32a,65d7722b,69fceead,6883d841,d7c8409e) Z8(7c08dfd4,53152375,a9591fdf,fd046cf4,25377ec7,0577e21b,e8beefdd,a20b5531) Z8(693267e9,f578765a,afe4c7eb,35e2eef6,befa438e,194b7633,0ab81da6,38ffcedc) Z8(840a9b18,9de6c8a6,ee256108,0f1860c6,968dd4d7,f9cf11bc,9e6f9c3b,76ff832e) Z8(e40fe013,4be1afdc,2a330703,6615d6b9,5403f219,0c69e0f1,ec8fb9be,36f28bc8) Z8(52284db7,afc84dfd,a6ecb2bf,ebcf0236,8d4c91ff,0d02cec6,97a06e64,e443afc5) Z8(7dfe214d,28628961,8950870c,10e2b3d1,883738ae,9c29ec42,4beea27b,ceb49a47) Z8(e173dd5c,d5f03d21,1e0a521c,f78abad6,e75305f7,cb16f34d,02f60518,126a150f) Z8(24d1e4e7,702bc5d2,91012da5,996c265a,4a551b2c,acdde710,9dcbb952,0e6a42df) Z8(633f1f85,218dcf42,a96188c8,5ba9d7d5,caf0d5d2,fbee344e,314e23a1,78bb26dd) Z8(6f0b58fb,08b90ec3,740a0c78,d81caa9b,1a38123d,3bce3da6,10667756,b85f69ee) Z8(72cc8751,e00ec18a,5fc7c44c,86089367,412f6321,e8deb2ff,cbd4949c,cd0cec78) Z8(67a9d380,c9b9ee65,bb339aa3,7e0c53a5,5141998e,8a04daee,18d0bcb7,9d12f2a3) Z8(f7d04569,1b638930,e84361f0,1614c07b,a1953880,b4108203,cb370351,7756a89b) Z8(d495d718,aa0f4ec8,ca0383c3,466f70d5,96e04600,a1dad4c7,e195df49,b3cba022) Z8(d99a1cfd,62dffef7,e17cbe0a,01f661af,6487d494,e9f5bc08,346df43b,05afb652) },{ Z8(4721c8a6,bbf66cd8,276a339e,5bd99769,e95d05a3,7afd5c57,fc6a1571,bd932e24) Z8(a65dd006,e3f44b06,abdc0309,16eabdf9,31206e04,36cfef33,4c050db7,18e10476) Z8(776b5cf9,e7a8dce7,97784e81,89ffd7d9,44389b74,e93f218c,51b14ac6,9ea14aa5) Z8(ed5f987b,46f09437,d742c766,3d7595cd,4c4fd33b,e4d2e4a9,b1a95d26,744b0159) Z8(a3898580,64f38012,674f5774,715750d4,3ac64985,4830c525,0485187f,31311473) Z8(7dfd0baf,10cd59a1,79810105,eb13755a,4d7afff2,ae16aa4f,c8a54cf0,41daedf1) Z8(806fcfbf,f86a2fe4,80c57d80,6196b728,adf47418,56a58176,8eded60a,ead91ce1) Z8(10d7da19,b56d1395,3942acfb,2f2ccbf1,efd45b86,0355a4f5,efe82f51,cdbeb1cd) Z8(807e86f3,bfdd1f34,0b271746,6bfaa2a3,3dc12483,1789a3ae,a8f5654d,a8cea408) Z8(ad59430d,609f446e,db96ec1f,09fd449b,00d18a96,94b1ceba,9c9589b4,8f876a3f) Z8(10a609f0,9b47fc64,b7c15d80,3c1806ec,b8a331cb,c62baedd,3d6308da,d997c68f) Z8(acf4fefa,b10554f3,155fbbe5,469dad29,802da824,43f84d19,f6869fe5,f5185580) Z8(7c204da8,ad26a9dc,53141562,13d6010e,620bfe87,68eacd59,7aac09a3,fa8b1481) Z8(e5b5a387,7fb0a7fa,58aaa5ea,a3ae6a7a,e76f60bf,042c672c,4c044aab,74f0b9aa) Z8(9890e6f1,183ea7a0,c45bf738,4159d14a,9813a0aa,927fd911,47e7951a,09abdca6) Z8(ecb2a27c,4836b43e,cf1fa379,1f9c224f,81c5bfcb,bccb8a12,ff26439e,1c64fa78) Z8(31e125ae,9bb5ffe0,140b9e2f,086d1607,45ddab78,67ded6c5,0efcad2b,d0f00eba) Z8(3a835116,96efb673,87466226,53c40a94,5af00773,49fd531c,f56c46aa,05ee46c1) },{ Z8(0e1ef5f4,0c0aba65,67d93493,c63d4fab,ec4f7edf,2e5285ee,a51fd253,8709d080) Z8(9e9da774,3f44fbbf,b86f7a37,44eab559,a39ef21f,1ef78815,eb155652,b6529cfd) Z8(a0742b6c,97fd08c8,459006de,5258e61e,042055ad,baae4f16,498efded,1016a8e2) Z8(89b968bd,5a6acebb,53485137,26addc62,0c8fd308,30eabf4e,8ea1d3ae,0190bcb2) Z8(0d4a5452,39d6218e,eaad6bec,fc5c0c1f,e98b71f5,07378fd9,5c914b68,2a6cf9fe) Z8(dcbc06a2,c3274877,99e9312c,5cde7527,539cfc0d,b781f2f0,f0b55398,760a7367) Z8(22357cb1,99b8f71e,9e5d7cdb,420f4812,dea6bbf3,faaad2ec,e3db1fdf,b162c28d) Z8(21c08cb5,fa52c599,724a7165,2f7ccef6,7fa6fdcf,d0ef31e0,38d21af6,28c27984) Z8(910ae92e,6bfbde01,cbcdbc01,87865c93,c9c0020c,1ab25081,52a8fced,595c515c) Z8(8c5c129d,20098635,bf5f97f0,898bb3c9,dc73723e,0af3ef92,f5a04a55,ba5549c2) Z8(882ecf38,d35ddf2a,ee2ceca8,e34b10ea,a7d18a91,310952cd,34af382c,ecb7c0e7) Z8(48e3cdb2,9436da17,01258875,6fe792bb,416faf07,c4fc9a30,058875e4,a8e7074b) Z8(7dc919b8,3f16ec2a,9ae9301e,564813ef,14a230e4,994da409,e2fcfaef,9e8d705f) Z8(26651e77,553c7ca9,56ea8d7c,e71764a7,0a999f86,3d71ed6c,f8d64db6,ff163382) Z8(3f26a731,658e9d44,b7ef25d7,0d38bca0,529b1a45,33bc9870,a10b5eab,8b4c7a5e) Z8(9fb0992a,d394879e,4a401d1a,9dac6a3a,643eaf4d,00a0fba4,51cf017f,4dd885d6) Z8(43f64265,a2d2d612,891af42e,14f91c4e,f83011bf,86b83575,3a33f6ad,ef686497) Z8(05e8bbe3,9132368c,4f979df5,a323f16f,d9dc732f,5691b69b,2a6c0387,062cc7eb) },{ Z8(aff37aaa,ca22d17d,4da8a7dc,06ca16ac,18d97957,897d2237,9e16f513,70604f05) Z8(7892dd29,a18a921e,688a6505,5bf19fdb,ff32b7ad,5fdc36d8,af84f790,05400a4f) Z8(fd39bc6f,00537c46,e5857707,1974243a,c625ad0e,51d64cce,f781cc06,bcc2a01e) Z8(27184414,9b2e6902,5ec5fa7a,50389bfa,3a62887e,eff33f3b,08bbe855,9e3d41b0) Z8(9aaab2d4,99c70370,fbc0cba5,0c65899e,d583dd2f,f8dde639,41bcad87,a3a066a9) Z8(49ca08ec,f3ec5739,f29bdc83,1a86ee24,2e5b6dd5,fa1c0a5d,5d3662a2,55ab19a3) Z8(1f9261a5,c3d6c550,1a29383d,8fa22d02,0abc3e6b,bdc2e674,74ce1388,9a8f1f0a) Z8(75ea6f30,7d12d69d,eb83e0da,b73b688a,b478221f,b0e76847,69a90e22,dfa28bb4) Z8(40ef61cd,cebef295,fd6b484f,5516d1ee,6e0e652b,d2e0a89d,90307856,30840193) Z8(6e0f1f03,09102b76,a1f27343,1d3b9d44,01fa09ea,feb7f9b1,bf8c889b,6f75f2f1) Z8(c5d8a2eb,2533f14d,985b9946,0fd766e5,4ab40c7f,d4cb8f02,49691c4c,e25f52c6) Z8(5b2d6f37,7aa0e898,0b6eb814,35d83a63,bcf59086,6ecd5229,28163efc,c13cbfd1) Z8(c83be49a,d7171a1d,51166345,78189cb4,9c900043,3629f968,8f9716ed,5a43826a) Z8(52004870,8a6a5ba8,39b704e3,1dc8ab8c,ce2ded5c,2be4f5f2,03027334,1533ae0e) Z8(60726c2e,1dba8cce,f46efa7e,4e1e33b0,ef9e598f,0fcf9351,637bb8d6,5b489633) Z8(c361e640,3c4b581b,70897f78,57284fad,69fb25d8,d595cc98,866d25b9,a27b6488) Z8(b37d5147,9908a950,39199fe3,6c87ac32,a274470f,98312fbd,6816dfeb,a504038d) Z8(d368a378,1b9e2cc8,ecdcc26a,54559665,167f14bb,409c1df8,47314513,066b39d5) },{ Z8(be0038dc,751b788b,0f9b7ffb,5b212afa,e0dbbbfc,34055ddd,c744fed5,861dae00) Z8(9fdd99c7,23ec8f66,4f99a141,459f0bac,afb868e5,21164c56,875142c9,74c00e30) Z8(e55b3321,b498bee5,20cbf9da,f0fcc957,ebd3e5cd,74e3fbcc,ade1ec4e,1c147958) Z8(de7f92ce,4e47f81e,0464ed12,d3ab8fe9,54f8cb75,ac21695a,368ba5aa,fc8cbaa4) Z8(19f98fa1,33c328e4,c8b5ed66,44657b62,43a40d4c,15e7f696,927f6b48,889ee15c) Z8(dfc9bb83,700ba2e4,5e82449f,57b8d6d4,1f1d430e,20813840,b0cb006f,ae0e3190) Z8(6b09552f,9b454a69,5bba59fe,59ee3258,e49225ee,bc9db60c,e11c3c9c,a11178d9) Z8(f76764ba,f7eeac1f,44c9cd40,35cb7eb3,c1b63658,89cfc036,3655e9f7,75d45cf8) Z8(40c7c293,20ecf925,8125642b,7845fc46,9db66dba,517711d0,6fe7f6b0,84f07d08) Z8(b424e99f,0c68d4ba,077ca960,88cdd408,eaeadad9,f8297ff9,3b6fefe0,711e41c0) Z8(2d5613cb,b4e20646,99778a7a,e7d727b4,a515882f,c54a1deb,a4d86ddc,8b61e520) Z8(7c54d151,4b3185c5,29cc184d,887715b7,fad5f7fe,3801b492,682729c8,32ea1363) Z8(d7406399,41e36217,74ef24fb,6adab348,e6f73660,c2a3e433,06275791,6b7cab2e) Z8(f06d1db1,78328c7b,c3a484e9,d724439e,2bd848aa,ede51de8,626db81a,c10e16f3) Z8(620fc557,e23769c5,af2d036b,b64cc638,0eba2743,9dcf5fd2,4325d4ec,40396b90) Z8(cb957a24,8164341e,662a5fe8,131af729,6d18da1d,ed836767,27d8dc31,dd64c2d2) Z8(9b429d9c,786747f0,1396e6e3,e032ce67,d10bc015,8f6de378,70ab5436,fda21c12) Z8(02988981,68e15d73,9c1314e2,d6bd36cf,d4ef6fbf,ae2d7a49,ba0d6a75,06a99c87) },{ Z8(70e8ea8c,615b856a,688b0b51,aab0458c,1d8d5b8f,54bba7ea,7e5e6b1d,cd2645c5) Z8(a201d318,66569a3c,dc86f805,d5fd5231,a59b1c27,d25d68c8,f411d831,7243dca7) Z8(affe4e9d,df89dc17,ec7570ab,96b48fc5,40389ff8,dbfb5cf4,ab14f32c,5157858f) Z8(941abbe3,ad754a1f,71591a1b,663ee34c,adb3b00a,73fd77ba,e0e5f7a5,d6715d5b) Z8(b708713d,a7a36eb1,b948a28b,86fe44d5,9dca3afa,8b711078,c471a2df,8dc5e53d) Z8(cc94533c,7286a2d7,4f17dd96,7f2067b3,2d808d46,98f476e6,085e52c1,47174c02) Z8(46e3416a,c35283b4,3e3bfbb4,d6715062,e2b72d91,563cb459,61ddaf82,04ca691b) Z8(2649807f,17772207,d3802e0a,7b1bed44,3da0b93d,3935c92c,c89743a9,abcba6d9) Z8(82d8c444,da4a2e8a,ca795fd9,a44e1a87,605af533,69c2aabc,a7771b80,5495df4f) Z8(e05cafa7,611a34f6,a16fb648,13571d21,82109b58,0b2c6b27,289bdd1d,6382d9a5) Z8(5d319990,e8be03e0,8f23a207,d108636d,98987bec,5aa0ed21,a95b32d1,f245bec7) Z8(485d8ef2,513e6cf6,23c8524c,52012516,85776eb7,13473f66,10a6e3c3,d044b30b) Z8(a70b9e7d,caeb7a04,679514bb,dd02b650,9e281815,6424a799,cadda2ae,2c7d0d54) Z8(00526fbf,1742bb5a,d68e13db,60055d20,f7d23fc5,1ca1abf8,b5326ead,2fcb76d9) Z8(b65341bf,b20a9a64,5f8b6449,f947d48e,4413aa3f,19b92876,75e6680f,3bd10a84) Z8(0869f15b,c009e034,9bd626e6,b54a70e4,c7f749da,20251a75,2e5db2b7,cc60184a) Z8(42ea37c9,ab1818bf,7219242b,a6bcc014,59343416,84d1855b,d32356b1,0ad8aaae) Z8(722da717,5890e9ad,14dcddcc,f6d4cc7d,2379867f,f5196dd6,ebe465fe,06e7f009) },{ Z8(01a4d3f0,057edd94,a9b2d735,ac94998f,3b24145b,d5139c86,ed6b2387,a523abd6) Z8(f2415e58,c95cc4e5,479af7ef,adcaa6f9,d7966ad4,f58e4457,941be2fe,a90b34ec) Z8(c71d0e53,bc334f28,582ec1a2,f6debe88,a58f7f00,9e6493cd,7d27fc27,ef71c7cb) Z8(de33bbc1,a54b7a8c,9fafa3d3,52a4a277,80a735e1,44fd5769,ba66b4aa,d0a041db) Z8(b16ec7cf,c58eb4d2,dccde30d,69781915,6667e692,d77f7803,cd357d1c,a2827258) Z8(918f24e4,d2fabaea,48bf74ef,12e6628d,221ffe31,51e6a4d0,5c6b9c7d,24e6c7d6) Z8(555a5dd6,aacdbce0,ee265e32,95a84f5a,de79ea30,5485931f,f08657a3,02cf092e) Z8(6ee55edc,191c0f35,76621d37,d53bba82,1aef01dc,cbc6aab6,672f8ecc,1bd52be2) Z8(3aaa2799,886b4161,d6dbf1c7,5e121ca8,e83e016c,b59e6ac3,7aff05bd,2254abec) Z8(c12defc8,77883600,5e632a3f,ef70b3e2,f8c682d6,92e52e07,e7bf0bdb,d00abd16) Z8(f398ccc9,80eda78c,9ff446b1,72fb8ccf,083af5db,9cf46081,0d05ec1c,e3b6b28a) Z8(70eabb2b,e06c2312,8e7ba3b9,114e0222,05e2174a,1a3d0ecc,0940bbe8,b1fc7712) Z8(93f1bb04,5503f52d,7bdba625,beb5550d,fd5ea10f,0339d65d,499715f7,9ba419ea) Z8(5b003297,590b64d7,2c509cf4,a8b7ee26,c1bb7e3a,5513a983,60b0ccca,9d8c3e75) Z8(741efc89,59ecf814,035e6c48,43f7c505,90f447cb,0bc4d957,3f10709a,916e59b3) Z8(8b66ae15,f7859b09,1d3e752d,e74ebebf,f79a6d44,6ab0f356,8abc4546,94208914) Z8(1fb53708,c0a4b18c,6e15e1b1,cad0c9c3,0b9f264e,878663a8,9844e710,14d25218) Z8(11756168,1a60f994,5c1c8434,963b4c9c,6d209101,7d3b1078,403204f5,07263463) },{ Z8(d575075b,b1bf895e,78fd94fb,79b4fc43,f4276543,e89c3e0b,104bdfaa,aa3519d2) Z8(834fbf89,a0ffd6ec,1c6b1d2f,606b52ab,45c52ecf,0d71e150,e432fbe5,428e1272) Z8(39b66eb9,b664efe3,71468977,b5b17fe6,d3c4ee69,eccd6884,90ee479f,4560fcc4) Z8(439d8e86,c3b30470,77d8871d,420bf9ee,3f5f203d,e3be9629,29ba0aab,3426c7cc) Z8(2dce18f3,0a027547,e193c5e6,f40f54b1,9f531ac4,52a68166,84d2c1d4,8af92b9e) Z8(2f428085,1c3b0114,8b53892d,72da518a,56abe013,076d5b2b,0fd8ad99,95595e86) Z8(66328621,92ed6e0d,2b45c6ef,3a01bd99,f91f2185,6df1aed3,67529e4a,de68c28b) Z8(cc74b470,a1c84162,14e85f09,9aa72160,e08110cd,0b224027,b28bca1c,d6476424) Z8(92cd7e50,247d9415,dba32570,eeaef994,fa6ed634,d55132cf,22a79d51,99ac3485) Z8(ae17f608,501ce93e,8cf1b4f4,b09e4791,61a987e3,da6aaf85,177024d8,b5491f43) Z8(50963782,5aea5cee,c459534a,a6dadd21,a387eea6,f136353a,9f6540e8,15059665) Z8(1dc6647a,6e41bbb4,d7fe2bda,9ececb92,62ded8ba,42302365,a05c719b,8a38da37) Z8(caef1492,e39f22c4,d4cba29a,9f473bc3,3520217f,bc76a14c,0ef6f273,6cc64971) Z8(593c8c4b,9ef237fc,8280a270,7cbd57db,cdee2b06,887a3da7,1d5bc6c5,a39df003) Z8(f43c4f35,39b1a417,7ea7115c,4111ca18,97fa4c19,eed3e8d0,4391fb5c,c64de291) Z8(5d9a5446,c3823d20,25310f76,0254bce6,89a0a329,c8a42948,8fcbd7ee,0bc27e8a) Z8(285c62b1,feea7834,fce882f9,68a22913,27abe10f,3e100040,aed28011,43cdf32b) Z8(35208971,8b00bde2,4f562287,62e61977,095529a8,b2c67dcd,150f30f8,0764699b) },{ Z8(62efed4a,55d9387e,8c14c622,8c591b98,21463246,d317fffb,8f7446d6,60a2476f) Z8(3f121620,6a0714c6,aa6efd2b,ef804980,226aa06b,6e670d15,85ed5130,24387392) Z8(f07e8607,c53088ef,2d173656,ac9137b0,bac63b66,537145d5,1122fd72,3c77d04c) Z8(b8f79cb0,7fa04398,ae00a8bc,3e9cea5d,78557d53,77742a8e,583acdc8,c3831771) Z8(c0186f48,d9e720cd,8187d24b,6e98d06b,f2b79f98,7b259256,6c3a8dfb,a9d5c488) Z8(587d5097,b8f34624,db93947b,b704b541,b105084e,4fd6257d,5f8d20c0,27b21e5f) Z8(c2a50d89,72efb36f,86f04428,2d787c2f,f4a8efa3,cf507845,747a7d69,029a22f9) Z8(d25a9931,8a785631,4c9ed692,aa7dc6e1,08cef331,1bb51ece,ed8aa4ba,2794a522) Z8(b67bff11,c515eb2e,afae91ac,a9b4c4dd,7798b9bc,fd09a602,9ceb2b26,de469963) Z8(bcedbceb,d908c4c5,5d01d3ad,5ce60c54,e4fb5689,4f07e9b1,72ca5e44,895eeaaa) Z8(8a5c7f50,0e370696,dccb0b50,4ae1431f,583d8943,8747770e,cf945c43,3e8770a4) Z8(6a05d1cf,6ee574c1,5cba0c6b,806ecba7,25c682f6,cc4da9e3,238b71f4,477c1c6d) Z8(a9c6160a,4c35ad28,0192c602,c0453095,9aa9efe2,45f82774,5acfc755,be1a90a3) Z8(fac4999f,840947cf,eef0e341,8e48c91d,82b60837,1cdf2664,80cf22ff,ab5874db) Z8(ab845e92,508f74a5,07f63095,4b573425,9a7a2074,bd351766,a8f73d53,0c41f64f) Z8(99facf27,e3de9df4,22b8d3ec,e2a022cd,5ea2d09c,26edce1c,494feb0d,d629cd56) Z8(630346e3,635144e2,378409fc,87012299,a556dc48,d48fc658,82a4441f,a8c1ebd6) Z8(f0a5b553,221ccad4,2d3e91ef,be0fe5f4,167294c9,e10d6380,c3372b02,07a28fb8) }}; arb-2.22.1/arb/log_ui_from_prev.c000066400000000000000000000060621417376376500166360ustar00rootroot00000000000000/* Copyright (C) 2013-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void bsplit(fmpz_t p1, fmpz_t q1, fmpz_t r1, const fmpz_t p, const fmpz_t q, slong a, slong b, int cont) { if (b - a == 1) { if (a == 0) { fmpz_set(p1, p); fmpz_mul_ui(q1, q, 2*a+1); fmpz_mul_ui(r1, p, 2*a+1); } else { fmpz_mul(p1, p, p); fmpz_mul(q1, q, q); fmpz_mul_ui(q1, q1, 2*a+1); fmpz_mul_ui(r1, p1, 2*a+1); } } else { fmpz_t p2, q2, r2; slong m; m = (a + b) / 2; fmpz_init(p2); fmpz_init(q2); fmpz_init(r2); bsplit(p1, q1, r1, p, q, a, m, 1); bsplit(p2, q2, r2, p, q, m, b, 1); fmpz_mul(p1, p1, q2); fmpz_addmul(p1, r1, p2); fmpz_mul(q1, q1, q2); if (cont) fmpz_mul(r1, r1, r2); fmpz_clear(p2); fmpz_clear(q2); fmpz_clear(r2); } } #define LOG2 0.69314718055994530942 /* Assumption: p/q <= 2 */ static void atanh_bs(arb_t s, ulong p, ulong q, slong prec) { fmpz_t pp, qq, P, Q, R; double logqp; slong N; if (p == 0) { arb_zero(s); return; } fmpz_init(pp); fmpz_init(qq); fmpz_init(P); fmpz_init(Q); fmpz_init(R); /* If N >= 1 and p/q <= 1/2, the error is bounded by (p/q)^(2N+1). For error <= 2^-prec, it is sufficient to pick N >= (1/2) * (prec * log(2) / log(q/p) - 1). */ logqp = mag_d_log_lower_bound(q / (double) p) * (1.0 - 1e-12); N = ceil((prec * (0.5 * LOG2) / logqp) * (1.0 + 1e-12)); N = FLINT_MAX(N, 1); fmpz_set_ui(pp, p); fmpz_set_ui(qq, q); bsplit(P, Q, R, pp, qq, 0, N, 0); arb_fmpz_div_fmpz(s, P, Q, prec); arb_add_error_2exp_si(s, -prec); fmpz_clear(pp); fmpz_clear(qq); fmpz_clear(P); fmpz_clear(Q); fmpz_clear(R); } static int n_width(ulong k) { int a, b; count_leading_zeros(a, k); count_trailing_zeros(b, k); return FLINT_BITS - a - b; } void arb_log_ui_from_prev(arb_t s, ulong k, arb_t log_prev, ulong prev, slong prec) { if (prev < 2 || prec < 600 || (prec < ARB_LOG_TAB2_PREC - 64 && n_width(k) <= ARB_LOG_TAB21_BITS + 1) || k < prev || (k + prev) < prev || (k - prev) >= 0.25 * (k + prev)) { arb_log_ui(s, k, prec); } else { arb_t t; ulong p, q; arb_init(t); p = k - prev; q = k + prev; if ((p % 2 == 0) && (q % 2 == 0)) { p >>= 1; q >>= 1; } atanh_bs(t, p, q, prec); arb_mul_2exp_si(t, t, 1); arb_add(s, log_prev, t, prec); arb_clear(t); } } arb-2.22.1/arb/max.c000066400000000000000000000022271417376376500140650ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_max(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_t left, right, t, xr, yr; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) { arb_indeterminate(z); return; } arf_init(left); arf_init(right); arf_init(t); arf_init_set_mag_shallow(xr, arb_radref(x)); arf_init_set_mag_shallow(yr, arb_radref(y)); arf_sub(left, arb_midref(x), xr, prec, ARF_RND_FLOOR); arf_sub(t, arb_midref(y), yr, prec, ARF_RND_FLOOR); arf_max(left, left, t); arf_add(right, arb_midref(x), xr, prec, ARF_RND_CEIL); arf_add(t, arb_midref(y), yr, prec, ARF_RND_CEIL); arf_max(right, right, t); arb_set_interval_arf(z, left, right, prec); arf_clear(left); arf_clear(right); arf_clear(t); } arb-2.22.1/arb/min.c000066400000000000000000000022271417376376500140630ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_min(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_t left, right, t, xr, yr; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) { arb_indeterminate(z); return; } arf_init(left); arf_init(right); arf_init(t); arf_init_set_mag_shallow(xr, arb_radref(x)); arf_init_set_mag_shallow(yr, arb_radref(y)); arf_sub(left, arb_midref(x), xr, prec, ARF_RND_FLOOR); arf_sub(t, arb_midref(y), yr, prec, ARF_RND_FLOOR); arf_min(left, left, t); arf_add(right, arb_midref(x), xr, prec, ARF_RND_CEIL); arf_add(t, arb_midref(y), yr, prec, ARF_RND_CEIL); arf_min(right, right, t); arb_set_interval_arf(z, left, right, prec); arf_clear(left); arf_clear(right); arf_clear(t); } arb-2.22.1/arb/mul.c000066400000000000000000000070231417376376500140740ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_mul_arf(arb_t z, const arb_t x, const arf_t y, slong prec) { mag_t zr, ym; int inexact; if (arb_is_exact(x)) { inexact = arf_mul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); else mag_zero(arb_radref(z)); } else if (ARB_IS_LAGOM(x) && ARF_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(ym, y); mag_init(zr); mag_fast_mul(zr, ym, arb_radref(x)); inexact = arf_mul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_fast_add_ulp(zr, zr, arb_midref(z), prec); *arb_radref(z) = *zr; } else { mag_init_set_arf(ym, y); mag_init(zr); mag_mul(zr, ym, arb_radref(x)); inexact = arf_mul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_swap(arb_radref(z), zr); mag_clear(ym); mag_clear(zr); } } void arb_mul(arb_t z, const arb_t x, const arb_t y, slong prec) { mag_t zr, xm, ym; int inexact; if (arb_is_exact(x)) { arb_mul_arf(z, y, arb_midref(x), prec); } else if (arb_is_exact(y)) { arb_mul_arf(z, x, arb_midref(y), prec); } else if (ARB_IS_LAGOM(x) && ARB_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(xm, arb_midref(x)); mag_fast_init_set_arf(ym, arb_midref(y)); mag_init(zr); mag_fast_mul(zr, xm, arb_radref(y)); mag_fast_addmul(zr, ym, arb_radref(x)); mag_fast_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_mul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); if (inexact) arf_mag_fast_add_ulp(zr, zr, arb_midref(z), prec); *arb_radref(z) = *zr; } else { mag_init_set_arf(xm, arb_midref(x)); mag_init_set_arf(ym, arb_midref(y)); mag_init(zr); mag_mul(zr, xm, arb_radref(y)); mag_addmul(zr, ym, arb_radref(x)); mag_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_mul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_swap(arb_radref(z), zr); mag_clear(xm); mag_clear(ym); mag_clear(zr); } } void arb_mul_si(arb_t z, const arb_t x, slong y, slong prec) { arf_t t; arf_init_set_si(t, y); /* no need to free */ arb_mul_arf(z, x, t, prec); } void arb_mul_ui(arb_t z, const arb_t x, ulong y, slong prec) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ arb_mul_arf(z, x, t, prec); } void arb_mul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) { arf_t t; if (!COEFF_IS_MPZ(*y)) { arf_init_set_si(t, *y); /* no need to free */ arb_mul_arf(z, x, t, prec); } else { arf_init(t); arf_set_fmpz(t, y); arb_mul_arf(z, x, t, prec); arf_clear(t); } } arb-2.22.1/arb/mul_2exp_si.c000066400000000000000000000017571417376376500155350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* mag_mul_2exp_si is non-inline, but avoid overhead here */ static __inline__ void _mag_mul_2exp_si(mag_t z, const mag_t x, slong y) { if (mag_is_special(x)) { mag_set(z, x); } else { if (y >= ADD2_FAST_MIN && y <= ADD2_FAST_MAX) _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(x), y); else fmpz_add_si(MAG_EXPREF(z), MAG_EXPREF(x), y); MAG_MAN(z) = MAG_MAN(x); } } void arb_mul_2exp_si(arb_t y, const arb_t x, slong e) { arf_mul_2exp_si(arb_midref(y), arb_midref(x), e); _mag_mul_2exp_si(arb_radref(y), arb_radref(x), e); } arb-2.22.1/arb/neg.c000066400000000000000000000010151417376376500140430ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_neg(arb_t y, const arb_t x) { arf_neg(arb_midref(y), arb_midref(x)); mag_set(arb_radref(y), arb_radref(x)); } arb-2.22.1/arb/neg_round.c000066400000000000000000000007741417376376500152650ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_neg_round(arb_t x, const arb_t y, slong prec) { arb_set_round(x, y, prec); arb_neg(x, x); } arb-2.22.1/arb/nonnegative_part.c000066400000000000000000000022771417376376500166500ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_nonnegative_part(arb_t res, const arb_t x) { if (!arb_contains_negative(x)) { arb_set(res, x); } else if (!arb_is_finite(x)) { arb_indeterminate(res); } else { arf_t t; arf_init(t); arf_set_mag(t, arb_radref(x)); arf_add(arb_midref(res), arb_midref(x), t, MAG_BITS, ARF_RND_CEIL); if (arf_sgn(arb_midref(res)) <= 0) { arf_zero(arb_midref(res)); mag_zero(arb_radref(res)); } else { arf_mul_2exp_si(arb_midref(res), arb_midref(res), -1); arf_get_mag(arb_radref(res), arb_midref(res)); /* needed since arf_get_mag is inexact */ arf_set_mag(arb_midref(res), arb_radref(res)); } arf_clear(t); } } arb-2.22.1/arb/one.c000066400000000000000000000007421417376376500140610ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_one(arb_t f) { arf_one(arb_midref(f)); mag_zero(arb_radref(f)); } arb-2.22.1/arb/overlaps.c000066400000000000000000000023001417376376500151230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_overlaps(const arb_t x, const arb_t y) { arf_t t; arf_struct u[4]; int result; if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) return 1; if (arf_equal(arb_midref(x), arb_midref(y))) return 1; arf_init(t); /* |xm - ym| <= xr + yr */ if (arf_cmp(arb_midref(x), arb_midref(y)) >= 0) { arf_init_set_shallow(u + 0, arb_midref(x)); arf_init_neg_shallow(u + 1, arb_midref(y)); } else { arf_init_neg_shallow(u + 0, arb_midref(x)); arf_init_set_shallow(u + 1, arb_midref(y)); } arf_init_neg_mag_shallow(u + 2, arb_radref(x)); arf_init_neg_mag_shallow(u + 3, arb_radref(y)); arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN); result = arf_sgn(t) <= 0; arf_clear(t); return result; } arb-2.22.1/arb/partitions_fmpz.c000066400000000000000000000034741417376376500165350ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "partitions.h" /* defined in flint*/ FLINT_DLL extern const unsigned int partitions_lookup[128]; /* we get log2(p(n))/2 bits with the leading term */ static int use_exact(const fmpz_t n, slong prec) { if (fmpz_size(n) >= 3) return 0; return (prec + 20.0) * (prec + 20.0) > 3.42 * fmpz_get_d(n); } void arb_partitions_fmpz(arb_t res, const fmpz_t n, slong prec) { if (fmpz_cmp_ui(n, 128) < 0) { arb_set_ui(res, fmpz_sgn(n) >= 0 ? partitions_lookup[*n] : 0); arb_set_round(res, res, prec); } else if (use_exact(n, prec)) { fmpz_t t; fmpz_init(t); partitions_fmpz_fmpz(t, n, 0); arb_set_round_fmpz(res, t, prec); fmpz_clear(t); } else { mag_t err; mag_init(err); partitions_leading_fmpz(res, n, prec + 10); /* n >= 128; it is easy to check that the error is bounded by the square root of the leading approximation */ arb_get_mag(err, res); mag_sqrt(err, err); arb_add_error_mag(res, err); arb_set_round(res, res, prec); mag_clear(err); } } void arb_partitions_ui(arb_t res, ulong n, slong prec) { if (n < 128) { arb_set_ui(res, partitions_lookup[n]); arb_set_round(res, res, prec); } else { fmpz_t t; fmpz_init_set_ui(t, n); arb_partitions_fmpz(res, t, prec); fmpz_clear(t); } } arb-2.22.1/arb/polylog.c000066400000000000000000000017771417376376500147760ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "acb.h" int polylog_is_real(const acb_t s, const acb_t z); void arb_polylog(arb_t w, const arb_t s, const arb_t z, slong prec) { acb_t ss, zz; acb_init(ss); acb_init(zz); acb_set_arb(ss, s); acb_set_arb(zz, z); if (polylog_is_real(ss, zz)) { acb_polylog(zz, ss, zz, prec); arb_set(w, acb_realref(zz)); } else { arb_indeterminate(w); } acb_clear(ss); acb_clear(zz); } void arb_polylog_si(arb_t w, slong s, const arb_t z, slong prec) { arb_t t; arb_init(t); arb_set_si(t, s); arb_polylog(w, t, z, prec); arb_clear(t); } arb-2.22.1/arb/pow.c000066400000000000000000000046561417376376500141150ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define BINEXP_LIMIT 64 void _arb_pow_exp(arb_t z, const arb_t x, int negx, const arb_t y, slong prec) { arb_t t; arb_init(t); if (negx) { arb_neg(t, x); arb_log(t, t, prec); } else arb_log(t, x, prec); arb_mul(t, t, y, prec); arb_exp(z, t, prec); arb_clear(t); } void arb_pow(arb_t z, const arb_t x, const arb_t y, slong prec) { if (arb_is_zero(y)) { arb_one(z); return; } if (arb_is_zero(x)) { if (arb_is_positive(y)) arb_zero(z); else arb_indeterminate(z); return; } if (arb_is_exact(y) && !arf_is_special(arb_midref(x))) { const arf_struct * ymid = arb_midref(y); /* small half-integer or integer */ if (arf_cmpabs_2exp_si(ymid, BINEXP_LIMIT) < 0 && arf_is_int_2exp_si(ymid, -1)) { fmpz_t e; fmpz_init(e); if (arf_is_int(ymid)) { arf_get_fmpz_fixed_si(e, ymid, 0); arb_pow_fmpz_binexp(z, x, e, prec); } else { arf_get_fmpz_fixed_si(e, ymid, -1); if (fmpz_sgn(e) >= 0) { arb_sqrt(z, x, prec + fmpz_bits(e)); arb_pow_fmpz_binexp(z, z, e, prec); } else { fmpz_neg(e, e); arb_rsqrt(z, x, prec + fmpz_bits(e)); arb_pow_fmpz_binexp(z, z, e, prec); } } fmpz_clear(e); return; } else if (arf_is_int(ymid) && arf_sgn(arb_midref(x)) < 0) { /* use (-x)^n = (-1)^n * x^n to avoid NaNs at least at high enough precision */ int odd = !arf_is_int_2exp_si(ymid, 1); _arb_pow_exp(z, x, 1, y, prec); if (odd) arb_neg(z, z); return; } } _arb_pow_exp(z, x, 0, y, prec); } arb-2.22.1/arb/pow_fmpq.c000066400000000000000000000022561417376376500151320ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_pow_fmpq(arb_t y, const arb_t x, const fmpq_t a, slong prec) { if (fmpz_is_one(fmpq_denref(a))) { arb_pow_fmpz(y, x, fmpq_numref(a), prec); } else { int use_exp; slong k = *fmpq_denref(a); if (k == 2 || k == 4) use_exp = 0; else if (k > 1 && k < 50) use_exp = prec < (WORD(1) << ((k / 8) + 8)); else use_exp = 1; if (use_exp) { arb_log(y, x, prec + 10); arb_mul_fmpz(y, y, fmpq_numref(a), prec + 10); arb_div_fmpz(y, y, fmpq_denref(a), prec + 10); arb_exp(y, y, prec); } else { arb_root_ui(y, x, k, prec); arb_pow_fmpz(y, y, fmpq_numref(a), prec); } } } arb-2.22.1/arb/pow_fmpz.c000066400000000000000000000012461417376376500151410ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_pow_fmpz(arb_t y, const arb_t b, const fmpz_t e, slong prec) { arb_pow_fmpz_binexp(y, b, e, prec); } void arb_pow_ui(arb_t y, const arb_t b, ulong e, slong prec) { fmpz_t f; fmpz_init_set_ui(f, e); arb_pow_fmpz(y, b, f, prec); fmpz_clear(f); } arb-2.22.1/arb/pow_fmpz_binexp.c000066400000000000000000000033201417376376500165010ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_pow_fmpz_binexp(arb_t y, const arb_t b, const fmpz_t e, slong prec) { slong i, wp, bits; if (-WORD(2) <= *e && *e <= WORD(2)) { if (*e == WORD(0)) arb_one(y); else if (*e == WORD(1)) arb_set_round(y, b, prec); else if (*e == -WORD(1)) arb_inv(y, b, prec); else if (*e == WORD(2)) arb_mul(y, b, b, prec); else { arb_inv(y, b, prec); arb_mul(y, y, y, prec); } return; } if (fmpz_sgn(e) < 0) { fmpz_t f; fmpz_init(f); fmpz_neg(f, e); if (arb_is_exact(b)) { arb_pow_fmpz_binexp(y, b, f, prec + 2); arb_inv(y, y, prec); } else { arb_inv(y, b, prec + fmpz_bits(e) + 2); arb_pow_fmpz_binexp(y, y, f, prec); } fmpz_clear(f); return; } if (y == b) { arb_t t; arb_init(t); arb_set(t, b); arb_pow_fmpz_binexp(y, t, e, prec); arb_clear(t); return; } arb_set(y, b); bits = fmpz_bits(e); wp = ARF_PREC_ADD(prec, bits); for (i = bits - 2; i >= 0; i--) { arb_mul(y, y, y, wp); if (fmpz_tstbit(e, i)) arb_mul(y, y, b, wp); } } arb-2.22.1/arb/power_sum_vec.c000066400000000000000000000027771417376376500161670ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "bernoulli.h" #include "arb_poly.h" /* todo: don't use exact bernoulli numbers for large len */ /* todo: output exact integers when precise enough */ void arb_power_sum_vec(arb_ptr res, const arb_t a, const arb_t b, slong len, slong prec) { arb_ptr t, u, v; slong k; if (len < 1) return; t = _arb_vec_init(len + 1); u = _arb_vec_init(len + 1); v = _arb_vec_init(len + 1); /* exp(ax), exp(bx) */ arb_set(t + 1, a); arb_set(u + 1, b); _arb_poly_exp_series(t, t, 2, len + 1, prec); _arb_poly_exp_series(u, u, 2, len + 1, prec); _arb_vec_sub(t, u, t, len + 1, prec); /* x/(exp(x)-1) */ BERNOULLI_ENSURE_CACHED(len + 1); for (k = 0; k <= len; k++) arb_set_fmpq(u + k, bernoulli_cache + k, prec); _arb_poly_borel_transform(u, u, len + 1, prec); _arb_poly_mullow(v, t, len + 1, u, len + 1, len + 1, prec); _arb_poly_inv_borel_transform(v, v, len + 1, prec); for (k = 0; k < len; k++) arb_div_ui(res + k, v + k + 1, k + 1, prec); _arb_vec_clear(t, len + 1); _arb_vec_clear(u, len + 1); _arb_vec_clear(v, len + 1); } arb-2.22.1/arb/primorial.c000066400000000000000000000075751417376376500153110ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define NUM_BASECASE 30 static int basecase(arb_t res, n_primes_t primes, ulong a, ulong b, ulong nmax, slong prec) { ulong n, p, pp; mp_limb_t prod[NUM_BASECASE]; mp_limb_t top; mp_size_t nlimbs; mp_limb_t hi, lo; int inexact, more; slong shift; nlimbs = 0; pp = 1; more = 1; for (n = a; n < b; n++) { p = n_primes_next(primes); if (p > nmax) { more = 0; break; } umul_ppmm(hi, lo, pp, p); if (hi != 0) { if (nlimbs == 0) { prod[0] = lo; prod[1] = hi; pp = 1; nlimbs = 2; } else { prod[nlimbs] = top = mpn_mul_1(prod, prod, nlimbs, pp); nlimbs += (top != 0); pp = p; } } else { pp = lo; } } if (nlimbs == 0) { arb_set_ui(res, pp); arb_set_round(res, res, prec); return more; } if (pp != 1) { prod[nlimbs] = top = mpn_mul_1(prod, prod, nlimbs, pp); nlimbs += (top != 0); } inexact = _arf_set_round_mpn(arb_midref(res), &shift, prod, nlimbs, 0, prec, ARB_RND); fmpz_set_si(ARF_EXPREF(arb_midref(res)), nlimbs * FLINT_BITS + shift); if (inexact) arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec); else mag_zero(arb_radref(res)); return more; } static int bsplit(arb_t res, n_primes_t primes, ulong a, ulong b, ulong nmax, slong prec) { if (b - a < NUM_BASECASE) { return basecase(res, primes, a, b, nmax, prec); } else { int more; more = bsplit(res, primes, a, a + (b - a) / 2, nmax, prec + 3); if (more) { arb_t t; arb_init(t); more = bsplit(t, primes, a + (b - a) / 2, b, nmax, prec + 3); arb_mul(res, res, t, prec); arb_clear(t); } else { arb_set_round(res, res, prec); } return more; } } void arb_primorial_nth_ui(arb_t res, ulong n, slong prec) { if (n < 10) { const unsigned int tab[] = { 1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870 }; arb_set_ui(res, tab[n]); arb_set_round(res, res, prec); } else if (FLINT_BITS == 32 && n >= 203280220) { arb_indeterminate(res); /* p_n will not fit a ulong */ } else { n_primes_t primes; n_primes_init(primes); bsplit(res, primes, 0, n, UWORD_MAX, prec); n_primes_clear(primes); } } void arb_primorial_ui(arb_t res, ulong n, slong prec) { if (n < 17) { const unsigned short tab[] = { 1, 1, 2, 6, 6, 30, 30, 210, 210, 210, 210, 2310, 2310, 30030, 30030, 30030, 30030 }; arb_set_ui(res, tab[n]); arb_set_round(res, res, prec); } else if (n >= UWORD_MAX / 2) { /* avoid potential slong/ulong issues and overflow in the multiply by two below. in any case, this would be quite big on 64-bit... */ arb_indeterminate(res); } else { n_primes_t primes; n_primes_init(primes); /* crude upper bound for pi(n) just to balance the binary splitting; we stop the prime iterator at the actual correct count */ bsplit(res, primes, 0, 2 * n / FLINT_BIT_COUNT(n) + 1, n, prec); n_primes_clear(primes); } } arb-2.22.1/arb/randtest.c000066400000000000000000000042511417376376500151230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_randtest_exact(arb_t x, flint_rand_t state, slong prec, slong mag_bits) { arf_randtest(arb_midref(x), state, prec, mag_bits); mag_zero(arb_radref(x)); } void arb_randtest_wide(arb_t x, flint_rand_t state, slong prec, slong mag_bits) { arf_randtest(arb_midref(x), state, prec, mag_bits); mag_randtest(arb_radref(x), state, mag_bits); } void arb_randtest_precise(arb_t x, flint_rand_t state, slong prec, slong mag_bits) { arf_randtest(arb_midref(x), state, prec, mag_bits); if (arf_is_zero(arb_midref(x)) || (n_randint(state, 8) == 0)) { mag_zero(arb_radref(x)); } else { mag_randtest(arb_radref(x), state, 0); if (!mag_is_zero(arb_radref(x))) { fmpz_add_si(MAG_EXPREF(arb_radref(x)), ARF_EXPREF(arb_midref(x)), -prec + 2 - n_randint(state, 8)); } } } void arb_randtest(arb_t x, flint_rand_t state, slong prec, slong mag_bits) { switch (n_randint(state, 8)) { case 0: arb_randtest_exact(x, state, prec, mag_bits); break; case 1: arb_randtest_wide(x, state, prec, mag_bits); break; default: arb_randtest_precise(x, state, prec, mag_bits); } } void arb_randtest_special(arb_t x, flint_rand_t state, slong prec, slong mag_bits) { arb_randtest(x, state, prec, mag_bits); if (n_randint(state, 10) == 0) mag_inf(arb_radref(x)); switch (n_randint(state, 10)) { case 0: arf_pos_inf(arb_midref(x)); break; case 1: arf_neg_inf(arb_midref(x)); break; case 2: arf_nan(arb_midref(x)); mag_inf(arb_radref(x)); break; default: break; } } arb-2.22.1/arb/rel_error_bits.c000066400000000000000000000030521417376376500163110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" slong arb_rel_error_bits(const arb_t x) { fmpz_t t; slong result; /* fast path for small exponents */ if (ARB_IS_LAGOM(x)) { if (mag_is_zero(arb_radref(x))) return -ARF_PREC_EXACT; else if (arf_is_special(arb_midref(x))) return ARF_PREC_EXACT; else return MAG_EXP(arb_radref(x)) + 1 - ARF_EXP(arb_midref(x)); } if (mag_is_zero(arb_radref(x))) { if (arf_is_nan(arb_midref(x))) return ARF_PREC_EXACT; else return -ARF_PREC_EXACT; } if (arf_is_special(arb_midref(x)) || mag_is_inf(arb_radref(x))) return ARF_PREC_EXACT; fmpz_init(t); fmpz_add_ui(t, MAG_EXPREF(arb_radref(x)), 1); result = _fmpz_sub_small(t, ARF_EXPREF(arb_midref(x))); fmpz_clear(t); return result; } slong arb_rel_one_accuracy_bits(const arb_t x) { if (arf_cmpabs_2exp_si(arb_midref(x), -1) < 0) { arb_t t; arf_init(arb_midref(t)); arf_one(arb_midref(t)); *arb_radref(t) = *arb_radref(x); return arb_rel_accuracy_bits(t); } else { return arb_rel_accuracy_bits(x); } } arb-2.22.1/arb/richcmp.c000066400000000000000000000146321417376376500147300ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_eq(const arb_t x, const arb_t y) { if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) return 0; if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) return 0; if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) || (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y)))) return arf_equal(arb_midref(x), arb_midref(y)); return 0; } int arb_ne(const arb_t x, const arb_t y) { if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) return 0; if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) return 0; if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) || (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y)))) return !arf_equal(arb_midref(x), arb_midref(y)); return !arb_overlaps(x, y); } int arb_lt(const arb_t x, const arb_t y) { arf_struct u[4]; arf_t t; int res; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) return 0; if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) return 0; if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) || (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y)))) return arf_cmp(arb_midref(x), arb_midref(y)) < 0; /* xm + xr < ym - yr <=> xm + xr - ym + yr < 0 */ arf_init_set_shallow(u + 0, arb_midref(x)); arf_init_neg_shallow(u + 1, arb_midref(y)); arf_init_set_mag_shallow(u + 2, arb_radref(x)); arf_init_set_mag_shallow(u + 3, arb_radref(y)); arf_init(t); arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN); res = (arf_sgn(t) < 0); arf_clear(t); return res; } int arb_le(const arb_t x, const arb_t y) { arf_struct u[4]; arf_t t; int res; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) return 0; if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) return (arf_is_neg_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) || (arf_is_pos_inf(arb_midref(y)) && mag_is_finite(arb_radref(y))); if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) || (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y)))) return arf_cmp(arb_midref(x), arb_midref(y)) <= 0; /* xm + xr <= ym - yr <=> xm + xr - ym + yr <= 0 */ arf_init_set_shallow(u + 0, arb_midref(x)); arf_init_neg_shallow(u + 1, arb_midref(y)); arf_init_set_mag_shallow(u + 2, arb_radref(x)); arf_init_set_mag_shallow(u + 3, arb_radref(y)); arf_init(t); arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN); res = (arf_sgn(t) <= 0); arf_clear(t); return res; } int arb_gt(const arb_t x, const arb_t y) { arf_struct u[4]; arf_t t; int res; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) return 0; if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) return 0; if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) || (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y)))) return arf_cmp(arb_midref(x), arb_midref(y)) > 0; /* xm - xr > ym + yr <=> xm - xr - ym - yr > 0 */ arf_init_set_shallow(u + 0, arb_midref(x)); arf_init_neg_shallow(u + 1, arb_midref(y)); arf_init_neg_mag_shallow(u + 2, arb_radref(x)); arf_init_neg_mag_shallow(u + 3, arb_radref(y)); arf_init(t); arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN); res = (arf_sgn(t) > 0); arf_clear(t); return res; } int arb_ge(const arb_t x, const arb_t y) { arf_struct u[4]; arf_t t; int res; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) return 0; if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) return (arf_is_pos_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) || (arf_is_neg_inf(arb_midref(y)) && mag_is_finite(arb_radref(y))); if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) || (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y)))) return arf_cmp(arb_midref(x), arb_midref(y)) >= 0; /* xm - xr >= ym + yr <=> xm - xr - ym - yr >= 0 */ arf_init_set_shallow(u + 0, arb_midref(x)); arf_init_neg_shallow(u + 1, arb_midref(y)); arf_init_neg_mag_shallow(u + 2, arb_radref(x)); arf_init_neg_mag_shallow(u + 3, arb_radref(y)); arf_init(t); arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN); res = (arf_sgn(t) >= 0); arf_clear(t); return res; } int arb_contains_zero(const arb_t x) { return arf_cmpabs_mag(arb_midref(x), arb_radref(x)) <= 0; } int arb_is_nonzero(const arb_t x) { return !arb_contains_zero(x); } int arb_is_positive(const arb_t x) { return (arf_sgn(arb_midref(x)) > 0) && (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) < 0) && !arf_is_nan(arb_midref(x)); } int arb_is_nonnegative(const arb_t x) { return (arf_sgn(arb_midref(x)) >= 0) && (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) <= 0) && !arf_is_nan(arb_midref(x)); } int arb_is_negative(const arb_t x) { return (arf_sgn(arb_midref(x)) < 0) && (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) < 0) && !arf_is_nan(arb_midref(x)); } int arb_is_nonpositive(const arb_t x) { return (arf_sgn(arb_midref(x)) <= 0) && (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) <= 0) && !arf_is_nan(arb_midref(x)); } int arb_contains_negative(const arb_t x) { return (arf_sgn(arb_midref(x)) < 0) || (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) > 0) || arf_is_nan(arb_midref(x)); } int arb_contains_nonpositive(const arb_t x) { return (arf_sgn(arb_midref(x)) <= 0) || (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) >= 0) || arf_is_nan(arb_midref(x)); } int arb_contains_positive(const arb_t x) { return (arf_sgn(arb_midref(x)) > 0) || (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) > 0) || arf_is_nan(arb_midref(x)); } int arb_contains_nonnegative(const arb_t x) { return (arf_sgn(arb_midref(x)) >= 0) || (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) >= 0) || arf_is_nan(arb_midref(x)); } arb-2.22.1/arb/rising2_ui.c000066400000000000000000000015271417376376500153540ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "arb_hypgeom.h" void arb_rising2_ui(arb_t u, arb_t v, const arb_t x, ulong n, slong prec) { if (x == u || x == v) { arb_t t; arb_init(t); arb_set(t, x); arb_rising2_ui(u, v, t, n, prec); arb_clear(t); } else { arb_struct tmp[2]; tmp[0] = *u; tmp[1] = *v; arb_hypgeom_rising_ui_jet(tmp, x, n, 2, prec); *u = tmp[0]; *v = tmp[1]; } } arb-2.22.1/arb/rising_fmpq_ui.c000066400000000000000000000033761417376376500163210ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void bsplit(arb_t y, const fmpz_t p, const fmpz_t q, ulong a, ulong b, slong prec) { if (b - a <= 8) { fmpz_t t, u; ulong c; fmpz_init(t); fmpz_init(u); fmpz_mul_ui(t, q, a); fmpz_add(t, t, p); fmpz_set(u, t); for (c = a + 1; c < b; c++) { fmpz_add(u, u, q); fmpz_mul(t, t, u); } arb_set_round_fmpz(y, t, prec); fmpz_clear(t); fmpz_clear(u); } else { arb_t w; ulong m = a + (b - a) / 2; arb_init(w); bsplit(y, p, q, a, m, prec); bsplit(w, p, q, m, b, prec); arb_mul(y, y, w, prec); arb_clear(w); } } void arb_rising_fmpq_ui(arb_t y, const fmpq_t x, ulong n, slong prec) { if (n == 0) { arb_one(y); } else if (n == 1) { arb_set_fmpq(y, x, prec); } else { slong wp; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); bsplit(y, fmpq_numref(x), fmpq_denref(x), 0, n, wp); if (fmpz_is_one(fmpq_denref(x))) { arb_set_round(y, y, prec); } else { arb_t t; arb_init(t); arb_set_fmpz(t, fmpq_denref(x)); arb_pow_ui(t, t, n, wp); arb_div(y, y, t, prec); arb_clear(t); } } } arb-2.22.1/arb/rising_ui.c000066400000000000000000000012051417376376500152630ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "arb_hypgeom.h" void arb_rising_ui(arb_t y, const arb_t x, ulong n, slong prec) { arb_hypgeom_rising_ui(y, x, n, prec); } void arb_rising(arb_t y, const arb_t x, const arb_t n, slong prec) { arb_hypgeom_rising(y, x, n, prec); } arb-2.22.1/arb/root_ui.c000066400000000000000000000046441417376376500147650ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void arb_root_arf(arb_t z, const arf_t x, ulong k, slong prec) { int inexact = arf_root(arb_midref(z), x, k, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); else mag_zero(arb_radref(z)); } void arb_root_ui_algebraic(arb_t res, const arb_t x, ulong k, slong prec) { mag_t r, msubr, m1k, t; if (arb_is_exact(x)) { arb_root_arf(res, arb_midref(x), k, prec); return; } if (!arb_is_nonnegative(x)) { arb_indeterminate(res); return; } mag_init(r); mag_init(msubr); mag_init(m1k); mag_init(t); /* x = [m-r, m+r] */ mag_set(r, arb_radref(x)); /* m - r */ arb_get_mag_lower(msubr, x); /* m^(1/k) */ arb_root_arf(res, arb_midref(x), k, prec); /* bound for m^(1/k) */ arb_get_mag(m1k, res); /* C = min(1, log(1+r/(m-r))/k) */ mag_div(t, r, msubr); mag_log1p(t, t); mag_div_ui(t, t, k); if (mag_cmp_2exp_si(t, 0) > 0) mag_one(t); /* C m^(1/k) */ mag_mul(t, m1k, t); mag_add(arb_radref(res), arb_radref(res), t); mag_clear(r); mag_clear(msubr); mag_clear(m1k); mag_clear(t); } void arb_root_ui_exp(arb_t res, const arb_t x, ulong k, slong prec) { arb_log(res, x, prec + 4); arb_div_ui(res, res, k, prec + 4); arb_exp(res, res, prec); } void arb_root_ui(arb_t res, const arb_t x, ulong k, slong prec) { if (k == 0) { arb_indeterminate(res); } else if (k == 1) { arb_set_round(res, x, prec); } else if (k == 2) { arb_sqrt(res, x, prec); } else if (k == 4) { arb_sqrt(res, x, prec + 2); arb_sqrt(res, res, prec); } else { if (k > 50 || prec < (WORD(1) << ((k / 8) + 8))) arb_root_ui_exp(res, x, k, prec); else arb_root_ui_algebraic(res, x, k, prec); } } /* backwards compatible alias */ void arb_root(arb_t res, const arb_t x, ulong k, slong prec) { arb_root_ui(res, x, k, prec); } arb-2.22.1/arb/rsqrt.c000066400000000000000000000044251417376376500144550ustar00rootroot00000000000000/* Copyright (C) 2012-2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_rsqrt(arb_t z, const arb_t x, slong prec) { mag_t t, u; slong acc; int inexact; if (!arb_is_finite(x) || arf_sgn(arb_midref(x)) <= 0) { if (arf_is_pos_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) arb_zero(z); else arb_indeterminate(z); } else if (mag_is_zero(arb_radref(x))) { inexact = arf_rsqrt(arb_midref(z), arb_midref(x), prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); else mag_zero(arb_radref(z)); } else { mag_init(t); arb_get_mag_lower(t, x); acc = arb_rel_accuracy_bits(x); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); if (acc <= 20) { if (mag_is_zero(t)) { arb_indeterminate(z); } else { mag_init(u); arb_get_mag(u, x); mag_rsqrt(t, t); mag_rsqrt_lower(u, u); arb_set_interval_mag(z, u, t, prec); mag_clear(u); } } else { /* error bound: (1/2) (x-r)^(-3/2) * r */ mag_init(u); mag_rsqrt(u, t); mag_div(t, u, t); mag_mul(t, t, arb_radref(x)); mag_mul_2exp_si(t, t, -1); inexact = arf_rsqrt(arb_midref(z), arb_midref(x), prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), t, arb_midref(z), prec); else mag_swap(arb_radref(z), t); mag_clear(u); } mag_clear(t); } } void arb_rsqrt_ui(arb_t z, ulong x, slong prec) { arb_t t; arb_init(t); arb_set_ui(t, x); arb_rsqrt(z, t, prec); arb_clear(t); } arb-2.22.1/arb/sec.c000066400000000000000000000010021417376376500140400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sec(arb_t res, const arb_t x, slong prec) { arb_cos(res, x, prec + 4); arb_inv(res, res, prec); } arb-2.22.1/arb/sech.c000066400000000000000000000017721417376376500142260ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sech(arb_t res, const arb_t x, slong prec) { if (arf_cmpabs_2exp_si(arb_midref(x), 0) > 0) { arb_t t; arb_init(t); if (arf_sgn(arb_midref(x)) > 0) { arb_neg(t, x); arb_exp(t, t, prec + 4); } else { arb_exp(t, x, prec + 4); } arb_mul(res, t, t, prec + 4); arb_add_ui(res, res, 1, prec + 4); arb_div(res, t, res, prec); arb_mul_2exp_si(res, res, 1); arb_clear(t); } else { arb_cosh(res, x, prec + 4); arb_inv(res, res, prec); } } arb-2.22.1/arb/set.c000066400000000000000000000010161417376376500140660ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set(arb_t x, const arb_t y) { arf_set(arb_midref(x), arb_midref(y)); mag_set(arb_radref(x), arb_radref(y)); } arb-2.22.1/arb/set_d.c000066400000000000000000000007621417376376500144000ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_d(arb_t x, double y) { arf_set_d(arb_midref(x), y); mag_zero(arb_radref(x)); } arb-2.22.1/arb/set_fmpz.c000066400000000000000000000007771417376376500151370ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_fmpz(arb_t x, const fmpz_t y) { arf_set_fmpz(arb_midref(x), y); mag_zero(arb_radref(x)); } arb-2.22.1/arb/set_interval_arf.c000066400000000000000000000027211417376376500166260ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_interval_arf(arb_t x, const arf_t a, const arf_t b, slong prec) { arf_t t; int inexact; /* [-inf, -inf] or [+inf, +inf] */ if (arf_is_inf(a) && arf_equal(a, b)) { arf_set(arb_midref(x), a); mag_zero(arb_radref(x)); return; } /* any nan -> [nan +/- inf] */ if (arf_is_nan(a) || arf_is_nan(b)) { arb_indeterminate(x); return; } /* [-inf, x] or [x, +inf] = [+/- inf] */ if (arf_is_neg_inf(a) || arf_is_pos_inf(b)) { arf_zero(arb_midref(x)); mag_inf(arb_radref(x)); return; } /* [(a + b) +/- (b - a)] / 2 */ arf_init(t); arf_sub(t, b, a, MAG_BITS, ARF_RND_UP); if (arf_sgn(t) < 0) { flint_printf("exception: arb_set_interval_arf: endpoints not ordered\n"); flint_abort(); } arf_get_mag(arb_radref(x), t); inexact = arf_add(arb_midref(x), a, b, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(x), arb_radref(x), arb_midref(x), prec); arb_mul_2exp_si(x, x, -1); arf_clear(t); } arb-2.22.1/arb/set_interval_mag.c000066400000000000000000000052121417376376500166200ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_interval_mag(arb_t res, const mag_t a, const mag_t b, slong prec) { if (MAG_IS_LAGOM(a) && MAG_IS_LAGOM(b)) { slong aexp, bexp; mp_limb_t aman, bman, mman, rman, tmp; aman = MAG_MAN(a); bman = MAG_MAN(b); aexp = MAG_EXP(a); bexp = MAG_EXP(b); if (aman == 0 && bman == 0) { arb_zero(res); return; } if (bman == 0 || (aman != 0 && (aexp > bexp || (aexp == bexp && aman > bman)))) { flint_printf("exception: arb_set_interval_mag: endpoints not ordered\n"); flint_abort(); } /* now a = 0 or bexp >= aexp */ if (aman == 0 || bexp - aexp > MAG_BITS) { mman = bman; /* midpoint a+b */ rman = bman + (aman != 0); /* radius b-a */ } else { tmp = (aman >> (bexp - aexp)); mman = bman + tmp; /* midpoint a+b */ rman = bman - tmp; /* radius b-a */ rman += ((tmp << (bexp - aexp)) != aman); /* rounding error */ } arf_set_ui(arb_midref(res), mman); /* m can't be zero */ ARF_EXP(arb_midref(res)) += bexp - MAG_BITS - 1; mag_set_ui(arb_radref(res), rman); if (rman != 0) /* r can be zero */ MAG_EXP(arb_radref(res)) += bexp - MAG_BITS - 1; arb_set_round(res, res, prec); } else { int inexact; arf_t aa, bb; if (mag_cmp(a, b) > 0) { flint_printf("exception: arb_set_interval_mag: endpoints not ordered\n"); flint_abort(); } if (mag_is_inf(a)) { arb_pos_inf(res); return; } if (mag_is_inf(b)) { arb_zero_pm_inf(res); return; } arf_init_set_mag_shallow(aa, a); arf_init_set_mag_shallow(bb, b); inexact = arf_add(arb_midref(res), aa, bb, prec, ARB_RND); mag_sub(arb_radref(res), b, a); if (inexact) arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec); arb_mul_2exp_si(res, res, -1); } } arb-2.22.1/arb/set_interval_mpfr.c000066400000000000000000000012401417376376500170150ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_interval_mpfr(arb_t x, const mpfr_t a, const mpfr_t b, slong prec) { arf_t aa, bb; arf_init(aa); arf_init(bb); arf_set_mpfr(aa, a); arf_set_mpfr(bb, b); arb_set_interval_arf(x, aa, bb, prec); arf_clear(aa); arf_clear(bb); } arb-2.22.1/arb/set_interval_neg_pos_mag.c000066400000000000000000000062471417376376500203430ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_interval_neg_pos_mag(arb_t res, const mag_t a, const mag_t b, slong prec) { if (MAG_IS_LAGOM(a) && MAG_IS_LAGOM(b)) { slong aexp, bexp, mexp, shift; mp_limb_t aman, bman, mman, rman, tmp; int negative; aman = MAG_MAN(a); bman = MAG_MAN(b); aexp = MAG_EXP(a); bexp = MAG_EXP(b); if (aman == 0) { if (bman == 0) { arb_zero(res); return; } negative = 0; mexp = bexp; mman = bman; rman = bman; } else if (bman == 0) { negative = 1; mexp = aexp; mman = aman; rman = aman; } else if (aexp == bexp) { mexp = aexp; negative = aman >= bman; if (negative) mman = aman - bman; else mman = bman - aman; rman = aman + bman; } else if (aexp > bexp) { negative = 1; mexp = aexp; shift = aexp - bexp; if (shift > MAG_BITS) { mman = aman; rman = aman + 2; } else { tmp = bman >> shift; mman = aman - tmp; rman = aman + tmp; rman += 2 * ((tmp << shift) != bman); } } else { negative = 0; mexp = bexp; shift = bexp - aexp; if (shift > MAG_BITS) { mman = bman; rman = bman + 2; } else { tmp = aman >> shift; mman = bman - tmp; rman = bman + tmp; rman += 2 * ((tmp << shift) != aman); } } arf_set_ui(arb_midref(res), mman); if (negative) arf_neg(arb_midref(res), arb_midref(res)); if (mman != 0) ARF_EXP(arb_midref(res)) += mexp - MAG_BITS - 1; mag_set_ui(arb_radref(res), rman); /* r can't be zero */ MAG_EXP(arb_radref(res)) += mexp - MAG_BITS - 1; arb_set_round(res, res, prec); } else { arf_t aa, bb; int inexact; if (mag_is_inf(a) || mag_is_inf(b)) { arb_zero_pm_inf(res); return; } arf_init_set_mag_shallow(aa, a); arf_init_set_mag_shallow(bb, b); inexact = arf_sub(arb_midref(res), bb, aa, prec, ARB_RND); mag_add(arb_radref(res), b, a); if (inexact) arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec); arb_mul_2exp_si(res, res, -1); } } arb-2.22.1/arb/set_round.c000066400000000000000000000013011417376376500152720ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_round(arb_t z, const arb_t x, slong prec) { int inexact; inexact = arf_set_round(arb_midref(z), arb_midref(x), prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } arb-2.22.1/arb/set_round_fmpz.c000066400000000000000000000012351417376376500163340ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_round_fmpz(arb_t y, const fmpz_t x, slong prec) { int inexact; inexact = arf_set_round_fmpz(arb_midref(y), x, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(y), arb_midref(y), prec); else mag_zero(arb_radref(y)); } arb-2.22.1/arb/set_round_fmpz_2exp.c000066400000000000000000000012761417376376500172770ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_round_fmpz_2exp(arb_t y, const fmpz_t x, const fmpz_t exp, slong prec) { int inexact; inexact = arf_set_round_fmpz_2exp(arb_midref(y), x, exp, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(y), arb_midref(y), prec); else mag_zero(arb_radref(y)); } arb-2.22.1/arb/set_si.c000066400000000000000000000007641417376376500145720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_si(arb_t x, slong y) { arf_set_si(arb_midref(x), y); mag_zero(arb_radref(x)); } arb-2.22.1/arb/set_str.c000066400000000000000000000120231417376376500147560ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "arb.h" static int arb_set_float_str(arb_t res, const char * inp, slong prec) { char * emarker; char * buf; int error; slong i; fmpz_t exp; fmpz_t man; slong num_int, num_frac; int after_radix; if (inp[0] == '+') { return arb_set_float_str(res, inp + 1, prec); } if (inp[0] == '-') { error = arb_set_float_str(res, inp + 1, prec); arb_neg(res, res); return error; } if (strcmp(inp, "inf") == 0) { arb_pos_inf(res); return 0; } if (strcmp(inp, "nan") == 0) { arb_indeterminate(res); return 0; } error = 0; fmpz_init(exp); fmpz_init(man); buf = flint_malloc(strlen(inp) + 1); emarker = strchr(inp, 'e'); /* parse exponent (0 by default) */ if (emarker != NULL) { /* allow e+42 as well as e42 */ if (emarker[1] == '+') { if (!(emarker[2] >= '0' && emarker[2] <= '9')) error = 1; else error = fmpz_set_str(exp, emarker + 2, 10); } else error = fmpz_set_str(exp, emarker + 1, 10); if (error) goto cleanup; } /* parse floating-point part */ { num_int = 0; num_frac = 0; after_radix = 0; for (i = 0; inp + i != emarker && inp[i] != '\0'; i++) { if (inp[i] == '.' && !after_radix) { after_radix = 1; } else if (inp[i] >= '0' && inp[i] <= '9') { buf[num_int + num_frac] = inp[i]; num_frac += after_radix; num_int += !after_radix; } else { error = 1; goto cleanup; } } buf[num_int + num_frac] = '\0'; /* put trailing zeros into the exponent */ while (num_int + num_frac > 1 && buf[num_int + num_frac - 1] == '0') { buf[num_int + num_frac - 1] = '\0'; num_frac--; } fmpz_sub_si(exp, exp, num_frac); error = fmpz_set_str(man, buf, 10); if (error) goto cleanup; } if (fmpz_is_zero(man)) { arb_zero(res); } else if (fmpz_is_zero(exp)) { arb_set_round_fmpz(res, man, prec); } else { arb_t t; arb_init(t); arb_set_ui(t, 10); arb_set_fmpz(res, man); if (fmpz_sgn(exp) > 0) { arb_pow_fmpz_binexp(t, t, exp, prec + 4); arb_mul(res, res, t, prec); } else { fmpz_neg(exp, exp); arb_pow_fmpz_binexp(t, t, exp, prec + 4); arb_div(res, res, t, prec); } arb_clear(t); } cleanup: fmpz_clear(exp); fmpz_clear(man); flint_free(buf); if (error) arb_indeterminate(res); return error; } int arb_set_str(arb_t res, const char * inp, slong prec) { char * buf; char * split; char * first; char * last; slong i, len; int error; error = 0; len = strlen(inp); buf = flint_malloc(len + 1); for (i = 0; i <= len; i++) buf[i] = tolower(inp[i]); split = strstr(buf, "+/-"); if (split == NULL) { /* strip whitespace and brackets */ first = buf; while (isspace(first[0]) || first[0] == '[') first++; last = buf + len; while (last - first > 0 && (isspace(last[-1]) || last[-1] == ']')) last--; last[0] = '\0'; error = arb_set_float_str(res, first, prec); } else { arb_t rad; arb_init(rad); /* strip whitespace and brackets */ first = buf; while (isspace(first[0]) || first[0] == '[') first++; last = split; while (last - first > 0 && (isspace(last[-1]) || last[-1] == ']')) last--; last[0] = '\0'; if (first == last) arb_zero(res); else error = arb_set_float_str(res, first, prec); if (!error) { /* strip whitespace and brackets */ first = split + 3; while (isspace(first[0]) || first[0] == '[') first++; last = buf + len; while (last - first > 0 && (isspace(last[-1]) || last[-1] == ']')) last--; last[0] = '\0'; error = arb_set_float_str(rad, first, prec); arb_abs(rad, rad); arb_add_error(res, rad); } arb_clear(rad); } flint_free(buf); return error; } arb-2.22.1/arb/set_ui.c000066400000000000000000000007641417376376500145740ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_set_ui(arb_t x, ulong y) { arf_set_ui(arb_midref(x), y); mag_zero(arb_radref(x)); } arb-2.22.1/arb/sgn.c000066400000000000000000000012571417376376500140710ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sgn(arb_t res, const arb_t x) { if (arb_is_zero(x)) { arb_zero(res); } else if (arb_contains_zero(x)) { arf_zero(arb_midref(res)); mag_one(arb_radref(res)); } else { arb_set_si(res, arf_sgn(arb_midref(x))); } } arb-2.22.1/arb/sgn_nonzero.c000066400000000000000000000010621417376376500156350ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int arb_sgn_nonzero(const arb_t x) { if (arb_is_positive(x)) return 1; else if (arb_is_negative(x)) return -1; else return 0; } arb-2.22.1/arb/sin_cos.c000066400000000000000000000372741417376376500147470ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/mpn_extras.h" #include "arb.h" #define TMP_ALLOC_LIMBS(__n) TMP_ALLOC((__n) * sizeof(mp_limb_t)) #define MAGLIM(prec) FLINT_MAX(65536, (4*prec)) static void mag_nonzero_fast_mul(mag_t z, const mag_t x, const mag_t y) { MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + LIMB_ONE; MAG_EXP(z) = MAG_EXP(x) + MAG_EXP(y); MAG_FAST_ADJUST_ONE_TOO_SMALL(z); } static void mag_nonzero_fast_add(mag_t z, const mag_t x, const mag_t y) { slong shift = MAG_EXP(x) - MAG_EXP(y); if (shift == 0) { MAG_EXP(z) = MAG_EXP(x); MAG_MAN(z) = MAG_MAN(x) + MAG_MAN(y); MAG_FAST_ADJUST_ONE_TOO_LARGE(z); /* may need two adjustments */ } else if (shift > 0) { MAG_EXP(z) = MAG_EXP(x); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(x) + LIMB_ONE; else MAG_MAN(z) = MAG_MAN(x) + (MAG_MAN(y) >> shift) + LIMB_ONE; } else { shift = -shift; MAG_EXP(z) = MAG_EXP(y); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(y) + LIMB_ONE; else MAG_MAN(z) = MAG_MAN(y) + (MAG_MAN(x) >> shift) + LIMB_ONE; } MAG_FAST_ADJUST_ONE_TOO_LARGE(z); } static int mag_nonzero_fast_cmp(const mag_t x, const mag_t y) { if (MAG_EXP(x) == MAG_EXP(y)) return (MAG_MAN(x) < MAG_MAN(y)) ? -1 : 1; else return (MAG_EXP(x) < MAG_EXP(y)) ? -1 : 1; } static void mag_fast_set(mag_t x, const mag_t y) { MAG_EXP(x) = MAG_EXP(y); MAG_MAN(x) = MAG_MAN(y); } void _arb_sin_cos(arb_t zsin, arb_t zcos, const arf_t x, const mag_t xrad, slong prec) { int want_sin, want_cos; slong radexp, exp, wp, wn, N, r, wprounded, maglim, orig_prec; mp_ptr tmp, w, sina, cosa, sinb, cosb, ta, tb; mp_ptr sinptr, cosptr; mp_limb_t p1, q1bits, p2, q2bits, error, error2, p1_tab1, radman; int negative, inexact, octant; int sinnegative, cosnegative, swapsincos; TMP_INIT; /* PART 1: special cases and setup. */ orig_prec = prec; /* Below, both x and xrad will be finite, and x will be nonzero. */ if (mag_is_inf(xrad) || arf_is_special(x)) { _arb_sin_cos_generic(zsin, zcos, x, xrad, prec); return; } exp = ARF_EXP(x); maglim = MAGLIM(prec); negative = ARF_SGNBIT(x); /* Unlikely: tiny or huge midpoint. As written, this test also catches any bignum exponents. */ if (exp < -(prec/2) - 2 || exp > maglim) { _arb_sin_cos_generic(zsin, zcos, x, xrad, prec); return; } want_sin = (zsin != NULL); want_cos = (zcos != NULL); /* Copy the radius data. */ radexp = MAG_EXP(xrad); radman = MAG_MAN(xrad); if (radman != 0) { /* Clamp the radius exponent to a safe range. */ if (radexp < MAG_MIN_LAGOM_EXP || radexp > MAG_MAX_LAGOM_EXP) { /* Very wide... */ if (fmpz_sgn(MAG_EXPREF(xrad)) > 0) { _arb_sin_cos_wide(zsin, zcos, x, xrad, prec); return; } radman = MAG_ONE_HALF; radexp = MAG_MIN_LAGOM_EXP + 1; } /* Use wide algorithm. */ if (radexp >= -24) { _arb_sin_cos_wide(zsin, zcos, x, xrad, prec); return; } /* Regular case: decrease precision to match generic max. accuracy. */ /* Note: near x=0, the error can be quadratic for cos. */ if (want_cos && exp < -2) prec = FLINT_MIN(prec, 20 - FLINT_MAX(exp, radexp) - radexp); else prec = FLINT_MIN(prec, 20 - radexp); } /* Absolute working precision (NOT rounded to a limb multiple) */ wp = prec + 8; if (want_sin && exp <= 0) wp += (-exp); /* Number of limbs */ wn = (wp + FLINT_BITS - 1) / FLINT_BITS; /* Precision rounded to a number of bits */ wprounded = FLINT_BITS * wn; /* Don't be close to the boundary (to allow adding adding the Taylor series truncation error without overflow) */ wp = FLINT_MAX(wp, wprounded - (FLINT_BITS - 4)); /* Too high precision to use table -- use generic algorithm */ if (wp > ARB_SIN_COS_TAB2_PREC) { _arb_sin_cos_generic(zsin, zcos, x, xrad, orig_prec); return; } /* PART 2: the actual computation. */ TMP_START; tmp = TMP_ALLOC_LIMBS(9 * wn); w = tmp; /* requires wn limbs */ sina = w + wn; /* requires wn limbs */ cosa = sina + wn; /* requires wn limbs */ sinb = cosa + wn; /* requires wn limbs */ cosb = sinb + wn; /* requires wn limbs */ ta = cosb + wn; /* requires 2*wn limbs */ tb = ta + 2*wn; /* requires 2*wn limbs */ /* reduce modulo pi/4 */ if (_arb_get_mpn_fixed_mod_pi4(w, NULL, &octant, &error, x, wn) == 0) { /* may run out of precision for pi/4 */ _arb_sin_cos_generic(zsin, zcos, x, xrad, orig_prec); TMP_END; return; } sinnegative = (octant >= 4) ^ negative; cosnegative = (octant >= 2 && octant <= 5); swapsincos = (octant == 1 || octant == 2 || octant == 5 || octant == 6); /* Table-based argument reduction (1 or 2 steps) */ if (wp <= ARB_SIN_COS_TAB1_PREC) { q1bits = ARB_SIN_COS_TAB1_BITS; q2bits = 0; p1 = p1_tab1 = w[wn-1] >> (FLINT_BITS - q1bits); w[wn-1] -= (p1 << (FLINT_BITS - q1bits)); p2 = 0; /* p1_tab1 will be used for the error bounds at the end. */ p1_tab1 = p1; } else { q1bits = ARB_SIN_COS_TAB21_BITS; q2bits = ARB_SIN_COS_TAB21_BITS + ARB_SIN_COS_TAB22_BITS; /* p1_tab1 will be used for the error bounds at the end. */ p1_tab1 = w[wn-1] >> (FLINT_BITS - ARB_SIN_COS_TAB1_BITS); p1 = w[wn-1] >> (FLINT_BITS - q1bits); w[wn-1] -= (p1 << (FLINT_BITS - q1bits)); p2 = w[wn-1] >> (FLINT_BITS - q2bits); w[wn-1] -= (p2 << (FLINT_BITS - q2bits)); } /* |w| <= 2^-r */ r = _arb_mpn_leading_zeros(w, wn); /* Choose number of terms N such that Taylor series truncation error is <= 2^-wp */ N = _arb_exp_taylor_bound(-r, wp); /* the summation for sin/cos is actually done to (2N-1)! */ N = (N + 1) / 2; if (N < 14) { /* Evaluate Taylor series */ _arb_sin_cos_taylor_rs(sina, cosa, &error2, w, wn, N, 0, 1); /* Taylor series evaluation error */ error += error2; /* Taylor series truncation error */ error += UWORD(1) << (wprounded-wp); } else /* Compute cos(a) from sin(a) using a square root. */ { /* Evaluate Taylor series */ _arb_sin_cos_taylor_rs(sina, cosa, &error2, w, wn, N, 1, 1); error += error2; error += UWORD(1) << (wprounded-wp); if (flint_mpn_zero_p(sina, wn)) { flint_mpn_store(cosa, wn, LIMB_ONES); error = FLINT_MAX(error, 1); } else { mpn_sqr(ta, sina, wn); /* 1 - s^2 (negation guaranteed to have borrow) */ mpn_neg(ta, ta, 2 * wn); /* top limb of ta must be nonzero, so no need to normalize before calling mpn_sqrtrem */ mpn_sqrtrem(cosa, ta, ta, 2 * wn); /* When converting sin to cos, the error for cos must be smaller than the error for sin; but we also get 1 ulp extra error from the square root. */ error += 1; } } /* sin(a+b) = sin(a)*cos(b) + cos(a)*sin(b) cos(a+b) = cos(a)*cos(b) - sin(a)*sin(b) [F1+e1]*[F2+e2] + [F3+e3]*[F4+e4] - F1 F2 + F3 F4 = e1 e2 + e3 e4 + e2 F1 + e1 F2 + e4 F3 + e3 F4 <= (e1 + e2 + e3 + e4) + 1 (ulp) <= 2*left_err + 2*right_err + 1 (ulp) Truncating both terms before adding adds another 2 ulp, so the error is bounded by <= 2*left_err + 2*right_err + 3 (ulp) */ if (p1 == 0 && p2 == 0) /* no table lookups */ { sinptr = sina; cosptr = cosa; } else if (p1 == 0 || p2 == 0) /* only one table lookup */ { mp_srcptr sinc, cosc; if (wp <= ARB_SIN_COS_TAB1_PREC) /* must be in table 1 */ { sinc = arb_sin_cos_tab1[2 * p1] + ARB_SIN_COS_TAB1_LIMBS - wn; cosc = arb_sin_cos_tab1[2 * p1 + 1] + ARB_SIN_COS_TAB1_LIMBS - wn; } else if (p1 != 0) { sinc = arb_sin_cos_tab21[2 * p1] + ARB_SIN_COS_TAB2_LIMBS - wn; cosc = arb_sin_cos_tab21[2 * p1 + 1] + ARB_SIN_COS_TAB2_LIMBS - wn; } else { sinc = arb_sin_cos_tab22[2 * p2] + ARB_SIN_COS_TAB2_LIMBS - wn; cosc = arb_sin_cos_tab22[2 * p2 + 1] + ARB_SIN_COS_TAB2_LIMBS - wn; } if ((want_sin && !swapsincos) || (want_cos && swapsincos)) { mpn_mul_n(ta, sina, cosc, wn); mpn_mul_n(tb, cosa, sinc, wn); mpn_add_n(w, ta + wn, tb + wn, wn); } if ((want_cos && !swapsincos) || (want_sin && swapsincos)) { mpn_mul_n(ta, cosa, cosc, wn); mpn_mul_n(tb, sina, sinc, wn); mpn_sub_n(ta, ta + wn, tb + wn, wn); } sinptr = w; cosptr = ta; error = 2 * error + 2 * 1 + 3; } else /* two table lookups, must be in table 2 */ { mp_srcptr sinc, cosc, sind, cosd; sinc = arb_sin_cos_tab21[2 * p1] + ARB_SIN_COS_TAB2_LIMBS - wn; cosc = arb_sin_cos_tab21[2 * p1 + 1] + ARB_SIN_COS_TAB2_LIMBS - wn; sind = arb_sin_cos_tab22[2 * p2] + ARB_SIN_COS_TAB2_LIMBS - wn; cosd = arb_sin_cos_tab22[2 * p2 + 1] + ARB_SIN_COS_TAB2_LIMBS - wn; mpn_mul_n(ta, sinc, cosd, wn); mpn_mul_n(tb, cosc, sind, wn); mpn_add_n(sinb, ta + wn, tb + wn, wn); mpn_mul_n(ta, cosc, cosd, wn); mpn_mul_n(tb, sinc, sind, wn); mpn_sub_n(cosb, ta + wn, tb + wn, wn); error2 = 2 * 1 + 2 * 1 + 3; if ((want_sin && !swapsincos) || (want_cos && swapsincos)) { mpn_mul_n(ta, sina, cosb, wn); mpn_mul_n(tb, cosa, sinb, wn); mpn_add_n(w, ta + wn, tb + wn, wn); } if ((want_cos && !swapsincos) || (want_sin && swapsincos)) { mpn_mul_n(ta, cosa, cosb, wn); mpn_mul_n(tb, sina, sinb, wn); mpn_sub_n(ta, ta + wn, tb + wn, wn); } error = 2 * error + 2 * error2 + 3; sinptr = w; cosptr = ta; } /* PART 3: compute propagated error and write output */ if (swapsincos) { mp_ptr tmptr = sinptr; sinptr = cosptr; cosptr = tmptr; } /* We have two sources of error. 1. Computation error: error * 2^(-wprounded) 2. With input radius r != 0, the propagated error bound: sin(x): min(2, r, |cos(x)|*r + 0.5*r^2) cos(x): min(2, r, |sin(x)|*r + 0.5*r^2) We skip the min by 2 since this is unnecessary with the separate code for wide intervals. */ if (radman == 0) { if (want_sin) { mag_set_ui_2exp_si(arb_radref(zsin), error, -wprounded); if (want_cos) mag_set(arb_radref(zcos), arb_radref(zsin)); } else { mag_set_ui_2exp_si(arb_radref(zcos), error, -wprounded); } } else { mag_t sin_err, cos_err, quadratic, comp_err, xrad_copy; mp_limb_t A_sin, A_cos, A_exp; /* Copy xrad to support aliasing (note: the exponent has also been clamped earlier). */ MAG_MAN(xrad_copy) = radman; MAG_EXP(xrad_copy) = radexp; /* Bound computed error. */ if (error != 0) { mag_init(comp_err); /* no need to free */ mag_set_ui_2exp_si(comp_err, error, -wprounded); } /* Bound quadratic term for propagated error: 0.5*r^2 */ mag_init(quadratic); /* no need to free */ mag_nonzero_fast_mul(quadratic, xrad_copy, xrad_copy); MAG_EXP(quadratic) -= 1; /* Bound linear term for propagated error: cos(x)*r, sin(x)*r. */ /* Note: we could have used the computed values, but then we would need to incorporate the computed error which would be slightly messier, and we would also need extra cases when only computing one of the functions. */ A_cos = arb_sin_cos_tab1[2 * p1_tab1][ARB_SIN_COS_TAB1_LIMBS - 1]; A_sin = arb_sin_cos_tab1[2 * p1_tab1 + 1][ARB_SIN_COS_TAB1_LIMBS - 1]; /* Note: ARB_SIN_COS_TAB1_BITS == 8 */ /* Adding 2 ulps (here ulp = 2^-8) gives an upper bound. The truncated table entry underestimates the sine or cosine of x by at most 1 ulp, and the top bits of x underestimate x by at most 1 ulp. */ A_sin = (A_sin >> (FLINT_BITS - ARB_SIN_COS_TAB1_BITS)) + 2; A_cos = (A_cos >> (FLINT_BITS - ARB_SIN_COS_TAB1_BITS)) + 2; A_exp = -ARB_SIN_COS_TAB1_BITS; if (swapsincos) { mp_limb_t tt = A_sin; A_sin = A_cos; A_cos = tt; } A_sin *= ((MAG_MAN(xrad_copy) >> (MAG_BITS - ARB_SIN_COS_TAB1_BITS)) + LIMB_ONE); A_cos *= ((MAG_MAN(xrad_copy) >> (MAG_BITS - ARB_SIN_COS_TAB1_BITS)) + LIMB_ONE); A_exp -= ARB_SIN_COS_TAB1_BITS; A_exp += radexp; if (want_sin) { mag_init(sin_err); mag_set_ui_2exp_si(sin_err, A_sin, A_exp); mag_nonzero_fast_add(sin_err, sin_err, quadratic); /* The propagated error is certainly at most r */ if (mag_nonzero_fast_cmp(sin_err, xrad_copy) > 0) mag_fast_set(sin_err, xrad_copy); /* Add the computed error. */ if (error != 0) mag_nonzero_fast_add(sin_err, sin_err, comp_err); /* Set it, and clear the original output variable which could have a bignum exponent. */ mag_swap(arb_radref(zsin), sin_err); mag_clear(sin_err); } /* The same as above. */ if (want_cos) { mag_init(cos_err); mag_set_ui_2exp_si(cos_err, A_cos, A_exp); mag_nonzero_fast_add(cos_err, cos_err, quadratic); if (mag_nonzero_fast_cmp(cos_err, xrad_copy) > 0) mag_fast_set(cos_err, xrad_copy); if (error != 0) mag_nonzero_fast_add(cos_err, cos_err, comp_err); mag_swap(arb_radref(zcos), cos_err); mag_clear(cos_err); } } /* Set the midpoints. */ if (want_sin) { inexact = _arf_set_mpn_fixed(arb_midref(zsin), sinptr, wn, wn, sinnegative, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(zsin), arb_radref(zsin), arb_midref(zsin), prec); } if (want_cos) { inexact = _arf_set_mpn_fixed(arb_midref(zcos), cosptr, wn, wn, cosnegative, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(zcos), arb_radref(zcos), arb_midref(zcos), prec); } TMP_END; } void arb_sin_cos(arb_t s, arb_t c, const arb_t x, slong prec) { _arb_sin_cos(s, c, arb_midref(x), arb_radref(x), prec); } void arb_sin(arb_t s, const arb_t x, slong prec) { _arb_sin_cos(s, NULL, arb_midref(x), arb_radref(x), prec); } void arb_cos(arb_t c, const arb_t x, slong prec) { _arb_sin_cos(NULL, c, arb_midref(x), arb_radref(x), prec); } arb-2.22.1/arb/sin_cos_arf_bb.c000066400000000000000000000206251417376376500162320ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" slong _arb_compute_bs_exponents(slong * tab, slong n); slong _arb_get_exp_pos(const slong * tab, slong step); static void bsplit(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const slong * xexp, const fmpz * xpow, flint_bitcnt_t r, slong a, slong b) { int cc; if (b - a == 1) { count_trailing_zeros(cc, (2 * a + 2)); fmpz_neg_ui(Q, (2 * a + 2) >> cc); fmpz_mul_ui(Q, Q, 2 * a + 3); *Qexp = 2 * r + cc; fmpz_set(T, xpow); } else if (b - a == 2) { fmpz_mul2_uiui(T, xpow, (2 * a + 4), (2 * a + 5)); fmpz_mul_2exp(T, T, 2 * r); fmpz_neg(T, T); fmpz_add(T, T, xpow + 1); count_trailing_zeros(cc, (2 * a + 4)); fmpz_neg_ui(Q, (2 * a + 4) >> cc); fmpz_mul_ui(Q, Q, 2 * a + 5); *Qexp = 2 * r + cc; count_trailing_zeros(cc, (2 * a + 2)); fmpz_mul2_uiui(Q, Q, (2 * a + 2) >> cc, (2 * a + 3)); fmpz_neg(Q, Q); *Qexp += 2 * r + cc; } else { slong step, m, i; flint_bitcnt_t Q2exp[1]; fmpz_t Q2, T2; step = (b - a) / 2; m = a + step; fmpz_init(Q2); fmpz_init(T2); bsplit(T, Q, Qexp, xexp, xpow, r, a, m); bsplit(T2, Q2, Q2exp, xexp, xpow, r, m, b); fmpz_mul(T, T, Q2); fmpz_mul_2exp(T, T, *Q2exp); /* find x^step in table */ i = _arb_get_exp_pos(xexp, step); fmpz_addmul(T, xpow + i, T2); fmpz_clear(T2); fmpz_mul(Q, Q, Q2); *Qexp = *Qexp + *Q2exp; fmpz_clear(Q2); } } /* todo: also allow computing cos, using the same table... */ void _arb_sin_sum_bs_powtab(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) { slong * xexp; slong length, i; fmpz * xpow; /* compute the powers of x^2 that will appear (at least x^2) */ xexp = flint_calloc(2 * FLINT_BITS, sizeof(slong)); length = _arb_compute_bs_exponents(xexp, N); xpow = _fmpz_vec_init(length); fmpz_mul(xpow, x, x); /* build x^i table */ for (i = 1; i < length; i++) { if (xexp[i] == 2 * xexp[i-1]) { fmpz_mul(xpow + i, xpow + i - 1, xpow + i - 1); } else if (xexp[i] == 2 * xexp[i-2]) /* prefer squaring if possible */ { fmpz_mul(xpow + i, xpow + i - 2, xpow + i - 2); } else if (xexp[i] == 2 * xexp[i-1] + 1) { fmpz_mul(xpow + i, xpow + i - 1, xpow + i - 1); fmpz_mul(xpow + i, xpow + i, xpow); } else if (xexp[i] == 2 * xexp[i-2] + 1) { fmpz_mul(xpow + i, xpow + i - 2, xpow + i - 2); fmpz_mul(xpow + i, xpow + i, xpow); } else { flint_printf("power table has the wrong structure!\n"); flint_abort(); } } bsplit(T, Q, Qexp, xexp, xpow, r, 0, N); _fmpz_vec_clear(xpow, length); flint_free(xexp); } /* Determine N such that the error is bounded by 2^-prec when summing the Taylor series of sin(x) up to term x^(2N+1) inclusive. We choose an N with many trailing zeros to improve efficiency of the binary splitting. */ static slong bs_num_terms(slong mag, slong prec) { slong N; N = _arb_exp_taylor_bound(mag, prec); N = N / 2 - 1; N = FLINT_MAX(N, 1); if (N > 10000) while (N % 128 != 0) N++; if (N > 1000) while (N % 16 != 0) N++; if (N > 100) while (N % 2 != 0) N++; return N; } void arb_sin_cos_fmpz_div_2exp_bsplit(arb_t wsin, arb_t wcos, const fmpz_t x, flint_bitcnt_t r, slong prec) { fmpz_t T, Q; slong N, xmag; flint_bitcnt_t Qexp[1]; /* slightly reduce memory usage at very high precision */ arb_zero(wsin); arb_zero(wcos); fmpz_init(T); fmpz_init(Q); if (r > prec) flint_abort(); /* Binary splitting (+1 fixed-point ulp truncation error). */ xmag = fmpz_bits(x) - r; N = bs_num_terms(xmag, prec); _arb_sin_sum_bs_powtab(T, Q, Qexp, x, r, N); /* we still need to multiply and add x/2^r to get sine */ fmpz_mul(T, T, x); Qexp[0] += r; /* T = T / Q (+1 fixed-point ulp error). */ if (Qexp[0] >= prec) { fmpz_tdiv_q_2exp(T, T, Qexp[0] - prec); fmpz_tdiv_q(T, T, Q); } else { fmpz_mul_2exp(T, T, prec - Qexp[0]); fmpz_tdiv_q(T, T, Q); } fmpz_mul_2exp(Q, x, prec - r); fmpz_add(T, T, Q); /* T = sin(u) with at most 2 fixed-point ulp error. */ arf_set_fmpz(arb_midref(wsin), T); arf_mul_2exp_si(arb_midref(wsin), arb_midref(wsin), -prec); mag_set_ui_2exp_si(arb_radref(wsin), 2, -prec); /* compute cos from sin */ arb_mul(wcos, wsin, wsin, prec); arb_sub_ui(wcos, wcos, 1, prec); arb_neg(wcos, wcos); arb_sqrt(wcos, wcos, prec); fmpz_clear(T); fmpz_clear(Q); } void arb_sin_cos_arf_bb(arb_t zsin, arb_t zcos, const arf_t x, slong prec) { slong k, iter, bits, r, xmag, q, wp; slong argred_bits, start_bits; int inexact, negative; fmpz_t t, u; arb_t wcos, wsin, tmp1; if (zsin == NULL) { arb_init(tmp1); arb_sin_cos_arf_bb(tmp1, zcos, x, prec); arb_clear(tmp1); return; } if (zcos == NULL) { arb_init(tmp1); arb_sin_cos_arf_bb(zsin, tmp1, x, prec); arb_clear(tmp1); return; } if (arf_is_zero(x)) { arb_zero(zsin); arb_one(zcos); return; } xmag = arf_abs_bound_lt_2exp_si(x); negative = arf_sgn(x) < 0; /* We assume that this function only gets called with something reasonable as input (huge/tiny input will be handled by the main sin/cos wrapper). */ if (arf_is_special(x) || arf_cmpabs_d(x, 3.15) > 0 || xmag < -2 * prec - 100) { flint_printf("arb_sin_cos_arf_bb: unexpectedly large/small input\n"); flint_abort(); } argred_bits = 24; start_bits = argred_bits * 3; q = FLINT_MAX(0, xmag + argred_bits); if (q <= 2) q = 0; wp = prec + 10 + 2 * (q - xmag) + 2 * FLINT_BIT_COUNT(prec); fmpz_init(t); fmpz_init(u); arb_init(wcos); arb_init(wsin); arb_init(tmp1); /* Convert x/2^q to a fixed-point number. */ inexact = arf_get_fmpz_fixed_si(t, x, -wp + q); fmpz_abs(t, t); /* Aliasing of z and x is safe now that only use t. */ /* Start with z = 1. */ arb_one(zcos); arb_zero(zsin); /* Bit-burst loop. */ for (iter = 0, bits = start_bits; !fmpz_is_zero(t); iter++, bits *= 3) { /* Extract bits. */ r = FLINT_MIN(bits, wp); fmpz_tdiv_q_2exp(u, t, wp - r); arb_sin_cos_fmpz_div_2exp_bsplit(wsin, wcos, u, r, wp); /* Remove used bits. */ fmpz_mul_2exp(u, u, wp - r); fmpz_sub(t, t, u); /* zsin, zcos = zsin wcos + zcos wsin, zcos wcos - zsin wsin */ /* using karatsuba */ arb_add(tmp1, zsin, zcos, wp); arb_mul(zcos, zcos, wcos, wp); arb_add(wcos, wcos, wsin, wp); arb_mul(wsin, wsin, zsin, wp); arb_mul(tmp1, tmp1, wcos, wp); arb_sub(zsin, tmp1, wsin, wp); arb_sub(zsin, zsin, zcos, wp); arb_sub(zcos, zcos, wsin, wp); arb_zero(tmp1); /* slightly reduce memory usage */ } /* Initial fixed-point truncation error. */ if (inexact) { arb_add_error_2exp_si(zcos, -wp); arb_add_error_2exp_si(zsin, -wp); } if (q != 0) { /* cos(x) = 2 cos(x/2)^2 - 1 */ for (k = 0; k < q; k++) { arb_mul(zcos, zcos, zcos, wp); arb_mul_2exp_si(zcos, zcos, 1); arb_sub_ui(zcos, zcos, 1, wp); } arb_mul(tmp1, zcos, zcos, wp); arb_sub_ui(tmp1, tmp1, 1, wp); arb_neg(tmp1, tmp1); arb_sqrt(zsin, tmp1, wp); } if (negative) arb_neg(zsin, zsin); arb_set_round(zsin, zsin, prec); arb_set_round(zcos, zcos, prec); fmpz_clear(t); fmpz_clear(u); arb_clear(wcos); arb_clear(wsin); arb_clear(tmp1); } arb-2.22.1/arb/sin_cos_arf_generic.c000066400000000000000000000211051417376376500172550ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* Computes sin(x) or cos(x) using Taylor series truncated at x^N exclusive. Computes error bound automatically. Does not allow aliasing of s and x. */ void arb_sin_cos_taylor_sum_rs(arb_t s, const arb_t x, slong N, int cosine, slong prec) { mag_t err; mag_init(err); arb_get_mag(err, x); mag_exp_tail(err, err, N); if (N == 0 || (!cosine && N == 1)) { arb_zero(s); } else if (cosine && N <= 2) { arb_one(s); } else if (!cosine && N <= 3) /* x */ { arb_set_round(s, x, prec); } else if (cosine && N <= 4) /* 1 - x^2/2 */ { arb_mul(s, x, x, prec / 2 + 4); arb_mul_2exp_si(s, s, -1); arb_sub_ui(s, s, 1, prec); arb_neg(s, s); } else if (!cosine && N <= 5) /* x - x^3/6 */ { arb_mul(s, x, x, prec / 2 + 4); arb_div_ui(s, s, 6, prec / 2 + 4); arb_mul(s, s, x, prec / 2 + 4); arb_sub(s, x, s, prec); } else { arb_ptr tpow; slong j, k, m, M, tp, xmag; mp_limb_t c, d, chi, clo; xmag = arf_abs_bound_lt_2exp_si(arb_midref(x)); /* Convert to order as a series in x^2. */ if (cosine) M = (N + 1) / 2; else M = N / 2; m = n_sqrt(M); /* not intended (and not 32-bit safe...) */ if (M > 30000) { flint_abort(); } tpow = _arb_vec_init(m + 1); arb_mul(s, x, x, prec); _arb_vec_set_powers(tpow, s, m + 1, prec); arb_zero(s); c = 1; j = (M - 1) % m; for (k = M - 1; k >= 0; k--) { tp = prec - 2 * k * (-xmag) + 10; tp = FLINT_MAX(tp, 2); tp = FLINT_MIN(tp, prec); if (cosine) d = (2 * k - 1) * (2 * k); else d = (2 * k) * (2 * k + 1); if (k != 0) { umul_ppmm(chi, clo, c, d); if (chi != 0) { arb_div_ui(s, s, c, tp); c = 1; } } if (k % 2 == 0) arb_addmul_ui(s, tpow + j, c, tp); else arb_submul_ui(s, tpow + j, c, tp); if (k != 0) { c *= d; if (j == 0) { arb_mul(s, s, tpow + m, tp); j = m - 1; } else { j--; } } } arb_div_ui(s, s, c, prec); if (!cosine) arb_mul(s, s, x, prec); _arb_vec_clear(tpow, m + 1); } arb_add_error_mag(s, err); mag_clear(err); } void arb_sin_cos_arf_rs_generic(arb_t res_sin, arb_t res_cos, const arf_t x, slong prec) { slong q, xmag, wp, k, N; arb_t s, t; int negate; if (arf_is_zero(x)) { if (res_sin != NULL) arb_zero(res_sin); if (res_cos != NULL) arb_one(res_cos); return; } xmag = arf_abs_bound_lt_2exp_si(x); /* x + O(x^3), 1 + O(x^2) */ if (xmag < -(prec / 2) - 4) { arb_init(t); arf_set(arb_midref(t), x); if (res_sin != NULL) arb_sin_cos_taylor_sum_rs(res_sin, t, 3, 0, prec); if (res_cos != NULL) arb_sin_cos_taylor_sum_rs(res_cos, t, 2, 1, prec); arb_clear(t); return; } xmag = FLINT_MAX(xmag, -prec); /* could include sanity test, but we assume that the function gets called with a valid |x| < pi/2 if (xmag > 0) { if (res_sin != NULL) arb_indeterminate(res_sin); if (res_cos != NULL) arb_indeterminate(res_cos); return; } */ arb_init(s); arb_init(t); negate = arf_sgn(x) < 0; /* generic tuning value */ q = 4.5 * pow(prec, 0.2); q = FLINT_MAX(q, 6); /* adjust to magnitude */ q = FLINT_MAX(0, xmag + q); /* don't do a redundant square root */ if (q <= 2) q = 0; wp = prec + 10 + 2 * FLINT_BIT_COUNT(prec); /* t = x/2^q */ arf_mul_2exp_si(arb_midref(t), x, -q); if (q == 0 && res_sin != NULL) { /* compute cos from sin since the square root has less cancellation */ wp += (-xmag); N = _arb_exp_taylor_bound(xmag, wp); arb_sin_cos_taylor_sum_rs(s, t, N, 0, wp); if (res_sin != NULL) arb_set_round(res_sin, s, prec); if (res_cos != NULL) { arb_mul(t, s, s, wp); arb_sub_ui(t, t, 1, wp); arb_neg(t, t); arb_sqrt(res_cos, t, prec); } } else { /* compute sin from cos */ wp = prec + 10 + 2 * FLINT_BIT_COUNT(prec); wp += 2 * (q - xmag); /* todo: too much when only computing cos? */ N = _arb_exp_taylor_bound(xmag - q, wp); arb_sin_cos_taylor_sum_rs(s, t, N, 1, wp); for (k = 0; k < q; k++) { arb_mul(s, s, s, wp); arb_mul_2exp_si(s, s, 1); arb_sub_ui(s, s, 1, wp); } if (res_cos != NULL) arb_set_round(res_cos, s, prec); if (res_sin != NULL) { arb_mul(s, s, s, wp); arb_sub_ui(s, s, 1, wp); arb_neg(s, s); arb_sqrtpos(res_sin, s, prec); if (negate) arb_neg(res_sin, res_sin); } } arb_clear(s); arb_clear(t); } void arb_sin_cos_arf_generic(arb_t res_sin, arb_t res_cos, const arf_t x, slong prec) { arb_t pi4, t, u, v; fmpz_t q; slong wp, mag; int octant, swapsincos, sinnegative, cosnegative, negative; mag = arf_abs_bound_lt_2exp_si(x); if (mag > FLINT_MAX(65536, 4 * prec)) { if (res_sin != NULL) arb_zero_pm_one(res_sin); if (res_cos != NULL) arb_zero_pm_one(res_cos); } else if (mag <= 0) /* todo: compare with pi/4-eps instead? */ { if (prec < 90000 || mag < -prec / 16 || /* rs is faster for even smaller prec/N than this but has high memory usage */ (prec < 100000000 && mag < -prec / 128)) arb_sin_cos_arf_rs_generic(res_sin, res_cos, x, prec); else arb_sin_cos_arf_bb(res_sin, res_cos, x, prec); } else { arb_init(pi4); arb_init(t); arb_init(u); arb_init(v); fmpz_init(q); wp = prec + mag + 10; negative = arf_sgn(x) < 0; arb_const_pi(pi4, wp); arb_mul_2exp_si(pi4, pi4, -2); arb_set_arf(t, x); arb_abs(t, t); arb_set_round(v, t, mag + 10); arb_set_round(u, pi4, mag + 10); arb_div(u, v, u, mag + 10); arf_get_fmpz(q, arb_midref(u), ARF_RND_DOWN); arb_submul_fmpz(t, pi4, q, wp); octant = fmpz_fdiv_ui(q, 8); if (octant & 1) arb_sub(t, pi4, t, wp); arb_clear(pi4); arb_clear(u); arb_clear(v); sinnegative = (octant >= 4) ^ negative; cosnegative = (octant >= 2 && octant <= 5); swapsincos = (octant == 1 || octant == 2 || octant == 5 || octant == 6); /* guard against infinite recursion */ if (arf_cmpabs_2exp_si(arb_midref(t), 0) > 0) { flint_printf("mod pi/4 reduction unexpectedly failed!\n"); flint_abort(); } /* todo: allow NULL in arb_sin_cos and simplify here */ if (swapsincos) { if (res_sin != NULL && res_cos != NULL) arb_sin_cos(res_cos, res_sin, t, prec); else if (res_sin != NULL) arb_cos(res_sin, t, prec); else arb_sin(res_cos, t, prec); } else { if (res_sin != NULL && res_cos != NULL) arb_sin_cos(res_sin, res_cos, t, prec); else if (res_sin != NULL) arb_sin(res_sin, t, prec); else arb_cos(res_cos, t, prec); } if (sinnegative && res_sin != NULL) arb_neg(res_sin, res_sin); if (cosnegative && res_cos != NULL) arb_neg(res_cos, res_cos); arb_clear(t); fmpz_clear(q); } } arb-2.22.1/arb/sin_cos_generic.c000066400000000000000000000056561417376376500164420ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_sin_cos_generic(arb_t s, arb_t c, const arf_t x, const mag_t xrad, slong prec) { int want_sin, want_cos; slong maglim; want_sin = (s != NULL); want_cos = (c != NULL); if (arf_is_zero(x) && mag_is_zero(xrad)) { if (want_sin) arb_zero(s); if (want_cos) arb_one(c); return; } if (!arf_is_finite(x) || !mag_is_finite(xrad)) { if (arf_is_nan(x)) { if (want_sin) arb_indeterminate(s); if (want_cos) arb_indeterminate(c); } else { if (want_sin) arb_zero_pm_one(s); if (want_cos) arb_zero_pm_one(c); } return; } maglim = FLINT_MAX(65536, 4 * prec); if (mag_cmp_2exp_si(xrad, -16) > 0 || arf_cmpabs_2exp_si(x, maglim) > 0) { _arb_sin_cos_wide(s, c, x, xrad, prec); return; } if (arf_cmpabs_2exp_si(x, -(prec/2) - 2) <= 0) { mag_t t, u, v; mag_init(t); mag_init(u); mag_init(v); arf_get_mag(t, x); mag_add(t, t, xrad); mag_mul(u, t, t); /* |sin(z)-z| <= z^3/6 */ if (want_sin) { arf_set(arb_midref(s), x); mag_set(arb_radref(s), xrad); arb_set_round(s, s, prec); mag_mul(v, u, t); mag_div_ui(v, v, 6); arb_add_error_mag(s, v); } /* |cos(z)-1| <= z^2/2 */ if (want_cos) { arf_one(arb_midref(c)); mag_mul_2exp_si(arb_radref(c), u, -1); } mag_clear(t); mag_clear(u); mag_clear(v); return; } if (mag_is_zero(xrad)) { arb_sin_cos_arf_generic(s, c, x, prec); } else { mag_t t; slong exp, radexp; mag_init_set(t, xrad); exp = arf_abs_bound_lt_2exp_si(x); radexp = MAG_EXP(xrad); if (radexp < MAG_MIN_LAGOM_EXP || radexp > MAG_MAX_LAGOM_EXP) radexp = MAG_MIN_LAGOM_EXP; if (want_cos && exp < -2) prec = FLINT_MIN(prec, 20 - FLINT_MAX(exp, radexp) - radexp); else prec = FLINT_MIN(prec, 20 - radexp); arb_sin_cos_arf_generic(s, c, x, prec); /* todo: could use quadratic bound */ if (want_sin) mag_add(arb_radref(s), arb_radref(s), t); if (want_cos) mag_add(arb_radref(c), arb_radref(c), t); mag_clear(t); } } void arb_sin_cos_generic(arb_t s, arb_t c, const arb_t x, slong prec) { _arb_sin_cos_generic(s, c, arb_midref(x), arb_radref(x), prec); } arb-2.22.1/arb/sin_cos_pi.c000066400000000000000000000071521417376376500154270ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sin_pi(arb_t y, const arb_t x, slong prec) { arb_t t; arb_t u; fmpz_t v; if (!arb_is_finite(x)) { arb_indeterminate(y); return; } if (arf_cmpabs_2exp_si(arb_midref(x), FLINT_MAX(65536, (4*prec))) > 0) { arf_zero(arb_midref(y)); mag_one(arb_radref(y)); return; } arb_init(t); arb_init(u); fmpz_init(v); arb_mul_2exp_si(t, x, 1); arf_get_fmpz(v, arb_midref(t), ARF_RND_NEAR); arb_sub_fmpz(t, t, v, prec); arb_const_pi(u, prec); arb_mul(t, t, u, prec); arb_mul_2exp_si(t, t, -1); switch (fmpz_fdiv_ui(v, 4)) { case 0: arb_sin(y, t, prec); break; case 1: arb_cos(y, t, prec); break; case 2: arb_sin(y, t, prec); arb_neg(y, y); break; default: arb_cos(y, t, prec); arb_neg(y, y); break; } fmpz_clear(v); arb_clear(t); arb_clear(u); } void arb_cos_pi(arb_t y, const arb_t x, slong prec) { arb_t t; arb_t u; fmpz_t v; if (!arb_is_finite(x)) { arb_indeterminate(y); return; } if (arf_cmpabs_2exp_si(arb_midref(x), FLINT_MAX(65536, (4*prec))) > 0) { arf_zero(arb_midref(y)); mag_one(arb_radref(y)); return; } arb_init(t); arb_init(u); fmpz_init(v); arb_mul_2exp_si(t, x, 1); arf_get_fmpz(v, arb_midref(t), ARF_RND_NEAR); arb_sub_fmpz(t, t, v, prec); arb_const_pi(u, prec); arb_mul(t, t, u, prec); arb_mul_2exp_si(t, t, -1); switch (fmpz_fdiv_ui(v, 4)) { case 0: arb_cos(y, t, prec); break; case 1: arb_sin(y, t, prec); arb_neg(y, y); break; case 2: arb_cos(y, t, prec); arb_neg(y, y); break; default: arb_sin(y, t, prec); break; } fmpz_clear(v); arb_clear(t); arb_clear(u); } void arb_sin_cos_pi(arb_t s, arb_t c, const arb_t x, slong prec) { arb_t t; arb_t u; fmpz_t v; if (!arb_is_finite(x)) { arb_indeterminate(s); arb_indeterminate(c); return; } if (arf_cmpabs_2exp_si(arb_midref(x), FLINT_MAX(65536, (4*prec))) > 0) { arf_zero(arb_midref(s)); mag_one(arb_radref(s)); arf_zero(arb_midref(c)); mag_one(arb_radref(c)); return; } arb_init(t); arb_init(u); fmpz_init(v); arb_mul_2exp_si(t, x, 1); arf_get_fmpz(v, arb_midref(t), ARF_RND_NEAR); arb_sub_fmpz(t, t, v, prec); arb_const_pi(u, prec); arb_mul(t, t, u, prec); arb_mul_2exp_si(t, t, -1); switch (fmpz_fdiv_ui(v, 4)) { case 0: arb_sin_cos(s, c, t, prec); break; case 1: arb_sin_cos(c, s, t, prec); arb_neg(c, c); break; case 2: arb_sin_cos(s, c, t, prec); arb_neg(s, s); arb_neg(c, c); break; default: arb_sin_cos(c, s, t, prec); arb_neg(s, s); break; } fmpz_clear(v); arb_clear(t); arb_clear(u); } arb-2.22.1/arb/sin_cos_pi_fmpq.c000066400000000000000000000107421417376376500164510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static int use_algebraic(const fmpz_t v, const fmpz_t w, slong prec) { fmpz q = *w; int r; if (COEFF_IS_MPZ(q)) return 0; if (q <= 6) return 1; count_trailing_zeros(r, q); q >>= r; if (r >= 4 && prec < (r - 3) * 300) return 0; if (q > 1000) return 0; if (prec < 1500 + 150 * q) return 0; return 1; } void _arb_sin_cos_pi_fmpq_oct(arb_t s, arb_t c, const fmpz_t v, const fmpz_t w, slong prec) { if (use_algebraic(v, w, prec)) { _arb_sin_cos_pi_fmpq_algebraic(s, c, *v, *w, prec); } else { arb_const_pi(s, prec); arb_mul_fmpz(s, s, v, prec); arb_div_fmpz(s, s, w, prec); arb_sin_cos(s, c, s, prec); } } void _arb_sin_pi_fmpq_oct(arb_t s, const fmpz_t v, const fmpz_t w, slong prec) { if (use_algebraic(v, w, prec)) { _arb_sin_pi_fmpq_algebraic(s, *v, *w, prec); } else { arb_const_pi(s, prec); arb_mul_fmpz(s, s, v, prec); arb_div_fmpz(s, s, w, prec); arb_sin(s, s, prec); } } void _arb_cos_pi_fmpq_oct(arb_t c, const fmpz_t v, const fmpz_t w, slong prec) { if (use_algebraic(v, w, prec)) { _arb_cos_pi_fmpq_algebraic(c, *v, *w, prec); } else { arb_const_pi(c, prec); arb_mul_fmpz(c, c, v, prec); arb_div_fmpz(c, c, w, prec); arb_cos(c, c, prec); } } static unsigned int reduce_octant(fmpz_t v, fmpz_t w, const fmpq_t x) { const fmpz * p = fmpq_numref(x); const fmpz * q = fmpq_denref(x); unsigned int octant; flint_bitcnt_t vval, wval; if (*p > COEFF_MIN / 8 && *p < COEFF_MAX / 8 && *q > 0 && *q < COEFF_MAX / 4) { slong pp, qq, ww, vv, tt; pp = *p; qq = *q; tt = pp * 4; ww = tt / qq; vv = tt - qq * ww; /* compute correct (floor) quotient and remainder */ if (vv < 0) { ww--; vv += qq; } octant = ((ulong) ww) % 8; ww = qq * 4; if (octant % 2 != 0) vv = qq - vv; if (vv != 0) { count_trailing_zeros(vval, vv); count_trailing_zeros(wval, ww); vval = FLINT_MIN(vval, wval); vv >>= vval; ww >>= vval; } fmpz_set_si(v, vv); fmpz_set_si(w, ww); } else { fmpz_mul_2exp(w, p, 2); fmpz_fdiv_qr(w, v, w, q); octant = fmpz_fdiv_ui(w, 8); fmpz_mul_2exp(w, q, 2); if (octant % 2 != 0) fmpz_sub(v, q, v); vval = fmpz_val2(v); wval = fmpz_val2(w); vval = FLINT_MIN(vval, wval); if (vval != 0) { fmpz_tdiv_q_2exp(v, v, vval); fmpz_tdiv_q_2exp(w, w, vval); } } return octant; } void arb_sin_cos_pi_fmpq(arb_t s, arb_t c, const fmpq_t x, slong prec) { fmpz_t v, w; unsigned int octant; fmpz_init(v); fmpz_init(w); octant = reduce_octant(v, w, x); if ((octant + 1) % 4 < 2) _arb_sin_cos_pi_fmpq_oct(s, c, v, w, prec); else _arb_sin_cos_pi_fmpq_oct(c, s, v, w, prec); if ((octant + 6) % 8 < 4) arb_neg(c, c); if (octant >= 4) arb_neg(s, s); fmpz_clear(v); fmpz_clear(w); } void arb_sin_pi_fmpq(arb_t s, const fmpq_t x, slong prec) { fmpz_t v, w; unsigned int octant; fmpz_init(v); fmpz_init(w); octant = reduce_octant(v, w, x); if ((octant + 1) % 4 < 2) _arb_sin_pi_fmpq_oct(s, v, w, prec); else _arb_cos_pi_fmpq_oct(s, v, w, prec); if (octant >= 4) arb_neg(s, s); fmpz_clear(v); fmpz_clear(w); } void arb_cos_pi_fmpq(arb_t c, const fmpq_t x, slong prec) { fmpz_t v, w; unsigned int octant; fmpz_init(v); fmpz_init(w); octant = reduce_octant(v, w, x); if ((octant + 1) % 4 < 2) _arb_cos_pi_fmpq_oct(c, v, w, prec); else _arb_sin_pi_fmpq_oct(c, v, w, prec); if ((octant + 6) % 8 < 4) arb_neg(c, c); fmpz_clear(v); fmpz_clear(w); } arb-2.22.1/arb/sin_cos_pi_fmpq_algebraic.c000066400000000000000000000114751417376376500204460ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "arb_poly.h" #include "arb_fmpz_poly.h" /* for minpoly */ void _arb_cos_pi_fmpq_algebraic(arb_t c, ulong p, ulong q, slong prec) { /* handle simple angles using exact formulas */ if (q <= 6) { if (p == 0) { arb_one(c); } else if (q == 2) /* p/q must be 1/2 */ { arb_zero(c); } else if (q == 3) /* p/q must be 1/3 */ { arb_set_ui(c, 1); arb_mul_2exp_si(c, c, -1); } else if (q == 4) /* p/q must be 1/4 */ { arb_sqrt_ui(c, 2, prec); arb_mul_2exp_si(c, c, -1); } else if (q == 5) /* p/q must be 1/5 or 2/5 */ { arb_sqrt_ui(c, 5, prec + 3); arb_add_si(c, c, (p == 1) ? 1 : -1, prec); arb_mul_2exp_si(c, c, -2); } else if (q == 6) /* p/q must be 1/6 */ { arb_sqrt_ui(c, 3, prec); arb_mul_2exp_si(c, c, -1); } } /* reduce even denominator */ else if (q % 2 == 0) { slong extra = 2 * FLINT_BIT_COUNT(q) + 2; if (4 * p <= q) { _arb_cos_pi_fmpq_algebraic(c, p, q / 2, prec + extra); arb_add_ui(c, c, 1, prec + extra); } else { _arb_cos_pi_fmpq_algebraic(c, q / 2 - p, q / 2, prec + extra); arb_sub_ui(c, c, 1, prec + extra); arb_neg(c, c); } arb_mul_2exp_si(c, c, -1); arb_sqrt(c, c, prec); } else { /* compute root of the minimal polynomial */ slong start_prec, eval_extra_prec; fmpz_poly_t poly; arb_poly_t fpoly; arf_t interval_bound; arb_t interval; arf_init(interval_bound); arb_init(interval); fmpz_poly_init(poly); arb_poly_init(fpoly); if (p % 2 == 0) arb_fmpz_poly_cos_minpoly(poly, q); else arb_fmpz_poly_cos_minpoly(poly, 2 * q); eval_extra_prec = fmpz_poly_max_bits(poly) * 2; /* heuristic */ eval_extra_prec = FLINT_ABS(eval_extra_prec); arb_poly_set_fmpz_poly(fpoly, poly, ARF_PREC_EXACT); /* todo: smallify for accuracy */ start_prec = 100 + eval_extra_prec; arb_const_pi(c, start_prec); arb_mul_ui(c, c, p, start_prec); arb_div_ui(c, c, q, start_prec); arb_cos(c, c, start_prec); arb_mul_2exp_si(c, c, 1); /* poly is for 2*cos */ if (100 + eval_extra_prec - 10 < prec) { arb_set(interval, c); mag_mul_2exp_si(arb_radref(interval), arb_radref(interval), 1); _arb_poly_newton_convergence_factor(interval_bound, fpoly->coeffs, fpoly->length, interval, start_prec); _arb_poly_newton_refine_root(c, fpoly->coeffs, fpoly->length, c, interval, interval_bound, eval_extra_prec, prec); } arb_mul_2exp_si(c, c, -1); fmpz_poly_clear(poly); arb_poly_clear(fpoly); arf_clear(interval_bound); arb_clear(interval); } } void _arb_sin_pi_fmpq_algebraic(arb_t s, ulong p, ulong q, slong prec) { if (q % 2 == 0) { p = q / 2 - p; while ((p % 2 == 0) && (q % 2 == 0)) { p /= 2; q /= 2; } _arb_cos_pi_fmpq_algebraic(s, p, q, prec); } else { _arb_cos_pi_fmpq_algebraic(s, q - 2 * p, 2 * q, prec); } } void _arb_sin_cos_pi_fmpq_algebraic(arb_t s, arb_t c, ulong p, ulong q, slong prec) { slong wp; if (q <= 6) { if (p == 0) { arb_one(c); arb_zero(s); return; } else if (q == 2) /* p/q must be 1/2 */ { arb_zero(c); arb_one(s); return; } else if (q == 4) /* p/q must be 1/4 */ { arb_sqrt_ui(c, 2, prec); arb_mul_2exp_si(c, c, -1); arb_set(s, c); return; } } wp = prec + 3; /* prefer the formula with less cancellation */ if (p <= q / 4) { _arb_sin_pi_fmpq_algebraic(s, p, q, wp); arb_mul(c, s, s, wp); arb_sub_ui(c, c, 1, wp); arb_neg(c, c); arb_sqrt(c, c, prec); } else { _arb_cos_pi_fmpq_algebraic(c, p, q, wp); arb_mul(s, c, c, wp); arb_sub_ui(s, s, 1, wp); arb_neg(s, s); arb_sqrt(s, s, prec); } } arb-2.22.1/arb/sin_cos_tab.c000066400000000000000000007023071417376376500155710ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #if FLINT_BITS == 64 #define Z2(a,b) UWORD(0x ## b ## a) #else #define Z2(a,b) UWORD(0x ## a), UWORD(0x ## b) #endif #define Z8(a,b,c,d,e,f,g,h) Z2(a,b), Z2(c,d), Z2(e,f), Z2(g,h), const mp_limb_t arb_pi4_tab[ARB_PI4_TAB_LIMBS] = { Z8(e6cc254b,db7f1447,ced4bb1b,44ce6cba,cf9b14ed,da3edbeb,865a8918,179727b0) Z8(9027d831,b06a53ed,413001ae,e5db382f,ad9e530e,f8ff9406,3dba37bd,c9751e76) Z8(602646de,c1d4dcb2,d27c7026,36c3fab4,34028492,4df435c9,90a6c08f,86ffb7dc) Z8(8d8fddc1,93b4ea98,d5b05aa9,d0069127,2170481c,b81bdd76,cee2d7af,1f612970) Z8(515be7ed,233ba186,a090c3a2,99b2964f,4e6bc05d,287c5947,1fbecaa6,2e8efc14) Z8(04de8ef9,dbbbc2db,2ad44ce8,2583e9ca,b6150bda,1a946834,6af4e23c,99c32718) Z8(bdba5b26,88719a10,a787e6d7,1a723c12,a9210801,4b82d120,e0fd108e,43db5bfc) Z8(74e5ab31,08e24fa0,bad946e2,770988c0,7a615d6c,bbe11757,177b200c,521f2b18) Z8(3ec86a64,d8760273,d98a0864,f12ffa06,1ad2ee6b,cee3d226,4a25619d,1e8c94e0) Z8(db0933d7,abf5ae8c,a6e1e4c7,b3970f85,5d060c7d,8aea7157,58dbef0a,ecfb8504) Z8(df1cba64,a85521ab,04507a33,ad33170d,8aaac42d,15728e5a,98fa0510,15d22618) Z8(ea956ae5,3995497c,95581718,de2bcbf6,6f4c52c9,b5c55df0,ec07a28f,9b2783a2) Z8(180e8603,e39e772c,2e36ce3b,32905e46,ca18217c,f1746c08,4abc9804,670c354e) Z8(7096966d,9ed52907,208552bb,1c62f356,dca3ad96,83655d23,fd24cf5f,69163fa8) Z8(1c55d39a,98da4836,a163bf05,c2007cb8,ece45b3d,49286651,7c4b1fe6,ae9f2411) Z8(5a899fa5,ee386bfb,f406b7ed,0bff5cb6,a637ed6b,f44c42e9,625e7ec6,e485b576) Z8(6d51c245,4fe1356d,f25f1437,302b0a6d,cd3a431b,ef9519b3,8e3404dd,514a0879) Z8(3b139b22,020bbea6,8a67cc74,29024e08,80dc1cd1,c4c6628b,2168c234,c90fdaa2) }; const mp_limb_t arb_sin_cos_tab1[2 * ARB_SIN_COS_TAB1_NUM][ARB_SIN_COS_TAB1_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) },{ Z8(c584231f,42c62544,77e886cc,aa20f9f8,fe4f25a3,210a5354,2c1d4109,1721956d) Z8(e9e36b4d,c4405259,25cbf0c7,20e25319,b26e498b,6a76a798,55577777,00ffffd5) },{ Z8(0370b3ba,94cd273e,2b207969,23a42900,14c6dcb3,23a6dbba,dbd88646,159e76d5) Z8(c276c47f,596a5b46,b54082cd,09039032,f7502b17,a4fbefbe,0aaaaa4f,ffff8000) },{ Z8(caec7acc,0d534b7e,4ae2e1bb,d3da4dc1,c8be6a05,16fa88a2,4353efc3,20596653) Z8(cd9c4aa4,943448d9,32d90612,ca4a3d86,1221010c,6e8744e6,aaeeeee8,01fffeaa) },{ Z8(e7c976ee,c55d8730,f47670bb,d4ba6011,ffc81fb4,d9fe3873,c6c9dd2e,f9b9ba8e) Z8(4c4ab792,64b0f827,585b1e5f,283c5951,b5b41832,4034032d,aaaa93e9,fffe0000) },{ Z8(8fdee34a,3fc81c11,4ce297c3,b59ee6f6,fb0e8d78,082af7b6,821e7854,3584d0b3) Z8(11de693e,b5ab634a,85d81bd2,cef9d52c,7e126af1,5082ea0d,020665f7,02fffb80) },{ Z8(a40379e7,ad1cfcf5,b7ac5136,6de072e9,f4ad5f6b,18c2a1eb,3c74e210,4a1df9d1) Z8(d94391b8,36bc82aa,f68391c5,18efb2d1,090fa8bf,f6750326,5ffefccc,fffb8003) },{ Z8(fdaf9747,8e9b8e30,566197ee,72435801,c62e2cf7,eb4498fb,5ea2034d,a1bd4211) Z8(985b1d56,077ec1bd,f5624024,62c181f7,1f113dca,aa938cac,5dddda9d,03fff555) },{ Z8(b77519c6,3a897fe0,6eb671be,01e286c4,edc98229,4942277e,e7d32643,9b3ed7ad) Z8(6ac7f294,121a3235,8d241e94,104dd21b,de6ace45,4514074b,aaa4fa51,fff8000a) },{ Z8(e3463014,cf3d5b67,78186dc9,3801a36e,ce2161f8,0373d0bf,6276fde2,4cf23b8a) Z8(f0bfed96,50fae5a7,7c6e0e96,4a14e87a,cccea63e,19b3218a,c4b545d5,04ffeb2a) },{ Z8(0aa8cc75,71ebe6b5,3da0bebf,2c3d56ff,aeedaac3,0b0e9804,0840625f,1e268993) Z8(1f19c22d,8bbdf397,c116c793,644d7b15,9a68ae63,21ed0e0d,0a94f726,fff3801a) },{ Z8(5bacb364,5423d214,a7f1a284,d474869f,89626be2,c4224296,a2fb6ce6,8fda35a7) Z8(4ec65078,057e5d7c,5e37ac6b,848a2e8e,27336737,efe2b515,40cc9541,05ffdc00) },{ Z8(555152bc,0b70a74a,ba9a9f17,8d823963,f1545bab,8a7f9869,ae2388f8,29fa7dd4) Z8(24020b86,f3a5aeed,50c100b1,135c2400,f79e495c,db5d0d2e,ffbf335c,ffee0035) },{ Z8(2e956a62,54707381,b634a0df,4304d14f,986f637c,02c0513f,a293758b,51d78b0e) Z8(a7332c80,bcb27f61,d2358820,03e277d3,4f02b7c5,f20c232a,e163a0dd,06ffc6d5) },{ Z8(b2849471,f41b4606,fa909aed,3958ae98,d8b099fd,0463c8a9,5a06813c,e1bc72de) Z8(9bd85d30,80c5648e,373fe8f1,4ab4504c,5a0fbdb7,382f503a,0a074478,ffe78064) },{ Z8(d76c7aa2,144d32b9,855bd545,58df22c8,b8e9f930,cc5797fe,df450ee3,b1e32374) Z8(5a7ebde5,7c101591,c611113c,e5790d2e,b51e4655,2bf904dd,bbba1ba3,07ffaaab) },{ Z8(b371a8ac,4d44035b,0403f94b,fc753c97,a918e8cd,f252a14b,87eae02a,c062a312) Z8(178307b4,79a38edb,4a661fc5,419c52ed,94946fb9,576da4ec,a93e9589,ffe000aa) },{ Z8(c61d8c05,a71c4e0e,0cfe31ff,702a3eb2,624cf7b0,a4bc4379,e61acfcd,f7950005) Z8(89a8a121,ff98c884,e65f65ab,f5141b95,98feaf9e,e9c9543e,ec0f7e36,08ff8681) },{ Z8(de7dd82e,dfe5e5f2,4874af27,0dee380e,6e9d51d0,f5afeb4b,7508921a,f6287824) Z8(80ed3526,bf270888,13470ce3,34833556,0a46279e,cff60078,5d1de75e,ffd78111) },{ Z8(f2acdfb5,ad9a1227,247ae519,6c2ccd63,7213726b,74fb0fff,a766e63c,1d510a43) Z8(7192725d,98c546be,66df98bd,36a42cf3,1c114647,ec54203d,96a2ea94,09ff5958) },{ Z8(cf146d17,e913f328,856c1462,dca08a12,309a4596,53f62a16,df4bb46b,f9409165) Z8(a0172d2f,485f7aee,45d15a02,ebe3652d,cdf8fb4f,8fa5f362,a53dd0cc,ffce01a0) },{ Z8(b618ab25,3f4a3c93,92c9dbc5,318e0099,2596d03f,91650a8a,80c84678,6e74cb9b) Z8(4d8a9237,43fe8112,a06ac39b,5954c63e,6f26ef10,f4dc6f44,e8b307ba,0aff222f) },{ Z8(686b0cf2,d2546d0a,e9821f82,e2067cbe,8a475a5b,3734a811,a44e2e43,7aebede2) Z8(ad087eb2,1cabe8c4,f7d76b34,2c96bc25,4e76a53b,f9d36cda,010e3f13,ffc38262) },{ Z8(5e326a2e,e353aa84,9dafa9fb,15b99cf8,41a5a79a,85dbb05e,3d0c7ad8,55017ddb) Z8(28e8fa0a,641e30ad,34d0d55c,75f5ca5a,cd0cc475,cc841722,197dd454,0bfee008) },{ Z8(0bde6e4e,85e59162,283b77ba,915b3322,e201480c,be6ad5ee,7acfde55,a0af570b) Z8(c4cb657e,1bf14a18,ee13e78a,299a949c,2a141836,c4a9f9b7,efccf674,ffb8035f) },{ Z8(27f3831d,d9dc50c1,0249e0a1,e39058d0,45873b27,a1436733,362605af,b5f0607e) Z8(87e6150e,700bc36e,47457856,2456f2a8,0a6fa210,f4e5d45a,6b406f68,0cfe91e1) },{ Z8(c7c18c80,c8c66321,5e9e4705,3e2ac7dd,0e50ea29,de046e8f,730584ac,4c07615d) Z8(1ccbf3a3,5bdbd6ab,761964e8,c5ccace4,59264716,14dad735,f07b12f0,ffab84a5) },{ Z8(05bc9d34,5af7980e,490e1805,24f43ec0,a992b594,ae530c17,3acffe21,9d5179da) Z8(16700538,e7b691c7,ed0929d7,1fb4cf74,fc8d840b,393f40f6,2c36d606,0dfe36bc) },{ Z8(02f2378b,14d13a0a,c6e4611c,9ed8df66,b74f80cc,2b81821c,3960c270,6c33282f) Z8(ec6120da,c19da3e5,004fb872,de514ab6,e6638e54,56dbddc0,81d18948,ff9e0640) },{ Z8(430cc0de,34eef08c,3a1329bd,4616f118,cf066ab4,1e1e1b58,607948b5,76cddbec) Z8(8c4d75af,21e7b727,f0bb7a22,6ea98795,80c49f44,62926993,b79b94f2,0efdcd98) },{ Z8(1ee1bfb3,cb84531b,f39b1732,06cf65a1,12243c85,a1fae32c,50ea1854,b8add525) Z8(87f658b2,bbef43f5,a033819b,eabd3c9a,4f571255,54b47558,2234a849,ff8f883d) },{ Z8(7e56278a,89187c07,eb2f7c1d,707140fb,f05f828c,7df2b307,50480352,ccb76f0a) Z8(d8b57b62,c2fd5380,b9cbf2d7,fb074dfb,692d4aca,5d259b2f,76a76d5a,0ffd5577) },{ Z8(a4b2a421,ccd95f9d,8283e803,a116e80b,db02969c,383c3ab7,342fe205,b609267a) Z8(c3e646d1,fff062e6,5a2928bd,f80466e8,4de215b8,070f7328,4fa69a65,ff800aaa) },{ Z8(ea105cbf,8f242ded,485f60a4,729705b9,b64f58a0,56468049,8a56a73f,bd523e59) Z8(f95f4db6,d07bd440,069af9be,5d56f1e0,2310b0a2,2ac69219,e190eb84,10fccd58) },{ Z8(25c9cc84,9d41b74d,7ec991a3,1626bf29,3907baf5,5b6acc2d,d3ae574f,6e8610d8) Z8(3912767f,c39d5e77,5162f111,b9224777,9d896f22,9ff3ef71,87b8e7b2,ff6f8d97) },{ Z8(af957b22,65e00256,9caf7677,a502d63f,74ed61fe,43d02548,93a4f706,6f996eaa) Z8(fa8e70ea,dc423804,1333b122,9d01f567,06c367f3,0b346431,808bee83,11fc343d) },{ Z8(2926e2b2,bec7bb97,b1274918,930d59c0,d84a3e5c,3a2429f0,8874ff44,cd25c62c) Z8(8464f2dd,421cc3f5,c0fe04fe,e564aa36,31dc4f1c,4d24d3d5,477cf85e,ff5e1115) },{ Z8(b1bf37d2,66af74fb,9aff687a,3897d0c1,30a9ff12,a76a1900,0b45a631,01b083c2) Z8(1cb8e835,ef221a58,268cbc2e,d6c70725,b448ff77,5311496b,ecc91fee,12fb8925) },{ Z8(f95d4ba4,1e85b5a2,e0692cc8,f52a985a,8d4a5c5f,ce9ba136,78af5602,673fc263) Z8(0d809f91,ba2688f6,f6a90446,e48a761a,aadeb56b,2fb61530,0b739799,ff4b9535) },{ Z8(ab68b561,5bfb6a58,1993388b,da0d0faa,3ae46c1f,9a61bb82,27c3ed45,4ea73543) Z8(3f537695,d0227066,f70faa38,058ee45e,e5d278c9,79bab59a,d1755a9b,13facb12) },{ Z8(286858cd,479546ad,cfc3c87e,e61cffa9,1a4c8daf,ed7df6d7,99386baf,43698254) Z8(daecd3a9,3d4c4669,ae6d2f79,b9df9716,834be062,05e641b4,4f7b771a,ff381a09) },{ Z8(4e732490,d0c331fc,5c6f829c,aa0498aa,33c32e71,7c57c71d,5d6bc519,d10b0cca) Z8(d9021f07,5163be06,20dc13d8,20864f53,69d7daa8,f762fe33,ecb8ff5b,14f9f904) },{ Z8(7c6947be,81cb80a2,6d18f2c9,1b9c4b49,de75722f,b08ba501,305b0279,c94d2283) Z8(c0d3c8c0,bb3a52b4,0e832d8a,ec6f57ab,da869d0c,03ba444f,8ebeb340,ff239fa5) },{ Z8(f59870b9,b0304ef0,18049042,86b6ffd7,06c44e8a,2b76f95f,17ee1716,3e712d95) Z8(8c318a2b,39d3e770,62f294a2,70bc6bdc,bbf76e6d,9ec3f505,10b736bf,15f911fd) },{ Z8(548b838e,41e7e7e7,57082561,bdbdb5b6,ba2dd0f9,d97a71c7,0fcd03fc,f77b6923) Z8(b329d0a7,5a664a6b,bd40392d,c5c1d16a,b5fd8a7d,5636fa83,439f57ea,ff0e261e) },{ Z8(83f689ea,efe10703,1c1f1a6c,4384b68b,6e9d52a3,596e264f,0e007ece,18c8e97e) Z8(af07ad8b,a57447cf,1a5a85de,6b4eba44,c92cdcce,30bd63b0,248d1edc,16f814fc) },{ Z8(4523e228,bc493f2b,c2d10cdd,234f720b,17b62a10,8cb91c0a,5f4a7270,8cda3c77) Z8(b5ed0cf0,462f9e3b,da551dd2,bbc1fd4c,7cf9f237,cc5f79cb,e7a2e617,fef7ad88) },{ Z8(0566391d,9e5c45f0,77b2a1c0,669ee14c,a4e4c850,27c6f292,1adeb42c,0a60fc19) Z8(db21f7ef,cdeae791,c393f5aa,e59085f4,501a1007,fc2d1800,2550e41a,17f70103) },{ Z8(76835799,629120d0,53e6ac1a,dacc91af,01b35920,6ffb549f,ef3f03ff,dfef1c85) Z8(d817f7af,f56a11fe,b961faad,c3813d8e,1b6b28df,2056a6bf,f35cda63,fee035fb) },{ Z8(a4e73e3b,d40b012f,4257c48c,70ed1cce,86889664,15230d12,ebeb5525,fea63914) Z8(17b61e98,efa07ec7,fc8c685d,0a90054e,3e43dc1f,7148236f,2710c40d,18f5d513) },{ Z8(62ed8ec0,209158eb,489539ab,04833c81,6cc0ec19,2a3dda43,d49c3386,a32002e2) Z8(69e18b9c,eabe2efd,e241ecf9,0c2469ee,f49478bd,5a260aac,de583471,fec7bf8e) },{ Z8(8d4da807,4e0d8065,b9304511,a5f02377,f85f6690,402559e8,1b1db1c3,436d35e0) Z8(d31d8bbd,9ffd4ea0,4bce6926,f8f43d55,77057fed,a5b5fab0,55d1f949,19f4902d) },{ Z8(a553bef3,7c7f2939,d24f4f92,62592faf,b5e4b3a8,fd12d6fa,fecfc368,15101e2f) Z8(9992d651,8283e936,8db3438a,e3ad0116,683996b6,c4b9a583,1effff68,feae4a5a) },{ Z8(4f045470,63bfce84,3a3e8fd7,73fb16e0,8787f997,36cec84b,ac97d990,b88ad604) Z8(c06aa038,dc416b66,f0232d76,2c5f9dd5,8fc2d005,dda62f74,f68f8f4f,1af33152) },{ Z8(5c98ca1c,87228a90,a03f5e42,77e3e076,b4040fb8,6e7e65db,9e7afdb9,e635b654) Z8(662af19e,d885a3f0,7bd7541f,0e5506fc,68251eef,ec97d26d,2a86db87,fe93d677) },{ Z8(c7066510,bbbd94dd,240c2ef3,f4e632dc,93169355,2189fab6,36431a8c,8d20af40) Z8(982e55fc,908d103d,4b090171,127f3274,331f2958,461077a9,68391d7a,1bf1b785) },{ Z8(5d948d86,6ee2bf5b,aec45210,fb4dc741,503e607f,c4da16a0,cc9ce305,b0378c13) Z8(6d8c8afb,f818c271,3aa13760,d38361e9,35611b2a,1ebc368c,74cd88f5,fe786400) },{ Z8(e33a955f,cf3546b8,949a11d7,8120ca71,446966a9,0f24ced4,399b2ee4,04d1d814) Z8(f9059dcc,1706070b,55e54f48,3ffd150f,13b03e4d,25448230,24b167f8,1cf021c6) },{ Z8(adf46942,a2388da1,d5466af5,64e86d26,2e9ab459,21f5fbd0,32b13254,b80a206a) Z8(3edc9ebe,ba309ffe,db072b72,3a34f6a2,0869db87,dcc41bda,704873df,fe5bf311) },{ Z8(94df5b1e,12ca6964,3abc9187,63e0408d,ae61d6e3,e44efc1a,39d75460,0edc3bbb) Z8(63c8027d,93b7af14,c6e6a3e6,b4bff38c,d31ab219,e0e3a091,c1cce5d5,1dee6f16) },{ Z8(460094ec,4b0d0c5b,18b6a474,8cc0c65a,84003219,81ccc41f,6b5e91d6,b8b4ca4a) Z8(c5758c70,eb1cd1ae,52fc525c,bd08c2eb,d0a10db2,ba488fb6,8de4420e,fe3e83c6) },{ Z8(d086de7c,551fed65,5509260d,c756bd7e,fad0a838,52307b68,45a5e91d,a1a39aa5) Z8(0a1e26af,eeec4318,6e163f89,0a9f3865,7f667db7,53517588,f2502b13,1eec9e78) },{ Z8(201c25d8,5780059f,d13d9302,1c048b26,af78c89e,38d3c38e,66bb5421,c58b80ae) Z8(efab5ff3,e6e23df4,e0cfe54d,2df1cdc9,7d15c02f,15d61e3b,3ce961f5,fe20163d) },{ Z8(c3450e07,fa68567c,427dc1a3,e5bd5ed0,497e9b70,9c828f90,1ad10ae2,d190d545) Z8(59fd631e,007995f0,5e671884,5995027b,1f89f85a,069a8672,86ee35ca,1feaaeee) },{ Z8(b7a7f8bb,65f0ab60,6d2a89ea,f2a44834,6b128c15,b1146ebf,41c56b3b,34935607) Z8(e7026cf1,962ddb33,783f8310,649bab98,f6f18ce5,1e6a129d,eade9b6d,fe00aa93) },{ Z8(a62d54fb,8074f616,c56e9754,58170296,7aa0ca6f,79823197,d1890ddb,b83f4334) Z8(434101fd,1e3bd662,5d761f2a,0f709e0f,8dcb5faa,07bfa5dc,6f469d65,20e89f79) },{ Z8(17899f6f,507af05c,b2bb6bc7,24c81bd0,ca1a50f8,64f99661,5c027437,dd1725ca) Z8(09aae2da,dd89d1c9,3a1bcefd,a03a1762,228a7597,94b8c338,036aa233,fde040ea) },{ Z8(60d10493,9737abda,a47115de,1d5f2427,cafbe64b,2ead12fa,54b24032,63894f67) Z8(c133934d,468079cf,efa586a3,694337c5,7cf273ae,23439278,bae3a2ec,21e66f1b) },{ Z8(1aedb10c,e1d26be9,59389d07,5224f5ae,3f0163e4,b75f394f,87a792da,e12ae5f5) Z8(3e3042b8,0a1c0555,c9f01e19,bc7d13e5,56262d4b,b5be9ecb,f034aa43,fdbed95f) },{ Z8(40622711,76bd567a,aef43b37,050f8dd6,2840b796,5522c0c0,782d4de8,5420c993) Z8(04842db9,f3c3b91b,8f6c1556,b6d9b1f0,99b81198,7ac4b9eb,9a382164,22e41cd7) },{ Z8(8f82702f,ffee6801,88f5b597,1caa9490,6a1a5d64,076e9dd2,2df5461e,36ebb7c6) Z8(a1cf8174,5b28854f,d4b33767,152f1a34,a30f5a1a,ba3d7221,18c3fe32,fd9c7417) },{ Z8(d37be716,e3e0b905,ad7c3033,a866ded9,2fd17173,f608a6bd,22b21c87,ac146ba0) Z8(2e7a881e,d9f0deda,bf5269e0,4194f3c5,b2da517a,8357b344,5f9d5d48,23e1a7af) },{ Z8(14c65cbf,10a0db89,bd87f6a1,e60e5f47,f5b973c1,df989770,2865dcb2,0e9b3e85) Z8(1f0f43d9,56dba79a,76b5a002,578c42df,625d2cc1,54c7b317,e25e97ab,fd791131) },{ Z8(3b5b78e1,321b7100,83db7f75,8e73b897,b9ab8d58,d7226748,60e55315,d6d78c4b) Z8(932ecb31,4e88cb59,f77eedc7,8c078c50,0e166fd3,9d3f9956,8050b219,24df0ea5) },{ Z8(9d20a707,c6cf89a1,10dbae84,c335a2bd,1bd2260f,b699ff0b,08b4d627,f30b13ef) Z8(ee6341b3,50aa7578,1866de04,86962c63,71fb1b51,95db8a61,afe6ba2a,fd54b0d3) },{ Z8(8284ef6a,a4bc2772,17a3af8f,d7493d3e,0792be5c,647a8999,9ea0c655,7420e9cc) Z8(68f35665,8b1a1129,b7a1e36e,959ee0bf,fd438cf5,9787d108,95711d0d,25dc50bc) },{ Z8(f5b07c65,97f130c9,906afbd4,38e9939f,e7096102,6548dd92,358ce0f0,6bc837c4) Z8(6d03cb00,bc524376,f1014b0f,a7b873af,98f79caa,9b4dda2f,e1b79020,fd2f5320) },{ Z8(290eddf7,daedd153,03c15f3d,873c5939,4ed3dfbe,68f42a67,c974b4ef,950f973e) Z8(8d13bd33,803887e4,343a06b5,e9fef5cf,03e64f6a,94e6d8f4,5cfca3da,26d96cf7) },{ Z8(7f9a2933,98aef8d1,f9a1cf4d,9b2b6c98,86d1360f,540b614a,9142fb26,535b01bf) Z8(b523e6eb,f0f6f474,c37c929d,fc113842,343f9dfb,6de19f58,d580ca98,fd08f83e) },{ Z8(5303bf5b,945bf567,97cc631a,101fee1a,c9a382ba,946c7b36,d8e715c9,bb6bdc22) Z8(6234ffde,9b8db9d3,b56a489e,38c5142b,5c87d594,eb335b36,bacd96a3,27d66258) },{ Z8(73c8905f,3b423688,f9e8c865,269f96c0,271485b0,a5a9a65c,649ac8f6,9813c9cb) Z8(ec796a24,10e95144,6f922acc,9dc71aa1,8c45bf0a,6d60c76e,e621438b,fce1a053) },{ Z8(b686bff2,ddca4706,e3a38c84,9ef55bf4,3fb654f1,3d5af067,d686df53,df56e55f) Z8(4d5c4e34,24dc8f60,04c9388f,e7c0cc0c,d52615ec,bb93bcf6,b997ac0a,28d32fe3) },{ Z8(3328b8b1,e961cbf7,2fc12eb2,f11a59f9,ba59a1a1,cad45d81,dc86617e,4ad98645) Z8(c87549b9,f8f4e14b,005fa5d6,429906c2,611352cb,a8dff287,6b80a305,fcb94b87) },{ Z8(0e821d24,ec5c5c2e,232db060,8bea56a6,462ff518,5280d9b7,ce1fb70d,53ff7c6c) Z8(1450f62e,226e410b,d105473b,34906c3d,cbf04269,276cab01,8be4f665,29cfd49b) },{ Z8(079516b4,a3670a4a,018dbf1c,bf4affe5,bb1c37e8,c3c52bc8,7a3cfd2b,acdb4030) Z8(fa50a6c7,e08019bf,07d22e19,ddb0cc4c,0d9fdf1f,7e05962b,ba680741,fc8ffa01) },{ Z8(69cae50c,52c42911,719180a3,61970d72,213f2b77,77dbf7ba,0d5430fd,d7f2d28d) Z8(9063d905,815f583f,2d073b04,7b270c83,5038d871,2cec8306,8d12b11f,2acc4f83) },{ Z8(e943c791,24da9455,8ed481c8,5022655d,b3145951,61574cf9,9e4bd137,69bdc509) Z8(50ea4f08,89aa03d0,51b6d271,171463e1,3367cc21,d7359adb,2459afe1,fc65abec) },{ Z8(a673db34,272c4b73,f8226336,a2aed2f6,c7b9d34e,af83672d,53bfbc62,f3b58a92) Z8(dbb9da49,736feb95,8c3244d4,b9faf564,b2514952,5de7ce03,424de548,2bc89f9f) },{ Z8(086825b4,e348ecce,1692070c,1b441897,bd7aeb72,01a567ed,0e3980c8,6bf361b8) Z8(0ed82b53,5d585585,f153a426,b5e59d3e,9d439e1d,5d63d99a,f767ac73,fc3a6170) },{ Z8(530e7239,b201f60d,38f2e7cf,e1d3851d,3c6eaf0f,7bb2a34b,db3f48a1,aea4099d) Z8(9ba9c0ae,df615113,c430d741,f7353fa0,ce212c18,cc8e22c0,5b8fe451,2cc4c3f2) },{ Z8(80a5e0c0,4fba1d9b,a61a7bd6,a9aaadaa,2b028755,a8be45ed,275f1dce,c467ff32) Z8(366e5194,dcb67a39,84cf822c,bda2a6bd,bd807d00,ef08d62f,7e098e5d,fc0e1abb) },{ Z8(2af80f28,9db27e1a,566f6f41,52929550,9b0559f4,536a1319,cacb565a,da02c04e) Z8(48cae929,8e7827e0,cf58b12c,af47ed2d,f8db9df7,b34e8dd1,b49a97ff,2dc0bb80) },{ Z8(62ff4a31,0744c695,a089bb0f,6209a983,34ee4949,4b3acbe9,c0bb557f,b3c7b981) Z8(bbe9ce04,781f9821,3f676b47,cea20c8f,f4f6a457,aa43b8ab,fef11e70,fbe0d7f7) },{ Z8(353e0183,b81af745,4a9b2bc8,6ab49d86,b0103e78,c57717e3,1b15e006,4877f9a6) Z8(397b18a5,be0adc98,82b525d4,7cc342a6,ef093831,880eddf1,55f4a692,2ebc854e) },{ Z8(c2d2970a,3ceebc00,b7011917,547e18d0,81c6d2a6,e9df07a5,b7a65f52,7c027f28) Z8(ea98f374,5f617294,ecd06179,0b585e0a,1e8ccecb,d499e08c,bcde1633,fbb29953) },{ Z8(cebbb957,432de451,392a9edf,9420aa30,7b858240,ad4158c3,5151ea43,4b44a6ea) Z8(59a6b00e,2c05e4df,e0189ef7,769af396,2f856258,56a1c479,75e56a2b,2fb8205f) },{ Z8(f29c7c34,b36ec3de,a7ac174b,92950edb,f914f757,8c62b2e5,3bc76154,26e8b67b) Z8(9f43aa56,9b783f4f,e9cdb389,ea358867,697eea13,e6fe7924,f670dd2c,fb835efc) },{ Z8(472a11a6,b8f66361,5d3a47fb,494f448e,3931fe0a,d27caa6c,ca161ab7,13c532a8) Z8(8106cc5a,095add11,3cae53a0,beca2111,4ca9c252,6b2c6ec5,7970ba6f,30b38bb8) },{ Z8(78b64c55,3aac246b,aad59e35,f72f30a7,c15ef140,1bf9109a,023cc002,08b17312) Z8(a104d886,d793fac3,3cd2bc79,d6f332da,6481a438,00da3dc0,e5fc4a42,fb532922) },{ Z8(a29f44dc,17abf4ff,35c8dea0,d4052966,b362968f,ca06bed0,0c108e9c,c15d57c3) Z8(6e1da919,b0b3698d,983d7011,6eba6799,35671324,82ece9a2,f552876f,31aec65d) },{ Z8(0af47eb5,44175df9,0a31272f,1c486f4a,a2e217ae,3daf385c,57cf029a,cc413862) Z8(99005dec,a46c6843,df80d9c8,674a92b4,8ac5fd76,00ac1fe2,c156696b,fb21f7f5) },{ Z8(8641e1f4,a74b57a1,c69985c9,cdba1007,40a3e9aa,cd92e011,64e7d7cd,33611ab5) Z8(91848e48,726fb98e,8a96f45c,1d1bd8f9,a40755cf,e88f1581,aefa44d6,32a9cf54) },{ Z8(9da7b864,67a4a5e2,a905091a,7943f26f,be87f569,51c92769,42c011f6,e4cc980b) Z8(aef3677b,679371a0,8500ea7b,0006144d,3aeaec85,7c8dc77c,b9a845df,faefcba6) },{ Z8(4b8f6574,73876ee7,98f8fd28,c86d0e9f,71b6631f,7eec963c,fd47188a,3a188879) Z8(e0a7ed58,eabb82e8,938477ae,3f4639ce,4df4fa51,10f602c4,9d862467,33a4a5a1) },{ Z8(3041d24c,887c78bb,9c277e34,12363c24,6fce6d7e,2dd47028,334e579b,726c3301) Z8(bcf3676e,f7b7609b,6ecd1cc9,5bfd6829,8ea33ade,d069f01d,fb3cb8f1,fabca467) },{ Z8(f827078f,54af72e4,b15b1a67,76112e76,c54e6406,1c1cfe1f,973560ef,1a401513) Z8(bfbdd303,6f87055e,106bb22e,5635c551,12a7dd92,7e1308d5,eabe1ec4,349f4849) },{ Z8(17db4da8,eaa50adb,dde92e41,5bc2e23d,8af5a107,3d270829,ae903e3b,5106869f) Z8(8aeb28b0,30a13383,b05395da,bb0764f2,1a0a1321,73057b79,ad4e3dc8,fa88826c) },{ Z8(8aa21f3b,79a77c70,d15156dc,e12eb7ff,04062f5e,cf92d656,93e8ff18,8df5f4f0) Z8(886f715d,18b97f48,54555de5,59c98d4e,c8561de1,df12a0a4,f40ec999,3599b652) },{ Z8(204f1879,5560e0af,aacb0461,a7a378b7,9a119b9d,dbca10c1,bc18cad5,49953a09) Z8(7a380df9,65a2b8c6,ab0f4ccf,3d7470a4,6ae64d98,be1db5d7,f1d3ca27,fa5365e8) },{ Z8(eee0fc74,7c870012,e8745cf0,2cf1187e,a24e377d,cfe151f5,0f6564df,f5bfca8d) Z8(abfea583,956ad6a3,68abb74f,9034a33b,b1915674,97d0c986,4b83fa16,3693eec2) },{ Z8(0ee24e4e,74b214bc,ce7ff12a,0de8faf5,ee0defbe,f9dffbad,bb995d1a,c73c9949) Z8(f765bbd7,a78b42f8,aa305870,9907eda6,a320fc87,50cdc117,e54cac7f,fa1d4f11) },{ Z8(3f3dbaa9,271dbe0e,0dabe8ba,d8ee03d6,6c3015ac,2bc1ba1f,5232ea30,1bb9f1da) Z8(11c1cd24,2b496c6d,768f68c3,26ea336c,65582e45,0d2b53d8,b8c332ce,378df09d) },{ Z8(62fca407,508dd123,53b9335c,0d26d438,17a36a41,311495c3,b4ec686e,65e72f7d) Z8(bed24b63,7bde901a,e11e09fc,1fd7fa2f,5b5ed9c1,2e296bae,9e8b6f6f,f9e63e1d) },{ Z8(b18c367f,7450450b,1e1cf3c4,2a4964a3,e7463b2f,86ec0904,a6b43640,da605a0a) Z8(acc640bb,91dc8e20,84ab9fa6,45aaa1b2,733b4832,4867a39f,3a05dbfd,3887baeb) },{ Z8(38ab1d3a,0e905326,1862e65e,35d0ea9f,d21fa777,e39e98e2,7aca61a0,527af66b) Z8(110b0dd4,d9d81bff,44aec93a,e4aeb34b,df0f350c,b483e7fd,2e7fc2f9,f9ae3343) },{ Z8(414796c0,142875fa,76f2bbf9,8a242e2a,78ccdf68,c187e30c,0c85ca6b,473934e2) Z8(36a10ab1,03bc09a4,675ab855,b150c21a,1ca6a337,b97b21bc,0513453c,39814cb1) },{ Z8(329fd9c0,4129920c,264eb5e2,d50e1950,6e7e8818,8e5ee38b,61b9e6ca,aeb6e52f) Z8(9b148921,6b2288d0,875ae63d,fb0f8d5b,b054a932,842beada,9fff6b98,f9752eba) },{ Z8(9dd69757,6eeb4648,29e9c996,759dd204,3151d8ef,6345f815,4204a3aa,4a74f4b1) Z8(fe1e4d05,f1965677,6209b1e0,62b4daec,7b2fc27a,16996ee1,883a6fa4,3a7aa4f5) },{ Z8(65a9745f,173be354,c2959358,1ed16683,1356ee74,1a4ae06a,3f97918d,87e9c06a) Z8(98efcc1e,5f4527f5,1d0cbba5,b7a6b6fe,1a508f3d,6683b3c2,f78e376b,f93b30bc) },{ Z8(91df6e48,02edc2f9,b401611d,73942968,6624a6c5,42e4a4a5,e02d31f1,1412f8c2) Z8(0515c18c,e58cb847,fa64b086,087f1753,81f0d965,8ef9499c,6b4b9f66,3b73c2bf) },{ Z8(479b5441,91b850ed,501eb4d1,a20cc972,3e42faa1,4b9639bf,6742eeff,57cae032) Z8(50493ce6,5788a861,7354d426,1fc733d9,84b6cbed,40416c19,3324f9b9,f9003984) },{ Z8(102f656e,78624014,1791524a,115d9dbd,43af1d83,d54ddaae,90bb46fe,6357580f) Z8(ddac0faf,777e7b8a,c42c9398,47ccee4b,9c01c98f,bf48c0c6,9091b3ed,3c6ca515) },{ Z8(891856af,a661b9a4,948b8e0c,66621acc,1713922d,197348a4,d29335a8,4a819493) Z8(5477100c,b49275ff,8c42e7c4,c92921e4,6626660d,13522ad6,49f78cfc,f8c4494b) },{ Z8(b49f77da,07a9227b,5c15ea5c,f9650f9d,2c708ecd,4af0c5cc,ffaad557,ccc6dff0) Z8(309b626e,472d9d40,26609204,39a8a406,98aba330,0fca8546,15cb457a,3d654aff) },{ Z8(5277f985,7987684d,449bc9e1,e9692d7a,9faa7810,bb40dddf,97bc188e,c2c1d496) Z8(d3fcfe9c,78ba8a28,5ad99540,ffc95b27,5059a789,0e4ec582,2c39dbb2,f887604e) },{ Z8(d2a5f4ad,5c0f3956,a9386272,34c99185,5c19709e,d74d5d64,1e1c88ea,b9ef1b51) Z8(733e38cf,acee1e60,184d46f1,7c43acc7,ea47637d,5e90bf79,5523874f,3e5db383) },{ Z8(56742729,f138feb8,3d9e8edc,6614ca67,e5c62b8a,a83993a9,3d9a2eb9,499f7a33) Z8(721b6afc,fa60f463,24c78f58,5f1f1f68,db0c7d4a,a0ac7537,c2e3f02e,f8497ec9) },{ Z8(4067fb09,06ae637d,ab3570d8,bd2a7e39,50b49ce5,2b800c53,42a81914,3c7f2854) Z8(af9330f0,898d7086,8d7db525,dd567664,6a3d1635,13bd7b8e,e62aed75,3f55dda9) },{ Z8(3295498a,2b7c5621,9c7761bc,2bbdaa00,6bb135bf,3a867cc4,ee16d0b2,0795b84f) Z8(c944551c,3ef9ec13,9edc4a02,1426dbe7,5f94f8a4,83d33cb9,ef750ba7,f80aa4fb) },{ Z8(3c001d52,151ddfeb,5720449d,2b04dbb0,82e2af67,cf6bf73d,785b5de3,95279123) Z8(c0efcd45,b0842f93,c12eebc9,4f5a9ee4,31536996,fa1d5106,9ecf9510,404dc87a) },{ Z8(73b5c7ce,d4209413,cafadcc7,3cb81ac8,6965fecb,d0ba1d9c,82e6c127,c49edb12) Z8(26b105be,53bd1d9a,835f4c00,d0757657,b5d41038,a207f321,8bb5c4ba,f7cad323) },{ Z8(0b4e4419,f06bd15f,fd4cca47,52b82aa8,b1a42a7a,94dfd8df,5d54f535,006426fb) Z8(8c4705ae,2e3e370e,db527011,c0ba050c,1388dd47,73d62027,94556e64,414572fd) },{ Z8(816b3a64,4f297bd3,2fef2a05,275623c7,b15de5e9,079a929d,ad7486d6,0e2c1547) Z8(5371b897,3311b4ba,2aeb446b,8cb1ab82,91b7c5a6,bc9ee425,69792daa,f78a0980) },{ Z8(ac1bb344,0f70ba42,e6777e38,7fb2628a,15382fee,baa9fa64,d4fad9ad,ee9abeec) Z8(6941cb73,9f3401ee,d6b1c5a9,1ddd1523,c09cc1cb,e1415ed0,1c4e2773,423cdc3b) },{ Z8(c91fc0de,c8b61213,9c6f9ba5,d735d464,681ef963,6ccb8c3f,dcba28ff,a6349c9e) Z8(5385a006,952f5202,22a82e46,ae7728dd,c64325b9,ab3522e2,525d0291,f7484853) },{ Z8(4a086b50,9caaf926,0683ce54,95a6ead3,8198e56d,618f31e9,9b70d7f1,2b5ffb37) Z8(968fa796,70b50e5b,8275b774,a8715043,d4b84451,4f5f36c1,cd90d660,4334033b) },{ Z8(88ed4f73,c4cd7bef,ed046287,12213b2b,fec017be,6854cdc5,d1fc5947,df9557c0) Z8(b5940ff7,1159620a,fe8b22f4,53e3c50a,789e4f42,05b8fe88,0788dfc8,f7058fde) },{ Z8(dd9c2b8b,b9225f64,3a6851e9,6fd068a1,faab5833,da341844,95ae8e14,0da2615f) Z8(56ae66dd,a5025618,2a9eeeec,9549e059,84089e5f,c39d6a5f,8131627b,442ae708) },{ Z8(6de708df,42d9c989,6c40ae4b,9165a1ef,500e8dcd,f700a4a1,218b1462,1dd844d5) Z8(861cef46,fa36bdf1,66656c91,25916702,f56e89d3,02d488ad,416c80c3,f6c1e063) },{ Z8(b6db7d18,16e5da80,0037eb0c,60b941f3,b7722f6e,22bd789a,a1a16170,21ef3317) Z8(2c559410,8c111ad1,6ab88cf8,969f4716,52e3a06a,bbf2524f,5377ab20,452186aa) },{ Z8(a5f01ac0,13e5dd25,2040c599,95026acd,08c891eb,3a6eb853,3eb1cdef,edc3f2e1) Z8(15ea3242,f53627f2,46c031ef,efb96d5b,f8c0067f,4bd6d42a,af7d07aa,f67d3a26) },{ Z8(3d593fe8,c381e987,11cc7e5d,181d7e08,87545172,d7c2efa6,43607e25,86acb0f9) Z8(87fc981e,224dadb9,4836f20a,b60d110d,2273de56,bc890c59,a4d66b55,4617e12a) },{ Z8(328299f3,7b6294f7,918f6e85,c3ec418a,050e0c5f,3daff194,d41dba22,0f1dea7f) Z8(6ac1e297,e0bc6486,46007655,8f7c4974,2ac3d9b2,7e80892a,f7f14de8,f6379d6c) },{ Z8(2bf07d16,dbf41cea,8ccb2f71,2aaa9b54,63a979d9,3ff98c35,fd335d10,98b5ae87) Z8(639e1f42,21f8462b,8ebc6078,bb2ede61,ff47fe31,076fe0dc,1ae1d946,470df593) },{ Z8(fa289398,cb4f5054,b36a1f04,25331b20,4fadab99,74d7a229,451a7da4,29977994) Z8(168d2e7c,3b9d623c,c0f82bae,80d01ce3,78427832,0c1da8b5,b77d3dfa,f5f10a7b) },{ Z8(8430150d,bc8cdf5a,2700ba20,a022c99d,8f591548,1716410e,0ccc2d0e,f28b18e2) Z8(9daafa54,852c337c,3d534aaf,10e23a4d,ac3d905c,dee4b477,a1460098,4803c2ed) },{ Z8(749e77ec,083c9e69,796d8528,98492c95,ad74be1a,d3931535,4d3ca4a6,048f6642) Z8(f3406952,6f05ea2f,bed01908,bbc1ba33,9bf46259,1c17e81e,810c36bf,f5a98199) },{ Z8(8ee904dc,b1ddfb71,a38d2b68,78ac6427,c9e12447,846afefa,5c21c742,b933e698) Z8(49514d44,948c7cdd,b0d24b59,eccad880,0e7a1b26,f7fccb10,6abcd6b0,48f94844) },{ Z8(01bc24cf,22ada201,75f79ca9,f4b8866f,0c1f0329,38bb6699,713def78,7fd00509) Z8(155cdb0f,e9ec48b3,5547bafe,4995667f,2c652155,0ea9f4a3,dd7a7896,f561030d) },{ Z8(26996ea9,ab9a0fb1,4be4664c,abf82c72,df50da72,920ba01e,3837b3ab,13dfd56a) Z8(cecc077d,36f4e7b4,8a2eb9cd,4297e48c,fca041b4,097ceb54,f20407de,49ee84a1) },{ Z8(b68fc6dc,9356a581,fe3720fd,41dba282,0fc23032,efa231d2,52605264,4bbe0113) Z8(496e9039,703d89b2,522a5c49,b5d7a7af,fd25b4c1,32933b05,4b4d9c85,f5178f21) },{ Z8(b514701d,b76b3e5d,3b25ad21,5334651b,f9a2c714,2bd556e2,16ec3e16,aebaeb97) Z8(9f86190a,499f05c2,a1471775,ce07dc08,c03519b9,a9c4cf96,fad27c8a,4ae37710) },{ Z8(50f24f80,983a3411,04c1dc43,261a0da6,b2bf92e4,2d839243,1959a705,c91e259c) Z8(58ba924c,feb39ed1,51c0631b,0b7ace2a,630d2ac0,369c8758,3e6c15bb,f4cd261d) },{ Z8(86cbba77,905adea4,5bcead06,e6320f61,157790ef,1f0c1458,0fb8d36f,af97d249) Z8(44bceea7,279a7280,2494d22f,2f52be53,fc42e332,f6b47bd3,92cd9570,4bd81e9c) },{ Z8(2dfc4611,97030bca,cb23b842,2d59631d,f6bdcf73,d5783dec,4291ec8c,43b09e11) Z8(2bcdc8ba,aaf43840,fd2cb93b,a5985f4b,4e165229,d56700e4,1fd3bdae,f481c84c) },{ Z8(2996c96d,b735b802,d80aa63e,b24ef7d3,419310bf,ca1b43cb,02fd3247,19509072) Z8(091a3739,1ae0288d,7702b047,bded4f9e,02c651f7,cb6b40c3,127e1de0,4ccc7a50) },{ Z8(1a0ba3c6,7d21f1d4,c77fa376,6a087558,ac646cc3,3c08108b,58a91203,ea9015d7) Z8(889305a9,1034e5b2,8ddf7c65,b52df1ee,14d2a64a,2f5fb76b,4d4f6b27,f43575f9) },{ Z8(86a2f1df,1eae00bd,dc8bcf26,cb03d912,60382fee,3950fed8,acd3e042,ffbd9163) Z8(9a669973,b4ac9df5,f82c4a05,3b62fe9b,c17de107,91ae9f9d,1e44f322,4dc08937) },{ Z8(eafe1e8e,7ee8a816,c3971c4f,e0230ffb,d9d1d320,0de8a2f9,a1cfe259,c7f8e46e) Z8(6672d324,26366c62,bcf60be2,89ed2d0c,a09c8cdd,3bc9345b,192b9477,f3e82f71) },{ Z8(bcee4138,848bc08e,f0f69a78,360ab090,70f66468,b6817754,7f010355,28036dcf) Z8(05f85471,a46977b1,b3eb2542,8603ffad,f0734e28,07aaa090,a74f6002,4eb44a5d) },{ Z8(c51a72d2,f0b5b03e,2edf9702,ec828b07,bc24ee60,10c39d7d,ca275d90,81d50d3c) Z8(8e5847d1,49535086,9f101ee4,102beb56,3dab8877,ae995726,c9e9fd37,f399f500) },{ Z8(e8cc3b0d,d56fe372,16b07003,1a3e3d73,c44cd4b9,7e6bb94e,f52e5ded,029914b6) Z8(1035f44c,c566431d,78b15fcb,c987d073,b9317e2f,9e953303,ec8b2b8c,4fa7bccf) },{ Z8(33109336,c15252b9,76848b02,c3053e84,f27d19c0,0a6affec,66da1166,ff805315) Z8(7184f7ed,cf608d71,7c6fcb6b,ea37c890,e6ceed93,a56b3a9f,99f46fcb,f34ac6f6) },{ Z8(4a34956a,6d5d0a32,3d4f2c9a,45014c28,943f3656,3a1abd4a,35bac327,133853bc) Z8(c21ecb00,44fdb986,b37169a6,18859f18,a60a1994,638a8fa3,7b9a5a0f,509adf9a) },{ Z8(f04ddbe3,08855228,17dbfb86,5bf29d6c,16d92f7d,ee5ea250,ab583f8f,7e03af4f) Z8(3d12b061,ae1124bf,a945e8e5,e69b7b15,177380e8,61fa05f9,b74e82fd,f2faa5a1) },{ Z8(2b2c12e8,1684223c,3ad5ee42,dd7023bd,1d55e7f6,aa8e4ac0,e12b7f46,3b575326) Z8(536d0b41,64613bc2,df9f00c6,b538184d,f2c5f375,b1b9036c,31c69f60,518db1ca) },{ Z8(86053277,4cb272ba,3dded8e6,41d5386d,0494aabc,98105bf7,38337b37,8819b0e9) Z8(a6d0e03d,f9c774d1,642b4eef,05198611,ef7dba00,4c8169ef,43466c01,f2a99152) },{ Z8(07e20d4b,16744752,704f7c54,f506d3c8,4cbec30f,e1251874,07589e32,26098616) Z8(c92c8a42,dec7df41,c4eb4ee3,93f2bce3,eac82c20,3ba6bb08,3cf48182,5280326c) },{ Z8(28f61c25,023115eb,fde92a12,b66b85b3,53368f0c,aa3737c1,6b809bc3,f1113ca0) Z8(ae3f893d,80186897,9eae2eb5,f5ea6f47,f99cc674,6bfa2eb2,5224dd2e,f2578a59) },{ Z8(5b9ae9fb,55dc3315,461941f2,1576da94,115e493e,51178456,df758c7f,19c873f1) Z8(7879f046,aa2d87d9,edb7ee79,c3aa3193,b27b6cbc,4903c81e,1c962aa8,5372608e) },{ Z8(72a8f01b,8b94a362,54606b28,9a573d5c,47d71895,c6ab3f70,5dbc7ac9,049d090f) Z8(34c4ad17,d04f1a2c,ad4e97f2,dc9a3181,9e89202f,7573acc7,eadbf1bc,f2049108) },{ Z8(6ad05eac,0f9b03b0,2dfe81f6,0cae1c92,f5dbcd84,fbf9119c,d51f1708,6175220e) Z8(03ccd92d,1c5eb8e1,4dddd949,e66c83bf,0f332fb3,57155eef,a29de9b3,54643b3d) },{ Z8(11c9693a,f8b92fee,3fea7c8b,8058b732,bbce0bbc,e0af44b5,3e367c2a,09660bdb) Z8(b25b0000,71b48e05,c7070517,8eb9ae2a,dc8d0dcc,86c55fea,06b526d8,f1b0a5b4) },{ Z8(bf965f26,3df9c619,c79afc90,1eb801e3,6e05842e,4bf340a8,2a24ac0d,e06fa85a) Z8(057e37db,d640aa7e,e09395bd,d9a23a3c,bb7c2331,9b54e12e,f4706029,5555c188) },{ Z8(821aa279,6375e91c,d88255f4,bc2e375d,ec4f1332,ecdff968,2767516a,3dee4e68) Z8(07c4e690,1c0b5128,bd579f09,d9fff438,fa59b164,937d0351,90fe6262,f15bc8ae) },{ Z8(d1ef3f4d,f1adb65d,0a2d8a5c,517aba32,54d27068,ff875262,d0222eb0,d9ce81a7) Z8(53cdfc90,b05ae267,74a00246,ee826d96,06572290,3a5d61ff,8bd65cbe,5646f27e) },{ Z8(7f3b6732,1228f67f,29a4d642,12a5296f,b2ca036d,c26749c2,57ae7419,e60f19e5) Z8(6b06d98e,07a4f6b5,d54dfb09,5142ac8a,72520443,7d44e042,66b607a6,f105fa4d) },{ Z8(88e18bf1,383a14bb,e6682b72,3fb8b385,04c57020,f165168d,863d8907,97a9e600) Z8(c4896f13,0ffc831d,2660f7d4,88319743,d1fdd9a5,58b493a1,37ee6174,5737cd2d) },{ Z8(1fa13d65,9c3a125e,92976c60,24c3dc72,c924bac4,f0add31d,af208071,c5b2ee48) Z8(bad01f0d,49c1b664,47d3613b,6ff6a757,1abeae3d,c3023855,56361a64,f0af3ae6) },{ Z8(32e06bb8,088db45c,99a244fb,a1654119,500db61d,e524ee13,c132655a,64f1f80a) Z8(90b5f851,da427ce0,89be794d,cdfa8f31,44cdbbbf,7f602ea2,1e1dd46c,582850a4) },{ Z8(08931b70,757e6833,c2e1a515,b0eb8c2d,6d403c8b,0ee45e2b,88738be8,0446fe33) Z8(71145b3e,c5a6b137,d0efb0f4,f74f3dc8,6b984afe,a39c09dc,1ede707f,f0578ad0) },{ Z8(18f6a990,75d5ef71,9ab29cae,240f2f1c,6e902be8,e2c07455,5416d0fc,af3d16b3) Z8(c4273155,7a8a67dd,b2df208d,c84dadea,8cb9a98f,238e8742,bb01da6b,59187bf2) },{ Z8(3524bae3,a2f56352,a16eb337,76821a66,740f4591,93ea3885,c0ae6e4d,a4aed446) Z8(d1342e89,6cfd5e11,bceb29b5,0f4ccbff,72c1909f,82b5e520,70bdf2a2,effeea62) },{ Z8(2204d30f,50e31719,f48acc2d,5aa972bf,e75cf637,4e5ea36d,6c198583,d8ceec12) Z8(0c295e36,647529d5,c0b1afc4,ed2b5d17,5531d74c,76dfdbbb,e35fda27,5a084e28) },{ Z8(7881d72b,15c48961,5f6d931c,a6b2beb8,8a1548e1,313ecb77,6546b41a,b06750a1) Z8(78f1daa0,fe6147b0,62261125,fcf91894,278a2d41,4eb03319,ec3aec3a,efa559f5) },{ Z8(add979cf,82dd8804,8ff444f4,4089e8dc,52623eda,4dcefc17,3285ff45,c9ba9f42) Z8(bd954cac,0f88aff7,ca133d57,f3e6f5a6,32409198,fd1595f4,c515a771,5af7c656) },{ Z8(1e6618f0,b79a9e42,3928be21,19bd01b4,74ddf59a,b8b1e571,9e176863,b5af1f18) Z8(002bf87f,d1fed731,1a484c3c,368faa22,c845c2cf,97ee38fb,21ba6b16,ef4ad9e4) },{ Z8(adc5abdd,afdf5945,a0077f5f,bf63214e,6537d114,8f421487,99d86baf,46738fa8) Z8(3f114eeb,188af565,b2e07624,e6734bca,a0d36483,bc14ee9d,e8095542,5be6e38c) },{ Z8(a0dceb6b,99573b18,e40590d9,a2ec0bd7,dfa8c076,408fd134,afac0be3,ef69e19e) Z8(4fded40b,bd41bf8e,5d93f48c,e2e4d7e1,ea0ac0d3,f9b95ea2,9146af0b,eeef6a87) },{ Z8(b8eccaed,1c37607e,9546abed,d2bbb661,a0276948,7f322829,ce8275f5,cece3694) Z8(22d838ae,fc958676,8fb6004e,5759508f,27e23655,3442bdd5,2f18adbf,5cd5a4dc) },{ Z8(3ed74500,a8f24d48,bf152487,6abcbaba,b38258f0,0b67d64d,9a0c16d7,d168c8ff) Z8(9999e98a,6771b0c0,ac0a028f,610f59ac,bc9f4476,6517d83b,aa34a9f1,ee930c3b) },{ Z8(13d01836,1d01d8eb,a878b922,c2e6fd73,38e8398a,a220f616,cd613334,bed1ba0c) Z8(240fce6c,3f2e24de,528a6afb,51320ff5,498de5d8,a94675a2,d9084f48,5dc40955) },{ Z8(67a74c0d,6cc0feb6,16a758ba,e1496860,62c52030,7c4dac07,9b7d0d8f,6daf28a8) Z8(be0091e7,17053803,9db604e2,262e3b60,34d3a47e,cd91ddb7,cac89052,ee35bf5c) },{ Z8(e4fe6324,268971d3,9e6651f0,93e21f0b,3d1a1407,8d172d90,6d6a81d0,9f435b0e) Z8(acb9cbcd,8185c558,f7eadea1,d35d92a3,25c074e2,9e39ea9f,81726da3,5eb2100b) },{ Z8(fbc2af11,33e967f2,1e0f0960,5af8840c,088b4f7f,409b4472,f55c6c4c,a6556c09) Z8(079965b7,a58d8e18,fe0c8187,d7b864a4,5fef1e81,a72b249e,3fd97b34,edd78448) },{ Z8(6a421a39,0747e5a9,8cc88052,206d398a,4f13e9b3,843ab974,073181e2,feb2fbd7) Z8(93f99c8e,7760dc00,e0fdf130,057ff42a,50e22c53,c432540a,21b53649,5f9fb80f) },{ Z8(eef23ab8,1e5247a0,d8f4ad88,a652378c,45d99a92,2b8b50b3,4da2e57c,680eb930) Z8(c162b199,58b28572,d8f8aca6,1c6f6b85,9d338a15,93c56bcb,44741b44,ed785b5c) },{ Z8(611a100f,65d9bcbe,f0d27f0b,23678649,b6bb906b,77249f12,bfcee298,4fe0b5e1) Z8(e574f22c,3e1cf8bd,dda03b7d,dc284e80,b39765e1,f6e47269,11e0d6f7,608d0073) },{ Z8(feefb929,dd358fee,6b5a41ab,44250fef,c05108f9,2361adbc,28bda278,175064f3) Z8(1b5957c4,e653d310,cfe99acf,5ea7a822,d7dfce83,8cb3a53f,017c7dd4,ed1844f8) },{ Z8(d87cf021,512554b5,0badae78,26cb9055,43712de6,dbae8f6e,0e9c2da0,4d75fe42) Z8(0c3458e8,fe629801,d0105d93,f8b5753c,ce03e525,40e9b5fa,09a5258a,6179e84a) },{ Z8(10be1f59,4b0878cd,3ada407f,5a4d2a9f,ad991091,39bee706,41d34e24,0ec8179c) Z8(100d1019,671303c8,6fb431d9,f1466600,73aa48f1,c37aba40,8d4ee3fe,ecb7417b) },{ Z8(7a09b6fe,7fd6a0f0,4021f8ac,e3260c64,775f8530,6b5aafe9,aae96f02,3804492f) Z8(3f0827fe,7c72e8ca,bbaf90e7,e8712dd3,8f7eb1a7,3fde2ea7,213ee838,62666ea7) },{ Z8(37b7965e,e70c7aec,b594a537,71866f7a,62557e1e,c4cf2ffb,19bea541,ac8955c2) Z8(5dcfcff8,f8d1b000,48a9de3a,570aa8d0,13508cc4,62941aeb,eb5fac51,ec555147) },{ Z8(723d53a9,72260bbe,a588cd84,a6d14da0,f5cbf941,6c42e4bd,ead1c971,7b2d3776) Z8(9a3c873f,fba5b94c,8def3cae,bd9695fc,325d8aa8,a02ea766,d264bd44,6352929d) },{ Z8(3bf0cb46,607171e5,ba8281bd,e9f86641,b9549852,c304cc48,9c102065,06a20d6b) Z8(dc5c6d08,155aacc9,42b1abfd,d3013b59,93626798,447e56a0,0bda4f62,ebf274bf) },{ Z8(034101cb,03f30f24,9c75fca8,d2ebd07f,1b74537f,a9f7ebaa,4d5c376f,beb92564) Z8(c1f80446,74279bbd,abc46175,6f5149e0,a2520a8e,c8fb2f2e,f933a132,643e5341) },{ Z8(b84af8ed,3e9118d1,4b5e4833,1ac3e8a3,728403bd,f062ccc0,a2e84a0c,0a2072f8) Z8(55fcabf0,b308867d,7b1ac403,e59618a4,8a70a2fc,a47ff098,cb3f6fab,eb8eac43) },{ Z8(4a1d9b4c,fb52518f,e1b96fba,6c52462f,10c921a4,cdf402b9,01b5b58c,37ef17ef) Z8(a8371c46,feb285ca,b0a47956,d7dc5368,0a840a11,31ec197c,d51b1296,6529afa7) },{ Z8(b303e4b2,0057d360,dcc1f95d,679525f5,c516131c,05545e05,95a71665,abb4c306) Z8(a14367e1,21558265,a4e8ea4b,15c85230,7916a78f,b9379682,f201fd13,eb29f839) },{ Z8(20ad581e,80694ac8,8f229442,2801646f,bdbbd12c,24392bc1,7bc1bbae,48378d31) Z8(8cfa5d2c,ae458883,93abc759,c095d35e,7f782ea2,3f3dce2b,09c8d28f,6614a6e4) },{ Z8(d905235a,9cf7571d,1380d952,7085815f,1b90be42,67e2e553,1255d7d2,10cbb0cf) Z8(f651f1ee,e01f8aeb,b774ea3b,b58dcc1c,b116f73a,1569e19a,34236c82,eac45906) },{ Z8(24a65211,6b45a0d6,9d265ccc,9f90ed46,7b7be717,ef6a7ffb,cbea0ad5,8139e1a1) Z8(34576c65,769a9b03,bcbf9b1a,65ea0585,0a3fa5fd,e39a320b,a0144109,66ff380b) },{ Z8(9eddf1e8,68473c57,afc5b52c,fe9e0430,76933278,8e61f612,a7b4c497,1a691fdc) Z8(6824b2cd,5a99b5e8,55c3b405,ba473838,ec26515f,976ef0b1,30cf03e6,ea5dcf0e) },{ Z8(0a0ceb7e,7645eff0,74e1f619,0bc6d754,1464dd9d,64993de5,12aae920,831b8389) Z8(4efc3306,122908c2,60a4a113,5cf7c1cf,3d2b6fb8,ab94a344,06e953d2,67e96234) },{ Z8(1df256a7,83aba255,45de4813,c761e969,492a9d7e,c1901940,22260433,61fb0ab8) Z8(70c491e2,6dc344e4,c2e45ad3,5f44ea5c,7e98cd2d,9b308765,71f43b16,e9f65ab8) },{ Z8(014cf5b2,8ce338fb,82aa6cd4,6f8bc626,15b49579,05f63d74,dcbdd26d,ed8eb76a) Z8(34dc49ff,243b2059,850c0655,7630d755,c4ccddc4,3bc712bc,14332797,68d32473) },{ Z8(6e58c504,34b42acf,14014bf1,d1d3ad15,5aa2f9ff,971ab2a9,062a9063,a5ec4efc) Z8(bea45b07,5202f03d,e97f7922,b1f6b2c1,bdd18a75,0dd3089c,6be031e6,e98dfc6c) },{ Z8(6eb57696,1e704b4f,01474331,9f96d624,fdad227a,fb58acc0,5ed66b5e,ec068416) Z8(b866e66f,11864549,b273c3b9,28f4dbe0,94ecfcc4,b0a34864,05c629e7,69bc7ddf) },{ Z8(f615c6c3,7098ba1b,b057d89b,6bf6d170,8d50531b,2ca96d4f,c03bad45,ad754841) Z8(42883951,73c55c7a,ca79b384,085e2d9e,ffdae99d,ece7ad24,7cd63be2,e924b492) },{ Z8(a0ef2b3d,3673290c,e7c126fa,95698eac,5a62160c,dab1e834,615c866d,b3b70179) Z8(7f22b95d,9b0bfb78,13349ca9,be456b9e,e3f9e559,b60a761f,8249db4e,6aa56d8e) },{ Z8(09327ce8,89160064,bd4fffd2,8a51880d,d651ec9b,8a4adfc5,39ab2a1b,7ab40097) Z8(0f9ee02b,d7bad7c1,c3677f73,89b3b101,91b61011,a563d834,eca7821a,e8ba8393) },{ Z8(97aacb38,5343a4b4,46642c05,66948233,87382211,857ff91b,818dc4c2,50b20ff8) Z8(4a9d256b,d1e76a48,9cc337c7,7cf8ca6a,13123ec3,94a67c8c,9a222896,6b8df298) },{ Z8(507aaa22,811bb7b3,db8673c0,9cae616b,1e93c41e,d3b8fe15,85a66f39,238842fa) Z8(8c24d48b,371859ba,c6ea4a12,75e5de85,b755a9db,b08f7858,ec49bb51,e84f69da) },{ Z8(9b9e9111,d9916eb1,6ea5fc1a,6f11cfc9,1df095ae,6a510663,4575b527,063a637f) Z8(414348c3,3724f8b4,0887a0b6,7036a0b4,ae6c52ac,dbd34660,c8585a51,6c760c14) },{ Z8(9b0f9a6f,7df537d2,5e335ae9,a6c9351e,ad884424,387fc8ac,0ff8d974,b630d6d5) Z8(6fe2b72b,4297e6a7,6455bf06,7f5c132a,419cd005,b6aa11e5,956cfb16,e7e367d2) },{ Z8(45abf26c,b354c791,577cf72f,83bea555,ff880ea8,e0a423e3,cbbc3629,a0c7dcc7) Z8(b104b84d,64919228,e58e927e,8b24d735,e8912c3f,b8a2f9cd,f38399be,6d5db91a) },{ Z8(8fe784a7,4e632877,6f32f497,2e6333a2,ee997e02,f8f0b040,f4161be9,0829c511) Z8(8708ba8f,05bf84ff,146f3522,26587359,e903be01,682a76d7,ea10981b,e7767de6) },{ Z8(e3b418a4,852cafd5,33eb1f29,ea31b56f,ca4f92f4,dcbf7a1f,9e357e87,7d06e724) Z8(68459e67,316442f1,215d26b0,a446ac4c,00f4d47b,752d093c,6eb10a1c,6e44f8c3) },{ Z8(d1cba51c,1248bb11,78ce0f55,649055a2,b151f5e8,2b2fd27a,9aac350d,0df8273e) Z8(1a7e7041,72a8f110,e702e77d,021074d7,13429e14,27376622,d4172a3e,e708ac84) },{ Z8(136c26fb,be6aa27f,0d0d8a26,40b01d9f,a94ae03a,17cd11ae,81156ebf,9934e65e) Z8(7bb82f03,9927a7b9,c4a0a9a2,c5d55c25,aabbe0a4,06e5fb8d,fa4b758b,6f2bca26) },{ Z8(f3174f49,10bd6668,7b10bb5f,7551fb3d,ab01d13e,ca8482df,c04add39,541fc68d) Z8(f64c99cb,cc79957d,a07f390e,83c21666,d4fb8fb9,834668b6,24d9a0b0,e699f41a) },{ Z8(16733f09,58d895b1,8ade085e,35678ae3,5c7afc67,afd1dd07,001f08f8,86060cbb) Z8(2b10b725,4f9a5269,79b09cf0,382e0383,fd340ccc,ff33abf4,c5028c8c,70122c5e) },{ Z8(2a2b91c9,60e5b82d,4fcdfd10,3cac4bdf,33884212,64845fa7,31e79e82,e6a71eb0) Z8(3a94ae49,66f9e7ac,0111df69,e47aca55,d4c0e483,70b15d41,94b970a7,e62a5515) },{ Z8(9659e871,e58f655b,cbca2f26,041d49ee,820ae5af,245029c7,ab4820c0,58164ca2) Z8(79b3befb,d7768559,a29f13a0,9c4d1996,ddc5e215,9ecf5610,6cb1b744,70f81e84) },{ Z8(87007065,ab03e21f,91f993d0,277f93bc,92ecf050,7ec576db,95be4879,bec821c9) Z8(31a03ab3,3def4011,686189e4,694708a8,2bcf803e,0d89542b,c2b1dd03,e5b9cfe6) },{ Z8(94a81bb7,1099ac70,fc425123,03444634,f4ff699f,0d97dd32,851b3216,9e98e49d) Z8(f1f98e8b,66c77413,b1c57cea,e3aac247,9f6729c6,3acb970a,ff467785,71dd9fb1) },{ Z8(4fb36d24,5b6ed80b,cb31f13e,9716ddae,f9911856,9965ea1a,5d5f9117,2603ae35) Z8(735820dd,fa6b6539,61702450,bc7c0d5f,5cf1b1a8,abf5bd0e,33e8575c,e54864fe) },{ Z8(809cc9c5,590ea2ee,9a4c0d8f,f80e6cc5,b35bc04c,b92ffc8d,b0952f43,d642b96f) Z8(5f9fb583,b80172ff,a626d4e7,ebc3b741,fb07c5c2,91403183,fba65ad2,72c2af01) },{ Z8(826337f1,2650e3b0,7a037833,ac36e9ec,4e7c28a6,6c651a92,d2ed1c99,c61e873e) Z8(d3e3a62c,908d3a6d,591ded6e,3d4cfd8a,aefb6ff6,c1088e06,533bfaea,e4d614cd) },{ Z8(266052ed,f59044e2,efdd5c62,57be7e22,1734b856,6144dfe4,9d537b9e,9fc63ff1) Z8(5ec60aad,a9b1cdb7,9bad0e3a,769bf477,eb3fb021,1baf6928,52947b68,73a74b8f) },{ Z8(3a89e3c9,03e56c2e,72b932d9,7553e766,416e19ca,c81f5b04,fa4a2e1a,77966bc4) Z8(1859aef5,01f91443,202bf5ab,a0547011,1228f146,3d1a1590,70d421ab,e462dfc6) },{ Z8(6783ce9d,699ba5c8,3cf3cfde,26d496b5,137b820f,7828d4b5,35348a70,81a10db6) Z8(bf2437aa,4798f789,cdf8dd1f,3ef0d7ff,5e00ccf9,de30c395,67968f62,748b7475) },{ Z8(b989ff3b,6deae6b7,179df131,95fb689a,96f3b371,86f62b25,a7590561,e67019f1) Z8(6c8aa52e,e1231db3,36ad6e97,6a2e3a07,412d5870,b878ab0f,c1ae1445,e3eec65c) },{ Z8(a99e863e,0fb66baa,53efb78d,21e1f1a7,0b54946f,87ae6b0a,92fd338d,0b2d3ad2) Z8(4be54cfd,b68a4c4c,582fdb74,734ecdfb,29c779bd,a44a75fc,11d98528,756f28d0) },{ Z8(e2743b29,97382411,43d0d9d8,ba4c67bb,4c2c415b,2447fbb5,952bc98a,dbf33d8e) Z8(b36e3f0b,2d4d0698,76c0dc30,2b3d109e,97c2057b,c4808aa4,5f29d517,e379c904) },{ Z8(6d33841a,d96f7468,46e33672,b9e75573,3a28f6fb,e1ccd7fd,99025c29,f086966c) Z8(f993355e,b6e416b5,b8af15b3,32e8708b,d0790138,0f254fbd,9d15ac28,765267bb) },{ Z8(eddc83aa,7c0e66aa,756f2efe,86bbae26,ef2514f6,ec33fe73,cfd4a91a,93ad19fe) Z8(0b2d7f40,eca149e5,b0d6e486,7ee50275,1b9271ca,9605f173,469606de,e303e832) },{ Z8(ff2215e7,f0aaed52,4d56fea6,6437823b,978cb216,9872d14d,c32d4494,3a9cd3c5) Z8(5340970a,964534c7,5f052fd2,fa8e1ede,d99e6b39,4c6e171f,ca72690d,77353054) },{ Z8(5148c9cf,5aeaa91d,cc755029,90fbad4e,bee7db2c,ab66a430,5fbc4034,c7f945ae) Z8(76cf512a,2ab7fe76,4fc2808c,66acd9eb,bc003c43,225e232a,58baef72,e28d245c) },{ Z8(5a8c9b7f,968b2186,751152b2,ff3df137,3bd59367,86374c21,3a23cd57,8ab0fe68) Z8(dc2a4f86,8f8c38bd,00f1617a,3ec30676,d49586ce,c1c29af1,d1697487,781781b8) },{ Z8(bcabde58,7f0ff458,283dbb03,11f8bdf1,ac15c83d,a2af36f6,eb71be86,c3aaafc6) Z8(d213fe0f,184de2c0,bf7beade,fd53f968,58d1d159,ac427c07,59649706,e2157df9) },{ Z8(c60bc44a,ec29cde8,0b375797,1332dac6,f31f1456,43900d9e,bcb383ba,0767dfcb) Z8(3b579e9e,32e605e5,20631ea9,224d08bc,1dc38c61,6df7bd98,60a9a3bd,78f95b05) },{ Z8(5cf700e4,84332c5e,4383e0da,5b0d2f1c,d1be4964,d4018669,7907fe2a,3691e5bd) Z8(22d94019,0a00f700,94e7b5f2,b2a1911c,4807ecef,a1422fa7,eeec046a,e19cf580) },{ Z8(09483c9c,e8463dba,8551c330,63b30eb5,7514a314,9ad22898,c693aa5e,4649923b) Z8(31ecf1a3,c0f7de46,04338baa,e43665ff,57ea801f,37d7fe3f,9ef93989,79dabb58) },{ Z8(068b6cf7,2e39f183,efcb4d4f,20117330,80c6692c,767387d7,99b2b6a5,601f8986) Z8(dcf766d7,2ff5140d,7b25c6fa,756b82eb,6d96b1dd,8b7af1a2,a1bf96b7,e1238b6b) },{ Z8(e88eb7cf,d296299d,0f56236e,0d0467b8,2ebbf6cc,5cfe8e99,3a9cfb75,db35ae8a) Z8(d2a0db47,8b303693,caf13cd5,92f45b4f,f60ded99,d92f0d93,2c17bfa1,7abba1d1) },{ Z8(c53ccdbf,72a25e5b,fa33e62f,005ab15e,8adf28ed,f8007990,e2efe077,01204d8f) Z8(3e8b19e8,d72350af,89f43eab,56566b3a,fafad985,bddd9da2,dbea7ced,e0a94032) },{ Z8(7f81b6cb,9ba656ac,cb010ade,19496af8,78d4098d,67f5c1bc,e2c45358,0d0b297c) Z8(639f60f3,91fe3a3e,c49a8888,4a25ad58,342b56ac,8d0e550a,219f66c7,7b9c0d8e) },{ Z8(49809a79,258af897,cdb8df8c,c178cd46,005f0c91,53160225,fb808fde,dcfa8eea) Z8(9a472ef5,e224795f,bdbbeb69,62b0fd73,d2a39b09,4359275d,e89b4bf3,e02e1450) },{ Z8(f8e7de33,cc21d763,66fd59a2,8129e9a1,854de0bc,460a7592,0f03489f,6bca0c91) Z8(850b6371,8d59282a,1b5362bb,aba6c074,25bfb113,212f8a75,13e5ed17,7c7bfdaf) },{ Z8(41a1775c,21c8d067,d204adbf,95c1e965,03913a67,554bd5b6,98b9b80c,83f25534) Z8(4d311123,029e9509,66cc2b55,ec583b83,342890b5,7ae2c515,f3a9b36f,dfb20840) },{ Z8(d921c485,eb2956f3,a62367a2,dcdefc80,97f50db0,55506abe,e7baabe1,c52b8507) Z8(596a389f,d3e7778e,9edc0c55,e1cc1e07,e8080aa5,8434fc65,12dd09a1,7d5b7154) },{ Z8(d1509b92,2a65d991,85a20be5,8635b755,000b760a,42274970,34ad88e2,2df3b7a2) Z8(c12c9ade,80daca87,7e7da500,21879f7e,2ac0775e,ab7587b0,091b51fd,df351c7f) },{ Z8(a344bb83,9257d97a,d7762f8d,ca80bb87,7e18cbff,7a866e49,699d64a7,073f6283) Z8(0d886dbd,f0c3a907,21823a4e,172961c9,028d0964,6542bcb4,aaf25c67,7e3a679d) },{ Z8(e4ccffa4,163105c1,422a535a,6f981a19,73210cf3,c43c16a9,91c59388,dc58f27d) Z8(d57574f7,6628d1d3,f20ae8c3,0bf8bb48,09cd41c5,bbcc88c1,14a7a931,deb75188) },{ Z8(a31a423c,5106025d,4907d9e3,98b5b8e0,c6f0c862,b51100f1,529390df,41c977c6) Z8(15a50d90,d1cdb528,aac06fb5,619c8682,2429c714,f507b2ea,e5eee1d8,7f18dfac) },{ Z8(48b0da57,7da091e2,08ca1580,9defba79,774e7a6f,9dc7cdc5,cca28a2c,f41c81e4) Z8(73f42a92,0da71e48,ecd05918,6580db61,30fc8dcf,19c8a06c,e13b31eb,de38a7d9) },{ Z8(3c2e74d8,62509b3e,16518d7c,84f6c985,4d0837c2,8d86127b,257978f5,fcf40900) Z8(939b5d4d,48b9eea8,8419c0b4,1f24e803,db5159df,54c97482,4bd5e8fa,7ff6d8a3) },{ Z8(76250108,1cd4bc58,88f1095a,a0a0fc27,b21958d8,8be9cb0b,0be7ddf1,a68955a8) Z8(7640a2eb,aa7dcf0d,94bcf0b8,69c64a00,a3889f51,bd2452d0,18799172,ddb91ff3) },{ Z8(636f4c67,a531aa94,15f46c8a,ad6b8920,8c96f0f6,88600799,8293a0f1,9bd5f3b4) Z8(02448ec8,02507817,e93b9376,656800f6,dc0a6a79,bd61086b,e3c38b4d,80d451a2) },{ Z8(06f15790,9b7059c2,758a57b1,6e3b7c3a,50d130b4,bcfc5231,33c48859,1b9f5617) Z8(43d075b4,ae836ac7,1337331b,c7267071,09896f4e,104d76ac,423eefe2,dd38ba53) },{ Z8(00295bfb,2528d664,f6997e46,b38e89d6,9e178116,313a4746,ad2b5f44,bb0f7fdf) Z8(d294d25d,074c83b2,ca951a93,74206c32,9fd4d6aa,e650f8d0,34caa5a4,81b149ce) },{ Z8(9be67be1,893b4335,657b211f,1b6b633a,0d0e08c3,0c1fec74,7341e221,56059fcd) Z8(eb7f21e5,522f5407,62843b54,939ecada,b780ce9c,68f31e3e,c4207051,dcb7777a) },{ Z8(e33b3b0b,78b65402,2b57bd39,515ebdb4,a7be3cb0,4094e3ff,05e8ef44,072dba13) Z8(972bf9e7,b642f7f7,9e5a3030,e541beb6,786d2cd2,b435cb7c,46d250fb,828dc048) },{ Z8(4b31d9de,752c5687,87a75854,1e7139ad,1043f0aa,b9b61875,dd1b5315,49a6228b) Z8(7d503d6a,8e630162,f80e4931,7b2543e1,62a44ac7,980ea93b,e0ebcb4d,dc3557ea) },{ Z8(6cc7a25f,f914d879,a74481dd,cf67b2c9,7a4c306b,d459df16,c3c749f8,401940d1) Z8(56b3678c,bcaec2a5,f5cb2e38,b2b493f6,e36ce1e0,b5c8a71f,a372da7e,8369b434) },{ Z8(917e083e,0ddb7324,f7bbcb1d,b6e97d1e,076b0699,b357d33f,055dd1b9,62183cfa) Z8(b229d4dd,bad20cc7,8b0ab628,c6533519,ec991b70,f6e7bc98,b8260c14,dbb25c25) },{ Z8(2f925e97,1980bb01,ab165007,86388f35,7c627ffe,2e4d6349,be7a526a,bfc69099) Z8(4aeba2a9,17fa3d9e,3d8572f9,ff202e92,66caad39,77801276,56d239e0,844524b7) },{ Z8(4b3b831d,c1273c39,1d265af1,47e7c4b2,64187766,5b05d4d5,419b9f92,9c34c9ee) Z8(b21f25cb,b2ecad63,df00e304,530ca02f,6bd12a0a,33cb4db2,4589711d,db2e84ae) },{ Z8(f3d618bd,2dcc67ad,2399de2e,0258719c,44801786,5b4bb4cb,a5863a0b,4f464f06) Z8(2f535740,9947b913,775ffc60,80c2e9e0,614753d0,378bd8dd,f0800521,852010f4) },{ Z8(eb1489dc,b345bb37,6e8f3076,76f3ef2f,101a5565,2639d62a,e2721d84,c6a0ec42) Z8(41ae1f3b,267a899d,3e7244fd,2e1b1714,e855e993,fde51c09,60827063,daa9d208) },{ Z8(981fc1fc,25f010c7,58957fae,944c8444,8ac1e406,d46d6396,ca4a488a,13789552) Z8(da2c66c3,c96d772a,965e44ea,a6762946,f21bfbe7,0676b4af,8450e0ed,85fa7812) },{ Z8(bfd60d07,47f46919,0eb3c71a,a7c7df5a,2b2ca944,e09bf92e,bee15be4,13a8ea36) Z8(16fc822a,5cec0fa9,9f8a0159,4655ae00,140a75a2,8be00386,bbabe00d,da2444b8) },{ Z8(38d06a2c,6c1506e4,6250cf31,00835da7,83b1e793,e428c10a,b18e8b45,1a1cc195) Z8(31f5ad98,c23401d2,aa782184,62dfcefe,dee54f35,e421e822,ab396cb4,86d45935) },{ Z8(31db8872,48d7ebe5,985e1e8d,ecdcf73a,25beec95,4f171510,2adeaab4,a89b7c18) Z8(c2c72be7,5c0da0b7,8c768454,fd54d78e,95204106,d4a3a3ed,e44a43d4,d99ddd44) },{ Z8(83dfa98b,1f88fafb,272f6d13,3f0dcf44,91b3763d,f7b5b104,6a32aa8a,d86ab2e3) Z8(2ec1429a,68884404,7c504f66,e9d6167d,b056eaed,ed13e5fb,8428a9a7,87adb384) },{ Z8(75e42688,d3cb1b7c,601e2dbc,10c2ce5c,ed653c83,a1d77cd5,68e7205d,3195b9c4) Z8(16200ef5,3a354718,5b01738a,f77f130f,4905032a,2cb41601,41c63fd2,d9169c33) },{ Z8(6c6f18b2,18079375,fe02182f,9baa1442,d9fd2440,9d924d29,40ffbb9c,2e98511f) Z8(e82459ff,b7daf8ad,cb16637c,00c143a5,30225272,31331013,b4e1dbb2,88868625) },{ Z8(54ad6bcd,98e8c786,d911d9cb,20f45700,d4862d5c,d45fa91a,3c87146c,2556da84) Z8(6a7e0fd4,44b13ca2,5d246c57,75eb26f6,0c1a9a53,d561efbc,1526311d,d88e820b) },{ Z8(3b76bac4,a748ff1d,5dbd4741,828bf0a6,a5c8b989,fa6500e1,e602994b,9c61f271) Z8(149deb2f,64735680,c68fb805,80bc19f9,2b2ed536,52ffdcfd,6ad5e3a7,895ed040) },{ Z8(8fc46d6c,489be650,82aa6826,8bfcffa3,389cb7c6,35bef9ca,7682947c,afbde054) Z8(10a360d7,708414f7,fd2734e2,f6223693,9825e4aa,e51cd540,7886ecd4,d8058f54) },{ Z8(68cedb8c,ce9bc14f,480d8d78,efe51fba,c07827f3,caa965fe,0aa9fa0d,cbb2861b) Z8(f9b4650f,fc18d530,514bbed7,48a41251,9a8512f4,9535e273,5bfc11bf,8a3690fc) },{ Z8(d4e38ebd,79c20bc7,5b72ed9c,56373513,be72d280,74baa84f,65e60f59,d814827f) Z8(6fc91bd4,58468b82,814acb03,e3a04258,06bbc6bb,c9d868b9,5e93a607,d77bc498) },{ Z8(3de18a2d,df8e30ff,5b1ac98b,ab34c5e0,d040f42e,fb23f519,576c7fcc,26c514b6) Z8(5498a46b,aae6d27e,b40f6845,b2d8cad0,fa211ba2,8468c86d,c7aa6f8e,8b0dc781) },{ Z8(0d66dc01,5c966084,60000e93,b1f9b0a2,70d1ff95,cda47857,5ff4d84b,86f63422) Z8(0d09de09,f9751cf3,5c0241e6,758db6d2,f3732ed5,7f89bf41,91fcfb1a,d6f12260) },{ Z8(d60e032d,35abfdaf,97472b00,0afe8632,6a7ca20a,8ae73c43,d572ec74,6ff729c5) Z8(65a0e3f2,e023fbc1,739cc894,6dfceeeb,243d63d6,f2b88171,776d809a,8be472f9) },{ Z8(6cdf3c68,6092a34d,a52a179d,af1b96fa,cc7d9205,63d83eb4,50ae774d,c03713f9) Z8(31117efa,fa151d76,faf31a9e,9c1d7051,d988a441,6d51bad6,b4ef2b1f,d665a937) },{ Z8(5b58fde5,d50dd8fc,651ee66b,b4653491,3a1cbaf2,529df076,6c4aab8d,ee7916b3) Z8(cdf05bb8,06534c44,62fe93db,ff94abc6,3453e17d,8516c71a,bfdf78c0,8cba928c) },{ Z8(54c3be24,23774b3d,a6502c9a,e1fde4c9,8977f598,e51f6d9b,9bac488d,de5361ba) Z8(7a8f8033,1e23c7e4,595a40bd,08c06b3f,f21c10e6,b3edf087,408773b6,d5d959a9) },{ Z8(330107bf,a5e94ea2,cad3e305,72c21d8b,ba777651,67069841,5d48bb2e,8377ddbf) Z8(e9132480,30d7f8bd,42d82ada,492cd36d,28060119,9bce3cd1,817ee783,8d902565) },{ Z8(67b80b2d,f2024af6,036648fc,ce04f33e,82e862df,f0bc71c1,5ac2a0bc,a5136f82) Z8(d9d9146c,1171d862,d7439dbb,5eba9fbf,55f1ba69,8f853f06,844897fc,d54c3441) },{ Z8(52997c82,761cb85e,fd6fa1dd,72ed0df2,16aa46d3,8ae54973,3c2542cd,f9a5de06) Z8(62d92089,10b8f7ec,d6a788ad,aec2841d,d5f2155a,eb0933b7,2984d780,8e652aae) },{ Z8(d3330138,cde8e1be,8cbabe05,0c46f3ef,b9d3cc47,b89eb267,fb61c0cf,3e8761ab) Z8(47e56d12,8b0ed44c,b7e0b6a1,548898b7,0cd443f7,45d6144e,a58e9112,d4be398d) },{ Z8(f3f0a1bb,b5fcad13,947a01b2,2d9ea398,50da2540,9f895450,9d128af3,5b4b28b2) Z8(c8fce5c7,0a14f7fc,f19a2223,21417d46,d5a3ffd4,a3fa4f41,b2ba6122,8f39a191) },{ Z8(90efd895,d9a725f4,7a5ecf8e,d9708ec1,69ee9a34,85c651f1,bdfe1ac9,18d1fd5b) Z8(241427fc,b68ca0f2,cb1d5fcc,d86f8d34,3c8d9304,f031c2f6,9f0168cd,d42f6a1b) },{ Z8(c66b3ade,fe702b25,980ddaff,9800fd23,378d0587,79e77105,b589cf7a,deb39345) Z8(83a69e49,8e5cc8bd,023aed60,1085bd8d,df977065,9c03ad85,a64dafc5,900d893b) },{ Z8(cae39e0f,b99c122a,b4f613cd,10f26991,c0419cca,64fcbe7f,00f56001,6570d5b4) Z8(389ef575,d604f62a,615060b4,0d4b0bd4,8204cfb5,46895a10,40073f1e,d39fc67a) },{ Z8(7019017c,d24c7503,6c9c83cf,80264695,4d1987e2,0b23440f,83039961,33237e0e) Z8(571e096a,8576aacc,be571bfa,c72ca78a,a8c2815b,6cc92c8e,1ca67879,90e0e0d8) },{ Z8(53254913,03a24761,f659f86d,ee4de1b8,5f9f0b61,a70cab10,097b83f3,7cf410eb) Z8(9eddba08,a22379ff,214b1d19,27846fef,a7d9b266,661c5fa8,2c357ab0,d30f4f39) },{ Z8(6ffb7b48,75c6be5c,bfc6a458,98755876,96d29724,936e6fe4,7d7af89f,8b0d4f82) Z8(9048f955,d67f9fea,1337eb5c,fc80b530,5fee29ee,167f6128,be39e187,91b3a793) },{ Z8(4d241d30,939c2924,da1881aa,e50b3fb3,53d79089,cbdae1ca,deed571a,41cc3c80) Z8(f9e1c82b,bb3e2536,00724339,877bf04f,8b6f0ddb,6317c099,dac12566,d27e04e8) },{ Z8(bc7fcace,b13828e0,86c1495c,1f07386c,31bde0b4,49c1cb3d,4fb88d3c,dba03287) Z8(fdace200,87195525,7929a8d2,75aab6ff,cce59c41,3d02457b,c45dd9ea,9285dc9b) },{ Z8(edcbaeeb,3c64c0bc,3f192951,651671d4,6db6f5f6,8ca2bf63,fa61cfd9,69b9dd1d) Z8(4b563172,930795e8,ad2232f6,d7eb44b8,32d6e922,48a26bcd,95ee752e,d1ebe81a) },{ Z8(dfe43caf,034a9047,8543e666,4e27649b,c474bcba,bfda182c,cce93cbc,6e2cf79a) Z8(4298bfae,90393e62,a97d4d9b,e7254ec3,3c59c186,a84bfeff,fa1bdfe9,93577f1d) },{ Z8(164b0763,039986b6,67ef8f9d,6bdefa35,4d3b8143,7eb28a7e,7f8f704a,dca31c8c) Z8(8e9bdcc2,00d5d0b9,1968a525,46ccf29b,c9c6ebe5,fe748eed,7a7f81c9,d158f960) },{ Z8(b79adb93,cb35a13f,e107e568,34e01b6b,3b3db018,cac3e829,e6900d5c,d208a0db) Z8(e2a53ffd,81f90c27,5c99fa00,f5d1d818,920497a8,41c4cbd2,bd0335fc,94288e48) },{ Z8(ea14d097,4ecc4293,b3fe668c,a71ad5dd,433626f6,e5dafee8,1e11afb3,26f5deff) Z8(7518e9e4,3914bfe2,344b13bd,de0af1ca,03574707,5e25736c,77222819,d0c5394d) },{ Z8(cb4e7dc5,c1140403,448e26c3,5d656419,df234433,19149a38,4bab6cf2,aa926d65) Z8(f41dec41,f86e6e9f,f22a7e32,be46bc5a,68a6c240,59989e9e,fdfa8528,94f9094a) },{ Z8(7731c120,0dd18365,2f67e325,08ff01d6,5114462f,8001b5d9,06596d00,75fb44ee) Z8(e36d365a,566e9cd7,f70a6727,a204e0c5,4288702f,94d9b97e,4bdd1b78,d030a875) },{ Z8(e5cdc91d,27f8d5f0,c52be852,efd5aff7,05125480,e80594be,8f90401f,f3c2ec26) Z8(445b61eb,f8c232a6,6ebb10f5,5fa61a15,aa09e851,91c49bd2,4210ec0b,95c8ef54) },{ Z8(228bcc6f,d1537178,3d3e077f,78e48ebc,bab40852,676aac6b,8789424c,db1974b5) Z8(445043dc,870f4200,0179a256,7bcc1ed0,3f308eaf,bfe750dd,897c25c5,cf9b476c) },{ Z8(d7cdbba5,b357fc93,7588455d,22bb495f,47e63558,d30f6f45,73e5d0af,5c1f89d3) Z8(27823dcb,1a3607f2,1c7be4fb,9495f18a,e0b5c442,5fe5f921,a34e79ba,96983f94) },{ Z8(f9efc524,c7d90c13,997b59d9,9c37eebd,9fbd54d4,c0ce9a8f,98ac4200,4523322e) Z8(b7d79603,a4d94834,4a914ebf,0bf2d2ef,0f5d54e0,845d429b,90fb96a1,cf0516c8) },{ Z8(af9ced0d,d3c9f468,f337977a,8ff9552c,b4191b08,7343c02a,903936c8,0acc5f78) Z8(215d3eb6,ae3f48c3,ce349901,6817bf94,6fc28abb,aafc1cfc,d18413a6,9766f93c) },{ Z8(d788a7ef,e344e046,2e8a3178,d5848d7a,9435adf8,b18ba526,d1a01d38,3f88c87e) Z8(369aabe7,8ceee1ae,13efc0e5,efae2484,ec440dda,32225327,92f2e27f,ce6e171f) },{ Z8(24f49964,9710732e,c557784f,4c661f77,3c70a162,20748af0,3fcd112a,e16fc39a) Z8(e58aad5b,2d632597,addeaf58,f0d0196e,8a9c466e,9f48b371,131ac5bd,98351b7e) },{ Z8(62ab8685,63c1d4c4,683ba2bd,bbbb958f,c35eccf7,9b4c5da7,f44d9006,8931a7cb) Z8(79c999ce,d51f2d07,8e49a3e2,2126c140,d3373464,d38de6a7,8efe7219,cdd64908) },{ Z8(91485289,0485c77e,e0ede29f,1ebd5113,7c0e616b,8effb27d,4bee5f3c,7319a7f9) Z8(df04daf6,373f42ca,c8172e0d,03f54d14,6b675ed5,68412b42,45e27bed,9902a58a) },{ Z8(44462c5d,55fe078a,f9613b48,123a28f2,8c914e50,46df8a94,826d0384,61631a06) Z8(51cc8a25,81c7adad,eba9604e,faccbc4e,f5108819,59f993f4,5328a2e4,cd3dad1b) },{ Z8(5f5b047c,d4a88b2e,d7d4616a,178453a2,9a095e66,c920002f,fb563009,feb5c048) Z8(200d9dde,9c5a6498,87899edc,c963a87b,321b75fd,171d1b56,dfe02444,99cf9693) },{ Z8(8640c911,4d78b141,ae43656b,23cd1e06,10f713f2,eae7fc26,476043cc,0e2d5d74) Z8(b9fcf6f3,ed552af8,d12c2b8c,d4234127,d024621d,e6cea471,7b51f90b,cca443f0) },{ Z8(226481db,5d31d8ab,2737535e,d63a9a2f,49b82842,9bc735ad,490b6a8f,845b5fa8) Z8(3a6e463f,39313dbe,3b89e28f,2033ead7,0781de29,93f3d782,f01b38d9,9a9bedcd) },{ Z8(5b17a7a4,d5c07768,7a1d731b,44225e62,637a5b36,f9b18754,44a2c2bd,ae64b8b7) Z8(91170761,9be02647,4e081be9,bd7ea2b0,11a07ee3,ff00911e,709883a3,cc0a0e21) },{ Z8(477d9562,09be9d76,8d8adfff,b900b878,831ff9f9,651884b9,09ce70be,46d3fdef) Z8(4ccb161e,21387ac8,ea8c1eff,dc77d77c,dbe8ceeb,0f90645a,1f6ab0b7,9b67aa6c) },{ Z8(37cfb87e,ac681235,d19bb1ab,a8b18fb6,1d77b6ad,3f7f55f5,5fa19ed7,54f55757) Z8(9ed300d0,6f8db35e,360e9dd0,fff2f2a6,32111fdd,44bb91cd,68be7395,cb6f0c48) },{ Z8(307cd9e6,d6d14ec2,8d9242b0,952e6f6a,24f1dd6b,8f14cad5,d045cab1,648a462b) Z8(bd7b9183,8e62a282,ceb1ac8a,6a547cd7,857991ca,05256c4f,b14156ef,9c32cba2) },{ Z8(d1df7c8f,fb375501,21d4b453,b25c3ad9,b0493a9c,0acc4600,787a6268,ca0e0e62) Z8(b3db1448,43d7be83,87a780b2,a773f879,3a66a0e6,204bbc0f,658fe5e8,cad33f00) },{ Z8(1b0e64ff,cb7db449,24615176,82029b38,8cbcc658,c3028a81,46bab7ef,673ad504) Z8(abefa250,7280b4f5,e3300699,90435c79,b7ecdef6,74da3b98,84798719,9cfd50a6) },{ Z8(1f462ccd,70f4445e,adcbf9ea,fa92a9b1,f53f9ae5,6b99fbc2,d437c2a4,43b373f9) Z8(cf7174e9,42037586,4bb9abe2,726e60a8,e3a45bd1,8de52f15,3447e205,ca36a6e5) },{ Z8(e97c1e35,46ea126e,379e0dac,786c6e86,11796b5f,44cf8f64,5254e08c,424dc9d3) Z8(b8488d55,2e08cf2b,886cfefe,0feece34,f8582659,9ac582d0,14204e68,9dc738ad) },{ Z8(5fe59211,a24c5d20,2c4e8bf5,e6df49fe,268b4389,989e0803,7b914ad9,bc3bc9cf) Z8(44878c62,203577de,daf6aae1,981e414b,64b3ddb7,11ff93fe,6cf48c89,c9994493) },{ Z8(27fa60ab,ddc6b473,4dfaa2b1,38b94eb6,48526969,dbae43ba,708ba13f,ed213d83) Z8(6e7fb1e1,870aac84,dc636c6c,069417ce,9e9e2d58,015216a5,783ff08b,9e9082ec) },{ Z8(60df74d1,c54a55ab,c83ecaed,27a66fcb,284c6390,a14b5b0d,4e999059,7a255737) Z8(041b5ee0,4f75f241,6ad7f15a,84891349,068fb449,a1660261,71da8f3f,c8fb18a8) },{ Z8(13b4bb64,54ab6869,0f005d79,c66d69cb,e5e0de6a,0afae163,dbfeaf35,5f266059) Z8(8101780c,59731103,c3f0a747,9040c45e,c1019984,6a3c7aa3,66a9cf90,9f592e9b) },{ Z8(f268261d,f7deea62,7ec4adcd,2ab491c7,34643dd5,412b54db,74f5aa51,6e32cd41) Z8(7d820c74,aff3c424,bf157de0,122876bf,47929682,14ef546c,6ed7b6f0,c85c23c2) },{ Z8(f28301ed,0d175c6b,e51ca4c9,fa8d59cf,e601f617,cde40777,2be41884,26cceee7) Z8(43f85dd0,9e38d91f,afc59c70,383f369d,02e31f6e,a6552176,33bfb607,a0213af1) },{ Z8(a045d1a2,12b3aeaa,3fab41be,27cf56e5,9ece4c11,4db25c3c,0e7c06db,25af3495) Z8(4679640b,cde9ce0b,4cfc0dff,99fd0fb8,08b49c99,8b09594f,58c4c78a,c7bc6680) },{ Z8(62c7faa4,000a21a6,d5c577d8,084c77e2,e4fa0d9d,388f4620,7dc82b30,42b1e8c6) Z8(68656948,076b9b0f,3e534358,ecfad43f,9e9a15ff,11fa50fd,d33c828c,a0e8a725) },{ Z8(cf4f372d,509e6f8a,a7533ca6,62e30d91,388d1e0e,10e96fe7,6ee476c8,59ccddd0) Z8(56437f1a,c40a4f00,dfb0a1d6,7d9adcb9,a03cca20,e2da5615,ecd6875c,c71be181) },{ Z8(d0eaca40,52441e30,7da798fb,3c501091,c3c7eb97,3f796a65,df7f6935,6320cbec) Z8(1094e8cf,ea4ec71f,c82b9b58,0ad3ae83,aca5adad,0acce6c2,d8fc33fa,a1af7271) },{ Z8(0982c705,4018a644,29b10c97,45d445f7,e561e9a3,e3d5ee51,02fef304,e28f1559) Z8(42b30f7d,bd6965c7,4333b6c2,066c35b9,cc55b98a,45b71ac7,affe01eb,c67a9567) },{ Z8(d517276e,b70ff3ad,973634be,ef29ee5f,93f211d4,6ca11f40,914f1901,7bda4332) Z8(4ad66f31,bb0b7cdf,cb1d9eb7,82c66160,5f5405c1,527c32b5,79c35582,a2759c0e) },{ Z8(d1b06f8b,122b6b60,8dbe2d11,02336e0f,29d5350a,e9896341,5da0dddd,4676a1cc) Z8(16de6ad4,365389b7,f93655d2,4f82ed4c,981e3480,7c07d28e,ee48030c,c5d882d2) },{ Z8(e6ad2e98,28730c2f,be4161b8,a4aff1fe,6ee08661,da71bdf6,4834c677,0496f5fb) Z8(cb558558,e7849d9e,8b2579da,ab28cb60,bd34862d,f2a623ca,8c05c9d4,a33b2335) },{ Z8(9fc86c65,bb040495,66c6dc11,3e69ea0f,dca2de26,0462a339,86a5b775,2e71debb) Z8(8b024b74,bb0e0230,aae8b1fa,623f1eda,86f32a1f,9271d995,ba3bcaea,c535aa65) },{ Z8(6ba387bb,62a14d7d,df192ccb,33f91922,6f7e7f0e,711adcf9,ed8758ba,06e3e927) Z8(455e21e5,cc364cea,1afe642b,f105e130,5e038346,d6b17382,88acf49c,a4000721) },{ Z8(a5764264,41b7e613,44f2d217,569a58c3,99d81f84,0f57cf7f,515ed81a,b093ee31) Z8(bcfd3bb7,885b981b,c2052ca8,66371ac4,b08884fc,1b38827d,ec38fb89,c4920cc2) },{ Z8(c2f0dc57,1dd2cd8b,e5d4a44f,f770bd16,358ae087,827c7ff2,b77857fa,7c3b618b) Z8(525b3f19,ecb08b0b,a6a090d6,9bc62f2f,691bfd87,f236b9ef,8bdd4185,a4c4470d) },{ Z8(d3b977c0,97790ae0,12bf54fd,0cb86957,7ccf7016,31335dec,942639c5,1d0b40ac) Z8(ef8179bf,0f24d3cb,c086722d,621f8db2,566629d8,1e410878,21d4c073,c3edaa8e) },{ Z8(b59e76d8,ebcbbcb3,8135b970,ca67bcb8,1112d213,3b933649,b9eee978,bdb97a99) Z8(810cce73,634a21b1,08d93793,16c3e9bd,62cdd293,6d02b9c6,55bb0808,a587e235) },{ Z8(5d951b21,af0ddcf7,f210dd4b,155ae8da,896dbd42,24b3c22f,aa953d08,c4542be0) Z8(1bf5caac,fe376bad,c51b4c13,35b4e9c0,9dd1381a,8ffe2bfe,bd363133,c348846b) },{ Z8(65621b65,c5bd01fa,d4acaafe,2a53dbec,5dc52f57,f4e0a47e,8e450c7c,33ce3c5c) Z8(fc6435e1,a41f60e4,64de18d4,a47220c4,dedd6862,f0f720bd,4b2ecb33,a64ad7d5) },{ Z8(40cab1ea,de676c83,f39fef84,483c80e1,d33a2acd,9fb0c4f4,bdfbddec,644cbd64) Z8(5453898a,50b7417b,9b834dd2,589e0206,4fac0bbc,ecbd60c5,e471ef3b,c2a29b00) },{ Z8(ce32a23f,99865f07,caf12b08,a9f717aa,006142fd,7d0d50ea,30372f5c,ed0e2843) Z8(6e58ead4,f3db7eea,c3079246,96dabf88,12bb748b,da0ec907,76a8d4b6,a70d272a) },{ Z8(ebfdca6f,f9d19c3f,824996aa,4ed7d4a9,e622f071,72f6910a,69f13e45,a7b77d3d) Z8(24fdc9f2,b5496272,343e53ad,fe814ec2,722f643f,5a613ec8,80e4ffdd,c1fbeef3) },{ Z8(1d531087,dfc6382a,2378f667,484bb783,b518e14a,eee14b02,b7c8256a,69ce99ef) Z8(755165aa,26a49b0b,dc708c02,84394ea1,bee3c202,ad8e98c4,88e42a5d,a7cecf72) },{ Z8(691e5e6a,266aeda1,dd19990d,0bf9c1b4,fc54adb5,42438571,012ad137,cae4d306) Z8(21d398b7,486d9ff4,dcf71e73,42542cbd,83b0fe27,76825189,3e8ee2f9,c15480ea) },{ Z8(215eddce,6525549f,55430115,ff9d7a6e,72ac7226,1a0fe34d,a9975ce8,4214f8cf) Z8(c6f12a2d,c985491e,e735f8bc,20f7e7fb,f9e24399,e2f3c76e,d9a8dd47,a88fcfeb) },{ Z8(6db6a625,4148ab97,27ed8b40,9e2eb1dd,e2f2afa8,fb6290b1,4361b8cc,9660116b) Z8(7de9aa6d,7a48a6e9,4356fb50,ebcb8bed,b90cb15a,ba37a3ee,8b6ae710,c0ac518c) },{ Z8(ac56ec04,890c3730,d422d132,ff83b0db,c29b765c,1e13a30a,8f606b95,01038993) Z8(cca5cff1,a3d8a26d,b88ee895,fceac47a,73819370,af7af179,688db20f,a95027d5) },{ Z8(1e6fbc6c,60d1c2dc,e7c30f32,9619cb3e,2b62c8de,4bca8792,51b3819d,e9b6ce2a) Z8(e43a043f,ce6e660a,1bdb7eed,ebcc6e6e,b2a73066,1f6ac151,96c8bb55,c0036182) },{ Z8(48a44a6d,a44af301,b6066288,e6ab77f2,bd9c04a5,f1f67e10,3f16aac5,9294d3a7) Z8(d5bb8102,ac216fbc,187f1471,3193b47f,3911b8a0,2c28520d,ddb92123,aa0fd66e) },{ Z8(0ca836a7,3320e22c,a88c1652,37c0d3c6,0e2fe16a,0a605af0,292cfca7,3da58f49) Z8(5fad5a6c,11c6cae8,1877c028,b4e48306,567cf3e3,75969296,50a44068,bf59b175) },{ Z8(f9f9b33e,7248794f,88ec1dfc,0529d89d,0df30a43,c1441a52,a41619d3,32912522) Z8(14f9e381,71e34834,8ad5534f,35b862cb,faf9f80b,d6081229,8aa1ae8d,aacedaf8) },{ Z8(54b9549b,9827b85d,fd615c97,79d8c10e,60f8ed0e,02c23a19,497cc6ca,9d776ab3) Z8(1e4ff94f,2be7f6e0,fbdfad15,e9da1856,4624c532,9524be9b,68fc986e,beaf420e) },{ Z8(cb130e48,de9a0465,19d3aa6e,13da5dd7,65686c06,38664d38,9ec7f704,d2cc1f1b) Z8(f55b9e01,c8d57dfd,fce43d55,dc2e7109,c65d7e3a,10ed343e,6acd9872,ab8d34b3) },{ Z8(3d0097bb,acb3f967,18b3a28f,e3981a86,aab2a1f9,bcf88c51,8b3002ee,8a52d51d) Z8(ea4a4846,283fefa0,243de8f2,d75a5560,8cbf4da1,614946a8,4f2a771c,be0413f8) },{ Z8(c71baf37,feee7693,1def3e87,c00d7342,d3b5f168,8905b801,a932296e,3052e595) Z8(5a4227e6,24607c29,10bc61d4,c3a65366,89d0d9f9,fe4592af,2491db72,ac4ae2e1) },{ Z8(f45194f7,62c09480,62754be0,fb383dfd,ba10a2c1,f696a48f,044f2aaf,f2eff911) Z8(a91c3918,d119698e,e35b4c83,c7a88750,a1373c37,483f3902,3135b26d,bd5827de) },{ Z8(0c02f411,1ff32882,cef2f697,a350cff6,7b2c8614,44556858,97ab55d4,e2546438) Z8(07cbd9f5,d6b23197,6f51e09b,636e74e7,b0ac24b8,a3a9057b,09d08c4f,ad07e4c4) },{ Z8(2b506e3a,80a59c78,ab1cad5d,23020c5f,346397fe,87a14359,25dc1e2b,3ac99c0f) Z8(21761101,1b34047e,c64a4e73,8ab14808,a376bec9,b122c574,fb2a14a9,bcab7e6b) },{ Z8(f7569076,70c9d4ad,80dc17ca,ac32e85e,f6ff8689,29267ea8,65ee7ef9,71e3bee3) Z8(9badf8c4,d5daf23e,b7a7d9fd,837f508a,15d858e3,07986543,18b685f1,adc4399f) },{ Z8(c3c551b0,9026ae27,199070fa,1d0a39d8,09f2b280,824d3570,5aa9da99,37c47c53) Z8(0e553a43,d3883121,79c768aa,b3cf8cf9,6d948663,85540223,566b7069,bbfe184e) },{ Z8(f5459f68,b53cadf4,06f81956,e7c8e051,27e858ee,ef13e9a8,a6a40f98,0a971a49) Z8(cd044cb1,7533f532,646425fc,476747c2,f140a488,966e1d6a,fc786b2d,ae7fe0b5) },{ Z8(8c9582b2,94980cc7,5304c25d,1fa13c55,d8e7df66,cc891f2d,d069f9b5,106dbe6f) Z8(e35575c3,e4aee845,0e7e44e6,e0bfb8f2,b9d993b4,c151839c,a908f73e,bb4ff632) },{ Z8(c677e41b,9143c42d,c266f052,b509c11e,7ab985bc,619d8270,62b33d6f,072b8bc7) Z8(38ade61b,d1c17663,23d57fe2,15606dd8,4519dcaf,cdcca897,0e0efb84,af3ad94d) },{ Z8(4da93476,ef62efbe,a51d4c60,cec5f580,6e1e1ff7,d45aa122,c42ed5cf,468b46b4) Z8(424db0af,ae64c22d,722801a1,2f94f99f,77159480,b651d3d6,150fd3b4,baa118c7) },{ Z8(14aa239b,5ca19494,f01dd6c9,bf408993,bd88ab79,4f0ff52a,1dddf51d,17a7b385) Z8(27ff6e25,bc4d5213,6c228e0a,9a5dfd5a,16e33f5e,d9defdc4,54f2ba16,aff522a9) },{ Z8(bdc5bd4f,12332859,5fc193fd,c3d84b49,1d084321,d228c5af,360e0103,56d55b53) Z8(d122de5b,4c3f8862,becacdd1,12230f14,95082990,628e135a,77dd0751,b9f180ba) },{ Z8(40bceafa,32bea5dd,d2ef9124,3326d7f1,b6e13602,abd4e97c,43831456,96047e2a) Z8(6d1d1abe,d0586057,3e912af0,ca6cb5fc,ceb0f64f,7d82f3fc,87d6e61c,b0aebc10) },{ Z8(479b3a66,997ffb26,67eed7d6,c8eb495f,6f5aa8c8,d4a72b22,ee097db0,682e9672) Z8(c908f94c,65aa441a,bd6d47ff,37a95ec6,eae2bc42,022de97f,696e8d47,b9412ebc) },{ Z8(bb6195f7,f25f9130,1b9549c0,e65999ff,92b101df,0963f8c7,0e6b7a1f,537a1a26) Z8(b926281f,53d6d400,078baa0c,c3c1225e,7cc23bd3,4cf5493b,0d63c424,b167a4c9) },{ Z8(86802969,6b056974,8fcdb467,2276059c,81be199f,b036479c,371dd16e,dda15e63) Z8(e58884d3,95e185f8,df940fa8,053730bb,9016bfa1,b614a053,3bb3c284,b890237d) },{ Z8(6b25eded,6c355392,d60a2c0d,cd4c4f37,bc7bc645,e4c0a8cc,4db2ce0e,d8038e83) Z8(ffa4d664,f6ed4a1c,231d611e,acbd3dc9,e999db8d,f1d197dd,fcf0375a,b21fdc19) },{ Z8(8f63fe0d,b442ef46,3cbe3801,2adc91be,47820e40,356b6c1c,cb456399,96399059) Z8(3645ae2a,ede1d3cb,faeace7b,86e6fe7f,6ba0965b,d8702367,f9dd13d5,b7de5fad) },{ Z8(a4ba456e,337f8452,91cfce6b,280080ed,d4011d71,42e8bd78,674d79fd,adc9eb89) Z8(3324815f,b026e673,3e29c1bc,e6d838c0,a77e1ca3,df2d6e20,1f3aaa24,b2d7614b) },{ Z8(8c842515,2adf15a5,b1c84bf3,79d6bf35,2646465b,94570eeb,b3b7ab27,fd5c5984) Z8(8e92b508,fe55d6ec,f0224a4a,f203f6b3,14c3d7d4,50dbdb7a,67aaf2c0,b72be400) },{ Z8(aeaf3f7e,dbc46936,4825ea3d,70d3a1ac,6c5d41f1,68bbf9f9,33a43ffa,7645763d) Z8(c2e66b84,768e7579,41f16117,ff47c12e,04145dc1,8d443c3c,ef214550,b38e33a4) },{ Z8(f9d28424,773bd205,da771ce0,71968fb0,627d099b,800a19de,1577763d,8a95419f) Z8(d0d646ec,d9f91389,acde57f6,f1a81925,2e79c13f,f32a51e8,00bc11d2,b678b127) },{ Z8(efb95d69,6f114a27,eb08228f,b5536120,2b4ae134,539ad8d9,5b30f6ab,111ddc38) Z8(2aeb4aae,d103207e,b2b133f7,11f0433e,434a59d1,05913765,9a597529,b4445270) },{ Z8(72c91199,73399f6c,2c4ab755,4da5f5b0,4e622c2f,62ec3d35,3e185eac,81bddfc3) Z8(6d6b90e8,9d9c53ee,e74fe751,3e73b6e5,4b1a498d,ac786ccf,f7dae915,b5c4c7d4) },{ Z8(4006f8a9,d5713745,2be2d16b,721dc592,34a02103,ade26dcf,99e2b9c0,e002efe7) Z8(f06a5b98,76efbf2e,da395601,3bbc9894,9f0d41d6,3a53f0b0,0226bbb1,b4f9bcf8) },{ Z8(a8140fbb,4ae92cf8,c2be9804,8c19f8b9,fd595376,694150c3,2cd0280f,5b1a4e4d) Z8(6c2d0fbf,6a1bbeb8,db5c1c7f,8406fdde,4974fe3f,fa0b372e,364a834d,b51028be) },{ Z8(f641a4ee,ba070aa1,7c9828e2,76e9d345,5b14a748,b3db3b6d,5d804b74,e8ad23b6) Z8(80f7b8b0,35098806,29d77010,e0a580d9,8f8b7a30,5753847e,bc10cf51,b5ae7285) },{ Z8(2a0c4b42,3726790d,f61b2a70,8b698cc6,4e1e4fa2,d7160eff,140ca7b3,5215df18) Z8(85e8e950,37e63acb,5835239a,8cd14b17,ec8f22a6,dca4cf40,5b1294ca,b45ad497) }}; const mp_limb_t arb_sin_cos_tab21[2 * ARB_SIN_COS_TAB21_NUM][ARB_SIN_COS_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) },{ Z8(e0c338fe,88ff112b,0c6e3774,88fa840c,ecc8f425,0a577f0f,e81559b4,da7478d1) Z8(85478845,528aa663,586b7744,fbc1d444,d865d6dc,d5ba05a7,41cb9c87,baade981) Z8(68403ffc,f11542a0,6437deb2,ce79b337,a2f156f6,0c75859c,07c31166,972d7430) Z8(ceb0c3bc,a4861b3b,8bf80ab7,b0abbc78,8b68d1e0,0d110d31,cc05e7ea,ce593092) Z8(af5dc645,593ad65d,03993f4a,eeaefea1,4b00a2fc,2dc7f173,d2bd9b37,9bea135c) Z8(1971c7b0,dc728536,23b1b1e8,211f57c5,93279c9b,943a5015,358fbebf,4fd0cd79) Z8(a81be4ef,2b15338a,c6d82eaa,1a19316a,a4e8bc2f,1beb1df5,d6ce0dea,a253092d) Z8(5036e35b,57c43b8d,09d059b1,98b8b569,46e2bf16,9393a979,f23e30fd,b163120b) Z8(5aa3c321,8a3ff9fe,120a3094,62122e17,108c46fd,9495201f,cd8948b7,15742c86) Z8(172ba7dd,4a122176,2be75224,65987e66,3c2980cc,fe0950e3,fbe7dfa9,a7a384c4) Z8(97531f52,4bba608f,d0e66952,61312726,91ef1758,9d5c5167,49655abd,e8eda144) Z8(ae32ae0d,67f16e15,97a3fe69,c315e024,855d6f35,04dcf0f5,fd68973c,5ed90796) Z8(a4360923,e70151ff,795df5fe,5c0966aa,7456952d,041e08d0,20a3dd14,56d51c04) Z8(423f2dab,06934477,d4e3a491,1d377066,246ed9be,8ba70628,47b3334f,c45e01ec) Z8(f9df42b4,1fba9602,069ee165,49a69418,7d0d19d9,4fd549a6,b641cc46,c156b690) Z8(f2dc36a3,3f3539c2,d3587a93,151646ca,0cc2644d,a6030f37,fa92f8d4,258f0365) Z8(d76c7aa2,144d32b9,855bd545,58df22c8,b8e9f930,cc5797fe,df450ee3,b1e32374) Z8(5a7ebde5,7c101591,c611113c,e5790d2e,b51e4655,2bf904dd,bbba1ba3,07ffaaab) },{ Z8(dd3a35ab,a15a52d5,c9ebf51e,8dcdb495,63d2504b,4cd532c0,417a36e0,aadd2678) Z8(425eccff,a5334f82,97e2777e,a19621c2,8fb7277a,40dccd39,0069ebf0,2c565ea4) Z8(45dbb553,ff159123,0aa763a9,8067cb39,6d765f9c,7102991f,5e6f33d1,d400589c) Z8(d27406df,36f6e1c2,a41e26c6,8565c202,efa3a9ae,07795e34,1c2ec4de,9aeb3038) Z8(e333b9f5,6033bf50,3508b960,8b9906b5,94c2061f,99c0fdb0,c975f687,477ae548) Z8(ea6bfde2,42d94539,0a6a6402,4935dfe7,ca4be966,74ec36d6,8f29a707,77284117) Z8(7ead6d11,fb8a01e2,f9191758,9c025d24,cb2f59a0,44286806,8ed8459a,660b6c56) Z8(eabaf865,5d070793,dd6e089d,bfbe29ea,4b674685,68074183,a0a1596c,13b55eca) Z8(8ee3bc75,4492431b,24d83de6,2f7c8de7,f9afed5d,0e5ef52a,9e48460e,cbd6e11b) Z8(022f6cf9,428bf4d7,6b9b1e25,2188d2f6,c66f5ca2,7d2ec765,cf0ae1d2,2da2960e) Z8(25c58808,0c947978,6d5dd635,fb0accf3,b29a49f8,2a02c8ba,28313397,d036ade4) Z8(83385cf8,6834d913,72a40660,3b42a69a,f7d6b0a8,49d92c20,02a48b6b,2aec3026) Z8(f056272e,e7bc96a7,b42abbd1,84df4b33,d3711284,b11a8231,aaf43244,a23cef69) Z8(26fd8cc9,120b47d0,0c3f418a,a09e7cef,967f14fa,8753c6ea,1ef7bc6a,d046890f) Z8(48dddb88,75943bdf,cd78fa4e,997993d2,3bcf102a,a6b0cab5,8dc658f8,de7d7416) Z8(11a56ec0,8a3d60b8,4b5fd1ec,a15eb205,4c229c78,85d6503e,670f22e7,2b1b8482) Z8(b371a8ac,4d44035b,0403f94b,fc753c97,a918e8cd,f252a14b,87eae02a,c062a312) Z8(178307b4,79a38edb,4a661fc5,419c52ed,94946fb9,576da4ec,a93e9589,ffe000aa) },{ Z8(62ec14eb,a8e0a5f6,10afa743,975ecb18,d37d0c3e,24f9e99f,3ae6cbba,1d5cb8d0) Z8(7ca7f6cb,a3bd8631,b1ade456,d67016f4,b1f5b7ec,8031d97b,de1e475a,5d5e11a4) Z8(8917d7f6,ea72c1eb,810bde4f,3603770e,a0c0e737,fffe2db1,4ded6e59,6e868a46) Z8(43f15442,d69ba718,5724d3e7,ef652979,7025dca0,c0068509,4b342437,ae721382) Z8(24ca37d2,d61a1d73,4daa0a71,136b22cb,55b8706b,339e8a36,fdd055f0,624d3f59) Z8(a052837f,4e51b4e1,7e11b078,4b4c4dde,68c94ff6,49f8c5c6,a6172898,b52dcca1) Z8(334cfb1e,b5fc541d,19aed5e5,67d74d90,f0c6885e,1b9b0c74,1c52627c,c834a323) Z8(8f3c774a,04cc5f69,a3c0e8e8,9e3d729d,ff026a90,c1e4d4be,f0ede5dd,ce220649) Z8(d2fa75cf,b2561b40,4d1ddf9a,106bff9e,faf3e806,49ba3a59,4e95a076,e844a836) Z8(eb29b59b,a70ce192,8f9d760a,91acde33,ff330c56,6ba95433,36c50df5,46cd586c) Z8(0bd428b5,0560d6e5,a8baab3a,5a2435f9,33e20ce5,c743f8cc,ad9c8f5e,feb33871) Z8(3426381e,d962c4e0,1e7ff5fe,2c85d140,e0abbc15,d6bf70b4,1731ba78,da613cf3) Z8(c0a3ef50,6746ec3c,747ada6c,bc53937a,d4d6469d,c3a81549,f66065bf,e443936e) Z8(b1e5ed23,a1e0ca43,52f5e750,fc00982b,1279c284,b4288c0f,fa05ab98,e3a1c261) Z8(0db2566e,0c35a5cf,08aaf2ee,43c1dad3,4ede8cdc,4e28f222,bf778a8e,5032c8c0) Z8(1ac0d7d8,8ed7557c,30c72f4c,47dfd0f8,c5a0de7e,78296297,96f19a00,cb583a45) Z8(7e56278a,89187c07,eb2f7c1d,707140fb,f05f828c,7df2b307,50480352,ccb76f0a) Z8(d8b57b62,c2fd5380,b9cbf2d7,fb074dfb,692d4aca,5d259b2f,76a76d5a,0ffd5577) },{ Z8(b2f3a461,bcc05676,e32fde39,c97fda49,5f5f3732,b5ffe9c6,3a485acb,5ae8e291) Z8(9f2a8018,61770423,3f4f8063,f5136161,dda87ae5,1c93b4cf,20980571,ed54ff71) Z8(395760ef,21a27ad4,ae85347f,b10b210f,df345326,b354754e,1576c5a5,d7b91567) Z8(8696d86d,07c16269,e61cd462,0c9747a1,a7e0f9f8,d8f7ac1b,8c698bc2,75ada6c3) Z8(ab912147,4bdc7922,69f16066,4c3ee0f1,945c03ea,e2c2253b,a36256c7,07972402) Z8(476c4263,20a2e7f8,6390abe6,611d379d,5ac779a8,f6e2efb8,9cfc47ac,b0502507) Z8(eb3f410c,00e83e70,01989b9f,d1ab1d06,2874e6ff,a6f64f9a,0d55dc43,94ffbeb7) Z8(1b2cc713,52891210,7ef259a1,f9cd7e0a,9489f286,90a7b3df,707073b8,67eb7d50) Z8(6af0edc1,e3d7ff4c,c0aab52e,9e1a05c6,fab4bdfb,b75e84b9,8debe52d,ec150670) Z8(75e2a407,ad4094c5,a73d4f2b,bae254a0,960dcafd,09a88275,e0fe9c25,e3b0e3f1) Z8(5f545f16,5b74e740,1f33c07a,1a80077f,9437fb62,5329e655,5df6de9a,d3150c03) Z8(9ea77159,75d9ce75,3f4ba064,e1ae5385,5bfd83ff,8bded550,27fd19c5,d22dfdc5) Z8(de4b45d6,8f58de60,e18c3aa1,b498d248,04e57a1b,acbc896c,d6c388f1,5439bea4) Z8(bebe8e59,f1467c91,1cbb2c01,bde418ed,19e2e127,bb2fcc2b,5d2603eb,8e28b193) Z8(95bc6bec,2b99c9a3,0a290389,cfb2759f,67fa0196,cccfcf16,af6b4d46,eb2c5f58) Z8(b1ae7846,d02b97e8,84c1e0f4,96ee711f,4a0e45f7,41602038,fb825705,86f62731) Z8(a4b2a421,ccd95f9d,8283e803,a116e80b,db02969c,383c3ab7,342fe205,b609267a) Z8(c3e646d1,fff062e6,5a2928bd,f80466e8,4de215b8,070f7328,4fa69a65,ff800aaa) },{ Z8(7e3d1af6,306e1398,1f737361,e0edd53e,c3b2c911,6eb951b7,82593dce,77339be5) Z8(dedc46b3,fe78a065,29a1f9f4,19182e34,a575361b,0cc235e3,c63b29ee,37172d63) Z8(ecc25c5d,90edabbb,2a1ad5d6,9f8688e5,324ac1cb,9938fb49,d683a12e,39b31ae6) Z8(1f6894c8,a79baafc,670f5399,47760acd,b8711b88,d966d630,fb7a21cb,2f3b9786) Z8(7aae678f,dcfd3d4b,5389393c,8f65e3f1,439f7fc9,b2a716c2,c2937690,0644349a) Z8(814a9296,b437ee90,5d97aab6,11cf9373,15bb199c,11c6387e,f7ecad17,fd9c1287) Z8(fdd5c3f7,78efaa15,f4b43663,6d370f11,513cc759,35522296,67ea06cf,619bda6b) Z8(e88c58c4,8eb31996,7aa3df00,8bbf1ba0,ac316236,9e74b423,f49310fd,fac7d829) Z8(abd1884c,834814e3,8d305e8b,d2e1ad20,f00a35f9,aa4e003a,fd4e3808,c6e3e2ad) Z8(687d53e3,473d7d3b,cdb504a0,9c554870,29045ed7,8eecfe5b,9c5054cc,a7aeabe9) Z8(5f98af21,639ff111,0c74eb09,f5e082be,d4d04a2d,596380c4,1687fe49,31587c86) Z8(b3a0cf25,d9d29464,b07c1169,3defaa77,63965af6,9149a497,08487555,171c586a) Z8(c431c150,2d3c3440,8b7e1f3d,bc9d8a89,3749f89a,b3f0f6d2,6b67ecb2,69df13a4) Z8(7a8f745f,dc6230f8,9f242116,61ddd376,44b8e911,8ddd0266,b5799624,4a4e3552) Z8(c4b699ef,c646f1d7,979d9cf2,38a5ab15,836bcdf0,a4c2fbba,32bff9ce,1f92ef97) Z8(1146a05b,ac6c29a4,aaf430c3,c5f5c19a,28ed8b5c,6ba19947,bda60cad,fc9fb9d6) Z8(0566391d,9e5c45f0,77b2a1c0,669ee14c,a4e4c850,27c6f292,1adeb42c,0a60fc19) Z8(db21f7ef,cdeae791,c393f5aa,e59085f4,501a1007,fc2d1800,2550e41a,17f70103) },{ Z8(717e2dee,8181dd09,4fbe442d,9f7710c4,25197ff7,6b5cb80f,495a19b3,8fb336eb) Z8(ad5fa360,b03f488d,e0350c6c,67389da2,feba6bb4,dc469f07,8bc497ba,ad8209a7) Z8(fd7f504f,93c5c665,4c35b590,d8db2f2b,8ecad7b1,51d59c53,cb60d901,e192f6c9) Z8(46440e95,58a04ebb,5820b109,dbe6f75b,f45d4003,e754dbe0,44194525,172b408f) Z8(d77f665b,86fbd691,cfb76d85,287e0e00,3c95c390,4655a400,aac98b30,f2fb2eed) Z8(54fee76f,5d532986,a2d09494,9fe0b07c,c06a8c62,5ef24a5f,d6357ec1,bda668ba) Z8(3246f86c,0806152a,728caba1,1494a85a,e89c6071,fbb05174,770d8a1f,81476141) Z8(f56b96e8,6a942c92,993435c1,3672b8cb,83174794,8a58a19e,c5071b25,7f71a072) Z8(37c1de49,de8ff2bc,63074017,46037024,7d316fac,7e399f63,4f7dc79c,507d066e) Z8(10c0a5e3,6996d46c,ca174c1e,0bb3e3b5,da387f6f,a760b60d,46fee35f,84394e7a) Z8(2ba8b8ba,a743a6a7,87ca2639,5e3ac7f9,8b60d39a,16c7862b,3bac9bfa,3370b3e4) Z8(2712f19c,d097e6f9,3cb39a62,8a86eb33,7a101267,f80922c9,a9bc4f88,6a1f9fe8) Z8(b6c41169,53eed228,90c9f40e,ec201e7b,71db85c8,e2786ac7,0c770c0e,1259c928) Z8(b062bdbb,fe68b0b8,010b5eb2,6425f375,5192867d,66c86d32,f44635b7,8d13b867) Z8(e849ee34,e9f8c4c4,3d89164c,016a3c1b,8d767fa8,bc290f6f,ce789107,1c967b97) Z8(4fda24a8,c0b74c3f,043aded3,8580b7fa,ccbf3c84,4f06a287,5ac5a313,2b22b952) Z8(76835799,629120d0,53e6ac1a,dacc91af,01b35920,6ffb549f,ef3f03ff,dfef1c85) Z8(d817f7af,f56a11fe,b961faad,c3813d8e,1b6b28df,2056a6bf,f35cda63,fee035fb) },{ Z8(9285662d,68ba398d,3b2de5b6,9c699e5e,a2b81b46,c98095a4,c21ce9ea,3342e3b8) Z8(665f3670,f2150d02,3175ca01,c80977fe,929f681b,b5b4c832,c52d661c,55fa7f07) Z8(04edc321,5dd1ea90,7a5864af,75aec5dd,3c3ca06b,79952f1e,c1a1912c,41281b8a) Z8(af9e96a2,bc896c56,42f4ff0a,59f26c0e,c7954044,c8d44eb7,315b23b2,9ba58dcd) Z8(d551a20b,27dccc71,01971d0c,f6774470,3cf54616,6f677f73,4d3fcdf5,915ff9e2) Z8(a48f12f1,b4fdb069,9347d23b,7fc4ae02,5bd79112,c3d70fa3,4f17cb25,c60fc0be) Z8(de9a11fc,2eaa8bfd,0d0f918a,bd92cf7c,4a1cd81a,6ed6ef9f,fcc20b8b,b015e493) Z8(7aea54e4,3baca448,63000f9a,ea64383f,ad9a4ff9,8e0ae851,5acda69f,e664345e) Z8(9f488c0c,358e70e4,4060242a,2a87e378,ebf9639d,e5d22873,6cfea8ee,f61b09e3) Z8(9b544346,19bfb12d,355b2570,73858e70,86c11b6b,6165c197,14cc2524,ae838a8d) Z8(bbd8d13b,ea3df091,780aa0bf,1df65e24,d422c944,f4fc75c7,be9b4efe,be4feec5) Z8(fb94423b,f8e6b977,34674541,1f359d5e,4834fe21,32c4a768,b8231781,15056776) Z8(f90d0057,e8c71924,e08ddb95,6e99bdf0,986f913e,d1662ac0,4f1e78b6,08c09a8e) Z8(a29cafd3,a4fbfb5c,493c2b1e,bbb58379,58ef9359,2694ae12,6cce4526,041432da) Z8(0a4770f0,176272e3,45c49bc0,289b9c51,0f0abf41,e5324ee0,ddc6d5c4,c9740eb8) Z8(88012cbc,beb05538,52f75f62,c7ed3324,ac4dec0a,3702f2fa,6c96888b,a69c919c) Z8(c3450e07,fa68567c,427dc1a3,e5bd5ed0,497e9b70,9c828f90,1ad10ae2,d190d545) Z8(59fd631e,007995f0,5e671884,5995027b,1f89f85a,069a8672,86ee35ca,1feaaeee) },{ Z8(b906ac44,d31d2737,071aae53,a81afbe1,1d0b38fb,e486e131,86fab677,43e453c4) Z8(fb679d1a,6b01f0ee,013b5a4f,85b61a97,0fd1d34f,1a07514e,e9fc3ac7,7e85e745) Z8(113c120c,c12388df,9374012e,6a8ef806,aa9c3d43,eec33f69,b728d8d7,6d9990e7) Z8(51ac8ec9,dd3cb025,543878e6,c5616c41,2a00de1f,081c375f,94dbdc7e,b14531ec) Z8(7edededf,2bfa77bf,6142767d,329e99a8,8caafb05,66800987,aff490cd,55fcc5a1) Z8(f4783c3e,cb3ee0b7,b41a05b6,b546fc3e,77ac426a,ed2ede34,813e3302,b7c6bae1) Z8(c4d2a3ff,44fc18e1,f1d72b79,077fe168,b1a4f0ba,1b37c6a1,ae525476,c82c8f15) Z8(512662e4,3c3e5961,655dcde4,cca52963,5efb4506,c17c34c5,fcbeeab1,ef9d3fac) Z8(fca17389,fdaf92fb,a37e0c54,ddfd90ef,8f34f1cc,ebc44c35,703099e5,09145a3a) Z8(0f583d8e,360ad060,fdf75e54,cb0fa961,b6bd91b5,c6680c51,374f5feb,0cddc52f) Z8(630c7b46,a25d5ade,6408e48d,a2267716,190483e7,99dc1842,6b98b0f4,e43c6d12) Z8(d708bb4b,f7bb4bf1,e7a3900d,8e27fc26,a4b7b501,ade110f7,c987082b,9ddc2cc2) Z8(3cc973c9,21777ce8,cbdaeec8,fa457f1e,2d288e3e,e3de84c9,131b0e16,dec6b5a8) Z8(40bff4dd,fa0f98f5,6e4f53d7,9b07d7c5,f1023070,63bc9832,af0cc648,045c373d) Z8(7711011e,0b477e89,c44052ea,8f6b96dc,ea22a4fa,dbb5f983,b00d7ec7,da201c52) Z8(ca721152,37343867,d0792aa9,da0120b0,954bd6b7,6509c28b,b5912d38,0f28806d) Z8(b7a7f8bb,65f0ab60,6d2a89ea,f2a44834,6b128c15,b1146ebf,41c56b3b,34935607) Z8(e7026cf1,962ddb33,783f8310,649bab98,f6f18ce5,1e6a129d,eade9b6d,fe00aa93) },{ Z8(d6c90eeb,5efbae71,ff432f81,60f0cc69,5715412c,bfce4e56,2344d121,0965d777) Z8(2163e83c,0046a728,bb9c3fb8,864cf453,6c3ecee0,45228657,320e21b0,5364fc9c) Z8(0333b45e,227e6637,7dca7f31,98225247,10d79b41,913e73a4,f2afc29a,cea093ed) Z8(cf057c7d,48cd7cb0,691e37cd,307f20a2,049f865d,da31d7ae,075f79bb,4f489d5f) Z8(77dd2ee8,7e58fff4,f59c5157,a71a1455,de35f4f4,2449393e,fb2f77a6,35de80f7) Z8(b1d83f9e,901ec905,50f6af5a,0eb56d43,f560303a,0cc55115,eefeb90f,fc069560) Z8(b2b60a59,f7cbae33,3b11826f,f1a103c1,405ab789,32b0fd12,d86c706d,cdafe8a8) Z8(64c490f2,5fe195a8,f5f204fd,2b072d8d,2c8982e9,47ad4c9b,e545143f,98be4251) Z8(061e2608,3e2b80c1,28650fa0,05963c91,b431178f,50e53848,263ff639,4d7dfb61) Z8(f0c1f6c8,6c790418,67da1798,1c0bd8d9,5f4302d7,ca80ff4b,1d0faef5,f2981188) Z8(a6330c9d,7866ec89,b263d3e7,03e611e5,91983e07,3a264e54,8951deae,f08eba6d) Z8(fd3fa44f,20d5c4c6,8c8da320,4ba620f6,dfb63bf1,e55fcfc0,a4ee6f56,8e51a449) Z8(99438e09,70946b37,484121e7,8d5f60f9,38117297,081f2a29,846ed588,193d3f3b) Z8(0d10f2a4,1cd14d47,aea5d9e2,ccb6ba65,f8d33f2f,fb77f119,d49c0fea,33546a79) Z8(fee109b8,2929955a,2da69309,6e143774,9d8aa54c,3ebc25ae,ff474070,84073474) Z8(8b06f120,7b364de3,69aa07d3,fb7bced6,dee40d72,ef995402,bd534ab5,1dbee581) Z8(5303bf5b,945bf567,97cc631a,101fee1a,c9a382ba,946c7b36,d8e715c9,bb6bdc22) Z8(6234ffde,9b8db9d3,b56a489e,38c5142b,5c87d594,eb335b36,bacd96a3,27d66258) },{ Z8(5e12f35c,68696d5e,10dd4783,102542c8,77892630,58f73581,f646babb,be682f10) Z8(b93bfce0,308366e2,20e5956a,9780d712,3653f238,0de586a3,dad9c87c,4d529306) Z8(39693b5b,a53f9f0c,2bfb04f3,a16b6459,9aa4e938,4214cb73,93602c3e,ba0042d1) Z8(9939fd9e,fed7481e,04b95eef,a4a16095,0a1949b6,2485420a,89a68672,fb062e83) Z8(db7a7de4,f3d1c202,bde24f55,2138afd0,b6639cff,d53e76de,dfe9b806,81f31918) Z8(46d3cb6d,a152e818,ffb15c50,8d5cfa56,9d0e1c52,d3a2823b,a8cb14ef,3cd6ff24) Z8(a990d32a,becd566f,9d7e9a2b,5ab11ad9,7ea3b116,7af7a26e,1d34226a,f12ea1d1) Z8(458ca4fb,2f782353,d2fa2ba8,eab2b7c4,f3c7327a,1107595a,a4dfb194,6dedf560) Z8(2e3853f7,8ade9d69,367fc153,5954fa8a,8b489a0c,25849675,c2959237,3032e839) Z8(44a35a6c,513735a1,7a0da995,455d500b,0d382bc5,dcf7dc75,04447bc0,c69877b9) Z8(f19053c9,b6dfded5,e16b083e,bb826fc2,bf16dd8f,61229267,f3bee9c0,4771f362) Z8(0fc27152,b9d6de50,8397862c,7a1b9f15,038f66be,062a83b5,8f84dab2,71f01f90) Z8(1aa69ee6,7d062493,abd7af62,50d8e1a9,4c6f6ed4,f2bf1b4d,593bbf02,e5b0cd3b) Z8(e4778360,e1dc14b8,c3f92800,31aa3931,64366cb4,fda3dd33,dd1cd326,6bc62d1f) Z8(f5819147,bc1a969c,f254d583,4b3e8a71,fbd79678,523ca325,50d5dfec,a81d6822) Z8(ecd11c36,dbde0ebe,b67d05c5,bbdd0f90,09eae33b,0408d187,25c0245d,cf0afacb) Z8(73c8905f,3b423688,f9e8c865,269f96c0,271485b0,a5a9a65c,649ac8f6,9813c9cb) Z8(ec796a24,10e95144,6f922acc,9dc71aa1,8c45bf0a,6d60c76e,e621438b,fce1a053) },{ Z8(8e602d79,b75923a5,46742dec,e0f34f66,5c65f549,5a84e693,29b30ab6,f685627e) Z8(3f616732,b46c144a,20eed860,bcba0aec,70fc0edf,5020985e,e3aaf28b,4ca61f2d) Z8(8d00016a,484ed26c,5d26a525,5a358509,4a15b5e1,a1404d86,9c0477a9,20dc268e) Z8(af22ed71,2f26e2f7,72f6eb7e,554f6fcb,bdf64b86,fcde2f23,e07e0878,e2ee03e6) Z8(34e2cf9a,30df7366,732d86b1,ec8924f0,02e870f7,64cf7a4b,50e74d69,02ef152c) Z8(54ca1803,d7861965,de5ddbd8,4765e3c9,78320497,13d3a798,6d9dfde4,60d2acb4) Z8(08eb06c7,6cae6f06,01904423,a98df786,c36a3584,6d159a6c,605dac4e,9423adc2) Z8(bd0dbffd,dbef6441,7bc94d1c,c661fba2,cee7aa03,145404b0,e1855fc4,f596e657) Z8(cb20af50,d5702076,3f7e9645,d8699d4f,4a6979be,caee70d4,b1451bcd,693c9748) Z8(9c306350,bc2bf666,b1b6e32f,0b1fcdad,40b207c3,497d4adc,59d13275,38559384) Z8(6ad47c8a,cfeaab4a,f9d18d13,4e6e04d5,2597221a,d72b96ff,339db714,c772ddd2) Z8(3df7cdf9,c047956b,c3401f7a,85c269b4,6dfc1938,26b46a28,ad474d52,9c47bd60) Z8(b0dd0c0c,2910ef5b,872af2f1,4d9ce74f,f7253fe4,c5a86573,3b084a3a,f50ac9b0) Z8(5410b3fb,1423aa40,d93c355b,6ad5da45,f07e8725,d4f3d009,480a737c,e2fa759c) Z8(81b5de24,5a184229,4335f1f9,4b9339a7,e7cb689d,50a495e2,db7840b6,529d6fa1) Z8(67a1c812,9f3ea571,149fc547,f472261d,ef91b3a9,d9be3dd6,0a6edf10,2ffb6c18) Z8(cebbb957,432de451,392a9edf,9420aa30,7b858240,ad4158c3,5151ea43,4b44a6ea) Z8(59a6b00e,2c05e4df,e0189ef7,769af396,2f856258,56a1c479,75e56a2b,2fb8205f) },{ Z8(807ea336,409f1d94,9dcf1be0,6dc44bb9,ed55acb1,32e94bce,c95e0fd8,5dc9f9a2) Z8(bf5e862a,30137bf6,87cddf46,a6270dd5,acdcb600,576158ae,3f97926b,432cc4bc) Z8(16b60325,7fed69ce,fb53b708,3313b0da,73b79b89,6fe8d1de,dfd2c778,b419b62a) Z8(9fb1af82,95872034,365c4ebd,12195f24,a4c04f51,5e64acd9,96fda853,a65f7894) Z8(3f09cc9e,86e3c8f8,37b6d6bb,90ff06c4,54928ae6,bb6ff537,3b6d8d1e,293c60a7) Z8(660f9aac,adfc4321,578d2b46,6828f7b1,13929da6,e8c831e7,5e346e24,c1047baa) Z8(ca71b75b,591e92ed,629ffa3d,445c44a7,e11b806f,135cb589,1211c0cd,e907a55a) Z8(18675dc6,4a527b4a,ef07a4a2,512a2f93,a10520fa,fff23185,337ce9d9,3af4a900) Z8(2c97f5ac,45700f76,0b2fe32c,72ffae11,0e161536,8977f1ce,20978375,726dbd5f) Z8(3de1e3af,e79c9776,c251bcf9,6d7bb4f2,12707c32,35758e76,446a1c73,89e0817e) Z8(14789d0f,8a47c6d3,17b2991f,ac6740c1,053a3a16,d9c60639,00dc3855,2de07dce) Z8(28c31eae,3d719b9a,c8f7d057,266b26a5,898a4039,89a10b0a,d0537ca3,81a0d78a) Z8(5d508092,5a47c05f,92b75088,10434675,616900cb,2032f566,9fb3cf9f,882e098d) Z8(fbf1cd39,8fec6a1e,31022c31,ffeb46f4,fc96afc2,fdd50ff8,55bd7175,32dd97d2) Z8(de6f59ce,f79d0ac1,6865f9d4,909f2f84,f9c9c03d,8478a90e,205e3954,6ac2df82) Z8(e3955ed1,34f6498a,106f9e8f,14677bce,6f64fd3a,b271972e,96b141b0,ee84ef81) Z8(f29c7c34,b36ec3de,a7ac174b,92950edb,f914f757,8c62b2e5,3bc76154,26e8b67b) Z8(9f43aa56,9b783f4f,e9cdb389,ea358867,697eea13,e6fe7924,f670dd2c,fb835efc) },{ Z8(a7b8db7a,73db1c99,1aca5f52,82f79bad,394ce5de,b3038026,ac33bb1f,11e5554b) Z8(26fa53c8,24996480,450e4486,5dfa8298,c399be91,be007b76,db1bfc63,1b6fcc23) Z8(17bb2e16,3ce4393d,301bd52e,77a3eca3,cf9deeef,0695e444,a5dfc765,b37f20b2) Z8(8e47e176,998625bc,2299c18b,c5b8c3dd,18fac754,8ebf7a75,e448d1ff,ebf68862) Z8(b2b9fddd,3097dd93,d320bcc7,ad88f722,c4b381b9,200e6534,df9c5a32,8a7fb2d8) Z8(1b82a341,2357dd79,84aaced6,e0720f60,9aa69e9c,cc663b62,5316218d,f24efbbf) Z8(fe2cd03f,527dd776,0e89cce7,f63a4c86,52be197c,2c5841e0,3e9556dd,f97d43be) Z8(509e56bb,43a0cd72,c0ac1a37,372dda10,88a59705,d3cc48fd,f5356b1b,9158cd7d) Z8(3ea3f789,0f0ef5e5,9d9530a2,4633af29,a60c0f3f,9ea64098,8c8515ea,1a5e2131) Z8(7eb0daf2,ea0e0dc8,29d45251,86ea65b6,963a98fd,5e297cc3,457aeb2b,f0d2a4d9) Z8(84ef502b,18740906,91e713ea,9bc97c89,dbd6f499,3c0f7d53,4436cf5d,0c48a29a) Z8(9c3add43,870f7ee6,ab7b59a0,6534745e,e10ce1a2,3c6b2515,d58f3d47,8aab6c74) Z8(f39f6d9c,b23c0de5,9d43d6e2,c1783f91,ffcd8aa9,6bce54c7,8e3ddea8,7104ac57) Z8(6a02832f,514335b5,52fdf84e,34e29594,9f36739b,67f3e2c6,2978da94,010686ee) Z8(cd06b5df,2c503cc8,32ef2461,8bdeb418,13378a71,4bbbf710,04866acc,e3812056) Z8(7c8cecbe,b095ef6b,21642ebe,cda71c58,465f0975,5c354c28,ab5ab64a,4548b927) Z8(3f3dbaa9,271dbe0e,0dabe8ba,d8ee03d6,6c3015ac,2bc1ba1f,5232ea30,1bb9f1da) Z8(11c1cd24,2b496c6d,768f68c3,26ea336c,65582e45,0d2b53d8,b8c332ce,378df09d) },{ Z8(8d2fc448,01883acc,d239fcb5,86bd281d,e7e10f7d,4527bbdf,560c7a76,222be7d1) Z8(55810d06,f666042f,5cf0aa3d,b8d96388,1c9b0c3d,a5fabe4c,0cfea960,91ca386f) Z8(41af1c0b,313b7985,32faab26,d6d12c15,db7e6888,fa58bff7,ffc3b6c5,bbe2860b) Z8(09eba40e,4765739d,c9af87e7,a50a5978,2cffaf5c,11015817,38d3b317,45e1eab1) Z8(37e0a574,e630e526,8f84312e,d57b455c,075f07c3,50117f1e,ddeffa0b,fe955e66) Z8(96ec7ccb,8f3b0712,a7b28fb8,d59e3dda,31c9d2e3,20f83452,b50a0729,e844d6c1) Z8(e90da717,b74ff029,2029ab23,81ccc3af,7c6f1a49,b746b340,51b9a177,6124915c) Z8(91a07ae6,3ef184fd,65b0ba5b,727c2fed,79645315,900cc21b,5a445a91,ad4cd4f4) Z8(c1daabe4,2f82b998,e42f13be,3bc1a3a2,575743e7,4911e831,5af9eee8,f2c4c858) Z8(a13bb978,51cf0eab,d023b6b5,0a7b9a45,f1949b62,e72fa9a5,9e08e90e,8e819cfd) Z8(5e15635a,3c911bdb,40de9d2b,648f694d,9c5786ec,9db5aaa7,551c51b7,1e49bbab) Z8(c09a60e8,18d76efe,623248bd,c7be1c79,95472115,31044865,c908a576,21e11df3) Z8(8b7cd5eb,f129c6ed,6aacc64a,8893b696,a822a026,74552784,f705eed9,2cef4b30) Z8(15afe4ab,c5d68698,eaf46cf3,711ac20d,415a010d,6dd4a603,a985285c,180a8af1) Z8(437fad60,5f3470b4,cd508a37,58ed8983,a4ab74a4,fd81f7ca,07cc3107,25c347f2) Z8(48a1aa42,034fdf8c,11b29223,e5fd0384,717e640a,197ec082,a9a10d81,af945024) Z8(62fca407,508dd123,53b9335c,0d26d438,17a36a41,311495c3,b4ec686e,65e72f7d) Z8(bed24b63,7bde901a,e11e09fc,1fd7fa2f,5b5ed9c1,2e296bae,9e8b6f6f,f9e63e1d) },{ Z8(b8e13d69,88c390b8,7dcfcdd8,2127888b,96065c17,0b78d5b3,52d55d98,1505e30a) Z8(1eab523c,d817681c,8490b96d,4764ea2e,c301d9c1,75dee1e5,0c37916f,2ee25f7f) Z8(11e2618b,a07c7950,0ca661aa,bd448234,18811f0d,c8cf443a,546bad8d,695c9894) Z8(a2636796,77198c2e,7e914f9e,59fb1cf2,ed194c56,d7310b55,3645bd99,668f6490) Z8(364692b4,1356eddc,ae8f6be1,d46f1619,2477476a,93a056de,f984f9fc,ee4237a4) Z8(c23e81ee,d37edbab,da38594f,3da276a9,7eb593e2,6d9f0277,fcbef52a,e44ae853) Z8(3e1c7d11,97673321,446a2175,8a0f1c94,7ab92e26,e842179a,a926eb9d,f683dce2) Z8(0c7a57a7,fd7775e2,ab33b8ab,7a98033e,2476979f,8d110d1b,de25c50d,38cbd9b4) Z8(145719b3,e7e8c2a2,f052031d,f557a52b,6d9106d8,d8ed170c,37f27248,f5c53e87) Z8(39b4527a,40fb7137,38ab2f52,e5eb7cd8,c771d782,9603966d,313f3b6f,2a3e7004) Z8(82ed1368,9d7f68b8,ce5f87cd,ad8f2a0e,bc9708d4,aef930a2,334a3c06,76a5ff93) Z8(5382af74,1a2bb834,41d9cb22,3fe865e6,0e5d4404,9044da8b,48fab53d,b6056afa) Z8(ede4c268,a2d01f91,bdbadb51,5e4ac05d,b737f868,e2d88c05,ef4c2147,741fac63) Z8(8ac09df7,e5e413c4,bafbd900,523b9c47,714ae638,2c7f3fdb,be984aba,1caace1b) Z8(b07e2a1d,85981902,68322690,9d8d2d9a,0b5c16a5,7047d743,1a9e72b6,5e981fa1) Z8(b3ea9e10,5a90781f,6746788c,acac168d,285c1399,d5de8857,198a89cb,efb5415f) Z8(4067fb09,06ae637d,ab3570d8,bd2a7e39,50b49ce5,2b800c53,42a81914,3c7f2854) Z8(af9330f0,898d7086,8d7db525,dd567664,6a3d1635,13bd7b8e,e62aed75,3f55dda9) },{ Z8(4199ce08,6d518285,33246122,0ae26a3b,9b0d4695,edde6b77,b825b53e,cd23d9a1) Z8(1600a160,533a60ab,ace9614a,25f844b4,da617d0f,914ba3c6,a2b5749a,ae8fccbf) Z8(b8aa08f4,ec37e5bf,8a6e64c1,d9a1d060,9afe1389,8c8916e2,4031cbaf,e7ffb3d2) Z8(459f5557,e9582dab,ad0b76cb,22056e5b,962cf535,25660e54,56973d81,4eb070ef) Z8(f8725653,f5d017b9,c7b6df50,53b3db67,b2e5cf9c,9dc43f98,6f03d9a6,cca7e64a) Z8(771fa350,47c5c428,6a28f9cc,9b7170b3,2680987b,082ee995,46271b64,a063728c) Z8(2fa5221f,ef1dcb37,95595ef2,cfa32807,92e9fa58,2917adb9,e7024465,da4dae33) Z8(d447adec,1e05440a,32d6d7a8,02c44685,e49b618c,b9e29b5c,c8d2dd5c,14081a9e) Z8(72be8628,e1b0da3f,d52e462c,7e34143f,90bf5b2c,1afb61c9,e6617ef5,1a31ef5b) Z8(c33a6227,db194899,c4b08e10,57a59cfd,66fbdf76,622e22c9,1fcdccf7,80ee30a3) Z8(335fbb1a,ff776bc3,b7d7c5df,886c8e04,314ab5ba,12823b3a,0f76c78a,9253c6ab) Z8(5403dd58,f27416c2,430e0500,178c8c4e,a25720f0,ec36ec86,fbd239dd,6a6614aa) Z8(d2ffe2e3,e5bdd91c,b1702031,1cd5874e,aa4c4e06,35bd7d77,a911dad4,ff976cfb) Z8(0ea8291e,f8c76d83,76f935bf,151c9ffb,6e222fb1,7be899ab,3e07a85b,531b9e60) Z8(2a6cee0f,37362ed9,705d7f6f,6d709942,c37eb320,3f31b66a,fc3f01a8,258c828c) Z8(19934f37,629234b8,6a27341a,a3435251,bda011eb,04bb5812,af6de116,48986a09) Z8(3295498a,2b7c5621,9c7761bc,2bbdaa00,6bb135bf,3a867cc4,ee16d0b2,0795b84f) Z8(c944551c,3ef9ec13,9edc4a02,1426dbe7,5f94f8a4,83d33cb9,ef750ba7,f80aa4fb) },{ Z8(658901a8,afb76b74,4e8352d3,d6a5a865,8cd0f19c,3909ef3e,6bd99518,7d01113f) Z8(f0455467,de092c92,9a991ccf,0b4b2a53,1c581d98,9311f90d,02c586b9,976848fa) Z8(4d659162,120a8be1,dc95d5fe,801c2a71,f7ec2d7c,72c3d96a,96beb9e2,793b37fc) Z8(de570b2a,c0be83a3,92d7e27a,71e7d6b7,d2562831,3ae1551d,5bdef1d4,f046b7f5) Z8(42a88c63,0a555989,94de40d0,4537fe73,d244f748,43105905,5b676e01,d1b60ee1) Z8(34f0b645,e39ce7b7,19070f02,12d84223,60b4c48d,c292117b,de2e4dcd,24f7b2fc) Z8(a3267ea8,26b60f69,095c7e33,b23ed300,0d3691f1,57c203be,aa96cd9b,c65decbb) Z8(0b3377ef,f1c0421d,b3cd6584,8901e493,114fe65e,59db0057,0298eb95,4c484b96) Z8(e39c9e37,c1bd1c12,a996a0a0,b2c051cf,8baa5c96,6dd418d3,e2c7b3ca,8f7e6c82) Z8(a850ef2d,513fd2b5,baf376d3,5d9af598,5da37d64,722cbb04,40dd5626,8c6b32f7) Z8(428d434d,ae3f64ed,dc7e5991,bc14cc2d,53138c05,c064bbf9,2c270e80,b4469fcc) Z8(40c2ae37,78d73472,50028ca6,b3833d45,6b8206f7,90d6c2ba,f18dc4ce,d2116630) Z8(5ef11ffc,f52f9631,1478dd0a,891454b2,aa02f870,29df6673,bff4e564,6a3a10d6) Z8(2f9ce4ab,8f723769,04487612,add1b618,13995af1,1d870653,370736d7,76c7f067) Z8(b5b6af67,f35e9b43,635cc97d,f040dae6,a6168bba,91b508f8,f25c1c61,d74195ff) Z8(b47bb43a,08e1c3d2,a24dd725,55674a8f,f8794226,14fc6498,2c445910,c28accaa) Z8(2bf07d16,dbf41cea,8ccb2f71,2aaa9b54,63a979d9,3ff98c35,fd335d10,98b5ae87) Z8(639e1f42,21f8462b,8ebc6078,bb2ede61,ff47fe31,076fe0dc,1ae1d946,470df593) },{ Z8(991b423c,a4084c7d,bfe6ce7d,b6d2fa69,c818114c,6f16ced1,0a4a3dd9,aa1c113c) Z8(8c405b1e,2605f8c6,0df298a3,ccdaae7f,db4aa3cd,a9f1cf71,45f86418,d4bf16a0) Z8(16325412,534e7e53,422ac10d,9e1a54bc,86d7df27,2aff0bc3,f01ff86c,6bbf46c5) Z8(ea821e63,83df41ce,d54caa8d,f888c076,e41438d1,d474a49d,2fb1ad44,6c99f3a8) Z8(7cbaf1c5,1b3e77b8,ebb1bc87,f086eb37,eefb8c96,e7919ae8,5920d6eb,1aead620) Z8(383558f6,1a812705,34450e94,33482906,e1e88395,ab0a1670,515b7765,711261e8) Z8(1676bd18,1e6309b4,97b7c05b,87ea55e5,b48b298d,677170a3,29de4429,eaebfa11) Z8(58cf0a04,3c34da0a,fd7da0c8,97548159,81d6a85c,43f69b76,c1c7e657,b36fdd0c) Z8(de64c266,15940c3c,9d18d004,24dd9191,0e231753,5ef025fd,2669cd3e,623077ba) Z8(f5932c5f,c6812e5d,a680ee87,e25e3fae,a55aab31,a9ce23e3,e6f4b2cc,9fd835f2) Z8(b436866e,9b4fe07c,f73f87b1,1985f017,6c9db731,1cd9379b,e135874e,dee5eaec) Z8(5df97a16,0305d1d7,e4697a06,3f444cd3,b22a8643,a1c8fc36,3bc8166c,6cf6bdee) Z8(b719965a,e6c40cb9,1e4eefaa,5033c3a9,719b5f40,950a8ea1,8ca08d56,f153905c) Z8(6f10c542,5e1011e8,6211ff84,0f899e08,e91c031b,fbe3cdbe,66bf4830,64eca749) Z8(1ad21d3d,6fe4b411,d2f0df55,94f3702d,b2ef60f8,ec3f66bb,01fb9e88,a389942d) Z8(53b38892,07b39c1d,279769e3,7ca3f502,2f86f959,83cbe64f,24a5e5a8,4947778f) Z8(fa289398,cb4f5054,b36a1f04,25331b20,4fadab99,74d7a229,451a7da4,29977994) Z8(168d2e7c,3b9d623c,c0f82bae,80d01ce3,78427832,0c1da8b5,b77d3dfa,f5f10a7b) },{ Z8(a38b076c,5e1e6f88,51293819,64faa216,1faff346,dd3d5bee,d172eda9,4d077ac0) Z8(093b60f3,282c6925,1f1db066,bc7a7df8,16bb43f2,e8b07391,0f6c69f7,c906c608) Z8(c4391ffc,645c470a,1c57f5e0,289d0b5c,b434c586,d9efd754,92cd26e0,b99396f4) Z8(39dc8066,c4c3e0b3,6014525a,58dbdd56,b7ed04bd,bd631d68,529dab91,0230861c) Z8(51880305,9153df8c,eeb53562,1f10d66f,ef6b3334,778a96b8,11734dd4,ed19cf56) Z8(ec13c796,264152c9,a9462c92,15d73aca,c03f1b1a,5e67392a,36fbb97e,4b8f6676) Z8(16a6f718,362332d1,b8182685,dcefcfa6,df65a914,a6b9172e,2917075a,636b1d51) Z8(2bb7309c,d7f47ee7,aa113fac,a38874f2,ece74ceb,04851219,d0ef8da6,2ef6bfbf) Z8(c7647e4f,5bbf6e89,4cc2b136,142d5be4,4b97ff59,e5dae53b,b73c6bca,32c81a37) Z8(567293ca,6082aec5,22a21df3,d47d6686,142662c4,34380928,f9792459,3b3f4bd7) Z8(6bdfca60,df50345b,20a8f2ee,6e0c6059,dd9aeb3a,69e9d146,064dd736,f5f7e936) Z8(b1ec4311,4f31747d,f7e08d1f,41270617,fbb0182e,902cf2ca,23ea22e3,584932f4) Z8(bba30075,521e0d23,4afd1409,69544017,f25f90c8,279141c9,05288130,aedc2552) Z8(ea9d9cda,3b93fa5a,c78cfaaf,7419e147,2300ed27,b6a104c4,0a31f2f4,0350334e) Z8(47c1eba9,cebe9bbc,bf82d1b4,71771ce1,502ce7bd,98d55e93,fbae1b39,75c4acbf) Z8(09dbd5a1,62486a57,0958b41c,9e7c9d11,4cc62cde,6416304c,56b1ac3e,9a0fca39) Z8(bcee4138,848bc08e,f0f69a78,360ab090,70f66468,b6817754,7f010355,28036dcf) Z8(05f85471,a46977b1,b3eb2542,8603ffad,f0734e28,07aaa090,a74f6002,4eb44a5d) },{ Z8(11a0322c,96ba4a01,7449c99a,e6addc1c,45f715c2,d1b115ad,59400c1b,d577402b) Z8(e44c0835,ebc5cfc2,4f5e58a4,19e1d245,bb4c016c,8fcccc1f,558f03d9,c8768e5d) Z8(f6c4b265,8e1d846c,23dfa3cd,5c6b83a4,514fb750,2d1b94ff,2c30b25d,86d538fb) Z8(8363caba,cfd8d47a,b22dba78,6a9d978c,e7de140f,b81f9b31,9bc8c52d,f64e839f) Z8(dd62b2bf,0a42f5ae,d7e11572,0e1537c8,4604d4df,6cddcd6c,854b3506,6b76633f) Z8(fc09e0e5,05aeadc4,8c2569d0,649d3844,ba0199dd,5620f428,0ae11889,89f6aeeb) Z8(2091d695,1237808b,c230b3cb,920a9d9c,aa5e8426,18a90271,c8099072,bf4e7e4e) Z8(408fdc7c,379930d4,d8fa4838,d8c1e2ab,c992088b,8b1f2268,f30078b6,ea95432a) Z8(5d5dc118,4da95e47,3e3865d0,4abedb1c,28ac87d6,bab110b8,60ca6ca1,5c6b6b5f) Z8(95e18395,c7bb269e,9c3ab328,b36f636e,55715123,066fe445,4af3fb03,12ef02dc) Z8(b5e71766,bd1ac7fa,a6ea3b76,e6d5e849,7e352636,2467d7bd,b0468f48,41c8566a) Z8(2d4d1771,054b69f2,d8f32bad,cad56c19,dc35bbd1,f2213deb,120c7651,6b982d7d) Z8(d06706fe,f53123a1,b3d2d5de,0af9bf65,4620aebf,61a8f091,0160d70a,7c0340fb) Z8(3ebad401,583c4e54,08362686,64269612,11488ebf,0fb2fbb8,76813439,9a2d6b99) Z8(6d012ae4,700145b9,13a5ab6f,8df8ec13,879327bd,bcab7729,eb1fd332,157a061a) Z8(30d688fe,a7efd763,db99ca8f,efee2e83,43ac00d6,50c7809f,9f1aecdf,060f2277) Z8(c51a72d2,f0b5b03e,2edf9702,ec828b07,bc24ee60,10c39d7d,ca275d90,81d50d3c) Z8(8e5847d1,49535086,9f101ee4,102beb56,3dab8877,ae995726,c9e9fd37,f399f500) },{ Z8(3706931f,05ed0c9c,701554d2,c29b0ee8,732866b4,1dd1a2bd,b4749fec,7d7db5f3) Z8(ca61e943,c70bb3f7,c39da7b1,e6d1cb16,e0afd06c,2b179dda,54dd287d,b374d62d) Z8(76109c45,18d0533b,bf958a6b,2dfeec0d,541e83e2,7659c439,4d6b7608,a66f5177) Z8(c33026d4,6c899756,3c44afea,9c57df98,f15c08e4,a32a0479,eea420a0,29445d68) Z8(7217caa5,819b825f,874a2662,dde28854,3aeb4992,4abfb2e5,7e07a740,bba329c0) Z8(21c31c4f,eb8591a2,8a9257f0,80182260,55280e9d,5cf2654f,83f6d5b2,6e271cf0) Z8(367e69e3,b5262ce0,1758bc66,e57bd7a1,e153715d,a7532a19,cbc826f2,c3bb3186) Z8(8d036cd8,b8d468db,6bdf37b2,102d6d48,ac01cd37,cf584e00,758fe886,e18ec1e4) Z8(a3b2ca80,54fd5839,ef9809ed,c48aeb29,f02e0eb2,40a831be,64b93309,78d5b6c2) Z8(1c6a2572,8d88b360,3908b39c,61bb3d90,f4e750d7,89161ee1,32adac24,1e411f75) Z8(a4259676,7d91b8ec,789d7ad2,27a9c752,da37efe2,f2d99a1a,c2bc9e11,7d279d5f) Z8(001d5116,c14082b9,ad86660f,9e014b98,a91cf6f6,98ef4a35,240090ce,66238d9c) Z8(47f4d5e6,1d7f490b,58086812,3fe6af37,9a0f7aee,2b7b044c,f6c71180,dc8c82f0) Z8(c7ef4049,d94c5c9b,ee7280d0,4aa7f194,45a3580c,7e7e8c1c,ef68d405,16611ee0) Z8(68700445,a48a3543,c62636ae,d6f51132,9d64caac,b10d76b3,644823d1,2b763fb1) Z8(2eee2b1f,b33fa2a8,0cec9c4a,3007af5e,ea98dede,e5fba6a6,8efa3ac5,e6806e20) Z8(d1ef3f4d,f1adb65d,0a2d8a5c,517aba32,54d27068,ff875262,d0222eb0,d9ce81a7) Z8(53cdfc90,b05ae267,74a00246,ee826d96,06572290,3a5d61ff,8bd65cbe,5646f27e) },{ Z8(17efb865,c381859b,07c1503d,e9709536,4870f925,764509f8,989adeba,7427f66b) Z8(e85662d0,3845f656,682b6325,0ad20fcb,43c60b2d,64f426f0,6cbc82a8,ce8551f1) Z8(68fe7baa,fd558e2e,0cfa1772,1e6dfab2,7d558792,4bd46f38,ee530ff2,9208a132) Z8(fa6dd952,91c2d0fe,cb85886b,029b0fb1,75bbd48c,da91039a,142791e5,c27049d0) Z8(e6a3fb42,21fd0a51,74efac80,e8cfc6b0,8a7d2ea9,5c1cfc5c,2da8457e,4f967cc8) Z8(49197888,90797dfd,c3a4ca9a,4ac8a92a,7fd9cad2,cfa0d0ed,d86d1a4b,1e746f0b) Z8(64ecc70f,f71ce45d,e181a191,c98fafb4,c5e573d1,90b3069e,70b80dc0,769ab688) Z8(d067eb28,36d7021d,b26b9701,74ec1a71,c3378ee8,b8aefa78,13939721,3e88bf16) Z8(c3ae6b46,ad9a092d,d56c59ca,09bc35a4,87689ad3,1a2f1fd5,dd3f6609,ae658555) Z8(fdee2013,bf40a73b,940f2843,9f90b7bf,4dd52bc1,4ed1944b,0f5e4fc1,cd153550) Z8(ae0e29c2,f7753c6b,9f230a2c,393488ee,e5bf9fe9,64d5fcc2,a86d927d,009d753d) Z8(16a2f266,5a544be5,cf4dd91e,1e8a868a,a38da902,e09ea76c,fa68b3f0,1de2208a) Z8(6084f467,b129b646,3c81c9f1,80b7dcde,12bc9718,d1687293,f56b88e9,36b9d87c) Z8(b21a575f,d587d304,d1d2fcad,2ddc72b4,1ecf7ced,02c5d20c,fa265e7f,3405b6cb) Z8(901db0a1,96906cfc,ff6fa7e3,d3fdc053,f44c1565,163954a4,3de4223b,2a99512b) Z8(73a9f7e1,abc68551,945b3a89,08410cfa,21e3fd1f,406a1b0b,8f28a6c8,597aefd2) Z8(7f3b6732,1228f67f,29a4d642,12a5296f,b2ca036d,c26749c2,57ae7419,e60f19e5) Z8(6b06d98e,07a4f6b5,d54dfb09,5142ac8a,72520443,7d44e042,66b607a6,f105fa4d) },{ Z8(d3a32e12,03e39233,6bce4a98,11ff267e,9c967e11,fff2e53f,abab2958,38d569ac) Z8(4a83e1c7,6671e463,ff59fdc5,f66d95ce,2260c80d,4a1cc8b5,02814849,488aa58c) Z8(03d3b19b,1d460235,fb16e508,9b2b863c,800fbaee,3522e7b7,8d673da3,28996912) Z8(b542635d,975e90d6,621f1aae,019c0a83,68697ecf,18894905,b36d6b12,76701de0) Z8(7119b74c,b4d0c075,f701729e,c970f383,91cdc2a5,4319951c,2671c893,e3ab1c10) Z8(25f56ef6,ea229835,4c6a32f9,9b86a542,bbb373e1,94f1cd2e,fb3b13f6,e03ea787) Z8(a97c82fa,8b61a989,cc3f76cd,e9efcd9f,336ab0ef,6453a53d,e0b061f9,db197653) Z8(d0b5f317,80c52f9d,3cf43af2,45f29fa4,7ffb515e,0dde8883,6937ea4a,00551055) Z8(762d3737,110a5601,bd41231c,18fe8d6a,81b028b8,cf528998,48aa51e9,f46cf699) Z8(da0a7c42,c3b5bac0,52b7e24b,ea09bf14,5557f941,ce0dd26e,a463d263,15e1bec4) Z8(435171ea,7f39f29d,7c289293,69dffff6,f23de214,0fc3f758,adc5482d,307facdf) Z8(f5d44084,abf1cbb7,57bab448,d4bfd11c,3b277f95,817dc230,ba403fc6,4a460f94) Z8(f43e2b0e,30c77951,f7fd94b2,15a3ac92,7273f4e5,b2ee1fcc,f3728e7a,632d0b39) Z8(162b9ad1,62936527,21ba95b8,ae581ff1,e8f63118,eb9a215e,df49c65b,270c9491) Z8(e88c8f25,c2d0a80c,48f77a6b,aeb7bbf3,35be79fa,1097db85,6c22e0cd,f4689347) Z8(2b16dabf,e01eefe2,7f6a8301,55ca0396,7700ea3b,8e61be54,a6f281b5,e49ea260) Z8(13d01836,1d01d8eb,a878b922,c2e6fd73,38e8398a,a220f616,cd613334,bed1ba0c) Z8(240fce6c,3f2e24de,528a6afb,51320ff5,498de5d8,a94675a2,d9084f48,5dc40955) },{ Z8(3fc97fde,1a4ddf02,26b84246,941ec763,ae6aa302,8b1d1295,34d6e5e5,884242cb) Z8(8206badd,bc4dbc2b,5e4c070d,94e4aafa,d5812794,c09d1dfa,4010ff72,ea62b2f6) Z8(38e7153d,69e7c308,4d8a0693,30984219,099a6585,2611bd57,75b2d5ff,1d1511e6) Z8(36a9eb3c,897cfaf7,787d8c00,4f915a21,bb3656fe,79f5300a,d7b9a4da,c9fa2e05) Z8(2750e8ba,1ed11a81,a08eefb6,4783eede,1107aed5,e5cabc08,ccbc7106,626e0147) Z8(feab5658,cddab506,be16d0ee,3b9b4db8,a61235fa,ce419907,53fc4516,418be4cf) Z8(1fa6bd83,a2f2d7b5,40f5f1d2,482a75db,dce2192d,3b449b2f,92cc69ad,0b13412f) Z8(da596fb3,faee3f62,4e875f0e,e320730c,5bef4549,2d21208f,24f49b80,7d012c33) Z8(f9f1093c,2c621e28,12f04d73,7b983ae0,ff79c413,e4f2071c,2a1faf57,23efaa0a) Z8(14642e16,d537db68,32500051,32ca0411,013f4977,4e8217a8,163372b4,bf74f9f3) Z8(612fd4cf,729e2f5e,8a90baa1,24f28913,a4ffadfe,5ba93e59,4323d173,e860eddd) Z8(0f77cace,16a75e7f,8ad3d0f3,e4beec90,4cb3f427,ab881fa0,a4a93551,6e0c28b6) Z8(ebfb7158,2c0dd06c,b9aadbb1,eeb880d3,caa64ef3,fe6b43b9,c6662a05,b2382daa) Z8(0327049d,e342106a,446ba297,646941eb,f1d0bd91,119e238a,cb87c2b1,f63f9b40) Z8(c29b231d,cd3e1ca5,30da7eb8,d9257c44,13d5f22a,599c654d,d885d77c,c0f43656) Z8(dbfc77e0,fb1fc9c7,b7632269,29aeefd2,e7e7d263,82033cb0,3a1d081c,17ec2316) Z8(67a74c0d,6cc0feb6,16a758ba,e1496860,62c52030,7c4dac07,9b7d0d8f,6daf28a8) Z8(be0091e7,17053803,9db604e2,262e3b60,34d3a47e,cd91ddb7,cac89052,ee35bf5c) },{ Z8(c79b22d2,c048221f,c8b7e867,de95c888,c7d35006,dbd670bc,7d729711,f20f4b16) Z8(f3c3f96e,db26476a,536efbd5,16eb519d,4f30c9d0,e7250bcd,c58492bb,2d8a53b4) Z8(1b5d853d,3a82c329,a035071d,a5663ad2,a3a5f6d2,e1a6d3de,c9a2bccc,b08c0ce8) Z8(3b8e161a,bb5e2c14,60977a17,646dadee,7b27ee6c,97bb69d3,f51dfc1e,05b465bb) Z8(31c2607e,2796071b,9ea62f27,e431cef0,15235027,bd803ae6,84676b48,6c2bcaa8) Z8(1967a4d9,8df58f47,206c6637,f9d4e9d7,8d45cc2d,ac615256,d8bc1e75,2826662a) Z8(6b059940,26c5a612,9f570818,60f28a5f,ee2e5eec,51e98125,1afe4386,775771bf) Z8(e6904fa3,0d19dc4f,7cfa1110,d99640b9,61d83a75,daff383d,d6aadde8,660878f4) Z8(50af25ee,d8f51218,1089cb80,fd199db5,4067b52b,94938faa,8cb50d6f,40e05939) Z8(a9f8736d,6bd0da22,5c5b35b3,76f5ca3c,93cd91b8,3f7aa4fa,650dc307,4468c521) Z8(d55c5119,06c6eae5,01b6adf0,53040e97,4b27be9d,a7cb1450,892a6dc8,6b19ab16) Z8(dcadeda3,ea83fce4,e1db5e66,7d937e9d,c5c6e4c0,b53ac651,232de996,1f15800d) Z8(52030864,6e8d2a07,16f71ebc,712be573,5921e41e,26e2fb64,c3430191,60c0e6af) Z8(3637a8af,d2954102,0b56a7ea,9570c4dd,f85de6a5,6d6283f1,46aa15c6,01d2c492) Z8(02f913f6,a0e5b9cb,9c1b24b1,341ce0de,ed1e2b6b,51f38d5d,85118daf,75a74457) Z8(81fc602b,e4f7206c,34b0b0e0,a78a9510,17d11471,9e8d617b,ad836757,31330d23) Z8(4a1d9b4c,fb52518f,e1b96fba,6c52462f,10c921a4,cdf402b9,01b5b58c,37ef17ef) Z8(a8371c46,feb285ca,b0a47956,d7dc5368,0a840a11,31ec197c,d51b1296,6529afa7) },{ Z8(cc9258f4,8333652b,5c5d2440,af5a7f6f,6a0df4f1,763c8e88,985bea95,8d06823f) Z8(a5210761,f9240d57,ffc1907b,f6e265e3,6c5ff90b,79b74a06,62a7f487,34d3af11) Z8(28e6d9db,62c06926,344fd00e,5fe99e8c,b375eb55,6d3129b7,110a1af7,7d01c168) Z8(c20512de,43b8358e,2ec26a13,cdb8172d,9102b6d0,d4e65bd5,cf2b25b7,2a8daec0) Z8(7da0ba82,00f8fa19,cc5ddfec,c56ecde3,491054c1,aaacddf7,22b3f20d,eb52e11d) Z8(0af89b3b,b7092411,6ebbd750,c121bbda,2c6a29f9,4f5a7032,998c5724,bed53c70) Z8(0c978b89,167d23c8,6673a9b7,6c56b148,75553dbf,4b2943ff,006ea26a,df1ccdf3) Z8(899491fa,66c3fa86,cf0fd541,e871b8fd,938e1650,c8b4c595,a2d8f3d7,3be06dfd) Z8(796a73cc,4ba45c75,e9fe04a9,7c850d52,4cc1468e,7b5d0885,53540d85,81647ff9) Z8(75ac9589,5b4a0d70,d341a550,88120d31,3f9845d8,b4f2fbd1,6064b38d,4d878278) Z8(9f6144a2,10fa3bbe,81484ae0,a941a8ef,6c134c8f,cb15edae,c6c083a8,e19b0410) Z8(63d15d94,ce0c0114,146bb6b0,8bb4328f,66c966ca,788ca439,44a82506,f6c89444) Z8(b8d2e8f2,3d61130a,790b18e4,e65eedb4,794c4b6b,5e097b88,069e7e56,ca9a8079) Z8(0bf3c7c1,519065d1,4ec2e6ba,b95470e0,f0e58402,4030c771,b9077591,62880fb1) Z8(3f208770,5556629b,b0e523c5,75bcda01,60ff4935,493989b1,a276ad09,08198845) Z8(e3d61506,bc0d115a,e04c8e9a,e766fade,748157a5,ebdb7aba,ac5a5dca,a0d7d4d2) Z8(b303e4b2,0057d360,dcc1f95d,679525f5,c516131c,05545e05,95a71665,abb4c306) Z8(a14367e1,21558265,a4e8ea4b,15c85230,7916a78f,b9379682,f201fd13,eb29f839) },{ Z8(2627282f,125cbe56,cd0d4c71,0ca740e9,4828f8ad,0e9e1794,856dd47a,af2781f6) Z8(4290f256,fb2fbcf3,3035ee50,0d46ec54,971b3d52,fd0184ec,c6f29e21,e5a982ac) Z8(f3f6e83a,ab689874,88d5c5a6,ad05b36f,6689b8f4,f397ceba,c6de87b2,05967223) Z8(991b5e82,e9c90555,53c2d4e0,8d22f3dc,6d7f5ad9,7d1d59ea,19e2e136,b7326100) Z8(a003eaff,f79181e1,f86ab668,b3692dfa,8a9cd1b6,93ea9813,15d34c04,033b3ec8) Z8(13da73cd,7113977d,f81cb75d,d7ac1ddc,fb16f72e,ccdfb5f7,cced9646,5e5c83d6) Z8(4ff6ce75,a42d4969,ba8abfa2,49958e83,05a17638,74a08640,b9f0f561,666c151d) Z8(074ce687,66fab7b5,615b3167,38a2232e,3bbb479f,bf4223ab,fefeeec1,565ff818) Z8(0fb48e6c,16ed3fdd,44da0cfb,fe299461,dd4f9077,8ff354f1,ab9be386,9ce21b86) Z8(48a0d667,1976864f,7c9b816c,b5895413,bc6e2806,29bdbb41,e279cab6,00a3aa40) Z8(cb244c62,94be494c,c3899fd0,509d1bfd,6f25fe36,04e77de0,9696a3c6,6791c277) Z8(04413599,de93581c,2438c5f8,65502e0b,eebfde4f,5e540019,7410bc80,1166bf31) Z8(0abd6082,539e3626,ff8a9814,047df7d6,e00d0572,14a1b657,7d7a1a81,867b92c3) Z8(a0f8a663,4672bf20,a641a6c2,138d0612,acdd0fe4,6cdf20f1,03fb3c72,93950547) Z8(20ac6c58,e94a68ec,93d4c4e4,7780914f,3e72b948,ef025561,894d7921,0598b6a5) Z8(02566f0e,e85962b9,9487258f,fa179dc4,3f3d2c27,9f614a63,e3873c7d,df8287cd) Z8(9b9e9111,d9916eb1,6ea5fc1a,6f11cfc9,1df095ae,6a510663,4575b527,063a637f) Z8(414348c3,3724f8b4,0887a0b6,7036a0b4,ae6c52ac,dbd34660,c8585a51,6c760c14) },{ Z8(f3a08ccb,5ff91449,9083ec5f,47eda00e,ef464dbf,ef5aaea0,b5b26f42,e54140f3) Z8(9871ce6d,39c4c66a,83ce9ee1,f10a8b8b,1168167a,eae04e7e,76e813fc,6e4858d9) Z8(5a2b38fa,ba3d55df,46574da8,df7ae0c7,a13ae982,b0ce5cc7,5eb02737,e753ba80) Z8(2d8706f2,9e4a1662,8c34fc6c,4970a842,8520bbe2,23634fdb,a8e1ee06,25fbf355) Z8(19c160d0,83d84d8e,8a8e0047,bb5925ec,4749bd11,b1b9f7db,b691a679,8bb97553) Z8(bfa2dbaa,46a97371,1d74eb96,27fd682c,77cdaf8a,7d4bbe46,c22d9c4d,6787ef31) Z8(c2efd7a6,0ca1a317,a6370e05,1e8b07e2,a4b9432f,56a1ebe4,dc8aa320,71d741b4) Z8(770a4d58,a0e1f12b,ee515335,93d4b6c6,59ba05ba,5083f113,831ce522,2a42acd1) Z8(dce777d9,7667862a,7be52361,3872e19e,20fd908a,c348ccb3,a0e9183a,6b0baf37) Z8(42c6f25b,51071f83,0cf8786b,16af5763,6c3aaf6d,654d57aa,59d29bfe,635acc55) Z8(82a086f2,298b0d78,c1801872,6d9fcccb,7d607966,e567d7b3,75b44114,88f16440) Z8(091495ba,e66f397d,8f41ec92,fba2624e,f2666db1,581e4448,205401ef,2e67c31b) Z8(e31c6844,786217b7,148588c4,56a17952,8582ea87,cc64d901,1645572e,3a857f74) Z8(80eac365,e3f4111c,0929829f,b39c5982,8c2372ab,5d85440f,e34ff9f3,f3031551) Z8(4f54d651,99522214,0fae82c4,d89ad287,53f3343f,21061c8f,1f842a07,aeef0e84) Z8(80f81535,fa6a7ee3,1656d6ad,d69325b9,115bcc7a,9e2f1b5c,f7449074,8f1017dc) Z8(9b0f9a6f,7df537d2,5e335ae9,a6c9351e,ad884424,387fc8ac,0ff8d974,b630d6d5) Z8(6fe2b72b,4297e6a7,6455bf06,7f5c132a,419cd005,b6aa11e5,956cfb16,e7e367d2) },{ Z8(12878625,8932f7af,2d6d4d49,65510988,109763fd,f406bea0,f1740121,31fd77b9) Z8(19d33f75,1084af2e,f888e13c,dc47e79a,1dd7e9f3,c704d9e0,27dd6433,edaa7b22) Z8(e30d4081,29c18b32,7335dc8f,d1ac7628,86a67d61,b8647848,e843efd2,bb6ff514) Z8(2d4e913a,d2a6b946,82c9a283,5344ef35,f709ceb6,f3d60fc9,e1724f4a,6f5ee09a) Z8(e5625625,4750b377,6eda66dc,df0dadd3,e707abe9,92af0aa4,dad29e7f,f01b64a7) Z8(3c925432,de01621c,08903c59,c3afcb5e,0de5bebd,4bfe26b3,4a67081f,0d8c451d) Z8(2e89f7c9,56b5a895,5b03c3dd,e00e5ddd,4c492af8,e3b74966,90118d40,be56bc97) Z8(0a76d39e,3e5a8f09,3553c55b,0cec762b,20fb0570,0f48d90c,e6b96c14,9f4dec14) Z8(1732f0dc,78ebc947,20e3fce2,8c94274d,3082bc18,77a5f5a7,3fac3ca8,ee2f8c55) Z8(4d70ac75,f20e38ca,66d13210,a2c5b035,4265ee37,fb0c6b64,2cfec8a9,e8bd82f7) Z8(931f13bd,b00bd2dc,e6cb962a,56ff82a7,6f3f1c85,38c839df,21c4531a,c81e7c40) Z8(ef8dd813,0fe870f7,868b8d37,fb248af0,cd9b8485,402f4545,4239c717,80ce29f8) Z8(3151891d,9bfab360,7c1615b2,bba72a89,827e64a2,0e21e3fa,a0625f5c,b9c707a3) Z8(9526b4d0,86fc190f,a3ba04ab,6156e2a1,d2b673ef,23b6e243,6fa66807,0073ec10) Z8(9d4e66f3,0b4659f2,6786c991,a52d1591,d1969f6b,53affcc9,b632e671,9b95e8d9) Z8(ce2912a5,856758aa,032093d7,40b2a460,ddd9203b,2b8a78d5,f5d4bd0a,d94f306a) Z8(266052ed,f59044e2,efdd5c62,57be7e22,1734b856,6144dfe4,9d537b9e,9fc63ff1) Z8(5ec60aad,a9b1cdb7,9bad0e3a,769bf477,eb3fb021,1baf6928,52947b68,73a74b8f) },{ Z8(3372fbac,1b226e45,f326a37a,570dd744,bb755f89,426017e2,ba4c10f1,fd521ff7) Z8(8f5c8a09,89db79ae,cc9ad947,c7c8620e,1b473940,f471115c,07905ac9,8e0f9ba6) Z8(6169c956,b000e7f0,e49eaa7b,4428322e,132d9fff,2ff24762,cfb1a252,cdb0fe9a) Z8(0d764b2b,25f5fec8,6c04239d,f89ff10c,7e12fcb9,76d36cb1,2901ad2d,21ec6d89) Z8(1e4b4a9a,e4d7ee42,5f2666ef,13a7ebdd,adef0f1d,b8017c2b,c73264dd,afdd5706) Z8(4123ebf5,61edfab2,2479e60e,c7eca630,d5ce3269,0fb0e9e3,871882ab,35f3b704) Z8(6f18eb7c,085bb698,43a8c811,6f2100a8,d0d4c25f,55dfba73,8c659338,f172d8d0) Z8(2885e3bf,8e98102b,be72823c,569152d6,e34879e0,cb7853c2,c4ddec13,5ab239f1) Z8(64c7cf11,664aef6e,3ada0b4e,d3c61c52,4aaaef60,3cbc839f,39021569,d9e73b07) Z8(b5b454ee,751bda20,f5dc0bb5,368805c7,2e1c27e1,f7f58c12,fac1c5ce,3543e455) Z8(9ba9a33a,5716c6d5,2c5fa83d,8fd59d79,6be816c6,6f3513b4,80983ca6,3b86c96d) Z8(6a93b56f,8daeb401,dcde127c,05ca3c7a,171724ca,ebb72ea8,fa2a5d7e,30f11940) Z8(96b72328,1e40fd15,9d3674e0,d13d4ba0,ee9b2f6e,6351f592,e748e8fa,e4112435) Z8(884608a7,3af38be0,435a58bd,2096bfb9,a067fbc9,9846ec94,84a0ec42,315ba6d5) Z8(8c9817a5,7274e03f,4fdf5c9e,48ea6a02,8efc8682,8260a2cb,7edd269e,de95473b) Z8(695bc50f,3ed3cc1a,0958bc6e,d1435bbc,dfa1824c,2854f7bc,4f42e7ae,1fe6f62c) Z8(3a89e3c9,03e56c2e,72b932d9,7553e766,416e19ca,c81f5b04,fa4a2e1a,77966bc4) Z8(1859aef5,01f91443,202bf5ab,a0547011,1228f146,3d1a1590,70d421ab,e462dfc6) },{ Z8(06a098e1,f4644c9b,748a7e3b,26f90701,ece36468,bb37f5f0,a9c95dc9,ad0f4097) Z8(86d80447,ec64203a,a90733e9,d02b2bb0,c95aa227,a5cce01e,4df3584f,2614c684) Z8(62a42625,0fdd162a,7c32a50f,52298403,e341b2a3,f365b353,976a8099,87efa7de) Z8(97691590,a7e74a0c,cb631ac7,754443cc,984af0d1,9b61659a,ecff868b,c3e5ad1a) Z8(a39c3d7d,8264ce53,0f6f9d72,f8002296,2f2867a4,259ae52e,45fe97a2,4bdec755) Z8(52c51597,e8023624,ee05c95c,adee53c0,d78a8b00,970a4c14,a92b4848,3242927f) Z8(00e4541f,6897dd79,b926a6e9,1bb021c2,f187e9f7,4578f8d4,64597cb1,7c9d1c1f) Z8(56d700e7,23c8171f,32bebe77,378b13fd,653f78c5,900b84a4,1dc3ec79,18ed926c) Z8(45c060a8,cb092c05,6d16b08f,0f67d5ba,ca63341a,6aeb188c,524df2c1,11a6fbe7) Z8(56b6161b,fef77a4b,10110bb6,12dd9276,9acc53d3,dadffb27,cec6a4c5,588271ca) Z8(9b0b45c1,541aab94,a8ced993,6cb9acac,a3eb2584,f63b6b68,d1c7cc9e,c6e09748) Z8(a07575ff,91a06ebe,3ce5bb8b,5a5160e3,e945d22e,43bc4157,da2e84f0,1d1d33d1) Z8(48779c25,27d22ce2,ade1936a,915d8a56,50138d33,21865127,e5f6c2fc,8f226abd) Z8(dd1ae876,98cda20d,16d8dde7,ff9384c4,406cebec,7ef9c972,ff8cc6c4,f5eaca2c) Z8(ce510e83,5d18613b,c5fde765,4e8b7f6f,923184df,671c41ea,0548011f,30e54430) Z8(84041175,e45770db,deb5662a,c26e6b0e,a95e5367,731f0bd4,a2f47178,e3c22408) Z8(e88eb7cf,d296299d,0f56236e,0d0467b8,2ebbf6cc,5cfe8e99,3a9cfb75,db35ae8a) Z8(d2a0db47,8b303693,caf13cd5,92f45b4f,f60ded99,d92f0d93,2c17bfa1,7abba1d1) },{ Z8(642953b1,469d3dad,73b9c08e,072f804c,b1796082,e88cbf06,0017379f,e2c71b62) Z8(8bff77d7,a01bc011,9bb50619,cadf4a28,3a4c997b,cfa6acd2,dc575f23,5a942c7a) Z8(45a961b9,9b33286f,b02d2c5c,ffece9c0,eccdb311,096e8dc5,82fc1ad5,02709a39) Z8(14531a29,66d50213,c6b588c0,7c32bc49,eb67d2d5,b3333ed3,3ad89a37,c426c86b) Z8(a15fb942,34019f68,e57af7e9,4fbc88a6,021f5f54,f1812929,a114ebff,f3f45805) Z8(7a2e7615,9d5dd9a3,83e9902d,85437ea0,b1166dd1,12369a22,f0cd3ce8,f4fd87af) Z8(bba8f25a,0c70fcaf,276fff5f,f74ce9ab,65f9eeb4,7ca6a1f0,2a47f759,eec34a26) Z8(9587220e,55c518de,79d56606,1bfafdac,830d5131,bce2cb7d,9d49ca32,cc6f6e8f) Z8(03732189,f487ac50,8041dc28,448debfd,96ce1e3a,8f081dc7,7e4d12e2,5caa664c) Z8(2b221531,6a33bb13,d577c701,98a17ce4,8b86ea74,bf078147,4d87983b,3b992a7f) Z8(56f32197,ddea2bfb,6c3bd9a0,a528c631,e9fa51eb,79f66285,c603e82e,556c4600) Z8(f2197234,a2b86956,c41eede5,851fc9f3,e85c7231,319b42a1,ff91e6d7,dfa02980) Z8(8ee27946,4177a9de,44b5f352,3f2e60d2,6c5650bb,d01b9c69,aa9126ab,921bd2ad) Z8(67701623,0e8861eb,f3c97ea3,d67358c8,8959bab5,d763f1b9,80703ab6,2f346a14) Z8(f7e1b94d,9205c824,f4522f36,cf14daa7,c76d5b8a,496b807d,10e44651,45d97b93) Z8(36ce5c4a,21a13286,d6d24009,c2be73e4,60fc2dc6,b5bbbbd9,bd1729ff,8852aec3) Z8(c53ccdbf,72a25e5b,fa33e62f,005ab15e,8adf28ed,f8007990,e2efe077,01204d8f) Z8(3e8b19e8,d72350af,89f43eab,56566b3a,fafad985,bddd9da2,dbea7ced,e0a94032) },{ Z8(f2633da1,543b7af1,d6e06f7b,37317d9c,11b56d68,ca3d6070,5fc007bc,11a0bf62) Z8(a29ac0c9,80eb11b9,51b7f561,943dd04f,b6ee6ac4,d1da5a32,cccab534,e19a1e4f) Z8(f262685b,e413da3e,5a03fc8f,92341feb,bb9ed428,57b825f4,51abdc72,edab1794) Z8(e2c226fb,00a95da3,9692634c,d32ff5a1,f98416d1,cdbcaebe,8c244990,cb37121a) Z8(7602c56a,e598ad86,e676d740,057a8ef5,7cfdf5d7,f4f6c7c0,020ab6ad,80ca5157) Z8(e4136bab,5de12ad9,c7b99576,db1f9775,3d7bee4d,8a9b484e,9e365e3a,c5941bee) Z8(753f9193,dc881402,6e414e8d,c7acbcc2,57b0d40a,cbd2fa14,64853d82,3b7476ab) Z8(40f678d7,a72cec98,f42662fa,6214a188,34ed20b0,1768cd61,6257bd11,8c35e318) Z8(4a7497bc,122d2f86,1f41764d,730d479c,0533c7a9,7aff187a,abb69ed1,b475dee6) Z8(5a8a97f7,ffddcc5f,0c4c3afc,8df534aa,875c7743,8fe0dad4,1d10fb46,14d1bb30) Z8(9bfe4be9,ec6903ac,9c988670,e253b4da,225a574e,0ff12cbc,8aacc911,6761e975) Z8(919647e7,2b7cb2ce,68ff562c,4f7692fd,2c26b028,ea98df8c,d89e1740,705c556f) Z8(ac0a7dfc,55aa1815,a75b26c8,dd88b31d,889fc448,80cc8161,7b1a0741,b54d530e) Z8(53318060,feff0b03,b50eeb23,2ba15797,160f45c8,d98e4b21,c90d0c2d,71c9004f) Z8(1df69374,d8fabb48,a772774b,1cb51dbe,b21bd707,73efe6c2,27b9338b,cf29ccc2) Z8(488132de,21c8c03b,bc5c4361,9925c116,87d794de,8e889659,5e481778,41a72398) Z8(00295bfb,2528d664,f6997e46,b38e89d6,9e178116,313a4746,ad2b5f44,bb0f7fdf) Z8(d294d25d,074c83b2,ca951a93,74206c32,9fd4d6aa,e650f8d0,34caa5a4,81b149ce) },{ Z8(868291e8,b149a0fc,47bf2bc1,cc5b3f34,33315820,5c4a2c19,4982ad4d,cab704e6) Z8(d6717639,39ac0fdb,46ba7613,67715fad,e8a95917,12e835f9,0887f8c2,bdb07a8d) Z8(5042dace,c659be8f,51fe433c,cbe7fea2,4b66ad2e,dc99ac44,38e5f951,91fc3578) Z8(f4887705,0acf9931,ca119164,bdcd35fe,998cade0,eccd3f6c,017cfa63,d4005b16) Z8(051db187,f7375936,13ba6c21,35c4cbc2,2873043c,923c2ae2,4dba68c1,55a11219) Z8(d86a9eda,71440428,0f9260da,5a5ad4da,db4c0b26,ec7aa414,a1daa78b,66bc04f7) Z8(1e4cfb8a,f2bfc63d,e083b697,35d16ef5,a86d81ed,c9e5f9f3,31f37f92,631960c8) Z8(fbb89cf9,0faace1f,379a6724,b849966b,be27dfb9,8318b67a,6b2a76dc,58615e59) Z8(1a20221e,4606dab8,16533d08,6d8d05dc,6765f54b,04a637c8,2fb70001,4be8d061) Z8(190aaaeb,b0e7f2ae,8db1d8ef,07d05b62,93472932,44a0b369,11745b45,1d7b5444) Z8(82ffd699,522b6174,d1607dc5,eaa77d6c,e1b1e270,162acba5,d5808084,a2c7c043) Z8(20e13e1a,0007ca23,0d74d047,ca2a736c,ffd3e270,8b2a6ba7,48c74248,cc18781c) Z8(c95448fc,3b23b3d3,df21dfcd,f1d2a64f,119fb5ac,3577b166,c9fd4ef7,396207a8) Z8(d45571ce,aee8bc90,73df053e,76a77dc2,571a5482,6746806f,94a7056b,9047d2ca) Z8(70f345c0,6c7ea4f6,dbacd433,d2a49638,ea3e8f4b,fb741592,0375df09,886ed9c0) Z8(2332705c,524c4fd1,a45bd272,31678b03,5f981867,edd70bc8,5670fb75,56f65639) Z8(9be67be1,893b4335,657b211f,1b6b633a,0d0e08c3,0c1fec74,7341e221,56059fcd) Z8(eb7f21e5,522f5407,62843b54,939ecada,b780ce9c,68f31e3e,c4207051,dcb7777a) },{ Z8(86b3dc5a,92f4a0c4,df88730a,ebf5b31a,90ab0817,eea18533,dba6abf2,cedc8d32) Z8(a9ccac7c,88a1605c,f78fb136,c80cdad2,e38a7900,39202e82,f091c780,0a55b4f3) Z8(15a43dfa,874aa3d1,1fe475da,255fe17a,10f7f793,d4dec8b1,ec26582d,1b58c715) Z8(007c42e1,82095a56,43312a50,8bbd14f0,ff0a754d,f30f8455,1130e5ed,aa9565fa) Z8(42e1deab,3874d75d,ae38c8d5,409c8dcd,5c54df95,a2526a79,a1659bf2,f5b6113a) Z8(4172e517,e3cf254f,7327089b,0e7496f5,f2c5e3e6,839e9ce7,67273dae,7ff334d4) Z8(ed507413,0683a4e1,413fbb05,f8957674,de2ea121,36cb54c8,e6046a56,ea223276) Z8(cfdf0bcb,d123057c,b850322b,b747b544,6f271073,4c8b06f9,5988feab,663bb60c) Z8(8416a9d1,6baa1f0e,c52e672c,fb39d1e6,59f39c99,09f018ef,1cbf3fee,9fce3f31) Z8(e744a12f,58187667,2ef124e9,e711448c,c5dcb3bd,e68572e1,b58d0d02,e6f8b288) Z8(2a538117,545e428e,5fbda996,5ccf7ec6,db26bc87,70213918,cf0e01b3,7af2f464) Z8(c7fe55cc,db4c8ac7,66f0fb42,4dab0ca4,49a8f45a,e099650e,e5aa1998,3719ba9f) Z8(002cf89d,3224cf1e,61c17f8d,556ea15d,a7f76f77,f181611a,64c931d0,0e67aaeb) Z8(013a3bf6,d0935eb0,b957f3aa,4b75521f,169fa734,d2f0ea1b,76447569,b2bfc5b2) Z8(10e5db78,25de698c,4c4d5221,dcec6cad,83bed06b,80463648,dc9e5134,3941bfce) Z8(a930e0ba,6c22ce62,5f2db9da,61f9e13b,de51beba,4f044b29,2e5d8410,c0300b90) Z8(6c6f18b2,18079375,fe02182f,9baa1442,d9fd2440,9d924d29,40ffbb9c,2e98511f) Z8(e82459ff,b7daf8ad,cb16637c,00c143a5,30225272,31331013,b4e1dbb2,88868625) },{ Z8(199145d2,4554ae5f,da1c3ded,1e6d7227,b11b34a8,222051aa,df867774,e62d7b6b) Z8(097a0750,e6c15308,9f12a714,9437ca09,28fddea1,286a1350,7f0002a3,2cd2fe3e) Z8(1433a800,8383c878,11c1f4bd,8ba6cc33,38d02d40,277ff01c,db97b7b0,e2ce597d) Z8(76a634d5,c6542b04,db08d831,8219c5ad,983c9548,c380256f,680073f7,1f6e017c) Z8(b86146e6,e482f35d,1e509c81,548bcc26,3f922d0d,508dbf6b,a8a10f5d,56b72717) Z8(bf9f8cda,1bf24835,1e3a4ff6,6e0a2181,9839fc0e,416b7f3b,76385c2d,bbfe75d7) Z8(8ef71662,0fb965a5,90b53c5c,1e45580d,ce418095,f0e34cee,ae5d38c1,ecaa201a) Z8(3c56a4d9,fe9d2bf8,526740f0,eafac849,85cae338,e540f22a,e876f25a,7d33fad8) Z8(2120b92f,453c5601,7be5304b,12d22972,20770012,e6dc0473,f54ac0d9,f91ffe85) Z8(0a7983f6,1edf2732,430f5ecf,73117c05,b68baedd,9fe7ec21,80e89127,952f83f7) Z8(87f08724,3235a3fd,6902b81f,1b845a52,afaea64a,c07cea6a,f83a2083,30f72627) Z8(85e697f8,2f5d95d3,04657951,f4bcc8bb,c35ac00d,ed1a73f8,0cccbc58,24dd6244) Z8(d2c2e9f5,7acd29df,aa698a38,b9943de9,98217007,012b3055,9fa2d471,c8407cb4) Z8(7640da09,b1a679ba,84e556c5,468c8fc9,5f2a0a28,8222f482,07ae30d6,b819a0d2) Z8(4c72ea2d,a8ae5fe5,4089ba0e,2404485d,a0542ac1,604f5d4c,b7fc39dc,40dcdba4) Z8(830afe4e,6bff8d1c,a57de353,a40d66f0,593a47f0,e3156f4c,1efcfd3d,90199701) Z8(54ad6bcd,98e8c786,d911d9cb,20f45700,d4862d5c,d45fa91a,3c87146c,2556da84) Z8(6a7e0fd4,44b13ca2,5d246c57,75eb26f6,0c1a9a53,d561efbc,1526311d,d88e820b) },{ Z8(70915b44,78221239,b4c5bdf6,2b4cd1e4,e64d98ee,496e8ba3,ccc5c3a8,2e75184e) Z8(33ccf672,a3213ed9,2dbf3052,55625d94,8f743223,658aa0b6,f0dfc541,a77b005f) Z8(3adf0dc1,3832bf32,cfde793f,dfbb8627,7bd7391b,570fafa2,8f84a790,1613a215) Z8(cd87e562,3d3f3de1,79149c02,a7e9acdf,0b3b26a0,050297e8,03c34fe5,c607cc02) Z8(00550082,a8c14011,bd9a9921,fcd9762b,ea120581,31a4236f,76ccc3a7,847aa2d2) Z8(3d19ae97,8f8e1db3,54726732,850ae9b9,5d4e3204,60d06320,f1e11bc2,40bd5238) Z8(465caa0a,58a54671,994b3887,f721d800,e3b82376,90f069cd,876b6ee8,138d680b) Z8(aa10c2d9,3ba6afcc,d7609a72,b82390d1,44b5535e,73b12a49,a681085e,a0ca2f84) Z8(b4b06438,55fd156f,70bb968f,2eff8eda,bec75566,163c3237,6227469f,e91a2b16) Z8(6d564fb6,9e2cd17b,d2e0a8ec,f09398f2,9a035b1b,06ee5e44,8b1543f0,55f76a15) Z8(daa49030,102fa89f,565de8bb,89e2de78,ffd3f1bb,ae8b325f,930b85b7,afd5156b) Z8(9dabd83b,1d215579,8615d730,ffdd6e5a,8ec363dc,f2383263,31a8b72b,83a666b4) Z8(e7dc8fda,0b788c55,cf059505,b272e815,192984c1,e9c78c99,744cc3be,4af5e107) Z8(9749a43c,9a2d97e4,64fd5909,acb45d8d,a19a8ba7,ace6c6d4,e2597cad,3d21c246) Z8(23948b74,af904ae2,1ed5f791,e40471d4,3a06823f,c3d44f2a,9cfa402e,7dbbf2b0) Z8(6b7e1b76,d3f8d17c,c8fc793d,7eaafc0d,b6055076,21689cff,e3c4be9d,bf70affd) Z8(f3f0a1bb,b5fcad13,947a01b2,2d9ea398,50da2540,9f895450,9d128af3,5b4b28b2) Z8(c8fce5c7,0a14f7fc,f19a2223,21417d46,d5a3ffd4,a3fa4f41,b2ba6122,8f39a191) },{ Z8(11fde46a,b0ec8483,192fe680,d5fd2e82,21491754,ab14fbaa,0a3b05dd,b271c498) Z8(50319442,a38e7d6a,5d349f95,c81ec3d1,5cbf9d7b,092dcf6b,8fa18f9b,2564f5e9) Z8(821bee27,28a531f6,b377a377,5958e669,b11ec868,40748370,e42047c0,e36ef3e6) Z8(9f733be5,049dca0a,632a8694,b7168e8b,d5c7e62a,80050f84,92ca2d2e,7d0f6dcf) Z8(e77497a0,774dba62,e706ad6b,12590b8c,17e91138,28e37ae6,a9d6b7af,c81ab034) Z8(376cad1f,2354baaa,ca3fb288,3257d015,86565542,8d1a299f,e3bef6c1,e30be40f) Z8(a508c917,eff14bfc,288968bd,1a836311,5e6d01bc,443d3ca5,f27d74a3,cdcd93ec) Z8(20f45db0,c4765296,0ea9ad78,6ddc02ff,c6b943ac,83f14d53,d283c07d,54d931ea) Z8(dc26fe2d,c3679a4e,b2767653,1c429e78,3b26632c,e1bf2f68,f0ba47a1,4e5fe7a6) Z8(ce5d41f0,3d86bd64,042925ca,a7889b0f,b98323cb,06187227,0a4d9fe2,05684711) Z8(a9426152,689b8d46,e99f8dac,4f6a4926,84743135,453a50c0,1d068eb2,b123ef4b) Z8(cbdba753,317753b5,311736ba,413e67b4,1bef794d,5e541db6,89fb228f,86ba041f) Z8(4f7ad377,baf131a7,1cd2c7b8,fdd8ba22,7c0619ec,c7e0e991,f5439383,cf170048) Z8(6eecfc51,dbd659f4,1cf885cd,45f839c9,4f8c7de3,96ff3b9e,c3bb3b89,99a15991) Z8(75aea318,e2a0386c,d0e4c0a5,84e88742,401bc26c,089013be,986bdea4,7608a6ad) Z8(4d0e3661,37b12f3b,e66a4b20,48736ba2,e00b117c,1cd6a41c,1b7960c5,a3ebefd2) Z8(90efd895,d9a725f4,7a5ecf8e,d9708ec1,69ee9a34,85c651f1,bdfe1ac9,18d1fd5b) Z8(241427fc,b68ca0f2,cb1d5fcc,d86f8d34,3c8d9304,f031c2f6,9f0168cd,d42f6a1b) },{ Z8(d881ba4a,32deab9c,6c56b5c9,59fc4f69,37790596,26d9c577,32d48c1d,4e3e7f28) Z8(73da8849,e6b0a703,c707210f,b18a5cfb,6d82893f,63babf47,1ce1c5d7,045a3597) Z8(f61bd745,2d15cf54,2664786c,2a7de8a5,8bdd43c0,077e7a1b,b0f08c3a,bc004bc4) Z8(923fd2ac,f9ae178b,77530553,90555248,eb6742a4,88582037,7fe8d5a9,1ad0d4a0) Z8(138be571,c23ccd95,880861d9,5afaaf7f,6e870f3a,c846b7c5,da488ebd,2696a4f8) Z8(41108363,8fcac41f,83b36342,508311eb,da290ac3,8bed3bc3,d1812b8d,2885260d) Z8(f9075942,a91dcdae,5de197b2,68c7d9a9,eb75f6f5,92b452d9,c55d2a9f,f83ec4aa) Z8(69eff276,76ce34de,5f7b8222,866b3694,9e120b1f,cbad5b5e,5d400d36,202baf4c) Z8(a428d468,f7048c56,986506b8,187a6558,13ac4561,e4672563,b01a2470,d9daf1f7) Z8(dedb8d30,3012b0cc,a3d00fac,d401d488,86107d94,fc44212b,bd3c0aec,979759d1) Z8(468d0447,61d7853c,64f6cd01,51682acf,db9b3961,c823b119,87a1cc7d,73f132f1) Z8(e2e0cd77,192821e2,b15e473b,54c350e4,7efaa243,639da0f8,50dd021c,c8dce081) Z8(1d78644a,4725fdcc,f9b31139,71587719,f21f4e91,718b93ed,a656247d,6c61d702) Z8(0e93f975,f31f5e74,f7f293cd,be4d4c42,0916e6e3,d5cab316,d2089162,e79f616e) Z8(55e113cd,4b51ecb7,3bd666e1,c4ff42ec,bf3cb880,fa371967,0bc3ff50,afdc4761) Z8(9da5bdd8,babe901f,cfa16516,47940b49,3ab9d457,6c585133,f92ebdf0,de759e14) Z8(e5cdc91d,27f8d5f0,c52be852,efd5aff7,05125480,e80594be,8f90401f,f3c2ec26) Z8(445b61eb,f8c232a6,6ebb10f5,5fa61a15,aa09e851,91c49bd2,4210ec0b,95c8ef54) },{ Z8(8a74526f,e740d1ff,281d2a0d,cf505283,b3ab412b,bfb8c163,f7d588d6,21eae431) Z8(3f9268ce,94154b51,bb29b94a,adf839ae,a92d135e,bee4ef55,94ef0839,4245d8ec) Z8(4824046a,3649b306,54c58b4c,5a7216fa,8824c197,f4b89228,9cf285d2,6532332a) Z8(6f7d304c,d35952f7,8b572692,7ab8f80d,876f2de2,ebef0b19,f9d92dc0,075d859b) Z8(6f4bd444,d2f55f03,573c37e7,d0bf12d8,024e833e,1b2f9705,d26c0292,2a779419) Z8(0165c3b7,de03142a,13ff09be,72c0ea63,c4cf0eb0,aa60e05a,9a408ad9,3448a2b6) Z8(98f60b03,51377e73,8d35cd51,b1d29845,f7ed3bef,7f64b3cd,8033b006,83901f06) Z8(bda90349,44e20144,7d89b058,f0689f15,45766f6d,b9324153,422505a3,c2660806) Z8(15de8ce5,59311871,a8319de3,a5a37c84,b682f00d,b97ae596,2abeaa32,c7261416) Z8(df89235f,6d10baaa,51335a18,513ef75e,53137aeb,be22c3fe,fe9165fa,7698d9fc) Z8(ae96338c,736df6bb,6314e7ae,a89ef087,5c9b5868,43175037,ad455325,a12a8360) Z8(007e6aa9,41f4610b,fdb3ad4b,c504da5a,2a5b5779,845a3287,acd4ccc2,59ea0f40) Z8(3970543b,b9efa8d4,03383bcf,361ade79,cbf5fc06,e5276002,14dcb4e9,8dd52ea9) Z8(88a97251,c2b4f1e7,a01d3d37,63e8c503,c6e49c4d,cae8d11e,2030fe80,cb335382) Z8(cbecc5dd,5575cbec,e794655b,6e2ab7df,4305aebd,a3bd6ed7,ba1f97db,f4d23ead) Z8(2a3da43e,f7d4faf7,4cb7a3bb,ed1760de,e2b9f96f,76b26b1d,de103ac8,58df8d78) Z8(228bcc6f,d1537178,3d3e077f,78e48ebc,bab40852,676aac6b,8789424c,db1974b5) Z8(445043dc,870f4200,0179a256,7bcc1ed0,3f308eaf,bfe750dd,897c25c5,cf9b476c) },{ Z8(2fec1d10,29b19213,311c948a,0e9bbfac,1721df97,3a05d7e1,21cf8a68,ac71c15f) Z8(33223616,f4c7d2e1,6a820e1f,f1328338,01403689,14aa32ef,6e802a59,2a1038d3) Z8(dc9a9033,b5846019,eacc2b16,c734a4b8,eb21ff9f,1bcd2fa0,8baefe92,7b4fb2b8) Z8(01659ece,0453281a,4e8cd4d4,4bbe5fd7,686097cc,4ed71e66,f3ba3954,72d80f48) Z8(486c207c,891a9a81,3d20f121,58c3c706,bfc95007,95b3e423,97c1ac7d,4e322d8a) Z8(555a143b,fd057f37,a691f840,903963d1,c87cf1c3,01195760,871d96f6,c4908929) Z8(81f4dccf,44367d05,55e35209,d20a98e3,d20e264d,530fdb1b,52af0d74,03e46cc4) Z8(a0c76b62,1ec49fa2,24b0fd9e,92b6bef6,32bab5e2,40c90cd6,36be955c,3cd3bee6) Z8(f32a62ea,3b0ccb0b,88458608,a74f7006,e3cb3ffb,5b9749c6,071ed0f4,c103307a) Z8(c33e108c,d8fa558a,d8134f8e,5605793f,19277773,2fb0bbb0,3716c5af,46b9083d) Z8(60ca69b6,16c116c7,ead99d44,25f8f4e1,1a7db835,06ac3787,de9c60af,c352a6a1) Z8(269c6394,74f2c81e,8cc56eec,1c2d38a2,5adc0416,e521cb11,d6af3455,e42264bd) Z8(8d2f5dfd,64f57d3a,cd570976,ca581afe,49df832a,853131f4,ca5900eb,ce2126bf) Z8(c560cd29,27a08b2f,2ebd613e,43e705cf,23fb0c02,4355087c,738ab7d7,f0cee866) Z8(b01bc204,01d259ca,42a2899a,6c9969f0,077d654f,de90f3b8,d70ac6ac,bbb92db3) Z8(178fb379,62b3a3d7,ef6c71e6,847d431b,9204a05e,bdb184e6,361d1046,23cba554) Z8(307cd9e6,d6d14ec2,8d9242b0,952e6f6a,24f1dd6b,8f14cad5,d045cab1,648a462b) Z8(bd7b9183,8e62a282,ceb1ac8a,6a547cd7,857991ca,05256c4f,b14156ef,9c32cba2) },{ Z8(03b84ba4,3d5237d2,5ba5697b,d646a88f,9c0ff08c,285955ac,e057593c,0a8774a9) Z8(7d4fefa8,c5036fe0,cfd9da80,3d240b28,33a321a2,a043f8e9,cc2159f0,c3d36f3a) Z8(f419c096,c8c8712f,1a7bceaf,ec349c90,524b58f8,bbe44176,3362a922,584c06f0) Z8(88b5c3e7,d63db159,091c88df,a8980e48,337282d7,b4a0a058,fbf735cb,29be8b0f) Z8(c21efa2f,c07a5caa,4e1bbc07,0eb2e2b6,e8dcb238,940ffd84,e4d6ec7e,f59383e5) Z8(ba6f0de4,eeff8066,3874a148,9626e36b,7f10de8f,240b04a0,3864ba92,7f8a129d) Z8(fb71bdc3,02d3fbde,80f9ca94,7e701be7,9d278a70,3bd4b959,bd5188a1,a66f71fc) Z8(06b7cf6a,63ac889c,6ea88304,62c0cebb,8763be2c,d93107b7,62c59afa,3066bb22) Z8(204a61d6,a3a5efc4,49934b16,d86c6609,972465fc,c2757f71,f79c0b29,e588c915) Z8(e03e1482,6969b9b7,4f64c738,ee35ff7a,2bca682b,0bf5cdd7,48d584e5,9a69bbd1) Z8(cb7de008,5749336d,203ce4a3,f891d728,e590234a,141d89fa,8be36e67,b2e59b37) Z8(2d415c38,908f7722,6f91859f,35d777cb,cbf9adc1,a89a9b1b,1bcb63a1,c1f9dddc) Z8(eb736331,6e455494,abd01265,b6f223d2,c145aca5,696a6d8d,58a9d010,fedf3bf9) Z8(73556876,f00a4dc3,03bc564e,c2b5c693,a0d6a476,b33ee6b3,efa90800,e2d2b13a) Z8(619a2841,12a98b58,39af4242,e72605fe,faf3dbcd,3da7bc62,6fc50a95,8e5ad663) Z8(945d02eb,15c7a822,d8a0e632,ba653704,68736294,c8fed5db,1c5b749c,155fef19) Z8(d1df7c8f,fb375501,21d4b453,b25c3ad9,b0493a9c,0acc4600,787a6268,ca0e0e62) Z8(b3db1448,43d7be83,87a780b2,a773f879,3a66a0e6,204bbc0f,658fe5e8,cad33f00) },{ Z8(8d6d70e3,e1b7f9aa,6d9184ca,8d0832be,9405d6d7,8fb94978,73b05491,38df2d94) Z8(00b8d279,ee14a39e,89b1244f,569956c9,1abbd0e7,f97ede86,b8bf597b,2d190e11) Z8(37044f29,24cc70ab,d0877263,c56fe8d5,46bdca3e,55483dc1,c4c574f8,91327289) Z8(0398e235,fdb10941,48325ebc,acc692c6,e7d6b6ab,79665e7a,52180adb,75a82d01) Z8(216d7d42,21562010,8b8ecf97,792a17c2,d272a21c,8034269d,e4bbc453,096ca489) Z8(3819c31d,4f420c50,3aaa3746,2af2716e,158760df,872038a3,2e1d98fc,193ef418) Z8(cf9c07e0,8a14d35a,e139c061,0522a6cc,758f3119,d45d8ebf,6ca92c66,2216f6e7) Z8(b1e16b7f,6840b21c,3e1087d3,b8f0d3f6,08670457,f0bd9650,423b6b67,62f8e2b5) Z8(8f320c80,23c9209e,6629b88b,c9ae21f6,2e61613d,e36a6cfb,222e7c37,ab8cde4a) Z8(ad7a1947,c5a6d2b4,e384e189,8774f2e8,46f048d9,c1978c6e,f394f878,9c9d8ed3) Z8(63e9be95,462762ee,76983983,d085c22b,02f99be8,b80fc4c7,d4ac8a7e,c503f211) Z8(df0d343d,58c1b818,f0a0409d,8557f2ce,60a3205f,9623e31c,0827bcb0,9cc4a821) Z8(b2bbfee2,40efc916,b29e78e8,52f47075,9364d504,056260c7,a05d11e3,1a84141b) Z8(6df825d0,092efa4e,1e6eee31,cbcd918b,22a317fd,4a51cc83,ab477ae2,9998c8fa) Z8(31f892f2,d478a67c,2ceda66f,7ddeecc9,3042a8fc,6b4c4b1a,5054eeb6,928c5bda) Z8(044f8786,5a23b635,1cc391d3,8f7cb21d,6967127d,b7e285f1,88305cc1,5953d866) Z8(d517276e,b70ff3ad,973634be,ef29ee5f,93f211d4,6ca11f40,914f1901,7bda4332) Z8(4ad66f31,bb0b7cdf,cb1d9eb7,82c66160,5f5405c1,527c32b5,79c35582,a2759c0e) },{ Z8(72aa41c8,9fb203cf,7298571b,58bd4295,52dbfac0,962c0f81,4075fb9a,80fe6803) Z8(48dcd218,49732822,9156640e,22f61d42,c3409dd6,7191d056,bc1bd3f1,e718a5ef) Z8(625ac2ec,e01263b6,59ac32a6,228c0ee2,748cb89c,ed296aab,8786f98f,210f655e) Z8(bab1b39c,c3c6c160,f4ff7481,c95b27ec,3a17d185,49d839c3,be472402,64314abf) Z8(2e35ecc3,3704b188,27be2bc0,54068d4d,e2e60be9,6bc735fa,faa8c0c1,638b4bc4) Z8(e9eadc25,4bc7c705,a0172e0a,62475449,9736efcc,684c0f88,a1a55bb9,1310cafa) Z8(f6bfb3d2,6f2b86dc,2f9b0c1c,dd1f93c4,32e888e4,69c11bdd,2d09c6b0,335685dd) Z8(fb01afad,e171f05f,c89f543c,139d89f7,8f0b8822,21861ef5,c07cda47,f3614101) Z8(3ff70794,702d995d,7d723fb4,0770831b,52749355,b4bdcb43,1cc21619,c7474526) Z8(f9470fc1,18c59c2c,5fa775aa,5466d2b8,4b0daa10,80aa5f60,6269bfb1,d6dffb6c) Z8(576f7700,6ab267d8,e8aaad8c,9bf2299e,953caa46,3e95db5b,e04690cd,e678b61e) Z8(6890f398,93ee0c2b,70ee01ae,cfa1715b,03e22d67,76942d1f,7d69b519,ed39dd27) Z8(4b49b807,bdfd9a4b,b26a67c8,019f2c2a,5e312275,4f413b69,abf7586a,03ae445d) Z8(9fd9c44c,8c232192,9be7611e,e34b07ad,570940e6,592317b3,176a22db,c6678387) Z8(1316bc5c,3936d6e6,a01fd034,174bcc0c,0246b9f0,1eb4a9cb,28aba4bc,fc90b2a3) Z8(1f4707f7,8dd119a9,ddc90133,2376174e,ad789019,1ad326f1,499cf19d,2b7190a6) Z8(d1b06f8b,122b6b60,8dbe2d11,02336e0f,29d5350a,e9896341,5da0dddd,4676a1cc) Z8(16de6ad4,365389b7,f93655d2,4f82ed4c,981e3480,7c07d28e,ee48030c,c5d882d2) },{ Z8(f7584d16,c902f221,79441dfc,1549088a,d62f96c4,c94c04c3,9c706888,aa6dbea4) Z8(219cb083,75184036,62755020,09229c82,241b0570,c88c813c,377a8bdc,076bbfbb) Z8(14b7b42b,093bc633,5396af98,9fd5847c,37cfc00c,72cc073a,e55ccfd8,051263d4) Z8(6656b24e,4f8021a0,f9360152,530c44d9,e5293e7d,3ae9033f,f27dc100,09f9dd34) Z8(042a2a9a,093075fb,6b86357c,4f357641,33e5edf3,e2e12f08,b38904ea,64d23074) Z8(bef69d49,cbd474c6,0a75d7e7,de712688,55b1bcbb,57991c7c,8e01507b,8feef664) Z8(f111e8a3,759dc600,f0620105,f711c6df,7aeed988,de4134e7,364f50ad,6422c14e) Z8(cdfc1ee0,f55865d0,a9c8e599,4c00da19,3092a183,5bd28923,fe14fd9e,f29a4c86) Z8(ea5bcfd6,2dc5e461,66a1e991,d5ef515b,8b293454,c1efadf1,df97088e,d8dc1c89) Z8(10c06d93,9dc38e9f,1ccf9a7f,cbccf897,0cf65b84,8e5f1281,0e78fac1,ead6a85b) Z8(937f349a,b3583913,4e3edd6a,1d41cafa,a4cd41fa,deb460a3,d9ae0ed0,3a008302) Z8(17aa26de,107b36c8,d50e638c,d7589b70,127b6f53,1aa09e34,b936cf34,f4ccd990) Z8(af43e24f,55673787,a3955ab5,562cbf5f,d7052875,99a69d00,6d8b6197,2206e66a) Z8(58eff311,6d2e172f,ab69ef04,acc07956,d0d13a69,9cbb57f0,dae4cb3b,487eb980) Z8(305fe6c9,5cc9110f,d8a26db0,d20dad38,2419c5b8,886c0911,20474b35,26988b3d) Z8(520d3776,e7a8e1a4,731500a7,4679930c,291c2bba,f1eed1c0,efa4a395,e1664007) Z8(215eddce,6525549f,55430115,ff9d7a6e,72ac7226,1a0fe34d,a9975ce8,4214f8cf) Z8(c6f12a2d,c985491e,e735f8bc,20f7e7fb,f9e24399,e2f3c76e,d9a8dd47,a88fcfeb) },{ Z8(eaaa1bc9,de763a75,13c798a6,cfa29156,2ea80de2,20b6f242,a3ec9d9e,7284b3cc) Z8(09f62682,a7fb5284,851df16c,5145bec7,f6d39dbe,0e2e33ca,c741fcff,4e9863db) Z8(4e4f85ee,5fe3ba1f,93b98c3b,a2eb9d63,5ce31e54,004ac3e0,5079a14c,84cf855e) Z8(0104ec51,7cc3e197,7a693862,5f1f55ab,b50deae6,d8264515,a9b8c109,7260179f) Z8(30ab6920,5b4078c6,5f102123,a6967ce1,1fe4927c,b1bc8977,3c5c5720,f03e07b6) Z8(c65cb58c,49f36308,f04b07e5,57f0f36f,af8d3dee,a857c4ae,09f586b7,d8208c2b) Z8(8f0ba46b,5d2a3875,11345820,5deecccf,d65ea79d,2da5ca60,e01416df,1223a4b5) Z8(047859d6,6fc50ced,3eb0fddc,3656a9f2,41650d0c,2b3b3647,17c5cdb7,daa2832a) Z8(839def48,5e075cb8,a91dd93d,97db7162,23eae84b,a5adc77e,ced34a63,940e7c4b) Z8(91582da7,2a909a07,f4cfdae0,b5554ea9,c21d97fe,14e3e2d7,f7e8d1a7,b4a4e017) Z8(92d41587,cabbc49e,c785e823,157b0273,f3e9b93c,8c32e17c,f67e464e,c374cdc9) Z8(4a81efe2,955278e7,64635805,aa0a5d71,346c9bc4,1084f03a,de4eabb0,8f792bed) Z8(dd1b163a,1d92c613,5d57b0c9,73908bae,73c86030,33206ea2,72e6343c,ea4438e5) Z8(5e5b27fd,14eae6c7,d6b05a55,bd0caf33,0522a926,ccbada42,5696dcf0,4a5cd73d) Z8(84f7ff86,0eaa3926,e5d9f74a,7805fa5d,87131de0,9e4384a4,2311ed73,54a416b7) Z8(8c3b7fe8,b3d03a08,5ddb2b2d,53093eec,61521ba8,85079f3c,dae799cc,55fc77f7) Z8(6db6a625,4148ab97,27ed8b40,9e2eb1dd,e2f2afa8,fb6290b1,4361b8cc,9660116b) Z8(7de9aa6d,7a48a6e9,4356fb50,ebcb8bed,b90cb15a,ba37a3ee,8b6ae710,c0ac518c) },{ Z8(8146ef86,1e21b0dc,94c239d9,623028c9,ac786783,be3796c8,440729c5,d45214a1) Z8(1081f102,88d48b28,3fa8beb4,fbed0e70,9950a057,44a6512b,53fd0174,41b9a64d) Z8(c015231a,718bcf5a,6a02369f,d6282f4c,c62db523,34350b99,fad983af,8a0cdc41) Z8(8dc6c5c6,de938b26,28814d70,83f9f67b,ef2657d0,6f0634fd,69e5ce84,c92c78fa) Z8(a4050f2a,96922b50,b6cc64aa,07c3c387,60fce5eb,03bfc115,7248092e,4421b282) Z8(db44a9d6,5101b96a,856a916d,7ce2d831,276a2e3d,9319571f,2cd6b8a8,3f559bc1) Z8(95a29215,22e5433e,5b4a21f3,25fc5a3b,f657f56a,43fc92f8,bf62a7a1,50b6d44f) Z8(47c37a9d,0372faf6,aa6181be,dc7c451d,10acbb5a,4efb18e6,5b572710,da1eed73) Z8(8cda5bde,3eb68632,e9000f08,b03b2b7a,b376b138,2e9915d0,6b13fed7,8e2ac220) Z8(579c696e,758d0bd1,3490dc1c,0dfd46de,82784e52,aff26b40,a42d0fdb,a8b1cde2) Z8(72b4ab24,7589b939,7b6f83b2,a4848d27,73c6f602,d0f83096,72fed717,e49d90a9) Z8(01b29481,802c4c4e,4211755b,28421097,4f3f9b27,afc857ff,1a6997cc,2643b076) Z8(bab6556c,cc49be09,f0d6011b,c5a2b785,346b867c,002920f1,96eead01,c7e4e3ee) Z8(15b65fbe,6ef9c4d4,9459d0ce,635b6f39,0e987bc6,af4964ea,93a037c6,80148dbd) Z8(2aaaa784,5c8f6855,2b7bd8b9,2d7fa7d7,cf257516,2d946de2,4e6beb47,d3042a20) Z8(8b6899b8,cfc6e9e0,e76d4989,ffc3c398,e64d7717,af419799,baa33593,988fd59e) Z8(f5459f68,b53cadf4,06f81956,e7c8e051,27e858ee,ef13e9a8,a6a40f98,0a971a49) Z8(cd044cb1,7533f532,646425fc,476747c2,f140a488,966e1d6a,fc786b2d,ae7fe0b5) },{ Z8(0a4d46f3,053a6f92,63f7193b,c8fc3cf7,ec20c825,ba9b6b4a,83a0e662,c7a8a3bd) Z8(ed9f5064,5c84708c,6141681d,9391c70b,98265a57,7fb2563e,13952c30,155299bc) Z8(2042f165,0abd82d4,527cff24,c3a77dea,8fa224d7,9fcfbbd9,8884e95b,9627d11a) Z8(140fac51,d4a637ab,e7b34121,29959997,77757122,9a05d2bc,4ab5cc04,4988b9cb) Z8(bec6b81d,d0f88e68,6c1fb45a,2d0ffd4a,773ca5d3,aba196ea,f184954a,4223581a) Z8(d53fc8aa,320b2554,7a0b722b,8db9e36d,7f507b2b,7ec19166,14e221c2,f82ac027) Z8(4e1713ac,bc45ba04,2a0e32d8,ad6414c3,53d3e2ce,0c7116cd,3ed8700f,e5b64cd2) Z8(4b76aa52,803182c7,75d8eee1,cb0320a3,3b735c99,638ac7a2,a1576b36,a769f620) Z8(a8ab7d9b,06756c7b,49d48083,3eda1e85,09efccc4,2d84e559,c191c446,f9edb8fc) Z8(8dd703b4,9c537e22,6e64fcce,4819e217,b676a260,b43d6216,4b028e6d,0fa0280c) Z8(434cb844,09e535ab,273f87bf,a1a1bca4,d7adb95b,68075b88,54d5f6a7,47824569) Z8(ce76d5ad,6f306378,0a8c5a46,fcf01054,24783339,b396bfab,416e64cb,5e1cfab8) Z8(d11590c9,ee2a2ac8,4bc91bfc,38b91773,98c4b344,30891746,ff67184b,9a7bb115) Z8(b25f8b0e,582006c5,ce2b0da4,dbe46dd5,01dafb04,6509c104,107c00cf,44f065e5) Z8(e25903ed,560d0916,21f76bb4,ea5c6808,c92bd72c,b7c6323b,610fc749,c98b64d0) Z8(1587b4ff,61fb608e,4a1b4868,ebc25092,75e04249,420d95f0,37c8d3ad,03bbc7be) Z8(8c9582b2,94980cc7,5304c25d,1fa13c55,d8e7df66,cc891f2d,d069f9b5,106dbe6f) Z8(e35575c3,e4aee845,0e7e44e6,e0bfb8f2,b9d993b4,c151839c,a908f73e,bb4ff632) },{ Z8(fced3a0f,73677216,f37a50a9,e6695f15,4624fae8,5b5dbe47,1fcb5803,1b618f2a) Z8(44748b8b,4e422175,d610c7f3,481937c8,aa2fc15e,f2a754f7,b335eb6d,94d0bcec) Z8(42853eec,96281e02,bc1a8adb,0e126ae4,7b45363c,86241398,6cfd0947,bb064960) Z8(e8cb845a,ba927717,cdc91aab,450bdfe9,ca254e12,24fb7ebb,2f51dd96,a527b371) Z8(d6e80d1c,e4c150e9,56e6c8be,0634ba41,9a21e798,6412cdd2,8c11784f,20a647f6) Z8(765396ef,7fa6f231,35121b53,81df0464,1db74c5e,aaeafceb,d39812d8,68e4b744) Z8(863ffe20,8ec917ea,c7b8096e,d5ab3930,8ae89c08,2e60d986,de336329,1f59adef) Z8(ee0d65b5,0fe00c04,209acbe8,7ca1179d,9a922749,c5850c77,242a80f8,2915180c) Z8(a632ebeb,110bfc7b,9b7b9e2c,f5b6c47b,44286c2b,5bdc8b25,506931c5,a28824d3) Z8(bb9dc8d0,2c67480c,c36e94e8,1cc3f53c,54e523b4,8c3d033b,cbde12b8,65c9087a) Z8(bf65b70b,cf607731,5b4059ae,56e00b0c,fd3d2993,797cc00a,8663963d,f4b6d78e) Z8(afcb1316,b5d50883,2dd1f440,28e01507,caacaefd,84afec08,d3d9266e,f9a4e2ab) Z8(3cee5f18,107f795d,cd38e678,6a0006a8,a79954b1,86693808,d42f67d3,c50addf2) Z8(7c54858d,e006a1b0,c4ac0e7a,af271db5,40213653,e7bd897e,e5a3d995,c2cc42b9) Z8(140314d0,2ba9e707,6186e48b,619e024e,caabb84e,c1557feb,e302502a,12d40ff5) Z8(a45c539a,86433a5b,fcbe505b,560cc7ca,abad4678,2824f2d8,089039d5,7373ca7c) Z8(efb95d69,6f114a27,eb08228f,b5536120,2b4ae134,539ad8d9,5b30f6ab,111ddc38) Z8(2aeb4aae,d103207e,b2b133f7,11f0433e,434a59d1,05913765,9a597529,b4445270) },{ Z8(55c52d9b,2079293f,266bccbd,995de7ad,49ccdbfa,1a909571,c7c27258,2b7c55b6) Z8(68e6e000,35cefd5f,42673e65,b37174b6,61fc186f,2073140c,86ebc13a,cf9ec9b2) Z8(2a242841,eded5651,78cdb97e,cb2c4a14,1f58f98a,51bb3bff,3e06b766,f63baa4b) Z8(b5a04397,c1db6437,ef4463c5,a9cea0cc,90aeac4f,2c49133b,aa41a566,e6666420) Z8(0c993034,8c6fe4b8,2949592e,133ffd5c,5e9d1767,9b370b6b,a895ff88,00bf9512) Z8(a43d36be,ef0954d7,4b9cc316,ce3dded0,dd05e790,6830b134,1c3264af,e45f8e45) Z8(61c06257,894d833b,7efd7967,503148da,cbe786b7,6f2204af,479fa7bd,325294e6) Z8(c847cf24,952d8577,8caf3a8b,6087ef81,589b3077,af032009,a2563029,31570933) Z8(fc2c2331,836a09de,4286198a,c91079f4,8b48ca43,45f05078,9c669b00,be0cabb9) Z8(339ea3d5,f44277fa,2c58e1b2,cc7db996,4f763bb5,aeff479b,e05d6d65,737d3847) Z8(08907b9b,488bed29,7607d91d,0a66b840,48718e94,9c642786,94d49441,de7f33e1) Z8(602dd604,f66a5a2e,fcc461b2,644f3463,32ade9d7,ca4983dd,6d4b1494,07f139b9) Z8(6901d476,0b073c68,643749df,a4c5b89e,db6a49c3,c5a04680,799585f9,fba170a5) Z8(ff58729e,a7a24cc2,4f2af059,4281c9bc,a9f6f666,d22d4e06,87314c18,9b2269e1) Z8(c8dcd584,0eadb51a,90ee9223,bc139a86,366cea4a,01f4e5c0,ad20f6e4,ab016631) Z8(b1571fa9,023600ee,6f3cc5b1,9e0793d8,05f49514,49244449,e7dc3024,dbe3c930) Z8(72c91199,73399f6c,2c4ab755,4da5f5b0,4e622c2f,62ec3d35,3e185eac,81bddfc3) Z8(6d6b90e8,9d9c53ee,e74fe751,3e73b6e5,4b1a498d,ac786ccf,f7dae915,b5c4c7d4) }}; const mp_limb_t arb_sin_cos_tab22[2 * ARB_SIN_COS_TAB22_NUM][ARB_SIN_COS_TAB2_LIMBS] = {{ Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) },{ Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) Z8(ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff) },{ Z8(370d0dbb,d133d2af,293f7660,41e6d1e0,3fd9988f,ef7a65da,bb5ab0cc,58f10d37) Z8(196aca8b,c62227a0,9b63185b,00a7cd98,19c8d7f0,35b3b678,8ebe6c24,fddcaaf9) Z8(87ed9056,cadfcac7,27b89df2,5ee474a5,e23fef08,cc39d58f,9afef193,715ca371) Z8(a6ea982c,ab6c35bb,1dc09422,50e88862,60d5c943,a70a47fc,c40034c0,e9e27117) Z8(ecd40cd3,f4fc351e,e054beea,0b4e7847,cef43bb3,b0a54a59,b02e604f,b3ddbc1f) Z8(204ce260,9efaadc1,25ddcf5e,b0836434,fc104e98,cdb73d54,06ead7d6,9cd83f53) Z8(eb156721,6abde0e6,06a4e3d6,43b5daae,441d8598,1dad0bb4,3791885a,ef90f16c) Z8(7bc256b8,deb9ac6d,b865b6dc,1939d5ca,c82a5a16,71fa50f1,4ad21c2a,bba8b41c) Z8(4cc06a44,2dff89d8,1578d90e,cd0833ea,efd9e91f,99a92841,2465bb99,7fc15d08) Z8(bb14e72f,f8b556db,b768057c,6eb27835,6552d95e,efe9a77e,42629efe,24d4c293) Z8(df89adfd,1726b1d9,e26ac62d,f7064fa9,0351da06,a820f727,a38b2408,b2c53a09) Z8(c9db9024,1e42f4bc,b723cf34,2e734481,d6f1e198,c97f9d1c,d9a5784b,9f51a9b2) Z8(9b578483,2153ad4a,47c08884,bf3cfdcf,1f397f2d,d0167a11,6b9c78ba,5065084e) Z8(cf8445f1,e90dd1ff,b3442520,8a5a4eab,a172dfa3,970d3618,352d2816,282cf9df) Z8(30e3d8c6,40af04b0,80fd8a20,9df6ec49,05453097,2b56558d,545de355,95609223) Z8(0018c1d0,4195be37,94e6d7e8,b9fb06bc,56cc89b6,1980f945,a033e3c8,cc347db6) Z8(78f33770,541a5b9b,cf786c4c,5fc14621,6abe2f10,90736720,4c533f8a,247a7949) Z8(8b0b60ae,da38f350,4f4348a9,7ad79ced,9db5698f,dddda9da,555555dd,003fffff) },{ Z8(7e01d160,8c2baa1b,ea2e971a,924d8012,b0fd9af6,24a61dc5,2e93fae5,91b6e434) Z8(7174e535,a9a51a76,d7a55dba,d8753355,00c2a6b8,482cef0c,5c4f508f,94e15efa) Z8(4e8d03d6,adb5ddf9,7839b1da,d1d52495,924e52bc,bda48b7b,a1fd8e80,0605265d) Z8(6dcdfd10,796eee9f,30a2c491,0b7a2616,4a01e13a,856b8b77,ca5c61e5,77fe5ce1) Z8(333a7443,569753bc,f16b29f9,0bafb325,a7516313,302b0d10,88aaf76d,f1a74f0a) Z8(7501a20f,c477cb51,b3f36f5b,553198fe,d4077777,53e1fdc0,9d98742d,74b2598f) Z8(0b017caf,3bb28410,e23e29d0,a75eac1f,68d0f715,9aab33cc,8f6af827,b3830188) Z8(1a283d2a,8fc68f6f,5c5c9daa,476c9e26,80ea38ed,0e2e52dc,1d5709b4,a3307a04) Z8(0ccebd55,e5fd575a,eb2af906,e60c3325,e1261516,6ff9d168,48e43c7a,218b8cec) Z8(8bad869e,773d8e88,c4784a1f,fbebbc6f,805b8591,46c9383f,2e79b290,56981513) Z8(1f880e0b,3cef1bf7,ffd45881,1bad0c36,00cc2276,fb9adbfe,44e18d5c,846c8dde) Z8(d4671611,6ae5cad4,f22ac6e9,25a110e7,8c15b58a,66a64e77,8ae8c517,863026ad) Z8(12d2fe3d,ef0538a1,e85366a4,c13496f5,5f38c369,46f2416e,eee8efa8,3b1f4639) Z8(61a00174,4cf4d454,731cf33c,19e4151c,12a5ba52,62b5c14c,8652ce6e,613ca3d0) Z8(b7a89315,cf78da75,672013cd,04bb6006,d6014f31,774dc4a4,cc1858c5,01b31089) Z8(f556eba4,6f881f68,5bebf492,2cdff950,6e353b24,52e5d955,5aacf241,f3683b91) Z8(a43b3321,786d5656,2638f6f6,ce32b63d,f29d77c3,3ce4ca6b,f1606a99,249478c7) Z8(218ac62a,3b56be83,959fd08b,7067c57e,9a69a650,a4fa4fa6,000aaaaa,fffff800) },{ Z8(b8403cf9,59492746,a3fc925c,98a2d108,3393d104,33ca9ea1,3916d291,cd7592dc) Z8(15400b44,8127c82d,d604db6e,f31de919,3c6010a3,c4606cf3,f2b4905b,b2fcd8cc) Z8(94b2efa1,7db51491,b6c05e21,e08ff0a9,f87a4dd8,630d587d,99a06095,e5d92ab6) Z8(0eb7f022,bb701754,cbe96eb6,742b8337,2665e2e3,ff8bfbca,4934ffef,1b5864ea) Z8(dc40e984,6655281b,05ab8352,26fc716b,ea584194,02b24b4d,79ededd2,d2755fb7) Z8(64b8eb7c,5ac77d2d,6f4dba8d,bb544f07,df4ddce3,e0790fcd,af2a7725,0bca5906) Z8(d981e911,7751548b,bdd32701,a29a875f,56b97f40,97b53a5b,24a2b0c1,f86588bb) Z8(dff807ea,1e001421,b49d2d0a,21591d79,1916dd50,c039759d,26ae3c9a,6d3ea427) Z8(eea05437,0f6b6e06,8a82e4e5,8c2943f5,7211aa7b,f9a61a45,acb9dcc8,b3bba369) Z8(069ad198,47410694,d710a819,691381b4,10f0da94,728411a2,7572776f,d37da6b7) Z8(73f7abc7,4cd10511,162118c7,5f6643e6,fca179a4,180aa255,dda681f2,11ce00ae) Z8(7267e588,01d01117,419899ee,dddeda31,cbb86aab,b923bc22,e2926b11,1e9ca5cf) Z8(8a442cb7,a1fdd976,18cae98f,06e7098a,37e76e75,89f23f0a,5876010c,ddc0259c) Z8(a86094cd,8c547a5e,d68056b8,a75f5c4e,8c5870b4,1daed039,096d40c7,2fd1f89c) Z8(073559bc,06427156,b6429d2a,41051985,b7126c57,691a4111,bfa3bb13,0477f492) Z8(e2fc83b4,a3856fee,c7f8f950,b4e1dc3d,cf5cabbd,73a2004d,cc5f04ee,8c603843) Z8(d586e1e8,36f73cf2,8ce764d3,bed5a942,e5a1f7a0,7a2b9bfc,76ad2efb,f813d949) Z8(8f5d3f78,521a69e0,b574f652,9dc026d3,b8d7ff39,bba1ba1b,aaaabbbb,007ffffa) },{ Z8(7748a6f3,54ae9cd1,9fc02d0e,5b252e65,43ad733c,4d3e1ec2,f0f1df98,aea5a2fe) Z8(f90eea6a,87ab92c7,06143123,cb33e447,ccc229d3,1af3afe2,3a762420,0bf6e2c1) Z8(e6326408,4f51875f,7b99bde3,43f7486e,e4d1b2d9,90e2855f,5e9469c5,fbd9eb10) Z8(825372db,66cc8790,8f50d40a,8fb44d25,898db129,7d2d8bf5,40f4b5a0,0c24e8a7) Z8(c32580ed,9dbea8d0,99057e43,af54a33a,8a049ad7,76ab19b5,a2439c63,f0b2f899) Z8(468cbe03,35af469e,41f8335c,8c164cfd,00e95f73,d3072c9e,b22f8a37,a2b745be) Z8(87846e40,10a79463,f9e4190d,02d196d3,feb3c960,847d82e5,c5019dc2,8d43e048) Z8(78de10ad,dc83fd38,43ec9c28,30170e16,0c539e65,dd793965,985d2375,0f58b6f0) Z8(f07c121c,1dd341d3,8baaf5a7,464bc351,7a4cdf97,9cba4e88,38d19f47,95c5b900) Z8(1a06bf4c,bad2a45e,35bde4ac,8e6941ca,c5499d8a,d47b0227,194d6579,39b6ea2c) Z8(9ba75f17,b2c0fa1b,17cb6891,e21f76a7,9c4d65d8,f8a427e4,9ba94020,93ebb975) Z8(17e2d921,41f6a291,75855735,5f172c57,27d4d614,42a0971b,0297fb8e,5b315551) Z8(d2862c2d,24e4c0a8,e575e389,2690ec07,95cb4f57,c6a3576f,ce6a51f0,d384c264) Z8(fab24def,7c4a7aa9,e9d3529b,de91c0ca,24e75625,5659d422,34f2001c,808b6d93) Z8(0d73c947,72ab9e48,83c0e9f3,de7b2ee4,aa7a61ec,4df3d374,e62428c0,a03795f4) Z8(f5c8525d,0f8e5a53,c1ace188,2a7633ee,474bbe68,d1e9e3a4,d9c9454a,dc506239) Z8(267301f4,58e7d5bc,64f6761b,420f2eec,4d7a6842,69678391,5c7fd885,72c23b20) Z8(f3ed34bc,77280380,64d2d641,eff69abc,ade9b6c8,3e93eade,00aaaaa9,ffffe000) },{ Z8(e8bc7449,34367665,ebda10af,96191907,9875c971,ef2a7d2b,351acf73,b6fd5957) Z8(19b803b8,4e9a9870,a20f171e,1169a751,9b1e71fe,d0d3bef0,6f13c4bc,89eea4c7) Z8(15642ea5,3006b1ba,b6208140,9a9ded53,f7707705,8a0239e3,274b1eca,144c5e4d) Z8(b9e7a938,dc62d5f6,1a2bd09e,d921ecd8,6aae1e27,8395b24c,702556f3,0c6ab967) Z8(02f78234,2a4ee510,ba43a9e9,87f35503,ff74887b,f9b47659,970b9c49,13934c77) Z8(5da154f0,f77cf547,fd728bc4,f17fb420,7e0d8454,9742d987,dee7e723,589a9502) Z8(daf3747e,f6baf4df,a22ff49c,2d18a868,c47ba0a3,0f8161c9,1cc1c763,28ddaf72) Z8(be93ec20,affb8983,e36c6d3f,432edef6,25b8e98f,94fae5af,b4762b7f,a1d9056c) Z8(0bce268f,3c3f55b5,bf638fb8,0bc79005,d24de3b6,bff33254,3f35ae1c,054132a9) Z8(e7c28112,f26a27b7,8bad5c45,6301bbfb,31300d05,be99abb8,cb844e6b,69cd2eb4) Z8(4c1f8ec4,48a6a8b1,a01c89a0,1c0596c4,78fabea0,fb1896f2,77fbe917,c28b4d79) Z8(da4deae0,f7a3a396,a9b6b7bb,f2120c7a,5210f19b,01f8fd5b,15350496,07a9cab5) Z8(56c219fc,0dffd9b3,5fdfe98a,9e9b1194,5e0fc10b,0d322877,f8792962,a5a8eeb8) Z8(5da52fa7,30192382,ece5fd02,203e7e65,d81a02e2,552ce3f8,2f50f2a9,5e80751c) Z8(d50126c7,063b8f01,3877db14,2b55b49d,f527a81c,7aae9902,acedf552,345f51e6) Z8(bae60ae9,af5c5c27,575d6bcd,3da8b2df,f66d310e,bf076ad4,9e1a0ee2,4264bfde) Z8(7506a5b5,3d438ab1,df9414bc,a27ac426,a558d4b5,b0522a7f,7edffaf3,86ef829a) Z8(4620ec5e,013de67f,54a8e0b4,92916d53,95f15a8a,97dd41d7,00008199,00bfffee) },{ Z8(0bc5789c,5a1c70a6,66ba25d1,904daae1,7f1af3a2,a6824c94,d2afc156,8ae0cd0f) Z8(aac25b86,99086514,251ff782,2b7e1c57,61c49cbe,4d221c93,b4e6654f,a38b68f0) Z8(40b0c40c,0c05714a,798d9ec9,da087e15,5fcb9076,36a6399c,83bab7ee,ef5a4a32) Z8(957473d8,9cd0c502,11b47c1c,6d9e130d,fdeacee1,49fd9107,930f3f9b,e88bbafb) Z8(a2b24e3b,35070a52,fe03b7f8,512ce54e,fee4e660,b857f05e,c5af1154,7ab958a5) Z8(f0b49864,10c2212c,1eb1d1bf,2edb32af,6c8e5eaf,d1cf2704,ac24b38c,3e36f38f) Z8(c1d7d826,a605af57,0923d3c2,4a63c25b,ac10735a,9cb1f4a7,d2367645,af9e81b5) Z8(7b7f9131,8f8c5083,1f384078,089fd245,5ee98bc7,7b7dacf9,d86f676e,7430ce5c) Z8(9e1b171a,4d87ad0c,f98c307d,f39ca5bc,646585f5,d5b62884,6878dc7e,0f2eaf89) Z8(631c8edf,87aba042,478d2633,42d2642d,fd54fce8,30bbe038,c3002e8d,80c390d7) Z8(678caf32,8c22e158,87780ba5,50220857,fcd87257,ccc4fd92,fda08a8a,8a2fb609) Z8(fe89755f,793938b1,040907bc,6e9c30fd,807d1412,3921c98c,afe37b21,c7025973) Z8(f27cea7b,8eeebaae,e07c2630,22bdfd0a,e883bb00,be0b324d,15065158,b5e54cc1) Z8(1669f01f,8a845674,16acdf97,d9876386,ee1948e4,9df1e68e,7d282342,92296d85) Z8(98b8bc07,1a7f19da,1f0a145b,0826e888,393468c0,09a6b316,70725193,c90eb4c9) Z8(99167b4c,c3e0d245,4b4df671,c1672008,b8175879,641b799a,6617b259,9d5dacda) Z8(b90824eb,0648d5e1,1c9a4ac9,58d7f79b,fd106c29,143f347b,667c4285,95152607) Z8(28d7483f,d9065bf8,8852eb83,9350fcfb,070dce43,ccccf675,035fffef,ffffb800) },{ Z8(d379d4f2,7d6ee2c3,60eba55f,3104dc97,a6f4f97d,b0479229,f4891e01,10afb56c) Z8(e84d11a6,e698b668,535042c2,d18db85f,e76557d2,9e3decb0,d507eae3,a9b06d81) Z8(fe4dbafb,18e4f25e,c9043d08,b08e918f,1874524b,fec3ff9b,743213b5,c0795288) Z8(d4edf2c6,29d573da,ec07d2a3,74503f45,f04e93cd,08ef672b,8afa93ef,469593df) Z8(1a3242b4,0caf6168,8993eb7a,afcfca79,cc207ad4,a0a623ee,66a718b5,0ac873c2) Z8(fc6d7172,f114bc29,c8fd84d2,129bdae2,84ecb14d,3c18b93f,a5847540,a92ae8b0) Z8(0ecc4391,33182948,aaab5a3d,e5a0f29c,4eeb0521,97cd2992,b5e4222c,01ce4397) Z8(f9fd5e02,84f2ab17,53a1d200,cd925400,ef81a2e7,665a1e61,0e944094,542b913b) Z8(ee90787f,e374acb7,556c4c8a,f5ff29a2,8cfb22c9,f93e7f02,c785ea9f,af0f6021) Z8(aa213678,d149325d,4bb225ee,fdfaedfa,80b09588,61b10d62,68a060a6,b16acee6) Z8(1523d2dd,9cfd9c2e,4e270948,bdf6a68b,6c64d15b,7a8f75fc,4ff8d59a,d16bb654) Z8(c339250a,e691ec0b,5b926a68,1836f3d6,502a3b12,7db020ca,87eac12f,ef1454a9) Z8(4f3b93f3,83d3f535,3a5a9abb,ef63b1e5,8156ab65,f02388cc,b6391642,d5024d2b) Z8(4357dd3a,c2726045,d4605fca,2482a424,6ae33f28,077c1143,b760a707,a48f16f6) Z8(aa4c4ff1,e6db3644,9a0d2450,8f3c8c64,4e330b9f,af5db8d3,f58638a7,70153c77) Z8(48927f69,4f111940,c1e8c4db,c18685a6,6f763f7b,49147aaf,887096d1,d2500397) Z8(c584231f,42c62544,77e886cc,aa20f9f8,fe4f25a3,210a5354,2c1d4109,1721956d) Z8(e9e36b4d,c4405259,25cbf0c7,20e25319,b26e498b,6a76a798,55577777,00ffffd5) },{ Z8(a525ce04,08dbedaf,7b19cb49,027b64f5,4ad6470e,10ad730e,10b1460b,3d79d8db) Z8(1ca3ded9,a32ab1b9,c1dd7af0,7c0095db,26957436,ad400174,3993ca07,9ac315c1) Z8(5d2ffde4,2c145796,adfec139,257e5769,2a1452ab,fbc877d5,4e6f985c,ecb350a1) Z8(a7753d8a,ba6004d1,41674415,d71a4d69,d2c7f624,39dcd12c,4cf5d32c,04e1c1a3) Z8(48e3bc31,365bf995,d92713a1,4d7a66cd,91c76350,d64d9c8c,e973a90b,cee0a81c) Z8(13f93c89,2806c058,753bf848,6ccd274b,f70d0f09,bfedeb00,1a5378ea,eee68cb5) Z8(263ab744,7df65926,92d4a774,d9962b8d,15252e81,bc703b0b,ccd8e799,0aba5c47) Z8(94bfd8c6,0fa99596,5eaaa6b5,89a98e5e,6363198d,c002e988,e324ca13,692cc3b0) Z8(0a7cac0d,2cf9d0ef,094500fe,5bf12978,89e1df2e,e34dcc45,548f6fe0,7b88ab57) Z8(8f03fa21,ff0ea778,8e1a7a90,e4a64d8c,e3aabc5d,bc1d47be,030649c1,de657ea2) Z8(80dee586,aa08cde3,61a16429,73dc8ff2,dba31915,17399dac,05a4633d,fcf0f5f3) Z8(645210a5,fe1b3491,e288cb86,1e199dff,1703d6bc,d7b5e9b4,c72e2804,8ff223d9) Z8(4940c14e,4b120363,2c59e6fd,5ed9e3c9,ea43d14b,5cff4bb0,bec28fa3,2847c865) Z8(66c24fa3,1937fad9,dd598e21,a658dce7,ed1a3db3,51a46b37,04442ac8,31f21f14) Z8(e6dfd030,a84d9527,85115961,5019c176,56e78761,72754e44,df033d10,5ac98331) Z8(d22d7675,241959a7,1fed516a,a7b6873c,11eaa8f7,31b8f827,4707f5a9,8e868251) Z8(0370b3ba,94cd273e,2b207969,23a42900,14c6dcb3,23a6dbba,dbd88646,159e76d5) Z8(c276c47f,596a5b46,b54082cd,09039032,f7502b17,a4fbefbe,0aaaaa4f,ffff8000) },{ Z8(f64071c4,f0a0c43c,d8a3095b,9ffc87e1,bfe3df20,4417fa07,ac8808f9,e4d1fd9b) Z8(43f01855,a00623ad,a4ce1a71,1ab486a2,5b0ebd1a,7ea12350,295d43c4,771cbdcd) Z8(4333ecd9,efdb8e71,d2a845c6,c80c9596,c4991018,48272b2d,be84ec65,d3ba08c7) Z8(5b80474b,00f9b332,fc114590,57cf0c0b,565416d7,f56df51c,358908c2,5ad18019) Z8(3108fbf8,e17631e1,f8abc148,1264a17f,cc928e94,a5239eb3,a88b6ef7,77f985c9) Z8(5d3cf27e,2bcaa535,f72ea91d,7a8d0e72,ba5e5977,8a5c3e3a,1c6f633c,6ee1bc11) Z8(332bd0af,a9c32ff9,08779cb3,19e4f65e,c2055e35,32247c0c,ee48cc95,3495a769) Z8(42948453,8c3f00e1,b162e1aa,e6ffa22d,a493655b,4c5620bc,1d191482,2a745fc0) Z8(a3f307a2,5a217707,a455a30b,34467846,f6ed0578,78df6580,14c861ef,66ed4972) Z8(9a50fc37,6d259d96,1414a7d0,07dff49f,3688afca,59f7b75f,c27d13ff,bf33c617) Z8(d5c6b032,dd708040,cd5eb750,3d358269,aef58500,821ede04,3924addc,e065564c) Z8(21cdc163,0d91ca74,7480c427,bb7ee402,93f534fc,df176a22,a3364e56,a78bae88) Z8(c8706c49,34f62b6d,558c65d0,fc19409a,5fba740d,60bc4391,d3bf9b34,46acc67a) Z8(77599852,f1660552,a273074f,a8fcb86e,dd2c0419,1348ef81,1df1c641,c9e68942) Z8(a7bbab4e,4394e6cb,acf22844,2a49a570,8e71a356,c5c5284f,ba946252,766cdf17) Z8(432fab46,3e36b556,ea4f7b31,de770bda,faeb8d38,8b26bf0e,d32b99c5,859a93b7) Z8(125a511a,5842cdd4,50c08d09,1fd44cdb,017988cc,b926bc56,39546916,d7b8adad) Z8(dee84423,fa9c2180,43d419ca,05db1128,8bb848ff,1754529d,aab12d55,013fffac) },{ Z8(5756052c,75a3f2f2,26d4f03a,dfca728f,7e0c17cf,22dfd54e,b1c170bb,9324e2c2) Z8(ffdb2be0,aa956b62,d756ec1b,45e55af1,ec668e71,d6dbffd6,a97aaa18,d11d3b48) Z8(ab246587,b3a6400b,a64f8e5e,b24b71ec,2c647631,fb24b0ea,b58b0970,907b95f7) Z8(a02f6bdd,62cc6e4d,67442729,ab05b82c,a12b5926,8de23522,3ff28ebf,4caf74d1) Z8(025104d2,52b553e2,971d4a4f,8463c8f9,6a7db9fd,a8af0cfb,355cd7a4,affab816) Z8(d448d550,d7420d29,df96cc07,cd1d98e9,157929b3,59f4f52a,94ae4867,4d52fc2f) Z8(02474219,dd9cc9fe,27622275,18b3e5cc,503aa5c6,7f6a45a0,e043e5d0,bc4b32bd) Z8(75286a9e,3d0b6151,ff5a06ca,eb4d3db7,6729550d,cdb3b3f8,9e01bb4b,a5a4292e) Z8(08524ea8,d1f82d12,e9ca6fd5,cba4f300,f0504cd6,7be01ae5,2be5ea02,f26347c9) Z8(01af1d0a,e36df157,148f45f0,565cff03,949abe11,d2fe8eee,ff6c2f03,a02e5802) Z8(77070c88,815ea76b,b0ea7723,6ec1d85e,6c79640c,80516311,fac74fb6,294f4bc3) Z8(6820174f,284193c8,5b6525ca,30c5af0c,aa5ac6bd,aedfdb8b,a4137c2e,472e8f75) Z8(685b8470,b3276149,6345a780,e433d122,ca601df9,c547e2e4,3e140632,7d1bdab6) Z8(f8945e60,1bcad5d8,10c09618,a26a91e8,ac0e2d51,71790e52,9f56735f,f0addd12) Z8(f6d59b5f,15309089,51f90843,f4b9c58a,9cdf8672,76e38b0a,f4abc527,feee42aa) Z8(1f512849,7a941c6c,c7eae2d6,e16aa754,9aee681e,20fd5789,0181b2b3,318d7eba) Z8(0ef67b12,4e80c212,42d9b12f,a3e23762,773f5771,b3cc1a58,8def3e63,8b910138) Z8(5214ad60,8ab14f18,4fb532d1,10b45ae7,3e97ad6f,71d0cc9a,1a0aa94f,ffff3800) },{ Z8(232a626d,4cd558bf,76207143,44336656,49a5be76,48c3d3a6,621a7bcb,f3e0d75a) Z8(ee2d24c6,12573c86,a3ec4f8f,14717de9,c2447f9c,ea510491,4dab1a74,82e20a0b) Z8(473c1059,39e751f6,4ea0741d,b404fcbd,f71cd4dc,dfbf01c7,0753c6db,f3861581) Z8(f178711d,1606f011,ca438d97,90c11ed8,922c428b,9a5da29e,00a70b70,65741054) Z8(1897754b,a658bb20,f693f3ac,bbfff017,a2e99fa1,d2f51956,9abfc86a,04912e56) Z8(f3ce2e6b,91b92900,e6a3697e,713045ce,a24939c0,2842e134,40ea622c,bfe3ee76) Z8(046a8a0a,fa45b598,c520c760,4ee576b0,1e9654d8,c505ee87,a2c296ad,1d287152) Z8(329d1467,90859b23,40433d43,95421bb4,fc7ef01b,71812973,e71a4f97,d46902f8) Z8(f86a6a62,7bc49420,7d23c2ae,67d5ecd5,3f8fad24,ed57598d,47cd45f7,4f4e30e6) Z8(e8f7791c,004f9710,09230d53,810b6c56,1cd5b089,9942e72f,3e14da32,e179c270) Z8(f3a51db1,51b169a6,c223af96,f0167f7e,51d3b53a,7968d89a,567e1b49,edfee7e2) Z8(d2e96aa4,445581a9,b342caa9,53bb086a,c038e4c0,adf699e5,4997a5c5,19217b6a) Z8(4073f9e0,9cb38572,a1e2681d,09e70f0f,44244408,b1d59ec1,5672e054,7712f066) Z8(86d5bce5,0f5d83d7,e55c9390,8fbc8c09,c1a82408,287cd351,99ed7fee,2f0ba84c) Z8(72c0de87,ee984624,cfe1af3a,43e36b6b,fc16dc7d,f2b33199,38ac5f6b,13dde9a0) Z8(1c11a950,ab2081f1,cbf4ddad,a99ea124,3465404c,af5e49f4,9e4fdb17,d7a74e20) Z8(b043a53b,17790849,9d116d28,47edff7e,033642c7,a9918844,388208a5,dc1e8c07) Z8(261cd2c4,1ada463c,cd22603e,5dce95a7,66420b70,55075766,00103332,017fff70) },{ Z8(082152f2,f124b328,37cc9579,6402be16,af9108eb,3c92c67f,0bfba1d0,a9857c05) Z8(6c683009,dc0c90cb,f8564503,bf3a99d2,463100d3,85b91e69,82845746,e5b71a61) Z8(00bc1abb,e605c6a3,63cb693c,c008b71f,b753973d,b39a3b21,eeab71eb,d256683d) Z8(056ec108,630a41e4,657fc44f,f8fdbd52,b896f171,ea866a93,d09de235,bebc22f4) Z8(36c982fa,3fa5976a,7abbd985,3533e70f,18cfa583,1aa5c634,78866af6,a32675e7) Z8(52ac2488,a6bf856a,bf014bf5,d917aa99,8ed576d3,cefb2662,70e6ac01,4c581849) Z8(23abb1a6,80474d94,f9724d6d,c8fa00e9,899ee827,1a323aab,c08d84ac,6571e8bb) Z8(ffc0854b,c123f850,c356687c,6fcaa0c8,5e7f7350,a129c4af,4a3d6d91,e7661631) Z8(320b1360,4f1f1dc4,3db33895,b5dc6d24,37fe0c43,c3658b1a,071a81c2,a885a09e) Z8(d7e0d5db,1e3ef422,24fd103f,4894de7b,2436bde4,ddf38491,34985b16,a03278a0) Z8(75a4705d,01340079,b5ca2aef,95137dbc,c819de09,886fa9d6,8f9b2b57,6b7055e2) Z8(a06e437d,9c73931c,1eed0945,e8547e08,3f3d86e8,fd5e83b4,6ca506ca,d1dfbecb) Z8(743bc06e,fc8bbcb4,4c044622,e716ce1b,e59d5262,0bfe2bf1,cf992f40,be1d13b2) Z8(10afb7f8,138d12e8,ab38affb,4ea90d57,b8a221d3,c0f6f9b7,40af79ce,0da5d81f) Z8(3d9d121a,a26b162e,1b87118d,c42be599,6bcd34d8,d8509af2,71bc9fba,6a8c3fc2) Z8(c0495f54,844c1fa7,988f53b0,0990f69c,f35558ff,c7f974fd,f553bca4,5ffb9a6b) Z8(329f19eb,d414ca2d,c79d7592,55b268d4,5d890db4,dc27a47c,75957223,7304ce77) Z8(10c9ceaf,10be56b2,2b576bab,d2544b46,ac40622a,335cdb6c,35fffbf3,fffee000) },{ Z8(02c3d20f,c03368e9,e9f26b33,524a0b96,9b559b2d,0a60607f,09445e76,b810a8d6) Z8(24269b85,313c8e02,dae8fdae,1b949d75,3b62c25d,8be8fce5,feeb95b8,155e5cb3) Z8(c87df239,27035eca,2941c7de,4277fefc,f399d9bc,abc79b1a,1986c75f,d7a2865b) Z8(3a7a73d1,40ace5b8,a8717906,84dbb10c,7753db2e,d38a042b,9a34ad12,3b23f1a4) Z8(80e4e7a7,4924366e,ba07e434,bd98cf90,9259368e,ce3a6db4,b3e56529,0f38848f) Z8(a546bca2,d6235d32,78c82337,105f1536,6f924271,a6494fc4,5d36934d,5b4bdfe5) Z8(e1485bae,247ecbe6,25006f82,ce407ac8,74677f46,1a367366,03185419,7676dd58) Z8(054e6a5a,864361d5,413f0bdd,04b55bdd,30e0b415,8435f41a,35bbfe37,9e00711e) Z8(0ca2ec29,db5fc360,7ddcb601,5227dd49,06c7531c,17cc0bd3,f92d7d72,09595c58) Z8(ced7dcfa,de451a88,90dffbb9,dc4760d0,24eee049,229891b8,8ebc51c6,adfc25d4) Z8(edb7b0cb,695cdd11,77463eb2,503d9e37,b7939c0b,535a2c4c,1701b26a,7c629ff3) Z8(c27dd8db,442387fb,482fc1f3,1b07b873,9353f95f,3e819f0e,536d8483,c318634a) Z8(94c9d54e,b4a7129c,806e87bc,26312074,48311e73,d7f1d98f,446d524e,1a64c26f) Z8(7014e478,77fa8d19,3619af74,6d4801dc,329f36bd,894f2ee0,63791dff,948687ea) Z8(03f0935e,7d16bb46,133df952,9d434b28,2e1a4f2d,03042a79,f01f7d67,fed188e5) Z8(2d17756f,4507ec8d,fe5cc22b,707fb5ab,16c856ea,f84ed1fd,22a6ae2a,dbf302cc) Z8(699bee4f,bc0d65a8,85288d08,38808b11,42c6361e,a1c4364d,1ecb2235,71d0a04e) Z8(46fdd0b1,844616e6,2e6d9544,e143bd1f,bf1166a2,8376272d,5578590e,01bfff1b) },{ Z8(f92efe58,378808f4,cb206f95,513fe000,61f9d569,2a34c401,64ecb7f3,5e023fac) Z8(b38476a5,0bcea69e,6b3df89c,f7cfba00,1df0957b,722dc3da,373ca8d4,339c94cf) Z8(262dba48,ad755bf9,33ae1ee1,721c58c9,7699dc8b,d13e2293,2e58c13a,4dacb89f) Z8(d618d3f1,f4afb85c,863e9414,443af678,47431141,3fc9d9b8,0ce23d27,f10a21cd) Z8(bdfe5e80,62315411,0851f31f,d1ac14f6,5c7c48f4,491f119d,904262ae,5e932c40) Z8(149a3a1a,a5fba725,c6ceef50,83238367,752a4e5a,6a5d1c13,3f016171,5c9768cc) Z8(fe3a345b,cd29f12e,3ded0a00,e371c7fd,3be181ab,2db115ae,6ad26b3b,1e7b878d) Z8(5c76d99d,5d80e64c,12c28cfe,e0571af1,b6229bc8,6a7bfdba,12c43a57,47d5b013) Z8(c119994f,2f237d6a,1885e361,e1e243a2,c6731a23,d33cb518,579eb744,526f0b63) Z8(848fea1c,eb4d0aa8,6568f941,5cf94eb5,da12e0f5,e9c1a6dd,bb52f4d3,6300ad02) Z8(cff4aa3e,725b6e29,728a3815,eb7a9e59,0d7d965b,c51da7d5,1c21d405,07428f71) Z8(717af0bf,cab2c4aa,4826a3cc,79a275ff,64377101,04cbbb88,7c5d7d08,ffbb33f2) Z8(6491a473,8ba62d92,e38fb8d3,b9d3bff1,9930e761,c40af9a5,ca0f2ca4,21d04cd3) Z8(f9647862,b147cfa0,cdb7c13c,362ef02b,118ce664,8a24f786,2b463108,e94e532c) Z8(cf301f12,fc22d8b5,b3b4dfdd,451d1712,8558bc0a,52960c6a,c5c6a6ec,6b0993dc) Z8(ea16a65b,984f83b8,6a0da499,45420df1,c886d048,6cd94b22,37b3fb2d,6cc4eca0) Z8(e7af2e86,89408458,554aa371,554d9abd,b90ff68b,bc39bb85,d6645e39,b127519b) Z8(eaabb869,18a31f6b,4ea4cc5b,5f180396,f501f430,3f22e322,640aa074,fffe7800) },{ Z8(545cfd07,ad7d5717,d74f0705,0012c733,a9ed1c1a,6d93163f,ed6439ed,66b501fc) Z8(96f38c4d,94a7dfce,f551a5e9,469d8489,452e2a6e,72664405,804171f1,7ee56d9c) Z8(737ffe70,5f3b3267,f9f45d9b,de1383d4,c6119b79,fc85daff,1c1d7f5b,2d844df0) Z8(acfd9949,1bd7c22a,eadb229c,db37a93c,1b57ab4d,7ec06836,630ca3cf,8e4e12b2) Z8(a0e522a7,a54e1bac,34f00b41,9792a4e0,ecd8a32f,a289584c,24a7a596,207a81a8) Z8(552175c2,25f4db17,b1d1121f,634066c0,73e26f5f,46637f8e,393a8c4d,f3ca3226) Z8(cad2a87f,8e845b84,36cec214,f6b1e7b5,f0245e0e,92d3943b,b3af407f,96884269) Z8(5eef30b3,9050fd38,773fb35a,70368973,51051fb6,a454a0fb,338d0858,1d3cbd11) Z8(0b0be3cc,db3b46a0,e7995861,10d2c431,ffaf3f20,ca18b0a5,6d1b8e36,af496798) Z8(5bf414a8,67244c2f,e0b0d221,b82bc6df,4f1f700e,b9147a66,9da4aff3,20716fd8) Z8(802a8370,5b14e5ff,d226596f,6cf2287b,ba60c77c,7c842b74,53d0062e,915751ce) Z8(b0802db4,0f9b631b,7155abe0,d2221277,8e2a49d3,9dd716cb,ee280b28,cb03117b) Z8(76e87acf,82931842,1e7d1d6f,0887bba0,fcd2ad3d,cc265048,de755943,f43855e1) Z8(01157bdc,8ab11029,b8509572,af3dbcc3,1071f7d2,41a3d980,6abf31d5,ee2e1e4d) Z8(dfbb1d0b,b28082fc,4d073bc2,e4e8edfd,23819b74,17fbb57a,af54a128,50ae742a) Z8(12fdedf7,61b22f48,a74a13bd,f005279c,e3cbad08,4a92af3b,1fef377a,a6729aec) Z8(caec7acc,0d534b7e,4ae2e1bb,d3da4dc1,c8be6a05,16fa88a2,4353efc3,20596653) Z8(cd9c4aa4,943448d9,32d90612,ca4a3d86,1221010c,6e8744e6,aaeeeee8,01fffeaa) },{ Z8(8286027b,43591dee,a466a739,e62478db,2d12077b,5b804346,1a77b88e,c9d88679) Z8(1c875f92,ee57e63d,e9b381b3,ca2daa68,21b72ef9,4f3bce41,9576f802,ace21709) Z8(73983318,33e37d82,761bff86,f16e2141,78fa2609,23874bb0,6014f8c1,ae6f8d95) Z8(ff539bfe,13fc458f,e12f0c6a,da680d15,20566eef,00e3dd9f,21f65cae,15d3dcbf) Z8(a4ca3235,3728e64e,f716c9b8,16b6cdba,ec6b2180,79ed0e85,0f938b84,27e7488f) Z8(12fa2ed0,165d9c39,7505f1b6,ae33c68a,9ea210c3,3de450be,db6672a5,c691e7aa) Z8(9830b290,f7f0fc2d,83ef96ad,e473ce89,2ede69f4,05a0bbae,758e40be,c06e3779) Z8(82ae0687,19d4795a,13900a74,b50bb030,2664a59d,f0a1bf37,6530f034,28288266) Z8(1b9b1571,1aababd6,70be3e9b,d64afaed,dd01d0f5,c3544d0c,0ce2c7c2,071661db) Z8(152fd4e0,4d89dc36,5a8a81d1,1fe8d0c0,bb5f87df,6afa7c54,cf0ae0d8,ebf3b9f0) Z8(81fb5cf1,8394a9d3,7e019805,5866db93,da442bc0,ba9040d5,c92e509e,1d55aa76) Z8(56d56619,58ca6650,e27b9e67,3e8b73c2,44db0536,67b3d9d1,59661a9c,0fa16e05) Z8(9c5ac6dc,2d404b42,f9bfa633,41c6af2c,bea5de95,fd202894,f15c7807,4fb2faf9) Z8(e144ebe3,2369b26d,2b669b84,488e296e,87ef51de,a4f40ae6,b2494e0d,1040176a) Z8(a0b31f2e,71f77c88,716026cd,4d7b2ae6,7e9e552b,7bda8ff9,e8422429,20786d50) Z8(16a5888d,abe60530,1d59257a,eb039e71,505a0c52,f63db1c1,ed70d326,8af90516) Z8(e7c976ee,c55d8730,f47670bb,d4ba6011,ffc81fb4,d9fe3873,c6c9dd2e,f9b9ba8e) Z8(4c4ab792,64b0f827,585b1e5f,283c5951,b5b41832,4034032d,aaaa93e9,fffe0000) },{ Z8(90250f5d,23ec91b1,bb68e5cc,89c11ada,3d8110cd,914d2439,d356b0a7,03bb1338) Z8(988d2fbb,cee45916,9dc84098,26cad172,1d42ecc1,21a496ad,43e7449d,2e26f621) Z8(39043953,d58bf1c3,fba54cad,1084e762,bacfe77d,5d2d842c,9674a719,7a50d7b3) Z8(37be3faf,b6f2ec29,e2cd04fc,f052ab80,69c7f710,c06a50d9,c252eadf,8a7729f0) Z8(e1f27a33,3fda4500,6af464b2,5f2fd915,f67b2145,c73727df,5dbb52a8,139b9222) Z8(0ca90d83,3945f43a,7392efcb,358b5875,d3e29595,2647f000,73a763a1,5d2e4fde) Z8(30c78c11,0027e8fe,d12be9c2,2bc729b4,88fe4593,664318dc,d3ed58f2,12ef72f3) Z8(30614753,91aec3af,d22d6c8c,e079f995,440663d1,68d443b6,91c4d17e,f9dfdf09) Z8(ccd1e8bc,b0b61e8c,fd7ca987,d8c433c1,48527cab,3a45823d,e79bcf80,42e97a61) Z8(8961ea07,ccd8be95,fb6f3296,f1a344c9,972a4a91,37353337,5ce18229,3191086c) Z8(ca198ea1,990374c5,b469d782,f43fddbb,d50440af,fa77242b,57e36b38,09595be7) Z8(c324ac0c,7ac824a2,0303554e,6c6d03df,efd66b4e,44fbdaca,088c8eed,e6e98617) Z8(4912b8f3,2d2f7089,acd36367,2eeb1b2d,e9edf732,efc0d5c0,56ec6215,df6ae696) Z8(3d3c47a4,339e3013,a6ef22e3,75d444f5,98a53abc,297e0e0d,1744fa55,95aed54c) Z8(75684159,d6af7eab,6ae5794e,18f264eb,4307fdc6,95c6b216,2cc6afe6,6bd7d24d) Z8(05a12ac9,bd250e8c,d4bfe93a,1e2c6753,42d073e9,764c1eec,8e27e09c,6e5386af) Z8(e578aad9,3b13c6d2,d1084a64,1a93cb56,9e3ef262,ea367b7b,87717a77,964117c6) Z8(bc105d91,18faa193,4c2def14,86f6b553,9f9a18fb,f8cc0397,007b04bd,023ffe1a) },{ Z8(1bb23550,663a3e0d,8e3c8b34,c48e6b40,e67ef873,dde3afc0,3d8a4fff,bad424ff) Z8(18c9da12,985e8d2a,a8d0c40d,80543cd8,71180e37,972acf9d,b98667dc,69b8e6be) Z8(ebde9e4d,bcaa7acf,57cda2d9,b7aecddc,2634de22,31d78b40,819a1ba0,90500b6d) Z8(07fb783e,0c1bd96b,a26f2b6a,7f8dbd9b,45fc29c2,4dd743f1,afc0967e,21fd4b60) Z8(46bb0e75,d4dfea42,35ee0acd,561fe7cc,4d932704,3b3171d7,e48881b7,ebdd58ee) Z8(5754a6a9,d55e7014,a130cebc,ee7b9b24,f25dce45,60665156,bad7caeb,2627e8a3) Z8(cb4634d5,48b5b977,0469b2c7,20e1c2f3,e55fbd96,aed347c6,f7bfa178,292cd689) Z8(8cb7fc18,f09d7aa9,dff2da23,bd1a5ada,82370275,bf67e901,c87508eb,58fcca61) Z8(bc96a04d,fc3b156d,558781fd,0b2002c8,8c6d47d9,4aa0397f,bd870ab2,d64fc0b0) Z8(fadf9592,3c7815da,9d3be168,1df69f0f,9131d2d8,4c3af0b2,c59ac2a8,df2dcfe7) Z8(50214c4e,21a5f50c,a9bdfcf9,f79fae9c,4fef59d1,422b9091,04b466d2,76b48fb9) Z8(7510f84d,3f99868a,cb16272a,140602d0,676e1357,1426c171,2a047834,e626c6e3) Z8(796ea514,1513fa43,d2de1517,184b5dfa,5464347d,ced3d216,982eec43,50c711bb) Z8(cae2bb62,9a08b0a5,bf47069c,5c9722be,e1d6125f,33a6e570,70d4b9c3,a08ed967) Z8(e7f3aa09,6e1c4bf1,ac0e2f19,e016d1a2,86216d11,b4a32875,bcf43b3b,a2212c26) Z8(564c7594,284d1e73,4fff8caf,ecd19f13,715430cd,cffc24eb,bead3165,70f8f11b) Z8(a02853bb,1bb73131,c5eb8ca4,20115c1b,edcbfd44,52855122,a43d1beb,95072824) Z8(f243d541,b227a130,ab634ff1,b8825f6b,cd9bcfd0,375ed37a,115fd1de,fffd7801) },{ Z8(c88cc59b,53802b1a,d9fe8118,f84c3957,8fcac84c,21a774a9,36adaed3,404d13ac) Z8(ee2a70a8,b6dd6d3f,e1312af9,574bf723,2ea63a0b,c0e6402e,59780871,7b4918df) Z8(85f885bc,5322a29c,3867f11b,3c17d568,64e47e9b,868965da,e1e1ae2e,9a871d09) Z8(9bed1e06,08b906a1,21843546,09eb639d,41128863,7a5dfe57,a1e448cd,bb0970b5) Z8(3db9e22a,d5ff3d54,894f15fb,0b9dc833,262f1200,2fb18db5,d87a415d,6412b1b4) Z8(e2f69b6f,b314fb51,f20b0b8b,d1d84710,0b9abed0,8790416d,7b7d8d42,d248509b) Z8(ca7c37dc,48fef532,f6fae069,5786dfbf,7724db3c,34255f58,1b338f2f,c4d411e3) Z8(a93f3e08,fb8498df,65639fd1,ceae5bee,e8067688,648a476d,d7a79848,70f614df) Z8(fc1848be,bf9efc5f,61656113,ec0b65b8,81c4d0ea,383bc3e9,a024f0eb,3d8506fa) Z8(0ca33dda,eb8ae2eb,8793ae34,c10723af,ba3aaac2,d71e827d,857b0e06,9667b645) Z8(5a567d40,2a08df35,10c18f2b,9af303d2,f2051e3c,e80a4a49,066f0402,4d2470ab) Z8(fb62fd28,6c13f2e2,0a57c482,056fbe03,ed193490,df6b0fb6,cac03911,6324b30b) Z8(c4168ebb,73d22bce,c792aeab,4419cc88,19553404,3723093e,98f6cfe0,ae956c45) Z8(d22cb086,dfca4b65,c7cef277,44a82f9d,5093d5cb,ed043847,ede22b4f,4a3579b9) Z8(3e12e212,23d772df,fdf8dac5,e3d0a9e7,9bdd489e,568fde0a,b1a0afa3,16e919f5) Z8(dc78baf6,f4b66cdd,282ad066,1d9df975,4f3584b9,e724aefd,2d69005b,a40b4031) Z8(8105582d,4d31c6a6,8f109482,448fccb1,6806445c,3f900b82,ce7d6682,294d3f75) Z8(a9f61923,9d167011,a5592d84,a5578bdd,d94ebf1d,aa2b5378,5625aa8b,027ffd65) },{ Z8(994d7baf,723e593d,34a60c3e,5fb64e41,42f115da,0cd86857,d50f9278,16c27d5e) Z8(f9a1d2ae,b8d57e99,7fd190fa,fd20448d,42c09c2c,b36fa204,518b6690,c4f41d54) Z8(465199b9,d3dd65d4,97781b16,7040257a,a814192b,47f219a8,4a89960c,0e80d426) Z8(46b66c7b,3daf7f36,ef09458e,e75b9383,c2d31447,468a4d1e,d4f6dfc1,3c5ab168) Z8(9dfbb738,e8c78aff,6ff75d20,1c7a6c1c,b3e5dfa5,ccf889a0,123e7962,f89f9ae7) Z8(40120079,717057cc,97336e1e,82b4c77f,e309cbf5,1196543e,2c266422,7ff44402) Z8(79aa395e,e50839b3,cb83585e,0bbcb52c,27f2ec47,b828e04d,d3647dc8,d9f18080) Z8(83ba983d,2c7991c1,3da38a8a,c89e538a,e83f8e6d,3686aaee,cca1a60e,97e0e0da) Z8(49b96242,b2a8940c,2d842951,8c6722e3,b197fb44,cb6c7511,fe9e15a6,ca8924a1) Z8(15be094e,75d0e53e,f210e6dd,fe45a431,fb3edb64,c8891fb2,64c1dd5f,cf436887) Z8(0cc36b47,2b8b89f9,02f21ec3,3e7a95c9,b014bed4,64d9feda,2830d8fd,65b405a3) Z8(322a9c6e,cff3201b,46764c31,3feede35,54852f8c,09826aa1,07ba7967,2b975841) Z8(92945fdd,06e29494,dea20078,4693b04a,b3d0563f,60c4d65b,2d275066,417fb81f) Z8(e9a73212,088973ec,3846a570,99d296bc,cdbc2363,99e02a30,7cc6db9c,369b8365) Z8(8a75e958,cfe1f257,45633481,73b893a8,8dbf1c2a,c9ffd0f9,b91a7182,481e19df) Z8(d2ffba6d,37a5e685,930f670f,99cf43cf,fda9a04f,58bdd1c8,de842efd,c4db3281) Z8(09128fe3,e02e79ab,6af78705,05df117e,de2e68f5,e4dd5f4a,e536f810,c4e4019a) Z8(c18c3620,ee0336d3,36f4cd0e,2595971a,159747bb,7b774468,a0aa53dc,fffce001) },{ Z8(d1fc94bf,e77f7b4c,17282c71,3fd487c5,8b706f7b,ccb2e605,61902f2b,ad02be4d) Z8(4719d832,a68f2c8c,20d65ea1,156f2c50,731f2a85,ede6ac0f,50f41611,1eb1f0d4) Z8(234975ef,d4f65410,d0e7b671,e73bb192,6e59a8d8,ac419fa2,9857c73b,966d9f45) Z8(ca8a6b5e,33c8b7d4,91bfad59,3b42c72a,bc823cc1,b0c46934,c72f7ac7,927dec4a) Z8(54ea2524,5ebb92cd,6991c173,a668a412,d6fbde77,3c0fd53a,a19fca95,7d25cff7) Z8(5ecb0e93,3708b26c,6a4a752f,86959de9,d7c4fca6,ea837f7a,09abe724,aaaafff2) Z8(186d3a32,0601727d,b4b02e6e,b15f319e,bf8784c5,4ff419cf,36bd7b0e,b6b0f503) Z8(21f93736,7fa05120,e55d9125,5442ed90,64bdfb8a,2d1436ea,60d010d8,a375fce5) Z8(e5128f75,cface491,c32cf755,8b7b1134,1c568ff5,97f6e9bc,6050f547,f376f7ae) Z8(dc78aead,bece546b,29c006b4,dcfb75b0,268a3350,1c74f021,d84b1049,c3016e85) Z8(cd2c195a,0fab52c4,9aed5bcd,997656f9,ae3af6f1,a73356a0,3f6ae5be,0071776a) Z8(48077c64,ff46ac4f,65dc3330,c7e9e437,a2a2e2b4,c2b805d2,8f18dacf,c9673501) Z8(fee00f1b,73d5ff7b,759c495b,349ae274,3c9e4d60,74d905aa,242eec0f,2c6810a3) Z8(b12e14ff,32a6af7c,458bf74c,6dda1e41,e7902431,394aeedb,00f24247,66de7e54) Z8(b46d0724,0a714de0,39f1c0d2,e1e75217,7819d7f2,645f36e3,c3d81e09,5d66dccc) Z8(89586805,89199e65,64971cc0,f1d106e5,ef44561a,81ff772c,d944dad1,6b6273fb) Z8(761f51a6,1c5c654a,d31ef08b,dd18b4b3,659345fb,396cbc4d,aa5bbdf9,abc29929) Z8(96bc6f82,165b3967,9a8412cc,441feac6,20eede53,1e8ca4dc,abfa304c,02bffc88) },{ Z8(a1ac661a,582a5b87,8df6520f,bf319cfc,63202431,894908ad,6c6293d3,0d267264) Z8(909b4f81,95afeb36,60edbdc5,9a2c59c5,9cd18ea7,896ea1bb,9be4473e,dba93582) Z8(2e2c587b,8113d321,9f21e319,e279dc6a,1ff02649,3969c431,a89240b2,8e12146b) Z8(2649d160,df95f683,f8ae5a24,737e5fe6,cb12f6e6,6d8ccdeb,dcdf6aec,9a1796aa) Z8(7c839764,f965d05c,880fd111,2b3c1181,97e7507a,9de0285c,c601632b,29aa7363) Z8(91395c3a,562d134d,81b0c7da,8a4eabe2,ccdb4ffa,188daa07,dc0fc93c,bc59496d) Z8(37a02b3c,85b6e3f1,03e5bad1,d5c8c2ae,9af8a84d,da472ab1,61971f26,67e04dee) Z8(4f48e780,768c6abd,c1ba3e89,88b1269f,b0ae77b3,85315236,b939f6b3,b91115ea) Z8(377e657e,202428ac,2566b22f,8cb30bde,2d133b25,fb2c7ed3,83e7e502,033cddba) Z8(0242486f,0befd950,90307a02,d509134d,34c013d0,69c1a99b,6eb69fd9,6d2680ca) Z8(e352f71d,d86f86c9,3c531748,1725f341,0e78e12d,88a1dc76,1b8f4074,35775be5) Z8(e710622f,d2ac0c58,9ee08dde,576e7b44,9244232a,b8bb6172,540f9521,72cb2cbb) Z8(6da98d30,8e2e768d,7f97ffc3,ac0cee93,35f4a305,b6d7627c,7931a017,d96aa031) Z8(40fe06e3,3e6dd8f6,07c050fa,8b0ce813,1fffd904,53e1bd5d,96f21b94,fef85a4b) Z8(2337aed5,b15d16ac,a09cd9c5,f5ba20ce,a3605d4e,06553e85,31b2a6c7,2b1ddd72) Z8(49292ac8,2e62a716,7b516267,d3fabb43,ff403ced,d7644899,5c0f345f,bed7167d) Z8(1c0495f3,d2af538b,290e7012,a8ae1b50,14664149,84c797cd,9f83f688,03ca8400) Z8(20f1480d,ebbc1abc,b32acbe5,2506505a,ec292b5e,b9bebeaa,620a10e2,fffc3802) },{ Z8(acf6b7eb,999596e4,bc5ef240,5fc26fc2,57dde96c,788f77cf,951461fb,02633677) Z8(2d9894bf,54c4d380,a084e882,9c9ad42a,123deb65,9d48f3f8,b6f3cf56,b503c507) Z8(5f5ea4f2,cee88ae4,2dcdf172,36bc211b,37f01699,f23c0945,02ee38d5,0495a158) Z8(a035e435,1f6c8e4a,e39fef4c,cc2468d9,4bcb73f4,7eb7f141,1e66e9ef,9565d579) Z8(32589ea0,aa40e404,641ed9ed,e04c571a,9dfb9cca,b2be4565,c1a10165,dfdb65b6) Z8(33e1a5b7,214fe8b6,8d4a126d,41ee5c78,24b7502f,8d09df06,0722d3e7,4d35d1ca) Z8(cd4fb7d9,1d9b7ca7,a9d0bf96,68cea71b,edd576ca,d8b0cf60,50038a0a,201cd019) Z8(5e1f44e6,f1454106,0a6d263c,044ae11c,07f04545,92245c0d,7c272d10,b7026216) Z8(0b06d037,8616eb59,84069f95,bcd68a4e,7c1d6369,119d18c6,79db1437,4d1f018c) Z8(8990e03d,6228a4d8,c557c11d,a6090c6c,a00247dd,77c0d023,e46663bf,9b01fcee) Z8(98e07f5a,3a06e825,bf677586,1b13df5a,59ba4239,949435b7,656b3614,fb867579) Z8(c258ea25,9e99b188,e36a0ef5,d79da795,15f82002,abedd9a8,73ac6edf,977c7b2a) Z8(6e9a3f60,c93c6a45,2b7a9306,406946fd,89fc4aca,9084f825,8db8ffe7,66df2202) Z8(d4606ada,451bd100,e4ae9eeb,7af3164f,fdd08b64,3312a994,55b28246,e0293e70) Z8(51330db3,e11e2b4c,d7751eda,5c238f6e,4074fdcb,f016448d,4b9df823,96aa0be6) Z8(b671f7d8,5feb5edb,0872d38c,fd684545,1c96a055,be571eee,8e1f2800,3b0183f2) Z8(8fdee34a,3fc81c11,4ce297c3,b59ee6f6,fb0e8d78,082af7b6,821e7854,3584d0b3) Z8(11de693e,b5ab634a,85d81bd2,cef9d52c,7e126af1,5082ea0d,020665f7,02fffb80) },{ Z8(c1518066,f10bb1e1,21698944,77dcbd57,d74e2d91,6940b757,5ea26f21,854b343c) Z8(53ee7043,0b3af485,9078436f,63a670c5,148047fb,564f6c5b,f54540bf,3ab95d26) Z8(f8a1bdb7,56ec684f,0c7cd0f3,299eb14b,1e995a49,dd9a6bf1,fc0d3a94,479fb7a3) Z8(78fe09fc,42973ab2,ae70344d,952cca3e,d7ab21a9,3fd1992d,210bb4c6,38e4c0f0) Z8(365f15ee,e1b59a99,df751d88,1d3cea30,5f7ccfd0,2b898ef8,1bfcac92,90b2f031) Z8(37316039,9319211c,e79d001a,93d27ac8,ca2c1e34,e0881f93,ce461204,be891045) Z8(33edb83b,f3cd3c83,f831614b,cc4a02b4,f2c9895c,9acab1df,20aa4722,ee322dae) Z8(181c8a26,a608b5d4,9b0e2919,3be2d26f,66482e66,521b01b3,6d76f662,b5d2bce3) Z8(96c1f03a,5abf2743,8678383a,0511d802,2ad1be28,b9f7f270,65084a45,ff07f72f) Z8(2d7b282e,4277c133,f969b89a,5e9889c2,ce4c64de,06892b3b,cf3763f9,c2e84afb) Z8(47308cfa,1e3742c4,34154a54,c607c3a8,f206d940,48eaea98,36d38a30,f49a3d0e) Z8(a24cbe32,da12cc06,68fe87ac,2cc5c1d8,0be0f2ef,868d3926,a76ce7c5,d265911d) Z8(4efb6e76,a4c00293,dd0030c4,8475b8a4,68d28e1d,3e106491,ee11f0d2,70bfe8b0) Z8(3cf46008,6e79d0fc,18fcb347,29e7e7bc,86cce2a1,9217e42a,141dac37,8eaab723) Z8(52f4d9b6,70cb6f73,a2ef2362,9cce9b5e,90df7f10,87443cba,6881a82f,f8e5193b) Z8(449aa2d5,52f8edaa,fcd16fb6,049e2201,746840c5,2af2df70,314226f0,b4eb930f) Z8(a40379e7,ad1cfcf5,b7ac5136,6de072e9,f4ad5f6b,18c2a1eb,3c74e210,4a1df9d1) Z8(d94391b8,36bc82aa,f68391c5,18efb2d1,090fa8bf,f6750326,5ffefccc,fffb8003) },{ Z8(f6a525f7,7979c8c1,1598b577,e7ca3074,f869958f,d071a389,44a48b63,54c8bca8) Z8(da6a87ff,72dee4e3,1262017a,dd32d409,db84dfd4,5b35bb7a,e8c80923,a638e7b4) Z8(b3233e84,28bae309,362ffb05,ad14d198,d1d6aa11,fd5115b0,998827f1,3bcc1db6) Z8(7bcfe3a4,d582f572,72846d8c,74e42431,6230375d,0ad05962,af48bfe3,9f8908b1) Z8(7f452f62,02ead4dd,4f0808cc,b4e57690,6807fdd9,f9a03b0e,4212ca7b,e1b3bbc4) Z8(edd7063e,5d1c7d29,1a20703b,70a5110f,88c1ee61,da59ca77,60c461d1,f17ce4e1) Z8(075febe1,b19e7120,950cd42e,b7580770,3c7dded6,6026c57d,8db4f0ec,58518717) Z8(232a487d,a6fe0f8b,a922f565,e1a36d4e,6a23ae27,22474d9e,d66095ab,042a6966) Z8(81e099c5,c566634f,6a48f063,b59c1105,32e56e9b,d8518f4d,5b32aba6,95aaf33e) Z8(863e438d,3fbd83ba,4aa3d220,6a4b8905,5c752ca2,43f6380e,f3386ad2,0e009149) Z8(f7b52ebf,01511c4f,214f2691,bb743837,e852a6f9,33b713e2,269a9829,a714bdd1) Z8(b119ff92,392763c3,31d94d23,40a27034,7d6bae67,c4d8ccfd,39f62582,449861b7) Z8(c2f19edf,d34a27ed,4939c83a,52bde187,185c5d34,4c1fff9b,c8406421,c35da683) Z8(464a431e,e9c2bf38,d20e6f1a,56dd6087,3cb5840c,38257026,60d66f52,913ec194) Z8(dc9c4f95,22ec2bd3,f9f5fdd8,b88b261f,0e6b8f39,1880c8f2,4e34f3a6,edae1d7d) Z8(f89a64a6,b74c23d7,3c291af1,850f1327,fffc9fb1,820e7741,6229d77a,f3efca2f) Z8(2f9b12bc,7a302ed3,624c1cda,9414b2a3,9705c9a1,84a5eeb2,ae61a891,75e8913c) Z8(33b08063,033c308d,ccabf770,109216aa,f141142d,bbf7c37a,585adb81,033ffa47) },{ Z8(e17368eb,28c437a6,07e07d96,5966cc13,b564b409,1c7586bc,e63a5175,8abb16fa) Z8(21e30419,7348e11e,b9bd4e1c,4155c2ea,ffab15cd,ca2cbab0,c750cb5a,973c8d33) Z8(5884ab60,79c4479d,a9c2db34,f65d1e87,5450c02c,efdb12b8,57273bc2,ae554884) Z8(566fab78,405afbcc,e4c9ad26,0c3bb3e5,f9fd7e11,16f12684,b1fe2da1,60d5a54b) Z8(28a7adf8,1d29a981,628b3242,58a63c6e,2a64b87a,787f0f21,8efa2d4c,a365835a) Z8(88118c56,a120d07c,4cb2b9d3,5fbd2a07,c0ca4914,8c58cfb8,e53ec2df,0dace61b) Z8(3067237d,a36babeb,a1161235,7b33a316,c0af0982,4f529980,a079f408,724490bb) Z8(b7c1f3c4,fa3f915a,2020ca00,0c6cc06a,9180e903,107f7e0f,297841e7,bee67c41) Z8(07f7d675,8ecc3587,a9353602,6119fb52,5b90edb3,bcba6623,a5f48ff8,200b0f2e) Z8(758bcd84,34ab3a52,a6e06431,c02a70b9,e323388a,5402c488,8791af7e,d7740da8) Z8(dbc72eb5,25a470c4,32c38e9d,eae9b47c,8aaaea9c,3ebc6ca5,2416495b,c63dd3e5) Z8(0d3c9813,e08cc3d3,43b08c65,ecdb59f7,bc44b484,57e8ad8a,fa03667e,ca0f9134) Z8(77e8c006,9752c492,0ab8d81a,ad165047,f7dd61b0,50820ed3,26f81f24,73f74c33) Z8(ec3dc240,cc91fdcd,8f47c9f8,48e63148,78bfb5a3,236df82d,8b1fe1bb,65edae00) Z8(e876ad95,c4621bd9,63008a6e,bbc29999,2d9b91f7,0df2ae47,a3614096,15299a1e) Z8(2f9b45f7,d539f362,c23d64b4,f305cfb8,8ff21f7f,367b01e8,31085ba7,ad4c309c) Z8(34e9d9c7,2a85ef25,f722cfdf,87f804a1,98d747cb,496024f9,9105c160,e75a7492) Z8(087ba8db,7a3d593f,d4851b07,61edaf45,7dbf28b8,8d9b4aa4,a60907ac,fffab804) },{ Z8(7841996a,d98d255f,b7fce581,c5d562dd,d566c7af,c98a4102,304d7c83,15754324) Z8(b396bb3c,38246b75,8965f2c4,23c89881,7c8fe42d,80bc6d12,81261966,c500b714) Z8(f687c6fb,7e87fb72,0c2b45c2,22b09394,54a7234f,47d3732e,b0df45e1,a924ac12) Z8(93bc93fb,26f017a1,b0ce37e6,29b34b26,4469604a,f578cbf6,1736c9bf,61233efc) Z8(758da5ce,387a0e65,09af1b33,ca16d756,7f445a28,f1eaeb6f,376565f7,8215fb85) Z8(6fb58751,fc62d500,2125b89f,7be45b2a,83a16ddd,e8bec672,195cefe0,2621fa8d) Z8(3ac866d7,ec3ed615,dee7493b,685b86c3,ba8f96dd,3db3abc4,8befe674,675e6db3) Z8(47506205,b051da0b,ae8c3379,900e36da,fa3c2d19,96eb3b5a,6ccee8c0,c2c52868) Z8(d1dbe3e6,2409a583,a252a11e,02bd0d56,29068804,1d8263e5,79af9a37,ce347ead) Z8(1a59f125,e15c9376,7aeff4c8,a35db0e5,92872c4d,e40ce315,9bee77c3,d158a20a) Z8(523bb1cf,6efdd5dd,bd999fba,2c998369,a3354927,b195bcf2,4f29c926,a6c3fb50) Z8(4695b7a3,59f2ff90,e8de6238,7dd9c04d,19dcf7fc,8f65f06a,2d0281a0,30e211e7) Z8(fa991dd2,dc25d183,6aa021bb,3af1da59,3e71cddf,2771fac7,8301b238,cbdb2d7d) Z8(c7d4320c,81c45f19,aaef9123,44e7426f,a8a4625b,c5fb4f70,2a81bce5,3155eaa8) Z8(15d9149d,ab42c56a,dbac5fb3,3f94ea6e,62a186be,e0f6496b,ff231fb7,34a6ab2f) Z8(2e85dd26,cfd056ee,92cc7048,561dc212,9f31ef24,8b4c6053,a6334228,0f71121b) Z8(ffc028cc,6b8b958c,df3022be,9e9844ac,09e268cd,46179b97,9535b306,caf89de6) Z8(afddd67c,07aefe2c,14c0179e,fef7f3d5,0677d335,54d6e402,af0b20db,037ff8da) },{ Z8(5209c5c7,2b73574a,8b6db333,8fde69af,90409176,60cb5349,0f45f1ad,32f5e40e) Z8(9d390d6c,d6557f48,a5064ba1,9bf826ad,5d3181e6,0f785f65,53dbd0bf,964f8d2a) Z8(2a18c308,723a820a,f60ede4f,f93606a4,b8380485,e2b3a83c,12719162,71b23a76) Z8(f02bf70b,9cdc1bc1,b7464b47,34d76953,987f7ccb,f9d52dd4,5b9a5459,40e08d50) Z8(f3c76f0f,513dc325,fbaedfd7,caa472dc,f4403440,f716248b,4328d7bd,5a2e3fca) Z8(f852b3b5,dfe368f9,bebcd33f,8860da3d,c15459a0,f35c0650,f0de0dae,a6c46cb9) Z8(75836cb7,48a82923,8a1d4988,52918699,f4816b0b,97cafdef,972cd2d0,b081aa75) Z8(ee018207,fd06ce31,715cc95d,af41a08e,cf5ecbe4,cbc01106,6f59e4b1,43821fed) Z8(810fb0a6,5dd1d223,ea4d0cc0,d9228078,4c3515cc,0358e713,3677f5d6,b38255bd) Z8(d8313c94,f06c70e4,b4ee9a52,f05e2aa4,7c439aec,99fe8be5,daa9451a,dcc54ca5) Z8(d8ce41fe,c2ff5704,a9a476de,73041559,57146407,32d5f450,b145494a,36de7e4c) Z8(8be22725,96ce1299,f7af7a2e,597f487d,ba90b216,79154c02,615e704a,7d69b192) Z8(df2964c9,ee559391,5584ac32,47810dec,bd2dba5a,9f493a52,b1567850,a903261c) Z8(48dc8a62,00a3e2ca,9a5bdaea,527ec3f8,03441501,f6a1d9fe,1e827ff7,c1fecea5) Z8(a21a82f8,367b653f,867ccb9d,d94ca157,deb513a6,fdefd9e5,12a7bcf9,4b913adc) Z8(368dea46,5dae5229,8f914959,f2e7038b,3dc5ddcb,d2d31571,e321f43a,21b874bd) Z8(972c07b6,cb9a3f33,6ca4fc79,d2fadd1b,8a750899,a74b1c3b,5d64fcb5,1b987741) Z8(b5ebb004,112782f7,7d909277,673892b9,a2c51bd9,33f4256d,40a81d10,fff9e006) },{ Z8(33589e47,3031c5f0,303cf21c,5621eefb,42bc9ceb,fdf044ea,faa41f23,c405c0ba) Z8(92616920,c9d37220,1d79a589,17f7da8b,d5a44e40,7dd3c084,8ddad853,9ddef75b) Z8(ae0f8419,0cc1482c,12b84c58,3a4b6ce6,2caec421,1ba7f6b3,12713a63,83123d74) Z8(7ec52084,8c739978,f620120e,b7bc7642,e1009222,8286bf08,2d7835d7,09a924f2) Z8(c80c2603,84bd960e,b01c5722,6caf29c6,b0636921,91639bf2,ce8863cc,59316de2) Z8(27ec7d7b,e1a3d15f,3d4f0ee1,94133e2b,c166e890,19463c38,cb99993d,f041960e) Z8(6641d3a6,f37d8016,5fcd0ec4,8d43fcb1,0383b37e,9a70c5b4,113de068,f47576bf) Z8(341311d1,276d0c6c,fec90b30,19de61ca,09576362,0c544bff,159cbb2d,aa151d94) Z8(3533b20e,591a5cca,2f3f4051,5233ccf8,6934ccda,5d6a523a,7919903c,1764172d) Z8(f2254e5d,d3b16bcc,ccc483ec,98ace46e,c247d5a2,014dbb79,29306188,a5086ccd) Z8(6a9ac41d,3aab8e94,a9b5a940,0a26024b,d1d049be,d55767ab,27af636b,d8aca7ac) Z8(c24cc81e,f8a25298,ef193605,b9bdad2a,df225465,3e88411d,b6dab238,91d5d34c) Z8(372fb12a,5a18bd62,932daf36,0ae01286,a5ddcb98,933ff4c6,ce1d200b,293648cd) Z8(ceb07d4e,90c6b228,7d55b2cf,4d61e8f5,da1253f5,182f60f2,c3b2cbb2,c924e012) Z8(5f45089f,e03f052a,728b369a,5b6aaac6,ff0cd22f,b89f4882,1521fc24,5aeb220d) Z8(8c4d5922,8c68917d,195891f0,6d6c5d8b,dc51b218,021a2cf1,7aa47790,0fddba8a) Z8(32fe285d,26fa8974,4240b66c,ccb58fca,a3fd5b87,55ecd26a,9a105a20,a2322756) Z8(b2fc2c7d,806f73d1,5ce0bbe9,ce1e66d3,4626b501,4db9bdfd,062e05ee,03bff736) },{ Z8(7e448dce,6cf482d3,89933037,51b02b64,8cf57dce,82d03d1d,5e9cd87b,bae09404) Z8(946db25c,b7316e0a,263afcaa,309139c7,f1ac2ae3,8337b795,5bd9a416,db9db091) Z8(5ea1e8c9,6da4b76d,ed31fbbc,8ef2e00d,af1f69fb,64b5eec9,a98dd858,2aff3bcd) Z8(ccc21dae,75f45cc3,c65c4a26,a92c92f2,edf493c2,801d7dc8,97ef2d1b,dbd0ca0f) Z8(d6b72b91,c6723f2f,02eaf03f,04ddb115,512da717,1abef62a,8e1081b2,abef50e6) Z8(27294d93,14537af1,8ff67ed9,33166425,09888efa,0e695b07,2adcdf67,da3d63d6) Z8(7e5c2458,da1ee229,c1606b74,d7f9e727,0328e0b9,b849e926,7b116648,41ff3c3e) Z8(0f79b1e0,5b78fa63,fb6ee976,dfaf9a63,043779be,2e3af270,6548358c,f170860b) Z8(ae703850,4440641a,742b317b,c0536f12,efc11222,b41c57fe,ec38a67b,bd9b4020) Z8(39a4807d,c51213d2,7995cfa0,737a3b30,45d3dfb7,00b5aff3,8353b906,68e5da73) Z8(b70ae76d,0845d388,9019cc98,c16b31bd,d3a1979c,1412b2d6,fc8f7996,bac1ff73) Z8(86ac1be1,40825c8d,3ed80fd4,a0b8dff6,9d862e1a,8ac8a6ef,71824e74,bee2fc5d) Z8(09c49fb5,7e870140,207570a5,d72db992,44244ea2,2f747d37,5fd30f14,332da58c) Z8(caa4b1ce,53367173,45b6ed80,b0e9081d,7ab37128,19aa04ce,a5399cb1,cb7a6906) Z8(73ea41db,a6fda334,952cd526,56676b37,2cac8dea,ece666ba,223c622e,c3f2a0a1) Z8(aabf14c2,809c0858,68ae1c16,3696a89e,3a0219d8,1ca4811d,7ba7d6f5,269a1a91) Z8(ced39ebb,27d1d873,41d11528,095fdec0,711983f2,41ee9060,e6e27262,52c7cda6) Z8(c442a703,b1caf8c0,9dc02d02,a1e37978,e4c45d19,f84b9aa1,3d5c233b,fff8f808) },{ Z8(164017c1,d0c9fe78,78856893,58ba5e47,0c93655e,a9af3b9b,33383006,74f5ea54) Z8(e22f7932,892d31a3,e3a02564,f7bbc241,5f620b4b,2c3c24e5,5753959f,209590f4) Z8(42a3d46e,c9001792,7cff2d58,01ba3fff,1df21db7,8077707c,a67dd958,b1da81d1) Z8(93342368,1629629a,f7ca4d6c,689a241d,ead99205,2415c3ae,87c60899,dd48d51c) Z8(b0ffc81b,52daa1a5,62dcb8e5,384dbad8,1a073e67,a224f911,cbf0722c,726113db) Z8(7c15a00d,3f6a63b4,cd391ff9,82b74a28,dca70dde,da38a972,724db7d1,3bc88188) Z8(7953a228,a360d91e,0478a668,e19d19a5,513226f5,cb6d8999,49d48ca5,ac3beb0f) Z8(b4042738,b15e4049,7e818482,8cdb87a7,28edf83f,17987d83,d0fc19c3,526f0d0b) Z8(2d74e4a0,3c532836,7ed69591,515760fe,42ee5466,7e4fa00a,d56fa58b,2611c602) Z8(0ab57a3b,471f96ab,473e1fec,18196160,5c919066,ed0cf6a4,f998674c,e8c7eb0b) Z8(296630b1,509950c6,aa30cfa5,3d43eaa8,87d6e66a,fac60b19,9d09e2b2,ce005481) Z8(9f5ec938,7714fbe2,314b3233,832e5618,642d6ec0,be58f64e,3357d03b,f45206b5) Z8(6ef5d017,cf8fc9d9,7b797895,36af96de,ce8793ea,35a73eb3,3e5038f9,23fac825) Z8(ba44cf25,6be96ff1,e40d251b,aff6307b,957e0afa,e9fcdb91,79365d7a,9354a105) Z8(a07f3326,95b1f4bd,2760c4ac,635ccdf6,392d3aca,fa1521eb,b33fe641,f6cddc99) Z8(2bfde828,05706765,7764c10c,031dfd78,3fb5e9c9,3cb35998,1bf507fd,a8c351ab) Z8(fdaf9747,8e9b8e30,566197ee,72435801,c62e2cf7,eb4498fb,5ea2034d,a1bd4211) Z8(985b1d56,077ec1bd,f5624024,62c181f7,1f113dca,aa938cac,5dddda9d,03fff555) },{ Z8(132dfb51,1c6840a8,6e4da03b,dd311dd3,7ff8d829,da7964ce,edbbd254,fafd6cd2) Z8(e20c4b52,58af214d,a44b685f,e4070dbb,9ce76286,903ef6d2,a4d60fa0,f5865c16) Z8(a5fb57a7,5779911b,d0956208,89acf67e,5fc89237,8beeef4e,87277c75,2d5227d8) Z8(2e1ab1f1,8270be12,652858f0,5470115b,aee5d70a,b418b83d,8e59ed32,674a1aaa) Z8(4dcc455c,6626159d,759ea347,af6911f2,84467826,2b781491,6b571705,1b78e9f8) Z8(a968c57c,b4f2e62a,3866f075,a41dcfe9,9e8752a6,4790281f,b5a22165,9373e4ed) Z8(910c914f,c4c72ba6,672e55f8,ae7c4cb4,a5da6a78,11a5e096,cd382fd6,fe7d7663) Z8(4a2768ca,629e4622,4d0ae329,f70ae17d,677272a6,ea552804,bf5fed9b,57e6a546) Z8(47ebfaad,46efc1fd,f5030314,ef530284,7b4378a0,0567dbc5,bc79625f,fac22941) Z8(50d23b5d,1663a006,0e20388e,ce49dbb8,a57ec1fd,3b82ff63,4207ebea,5ab8689a) Z8(fb6ca96d,a068b5fa,db4ba31d,1fc00d03,b8c1933a,57822bfa,9c80c7ce,b3111559) Z8(d8d8c519,866078b0,dad11f51,18ccf4a2,44cf5a38,490103ee,69c84da8,3c94bf6c) Z8(dc92b670,80b5809f,73325b5a,24ba49d1,408d86d5,2457f80e,def240e1,66333d42) Z8(4305b43c,3de4c5a7,90cda035,a9e29e61,e2c790aa,70a1469d,9a803791,37b9e15a) Z8(719ae310,7fc75619,efa2a828,edb80de6,9be94aa7,65fbe5e9,6fb28871,43e6e97f) Z8(d3588aca,46ae2710,7f5262fc,c9f13d2b,2e8a1ecf,7095ca07,5424f909,b263f5f0) Z8(b77519c6,3a897fe0,6eb671be,01e286c4,edc98229,4942277e,e7d32643,9b3ed7ad) Z8(6ac7f294,121a3235,8d241e94,104dd21b,de6ace45,4514074b,aaa4fa51,fff8000a) },{ Z8(06955414,d8cf002d,d7c470a1,2474b7a0,a968e502,1f7f093f,1ab5406f,0ceb57d0) Z8(c3c87ba5,cd9de1d4,165cfc78,803504cb,3f747395,1eb44006,540be673,3bc4a286) Z8(12e25547,cdd74637,ad16e5b6,ee1593f0,b44e3177,4608d95e,f6254b27,d2e1c3f9) Z8(84f7b56f,0eadfa2d,7f1a6d94,15670c54,2c8cfead,03c4e6ef,c4450888,13ca544a) Z8(f31bf90b,d939dc44,8e4035af,65fc1a65,6d6cdadf,76d39174,62cc8a89,9ced7f03) Z8(cf5bade6,f1df26d2,36a1f120,76545178,222d8baf,e9821d3f,c83cae62,4bb27f22) Z8(ed3298c7,0a0f696f,6421c9f9,736abc93,9dcd3e8c,559f0cc9,055124ee,d308a7c1) Z8(768568a5,4837e3d0,1e653ce3,617959a4,9e6c9276,d20e6acb,d658ba70,c58072e8) Z8(585729f5,31592e96,53d2fb42,d0b1c4c7,c9e066d7,fd478fe9,f5d952e4,bec81e12) Z8(450c3b58,6bd7b713,76609434,b0616423,785b7635,56bb979e,55700fc2,b98417bb) Z8(dc6c4bc7,1e3aa39f,91e5fd0b,4b672968,f2613af1,5f1ec920,985bc6f3,35989357) Z8(9e5ab52a,87ff33ee,2ee79a07,e791395f,b7aa249a,b7445f7b,6aa17230,f96c959e) Z8(71b633ed,6a70305e,bdffcbb2,cf220246,e4d9276f,6b363cfd,815dbed8,301958c2) Z8(f6ea2209,d21a1254,07145009,362e8b84,22f3515c,defeed1d,1aa00a7a,fa9696fc) Z8(363d3c72,f70d934e,371e23f0,75d0e24f,9c411c3a,54cdfdb3,94c6f8a2,0c235a75) Z8(2bf259d2,79d0d9d9,5f8a00ae,b7ba8a3d,5ca7adb1,0352db17,671295e8,0118efc5) Z8(ed83fdc5,e9ca207c,cf51788a,b3a5ef3f,82be84cc,933b1f06,4ffd5a0f,0824eb80) Z8(8987a7b0,39d50c30,6c7a51be,75860538,ddb1c87d,9b5dd0cf,b638aec3,043ff334) },{ Z8(427df3d5,59c276f6,30249f13,93b211c8,814069c7,de254dd7,15e43f9e,e9a73aa5) Z8(db37e58a,12ce19fb,01394e2b,b6935d02,223987e2,15354b5c,2c18816a,cdfc7f6f) Z8(282cb8b8,5be6d76b,bd16f79a,866d8e9b,598785bf,3ec9f84b,fe8bf847,4cc95393) Z8(cace4975,30dea243,c72cc709,ab88b374,092383e6,51d89be2,5ee197e5,a7d0dde6) Z8(2f009285,7bc2d2f0,bbb90f82,53a98d55,0189c120,2db9bc76,33997137,60c05fe4) Z8(331a63dd,3bd8f01d,c4418b79,7c0c61e0,88ab8f08,790c4095,3b6b14cc,296ff1a2) Z8(d3bdf72f,877d1dc6,4c39e22a,90f1b332,9f1877bf,343ff81d,3d80c028,64270846) Z8(20590f2a,4366c823,bc8ba44a,155d4980,856c83e7,ddf01a1a,6f8c8e79,66df0e45) Z8(258e0b7e,6359d8eb,4ed47a4b,fbf361ef,20795c7f,2d6bf821,cae2cc4f,d9bc8bb1) Z8(5da40fb9,0c23e4c1,0141dbde,3704169a,4fc1eb38,b4b75716,ab72cedf,710e29b2) Z8(bca40f55,4cef01a3,3b4a4846,984d6fbf,81d8fea7,3b48ed76,c1ee8701,7f8f7a12) Z8(3ffae8fd,643e91e7,d595eb24,1f7bdb17,fb599e55,2b365242,6275d350,bdfc3f83) Z8(75db139c,87bb2753,18fd3817,2d3038fd,9571bbda,08e979e4,109fb9bc,6461ec14) Z8(f3734e59,901d241f,77d71bd3,4d9b53ba,17881ff3,2e36e5df,0f0e6a1e,09e7d6f2) Z8(59910a2d,576060ba,96876272,bfdeaad9,c68cb99a,3c228c5d,2782b9a9,47266926) Z8(d040252a,b82cb273,731b9686,29336167,3004a776,6ba0c58f,8041b71b,bd33e62e) Z8(c2190e8f,2c8e605b,55a6f28e,ec6590ce,44a1a631,34355c64,2802380c,15f9549a) Z8(3ac2ed22,13e63182,4f0bd8fd,3d9fe5bc,df6f3ef4,e2653d0b,98027b66,fff6f80d) },{ Z8(653b135c,e4647f3e,f2dc191d,8776c725,d79a8741,b30ac316,c5f95bb6,ff3218eb) Z8(802107b9,4ea9169c,2128fca6,eece940e,460677d7,c37a5799,15284ba4,9720bcf2) Z8(e2f96097,d1214cb3,69eb4758,bab97e85,34e85762,37db6dee,24ed8905,a28aa2a5) Z8(e508b0e9,c3e0aed8,6663cfb4,2fc8033c,45162538,72b83cac,44ee5abb,078eed80) Z8(881bc7ee,4877038b,058e9cf0,c3b3900c,9612b339,401c2f73,ca950554,05a563ba) Z8(0a6af183,fd854410,aa2dc3a1,16a17aa6,eb28afe6,fdb1483e,2eab532a,35778044) Z8(74a6b09d,332bb3f1,cfe14f00,084e1092,2ae42be0,8fec846a,349934d7,86dc35ac) Z8(effe756b,41258be1,173d7e0b,dae90ec0,2afc3e42,8479ed4b,a77a174d,687c8148) Z8(14639686,50925e7c,b07fad62,6e1c1636,6eddbb9c,65c8737f,83aac48b,758634f0) Z8(d3094742,afebea6f,77153f39,ccc8e3ba,d8033529,29555bf0,bb27b3f8,99087283) Z8(f9bf590e,210de2ee,391a4e87,12c74b37,36feba7e,500a866e,cdb4f9bb,39aa7e7a) Z8(9a1efa36,1346f70f,7d3e0109,37e5b621,681c6689,06dac5b9,5fe11a6c,5a7ee11a) Z8(4ac97c4a,afc6dc96,baba8f9b,ea9a3463,86317ae0,80ded43c,a4b5f908,7e7e488e) Z8(58768f6a,edd78b8d,9c17b915,bc075b21,afa8551d,38831b22,0232b450,ee0d79a8) Z8(d2430024,ceeebe71,d3e85dcd,ff485924,934db7e7,62cd4325,3732771e,a3f55f15) Z8(36464913,f6d49302,d19365a3,b17a8514,813eee65,ce7c34ee,d2096b36,4ada09a0) Z8(74763332,aca214fb,bf760103,8cc3bf35,d01ed556,d0fa3513,494bf88b,76903bad) Z8(38d0ce72,6354fa38,d7908e87,77fde0b6,3e8848d6,9ac55ad8,0f60922f,047ff0d0) },{ Z8(0f73d7f5,ab9389e9,ac33a49a,39f104b2,11c8f942,26e74f0b,a0f49211,8cbaf305) Z8(b76e4db7,17c02f0d,f863b902,288d2308,65341f0d,84d834ff,422deea7,d0dc3b78) Z8(e73bc79d,f881b9e4,fcdd2a86,b5c83c39,1d5ecb19,1129be12,407a8d4f,cd3a8fb1) Z8(6d725467,fd2f256f,34898437,736e0d1a,c4cf1caf,087a707d,dbe2ee11,068aee91) Z8(c0f5c955,b3c8e0e6,c1bb4518,abba6fb1,ad394d21,bdb7b91e,235889d2,82cdbe7f) Z8(c0197740,6c5865a4,9cdf6ca1,6ac83922,27b1e23c,8258ebd6,015ea26e,79f12c9c) Z8(a632410e,9d29d90e,814f7f6a,f5f463a7,5a1a03d6,dd06a6fc,ef2f5aa2,2706b56b) Z8(3ee69444,53263303,a13a85ca,bee0a36f,cb25afbb,9cb4587d,d33047d8,2a2635a1) Z8(3c3d054a,390ba045,78be49b3,b6dd2a06,f9d8f225,77b3f17f,7b4e151c,8b640249) Z8(1831782a,9bf32912,297ba07f,1a595072,fdffe71e,f3dea97d,44d1f143,41da87f7) Z8(bd0356e1,54efbca1,701c407f,f5ef7972,6914b016,a11a87b9,ff8eb648,dcf2899b) Z8(94e70d40,a4ca09f6,4bbcd161,424df9a7,f9d4e136,e17479db,da3fae1f,c3f8a97d) Z8(9d06502a,f9d92e5b,47404f9f,90389232,52ddd98f,b929ca73,114e7ce1,25a14479) Z8(0fa0d742,ef393304,983cebc9,c2b14171,9f80e687,b2cf9713,17a447c4,2e430836) Z8(167f8491,c5f04741,c7b45389,fd23640d,27a09bcf,635ce4c3,f1882608,613dcbb3) Z8(77aa3dcc,78e9b9ff,82d1c672,71c7f783,607988cd,cb0eb328,c99b782c,0c022cc4) Z8(a2226ea2,ce0034cb,a32eb5ed,555c71f8,46bfc5e0,4117d8c0,063da242,8fd463bf) Z8(67b4a608,73791d88,fddec6af,dcbc64ac,db57baec,f86c603d,15f47790,fff5e011) },{ Z8(3d193e7a,e57eca97,64f293f8,9382db2b,53ce7096,9c4fd523,b32cb313,ae2b5968) Z8(cdbfce58,25a25cba,163a94f6,9fd4ab87,8549d1f3,989d0633,d867c58b,f4373d84) Z8(0ad7c50c,aa42f13e,bec82d05,9ea167d9,769957cd,49067808,b8a48ef4,82d8671e) Z8(0d13b7f8,c76bc343,f001755e,b09593c3,e13be7cc,21ddab68,4c9646ad,436a4970) Z8(15bd07b0,fabfb15f,8983ab35,f2f50cf7,1e49c868,43cd0b7a,2f30e248,6de1b32f) Z8(1c2749b9,f8435316,463bc544,ff2203ac,c3fb5c0e,a0d88cce,c725979d,19849e0c) Z8(5d8679ca,37ad2036,de254ac4,9c97ad1c,88e84ea4,b17ac78a,3f7bcdeb,e501ced1) Z8(f0f2062f,e5ec45ac,ff6f7af8,1674d386,6b22f1f9,edd2d5d5,f7d0033e,00120a5e) Z8(0d014037,36d0846f,0785199b,63ffa8a1,9b3240bd,870d7c26,19f0715d,4fa0036b) Z8(50a13851,766cdfbd,ca4e7059,7da6eae8,b23f6cb5,0e88fc84,435cfc64,980f1265) Z8(2071eca4,c35b66e9,05c948c7,d358eceb,1c059005,34504567,719bef0a,abf1c136) Z8(5aff1164,fa3700a6,9cd879aa,eb620226,86272403,df080639,351845a8,05f73fd8) Z8(00e9dfe4,3f9d452b,17160d20,4fdd05c9,9013dd2f,c15c290b,4627d469,37370174) Z8(9beb0195,e8ae1b17,9b2c5fea,74076e06,94c6c479,6aae0768,f6d780cc,0cc82cc6) Z8(da1c2fbb,c4dd61c0,6f8a3979,5a1d5ff5,918286c1,9c76b656,dfa9a4b2,fb82aada) Z8(d5f0b479,70b02509,c126f4c4,328aa09d,63dfc2d0,5dfdad0a,d9697866,6ab2ebaa) Z8(b934085d,58693c16,8be9ce9b,036966af,fceaf652,ac8afe91,a250df99,2e9d0c29) Z8(5a7d450c,6c6b1030,637e8ac2,65b3ea67,1fdedd3c,4cd800ba,697bd4a4,04bfee23) },{ Z8(0ca17b8c,69cd8dbe,bb9da9b5,c34b3121,9ca6f98d,ca52b03a,e03cc442,bf9a96c2) Z8(56620874,c4977725,bac436bd,498808f9,6b4b6faf,f6542751,77eceea0,17416127) Z8(906cfb5e,f3e05fb8,f8949b66,a5deed90,9188a83d,d7d14f01,2f27ca90,d9fadd8a) Z8(d09537dd,3f644db8,838da7f6,c74812a5,afc0e6f5,2da3cbb4,550e0725,013a1ca8) Z8(65bd24da,ad26b3a0,b2e65020,e2bade84,6e0feed6,e5da133a,c030982d,4230044a) Z8(82ba66aa,507856e5,85515351,4ee33518,9ffb25d6,4f9b96e0,fb8f456c,785fb8e4) Z8(7ec4fbb1,2f425bba,98e86872,d0299fac,9d27d232,3afc9c45,721b215c,e1d62401) Z8(0b5c9eef,c55a008f,f61d140b,65a6b00f,cb58ebc9,10d3d32a,904c46b2,a587a07f) Z8(0d31928c,f53bae5f,c6b1d0f5,8121a865,40dcd543,ea225eb7,b3431076,86d1461a) Z8(31596430,6d441571,c0f5d97c,b66c7639,4d9f681c,0efebc5f,e0e224b2,d51e58d0) Z8(33a77edc,f55cee1b,19c10bd4,5b834ec9,9ff8de82,1fe50316,bb4dc05a,66c1511e) Z8(c41becc4,7384bae6,f69c91b4,ab596ca8,3e08dbe8,60421a4c,2c77aa09,17463225) Z8(78615382,eac71c59,e3f4e95b,024a8b98,a7aa08a9,4ad81036,ba0d38fc,04b1fa7e) Z8(93fde3e0,8989d5ef,e0c541d4,0d93c939,c5ceddf0,0f1b5135,8fa7a700,489094a6) Z8(0c8ba07c,fc585258,3df540b1,0c9ec4e1,bb8d464e,97bcd9ff,6f6f30ef,1fc7e603) Z8(8a8f6b00,d797db6e,36598dec,9af04291,489b04ce,ad167d1c,20b79d69,f126e509) Z8(07eb829c,c9711a5e,63e9cfc5,2ea4c25a,5ced66c5,9079531c,4c827777,0001611a) Z8(79707df0,9d149c02,b02fec1e,1a7ec6d6,ad7b6a5c,125c0572,35fab6d9,fff4b815) },{ Z8(39a69d79,5d38ca4b,199486af,a9595bd4,4af40e59,eda04154,fadf5072,9520f1f8) Z8(8ae3dfd0,f81d8f12,1c38b893,1b81b428,add20497,1d340f2c,09d2bb96,c92a802e) Z8(ef3b5747,f752d978,ffc55cdd,3c3a5233,e69f4408,75381d6e,40a97631,2822b170) Z8(bc5d9d36,6fb9654e,4cbf2040,030c09be,9de33f5e,76b0150e,e5730ad0,0d48f076) Z8(a1aed8da,5d73826e,d7f0e850,1fcbfc05,5151f5b2,0512633e,91032939,aa45df3e) Z8(aafdff5a,a111b15b,dbf99285,1bbd8979,9c105e6c,b8a7c0af,fe5fa9bf,1a227f1e) Z8(d3e43604,3342f3b3,fc67ff41,2a88f8bd,2adf37e9,a862078d,a9c9ad60,fd846679) Z8(d7ab9898,454f928f,e772d7ed,d6fdc733,e5eb0626,a582f8c8,55023fcc,daff45b3) Z8(c5964358,642c0999,3a9a567a,f1f3d341,c0226a52,bbb1b926,412c6121,47d8c4bc) Z8(f32a54fd,510e1d86,a1c5d338,c6dffae4,51f7a389,6f8aba80,dc12f069,75e168e5) Z8(995fbaca,8f205242,5429cfdc,d7babe91,7f2b0b92,6002edf9,1c7d2c4f,a0320309) Z8(e1737d94,b7586a35,30c28271,963f6d3f,76824b71,21894523,43c1cee9,8b96eb32) Z8(b555630a,54004b3d,7bb47c93,8b6a4750,cf8365ae,b9011182,d3bf928d,9528556e) Z8(f5a4699c,a79ecb23,5f888970,8d7ccfb8,786829a4,5669d741,12295701,e0059744) Z8(d562e60a,5ec6cd88,c7eaf6b3,e9344c45,27bd2c2e,66f47f7d,32252d04,71c1e44a) Z8(8441fc0e,3822fd41,c285a67a,9bc474b0,851f883c,7f7152a2,c8e09c07,54587842) Z8(e3463014,cf3d5b67,78186dc9,3801a36e,ce2161f8,0373d0bf,6276fde2,4cf23b8a) Z8(f0bfed96,50fae5a7,7c6e0e96,4a14e87a,cccea63e,19b3218a,c4b545d5,04ffeb2a) },{ Z8(febf3d9b,074493e5,10711f14,105c81ba,7158abd0,c856e764,3f18f8a9,9c34723e) Z8(95dbee56,430a0968,5b7c7a4c,4d087761,4a87d77c,6b016c0e,83b8b022,d9f287a8) Z8(75740038,f6a98df9,0ba0c6f6,f888c0c9,c754a736,79702e8e,653d68e4,11f67ee4) Z8(1c7d081e,200e0041,a0f7d342,24c54ae2,b2b60b73,28fcce79,26e5f1d9,b5f00462) Z8(43b09c72,ca8aeae1,0f20a263,8c14f409,21f35d18,4b67b636,941896f3,c16a8142) Z8(9e25a490,6fdcce02,3c1ea289,672f252c,b087712c,f9f9fe65,7ae37409,f54d8c69) Z8(a813a677,4aa5a273,132ea988,4d77b9a8,68c0e799,4e462505,a06e2e9a,70e5c649) Z8(feef80c1,cec819df,0ee9ed1f,cf9cbe8f,ca19d568,543670e2,99d4ee91,d5aee545) Z8(ff47db39,5d22f683,20b8bdd3,3f158e2a,039a0dc0,5be1698c,af5641fa,f7419cff) Z8(b2cc033c,21209e7f,841baa1f,2d7fea4f,afe21664,468d7ad8,a6d66b04,1b864a5e) Z8(c81ff57e,9951e92c,91e23991,e3c2fdf8,3d326eab,1a96a7ce,7ff111ec,d2b71793) Z8(11703218,d86a3c4e,9c3df620,470ca099,7519cab9,69b07169,a6d5faa5,4fab7b5c) Z8(df8904ba,00ccd1f0,77616676,0110f59d,8a6461af,5aa94392,43d8ad5b,64fabb52) Z8(2d49a875,16f1082e,b0e3453b,e9001824,d4181410,383b0325,a0a576de,3f1f7447) Z8(91924f43,150bf444,113d6a24,aed72ed7,38aaf72f,c713c725,ab19f15b,7df222cf) Z8(cfbb7ac2,57bf1e03,fd7ad0af,8d1c83dc,666b8e16,f300230b,3da1138c,f13a121f) Z8(0aa8cc75,71ebe6b5,3da0bebf,2c3d56ff,aeedaac3,0b0e9804,0840625f,1e268993) Z8(1f19c22d,8bbdf397,c116c793,644d7b15,9a68ae63,21ed0e0d,0a94f726,fff3801a) },{ Z8(6e22da5a,5efcf478,44bd1bd3,e6631fb5,633b40a0,f54bcd95,e8bd6b14,06f474ff) Z8(ae7a1de8,a0b7f5d0,9bc273e9,d9101062,975ffd9d,0d5bb973,47a4153c,0b41b5ed) Z8(3c23cfde,0daa366e,dfed4ea4,20d60fd7,c4d96002,49a94b4a,2caf7f4d,9e7493c7) Z8(a63a2d25,cd7a5f99,214424f0,ff0addbb,7025e6d2,56ecf9fa,fa024524,187ceed5) Z8(c8d94d44,b1ce9ecd,cbb03d6d,86371644,7aca7a4f,1bce57f3,4d72608c,ecc04c8f) Z8(64867d41,44356bf4,0255969c,27e3ba06,f8f27b1b,9605054f,677af06e,25ccafae) Z8(0d81f72d,b25326e7,6e490c24,fc9df80b,bf1f321a,f692dc6c,279bf1ac,7c867c4e) Z8(fe2dfd5a,be0e17bc,49eb6cb0,77365589,7cfae2ad,cdebda01,08886267,e85b6b59) Z8(301bfe08,df7de8c8,8429ff9e,9a122f14,26234696,7c95d80e,c140b6d5,4d349f0e) Z8(a78d8a47,9f1e30ee,f9382f1e,c9bd84a0,6a241e23,e1f93b02,fefe280d,23dee60b) Z8(696868e6,5f8b3653,852ed809,b2f1adfe,a3517372,bad9d9c5,3585931e,5cda001c) Z8(b8f97d64,2d554b10,184ed5d3,912afc23,068124f3,ec70c1fb,1534e3f6,87b4c502) Z8(058e7000,bac54ded,20479e9b,2a6b6d8e,7da58f73,f1d15f2c,1ea550b9,d072c2ec) Z8(ff610eb8,34e5e564,3eaf1677,29185b04,8f28691e,964beebb,bcfd79d9,d4c8b17e) Z8(aa4bc305,bf5b1ff4,80127dbe,31f3cd25,893381e1,e2a1f57a,86563188,c751fee8) Z8(9c455c5e,8466f4e6,be46e35b,ebb4ff2d,e8492838,04eaa0f2,06e95699,b4fd17de) Z8(ad1acda2,2667d353,aa58bf9d,76779248,efe922c6,9dad6b88,424ce583,cbe2bac2) Z8(d7b1475e,adff56d8,254a25d6,bdc49376,4e6d655b,80331d3a,213c7563,053fe7e2) },{ Z8(5235cb26,41ca6459,060bcb5d,07f37cc4,66c82df5,ab6d90b0,9323d4eb,6be6dcc3) Z8(384a803b,8b11311a,97664490,e290d6bf,02fe1a72,d18bd1ae,820f1746,ee85f9f8) Z8(8b963f85,4ae2ee2f,732a87a8,e4b5ebf5,b09f0853,db04b09d,e8254886,722e925c) Z8(65a061bc,016b6a98,0afa51e2,82301de9,c1653bb7,508f5203,22495a12,cd307af8) Z8(4758f46a,877b2da1,4723b760,bf1a0654,251c3201,c5adc8e2,ac8817a7,f5578eac) Z8(631b0569,916b6e36,8e826bcc,6b91f4f2,bba4e2c4,154939ce,99c1c1a1,7d9c1f96) Z8(25d007e3,0fc0179b,b8ecf18e,f2e7a9a9,009d027f,a7275248,3b131727,41ff594f) Z8(06342486,d6962016,cb62f343,10fd2442,3e9faf8a,b34f7766,4c092cdc,e21f6875) Z8(d16e690f,7e2d71ef,e32c00ae,1a2c04e2,3991ffe2,6c2e987f,91434a7f,fb922815) Z8(be7733bb,2b983b4e,5c3f70c0,21f44d42,c0b6ad27,aa3fa60c,3c15c72b,ad7f8a8e) Z8(52cde49e,d1a3a92c,2b0d3911,b595f9bf,c409c853,f8326673,304a454d,36b8f36a) Z8(cc68342f,088da43d,6332e66f,275d7c79,da8a2e5c,fd0d1428,6d3eafb0,fb55ba19) Z8(49095e02,b0c95ed1,67771510,681abb46,37128aa0,7b6b5d58,bd8b41e0,4754e268) Z8(5cf60df5,79844350,1a6c40bf,f037698b,da6f5b54,5361e180,ff7f44de,464ac5ed) Z8(4dcede95,b189b6f9,65bba3bd,30efc5eb,5a3024a6,ee5458c7,d44c08d6,cb0fdf32) Z8(88751a13,43280d31,c6cfa7c5,bd74ebab,2de219b6,c29ff096,68fcca12,ebe59800) Z8(43fac8c9,f0cd9b47,b45a3671,ccefa359,81924715,9bb5a72c,8d9e6381,3e93f221) Z8(649723b0,96a59a71,0f3110e9,6aa11e45,e9909755,8381c3cd,a742eb14,fff2381f) },{ Z8(4882f7bd,8298d940,f496a446,7a6d34ad,aff15e94,397204a9,8f834c0e,12a93722) Z8(8f3841fa,5a7148b6,b143f880,bc0c4ced,846d93d1,41ecf7ff,a0b3ef84,4ff3405b) Z8(9601a9f4,df79a0a6,1d8c7833,9cfd8244,54c66466,83d805fe,88a14640,69d30878) Z8(5ad7318b,4d32b64d,43356113,7aa51619,539cdc29,747d8a51,8f9c973f,8c5bd6d3) Z8(e071ddef,1a68a38f,4646095d,ddd43dc4,3ccd97ba,e4e5eab6,e77970e4,d4bcb8dd) Z8(b3d919fc,d14e4e53,be2829ee,aaf4922a,7b02f782,af0d6b76,a315dfb3,e91afc25) Z8(f4b7e175,fcbccf14,fcc11404,772a4b8e,655b4e93,c47c825b,af9228b8,e8d7d2e3) Z8(57b15d26,c5a3dc84,f7409ce9,0de8e352,0c33fd83,05b9269d,b4b3383b,0a7509c8) Z8(535baeab,75004ef2,91d9958e,6f6084a8,a6f3ac3d,43d11cc4,2e8afd4c,1f7f1c44) Z8(12a49359,3da4f391,ec74b744,b56a48e9,d42852cc,f6d9f172,0ad977b3,b8491f28) Z8(57d90664,04cd5b4d,4c006a02,cd95ba77,1bd6f53e,0be9e34e,3950fb6c,42fd2611) Z8(f26cdd53,01ef2402,71939e98,c122efc1,4fd19343,bd55673d,773032b4,9578b603) Z8(1fa1b134,05473938,7fc425ad,8ee2b392,6f96374a,ef3569c9,15c4fa39,cd0879b5) Z8(b398cd12,d35f94fd,0a938347,e74c867b,74ae34da,5eb4a9ea,757e2505,012a7a26) Z8(b8b310ae,1ba710b0,b8ee2cbc,17e152aa,2f933bb9,2fe9ae80,c4fedebc,6d4a09fb) Z8(950ba3e3,63b65a87,983774d8,4b52d360,01dfec65,0e06da3a,a0d65296,9b402f8d) Z8(e88f51a5,f97ecfc7,09c644a0,32046db1,c8695522,ec24d8f2,045559f3,2d450f2a) Z8(9ee5227e,703ef91d,ad8f5210,6c96c9db,20c47478,1ca3eb47,7f45f2dc,057fe445) },{ Z8(8ebe4614,dbb97880,a9ad2463,e6f8053b,2cc29cab,b79275ac,40142338,0b97d4cc) Z8(056abce8,6c4aa56e,6b920e21,6cbd4023,5922dc4e,488edce7,9726193b,803f2b15) Z8(07460d6a,2c36d2d9,88fd6668,02db7f5b,c523a36c,56cdced6,625665e2,145b04bc) Z8(bcd3118d,021968cc,d580403a,7c8c0088,569decf0,35ae8514,c06a72a7,c29ec830) Z8(7dfe7c1d,896c21a7,4c297cc2,d3002f02,6b2f32e0,a648da3c,28733ea1,5ddc59ca) Z8(08cacbab,325d61e9,98cdac90,8f35a929,3ea58333,2c460400,13278a6b,b92ae3a0) Z8(298f8d7d,b195edad,3adf3ddf,568cad7d,7a4410a7,6ad89cdd,53e69184,b7723cbb) Z8(5fd5565f,4761e176,4721575e,0854c1da,e4dd39e7,d4a13f56,4f52de77,083c8243) Z8(06467610,4f5d6822,5d2c7e4e,19cf5fef,f652396e,fdfe7906,70dbc585,3cd6be36) Z8(db09bba1,c76bc3d9,b0499267,8c91b1dd,032e816a,74c0b120,2069604f,aa1c5b39) Z8(1f884a3e,dc2c8f10,6e5bd0d0,52824d74,88d1ef7d,3bdc5903,4ac3719d,9a099eb7) Z8(ad86f301,5486369f,3d67ea3d,7cd011d3,5cfb7dcd,d0ce4faa,0c8b16fe,3872b2b9) Z8(65b75f9b,7875cd14,13bf258e,9965f6fe,34bb2bed,070bcd3a,1585de56,add73a0c) Z8(74c705fa,4a125101,5b5a673f,8b05c514,da7e90db,d9b4cd40,d5c244ad,d52396a0) Z8(cbc46e56,eb8fcb1e,4b0bb6f8,e7a86883,729df6fc,195022c0,931f7f3a,2e76ddcb) Z8(4d0f4f97,60783ac3,1ecdfdd6,8a9c537b,bc7a9476,e412c964,16c3dec0,7a41d0c7) Z8(5e0f125f,5a677bb9,91310b25,6f2379d1,1f9f50a5,fb3c6a5f,b56d7989,eb747999) Z8(ee4db8bc,db8fe8c8,db3a6b2d,708d1f34,4cd4c8ad,02fdb302,208438be,fff0e026) },{ Z8(2fd3337a,ed99e6b1,9822f7e9,a19f77d9,5a568195,584dac44,ae00801a,f97f8143) Z8(6ccca5d2,182b5e24,7b6cc28f,b020899d,dbd969f9,edb7fab4,7c0573c6,ddc597b1) Z8(4c118eb9,9c3699e5,e4872a1d,3185519e,b3849051,f9a380f1,1a1c083f,33b7e8eb) Z8(c1d7d910,7cdfaec8,b76c9a5c,e2e2d790,f3093869,090ffc3e,b1c71074,8b47fd36) Z8(ca2cbcc1,f5062fd1,70b00ac9,3c77973a,9982fb39,2f171378,cca0efcc,3d34344e) Z8(d7c518c3,1aecbea9,7c196b97,1cd03988,0c9d44ed,e5ee43d6,fb4bdf98,ecd650a3) Z8(efa2475a,9742d62d,20f8e418,f4f7527d,c84045b5,d693f559,82d2b3d4,f3d9d0bd) Z8(1a8ca89f,5ef79495,558340fb,70f93a62,9e7416db,2a188ae8,1e866456,2db9e336) Z8(4c60b3b2,3c5a0539,90ba331d,06457203,1b857e9a,dfcb1b04,9d566fab,37657e26) Z8(b3fc53f5,2f845b03,536e1804,a6e08812,c9727ce1,c9c076f8,92ca0530,1f804800) Z8(4a79528b,826c5557,26c055a6,69357db1,57155355,759e0f95,be2fb411,556d02c9) Z8(9f3ee910,73bf71e2,bbf3c039,1140ec12,563dc8dd,8cb649c3,7b09891b,e80a52fd) Z8(707f77dd,e4d5914a,c70bcbd9,08df6b8f,af09469b,9d34919e,423c8dd8,38352908) Z8(4fe93786,785323e8,35889822,6705d56f,9d80d5a0,00d96150,5aa21f12,dc0e07d1) Z8(ea928c9f,12995ba3,c9ba31bb,49102ffd,81fd83cd,afaa6cf5,097cb331,5613760d) Z8(adf7edea,9d651acf,13901c8b,99fe66a3,e0f92e45,7b800e59,023e912e,88e4ce90) Z8(30c340ae,bdd2adbb,48997b50,16897058,afa96d59,17772c97,31b45a84,37bc5389) Z8(b740c8fc,4ce58223,5d8d95a7,b80378bd,973bbbdf,5f730005,df0b8db3,05bfe050) },{ Z8(e5eafb5f,ffd81142,a4585b8e,c7b9632d,04c42784,5e4b49aa,91d288b3,b7f030d9) Z8(8baedd01,fb2555e4,a524c2c2,750d743e,c9465c84,5e778e49,cfda42b0,603b58ee) Z8(28e637b4,faf85e5d,fa030591,3c5795ff,8c8ffefc,20235ac5,75fee8bd,e8fd4d56) Z8(4eeccc58,dd9827cd,1a824b10,f17ebc63,db4b7da5,1b7e1b9b,2945ec50,01b2b13a) Z8(95556c3c,45f96035,3d18335e,9fde858c,3afc5233,6c9a5328,02acc18e,597a42d9) Z8(35e2d092,3c7dc2a1,0122c2f0,3dd70a53,d769e5f0,5ae86490,6447b742,0703ca96) Z8(1d78f050,ce2a4a8f,f5d07c47,4479ffbf,b123d901,605a3b9f,f93439be,066d764c) Z8(41993220,72b7ed8d,0af3306a,ae28abe0,964aaebd,6a5e3438,9046bf11,2ef652ec) Z8(da363379,5503b6ed,2b8c3593,0cd453fa,39469149,764dd97f,2c5af574,56ee520e) Z8(c5559f74,58e04371,5cd18f8c,de2188c2,57a37d8a,c794b8b9,7b319b5e,33e55419) Z8(9db51b3b,ac05a7b3,9781b6c7,19a66f63,293ac5f1,534ff057,2cb5e5a1,3056dcf3) Z8(3e326cc0,fa26e309,ade8c47a,c229f10f,90339e04,d0747410,18c8e26b,951e2373) Z8(2cbbaa0e,89db8112,168eba6f,85f18e62,2868053b,bdf5efdb,0a0251ac,63210854) Z8(49f0c726,59ebbb3c,a8e3a8ce,3eb4ded6,bc327b38,339bd77e,c3e5f5e3,35713ffc) Z8(fdb9865e,3e36f707,603952a0,3ef3b10b,da51c83e,e17731ec,92d4a809,c9635390) Z8(69a64f13,1a8f6b5d,19391545,32fd3822,9cfd4d19,761da990,87bde19d,f4f8aaaf) Z8(b4496af3,bc9ff45c,eed06b28,f2bc947e,acb56373,656d631d,dae080ac,3165af51) Z8(d2da4da5,8544cb76,b4851a95,16a4658b,7e54fba8,e165c318,8bd87871,ffef782d) },{ Z8(50c7be0b,d6fc7383,74321d11,976f460d,fe161827,aced4c22,a38d316b,152554b4) Z8(2a226df1,23f3fd43,279edb7e,77d46cc6,c1cb5273,eb069f97,6ce955da,be586234) Z8(04aa26ed,72c38cba,0a015f21,5c055efc,0f0ef828,8abe466e,a5ce85b7,d2bf74ad) Z8(edeb21ea,10a22e60,aac19a0c,6eec03e4,9b7a6497,f67591bc,ff2d34e9,c2d67aa0) Z8(f6c03c76,abba831b,6875bf0f,b8c159b6,c84d47d0,bfa3c674,d347ac90,e79eff1d) Z8(c1676386,d8c5d069,68bad8e9,089bbee2,efc630fa,bc28d416,c85568dc,94376898) Z8(e61bb309,b69a8c82,d236c3ba,b29f9975,ab90c27c,75b99c4a,b408e692,8bd621f5) Z8(29f70b2f,907cdacb,9bcbc796,d6de7841,c55a3d44,9b7e19c8,9a32d218,957c1030) Z8(916ee237,71a68e25,16e09de9,bde41e44,9aa64006,fb608e2b,4a932101,a1b491b5) Z8(f0131fc6,c5f6af4c,74e572c1,95b4c1f1,91e789aa,1a8813c6,43e26abe,e83123a1) Z8(bfa7b783,94de2aa8,5396a1a2,c89069cf,5ef27199,b05d9003,8f20d727,d1c0f5e6) Z8(c04fb06b,6fae461f,b6f58424,bbc32f14,5d184f28,cee044ac,1ca1425a,7123eebb) Z8(c386ab0c,a9eec7b8,e5bd873f,c0b30d84,b3010d28,3c46f79f,cf4b7a5c,b1772e4b) Z8(fc93122f,456cd25c,4eef8f0d,b130b337,274c54f5,cf314946,cf78ecf7,16945e41) Z8(17af6439,891abda2,500634df,72ada566,ba71b00a,4ca5f229,15c33fb0,e1c55f88) Z8(dfb07db3,0efd99cd,a20cb058,64efe7e2,5b9f6b89,91f7e2a4,04f1d767,c7cbd9b9) Z8(5bacb364,5423d214,a7f1a284,d474869f,89626be2,c4224296,a2fb6ce6,8fda35a7) Z8(4ec65078,057e5d7c,5e37ac6b,848a2e8e,27336737,efe2b515,40cc9541,05ffdc00) },{ Z8(af253b4e,65535844,82c49e25,1bcab93f,f0531a6d,6480b5e8,4852751a,12880461) Z8(8f1e3e5d,fd4cff54,f8baf6d3,49420983,32845c92,c1ae550f,adb4acc2,d8135b89) Z8(e26a9881,5fd3da8a,0b9dcdf5,b7f6a13a,0d61e535,be4e691e,3160545b,3e63dbf0) Z8(53c941eb,9c176e3d,b588aa4d,764370dc,843bd251,590334bc,b4ae5a1c,b9365abd) Z8(4e0c3178,33358ee4,4d952438,cc31b965,2af918f0,7cfde73f,600edb9c,7da16c56) Z8(9cdba02a,a35dc802,587d8af2,7f73b32e,7030c321,238b7ae0,7cf914b3,0236b985) Z8(c384dbfe,fde7998e,102744c4,a64e27a8,f84aa5b0,f33bf56d,304126a1,c2da1dc7) Z8(19d6f3b9,1947ee29,08834601,eac9138b,a309b9c7,4b2ba879,0715c996,002eac09) Z8(ddd46bc5,a077cb4b,790e3f08,be44a1e4,08527558,719e05b7,906d7404,b848546f) Z8(d38b0bc5,1d6b3872,9c2b2d8c,cb3df97c,e5879656,6a29769d,280fd530,bf856d54) Z8(0c34387b,3a1f4b0e,068151b0,083ad6f2,c354686d,322698de,21ecb0b5,c779d84a) Z8(ff333653,1083182d,f55ce40f,bb6b87c8,cefc24f6,22043cae,cb6a73dc,ada5cad8) Z8(5d091941,5130a8b8,923c8784,e6881f4c,16afb496,7dce4a08,ae480825,f92f5517) Z8(7e4eabf3,607df764,994b23d3,adf6ea40,3e82710e,f01fe0f6,8ad4bc3e,62257bda) Z8(f61f6762,f22f164b,2efa0591,945b6eb5,aeb92097,2cccb633,24546d9b,0844eb49) Z8(5abe6ae4,85646629,30f8b40f,584eb597,94c7a512,7bfde352,e2774375,48331c09) Z8(555152bc,0b70a74a,ba9a9f17,8d823963,f1545bab,8a7f9869,ae2388f8,29fa7dd4) Z8(24020b86,f3a5aeed,50c100b1,135c2400,f79e495c,db5d0d2e,ffbf335c,ffee0035) },{ Z8(e1ae2b31,ca61c955,b4bc74b8,b9b1a066,51b6abef,ea021cd3,37e7f457,1ec67a4d) Z8(955c8e48,017bac80,8e3f68a0,d8a8f5a4,8c7a1323,dce0965c,f7239f64,9725439c) Z8(760a2c35,c6f294e8,2a883723,d8954b9e,a0e025a4,51484942,51f7a26a,2d1a63d5) Z8(f8da989e,0c5b4977,285a8371,53b35da6,b68a5808,fe4575ee,96795715,3805f411) Z8(1843c2a7,85bbbe79,34d6a09f,2ecbf9a0,c0e00ab4,878404a8,47e0cee4,a0f69069) Z8(18d7f17b,8e0fa1d6,a0febc4f,7b85e28f,be4d9e06,cb5f553b,6ed004ef,cdf2dadf) Z8(64bb24ff,bf6e7fb2,6238dbaf,99c9aaf1,04df4863,33413514,8649a531,2bf323e7) Z8(656abf16,79b90351,1d1a8e4a,ccd923c8,a879cda4,76f39105,b7c9ccf8,61bf41ab) Z8(4d7cbdb8,bbcab29c,496c78ae,067d3232,fc67646c,d67e0d28,edbdafe8,7ddf1865) Z8(280cbc72,f3e7b2e0,e8dfa028,7b55baf9,26283819,5dd6d555,03992136,1becd708) Z8(7ed2d4e2,f6f9215b,8b51832f,7ea3ff72,a9da44da,547bd527,6e861d6a,b0fe7a64) Z8(2b9ca4b6,82826df3,a9a0394a,eecf6eee,421e75cd,50380244,4a5b7991,fae6aebf) Z8(43cd7c61,22ec7467,315c2261,015f5567,8991c20e,d2d02a6a,2b0619f4,f41c353e) Z8(23b417bd,ad89fd2f,d10f20f3,22fed282,17ad64fb,ee42e729,dbbf6ac3,0618480c) Z8(3e4794ef,6b0960d1,6ec26037,2bce6b3f,d90a3870,b19d9cf4,bdf70ae1,2af4d930) Z8(cd027ecd,d1f97581,1313b548,22ab959c,a42db987,a47912aa,65b0ed2f,6352e4e8) Z8(0fb568de,661c0206,328735af,07e9a6af,1bc05584,097bf812,e210509b,5d6ed45f) Z8(ce86ffee,01653978,7d7c212c,9c1a33dd,b74d3b7e,b6bf6edd,a4ce18c0,063fd74f) },{ Z8(94f5267f,5d7b9178,364eaafb,14fb3c5d,5c7e6961,d11a658f,63b955fa,66723e98) Z8(39a82630,90dd51b9,7087571b,8778eb47,a0f13d33,39fe5cf4,53153f78,ac563a84) Z8(2b5ba059,74b03a9f,710a5c6d,d0bac4df,901e1a09,d922a155,b77d193a,db72b1d2) Z8(7a628035,f79099bd,517c1aee,4f22de96,10e263d7,9d31cb8b,121178da,0bd6cd4c) Z8(de332b82,221b4e53,8e101ed9,ac18eb93,2d8584c0,12632c47,03219fff,ff13d660) Z8(025da9eb,d47dd418,3161d960,013a6099,2c423f81,5a9a7f99,f19aa012,836a9ec0) Z8(338762f6,cc9bc351,93bc83c7,e3f1382b,9f6e61df,77d4c8e8,00b5b4d4,22fa54ee) Z8(add9a4f6,597d453f,a41e2d34,82d7aa61,5f797ec8,d2e91709,c08f0b05,4b27a624) Z8(57e8da2b,0bcfd5ae,52533c87,af5c0601,cc44ae0e,ce6785f0,9d797141,76bd3674) Z8(5631939a,07739044,6fc2ca82,472fb44c,8a9a887a,3831e072,224aa081,39085bfd) Z8(00b8491f,3f7de85a,f9ae56c8,70a4556d,7ccc3048,5454fdbb,6d7043a6,dd04807f) Z8(1c8ca0c1,3506d46a,8695d151,3984f187,9b38972a,b711fc44,1f186284,dc95e914) Z8(df09a7de,bcc2e6f2,9e3768d4,19fcade0,c10b3cd4,3bcbab30,5b39b5c7,ba9c61bd) Z8(23e83258,d43c02b4,b8d4a3ed,7862ac89,10e51140,49bb767b,2a78254a,92807039) Z8(26f61423,39f78c88,9a5a1bf1,ee6cbbb4,d36d67ca,f67ae4a6,efeea53d,06846e8a) Z8(a6b93786,2d6f904c,c5dbbf7c,2a70fcfe,a6c20269,d20e7918,fbb5dc8e,4c26343a) Z8(b7a365a9,7b08ddeb,0ed1661f,46d680ac,40d06d94,b7a9af12,7465dae3,e4d6f3cb) Z8(1b56d0b5,413d53d4,4e9a0efb,ba1aadf2,d82900ab,3093f040,93b7e221,ffec783f) },{ Z8(eec4ab0e,ffb61eec,ee1613b0,f8a18a45,9013aab0,dcc3f76c,eb2e8d73,a7e9cfeb) Z8(f9450a25,bc1edfb9,e63ab97d,ffaa1c3f,ee7f63df,3d1e3fa8,3a93190e,0d5734e5) Z8(e1bc8b99,2de17285,d816a689,c1769d6f,6d83a50a,8b0782ba,5d79dac3,bd7ef6e2) Z8(4ba292cb,514b6225,69c065bd,d304530e,663003ef,58ec33cc,43b5636d,2fc66674) Z8(1a83dd07,ec7fa619,d420db42,202e8100,a32d67ce,02cd1bcb,be21f2f5,9fe7005f) Z8(5ac4576b,77473c94,359fc3b2,f9d3bb45,91050304,5f46e951,67348ddc,03525c78) Z8(032327d1,115983ca,ee365180,0976c571,f39e5802,a7978768,e02e8946,a81cfde0) Z8(fac9e295,521cea91,18396379,525133d9,ee30c410,7f06e878,95c54d76,b48aadd9) Z8(87c49418,9def9f98,5131874e,6674d559,956e2b26,09b77a70,69f1aea2,53d744fe) Z8(169a09b1,10c4ef89,d8904003,027b8341,8758ecee,dbf4395a,9dc4d213,2b0e97c1) Z8(068d9f30,c24f7c01,059892ba,d9402453,30152b5e,099b6a4e,6e3801b8,fbd11f81) Z8(a571b75e,e414cb06,96116b50,a760c300,ed3890cb,fb06801e,c68d2f72,e7fd9f5e) Z8(75862281,166ff3fe,b7678be8,95f4d6c9,9b8f1319,e93b588d,c6c15b52,60bdcb2c) Z8(a7161cc6,461ccb6b,491fb7e3,a6be37b1,6ea81422,21140f9b,a13059f4,5bf3b8b7) Z8(c6773042,20646d44,5a39fe2c,e302f93a,655e3e42,14206cfa,faec3898,a6e89a8d) Z8(6a3e7af2,2da2b9a1,d92aeecd,541b8db1,9aacaaed,b60c567f,e0d2b088,f84bc1d5) Z8(3f1dfc77,f6dccb87,b03aa937,dc9652f0,d8096eb0,be7ab42f,22a43a24,6f248807) Z8(df94ab7e,110d1bdd,3c42e8e2,da1785c9,f60e9ab7,8d16be6e,0b5b2744,067fd23b) },{ Z8(3a76c04f,aeedd18f,06fe41cd,0bfe25bc,1abce867,f358eac5,04f6f923,6f5f0cfb) Z8(3bb04525,8e869c83,0bffeba4,a842b81f,c827312e,0aeea878,6938b390,8cd542c4) Z8(31b4e49e,3947da8b,28ed52fd,bc0265a5,79a510de,d2c6ea76,0c5f0c83,4a6e7c41) Z8(2d593159,4983f611,0ae42d3c,3bae6059,6344191c,e8458e09,e73149c5,8887ceed) Z8(ba0beb05,e24306d2,a70099d4,7b5378c3,d36a3f5d,a8fcc154,ddf53297,668b6922) Z8(6741087c,1ea6ad62,9984a0f6,1ff23751,06bdf793,af24f7bb,c0795543,494b9e78) Z8(9aa3f14a,21538ff6,c92ef8cd,22fce0e7,c2f65f24,7414316a,f71afa15,4efa50e9) Z8(99cb626d,00da2e57,a86be69a,7a16336f,3f62e83e,094318f6,b1ac3d07,148ab348) Z8(451450de,8548667c,c130b237,6555c85a,ca1676f9,cca0c7c5,e6911d0d,013248dd) Z8(cd93188a,0e2bbdbf,96f38221,c1059935,d416d6ed,514175b0,71941955,b0fd8585) Z8(320b8e0f,66ed7f7c,3064bc3d,c042f1bd,3c18bdaf,362f0fed,dfaa31ad,96a39d76) Z8(19f90ee8,cdee5070,3bb6281c,bfc59d48,a663bdb7,5f4df90d,50538e87,b8a16188) Z8(cacd4673,2da7b0da,ad1ac901,7bc0fd1a,bf19626e,0025eeee,99cbab0c,b9059fc2) Z8(5458b4d9,48986484,f3e1701d,2da9c918,b219c905,5c8eab1c,fdb61250,6559c18a) Z8(8ec3ee7c,e6fb7487,a62e4d85,07eebf24,44ac89d0,72a31dc0,329f4c32,5a4536a5) Z8(3347ebb8,37b1993c,36ebcdac,9616b918,fdb20335,a9e784b7,977e87d7,6c84828b) Z8(6820c3fb,88689982,1db7caa5,99988758,899c8c0c,1bdd50f9,c6067da6,628a6eb6) Z8(7ac4fecd,dc09c364,835ccaba,76e7290c,ebe2e84e,ac3fe274,6041eb5e,ffeae04a) },{ Z8(00c9f09c,8702bc5a,f2bac302,044d5061,94d26d40,945f9774,5e010f8e,308e0529) Z8(2eef9e92,a4f1b676,d1bd82f8,10f5a90d,b5b98b3e,a7e64122,f0b5ca81,2029ca83) Z8(e2b30c63,06d61c95,128ea09b,b20d3602,8889a030,6338a379,0ba873e2,3b0413c6) Z8(ec42f0f8,e709f1a7,49d1a87e,296508fa,acc722ef,dbe78f5d,d1a79e6f,a91a7113) Z8(d662bd18,409fc8d6,26e11cd0,ab9b5ab8,7cc202d5,4fb1d928,597a0aed,140052d3) Z8(6b4b462b,c4bc7de0,633e7915,db110fb5,596befd9,f58e7cbb,54d7db8f,6b838c37) Z8(347a379d,e939275a,1075a55b,2a1ea2b5,6eed7072,c189fd2a,7b9fdead,428dc9a8) Z8(0800c776,9c26414c,377c863c,a73c0139,e042d507,2eb794f2,852f2604,165c2d38) Z8(d717807e,e8063cb0,e820aba8,45702e91,ed1c8d69,9c270471,eacd3e5b,53892eb8) Z8(a010ad0f,f2f18d8a,bd015c36,533a232a,e8a19c93,eb13a4cb,d3888ae5,70a2c4ac) Z8(dfdd16c1,4db70723,0c880410,99c1a24c,5c15f3d8,b10db17d,88560b4d,515a685b) Z8(c8bc1f21,72714d62,cb3b83aa,3c9fbeb8,2ed597ba,5f923234,28db9eba,616316ba) Z8(b88aaf04,7a8d900b,0c635ff4,c35d8414,a14cec5c,8c452632,5cac2895,67bf08e2) Z8(ad0fbe66,bc7c75fd,70dc49df,be415944,a991373e,f9900e4f,85fac335,3cf6c610) Z8(d5a616a3,4d41299f,846f463b,4887f7cc,8f342d1b,04164174,19678503,96dd73f0) Z8(a6720ffd,9eafc78a,900d618a,1ab89e67,a17bea60,49f03dc0,e4308067,f347f1fa) Z8(d56ba800,89470e8c,8ac3e462,c7906e3f,d8f91c20,ebf7a5b4,af416325,a97f8639) Z8(a6c40ba0,40c67438,e53cba02,81a6de42,9ab676ed,8af0c4db,74c50fb9,06bfccbe) },{ Z8(b60366bf,6cc54c75,fe18d496,4da77ea6,49d49305,a69609ad,b8808b0e,d01938e2) Z8(7a93235b,b3de603a,8a9ace50,09f5b452,f8efc7a3,17632bf3,e97d1e1e,015ff767) Z8(53fd618a,0f859294,fad81d80,4c91c7b5,c018687c,81888164,a0d95acc,d4e55c26) Z8(6a8d45fe,7c3d0608,0cc36e83,6e74c915,11d09578,9fc64253,a5028070,21db87ec) Z8(ba839ef8,d1829e34,e23d9139,2f727d57,ea49b660,6319e47e,bbc2b2c9,50aa08e1) Z8(bbaf42ba,178d953b,ed0184fa,f6ed1a5f,7e7bba4b,9d142c01,292294e1,ce3dcbda) Z8(edb2189d,38b96160,d1c7a7c6,90264f8e,5e2b8a53,af8e2c81,80eb386b,097e7860) Z8(9fac1544,159e6f5a,e747c496,42b512a8,bd095aba,6f66e820,e761beb5,c7215616) Z8(05bccd53,7bec3faf,62dfe0fd,c6b17391,91c0d0a3,8f9d684f,aac2cc59,c32336a6) Z8(c4b3ec2d,20bb565c,5b6d9dee,a594b5c1,459436f6,5e14e633,d7684a42,efacb58f) Z8(2208eaef,9ee7e916,c7806883,5f2bb42a,5cbcb93b,7f2a2cf2,b89c60d8,d3fcaa85) Z8(1f826b1b,26179226,3a19dfd0,dcbf8f2f,980b295b,8c3c664f,15a5ba00,9e4fb8ba) Z8(504589d5,21f9009e,123733a2,d6ddfb0a,39a3e61d,85789b5d,b780ca20,e84c45cb) Z8(1b0e0e6e,40fb1f22,0caffb40,e5884c5b,d0f7e460,30cec49b,3508af73,f2daeea5) Z8(d2d8f94e,27abd448,2903f30c,7dbcb929,8186a2e7,0b393700,77340556,d46dc973) Z8(d82731ff,7448cd19,4aa14539,fd410b65,8852246a,96c0872a,fe96a5dd,58e02e86) Z8(d7615cd9,5c07a6e1,433575af,c61e54b9,ecbc6d41,fc9fdb2a,042e1cec,dc46c8f0) Z8(f83e8ba4,a3e40661,c1c37011,c18511b8,355c5beb,aeb37f08,7edca22a,ffe93856) },{ Z8(f5083898,ca7aa421,1692e5e9,99127133,f75e2bd9,aa0a6392,d4b3ec6a,152d0b5e) Z8(6475ca86,75271b17,c8a155e9,c7ba8ec1,29e58d31,07f06c39,dac1214d,fc56d0a2) Z8(bbbce99c,d26f438f,b5cad56f,39ce4e2a,1df2677a,c05d81a0,0d1f82bc,adc81084) Z8(505773d3,64c5a818,eeb34c90,2b3f2e06,1ca43ae2,cc132820,a25266d9,7da4ef8d) Z8(aa4c0517,f0c68094,b9393b06,63cdaa56,1c8bc744,39cc0483,75653b9a,c8686a43) Z8(1945ecb6,263b4452,b38a3dd4,73b7074d,3d27c37e,b7bcbac6,430be3b9,9957fe50) Z8(4b8f50a7,4b52bb13,a964462d,c7005ee5,c4ef03ed,5a8f25f6,e4443ce0,589cd340) Z8(4f25dfc6,1694b28d,2025c938,a4a28ee5,190f52d6,e1693d95,83f13e25,3817d651) Z8(d05990c9,39285fbd,0887dd02,ebb2edb3,c582c3a6,67cf9a7e,9a78f6c7,4bfe5128) Z8(b39c759d,9b856bd5,411775cf,ec3ed91d,9217b22e,970992d0,9e7d812d,6d9e6bfc) Z8(229371e9,6d8fa7c0,e446fa8f,acfee884,a450b161,5641f8f8,3ea7ebfd,b4a46f7d) Z8(5bb21d3f,aa389162,84f2d9e3,28e24647,977991e8,5e14260a,f09cc690,0bf4219f) Z8(b21e09d7,996c9e54,c16fb459,a4829b41,c639bc03,cbc848d9,d04d56b4,cbdd5f45) Z8(13178492,780be53b,0c828e9a,e150d397,4dcb40ed,bb476b78,937bb97e,e0d10695) Z8(0e8d0c2b,8f136af1,c2f4ee40,0c1f399d,2b67877b,b4f10119,0616d700,d90d3618) Z8(820b8870,aa57260b,a3f8c7f9,6c147ef4,0bedee10,f8be03bf,c88b87b6,0f568cce) Z8(2e956a62,54707381,b634a0df,4304d14f,986f637c,02c0513f,a293758b,51d78b0e) Z8(a7332c80,bcb27f61,d2358820,03e277d3,4f02b7c5,f20c232a,e163a0dd,06ffc6d5) },{ Z8(3168392f,824f6319,6a768e1a,89455c4c,49d4ba77,d90a3424,03fe5c73,6ef45fff) Z8(eef0dea2,0c67aa7c,292dee00,cf0fbd4e,bb417849,2b2c093a,1360208f,81737528) Z8(a2f551c5,fb77140d,ba6599c8,11d7107f,961c27aa,555ae8d6,960b9fa7,bac96c16) Z8(6b560476,21a3194e,61a7dc78,50ab88de,eac7ab91,7222d170,dcdf5e29,29ee04fc) Z8(8f0d8d41,35813120,38873052,fb72f092,87819ab6,373e5825,332ca43b,38a3b938) Z8(76ee2a63,e36bf7e0,306afd4e,46c366bb,1b1ace42,578bb7c4,af55c32e,e69a94b1) Z8(36584b6b,fc4fe710,c011e17a,1b90c6af,f5e65121,f602e5be,c8feee2a,a5f11bc6) Z8(93525375,03ac22a0,0ade8b16,58b2bcfb,29fad303,b9f4a00f,33501a21,646ea2a9) Z8(a274cfca,7d82b577,40863707,973c8f41,7969ae62,e00ccc2c,07337e53,6f31cd9e) Z8(5c8c707d,8af4a9f1,0f7ed350,fa0ba7fe,c3c0c72f,bcfbdc34,e8b2e34c,2234108b) Z8(b88ab5c0,6ec79dc9,6a73db02,d65b5eaf,3240346e,134302bf,6cb42e9b,8be15750) Z8(aba831fa,b05b0b6d,bd763849,c0807ff4,ae3a9a7b,e3f0ee91,6e3b8321,23e316dc) Z8(bd3bdeb5,392c946e,aef58b25,894228f9,17aac9e7,fa90632f,e8f217d3,53ce8107) Z8(e1a3577d,04dbe248,a368534a,2e7550a6,2649c69c,bcabadfe,637eef8c,6b03873e) Z8(9134d7a6,68bcddbf,882b0053,2509f977,243f98ea,13f88527,70222412,68f3b7df) Z8(e75924b5,f3f1104c,d6384f68,1b175c93,2dbfef1e,012eeb06,bbcac937,9afeb860) Z8(b2849471,f41b4606,fa909aed,3958ae98,d8b099fd,0463c8a9,5a06813c,e1bc72de) Z8(9bd85d30,80c5648e,373fe8f1,4ab4504c,5a0fbdb7,382f503a,0a074478,ffe78064) },{ Z8(99a5ff40,ed250449,91b175ba,7ce808ca,5e9c714d,5eab5fb2,c2f58fc7,b35482ea) Z8(150e2be5,9b71aa01,7aeba496,e0b916d6,624484f3,c8b87e7c,fef84e0b,30f25173) Z8(a88823df,2b88494e,078b5e46,759991fe,18f06758,1a1a777c,cb37e23c,b50895c2) Z8(433a5350,5294850f,b7b08889,d50b756b,7d799cd7,2306cb43,7a505cb0,8c9173eb) Z8(e91b8abf,ead9967c,50555741,f91647bc,94328d82,75825f60,9d83ba08,6120cdb7) Z8(5dc8a264,ca8e7c04,4871c7fe,a0715596,082a8ce2,5a56eb43,68d6432f,2dbf038e) Z8(dfb66c5f,87cd53c2,91a424c2,08f5b1d5,2e47ea89,d6cf62e5,778db7e9,a1fde7cd) Z8(26fd0e9a,999430f9,26cd65c7,5ccb9dcd,3c9ffc4a,bfebd3b2,99af36e5,aa6e7f9e) Z8(e8e8a12c,272adace,a88d7b25,95c39020,baf7b80c,52ba9ea9,9026c37a,41910935) Z8(c6d715d1,1203e36d,5e93aa68,68df2a16,f7a3443f,83a53fa6,c261cd78,e3b167c6) Z8(0ce3a657,750574c6,dc6262c4,b9a35586,e097c678,76d5f9a6,1e832085,d0ec1f75) Z8(e68a28ed,9a890b5a,2d5e3988,fbdd1960,29aa5b7c,61b4f832,9465fa96,85779941) Z8(c910720e,fb2db811,377dec5d,1bebbe3f,7a33781c,4b6cc7b2,cbcc94c6,c8475f8e) Z8(7cf89e15,eab94e2f,35833b7e,afe0d908,6462a58e,5eb1834a,2e3bb012,5e399540) Z8(ec8642e7,05a00180,61b2d1eb,947effe1,0300c3a3,5653a525,4b872d67,261941bd) Z8(057defe9,612fa5af,381c22e7,86dca66a,36132a9a,eae074ec,4ed97e7d,1de20a19) Z8(06acae3a,e8f61e64,75d6bde9,9c4f66da,6ffd0348,76bede27,9c6fc57b,4bf8b364) Z8(77c8377b,8075646b,918c1bd7,955a9c52,d7cee62d,b09cc835,5195693c,073fc07d) },{ Z8(ffb0352a,a97a36af,07793aec,ddc60323,bedc8893,3b3192a7,8418c193,72ee8e7d) Z8(04528bfb,1867c2af,aeb7fe11,2075dd47,674da3f7,dee403fe,03168e44,01d14e26) Z8(3724f526,1f663e44,21dc8e6c,c06e1c60,d62aaccf,ca8c9dc3,108d749e,7e4bf24a) Z8(ef0d3616,2b4b2e3d,671306f1,23e6722c,c3aa314d,59bf9975,a63d302c,95e698c8) Z8(fe9e52d6,1903bc0c,3511470e,a6a4a515,bad8d052,f69ef44b,e52750bf,2b1b5ba1) Z8(db298952,cac0570d,e1060394,c6af2f69,1e1d3d77,432bbaf8,5c2fbbc7,b32ff79a) Z8(cc092865,cb8f7e2d,7e4fe5eb,d8795b13,75f90d2e,a4e98d1a,f0ba5a78,f1b29487) Z8(19366f50,340fd506,aabd0a13,c81dbcd7,547492b4,81e22300,35797bac,f51a7800) Z8(aaffce9c,80cbffac,920f1664,da4dab9d,aa1fa44d,bea6d729,22a54e21,3236c571) Z8(cef026cf,d3a8b4f8,6c27be72,b86015cb,0e03a8d1,efa5cbbd,4152be9f,25324c91) Z8(cc7c3164,491d48ed,ed793ca6,8fcb181e,cccc21d4,5e8e03e7,d827c697,5c2e8ec3) Z8(0eeb8bdf,c24443b0,44a947aa,eb12320b,cbf42b9b,1501a7bc,a0506d75,71994b92) Z8(205b238e,561cb8eb,24a3fd9c,f48d0da6,79270be2,d653ad49,7eea2258,d26f15cf) Z8(7fbd7818,29dbc73c,cf2f706f,24451f1a,da786a2b,5e2c948b,571c01a1,ecdee7ca) Z8(55c08ff2,e3ca67d4,e7aab3ab,46bb434f,0c6e19aa,3916a6ce,0cb9fa02,7922119a) Z8(9586696b,0e3005bd,d82b4410,941712fe,dd979139,5ac8d1f7,ae1042d4,c3da4846) Z8(49a8f053,99e2c18d,c8e63104,1414c6d5,32ac61b1,6721bd39,87b9e915,74ab7627) Z8(7b8da3b0,8f42a7ee,fc987924,8c8185ab,c2255c97,f504d48e,1d40f96f,ffe5b873) },{ Z8(cc8afa8a,ab7b19f0,4dc42e10,b48153f3,18cd1bdf,b7416084,6759b67c,9aec99af) Z8(665478cb,353dc8d8,d9a78522,180cc22a,5a3b5459,04e5bd03,5831acec,265ec10a) Z8(463c950e,254e017a,d1a1eed0,c5a50704,4aa2d6b5,4c9974ef,c12739ad,b5c839ec) Z8(230261b6,cd3d9cf1,c7513394,845d14c6,f9e6335e,a6ed7865,5205275c,612dea0f) Z8(bcef932a,ec6c6b2b,9d157def,1b6a7548,ee7d6b74,75d48305,f39eb96a,a28c7998) Z8(20440fe3,3bd29d55,49c291c1,f9aacf1d,f8ca1e32,f625bf0f,dee6c223,a204de88) Z8(943a9d62,50f0abc3,d88dd1ee,f59eb5e9,e65c8d20,7155ea75,44361b4d,6949f210) Z8(1fbfdf0e,53bc45b5,6c294663,60c5fa6c,53e9985e,bfbcf8a6,85abed98,28769f24) Z8(8d3c926e,fdcb674e,49aa391b,4b1152d3,567a6231,ec3b422b,8a9e661f,2ae13ad9) Z8(06aa76ae,7dc3212a,456936b6,7884c959,017e8f59,e201fc39,e64b073b,ec6f9850) Z8(4c6eecb3,595f6e8d,a0283666,77c6a0ec,544bfc50,1f256417,6d006a37,b1db2887) Z8(f264ae7a,3775ef65,87e14ef7,a538203d,60b12b3e,03d32f7f,f8dd70d1,0d47b82e) Z8(ae73ef90,ccd2a182,5640e820,3588cf3a,f5e5355c,dfc34545,4c957c3e,205dcd6b) Z8(f9a9567f,db31686f,372d2831,c635315b,9660e977,40b67003,b2281c96,02b4fb0d) Z8(d55e0622,754daf29,5ea19f13,e1959f03,9c97bd76,345233c6,5884ab38,8ac56592) Z8(c2adf480,c0250371,8c9ad0a5,39f0b078,1c0fe62b,ad19a564,856db36b,66cdbdca) Z8(1348c050,c3960698,28f39bf4,8a330217,0143c678,82e781f4,ceda6eee,fc135a98) Z8(602c315e,358d5e18,cf92e53f,e11d1c70,e48e5358,780df455,c5bff727,077fb9b0) },{ Z8(c2249889,03363e8d,c216b563,aa7097bf,c23f2095,deb8649b,c7ad3b5e,000620b3) Z8(6d8ff8de,093d654a,3bbe901e,4a88b2a3,a776dee4,b83881da,0064983f,2626dfdc) Z8(e43b5380,88a0a954,e67ea023,f8a0c097,6f449d75,fbc7a82f,81e84ab1,4352371d) Z8(8b0b59ef,1c2b1527,c4894555,053ec7a9,62a9c896,b8b50b62,1d569a82,e0ccedd5) Z8(177343e6,915b2beb,f7f8e36b,917d1be4,d12ddfe8,e50405f7,c2f80eb0,cafa8e8c) Z8(87433dc2,65bc5246,49cb69e5,288629a4,126af65f,36a67be0,cae9c873,5232af1a) Z8(cfc77839,4872deb5,df522260,eb802ac6,5c132b14,80e2dba7,75d046a8,5ab94e89) Z8(dcb1e85a,663cc10b,cdb813b0,e977750c,d02e951c,e473d63b,6ac1e49c,974583e9) Z8(aced11a2,e724ce93,24b1c5cd,610af596,169611f1,c4d755d3,16e2b859,3c893f59) Z8(efc087eb,91bb54aa,814382bc,0c67f681,9cf7037d,9654525a,90f0ca8a,22d80880) Z8(730a64b0,242b02a5,4b2f0278,ac9c9e9f,96830d7e,ff226fde,3f149f2e,6a4f224d) Z8(934ab39e,db28a312,8dd94b4e,7ffeff23,eb6498b3,61bb0f09,77e1a933,d9ecd5de) Z8(b20beea8,a7284ff8,db7a4324,4777aed5,fa197128,a78f8e67,84015b38,1fded28b) Z8(0beb6869,4c149190,1850f478,bcf87632,4f045fd8,aa51dbbe,e12fb274,53da86be) Z8(bf6790bb,8ab9c0d6,e7f9c881,90e29df9,cdda1be9,cb907d5c,db91e0b7,3567279e) Z8(4ac9e39e,379487fc,7226006a,91b9f4ed,4f496f92,5cbd5e68,da6e21b4,077c5dfb) Z8(6703a645,6f35d80e,67a160b1,0dd3d997,caf13d7e,48ca1222,4a9f00bf,2edfde4a) Z8(8d72ed4c,c95d63bf,cd24476c,1c54dd30,180b6a83,4b263ea0,d508cfb8,ffe3e083) },{ Z8(d0af47f2,fff68991,0c4f4089,798d9e9d,026d4904,4cd285ea,9e9123c9,13eba9f4) Z8(20f01965,32fded1a,09f67dfe,e11720c0,f5cae49d,4ddb6257,c035386c,edb9f29a) Z8(ba205689,41f7624b,15dcc811,784ea3e1,a45be301,972c5fc1,e3106665,7142d42d) Z8(f228a918,54997f8c,99ca57ec,5ad49717,ef8f3811,782cf04f,8bf5a502,581183ce) Z8(5e2c7cde,c2b51430,671cac5a,b7771b04,bcbf732c,5af858da,e8a389bc,2e4642a5) Z8(222cd6fa,6a2fde63,5db1df9b,30b46d52,d9442711,801f9095,9102bea8,b9184a7d) Z8(6321034b,da48ac33,8ede6674,fee0f96c,a8289ecd,92cd1cd9,51bca194,618a3e4d) Z8(b89c4cd3,3c1a3263,7786cfc2,aa0f1fce,003fc678,3be611b8,d7ab2b24,2aa15d8b) Z8(e739dcd2,2f90cf28,0267fbcd,30422e44,0140c51b,d73da67d,8a59d886,426b19d2) Z8(bbf70664,b49aaf4a,62e3cb4a,20319960,a6dea411,2d463c91,cbf80414,e8e8d7f7) Z8(d631f996,1ca60f9e,46db5a26,50ae5f8b,7ee74da1,4eb3c065,7aa2dbf2,64ea2ff7) Z8(ba994626,b3722d67,91ea6a1f,d962515c,64561234,367a6190,8a75f681,37e9ec59) Z8(60a66da3,061686fe,c701fced,b4c85e67,e92dddfe,08f1e6ab,797493bd,ee04d7a2) Z8(99a6f3be,1c59f59f,8309a279,94ce05b5,f0ad121d,7aa1215a,ec334796,52b639df) Z8(0981786e,905d83dc,91508790,b06e2087,97ad3716,63b5eee0,c4fa5bb2,bb92ec09) Z8(1d843143,dd2c810c,45359f2c,414e05db,a37dfac8,ab989866,24535faa,0426ac56) Z8(a9121bef,c59edbb2,72e0ac36,27df521a,c32d5cf6,58971e70,47da7ebd,0d02503c) Z8(73905803,1680c4b6,c4de8419,effa116c,ba3e6603,63c7d169,3e5018b0,07bfb26c) },{ Z8(deec5c26,db8ed1a7,05bd7d1d,4fd38b06,3367b1eb,05e2570e,b14207d3,1d07a4ac) Z8(d11a1dcd,c77989c5,9bed1249,05ecb233,f533352b,eba8b51f,973a69bb,f9a79603) Z8(0a204b77,919178b8,2134b24a,68e08353,8c3da985,e1fbeda1,d7816d8c,684e6a74) Z8(b80d3c1a,64401998,63d32ead,2ac2f24e,28217c8e,f21317c2,6bc3ee14,2098ed29) Z8(a5830a59,0ad4e504,4d25ed24,3440e93c,fffaf097,1492a6ed,862f915e,63b7e836) Z8(afa228b0,49bd1db7,d146c767,3d40ad9e,bf64c3b6,3bce64f3,e7b0bea6,d2b29a4d) Z8(0603cc19,9783ab12,ab8d53f6,036259ab,30a24b86,32a47654,cb202c34,a5a39278) Z8(cab13889,531ec96d,dccbea36,3cf9fa24,4e2597fd,35cf8e51,709a5e8a,28fdb81a) Z8(8d44b046,3053b695,7157ea17,0578864a,27a0fcf9,e76d9305,8bbc6f44,bcdece62) Z8(23b24595,fb93441e,426d2535,de660905,d51df433,1c11b677,c0288110,e0767420) Z8(e5455b20,c705ae7c,b90a24b4,32bd9ef9,4e3ddd65,63921798,4cdeb18a,da61b9e2) Z8(45bb25a6,ea960a01,542e6c62,6250c141,beffe55a,e07d8b20,1d22f180,8fb3ee17) Z8(c849557d,4da47aba,8a81ae40,465492db,81ae1a10,e9e4358c,8e3fed91,46560d4f) Z8(e21b660b,d8da90c0,6a3661cd,ad71cc57,61ba637f,8769953d,fad12744,b2f6c867) Z8(caa48e0d,e9287446,0798d8a0,14f74eb5,5ef39dcc,9f5ff1e1,c9e99daa,9ea35b57) Z8(34529182,f6f71374,81b29466,4fc50765,12fe4f23,31ee72a0,adb91867,aef63b1e) Z8(6d843aa5,68dad114,fa7dd2a0,2207284f,50bffa10,d862be6f,36f2b1d6,37bf5acb) Z8(28028625,d4aeb2b1,b86cbdad,1e98172a,073b41d4,693e6ead,4eddbbad,ffe1f896) }}; arb-2.22.1/arb/sin_cos_taylor_naive.c000066400000000000000000000037321417376376500175130ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_sin_cos_taylor_naive(mp_ptr ysin, mp_ptr ycos, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N) { ulong k; mp_ptr s, s2, t, u, v; mp_size_t nn = xn + 1; if (N == 0) { flint_mpn_zero(ysin, xn); flint_mpn_zero(ycos, xn); error[0] = 0; return; } s = flint_malloc(sizeof(mp_limb_t) * (nn + 1)); s2 = flint_malloc(sizeof(mp_limb_t) * (nn + 1)); t = flint_malloc(sizeof(mp_limb_t) * nn); v = flint_malloc(sizeof(mp_limb_t) * nn); u = flint_malloc(sizeof(mp_limb_t) * 2 * nn); /* s = 1 */ flint_mpn_zero(s, nn); s[nn] = 1; /* s2 = 0 */ flint_mpn_zero(s2, nn + 1); /* t = v = x */ flint_mpn_zero(t, nn); flint_mpn_copyi(t + 1, x, xn); flint_mpn_copyi(v, t, nn); for (k = 1; k < 2 * N; k++) { if (k % 4 == 0) s[nn] += mpn_add_n(s, s, t, nn); else if (k % 4 == 1) s2[nn] += mpn_add_n(s2, s2, t, nn); else if (k % 4 == 2) s[nn] -= mpn_sub_n(s, s, t, nn); else s2[nn] -= mpn_sub_n(s2, s2, t, nn); /* t = t * x / (k + 1) */ mpn_mul_n(u, t, v, nn); flint_mpn_copyi(t, u + nn, nn); mpn_divrem_1(t, 0, t, nn, k + 1); } if (s[nn] != 0) { flint_mpn_store(ycos, xn, LIMB_ONES); flint_mpn_copyi(ysin, s2 + 1, xn); } else { flint_mpn_copyi(ycos, s + 1, xn); flint_mpn_copyi(ysin, s2 + 1, xn); } error[0] = 2; flint_free(s); flint_free(s2); flint_free(t); flint_free(u); flint_free(v); } arb-2.22.1/arb/sin_cos_taylor_rs.c000066400000000000000000000116501417376376500170330ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* See verify_taylor.py for code to generate tables and proof of correctness */ #define TMP_ALLOC_LIMBS(size) TMP_ALLOC((size) * sizeof(mp_limb_t)) #define FACTORIAL_TAB_SIZE 288 ARB_DLL extern const mp_limb_t factorial_tab_numer[FACTORIAL_TAB_SIZE]; ARB_DLL extern const mp_limb_t factorial_tab_denom[FACTORIAL_TAB_SIZE]; void _arb_sin_cos_taylor_rs(mp_ptr ysin, mp_ptr ycos, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int sinonly, int alternating) { mp_ptr s, t, xpow; mp_limb_t new_denom, old_denom, c; slong power, k, m; int cosorsin; TMP_INIT; TMP_START; if (2 * N >= FACTORIAL_TAB_SIZE - 1) { flint_printf("_arb_sin_cos_taylor_rs: N too large!\n"); flint_abort(); } if (N <= 1) { if (N == 0) { flint_mpn_zero(ysin, xn); if (!sinonly) flint_mpn_zero(ycos, xn); error[0] = 0; } else if (N == 1) { flint_mpn_copyi(ysin, x, xn); if (!sinonly) flint_mpn_store(ycos, xn, LIMB_ONES); error[0] = 1; } } else { /* Choose m ~= sqrt(num_terms) (m must be even, >= 2) */ m = 2; while (m * m < N) m += 2; /* todo: merge allocations */ xpow = TMP_ALLOC_LIMBS((m + 1) * xn); s = TMP_ALLOC_LIMBS(xn + 2); t = TMP_ALLOC_LIMBS(2 * xn + 2); /* todo: 1 limb too much? */ /* higher index ---> */ /* | ---xn--- | */ /* xpow = | | x^m | x^(m-1) | ... | x^2 | x | */ #define XPOW_WRITE(__k) (xpow + (m - (__k)) * xn) #define XPOW_READ(__k) (xpow + (m - (__k) + 1) * xn) mpn_sqr(XPOW_WRITE(1), x, xn); mpn_sqr(XPOW_WRITE(2), XPOW_READ(1), xn); for (k = 4; k <= m; k += 2) { mpn_mul_n(XPOW_WRITE(k - 1), XPOW_READ(k / 2), XPOW_READ(k / 2 - 1), xn); mpn_sqr(XPOW_WRITE(k), XPOW_READ(k / 2), xn); } for (cosorsin = sinonly; cosorsin < 2; cosorsin++) { flint_mpn_zero(s, xn + 1); /* todo: skip one nonscalar multiplication (use x^m) when starting on x^0 */ power = (N - 1) % m; for (k = N - 1; k >= 0; k--) { c = factorial_tab_numer[2 * k + cosorsin]; new_denom = factorial_tab_denom[2 * k + cosorsin]; old_denom = factorial_tab_denom[2 * k + cosorsin + 2]; /* change denominators */ if (new_denom != old_denom && k < N - 1) { if (alternating && (k % 2 == 0)) s[xn] += old_denom; mpn_divrem_1(s, 0, s, xn + 1, old_denom); if (alternating && (k % 2 == 0)) s[xn] -= 1; } if (power == 0) { /* add c * x^0 -- only top limb is affected */ if (alternating & k) s[xn] -= c; else s[xn] += c; /* Outer polynomial evaluation: multiply by x^m */ if (k != 0) { mpn_mul(t, s, xn + 1, XPOW_READ(m), xn); flint_mpn_copyi(s, t + xn, xn + 1); } power = m - 1; } else { if (alternating & k) s[xn] -= mpn_submul_1(s, XPOW_READ(power), xn, c); else s[xn] += mpn_addmul_1(s, XPOW_READ(power), xn, c); power--; } } /* finally divide by denominator */ if (cosorsin == 0) { mpn_divrem_1(t, 0, s, xn + 1, factorial_tab_denom[0]); /* perturb down to a number < 1 if necessary. note that this does not invalidate the error bound: 1 - ulp is either 1 ulp too small or must be closer to the exact value */ if (t[xn] == 0) flint_mpn_copyi(ycos, t, xn); else flint_mpn_store(ycos, xn, LIMB_ONES); } else { mpn_divrem_1(s, 0, s, xn + 1, factorial_tab_denom[0]); mpn_mul(t, s, xn + 1, x, xn); flint_mpn_copyi(ysin, t + xn, xn); } } /* error bound (ulp) */ error[0] = 2; } TMP_END; } arb-2.22.1/arb/sin_cos_wide.c000066400000000000000000000146361417376376500157540ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define ONE_OVER_PI 0.31830988618379067154 #define PI 3.1415926535897932385 /* We use doubles in a way that keeps the final error <= EPSILON. */ #define EPSILON ldexp(1.0, -30) /* For |x| <= 2^MAX_EXP, doubles can be used directly for quadrant reduction. Note: 2^MAX_EXP must also fit in an int. */ #define MAX_EXP 20 /* Lookup tables, steps of 1/16. */ static const double sin_tab[] = { 0.0,0.062459317842380198585,0.12467473338522768996, 0.18640329676226988455,0.24740395925452292960,0.30743851458038085067, 0.36627252908604756137,0.42367625720393801036,0.47942553860420300027, 0.53330267353602017333,0.58509727294046215481,0.63460708001526929685, 0.68163876002333416673,0.72600865526071254966,0.76754350223602703963, 0.80608110826069299518,0.84147098480789650665,0.87357493516707112023, 0.90226759409909516292,0.92743691738486767172,0.94898461935558621435, 0.96682655669618022997,0.98089305702315569609,0.99112919095376166988, 0.99749498660405443094,0.99996558567824887530, }; static const double cos_tab[] = { 1.0,0.99804751070009914963,0.99219766722932905315, 0.98247331310125525749,0.96891242171064478414,0.95156794804817220215, 0.93050762191231429115,0.90581368342593642074,0.87758256189037271612, 0.84592449923106795446,0.81096311950521790219,0.77283494615247154481, 0.73168886887382088631,0.68768556222050484451,0.64099685816332513036, 0.59180507509247750546,0.54030230586813971740,0.48668966770196333087, 0.43117651679866617655,0.37397963082453319229,0.31532236239526866545, 0.25543376688881169791,0.19454770798898718445,0.13290194445282520566, 0.070737201667702910088,0.0082962316238583774779, }; /* Computes sin(a) and cos(a) and also sets q to the (approximate) quadrant of a. The absolute error of the straightforward algorithm below can be bounded as the error in the mod pi/2 reduction plus the negligible contribution (O(1) * 2^-53) of all other steps. Since |a| < 2^20 by assumption, we have 3 bits of margin for the final error bound of 2^-30 for the entire algorithm. */ static void sin_cos(double * sin_a, double * cos_a, int * q, double a) { double as, ac, t, b, bs, bc, v; int i, qa; *q = qa = floor(a * (2.0 * ONE_OVER_PI)); a = a - qa * (0.5 * PI); if (a < 0.0) a = 0.0; if (a > 0.5 * PI) a = 0.5 * PI; i = a * 16.0; if (i < 0 || i > 25) flint_abort(); as = sin_tab[i]; ac = cos_tab[i]; b = a - i * (1 / 16.0); v = b * b; /* Just use the Taylor series. */ bs = 2.7557319223985890653e-6 * v; bs = (-0.0001984126984126984127 + bs) * v; bs = (0.0083333333333333333333 + bs) * v; bs = (-0.16666666666666666667 + bs) * v; bs = (1.0 + bs) * b; bc = -2.7557319223985890653e-7 * v; bc = (0.000024801587301587301587 + bc) * v; bc = (-0.0013888888888888888889 + bc) * v; bc = (0.041666666666666666667 + bc) * v; bc = (-0.5 + bc) * v; bc = 1.0 + bc; t = as * bc + ac * bs; ac = ac * bc - as * bs; as = t; if ((qa & 3) == 0) { *sin_a = as; *cos_a = ac; } else if ((qa & 3) == 1) { *sin_a = ac; *cos_a = -as; } else if ((qa & 3) == 2) { *sin_a = -as; *cos_a = -ac; } else { *sin_a = -ac; *cos_a = as; } } /* FIXME: this is the bottleneck -- an mpn version would be better */ static void _arb_mod_2pi(arb_t x, slong mag) { arb_t t; arf_t q; arf_init(q); arb_init(t); arb_const_pi(t, mag + 53); arb_mul_2exp_si(t, t, 1); arf_div(q, arb_midref(x), arb_midref(t), mag + 10, ARF_RND_NEAR); arf_floor(q, q); arb_submul_arf(x, t, q, 53); arf_clear(q); arb_clear(t); } void _arb_sin_cos_wide(arb_t sinx, arb_t cosx, const arf_t xmid, const mag_t xrad, slong prec) { double m, a, b, r, cos_min, cos_max, sin_min, sin_max; double as, ac, bs, bc; int i, qa, qb; slong mag; mag = arf_abs_bound_lt_2exp_si(xmid); if (mag > FLINT_MAX(65536, 4 * prec) || mag_cmp_2exp_si(xrad, 3) >= 0) { if (sinx != NULL) arb_zero_pm_one(sinx); if (cosx != NULL) arb_zero_pm_one(cosx); return; } else if (mag <= MAX_EXP) { m = arf_get_d(xmid, ARF_RND_DOWN); r = mag_get_d(xrad); } else { arb_t t; arb_init(t); arf_set(arb_midref(t), xmid); mag_set(arb_radref(t), xrad); _arb_mod_2pi(t, mag); /* this should not happen */ if (arf_cmpabs_2exp_si(arb_midref(t), 5) > 0 || mag_cmp_2exp_si(arb_radref(t), 5) > 0) { flint_printf("unexpected precision loss in sin_cos_wide\n"); if (sinx != NULL) arb_zero_pm_one(sinx); if (cosx != NULL) arb_zero_pm_one(cosx); arb_clear(t); return; } m = arf_get_d(arb_midref(t), ARF_RND_DOWN); r = mag_get_d(arb_radref(t)); arb_clear(t); } a = m - r; b = m + r; sin_cos(&as, &ac, &qa, a); sin_cos(&bs, &bc, &qb, b); sin_min = FLINT_MIN(as, bs); sin_max = FLINT_MAX(as, bs); cos_min = FLINT_MIN(ac, bc); cos_max = FLINT_MAX(ac, bc); /* Handle the quadrant crossings. */ for (i = qa; i < qb; i++) { if ((i & 3) == 1) cos_min = -1.0; if ((i & 3) == 3) cos_max = 1.0; if ((i & 3) == 2) sin_min = -1.0; if ((i & 3) == 0) sin_max = 1.0; } if (sinx != NULL) { a = (sin_max + sin_min) * 0.5; r = (sin_max - sin_min) * 0.5 + EPSILON; arf_set_d(arb_midref(sinx), a); mag_set_d(arb_radref(sinx), r); arb_set_round(sinx, sinx, prec); } if (cosx != NULL) { a = (cos_max + cos_min) * 0.5; r = (cos_max - cos_min) * 0.5 + EPSILON; arf_set_d(arb_midref(cosx), a); mag_set_d(arb_radref(cosx), r); arb_set_round(cosx, cosx, prec); } } void arb_sin_cos_wide(arb_t sinx, arb_t cosx, const arb_t x, slong prec) { _arb_sin_cos_wide(sinx, cosx, arb_midref(x), arb_radref(x), prec); } arb-2.22.1/arb/sinc.c000066400000000000000000000037621417376376500142410ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_sinc_derivative_bound(mag_t d, const arb_t x) { /* |f'(x)| < min(arb_get_mag(x), 1) / 2 */ mag_t r, one; mag_init(r); mag_init(one); arb_get_mag(r, x); mag_one(one); mag_min(d, r, one); mag_mul_2exp_si(d, d, -1); mag_clear(r); mag_clear(one); } void _arb_sinc_direct(arb_t z, const arb_t x, slong prec) { /* z = sin(x) / x */ slong wp; arb_t y; wp = prec + 2; arb_init(y); arb_sin(y, x, wp); arb_div(z, y, x, prec); arb_clear(y); } void arb_sinc(arb_t z, const arb_t x, slong prec) { mag_t c, r; mag_init(c); mag_init(r); mag_set_ui_2exp_si(c, 5, -1); arb_get_mag_lower(r, x); if (mag_cmp(c, r) < 0) { /* x is not near the origin */ _arb_sinc_direct(z, x, prec); } else if (mag_cmp_2exp_si(arb_radref(x), 1) < 0) { /* determine error magnitude using the derivative bound */ if (arb_is_exact(x)) { mag_zero(c); } else { _arb_sinc_derivative_bound(r, x); mag_mul(c, arb_radref(x), r); } /* evaluate sinc at the midpoint of x */ if (arf_is_zero(arb_midref(x))) { arb_one(z); } else { arb_get_mid_arb(z, x); _arb_sinc_direct(z, z, prec); } /* add the error */ mag_add(arb_radref(z), arb_radref(z), c); } else { /* x has a large radius and includes points near the origin */ arf_zero(arb_midref(z)); mag_one(arb_radref(z)); } mag_clear(c); mag_clear(r); } arb-2.22.1/arb/sinc_pi.c000066400000000000000000000024161417376376500147240ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sinc_pi(arb_t res, const arb_t x, slong prec) { mag_t m; arb_t t; if (!arb_is_finite(x)) { if (arf_is_nan(arb_midref(x))) arb_indeterminate(res); else if (arb_contains_zero(x)) arb_zero_pm_one(res); else arb_zero(res); return; } if (arb_is_int(x)) { if (arb_is_zero(x)) arb_one(res); else arb_zero(res); return; } mag_init(m); arb_init(t); arb_get_mag_lower(m, x); if (mag_cmp_2exp_si(m, -1) > 0) { arb_const_pi(t, prec + 4); arb_mul(t, t, x, prec + 4); arb_sin_pi(res, x, prec + 4); arb_div(res, res, t, prec); } else { arb_const_pi(t, prec + 4); arb_mul(t, t, x, prec + 4); arb_sinc(res, t, prec); } mag_clear(m); arb_clear(t); } arb-2.22.1/arb/sinh_cosh.c000066400000000000000000000123141417376376500152530ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sinh_cosh_wide(arb_t s, arb_t c, const arb_t x, slong prec) { mag_t t, u, v, w; mag_init(t); mag_init(u); mag_init(v); mag_init(w); arb_get_mag_lower(t, x); arb_get_mag(u, x); if (c != NULL) { mag_cosh_lower(v, t); mag_cosh(w, u); } if (s != NULL) { if (mag_is_zero(t)) { arf_get_mag_lower(t, arb_midref(x)); mag_sub(t, arb_radref(x), t); mag_sinh(t, t); mag_sinh(u, u); if (arf_sgn(arb_midref(x)) > 0) arb_set_interval_neg_pos_mag(s, t, u, prec); else arb_set_interval_neg_pos_mag(s, u, t, prec); } else { mag_sinh_lower(t, t); mag_sinh(u, u); if (arf_sgn(arb_midref(x)) > 0) { arb_set_interval_mag(s, t, u, prec); } else { arb_set_interval_mag(s, t, u, prec); arb_neg(s, s); } } } if (c != NULL) arb_set_interval_mag(c, v, w, prec); mag_clear(t); mag_clear(u); mag_clear(v); mag_clear(w); } void arb_cosh(arb_t c, const arb_t x, slong prec) { if (arb_is_zero(x)) { arb_one(c); } else if (!arb_is_finite(x)) { if (arf_is_nan(arb_midref(x))) arb_indeterminate(c); else if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) arb_pos_inf(c); else arb_zero_pm_inf(c); } else if (mag_cmp_2exp_si(arb_radref(x), -20) > 0 && mag_cmp_2exp_si(arb_radref(x), 10) < 0 && arf_cmpabs_2exp_si(arb_midref(x), 4) < 0) { arb_sinh_cosh_wide(NULL, c, x, prec); } else { arb_t t; slong wp = prec + 4; /* todo: close to 0, could use derivative to bound propagated error more tightly */ arb_init(t); arb_exp_invexp(c, t, x, wp); arb_add(c, c, t, prec); arb_mul_2exp_si(c, c, -1); arb_clear(t); } } void arb_sinh(arb_t s, const arb_t x, slong prec) { if (arb_is_zero(x)) { arb_zero(s); } else if (!arb_is_finite(x)) { if (arf_is_nan(arb_midref(x))) arb_indeterminate(s); else if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) { arf_set(arb_midref(s), arb_midref(x)); mag_zero(arb_radref(s)); } else arb_zero_pm_inf(s); } else if (mag_cmp_2exp_si(arb_radref(x), -20) > 0 && mag_cmp_2exp_si(arb_radref(x), 10) < 0 && arf_cmpabs_2exp_si(arb_midref(x), 4) < 0) { /* for sinh this is not more accurate, but slightly faster */ arb_sinh_cosh_wide(s, NULL, x, prec); } else { arb_t t; slong wp = prec + 4; arb_init(t); if (arf_cmpabs_2exp_si(arb_midref(x), -1) <= 0 && mag_cmp_2exp_si(arb_radref(x), -4) <= 0) { arb_expm1(s, x, wp); arb_add_ui(t, s, 1, wp); arb_div(t, s, t, wp); arb_add(s, s, t, prec); } else { arb_exp_invexp(s, t, x, wp); arb_sub(s, s, t, prec); } arb_mul_2exp_si(s, s, -1); arb_clear(t); } } void arb_sinh_cosh(arb_t s, arb_t c, const arb_t x, slong prec) { if (arb_is_zero(x)) { arb_zero(s); arb_one(c); } else if (!arb_is_finite(x)) { if (arf_is_nan(arb_midref(x))) { arb_indeterminate(s); arb_indeterminate(c); } else if (arf_is_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) { arf_set(arb_midref(s), arb_midref(x)); mag_zero(arb_radref(s)); arf_abs(arb_midref(c), arb_midref(s)); mag_zero(arb_radref(c)); } else { arb_zero_pm_inf(s); arb_zero_pm_inf(c); } } else if (mag_cmp_2exp_si(arb_radref(x), -20) > 0 && mag_cmp_2exp_si(arb_radref(x), 10) < 0 && arf_cmpabs_2exp_si(arb_midref(x), 4) < 0) { arb_sinh_cosh_wide(s, c, x, prec); } else { arb_t t; slong wp = prec + 4; arb_init(t); if (arf_cmpabs_2exp_si(arb_midref(x), -1) <= 0 && mag_cmp_2exp_si(arb_radref(x), -4) <= 0) { arb_expm1(s, x, wp); arb_add_ui(t, s, 1, wp); arb_inv(c, t, wp); arb_addmul(s, s, c, prec); arb_add(c, c, t, prec); } else { arb_exp_invexp(c, t, x, wp); arb_sub(s, c, t, prec); arb_add(c, c, t, prec); } arb_mul_2exp_si(s, s, -1); arb_mul_2exp_si(c, c, -1); arb_clear(t); } } arb-2.22.1/arb/sqrt.c000066400000000000000000000105431417376376500142710ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sqrt_ui(arb_t z, ulong x, slong prec) { arf_t t; arf_init_set_ui(t, x); /* no need to free */ arb_sqrt_arf(z, t, prec); } void arb_sqrt_fmpz(arb_t z, const fmpz_t x, slong prec) { arf_t t; arf_init(t); arf_set_fmpz(t, x); arb_sqrt_arf(z, t, prec); arf_clear(t); } void arb_sqrt_arf(arb_t z, const arf_t x, slong prec) { if (arf_sgn(x) < 0 || arf_is_nan(x)) { arb_indeterminate(z); } else { int inexact; inexact = arf_sqrt(arb_midref(z), x, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); else mag_zero(arb_radref(z)); } } void arb_sqrt(arb_t z, const arb_t x, slong prec) { mag_t rx, zr; int inexact; if (mag_is_zero(arb_radref(x))) { arb_sqrt_arf(z, arb_midref(x), prec); } else if (arf_is_special(arb_midref(x)) || arf_sgn(arb_midref(x)) < 0 || mag_is_inf(arb_radref(x))) { if (arf_is_pos_inf(arb_midref(x)) && mag_is_finite(arb_radref(x))) arb_sqrt_arf(z, arb_midref(x), prec); else arb_indeterminate(z); } else /* now both mid and rad are non-special values, mid > 0 */ { slong acc; acc = _fmpz_sub_small(ARF_EXPREF(arb_midref(x)), MAG_EXPREF(arb_radref(x))); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); if (acc < 0) { arb_indeterminate(z); } else if (acc <= 20) { mag_t t, u; mag_init(t); mag_init(u); arb_get_mag_lower(t, x); if (mag_is_zero(t) && arb_contains_negative(x)) { arb_indeterminate(z); } else { arb_get_mag(u, x); mag_sqrt_lower(t, t); mag_sqrt(u, u); arb_set_interval_mag(z, t, u, prec); } mag_clear(t); mag_clear(u); } else if (ARB_IS_LAGOM(x)) /* small exponents, acc *and* prec >= 20 */ { mag_t t; mag_init(t); /* no need to free */ inexact = arf_sqrt(arb_midref(z), arb_midref(x), prec, ARB_RND); /* sqrt(x) - sqrt(x-r) <= 0.5 * r * rsqrt(x-r) */ /* we have rsqrt(x-r) ~= 1/sqrt(x) */ arf_get_mag_lower(t, arb_midref(z)); /* note: we need to write rad(z) first to use fast_mul later */ mag_div(arb_radref(z), arb_radref(x), t); /* We are guaranteed to have acc and prec >= 20. */ /* 0.5 + eps corrects for errors */ MAG_MAN(t) = MAG_ONE_HALF + (MAG_ONE_HALF >> 16); MAG_EXP(t) = 0; mag_fast_mul(arb_radref(z), arb_radref(z), t); if (inexact) arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else { mag_init(zr); mag_init(rx); /* rx = upper bound for r / x */ arf_get_mag_lower(rx, arb_midref(x)); mag_div(rx, arb_radref(x), rx); inexact = arf_sqrt(arb_midref(z), arb_midref(x), prec, ARB_RND); /* zr = upper bound for sqrt(x) */ arf_get_mag(zr, arb_midref(z)); if (inexact) arf_mag_add_ulp(zr, zr, arb_midref(z), prec); /* propagated error: sqrt(x) - sqrt(x-r) = sqrt(x) * [1 - sqrt(1 - r/x)] <= sqrt(x) * 0.5 * (rx + rx^2) */ mag_addmul(rx, rx, rx); mag_mul(zr, zr, rx); mag_mul_2exp_si(zr, zr, -1); /* add the rounding error */ if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_swap(arb_radref(z), zr); mag_clear(zr); mag_clear(rx); } } } arb-2.22.1/arb/sqrt1pm1.c000066400000000000000000000030051417376376500147630ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void arb_sqrt1pm1_tiny(arb_t r, const arb_t z, slong prec) { mag_t b, c; arb_t t; mag_init(b); mag_init(c); arb_init(t); /* if |z| < 1, then |(sqrt(1+z)-1) - (z/2-z^2/8)| <= |z|^3/(1-|z|)/16 */ arb_get_mag(b, z); mag_one(c); mag_sub_lower(c, c, b); mag_pow_ui(b, b, 3); mag_div(b, b, c); mag_mul_2exp_si(b, b, -4); arb_mul(t, z, z, prec); arb_mul_2exp_si(t, t, -2); arb_sub(r, z, t, prec); arb_mul_2exp_si(r, r, -1); if (mag_is_finite(b)) arb_add_error_mag(r, b); else arb_indeterminate(r); mag_clear(b); mag_clear(c); arb_clear(t); } void arb_sqrt1pm1(arb_t r, const arb_t z, slong prec) { slong magz, wp; if (arb_is_zero(z)) { arb_zero(r); return; } magz = arf_abs_bound_lt_2exp_si(arb_midref(z)); if (magz < -prec) { arb_sqrt1pm1_tiny(r, z, prec); } else { if (magz < 0) wp = prec + (-magz) + 4; else wp = prec + 4; arb_add_ui(r, z, 1, wp); arb_sqrt(r, r, wp); arb_sub_ui(r, r, 1, wp); } } arb-2.22.1/arb/sqrtpos.c000066400000000000000000000023101417376376500150040ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sqrtpos(arb_t z, const arb_t x, slong prec) { if (!arb_is_finite(x)) { if (mag_is_zero(arb_radref(x)) && arf_is_pos_inf(arb_midref(x))) arb_pos_inf(z); else arb_zero_pm_inf(z); } else if (arb_contains_nonpositive(x)) { arf_t t; arf_init(t); arf_set_mag(t, arb_radref(x)); arf_add(t, arb_midref(x), t, MAG_BITS, ARF_RND_CEIL); if (arf_sgn(t) <= 0) { arb_zero(z); } else { arf_sqrt(t, t, MAG_BITS, ARF_RND_CEIL); arf_mul_2exp_si(t, t, -1); arf_set(arb_midref(z), t); arf_get_mag(arb_radref(z), t); } arf_clear(t); } else { arb_sqrt(z, x, prec); } arb_nonnegative_part(z, z); } arb-2.22.1/arb/sub.c000066400000000000000000000036541417376376500140760ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sub(arb_t z, const arb_t x, const arb_t y, slong prec) { int inexact; inexact = arf_sub(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); mag_add(arb_radref(z), arb_radref(x), arb_radref(y)); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } void arb_sub_arf(arb_t z, const arb_t x, const arf_t y, slong prec) { int inexact; inexact = arf_sub(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } void arb_sub_ui(arb_t z, const arb_t x, ulong y, slong prec) { int inexact; inexact = arf_sub_ui(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } void arb_sub_si(arb_t z, const arb_t x, slong y, slong prec) { int inexact; inexact = arf_sub_si(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } void arb_sub_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) { int inexact; inexact = arf_sub_fmpz(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); else mag_set(arb_radref(z), arb_radref(x)); } arb-2.22.1/arb/submul.c000066400000000000000000000070151417376376500146070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_submul_arf(arb_t z, const arb_t x, const arf_t y, slong prec) { mag_t ym; int inexact; if (arb_is_exact(x)) { inexact = arf_submul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else if (ARB_IS_LAGOM(x) && ARF_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(ym, y); mag_fast_addmul(arb_radref(z), ym, arb_radref(x)); inexact = arf_submul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else { mag_init_set_arf(ym, y); mag_addmul(arb_radref(z), ym, arb_radref(x)); inexact = arf_submul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); mag_clear(ym); } } void arb_submul(arb_t z, const arb_t x, const arb_t y, slong prec) { mag_t zr, xm, ym; int inexact; if (arb_is_exact(y)) { arb_submul_arf(z, x, arb_midref(y), prec); } else if (arb_is_exact(x)) { arb_submul_arf(z, y, arb_midref(x), prec); } else if (ARB_IS_LAGOM(x) && ARB_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(xm, arb_midref(x)); mag_fast_init_set_arf(ym, arb_midref(y)); mag_fast_init_set(zr, arb_radref(z)); mag_fast_addmul(zr, xm, arb_radref(y)); mag_fast_addmul(zr, ym, arb_radref(x)); mag_fast_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_submul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARF_RND_DOWN); if (inexact) arf_mag_fast_add_ulp(zr, zr, arb_midref(z), prec); *arb_radref(z) = *zr; } else { mag_init_set_arf(xm, arb_midref(x)); mag_init_set_arf(ym, arb_midref(y)); mag_init_set(zr, arb_radref(z)); mag_addmul(zr, xm, arb_radref(y)); mag_addmul(zr, ym, arb_radref(x)); mag_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_submul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARF_RND_DOWN); if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_set(arb_radref(z), zr); mag_clear(zr); mag_clear(xm); mag_clear(ym); } } void arb_submul_si(arb_t z, const arb_t x, slong y, slong prec) { arf_t t; arf_init_set_si(t, y); /* no need to free */ arb_submul_arf(z, x, t, prec); } void arb_submul_ui(arb_t z, const arb_t x, ulong y, slong prec) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ arb_submul_arf(z, x, t, prec); } void arb_submul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) { arf_t t; if (!COEFF_IS_MPZ(*y)) { arf_init_set_si(t, *y); /* no need to free */ arb_submul_arf(z, x, t, prec); } else { arf_init(t); arf_set_fmpz(t, y); arb_submul_arf(z, x, t, prec); arf_clear(t); } } arb-2.22.1/arb/tan.c000066400000000000000000000010641417376376500140600ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_tan(arb_t y, const arb_t x, slong prec) { arb_t u; arb_init(u); arb_sin_cos(y, u, x, prec + 4); arb_div(y, y, u, prec); arb_clear(u); } arb-2.22.1/arb/tan_pi.c000066400000000000000000000014771417376376500145600ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_tan_pi(arb_t y, const arb_t x, slong prec) { if (!arb_is_finite(x)) { arb_indeterminate(y); } else if (arb_is_int_2exp_si(x, -1)) { if (arb_is_int(x)) arb_zero(y); else arb_indeterminate(y); } else { arb_t u; arb_init(u); arb_sin_cos_pi(y, u, x, prec + 4); arb_div(y, y, u, prec); arb_clear(u); } } arb-2.22.1/arb/tanh.c000066400000000000000000000022221417376376500142250ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_tanh(arb_t y, const arb_t x, slong prec) { arb_t t, u; int sign = arf_sgn(arb_midref(x)) < 0; arb_init(t); arb_init(u); arb_mul_2exp_si(t, x, 1); if (!sign) arb_neg(t, t); if (arf_cmpabs_2exp_si(arb_midref(x), 1) > 0) { /* tanh(x) = 1 - 2 exp(-2x) / (1 + exp(-2x)) */ arb_exp(t, t, prec + 4); arb_add_ui(u, t, 1, prec + 4); arb_div(y, t, u, prec + 4); arb_mul_2exp_si(y, y, 1); arb_sub_ui(y, y, 1, prec); } else { /* tanh(x) = (exp(2x) - 1) / (exp(2x) + 1) */ arb_expm1(t, t, prec + 4); arb_add_ui(y, t, 2, prec + 4); arb_div(y, t, y, prec); } if (!sign) arb_neg(y, y); arb_clear(t); arb_clear(u); } arb-2.22.1/arb/test/000077500000000000000000000000001417376376500141105ustar00rootroot00000000000000arb-2.22.1/arb/test/t-acos.c000066400000000000000000000057121417376376500154470ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("acos...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_acos(t, t, MPFR_RNDN); arb_acos(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_printd(a, 100); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 100); flint_printf("\n\n"); flint_abort(); } arb_acos(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* check large arguments */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 100); arb_acos(b, a, prec1); arb_acos(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check sin(asin(x)) = x */ arb_cos(c, b, prec1); if (!arb_contains(c, a)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-acosh.c000066400000000000000000000045131417376376500156150ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("acosh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_acosh(a, x, prec1); arb_acosh(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check cosh(acosh(x)) = x */ arb_cosh(b, b, prec1); if (!arb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_acosh(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-add.c000066400000000000000000000105061417376376500152470ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("add...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t x, y, z; arb_init(a); arb_init(b); arb_init(c); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_add(c, a, b, 2 + n_randint(state, 200)); fmpq_add(z, x, y); if (!arb_contains_fmpq(c, z)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_add(a, a, b, 2 + n_randint(state, 200)); fmpq_add(z, x, y); if (!arb_contains_fmpq(a, z)) { flint_printf("FAIL: aliasing (c, a)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and b */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_add(b, a, b, 2 + n_randint(state, 200)); fmpq_add(z, x, y); if (!arb_contains_fmpq(b, z)) { flint_printf("FAIL: aliasing (c, b)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-add_arf.c000066400000000000000000000055671417376376500161120ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("add_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_add_arf(c, a, x, prec); arb_add(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arf_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_add_arf(c, a, x, prec); arb_add_arf(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-add_error.c000066400000000000000000000200751417376376500164620ustar00rootroot00000000000000/* Copyright (C) 2012-2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("add_error...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t m, r; arb_init(a); arb_init(b); arb_init(c); arf_init(m); arf_init(r); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 10); arf_randtest_special(m, state, 1 + n_randint(state, 2000), 10); arf_randtest_special(r, state, 1 + n_randint(state, 2000), 10); /* c = a plus error bounds */ arb_set(c, a); arf_set(arb_midref(b), m); arf_get_mag(arb_radref(b), r); arb_add_error(c, b); /* b = a + random point */ arb_set(b, a); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), r, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), r, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { flint_printf("FAIL (arb_add_error)\n\n"); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(m); arf_clear(r); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t m; arb_init(a); arb_init(b); arb_init(c); arf_init(m); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 10); arf_randtest_special(m, state, 1 + n_randint(state, 2000), 10); /* c = a plus error bounds */ arb_set(c, a); arb_add_error_arf(c, m); /* b = a + random point */ arb_set(b, a); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { flint_printf("FAIL (arb_add_error_arf)\n\n"); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(m); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t t; mag_t r; arb_init(a); arb_init(b); arb_init(c); mag_init(r); arf_init(t); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); mag_randtest(r, state, 10); /* c = a plus error bounds */ arb_set(c, a); arb_add_error_mag(c, r); /* b = a + random point */ arb_set(b, a); arf_set_mag(t, r); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { flint_printf("FAIL (arb_add_error_mag)\n\n"); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); mag_clear(r); arf_clear(t); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t t; slong e; arb_init(a); arb_init(b); arb_init(c); arf_init(t); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); e = n_randint(state, 10) - 10; /* c = a plus error bounds */ arb_set(c, a); arb_add_error_2exp_si(c, e); /* b = a + random point */ arb_set(b, a); arf_one(t); arf_mul_2exp_si(t, t, e); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { flint_printf("FAIL (arb_add_error_2exp_si)\n\n"); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(t); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t t; fmpz_t e; arb_init(a); arb_init(b); arb_init(c); arf_init(t); fmpz_init(e); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); fmpz_randtest(e, state, 10); /* c = a plus error bounds */ arb_set(c, a); arb_add_error_2exp_fmpz(c, e); /* b = a + random point */ arb_set(b, a); arf_one(t); arf_mul_2exp_fmpz(t, t, e); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { flint_printf("FAIL (arb_add_error_2exp_fmpz)\n\n"); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(t); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-add_fmpz.c000066400000000000000000000055531417376376500163110ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("add_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_add_fmpz(c, a, x, prec); arb_add(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_add_fmpz(c, a, x, prec); arb_add_fmpz(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpz_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-add_fmpz_2exp.c000066400000000000000000000056171417376376500172500ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("add_fmpz_2exp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t x, e; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(x); fmpz_init(e); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); fmpz_randtest(e, state, 1 + n_randint(state, 200)); prec = 2 + n_randint(state, 2000); arb_set_fmpz_2exp(b, x, e); arb_add_fmpz_2exp(c, a, x, e, prec); arb_add(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(x); fmpz_clear(e); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, c; fmpz_t x, e; slong prec; arb_init(a); arb_init(c); fmpz_init(x); fmpz_init(e); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); fmpz_randtest(e, state, 1 + n_randint(state, 200)); prec = 2 + n_randint(state, 2000); arb_add_fmpz_2exp(c, a, x, e, prec); arb_add_fmpz_2exp(a, a, x, e, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(c); fmpz_clear(x); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-add_si.c000066400000000000000000000053461417376376500157500ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("add_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_add_si(c, a, x, prec); arb_add(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_add_si(c, a, x, prec); arb_add_si(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-add_ui.c000066400000000000000000000053471417376376500157530ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/ulong_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("add_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_add_ui(c, a, x, prec); arb_add(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_add_ui(c, a, x, prec); arb_add_ui(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-addmul.c000066400000000000000000000221011417376376500157570ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int mag_close(const mag_t am, const mag_t bm) { arf_t t, a, b; int res1, res2; arf_init(t); arf_init(a); arf_init(b); arf_set_mag(a, am); arf_set_mag(b, bm); arf_mul_ui(t, b, 257, MAG_BITS, ARF_RND_UP); arf_mul_2exp_si(t, t, -8); res1 = arf_cmp(a, t) <= 0; arf_mul_ui(t, a, 257, MAG_BITS, ARF_RND_UP); arf_mul_2exp_si(t, t, -8); res2 = arf_cmp(b, t) <= 0; arf_clear(t); arf_clear(a); arf_clear(b); return res1 && res2; } void arb_addmul_naive(arb_t z, const arb_t x, const arb_t y, slong prec) { arb_t t; arb_init(t); arb_mul(t, x, y, ARF_PREC_EXACT); arb_add(z, z, t, prec); arb_clear(t); } int main() { slong iter, iter2; flint_rand_t state; flint_printf("addmul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t x, y, z; arb_init(a); arb_init(b); arb_init(c); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_get_rand_fmpq(z, state, c, 1 + n_randint(state, 200)); arb_addmul(c, a, b, 2 + n_randint(state, 200)); fmpq_addmul(z, x, y); if (!arb_contains_fmpq(c, z)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); fmpq_set(z, x); arb_addmul(a, a, b, 2 + n_randint(state, 200)); fmpq_addmul(z, x, y); if (!arb_contains_fmpq(a, z)) { flint_printf("FAIL: aliasing (c, a)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and b */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); fmpq_set(z, y); arb_addmul(b, a, b, 2 + n_randint(state, 200)); fmpq_addmul(z, x, y); if (!arb_contains_fmpq(b, z)) { flint_printf("FAIL: aliasing (c, b)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* main test */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z, v; slong prec; arb_init(x); arb_init(y); arb_init(z); arb_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arb_randtest_special(x, state, n_randint(state,2) ? 2000 : 200, 200); arb_randtest_special(y, state, n_randint(state,2) ? 2000 : 200, 200); arb_randtest_special(z, state, n_randint(state,2) ? 2000 : 200, 200); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 5)) { case 0: arb_set(v, z); arb_addmul(z, x, y, prec); arb_addmul_naive(v, x, y, prec); if (!arf_equal(arb_midref(z), arb_midref(v)) || !mag_close(arb_radref(z), arb_radref(v))) { flint_printf("FAIL!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 1: arb_set(y, x); arb_set(z, v); arb_addmul(z, x, y, prec); arb_addmul(v, x, x, prec); if (!arf_equal(arb_midref(z), arb_midref(v)) || !mag_close(arb_radref(z), arb_radref(v))) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 2: arb_set(v, x); arb_addmul(v, x, x, prec); arb_addmul(x, x, x, prec); if (!arf_equal(arb_midref(x), arb_midref(v)) || !mag_close(arb_radref(x), arb_radref(v))) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 3: arb_set(v, x); arb_addmul(v, x, y, prec); arb_addmul(x, x, y, prec); if (!arf_equal(arb_midref(x), arb_midref(v)) || !mag_close(arb_radref(x), arb_radref(v))) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; default: arb_set(v, x); arb_addmul(v, x, y, prec); arb_addmul(x, y, x, prec); if (!arf_equal(arb_midref(x), arb_midref(v)) || !mag_close(arb_radref(x), arb_radref(v))) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; } } arb_clear(x); arb_clear(y); arb_clear(z); arb_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-addmul_arf.c000066400000000000000000000056641417376376500166260ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("addmul_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_set(d, c); arb_addmul_arf(c, a, x, prec); arb_addmul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arf_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_set(c, a); arb_addmul_arf(c, a, x, prec); arb_addmul_arf(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-addmul_fmpz.c000066400000000000000000000056501417376376500170250ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("addmul_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_set(d, c); arb_addmul_fmpz(c, a, x, prec); arb_addmul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_set(c, a); arb_addmul_fmpz(c, a, x, prec); arb_addmul_fmpz(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpz_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-addmul_si.c000066400000000000000000000054431417376376500164640ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("addmul_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_set(d, c); arb_addmul_si(c, a, x, prec); arb_addmul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_set(c, a); arb_addmul_si(c, a, x, prec); arb_addmul_si(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-addmul_ui.c000066400000000000000000000054441417376376500164670ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/ulong_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("addmul_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_set(d, c); arb_addmul_ui(c, a, x, prec); arb_addmul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_set(c, a); arb_addmul_ui(c, a, x, prec); arb_addmul_ui(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-agm.c000066400000000000000000000102601417376376500152600ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("agm...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t q, r; mpfr_t t, u; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); fmpq_init(q); fmpq_init(r); mpfr_init2(t, prec + 100); mpfr_init2(u, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_randtest(c, state, 1 + n_randint(state, 200), 3); arb_agm(c, a, b, prec); if (arb_equal(a, b)) { if (!arb_contains(c, a)) { flint_printf("FAIL: containment (identity)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } } else { arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(r, state, b, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); fmpq_get_mpfr(u, r, MPFR_RNDN); mpfr_agm(t, t, u, MPFR_RNDN); if (!arb_contains_mpfr(c, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(q); fmpq_clear(r); mpfr_clear(t); mpfr_clear(u); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x1, x2, y1, y2, r1, r2; slong prec1, prec2; arb_init(x1); arb_init(x2); arb_init(y1); arb_init(y2); arb_init(r1); arb_init(r2); arb_randtest_special(x1, state, 1 + n_randint(state, 200), 100); arb_randtest_special(y1, state, 1 + n_randint(state, 200), 100); if (n_randint(state, 2)) { arb_randtest_special(r1, state, 1 + n_randint(state, 200), 100); arb_randtest_special(r2, state, 1 + n_randint(state, 200), 100); } else { arb_zero(r1); arb_zero(r2); } prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); arb_add(x2, x1, r1, prec2); arb_sub(x2, x2, r1, prec2); arb_add(y2, y1, r2, prec2); arb_sub(y2, y2, r2, prec2); arb_agm(r1, x1, y1, prec1); arb_agm(r2, x2, y2, prec2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x1 = "); arb_printn(x1, 30, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 30, 0); flint_printf("\n\n"); flint_printf("y1 = "); arb_printn(y1, 30, 0); flint_printf("\n\n"); flint_printf("y2 = "); arb_printn(y2, 30, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 30, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 30, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x1); arb_clear(x2); arb_clear(y1); arb_clear(y2); arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-approx_dot.c000066400000000000000000000204231417376376500166750ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("approx_dot...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_ptr x, y; arb_t s1, s2, z; slong i, len, prec, xbits, ybits, ebits; int initial, subtract, revx, revy; if (n_randint(state, 100) == 0) len = n_randint(state, 100); else if (n_randint(state, 10) == 0) len = n_randint(state, 10); else len = n_randint(state, 3); if (n_randint(state, 10) != 0 || len > 10) { prec = 2 + n_randint(state, 500); xbits = 2 + n_randint(state, 500); ybits = 2 + n_randint(state, 500); } else { prec = 2 + n_randint(state, 4000); xbits = 2 + n_randint(state, 4000); ybits = 2 + n_randint(state, 4000); } if (n_randint(state, 100) == 0) ebits = 2 + n_randint(state, 100); else ebits = 2 + n_randint(state, 10); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _arb_vec_init(len); y = _arb_vec_init(len); arb_init(s1); arb_init(s2); arb_init(z); switch (n_randint(state, 3)) { case 0: for (i = 0; i < len; i++) { arb_randtest(x + i, state, xbits, ebits); arb_randtest(y + i, state, ybits, ebits); } break; /* Test with cancellation */ case 1: for (i = 0; i < len; i++) { if (i <= len / 2) { arb_randtest(x + i, state, xbits, ebits); arb_randtest(y + i, state, ybits, ebits); } else { arb_neg(x + i, x + len - i - 1); arb_set(y + i, y + len - i - 1); } } break; default: for (i = 0; i < len; i++) { if (i <= len / 2) { arb_randtest(x + i, state, xbits, ebits); arb_randtest(y + i, state, ybits, ebits); } else { arb_neg_round(x + i, x + len - i - 1, 2 + n_randint(state, 500)); arb_set_round(y + i, y + len - i - 1, 2 + n_randint(state, 500)); } } break; } arb_randtest(s1, state, 200, 100); arb_randtest(s2, state, 200, 100); arb_randtest(z, state, xbits, ebits); arb_approx_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); mag_zero(arb_radref(s1)); /* With the fast algorithm, we expect identical results when reversing the vectors. */ if (ebits <= 12) { arb_approx_dot(s2, initial ? z : NULL, subtract, !revx ? (x + len - 1) : x, !revx ? -1 : 1, !revy ? (y + len - 1) : y, !revy ? -1 : 1, len, prec); mag_zero(arb_radref(s2)); if (!arb_equal(s1, s2)) { flint_printf("FAIL (reversal)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } } /* Verify that radii are ignored */ for (i = 0; i < len; i++) { arb_get_mid_arb(x + i, x + i); arb_get_mid_arb(y + i, y + i); } arb_get_mid_arb(z, z); arb_approx_dot(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); mag_zero(arb_radref(s2)); if (!arb_equal(s1, s2)) { flint_printf("FAIL (radii)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } /* Compare with arb_dot */ arb_approx_dot(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); { mag_t err, xx, yy; mag_init(err); mag_init(xx); mag_init(yy); if (initial) arb_get_mag(err, z); for (i = 0; i < len; i++) { arb_get_mag(xx, revx ? x + len - 1 - i : x + i); arb_get_mag(yy, revx ? y + len - 1 - i : y + i); mag_addmul(err, xx, yy); } mag_mul_2exp_si(err, err, -prec + 2); arb_add_error_mag(s2, err); if (!arb_contains(s2, s1)) { flint_printf("FAIL (inclusion)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } mag_clear(err); mag_clear(xx); mag_clear(yy); } arb_clear(s1); arb_clear(s2); arb_clear(z); _arb_vec_clear(x, len); _arb_vec_clear(y, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-asin.c000066400000000000000000000056761417376376500154650ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("asin...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_asin(t, t, MPFR_RNDN); arb_asin(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_asin(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* check large arguments */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 100); arb_asin(b, a, prec1); arb_asin(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check sin(asin(x)) = x */ arb_sin(c, b, prec1); if (!arb_contains(c, a)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-asinh.c000066400000000000000000000045131417376376500156220ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("asinh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_asinh(a, x, prec1); arb_asinh(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check sinh(asinh(x)) = x */ arb_sinh(b, b, prec1); if (!arb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_asinh(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atan.c000066400000000000000000000157141417376376500154500ustar00rootroot00000000000000/* Copyright (C) 2012-2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("atan...."); fflush(stdout); flint_randinit(state); /* Compare with MPFR */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_atan(t, t, MPFR_RNDN); arb_atan(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_atan(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* Check large arguments. */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 100); arb_atan(b, a, prec1); arb_atan(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check tan(atan(x)) = x */ arb_sin_cos(c, d, b, prec1); arb_div(c, c, d, prec1); if (!arb_contains(c, a)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* Compare with MPFR, higher precision. */ for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 5000); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 5000), 8); arb_randtest(b, state, 1 + n_randint(state, 5000), 8); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_atan(t, t, MPFR_RNDN); arb_atan(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 50); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 50); flint_printf("\n\n"); flint_abort(); } arb_atan(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* Higher precision + large arguments. */ for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 5000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_precise(a, state, 1 + n_randint(state, 5000), 100); arb_atan(b, a, prec1); arb_atan(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check tan(atan(x)) = x */ arb_sin_cos(c, d, b, prec1); arb_div(c, c, d, prec1); if (!arb_contains(c, a)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* Check wide arguments. */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 100); arb_randtest_precise(b, state, 1 + n_randint(state, 1000), 100); if (n_randint(state, 2)) arb_add(a, a, b, 2 + n_randint(state, 1000)); arb_union(d, a, b, 2 + n_randint(state, 1000)); arb_atan(a, a, 2 + n_randint(state, 2000)); arb_atan(b, b, 2 + n_randint(state, 2000)); arb_atan(c, d, 2 + n_randint(state, 2000)); if (!arb_overlaps(c, a) || !arb_overlaps(c, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atan2.c000066400000000000000000000037141417376376500155270ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("atan2...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t q, r; mpfr_t t, u; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); fmpq_init(q); fmpq_init(r); mpfr_init2(t, prec + 100); mpfr_init2(u, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_randtest(c, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(r, state, b, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); fmpq_get_mpfr(u, r, MPFR_RNDN); mpfr_atan2(t, u, t, MPFR_RNDN); arb_atan2(c, b, a, prec); if (!arb_contains_mpfr(c, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(q); fmpq_clear(r); mpfr_clear(t); mpfr_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atan_arf.c000066400000000000000000000050001417376376500162630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("atan_arf...."); fflush(stdout); flint_randinit(state); /* self-consistency test */ for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arf_t x; arb_t y1, y2; slong prec1, prec2, acc1, acc2; prec1 = 2 + n_randint(state, 9000); prec2 = 2 + n_randint(state, 9000); arf_init(x); arb_init(y1); arb_init(y2); arf_randtest_special(x, state, 1 + n_randint(state, 9000), 200); arb_randtest_special(y1, state, 1 + n_randint(state, 9000), 200); arb_randtest_special(y2, state, 1 + n_randint(state, 9000), 200); if (n_randint(state, 2)) arf_add_ui(x, x, 1, 2 + n_randint(state, 9000), ARF_RND_DOWN); arb_atan_arf(y1, x, prec1); arb_atan_arf(y2, x, prec2); if (!arb_overlaps(y1, y2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y1 = "); arb_print(y1); flint_printf("\n\n"); flint_printf("y2 = "); arb_print(y2); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(y1); acc2 = arb_rel_accuracy_bits(y2); if (!arf_is_nan(x)) { if (acc1 < prec1 - 2 || acc2 < prec2 - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("acc1 = %wd, acc2 = %wd\n\n", acc1, acc2); flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n"); flint_printf("y1 = "); arb_printd(y1, 50); flint_printf("\n\n"); flint_printf("y2 = "); arb_printd(y2, 50); flint_printf("\n\n"); flint_abort(); } } arf_clear(x); arb_clear(y1); arb_clear(y2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atan_arf_bb.c000066400000000000000000000056601417376376500167420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_atan_arf_via_mpfr(arb_t z, const arf_t x, slong prec) { mpfr_t t, u; int exact; mpfr_init2(t, 2 + arf_bits(x)); mpfr_init2(u, prec); mpfr_set_emin(MPFR_EMIN_MIN); mpfr_set_emax(MPFR_EMAX_MAX); arf_get_mpfr(t, x, MPFR_RNDD); exact = (mpfr_atan(u, t, MPFR_RNDD) == 0); arf_set_mpfr(arb_midref(z), u); if (!exact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); mpfr_clear(t); mpfr_clear(u); } int main() { slong iter; flint_rand_t state; flint_printf("atan_arf_bb...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_t x, y, z; slong prec, prec2; arb_init(x); arb_init(y); arb_init(z); prec = 2 + n_randint(state, 8000); arb_randtest(x, state, 1 + n_randint(state, 8000), 3); mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_mul_2exp_si(x, x, 1 + n_randint(state, 40)); else arb_mul_2exp_si(x, x, -n_randint(state, 1.5 * prec)); if (!arf_is_special(arb_midref(x))) prec2 = prec + 100 + 2 * (-ARF_EXP(arb_midref(x))); else prec2 = prec + 100; arb_atan_arf_via_mpfr(y, arb_midref(x), prec2); arb_atan_arf_bb(z, arb_midref(x), prec); if (!arb_contains(z, y)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 50); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(z) < prec - 2) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd, acc = %wd\n\n", prec, arb_rel_accuracy_bits(z)); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 50); flint_printf("\n\n"); flint_abort(); } arb_atan_arf_bb(x, arb_midref(x), prec); if (!arb_overlaps(x, z)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atan_sum_bs_powtab.c000066400000000000000000000036671417376376500204000ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("atan_sum_bs_powtab...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2500 * arb_test_multiplier(); iter++) { slong N; fmpz_t x, T, Q; fmpq_t S, V; flint_bitcnt_t Qexp, r; fmpz_init(x); fmpz_init(T); fmpz_init(Q); fmpq_init(S); fmpq_init(V); N = 1 + n_randint(state, 200); r = n_randint(state, 10); fmpz_randtest(x, state, 30); _arb_atan_sum_bs_simple(T, Q, &Qexp, x, r, N); fmpq_set_fmpz_frac(S, T, Q); fmpq_div_2exp(S, S, Qexp); _arb_atan_sum_bs_powtab(T, Q, &Qexp, x, r, N); fmpq_set_fmpz_frac(V, T, Q); fmpq_div_2exp(V, V, Qexp); if (!fmpq_equal(S, V)) { flint_printf("FAIL\n\n"); flint_printf("N = %wd\n\n", N); flint_printf("r = %wu\n\n", r); flint_printf("x = "); fmpz_print(x); flint_printf("\n\n"); flint_printf("T = "); fmpz_print(T); flint_printf("\n\n"); flint_printf("Q = "); fmpz_print(T); flint_printf("\n\n"); flint_printf("V = "); fmpq_print(V); flint_printf("\n\n"); flint_printf("S = "); fmpq_print(S); flint_printf("\n\n"); flint_abort(); } fmpz_clear(x); fmpz_clear(T); fmpz_clear(Q); fmpq_clear(S); fmpq_clear(V); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atan_tab.c000066400000000000000000000120631417376376500162700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong i; mpfr_t tabx, atanx, y1, y2; mpz_t tt; flint_printf("atan_tab...."); fflush(stdout); { slong prec, bits, num; prec = ARB_ATAN_TAB1_LIMBS * FLINT_BITS; bits = ARB_ATAN_TAB1_BITS; num = 1 << ARB_ATAN_TAB1_BITS; mpfr_init2(tabx, prec); mpfr_init2(atanx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_atan_tab1[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(atanx, i, MPFR_RNDD); mpfr_div_2ui(atanx, atanx, bits, MPFR_RNDD); mpfr_atan(atanx, atanx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, atanx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(atanx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_ATAN_TAB2_LIMBS * FLINT_BITS; bits = ARB_ATAN_TAB21_BITS; num = 1 << ARB_ATAN_TAB21_BITS; mpfr_init2(tabx, prec); mpfr_init2(atanx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_atan_tab21[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(atanx, i, MPFR_RNDD); mpfr_div_2ui(atanx, atanx, bits, MPFR_RNDD); mpfr_atan(atanx, atanx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, atanx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(atanx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_ATAN_TAB2_LIMBS * FLINT_BITS; bits = ARB_ATAN_TAB21_BITS + ARB_ATAN_TAB22_BITS; num = 1 << ARB_ATAN_TAB22_BITS; mpfr_init2(tabx, prec); mpfr_init2(atanx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_atan_tab22[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(atanx, i, MPFR_RNDD); mpfr_div_2ui(atanx, atanx, bits, MPFR_RNDD); mpfr_atan(atanx, atanx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, atanx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(atanx); mpfr_clear(y1); mpfr_clear(y2); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atan_taylor_rs.c000066400000000000000000000044751417376376500175500ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/mpn_extras.h" #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("atan_taylor_rs...."); fflush(stdout); flint_randinit(state); _flint_rand_init_gmp(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mp_ptr x, y1, y2, t; mp_limb_t err1, err2; ulong N; mp_size_t xn; int alternating, cmp, result; N = n_randint(state, 256); alternating = n_randint(state, 2); xn = 1 + n_randint(state, 20); x = flint_malloc(sizeof(mp_limb_t) * xn); y1 = flint_malloc(sizeof(mp_limb_t) * xn); y2 = flint_malloc(sizeof(mp_limb_t) * xn); t = flint_malloc(sizeof(mp_limb_t) * xn); flint_mpn_rrandom(x, state->gmp_state, xn); x[xn - 1] &= (LIMB_ONES >> 4); _arb_atan_taylor_naive(y1, &err1, x, xn, N, alternating); _arb_atan_taylor_rs(y2, &err2, x, xn, N, alternating); cmp = mpn_cmp(y1, y2, xn); if (cmp == 0) { result = 1; } else if (cmp > 0) { mpn_sub_n(t, y1, y2, xn); result = flint_mpn_zero_p(t + 1, xn - 1) && (t[0] <= err2); } else { mpn_sub_n(t, y2, y1, xn); result = flint_mpn_zero_p(t + 1, xn - 1) && (t[0] <= err2); } if (!result) { flint_printf("FAIL\n"); flint_printf("N = %wd xn = %wd alternating = %d\n", N, xn, alternating); flint_printf("x ="); flint_mpn_debug(x, xn); flint_printf("y1 ="); flint_mpn_debug(y1, xn); flint_printf("y2 ="); flint_mpn_debug(y2, xn); flint_abort(); } flint_free(x); flint_free(y1); flint_free(y2); flint_free(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-atanh.c000066400000000000000000000045131417376376500156130ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("atanh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_atanh(a, x, prec1); arb_atanh(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* check tanh(atanh(x)) = x */ arb_tanh(b, b, prec1); if (!arb_contains(b, x)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_atanh(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-bell_fmpz.c000066400000000000000000000046211417376376500164720ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("bell_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_t b1, b2; fmpz_t n; slong prec1, prec2, acc1, acc2; fmpz_init(n); arb_init(b1); arb_init(b2); if (iter % 100 == 0) { fmpz_randtest(n, state, 1 + n_randint(state, 100)); fmpz_abs(n, n); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); } else { fmpz_randtest(n, state, 1 + n_randint(state, 20)); fmpz_abs(n, n); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); } arb_bell_fmpz(b1, n, prec1); arb_bell_fmpz(b2, n, prec2); if (!arb_overlaps(b1, b2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("b1 = "); arb_printn(b1, 50, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, 50, 0); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(b1); acc2 = arb_rel_accuracy_bits(b2); if (acc1 < prec1 - 4 || acc2 < prec2 - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd\n", prec1, acc1); flint_printf("prec2 = %wd, acc2 = %wd\n", prec2, acc2); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("b1 = "); arb_printn(b1, 50, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(b1); arb_clear(b2); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-bell_sum_taylor.c000066400000000000000000000037671417376376500177260ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("bell_sum_taylor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t s1, s2; fmpz_t a, b, n; slong prec; arb_init(s1); arb_init(s2); fmpz_init(a); fmpz_init(b); fmpz_init(n); prec = 2 + n_randint(state, 300); fmpz_randtest_unsigned(n, state, 1 + n_randint(state, 100)); fmpz_randtest_unsigned(a, state, 1 + n_randint(state, 100)); fmpz_add_ui(b, a, n_randint(state, 100)); arb_bell_sum_bsplit(s1, n, a, b, NULL, prec); arb_bell_sum_taylor(s2, n, a, b, NULL, prec); if (!arb_overlaps(s1, s2) || (arb_rel_accuracy_bits(s1) < prec - 4) || (arb_rel_accuracy_bits(s2) < prec - 4)) { flint_printf("FAIL: overlap or accuracy\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); fmpz_clear(a); fmpz_clear(b); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-bernoulli_poly_ui.c000066400000000000000000000043501417376376500202520ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("bernoulli_poly_ui...."); fflush(stdout); flint_randinit(state); /* test multiplication theorem */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, t, res1, res2; ulong n, m, k; slong prec; n = n_randint(state, 50); m = 1 + n_randint(state, 5); prec = 2 + n_randint(state, 200); arb_init(x); arb_init(t); arb_init(res1); arb_init(res2); arb_randtest(x, state, 2 + n_randint(state, 200), 20); arb_randtest(res1, state, 2 + n_randint(state, 200), 20); arb_mul_ui(t, x, m, prec); arb_bernoulli_poly_ui(res1, n, t, prec); arb_zero(res2); for (k = 0; k < m; k++) { arb_set_ui(t, k); arb_div_ui(t, t, m, prec); arb_add(t, t, x, prec); arb_bernoulli_poly_ui(t, n, t, prec); arb_add(res2, res2, t, prec); } if (n > 0) { arb_ui_pow_ui(t, m, n - 1, prec); arb_mul(res2, res2, t, prec); } else { arb_div_ui(res2, res2, m, prec); } if (!arb_overlaps(res1, res2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu, m = %wu\n\n", n, m); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("res1 = "); arb_printd(res1, 15); flint_printf("\n\n"); flint_printf("res2 = "); arb_printd(res2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(t); arb_clear(res1); arb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-bernoulli_ui.c000066400000000000000000000036231417376376500172110ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("bernoulli_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t b1, b2; ulong n; slong prec1, prec2, acc1, acc2; n = n_randint(state, 10000); prec1 = 2 + n_randint(state, 10000); prec2 = prec1 + 100; arb_init(b1); arb_init(b2); arb_bernoulli_ui(b1, n, prec1); arb_bernoulli_ui(b2, n, prec2); if (!arb_overlaps(b1, b2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("b1 = "); arb_print(b1); flint_printf("\n\n"); flint_printf("b2 = "); arb_print(b2); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(b1); acc2 = arb_rel_accuracy_bits(b2); if (acc1 < prec1 - 2 || acc2 < prec2 - 2) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec1 = %wd\n", prec1); flint_printf("prec2 = %wd\n", prec2); flint_printf("b1 = "); arb_printd(b1, prec1 / 3.33); flint_printf("\n\n"); flint_printf("b2 = "); arb_printd(b2, prec2 / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(b1); arb_clear(b2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-can_round_mpfr.c000066400000000000000000000044211417376376500175120ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("can_round_mpfr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { mpfr_t x, y1, y2; int r1, r2; arb_t t; slong prec; mpfr_rnd_t rnd; prec = 2 + n_randint(state, 300); mpfr_init2(x, 2 + n_randint(state, 300)); mpfr_init2(y1, prec); mpfr_init2(y2, prec); arb_init(t); switch (n_randint(state, 5)) { case 0: rnd = MPFR_RNDN; break; case 1: rnd = MPFR_RNDZ; break; case 2: rnd = MPFR_RNDU; break; case 3: rnd = MPFR_RNDD; break; default: rnd = MPFR_RNDA; } arf_randtest(arb_midref(t), state, mpfr_get_prec(x), 1 + n_randint(state, 10)); arf_abs(arb_midref(t), arb_midref(t)); arf_get_mpfr(x, arb_midref(t), MPFR_RNDN); arb_root_ui(t, t, 4, 2 + n_randint(state, 300)); if (arb_can_round_mpfr(t, prec, rnd)) { #if MPFR_VERSION_MAJOR >= 4 r1 = mpfr_rootn_ui(y1, x, 4, rnd); #else r1 = mpfr_root(y1, x, 4, rnd); #endif r2 = arf_get_mpfr(y2, arb_midref(t), rnd); if (r1 != r2 || !mpfr_equal_p(y1, y2)) { flint_printf("FAIL!\n"); flint_printf("r1 = %d, r2 = %d, prec = %wd\n", r1, r2, prec); flint_printf("x = "); mpfr_dump(x); flint_printf("\n"); flint_printf("y1 = "); mpfr_dump(y1); flint_printf("\n"); flint_printf("y2 = "); mpfr_dump(y2); flint_printf("\n"); flint_abort(); } } arb_clear(t); mpfr_clear(x); mpfr_clear(y1); mpfr_clear(y2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-ceil.c000066400000000000000000000037321417376376500154360ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("ceil...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x; fmpz_t y; slong prec; arb_init(a); arb_init(b); fmpq_init(x); fmpz_init(y); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_ceil(b, a, prec); fmpz_cdiv_q(y, fmpq_numref(x), fmpq_denref(x)); if (!arb_contains_fmpz(b, y)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_abort(); } arb_ceil(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpz_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-chebyshev_t_ui.c000066400000000000000000000064231417376376500175220ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("chebyshev_t_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; ulong n; slong prec; n = n_randtest(state); prec = 2 + n_randint(state, 300); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest(a, state, 1 + n_randint(state, 300), 5); arb_randtest(c, state, 1 + n_randint(state, 300), 5); arb_cos(b, a, prec); arb_chebyshev_t_ui(c, n, b, prec); arb_mul_ui(d, a, n, prec); arb_cos(d, d, prec); if (!arb_overlaps(c, d)) { flint_printf("FAIL: c = T_n(cos(a)) = d = cos(n*a)\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("d = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_chebyshev_t_ui(b, n, b, prec); if (!arb_equal(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_randtest(a, state, 1 + n_randint(state, 300), 5); arb_randtest(b, state, 1 + n_randint(state, 300), 5); arb_randtest(c, state, 1 + n_randint(state, 300), 5); arb_chebyshev_t2_ui(b, c, n, a, prec); arb_chebyshev_t_ui(d, n, a, prec); if (!arb_overlaps(b, d)) { flint_printf("FAIL: T_n\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } if (n == 0) arb_set(d, a); else arb_chebyshev_t_ui(d, n - 1, a, prec); if (!arb_overlaps(c, d)) { flint_printf("FAIL: T_{n-1}\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-chebyshev_u_ui.c000066400000000000000000000073231417376376500175230ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("chebyshev_u_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d, e; ulong n; slong prec; n = n_randtest(state); prec = 2 + n_randint(state, 300); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(e); arb_randtest_precise(a, state, 1 + n_randint(state, 300), 5); arb_randtest_precise(c, state, 1 + n_randint(state, 300), 5); arb_sin_cos(d, b, a, prec); arb_chebyshev_u_ui(c, n, b, prec); arb_mul(d, c, d, prec); if (n == LIMB_ONES) arb_mul_2exp_si(e, a, FLINT_BITS); else arb_mul_ui(e, a, n + 1, prec); arb_sin(e, e, prec); if (!arb_overlaps(d, e)) { flint_printf("FAIL: sin(a)*U_n(cos(a)) = sin((n+1)a)\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_printd(d, 15); flint_printf("\n\n"); flint_printf("e = "); arb_printd(e, 15); flint_printf("\n\n"); flint_abort(); } arb_chebyshev_u_ui(b, n, b, prec); if (!arb_equal(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_randtest(a, state, 1 + n_randint(state, 300), 5); arb_randtest(b, state, 1 + n_randint(state, 300), 5); arb_randtest(c, state, 1 + n_randint(state, 300), 5); arb_chebyshev_u2_ui(b, c, n, a, prec); arb_chebyshev_u_ui(d, n, a, prec); if (!arb_overlaps(b, d)) { flint_printf("FAIL: U_n\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } if (n == 0) arb_zero(d); else arb_chebyshev_u_ui(d, n - 1, a, prec); if (!arb_overlaps(c, d)) { flint_printf("FAIL: U_{n-1}\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_apery.c000066400000000000000000000031061417376376500170430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_apery...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r; mpfr_t s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 17)); arb_init(r); mpfr_init2(s, prec + 1000); arb_const_apery(r, prec); mpfr_zeta_ui(s, 3, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_catalan.c000066400000000000000000000031151417376376500173260ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_catalan...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r; mpfr_t s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 16)); arb_init(r); mpfr_init2(s, prec + 1000); arb_const_catalan(r, prec); mpfr_const_catalan(s, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_e.c000066400000000000000000000031401417376376500161450ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_e...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r; mpfr_t s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 16)); arb_init(r); mpfr_init2(s, prec + 1000); arb_const_e(r, prec); mpfr_set_ui(s, 1, MPFR_RNDN); mpfr_exp(s, s, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_euler.c000066400000000000000000000031071417376376500170400ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_euler...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r; mpfr_t s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 16)); arb_init(r); mpfr_init2(s, prec + 1000); arb_const_euler(r, prec); mpfr_const_euler(s, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_glaisher.c000066400000000000000000000043021417376376500175200ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_glaisher...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r, s, t; fmpz_t v; slong accuracy, prec; prec = 2 + n_randint(state, 2000); arb_init(r); arb_init(s); arb_init(t); fmpz_init(v); arb_const_glaisher(r, prec); arb_const_glaisher(s, prec + 100); if (!arb_overlaps(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } if (n_randint(state, 30) == 0) { flint_cleanup(); } fmpz_set_str(v, "128242712910062263687534256886979172776768892732500", 10); arb_set_fmpz(t, v); mag_one(arb_radref(t)); fmpz_ui_pow_ui(v, 10, 50); arb_div_fmpz(t, t, v, 170); if (!arb_overlaps(r, t)) { flint_printf("FAIL: reference value\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); arb_clear(s); arb_clear(t); fmpz_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_khinchin.c000066400000000000000000000030561417376376500175220ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_khinchin...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r, s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 14)); arb_init(r); arb_init(s); arb_const_khinchin(r, prec); arb_const_khinchin(s, prec + 1000); if (!arb_overlaps(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); arb_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_log10.c000066400000000000000000000031511417376376500166450ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_log10...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r; mpfr_t s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 16)); arb_init(r); mpfr_init2(s, prec + 1000); arb_const_log10(r, prec); mpfr_set_ui(s, 10, MPFR_RNDN); mpfr_log(s, s, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_log2.c000066400000000000000000000031041417376376500165640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_log2...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r; mpfr_t s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 16)); arb_init(r); mpfr_init2(s, prec + 1000); arb_const_log2(r, prec); mpfr_const_log2(s, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-const_pi.c000066400000000000000000000030761417376376500163410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("const_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 250 * arb_test_multiplier(); iter++) { arb_t r; mpfr_t s; slong accuracy, prec; prec = 2 + n_randint(state, 1 << n_randint(state, 18)); arb_init(r); mpfr_init2(s, prec + 1000); arb_const_pi(r, prec); mpfr_const_pi(s, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-contains.c000066400000000000000000000045701417376376500163410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("contains...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t am, ar, bm, br, t, u; int c1, c2; arb_init(a); arb_init(b); fmpq_init(am); fmpq_init(ar); fmpq_init(bm); fmpq_init(br); fmpq_init(t); fmpq_init(u); arb_randtest(a, state, 1 + n_randint(state, 500), 14); arb_randtest(b, state, 1 + n_randint(state, 500), 14); arf_get_fmpq(am, arb_midref(a)); mag_get_fmpq(ar, arb_radref(a)); arf_get_fmpq(bm, arb_midref(b)); mag_get_fmpq(br, arb_radref(b)); c1 = arb_contains(a, b); fmpq_sub(t, am, ar); fmpq_sub(u, bm, br); c2 = fmpq_cmp(t, u) <= 0; fmpq_add(t, am, ar); fmpq_add(u, bm, br); c2 = c2 && (fmpq_cmp(t, u) >= 0); if (c1 != c2) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("am = "); fmpq_print(am); flint_printf("\n\n"); flint_printf("ar = "); fmpq_print(ar); flint_printf("\n\n"); flint_printf("bm = "); fmpq_print(bm); flint_printf("\n\n"); flint_printf("br = "); fmpq_print(br); flint_printf("\n\n"); flint_printf("t = "); fmpq_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpq_print(u); flint_printf("\n\n"); flint_printf("c1 = %d, c2 = %d\n\n", c1, c2); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(am); fmpq_clear(ar); fmpq_clear(bm); fmpq_clear(br); fmpq_clear(t); fmpq_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-contains_arf.c000066400000000000000000000040551417376376500171670ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("contains_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a; arf_t b; fmpq_t am, ar, bm, t; int c1, c2; arb_init(a); arf_init(b); fmpq_init(am); fmpq_init(ar); fmpq_init(bm); fmpq_init(t); arb_randtest(a, state, 1 + n_randint(state, 500), 14); arf_randtest(b, state, 1 + n_randint(state, 500), 14); arf_get_fmpq(am, arb_midref(a)); mag_get_fmpq(ar, arb_radref(a)); arf_get_fmpq(bm, b); c1 = arb_contains_arf(a, b); fmpq_sub(t, am, ar); c2 = fmpq_cmp(t, bm) <= 0; fmpq_add(t, am, ar); c2 = c2 && (fmpq_cmp(t, bm) >= 0); if (c1 != c2) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("am = "); fmpq_print(am); flint_printf("\n\n"); flint_printf("ar = "); fmpq_print(ar); flint_printf("\n\n"); flint_printf("bm = "); fmpq_print(bm); flint_printf("\n\n"); flint_printf("t = "); fmpq_print(t); flint_printf("\n\n"); flint_printf("c1 = %d, c2 = %d\n\n", c1, c2); flint_abort(); } arb_clear(a); arf_clear(b); fmpq_clear(am); fmpq_clear(ar); fmpq_clear(bm); fmpq_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-contains_fmpq.c000066400000000000000000000046561417376376500173710ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("contains_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; fmpq_t y; fmpz_t a, b, t; int c1, c2; slong shift; arb_init(x); fmpq_init(y); fmpz_init(a); fmpz_init(b); fmpz_init(t); arb_randtest_special(x, state, 1 + n_randint(state, 500), 12); if (n_randint(state, 2) && arb_is_finite(x)) { arb_get_rand_fmpq(y, state, x, 1 + n_randint(state, 500)); fmpz_add_si(fmpq_numref(y), fmpq_numref(y), n_randint(state, 3) - 1); } else fmpq_randtest(y, state, 1 + n_randint(state, 500)); c1 = arb_contains_fmpq(x, y); if (arb_is_finite(x)) { arb_get_interval_fmpz_2exp(a, b, t, x); shift = fmpz_get_si(t); fmpz_mul(a, a, fmpq_denref(y)); fmpz_mul(b, b, fmpq_denref(y)); fmpz_set(t, fmpq_numref(y)); if (shift >= 0) { fmpz_mul_2exp(a, a, shift); fmpz_mul_2exp(b, b, shift); } else { fmpz_mul_2exp(t, t, -shift); } c2 = (fmpz_cmp(a, t) <= 0) && (fmpz_cmp(t, b) <= 0); } else { fmpz_tdiv_q(t, fmpq_numref(y), fmpq_denref(y)); c2 = arb_contains_fmpz(x, t); } if (c1 != c2) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c1 = %d, c2 = %d\n\n", c1, c2); flint_abort(); } arb_clear(x); fmpq_clear(y); fmpz_clear(a); fmpz_clear(b); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-contains_int.c000066400000000000000000000025171417376376500172120ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("contains_int...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a; slong c; int r, ok; arb_init(a); arb_randtest_special(a, state, 1 + n_randint(state, 500), 2); r = arb_contains_int(a); ok = !r; for (c = 0; c < 10; c++) { if (arb_contains_si(a, c) || arb_contains_si(a, -c)) { ok = !ok; break; } } if (!ok) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("r = %d\n\n", r); flint_abort(); } arb_clear(a); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-contains_interior.c000066400000000000000000000046101417376376500202470ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("contains_interior...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t am, ar, bm, br, t, u; int c1, c2; arb_init(a); arb_init(b); fmpq_init(am); fmpq_init(ar); fmpq_init(bm); fmpq_init(br); fmpq_init(t); fmpq_init(u); arb_randtest(a, state, 1 + n_randint(state, 500), 14); arb_randtest(b, state, 1 + n_randint(state, 500), 14); arf_get_fmpq(am, arb_midref(a)); mag_get_fmpq(ar, arb_radref(a)); arf_get_fmpq(bm, arb_midref(b)); mag_get_fmpq(br, arb_radref(b)); c1 = arb_contains_interior(a, b); fmpq_sub(t, am, ar); fmpq_sub(u, bm, br); c2 = fmpq_cmp(t, u) < 0; fmpq_add(t, am, ar); fmpq_add(u, bm, br); c2 = c2 && (fmpq_cmp(t, u) > 0); if (c1 != c2) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("am = "); fmpq_print(am); flint_printf("\n\n"); flint_printf("ar = "); fmpq_print(ar); flint_printf("\n\n"); flint_printf("bm = "); fmpq_print(bm); flint_printf("\n\n"); flint_printf("br = "); fmpq_print(br); flint_printf("\n\n"); flint_printf("t = "); fmpq_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpq_print(u); flint_printf("\n\n"); flint_printf("c1 = %d, c2 = %d\n\n", c1, c2); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(am); fmpq_clear(ar); fmpq_clear(bm); fmpq_clear(br); fmpq_clear(t); fmpq_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-cos.c000066400000000000000000000070661417376376500153120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("cos...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec0, prec; prec0 = 400; if (iter % 100 == 0) prec0 = 8000; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec0 + 100); arb_randtest(a, state, 1 + n_randint(state, prec0), 6); arb_randtest(b, state, 1 + n_randint(state, prec0), 6); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, prec0)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_cos(t, t, MPFR_RNDN); arb_cos(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_cos(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* check large arguments */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec0, prec1, prec2; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec0), prec0); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(d, state, 1 + n_randint(state, prec0), 100); arb_cos(b, a, prec1); arb_cos(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check cos(2a) = 2cos(a)^2-1 */ arb_mul_2exp_si(c, a, 1); arb_cos(c, c, prec1); arb_mul(b, b, b, prec1); arb_mul_2exp_si(b, b, 1); arb_sub_ui(b, b, 1, prec1); if (!arb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-cos_pi.c000066400000000000000000000030511417376376500157700ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("cos_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_const_pi(b, prec); arb_mul(b, b, a, prec); arb_cos(b, b, prec); arb_cos_pi(c, a, prec); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-cos_pi_fmpq.c000066400000000000000000000030611417376376500170140ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("cos_pi_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t c1, c2; fmpq_t x; slong prec; prec = 2 + n_randint(state, 5000); arb_init(c1); arb_init(c2); fmpq_init(x); fmpq_randtest(x, state, 1 + n_randint(state, 200)); arb_cos_pi_fmpq(c1, x, prec); arb_const_pi(c2, prec); arb_mul_fmpz(c2, c2, fmpq_numref(x), prec); arb_div_fmpz(c2, c2, fmpq_denref(x), prec); arb_cos(c2, c2, prec); if (!arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("c1 = "); arb_printd(c1, 15); flint_printf("\n\n"); flint_printf("c2 = "); arb_printd(c2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(c1); arb_clear(c2); fmpq_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-cos_pi_fmpq_algebraic.c000066400000000000000000000040241417376376500210050ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("cos_pi_fmpq_algebraic...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t c1, c2; ulong p, q, g; slong prec; prec = 2 + n_randint(state, 5000); q = 1 + n_randint(state, 500); p = n_randint(state, q / 2 + 1); g = n_gcd(q, p); q /= g; p /= g; arb_init(c1); arb_init(c2); _arb_cos_pi_fmpq_algebraic(c1, p, q, prec); arb_const_pi(c2, prec); arb_mul_ui(c2, c2, p, prec); arb_div_ui(c2, c2, q, prec); arb_cos(c2, c2, prec); if (!arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("c1 = "); arb_printd(c1, 15); flint_printf("\n\n"); flint_printf("c2 = "); arb_printd(c2, 15); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(c1) < prec - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("prec=%wd eff=%wd\n", prec, arb_rel_accuracy_bits(c1)); flint_printf("c1 = "); arb_printd(c1, 15); flint_printf("\n\n"); flint_printf("c2 = "); arb_printd(c2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(c1); arb_clear(c2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-cosh.c000066400000000000000000000033201417376376500154470ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("cosh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_cosh(t, t, MPFR_RNDN); arb_cosh(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_cosh(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-cot_pi.c000066400000000000000000000067671417376376500160120ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("cot_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(y); arb_init(a); arb_init(b); arb_init(c); arb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_cot_pi(a, x, prec1); arb_cot_pi(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } /* compare with cot */ arb_const_pi(c, prec1); arb_mul(y, x, c, prec1); arb_cot(c, y, prec1); if (!arb_overlaps(a, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_cot_pi(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(a); arb_clear(b); arb_clear(c); } /* Check a few special points. */ { arb_t x, y; slong i, prec; arb_init(x); arb_init(y); prec = 32; for (i = -1; i <= 1; i++) { int arbitrary_integer = 7; /* integer */ arb_set_d(x, arbitrary_integer*i); arb_cot_pi(y, x, prec); if (arb_is_finite(y)) { flint_printf("FAIL: (integer)\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } /* integer + 1/2 */ arb_set_d(x, arbitrary_integer*i + 0.5); arb_cot_pi(y, x, prec); if (!arb_is_zero(y)) { flint_printf("FAIL: (integer + 1/2)\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } } arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-coth.c000066400000000000000000000052341417376376500154560ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("coth...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(y); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_precise(x, state, 1 + n_randint(state, 1000), 100); arb_randtest_precise(y, state, 1 + n_randint(state, 1000), 100); arb_coth(a, x, prec1); arb_coth(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } /* check coth(x+y) = (1 + coth(x) coth(y)) / (coth(x) + coth(y)) */ arb_add(b, x, y, prec1); arb_coth(b, b, prec1); arb_coth(c, y, prec1); arb_add(d, a, c, prec1); arb_mul(c, a, c, prec1); arb_add_ui(c, c, 1, prec1); arb_div(d, c, d, prec1); if (!arb_overlaps(b, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_coth(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-csc.c000066400000000000000000000034341417376376500152710ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("csc...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 300), 100); arb_randtest_special(a, state, 1 + n_randint(state, 300), 100); arb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { arb_csc(a, x, prec1); } else { arb_set(a, x); arb_csc(a, a, prec1); } arb_sin(b, x, prec2); arb_inv(b, b, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-csc_pi.c000066400000000000000000000035171417376376500157630ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("csc_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 300), 100); arb_randtest_special(a, state, 1 + n_randint(state, 300), 100); arb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { arb_csc_pi(a, x, prec1); } else { arb_set(a, x); arb_csc_pi(a, a, prec1); } arb_sin_pi(b, x, prec2); arb_inv(b, b, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-csch.c000066400000000000000000000034401417376376500154360ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("csch...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 300), 100); arb_randtest_special(a, state, 1 + n_randint(state, 300), 100); arb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { arb_csch(a, x, prec1); } else { arb_set(a, x); arb_csch(a, a, prec1); } arb_sinh(b, x, prec2); arb_inv(b, b, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-digamma.c000066400000000000000000000045241417376376500161210ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("digamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 10); arb_digamma(b, a, prec1); arb_digamma(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_set(c, a); arb_digamma(c, c, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check digamma(z+1) = digamma(z) + 1/z */ arb_inv(c, a, prec1); arb_add(b, b, c, prec1); arb_add_ui(c, a, 1, prec1); arb_digamma(c, c, prec1); if (!arb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-digits_round_inplace.c000066400000000000000000000047111417376376500207050ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { flint_rand_t state; flint_printf("digits_round_inplace...."); fflush(stdout); flint_randinit(state); { char s[30]; slong i, j, len, n; flint_bitcnt_t shift; fmpz_t inp, out, err, t; arf_rnd_t rnd; fmpz_init(inp); fmpz_init(out); fmpz_init(err); fmpz_init(t); for (i = 0; i < 100000 * arb_test_multiplier(); i++) { len = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); s[0] = (n_randint(state, 9) + '1'); for (j = 1; j < len; j++) s[j] = (n_randint(state, 10) + '0'); s[len] = '\0'; fmpz_set_str(inp, s, 10); switch (n_randint(state, 3)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; default: rnd = ARF_RND_NEAR; break; } _arb_digits_round_inplace(s, &shift, err, n, rnd); fmpz_set_str(out, s, 10); fmpz_set_ui(t, 10); fmpz_pow_ui(t, t, shift); fmpz_mul(t, t, out); fmpz_add(t, t, err); if (!fmpz_equal(t, inp) || (rnd == ARF_RND_UP && fmpz_sgn(err) > 0)) { flint_printf("FAIL!\n"); flint_printf("inp = "); fmpz_print(inp); flint_printf("\n\n"); flint_printf("shift = %wd\n\n", shift); flint_printf("err = "); fmpz_print(err); flint_printf("\n\n"); flint_printf("out = "); fmpz_print(out); flint_printf("\n\n"); flint_printf(" t = "); fmpz_print(t); flint_printf("\n\n"); flint_abort(); } } fmpz_clear(inp); fmpz_clear(out); fmpz_clear(err); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-div.c000066400000000000000000000176361417376376500153140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("div...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t x, y, z; arb_init(a); arb_init(b); arb_init(c); fmpq_init(x); fmpq_init(y); fmpq_init(z); do { arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); } while (fmpq_is_zero(y)); arb_div(c, a, b, 2 + n_randint(state, 200)); fmpq_div(z, x, y); if (!arb_contains_fmpq(c, z)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); do { arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); } while (fmpq_is_zero(y)); arb_div(a, a, b, 2 + n_randint(state, 200)); fmpq_div(z, x, y); if (!arb_contains_fmpq(a, z)) { flint_printf("FAIL: aliasing (c, a)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and b */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); do { arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); } while (fmpq_is_zero(y)); arb_div(b, a, b, 2 + n_randint(state, 200)); fmpq_div(z, x, y); if (!arb_contains_fmpq(b, z)) { flint_printf("FAIL: aliasing (c, b)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* test special values */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(c, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_div(c, a, b, 2 + n_randint(state, 200)); arb_mul(d, c, b, 2 + n_randint(state, 200)); if (!arb_contains(d, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_printd(d, 15); flint_printf("\n\n"); flint_abort(); } if (arf_is_nan(arb_midref(a)) || arf_is_nan(arb_midref(b)) || arb_contains_zero(b) || (!arb_is_finite(a) && !arb_is_finite(b))) { if (!arf_is_nan(arb_midref(c)) || !mag_is_inf(arb_radref(c))) { flint_printf("FAIL: special value 1\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_abort(); } } if (!arb_is_finite(a) && !arb_contains_zero(a) && !arb_contains_zero(b) && arb_is_finite(b)) { if (!arf_is_inf(arb_midref(c)) || !mag_is_zero(arb_radref(c)) || arf_sgn(arb_midref(a)) * arf_sgn(arb_midref(b)) != arf_sgn(arb_midref(c))) { flint_printf("FAIL: special value 2\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_abort(); } } if (!arb_is_finite(a) && !arf_is_nan(arb_midref(a)) && arb_contains_zero(a) && !arb_contains_zero(b) && arb_is_finite(b)) { if (!arf_is_zero(arb_midref(c)) || !mag_is_inf(arb_radref(c))) { flint_printf("FAIL: special value 3\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_abort(); } } if (arb_is_finite(a) && !arb_is_finite(b) && !arb_contains_zero(b)) { if (!arb_is_zero(c)) { flint_printf("FAIL: special value 4\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-div_2expm1_ui.c000066400000000000000000000052771417376376500172030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("div_2expm1_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong n; slong prec, acc1, acc2; fmpz_t t; arb_init(a); arb_init(b); arb_init(c); fmpz_init(t); prec = 2 + n_randint(state, 10000); arb_randtest(a, state, 1 + n_randint(state, 10000), 10); if (n_randint(state, 2)) n = 1 + (n_randtest(state) % (10 * prec)); else n = n_randtest(state); arb_div_2expm1_ui(b, a, n, prec); arb_one(c); if (n >= (UWORD(1) << (FLINT_BITS-1))) { arb_mul_2exp_si(c, c, (UWORD(1) << (FLINT_BITS-2))); arb_mul_2exp_si(c, c, (UWORD(1) << (FLINT_BITS-2))); arb_mul_2exp_si(c, c, n - (UWORD(1) << (FLINT_BITS-1))); } else { arb_mul_2exp_si(c, c, n); } arb_sub_ui(c, c, 1, prec); arb_div(c, a, c, prec); acc1 = arb_rel_accuracy_bits(a); acc2 = arb_rel_accuracy_bits(b); if (!arb_overlaps(b, c)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } if (n > 0 && acc1 > 1 && (acc2 < FLINT_MIN(prec, acc1) - 10) && !(acc1 == -ARF_PREC_EXACT && acc2 == -ARF_PREC_EXACT)) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec=%wd, acc1=%wd, acc2=%wd\n\n", prec, acc1, acc2); flint_printf("n = %wu\n\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-div_arf.c000066400000000000000000000055671417376376500161440ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("div_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_div_arf(c, a, x, prec); arb_div(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arf_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_div_arf(c, a, x, prec); arb_div_arf(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-div_fmpz.c000066400000000000000000000055531417376376500163430ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("div_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_div_fmpz(c, a, x, prec); arb_div(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_div_fmpz(c, a, x, prec); arb_div_fmpz(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpz_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-div_si.c000066400000000000000000000053461417376376500160020ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("div_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_div_si(c, a, x, prec); arb_div(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_div_si(c, a, x, prec); arb_div_si(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-div_ui.c000066400000000000000000000053471417376376500160050ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/ulong_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("div_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_div_ui(c, a, x, prec); arb_div(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_div_ui(c, a, x, prec); arb_div_ui(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dot.c000066400000000000000000000144741417376376500153150ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { arb_ptr x, y; arb_t s1, s2, z; slong i, len, prec, xbits, ybits, ebits; int ok, initial, subtract, revx, revy; if (n_randint(state, 100) == 0) len = n_randint(state, 100); else if (n_randint(state, 10) == 0) len = n_randint(state, 10); else len = n_randint(state, 3); if (n_randint(state, 10) != 0 || len > 10) { prec = 2 + n_randint(state, 500); xbits = 2 + n_randint(state, 500); ybits = 2 + n_randint(state, 500); } else { prec = 2 + n_randint(state, 4000); xbits = 2 + n_randint(state, 4000); ybits = 2 + n_randint(state, 4000); } if (n_randint(state, 100) == 0) ebits = 2 + n_randint(state, 100); else ebits = 2 + n_randint(state, 10); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _arb_vec_init(len); y = _arb_vec_init(len); arb_init(s1); arb_init(s2); arb_init(z); switch (n_randint(state, 3)) { case 0: for (i = 0; i < len; i++) { arb_randtest(x + i, state, xbits, ebits); arb_randtest(y + i, state, ybits, ebits); } break; /* Test with cancellation */ case 1: for (i = 0; i < len; i++) { if (i <= len / 2) { arb_randtest(x + i, state, xbits, ebits); arb_randtest(y + i, state, ybits, ebits); } else { arb_neg(x + i, x + len - i - 1); arb_set(y + i, y + len - i - 1); } } break; default: for (i = 0; i < len; i++) { if (i <= len / 2) { arb_randtest(x + i, state, xbits, ebits); arb_randtest(y + i, state, ybits, ebits); } else { arb_neg_round(x + i, x + len - i - 1, 2 + n_randint(state, 500)); arb_set_round(y + i, y + len - i - 1, 2 + n_randint(state, 500)); } } break; } arb_randtest(s1, state, 200, 100); arb_randtest(s2, state, 200, 100); arb_randtest(z, state, xbits, ebits); arb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); arb_dot_precise(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, ebits <= 12 ? ARF_PREC_EXACT : 2 * prec + 100); if (ebits <= 12) ok = arb_contains(s1, s2); else ok = arb_overlaps(s1, s2); if (!ok) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } /* With the fast algorithm, we expect identical results when reversing the vectors. */ if (ebits <= 12) { revx ^= 1; revy ^= 1; arb_dot(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); if (!arb_equal(s1, s2)) { flint_printf("FAIL (reversal)\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } } arb_clear(s1); arb_clear(s2); arb_clear(z); _arb_vec_clear(x, len); _arb_vec_clear(y, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dot_fmpz.c000066400000000000000000000057571417376376500163550ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_siui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_ptr x, y; fmpz * w; arb_t s1, s2, z; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _arb_vec_init(len); y = _arb_vec_init(len); w = _fmpz_vec_init(len); arb_init(s1); arb_init(s2); arb_init(z); for (i = 0; i < len; i++) { arb_randtest(x + i, state, 2 + n_randint(state, 200), 10); fmpz_randtest(w + i, state, 1 + n_randint(state, 200)); arb_set_fmpz(y + i, w + i); } arb_randtest(s1, state, 200, 10); arb_randtest(s2, state, 200, 10); arb_randtest(z, state, 200, 10); arb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); arb_dot_fmpz(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + len - 1) : w, revy ? -1 : 1, len, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(z); _arb_vec_clear(x, len); _arb_vec_clear(y, len); _fmpz_vec_clear(w, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dot_si.c000066400000000000000000000057141417376376500160050ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_ptr x, y; slong * w; arb_t s1, s2, z; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _arb_vec_init(len); y = _arb_vec_init(len); w = flint_malloc(sizeof(ulong) * len); arb_init(s1); arb_init(s2); arb_init(z); for (i = 0; i < len; i++) { arb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[i] = n_randtest(state); arb_set_si(y + i, w[i]); } arb_randtest(s1, state, 200, 10); arb_randtest(s2, state, 200, 10); arb_randtest(z, state, 200, 10); arb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); arb_dot_si(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + len - 1) : w, revy ? -1 : 1, len, prec); if (!arb_equal(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(z); _arb_vec_clear(x, len); _arb_vec_clear(y, len); flint_free(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dot_siui.c000066400000000000000000000062101417376376500163330ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_siui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_ptr x, y; ulong * w; arb_t s1, s2, z; fmpz_t c; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _arb_vec_init(len); y = _arb_vec_init(len); w = flint_malloc(2 * sizeof(ulong) * len); arb_init(s1); arb_init(s2); arb_init(z); fmpz_init(c); for (i = 0; i < len; i++) { arb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[2 * i] = n_randtest(state); w[2 * i + 1] = n_randtest(state); fmpz_set_signed_uiui(c, w[2 * i + 1], w[2 * i]); arb_set_fmpz(y + i, c); } arb_randtest(s1, state, 200, 10); arb_randtest(s2, state, 200, 10); arb_randtest(z, state, 200, 10); arb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); arb_dot_siui(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + 2 * len - 2) : w, revy ? -1 : 1, len, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(z); _arb_vec_clear(x, len); _arb_vec_clear(y, len); flint_free(w); fmpz_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dot_ui.c000066400000000000000000000057141417376376500160070ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_ptr x, y; ulong * w; arb_t s1, s2, z; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _arb_vec_init(len); y = _arb_vec_init(len); w = flint_malloc(sizeof(ulong) * len); arb_init(s1); arb_init(s2); arb_init(z); for (i = 0; i < len; i++) { arb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[i] = n_randtest(state); arb_set_ui(y + i, w[i]); } arb_randtest(s1, state, 200, 10); arb_randtest(s2, state, 200, 10); arb_randtest(z, state, 200, 10); arb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); arb_dot_ui(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + len - 1) : w, revy ? -1 : 1, len, prec); if (!arb_equal(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(z); _arb_vec_clear(x, len); _arb_vec_clear(y, len); flint_free(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dot_uiui.c000066400000000000000000000062011417376376500163350ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("dot_uiui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_ptr x, y; ulong * w; arb_t s1, s2, z; fmpz_t c; slong i, len, prec; int initial, subtract, revx, revy; len = n_randint(state, 5); prec = 2 + n_randint(state, 200); initial = n_randint(state, 2); subtract = n_randint(state, 2); revx = n_randint(state, 2); revy = n_randint(state, 2); x = _arb_vec_init(len); y = _arb_vec_init(len); w = flint_malloc(2 * sizeof(ulong) * len); arb_init(s1); arb_init(s2); arb_init(z); fmpz_init(c); for (i = 0; i < len; i++) { arb_randtest(x + i, state, 2 + n_randint(state, 200), 10); w[2 * i] = n_randtest(state); w[2 * i + 1] = n_randtest(state); fmpz_set_uiui(c, w[2 * i + 1], w[2 * i]); arb_set_fmpz(y + i, c); } arb_randtest(s1, state, 200, 10); arb_randtest(s2, state, 200, 10); arb_randtest(z, state, 200, 10); arb_dot(s1, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (y + len - 1) : y, revy ? -1 : 1, len, prec); arb_dot_uiui(s2, initial ? z : NULL, subtract, revx ? (x + len - 1) : x, revx ? -1 : 1, revy ? (w + 2 * len - 2) : w, revy ? -1 : 1, len, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("iter = %wd, len = %wd, prec = %wd\n\n", iter, len, prec); if (initial) { flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z)); } for (i = 0; i < len; i++) { flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i)); flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i)); } flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(z); _arb_vec_clear(x, len); _arb_vec_clear(y, len); flint_free(w); fmpz_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-doublefac_ui.c000066400000000000000000000030251417376376500171360ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("doublefac_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong n; slong prec1, prec2; prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); arb_init(a); arb_init(b); arb_init(c); n = n_randtest(state); if (n + 1 == 0 || n + 2 == 0) n -= 2; arb_doublefac_ui(a, n, prec1); arb_doublefac_ui(b, n + 2, prec1); arb_mul_ui(c, a, n + 2, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dump_file.c000066400000000000000000000054331417376376500164660ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "arb.h" int main() { flint_rand_t state; slong iter; flint_printf("dump_file/load_file...."); fflush(stdout); flint_randinit(state); /* assume tmpfile() is broken on windows */ #if !defined(_MSC_VER) && !defined(__MINGW32__) /* just test no crashing... */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; FILE* tmp; arb_init(x); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); tmp = tmpfile(); if (tmp == NULL) { flint_printf("FAIL (creating temporary file) iter = %wd\n\n", iter); flint_abort(); } arb_dump_file(tmp, x); fflush(tmp); rewind(tmp); arb_load_file(x, tmp); fclose(tmp); arb_clear(x); } for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y, z; int conversion_error; FILE* tmp; arb_init(x); arb_init(y); arb_init(z); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); tmp = tmpfile(); arb_dump_file(tmp, x); fputc(' ', tmp); arb_dump_file(tmp, y); fflush(tmp); rewind(tmp); conversion_error = arb_load_file(z, tmp); if (conversion_error || !arb_equal(x, z)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 50); flint_printf("\n\n"); flint_abort(); } conversion_error = arb_load_file(z, tmp); if (conversion_error || !arb_equal(y, z)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 50); flint_printf("\n\n"); flint_abort(); } fclose(tmp); arb_clear(x); arb_clear(y); arb_clear(z); } #endif flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-dump_str.c000066400000000000000000000035611417376376500163570ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { flint_rand_t state; slong iter; flint_printf("dump_str/load_str...."); fflush(stdout); flint_randinit(state); /* just test no crashing... */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; char * s; arb_init(x); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); s = arb_dump_str(x); flint_free(s); arb_clear(x); } for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y; char * s; int conversion_error; arb_init(x); arb_init(y); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); s = arb_dump_str(x); conversion_error = arb_load_str(y, s); if (conversion_error || !arb_equal(x, y)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("s = %s", s); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } flint_free(s); arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-euler_number_fmpz.c000066400000000000000000000062551417376376500202450ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("euler_number_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_t b1, b2; fmpz_t n, bv; slong prec1, prec2, acc1, acc2; fmpz_init(n); fmpz_init(bv); arb_init(b1); arb_init(b2); if (iter % 100 == 0) { fmpz_randtest(n, state, 1 + n_randint(state, 1000)); fmpz_abs(n, n); } else { fmpz_randtest(n, state, 1 + n_randint(state, 20)); fmpz_abs(n, n); } prec1 = 2 + n_randint(state, 1000); if (iter % 100 == 0) { fmpz_one(n); fmpz_mul_2exp(n, n, 64); arb_euler_number_fmpz(b1, n, prec1); arb_set_str(b2, "3.69772629631570244101368532955e+343764398125858671130", 64); prec2 = 64; } else if (iter % 100 == 1) { fmpz_one(n); fmpz_mul_2exp(n, n, 64); fmpz_add_ui(n, n, 2); arb_euler_number_fmpz(b1, n, prec1); arb_set_str(b2, "-5.09958051083474382772175848886e+343764398125858671168", 64); prec2 = 64; } else { prec2 = 2 + n_randint(state, 1000); arb_euler_number_fmpz(b1, n, prec1); arb_euler_number_fmpz(b2, n, prec2); } if (fmpz_cmp_ui(n, 300) < 0) { arith_euler_number(bv, fmpz_get_ui(n)); } if (!arb_overlaps(b1, b2) || (fmpz_cmp_ui(n, 100) < 0 && !arb_contains_fmpz(b1, bv))) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("b1 = "); arb_printn(b1, 50, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, 50, 0); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(b1); acc2 = arb_rel_accuracy_bits(b2); if (acc1 < prec1 - 4 || acc2 < prec2 - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd\n", prec1, acc1); flint_printf("prec2 = %wd, acc2 = %wd\n", prec2, acc2); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("b1 = "); arb_printn(b1, 50, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(b1); arb_clear(b2); fmpz_clear(n); fmpz_clear(bv); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-euler_number_ui.c000066400000000000000000000075601417376376500177060ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "arb.h" ulong euler_mod_p_powsum_noredc(ulong n, ulong p, const unsigned int * divtab); ulong euler_mod_p_powsum(ulong n, ulong p, const unsigned int * divtab); ulong euler_mod_p_powsum_1(ulong n, ulong p); static void divisor_table_odd(unsigned int * tab, slong len) { slong i, j; tab[0] = 0; for (i = 1; i < len; i += 2) { tab[i] = 1; tab[i + 1] = i; } for (i = 3; i < len; i += 2) { for (j = 3; j <= i && i * j < len; j += 2) { tab[i * j] = j; tab[i * j + 1] = i; } } } int main() { slong iter; flint_rand_t state; flint_printf("euler_number_ui...."); fflush(stdout); flint_randinit(state); { slong nmax; unsigned int * divtab_odd; fmpz * En; nmax = 1000 * FLINT_MIN(1.0, arb_test_multiplier()); En = _fmpz_vec_init(nmax); arith_euler_number_vec(En, nmax); { fmpz_t E; slong n; double alpha; fmpz_init(E); for (n = 0; n < nmax; n++) { if (n_randint(state, 2)) alpha = -1.0; else alpha = n_randint(state, 11) / (double) 10; arb_fmpz_euler_number_ui_multi_mod(E, n, alpha); if (!fmpz_equal(En + n, E)) { flint_printf("FAIL: n = %wd\n", n); flint_printf("vec: "); fmpz_print(En + n); flint_printf("\n"); flint_printf("single: "); fmpz_print(E); flint_printf("\n"); flint_abort(); } arb_fmpz_euler_number_ui(E, n); if (!fmpz_equal(En + n, E)) { flint_printf("FAIL (2): n = %wd\n", n); flint_printf("vec: "); fmpz_print(En + n); flint_printf("\n"); flint_printf("single: "); fmpz_print(E); flint_printf("\n"); flint_abort(); } } fmpz_clear(E); } /* test the mod p code */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { ulong p, n, m, m1, m5; n = n_randint(state, nmax); p = 4 + n_randint(state, 10000); p = n_nextprime(p, 1); divtab_odd = flint_malloc(sizeof(unsigned int) * (p / 4 + 2)); divisor_table_odd(divtab_odd, p / 4 + 1); m = fmpz_fdiv_ui(En + n, p); if (n_randint(state, 2)) m5 = euler_mod_p_powsum(n, p, divtab_odd); else m5 = euler_mod_p_powsum_noredc(n, p, divtab_odd); if (n_randint(state, 30) == 0) { m1 = euler_mod_p_powsum_1(n, p); if (m1 != UWORD_MAX && m != m1) { flint_printf("FAIL\n\n"); flint_printf("n = %wu, p = %wu, m = %wu, m1 = %wu\n\n", n, p, m, m1); flint_abort(); } } if (m5 != UWORD_MAX && m != m5) { flint_printf("FAIL\n\n"); flint_printf("n = %wu, p = %wu, m = %wu, m5 = %wu\n\n", n, p, m, m5); flint_abort(); } flint_free(divtab_odd); } _fmpz_vec_clear(En, nmax); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-exp.c000066400000000000000000000152661417376376500153230ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* check accuracy compared to reference algorithm */ void arb_exp_simple(arb_t res, const arb_t x, slong prec) { mag_t t, u; mag_init_set(t, arb_radref(x)); mag_init(u); arf_set(arb_midref(res), arb_midref(x)); mag_zero(arb_radref(res)); arb_exp(res, x, prec); mag_expm1(t, t); arb_get_mag(u, res); mag_addmul(arb_radref(res), t, u); mag_clear(t); mag_clear(u); } int main() { slong iter; flint_rand_t state; flint_printf("exp...."); fflush(stdout); flint_randinit(state); /* check large arguments + compare with exp_simple */ for (iter = 0; iter < 100000 *arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec0, prec1, prec2, acc1, acc2; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_exp(b, a, prec1); arb_exp(c, a, prec2); arb_exp_simple(d, a, prec1); if (!arb_overlaps(b, c) || !arb_overlaps(b, d) || !arb_overlaps(c, d)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } /* compare accuracy with exp_simple */ acc1 = arb_rel_accuracy_bits(b); acc2 = arb_rel_accuracy_bits(d); if (acc2 > 0 && acc1 < acc2 - 1) { flint_printf("FAIL: accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd, acc2 = %wd\n\n", prec1, acc1, acc2); flint_printf("a = "); arb_printd(a, 50); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 50); flint_printf("\n\n"); flint_printf("d = "); arb_printd(d, 50); flint_printf("\n\n"); flint_abort(); } arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); /* check exp(a)*exp(b) = exp(a+b) */ arb_exp(c, a, prec1); arb_exp(d, b, prec1); arb_mul(c, c, d, prec1); arb_add(d, a, b, prec1); arb_exp(d, d, prec1); if (!arb_overlaps(c, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* test union */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d, e; slong prec0, prec1, prec2, prec3, prec4; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); prec3 = 2 + n_randint(state, prec0); prec4 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(e); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 200); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 200); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 200); arb_randtest_special(d, state, 1 + n_randint(state, prec0), 200); arb_randtest_special(e, state, 1 + n_randint(state, prec0), 200); arb_exp(c, a, prec1); arb_exp(d, b, prec2); arb_union(e, a, b, prec3); arb_exp(e, e, prec4); if (!arb_overlaps(e, c) || !arb_overlaps(e, d)) { flint_printf("FAIL: union\n\n"); flint_printf("a = "); arb_printn(a, 1000, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 1000, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 1000, 0); flint_printf("\n\n"); flint_printf("d = "); arb_printn(d, 1000, 0); flint_printf("\n\n"); flint_printf("e = "); arb_printn(e, 1000, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(e); } /* comparison with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec0, prec; prec0 = 400; if (iter % 100 == 0) prec0 = 10000; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, prec0), 4); arb_randtest(b, state, 1 + n_randint(state, prec0), 4); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, prec0)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_exp(t, t, MPFR_RNDN); arb_exp(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("iter = %wd, prec = %wd\n\n", iter, prec); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_exp(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("iter = %wd, prec = %wd\n\n", iter, prec); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-exp_arf_bb.c000066400000000000000000000057011417376376500166070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_exp_arf_via_mpfr(arb_t z, const arf_t x, slong prec) { mpfr_t t, u; int exact; mpfr_init2(t, 2 + arf_bits(x)); mpfr_init2(u, prec); mpfr_set_emin(MPFR_EMIN_MIN); mpfr_set_emax(MPFR_EMAX_MAX); arf_get_mpfr(t, x, MPFR_RNDD); exact = (mpfr_exp(u, t, MPFR_RNDD) == 0); arf_set_mpfr(arb_midref(z), u); if (!exact) arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec); mpfr_clear(t); mpfr_clear(u); } int main() { slong iter; flint_rand_t state; flint_printf("exp_arf_bb...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_t x, y, z; slong prec = 2 + n_randint(state, 8000); arb_init(x); arb_init(y); arb_init(z); arb_randtest(x, state, 1 + n_randint(state, 8000), 3); mag_zero(arb_radref(x)); if (n_randint(state, 2)) { if ((FLINT_BITS == 64) && (sizeof(mpfr_exp_t) >= sizeof(slong))) arb_mul_2exp_si(x, x, 1 + n_randint(state, 40)); else arb_mul_2exp_si(x, x, 1 + n_randint(state, 20)); } else { arb_mul_2exp_si(x, x, -n_randint(state, 1.5 * prec)); } arb_exp_arf_via_mpfr(y, arb_midref(x), prec + 100); arb_exp_arf_bb(z, arb_midref(x), prec, 0); if (!arb_contains(z, y)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 50); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(z) < prec - 2) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd, acc = %wd\n\n", prec, arb_rel_accuracy_bits(z)); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } arb_exp_arf_bb(x, arb_midref(x), prec, 0); if (!arb_overlaps(x, z)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-exp_arf_rs_generic.c000066400000000000000000000075371417376376500203550ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* these functions are not exposed to the public for now, but it still makes sense to test them explicitly */ void arb_exp_taylor_sum_rs_generic(arb_t s, const arb_t x, slong N, slong prec); int main() { slong iter; flint_rand_t state; flint_printf("exp_arf_rs_generic...."); fflush(stdout); flint_randinit(state); /* test the rs algorithm explicitly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, s1, s2; slong prec; int minus1; arb_init(x); arb_init(s1); arb_init(s2); prec = 2 + n_randint(state, 2000); minus1 = n_randint(state, 2); arb_randtest(x, state, 1 + n_randint(state, 2000), 3); mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_mul_2exp_si(x, x, -n_randint(state, 2 * prec)); if (minus1) arb_expm1(s1, x, prec); else arb_exp(s1, x, prec); switch (n_randint(state, 2)) { case 0: arb_exp_arf_rs_generic(s2, arb_midref(x), prec, minus1); break; case 1: arb_set(s2, x); arb_exp_arf_rs_generic(s2, arb_midref(s2), prec, minus1); break; } if (!arb_overlaps(s1, s2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd, minus1 = %d\n\n", prec, minus1); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(s2) < prec - 2) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd, acc1 = %wd, minus1 = %d\n\n", prec, arb_rel_accuracy_bits(s2), minus1); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(s1); arb_clear(s2); } /* test the series evaluation code directly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z; slong prec; slong N; arb_init(x); arb_init(y); arb_init(z); prec = 2 + n_randint(state, 2000); N = n_randint(state, 100); arb_randtest(x, state, 1 + n_randint(state, 2000), 1); mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_mul_2exp_si(x, x, -n_randint(state, 2 * prec)); arb_exp(y, x, prec); arb_exp_taylor_sum_rs_generic(z, x, N, prec); if (!arb_overlaps(z, y)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd, N = %wd\n\n", prec, N); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 500, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 500, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-exp_invexp.c000066400000000000000000000060051417376376500167030ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_invexp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec, acc1, acc2; if (iter % 10 == 0) prec = 10000; else prec = 1000; prec = 2 + n_randint(state, prec); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec), 1 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, prec), 1 + n_randint(state, 100)); arb_randtest_special(c, state, 1 + n_randint(state, prec), 1 + n_randint(state, 100)); if (n_randint(state, 2)) { arb_exp_invexp(b, c, a, prec); } else if (n_randint(state, 2)) { arb_set(b, a); arb_exp_invexp(b, c, b, prec); } else { arb_set(c, a); arb_exp_invexp(b, c, c, prec); } arb_exp(d, a, prec); acc1 = arb_rel_accuracy_bits(b); acc2 = arb_rel_accuracy_bits(d); if (!arb_overlaps(b, d) || ((acc1 > 0 || acc2 > 0) && acc1 < FLINT_MIN(acc2, prec) - 3)) { flint_printf("FAIL: overlap 1\n\n"); flint_printf("prec = %wd, acc1 = %wd, acc2 = %wd\n\n", prec, acc1, acc2); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_neg(d, a); arb_exp(d, d, prec); acc1 = arb_rel_accuracy_bits(c); acc2 = arb_rel_accuracy_bits(d); if (!arb_overlaps(c, d) || ((acc1 > 0 || acc2 > 0) && acc1 < FLINT_MIN(acc2, prec) - 3)) { flint_printf("FAIL: overlap 2\n\n"); flint_printf("prec = %wd, acc1 = %wd, acc2 = %wd\n\n", prec, acc1, acc2); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-exp_sum_bs_powtab.c000066400000000000000000000036651417376376500202470ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_sum_bs_powtab...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong N; fmpz_t x, T, Q; fmpq_t S, V; flint_bitcnt_t Qexp, r; fmpz_init(x); fmpz_init(T); fmpz_init(Q); fmpq_init(S); fmpq_init(V); N = 1 + n_randint(state, 300); r = n_randint(state, 10); fmpz_randtest(x, state, 80); _arb_exp_sum_bs_simple(T, Q, &Qexp, x, r, N); fmpq_set_fmpz_frac(S, T, Q); fmpq_div_2exp(S, S, Qexp); _arb_exp_sum_bs_powtab(T, Q, &Qexp, x, r, N); fmpq_set_fmpz_frac(V, T, Q); fmpq_div_2exp(V, V, Qexp); if (!fmpq_equal(S, V)) { flint_printf("FAIL\n\n"); flint_printf("N = %wd\n\n", N); flint_printf("r = %wu\n\n", r); flint_printf("x = "); fmpz_print(x); flint_printf("\n\n"); flint_printf("T = "); fmpz_print(T); flint_printf("\n\n"); flint_printf("Q = "); fmpz_print(T); flint_printf("\n\n"); flint_printf("V = "); fmpq_print(V); flint_printf("\n\n"); flint_printf("S = "); fmpq_print(S); flint_printf("\n\n"); flint_abort(); } fmpz_clear(x); fmpz_clear(T); fmpz_clear(Q); fmpq_clear(S); fmpq_clear(V); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-exp_tab.c000066400000000000000000000120031417376376500161330ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong i; mpfr_t tabx, expx, y1, y2; mpz_t tt; flint_printf("exp_tab...."); fflush(stdout); { slong prec, bits, num; prec = ARB_EXP_TAB1_LIMBS * FLINT_BITS; bits = ARB_EXP_TAB1_BITS; num = ARB_EXP_TAB1_NUM; mpfr_init2(tabx, prec); mpfr_init2(expx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_exp_tab1[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(expx, i, MPFR_RNDD); mpfr_div_2ui(expx, expx, bits, MPFR_RNDD); mpfr_exp(expx, expx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, expx, prec - 1, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(expx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_EXP_TAB2_LIMBS * FLINT_BITS; bits = ARB_EXP_TAB21_BITS; num = ARB_EXP_TAB21_NUM; mpfr_init2(tabx, prec); mpfr_init2(expx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_exp_tab21[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(expx, i, MPFR_RNDD); mpfr_div_2ui(expx, expx, bits, MPFR_RNDD); mpfr_exp(expx, expx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, expx, prec - 1, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(expx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_EXP_TAB2_LIMBS * FLINT_BITS; bits = ARB_EXP_TAB21_BITS + ARB_EXP_TAB22_BITS; num = ARB_EXP_TAB22_NUM; mpfr_init2(tabx, prec); mpfr_init2(expx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_exp_tab22[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(expx, i, MPFR_RNDD); mpfr_div_2ui(expx, expx, bits, MPFR_RNDD); mpfr_exp(expx, expx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, expx, prec - 1, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(expx); mpfr_clear(y1); mpfr_clear(y2); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-exp_taylor_rs.c000066400000000000000000000045361417376376500174170ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/mpn_extras.h" #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_taylor_rs...."); fflush(stdout); flint_randinit(state); _flint_rand_init_gmp(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mp_ptr x, y1, y2, t; mp_limb_t err1, err2; ulong N; mp_size_t xn; int cmp, result; N = n_randint(state, 288 - 1); xn = 1 + n_randint(state, 20); x = flint_malloc(sizeof(mp_limb_t) * xn); y1 = flint_malloc(sizeof(mp_limb_t) * (xn + 1)); y2 = flint_malloc(sizeof(mp_limb_t) * (xn + 1)); t = flint_malloc(sizeof(mp_limb_t) * (xn + 1)); flint_mpn_rrandom(x, state->gmp_state, xn); flint_mpn_rrandom(y1, state->gmp_state, xn + 1); flint_mpn_rrandom(y2, state->gmp_state, xn + 1); x[xn - 1] &= (LIMB_ONES >> 4); _arb_exp_taylor_naive(y1, &err1, x, xn, N); _arb_exp_taylor_rs(y2, &err2, x, xn, N); cmp = mpn_cmp(y1, y2, xn + 1); if (cmp == 0) { result = 1; } else if (cmp > 0) { mpn_sub_n(t, y1, y2, xn + 1); result = flint_mpn_zero_p(t + 1, xn) && (t[0] <= err2); } else { mpn_sub_n(t, y2, y1, xn + 1); result = flint_mpn_zero_p(t + 1, xn) && (t[0] <= err2); } if (!result) { flint_printf("FAIL\n"); flint_printf("N = %wd xn = %wd\n", N, xn); flint_printf("x ="); flint_mpn_debug(x, xn); flint_printf("y1 ="); flint_mpn_debug(y1, xn + 1); flint_printf("y2 ="); flint_mpn_debug(y2, xn + 1); flint_abort(); } flint_free(x); flint_free(y1); flint_free(y2); flint_free(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-expm1.c000066400000000000000000000100441417376376500155460ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("expm1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec0, prec; prec0 = 400; if (iter % 100 == 0) prec0 = 10000; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, prec0), 4); arb_randtest(b, state, 1 + n_randint(state, prec0), 4); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, prec0)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_expm1(t, t, MPFR_RNDN); arb_expm1(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("iter = %wd, prec = %wd\n\n", iter, prec); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_expm1(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("iter = %wd, prec = %wd\n\n", iter, prec); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* check large arguments */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec0, prec1, prec2, acc1, acc2; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_expm1(b, a, prec1); arb_set(c, a); /* also tests aliasing */ arb_expm1(c, c, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); /* compare with exp */ arb_expm1(c, a, prec1); arb_exp(d, a, prec1); arb_sub_ui(d, d, 1, prec1); acc1 = arb_rel_accuracy_bits(c); acc2 = arb_rel_accuracy_bits(d); if (!arb_overlaps(c, d) || ((acc2 > 0) && acc1 < FLINT_MIN(acc2, prec1) - 3)) { flint_printf("FAIL: comparison with exp\n\n"); flint_printf("prec = %wd, acc1 = %wd, acc2 = %wd\n\n", prec1, acc1, acc2); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-fac_ui.c000066400000000000000000000027621417376376500157520ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("fac_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong n; slong prec1, prec2; prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); arb_init(a); arb_init(b); arb_init(c); n = n_randtest(state); if (n + 1 == 0) n--; arb_fac_ui(a, n, prec1); arb_fac_ui(b, n + 1, prec1); arb_mul_ui(c, a, n + 1, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-floor.c000066400000000000000000000037351417376376500156460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("floor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x; fmpz_t y; slong prec; arb_init(a); arb_init(b); fmpq_init(x); fmpz_init(y); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_floor(b, a, prec); fmpz_fdiv_q(y, fmpq_numref(x), fmpq_denref(x)); if (!arb_contains_fmpz(b, y)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_abort(); } arb_floor(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpz_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-fma.c000066400000000000000000000071001417376376500152560ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_fma_naive(arb_t res, const arb_t x, const arb_t y, const arb_t z, slong prec) { arb_t t; arb_init(t); arb_set(t, z); arb_addmul(t, x, y, prec); arb_set(res, t); arb_clear(t); } int main() { slong iter; flint_rand_t state; flint_printf("fma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z, res1, res2; slong prec; int aliasing; arb_init(x); arb_init(y); arb_init(z); arb_init(res1); arb_init(res2); prec = 2 + n_randint(state, 200); arb_randtest_special(x, state, 200, 100); arb_randtest_special(y, state, 200, 100); arb_randtest_special(z, state, 200, 100); arb_randtest_special(res1, state, 200, 100); arb_randtest_special(res2, state, 200, 100); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(arb_midref(x))) < 10 && fmpz_bits(ARF_EXPREF(arb_midref(y))) < 10 && fmpz_bits(ARF_EXPREF(arb_midref(z))) < 10) { prec = ARF_PREC_EXACT; } aliasing = n_randint(state, 7); switch (aliasing) { case 0: arb_fma(res1, x, y, z, prec); arb_fma_naive(res2, x, y, z, prec); break; case 1: arb_set(res1, z); arb_fma(res1, x, y, res1, prec); arb_fma_naive(res2, x, y, z, prec); break; case 2: arb_set(res1, x); arb_fma(res1, res1, y, z, prec); arb_fma_naive(res2, x, y, z, prec); break; case 3: arb_set(res1, y); arb_fma(res1, x, res1, z, prec); arb_fma_naive(res2, x, y, z, prec); break; case 4: arb_fma(res1, x, x, z, prec); arb_fma_naive(res2, x, x, z, prec); break; case 5: arb_set(res1, x); arb_fma(res1, res1, res1, z, prec); arb_fma_naive(res2, x, x, z, prec); break; default: arb_set(res1, x); arb_fma(res1, res1, res1, res1, prec); arb_fma_naive(res2, x, x, x, prec); break; } if (!arb_equal(res1, res2)) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, aliasing = %d\n\n", prec, aliasing); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_printf("res1 = "); arb_printd(res1, 30); flint_printf("\n\n"); flint_printf("res2 = "); arb_printd(res2, 30); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); arb_clear(res1); arb_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-gamma.c000066400000000000000000000036311417376376500156020ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 3); arb_gamma(b, a, prec1); arb_gamma(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check gamma(z+1) = z gamma(z) */ arb_mul(b, b, a, prec1); arb_add_ui(c, a, 1, prec1); arb_gamma(c, c, prec1); if (!arb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-gamma_fmpq.c000066400000000000000000000074621417376376500166330ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t r, s; fmpq_t q; slong accuracy, prec, pp, qq; prec = 2 + n_randint(state, 1 << n_randint(state, 12)); prec += 20; arb_init(r); arb_init(s); fmpq_init(q); pp = -100 + n_randint(state, 10000); qq = 1 + n_randint(state, 20); fmpq_set_si(q, pp, qq); arb_gamma_fmpq(r, q, prec); arb_set_fmpq(s, q, prec); arb_gamma(s, s, prec); if (!arb_overlaps(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); arb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_abort(); } if (!(fmpz_is_one(fmpq_denref(q)) && fmpz_sgn(fmpq_numref(q)) <= 0) && FLINT_ABS(pp / qq) < 10) { accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 6) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } arb_clear(r); arb_clear(s); fmpq_clear(q); } for (iter = 0; iter < 50 * arb_test_multiplier(); iter++) { arb_t r, s; fmpq_t q; slong accuracy, prec; prec = 2 + n_randint(state, 25000); arb_init(r); arb_init(s); fmpq_init(q); fmpz_randtest(fmpq_numref(q), state, 3 + n_randlimb(state) % 30); fmpz_randtest_not_zero(fmpq_denref(q), state, 3 + n_randlimb(state) % 30); fmpq_canonicalise(q); arb_gamma_fmpq(r, q, prec); arb_set_fmpq(s, q, prec); arb_gamma(s, s, prec); if (!arb_overlaps(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); arb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_abort(); } if (!(fmpz_is_one(fmpq_denref(q)) && fmpz_sgn(fmpq_numref(q)) <= 0) && fabs(fmpq_get_d(q)) < 10.0) { accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 6) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, prec / 3.33, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, prec / 3.33, 0); flint_printf("\n\n"); flint_abort(); } } arb_clear(r); arb_clear(s); fmpq_clear(q); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_abs_lbound_arf.c000066400000000000000000000061241417376376500203170ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_abs_lbound_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; arf_t b, b2, b3; fmpq_t q; arb_init(x); arf_init(b); arf_init(b2); arf_init(b3); fmpq_init(q); arb_randtest(x, state, 1 + n_randint(state, 200), 10); arb_get_abs_lbound_arf(b, x, 2 + n_randint(state, 200)); arb_get_rand_fmpq(q, state, x, 1 + n_randint(state, 200)); arf_mul_fmpz(b2, b, fmpq_denref(q), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_fmpz(b3, fmpq_numref(q)); arf_abs(b3, b3); if (arf_cmp(b2, b3) > 0) { flint_printf("FAIL (abs_lbound):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("b2 = "); arf_print(b2); flint_printf("\n\n"); flint_printf("b3 = "); arf_print(b3); flint_printf("\n\n"); flint_abort(); } arb_get_abs_ubound_arf(b, x, 2 + n_randint(state, 200)); arb_get_rand_fmpq(q, state, x, 1 + n_randint(state, 200)); arf_mul_fmpz(b2, b, fmpq_denref(q), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_fmpz(b3, fmpq_numref(q)); arf_abs(b3, b3); if (arf_cmp(b2, b3) < 0) { flint_printf("FAIL (abs_ubound):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("b2 = "); arf_print(b2); flint_printf("\n\n"); flint_printf("b3 = "); arf_print(b3); flint_printf("\n\n"); flint_abort(); } arb_randtest_special(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); arb_get_abs_lbound_arf(b, x, 2 + n_randint(state, 200)); arb_get_abs_ubound_arf(b2, x, 2 + n_randint(state, 200)); if (arf_cmp(b, b2) > 0) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("b2 = "); arf_print(b2); flint_printf("\n\n"); flint_abort(); } arb_clear(x); fmpq_clear(q); arf_clear(b); arf_clear(b2); arf_clear(b3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_fmpz_mid_rad_10exp.c000066400000000000000000000051121417376376500210230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_fmpz_mid_rad_10exp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_t x, y, t; fmpz_t mid, rad, exp; slong n, prec; arb_init(x); arb_init(y); arb_init(t); fmpz_init(mid); fmpz_init(rad); fmpz_init(exp); arb_randtest_special(x, state, 1 + n_randint(state, 500), 1 + n_randint(state, 500)); n = 1 + n_randint(state, 500); prec = 2 + n_randint(state, 1500); arb_get_fmpz_mid_rad_10exp(mid, rad, exp, x, n); arf_set_fmpz(arb_midref(y), mid); mag_set_fmpz(arb_radref(y), rad); arb_set_ui(t, 10); arb_pow_fmpz(t, t, exp, prec); arb_mul(y, y, t, prec); if (arb_is_finite(x) && !arb_is_zero(x) && fmpz_sizeinbase(mid, 10) < n && fmpz_sizeinbase(rad, 10) < n) { flint_printf("FAIL (too few digits):\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_printf("mid = "); fmpz_print(mid); flint_printf("\n\n"); flint_printf("rad = "); fmpz_print(rad); flint_printf("\n\n"); flint_printf("exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_abort(); } if (arb_is_finite(x) && !arb_contains(y, x)) { flint_printf("FAIL (containment):\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_printf("mid = "); fmpz_print(mid); flint_printf("\n\n"); flint_printf("rad = "); fmpz_print(rad); flint_printf("\n\n"); flint_printf("exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(t); fmpz_clear(mid); fmpz_clear(rad); fmpz_clear(exp); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_interval_arf.c000066400000000000000000000027631417376376500200400ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_interval_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y; arf_t a, b; arb_init(x); arf_init(a); arf_init(b); arb_init(y); arb_randtest_special(x, state, 200, 100); arb_get_interval_arf(a, b, x, 2 + n_randint(state, 200)); arb_set_interval_arf(y, a, b, 2 + n_randint(state, 200)); if (!arb_contains(y, x)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arf_clear(a); arf_clear(b); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_interval_fmpz_2exp.c000066400000000000000000000044131417376376500211740ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_interval_fmpz_2exp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x; arf_t y; fmpz_t a, b, exp; arb_init(x); arf_init(y); fmpz_init(a); fmpz_init(b); fmpz_init(exp); arb_randtest(x, state, 200, 10); arb_get_interval_fmpz_2exp(a, b, exp, x); arf_set_fmpz_2exp(y, a, exp); if (!arb_contains_arf(x, y)) { flint_printf("FAIL (a):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); fmpz_print(a); flint_printf(" exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_abort(); } arf_set_fmpz_2exp(y, b, exp); if (!arb_contains_arf(x, y)) { flint_printf("FAIL (b):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf(" exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_abort(); } if (fmpz_is_even(a) && fmpz_is_even(b) && !(fmpz_is_zero(a) && fmpz_is_zero(b))) { flint_printf("FAIL (odd):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf(" exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arf_clear(y); fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_interval_mpfr.c000066400000000000000000000030751417376376500202310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_interval_mpfr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y; mpfr_t aa, bb; arb_init(x); arb_init(y); mpfr_init2(aa, 2 + n_randint(state, 200)); mpfr_init2(bb, 2 + n_randint(state, 200)); arb_randtest_special(x, state, 200, 10); arb_get_interval_mpfr(aa, bb, x); arb_set_interval_mpfr(y, aa, bb, 2 + n_randint(state, 200)); if (!arb_contains(y, x)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("aa = "); mpfr_printf("%.50Rg", aa); flint_printf("\n\n"); flint_printf("bb = "); mpfr_printf("%.50Rg", bb); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); mpfr_clear(aa); mpfr_clear(bb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_lbound_arf.c000066400000000000000000000060061417376376500174710ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_lbound_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; arf_t b, b2, b3; fmpq_t q; arb_init(x); arf_init(b); arf_init(b2); arf_init(b3); fmpq_init(q); arb_randtest(x, state, 1 + n_randint(state, 200), 10); arb_get_lbound_arf(b, x, 2 + n_randint(state, 200)); arb_get_rand_fmpq(q, state, x, 1 + n_randint(state, 200)); arf_mul_fmpz(b2, b, fmpq_denref(q), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_fmpz(b3, fmpq_numref(q)); if (arf_cmp(b2, b3) > 0) { flint_printf("FAIL (lbound):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("b2 = "); arf_print(b2); flint_printf("\n\n"); flint_printf("b3 = "); arf_print(b3); flint_printf("\n\n"); flint_abort(); } arb_get_ubound_arf(b, x, 2 + n_randint(state, 200)); arb_get_rand_fmpq(q, state, x, 1 + n_randint(state, 200)); arf_mul_fmpz(b2, b, fmpq_denref(q), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_fmpz(b3, fmpq_numref(q)); if (arf_cmp(b2, b3) < 0) { flint_printf("FAIL (ubound):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("b2 = "); arf_print(b2); flint_printf("\n\n"); flint_printf("b3 = "); arf_print(b3); flint_printf("\n\n"); flint_abort(); } arb_randtest_special(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); arb_get_lbound_arf(b, x, 2 + n_randint(state, 200)); arb_get_ubound_arf(b2, x, 2 + n_randint(state, 200)); if (arf_cmp(b, b2) > 0) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("b2 = "); arf_print(b2); flint_printf("\n\n"); flint_abort(); } arb_clear(x); fmpq_clear(q); arf_clear(b); arf_clear(b2); arf_clear(b3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_mag.c000066400000000000000000000027361417376376500161300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mag...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; mag_t m; arb_init(a); arb_init(b); mag_init(m); arb_randtest_special(a, state, 200, 1 + n_randint(state, 100)); arb_get_mag(m, a); MAG_CHECK_BITS(m) if (arf_is_nan(arb_midref(a))) arf_nan(arb_midref(b)); else arf_zero(arb_midref(b)); mag_set(arb_radref(b), m); if (!arb_contains(b, a)) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("m = "); mag_print(m); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); mag_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_mag_lower.c000066400000000000000000000036661417376376500173430ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mag_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a; mag_t m; int result; arf_struct t[3]; arf_t s; arb_init(a); mag_init(m); arf_init(s); arb_randtest_special(a, state, 200, 1 + n_randint(state, 100)); arb_get_mag_lower(m, a); MAG_CHECK_BITS(m) if (arb_contains_zero(a)) { result = mag_is_zero(m); } else if (arb_contains_negative(a)) { arf_init_set_shallow(t + 0, arb_midref(a)); arf_init_set_mag_shallow(t + 1, arb_radref(a)); arf_init_set_mag_shallow(t + 2, m); arf_sum(s, t, 3, 16, ARF_RND_DOWN); result = (arf_sgn(s) <= 0); } else { arf_init_set_shallow(t + 0, arb_midref(a)); arf_init_neg_mag_shallow(t + 1, arb_radref(a)); arf_init_neg_mag_shallow(t + 2, m); result = (arf_sgn(s) >= 0); } if (!result) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("m = "); mag_print(m); flint_printf("\n\n"); flint_abort(); } arb_clear(a); mag_clear(m); arf_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_mag_lower_nonnegative.c000066400000000000000000000033121417376376500217240ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mag_lower_nonnegative...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a; mag_t m; int result; arf_struct t[3]; arf_t s; arb_init(a); mag_init(m); arf_init(s); arb_randtest_special(a, state, 200, 1 + n_randint(state, 100)); arb_get_mag_lower_nonnegative(m, a); MAG_CHECK_BITS(m) if (arb_contains_nonpositive(a)) { result = mag_is_zero(m); } else { arf_init_set_shallow(t + 0, arb_midref(a)); arf_init_neg_mag_shallow(t + 1, arb_radref(a)); arf_init_neg_mag_shallow(t + 2, m); arf_sum(s, t, 3, 16, ARF_RND_DOWN); result = (arf_sgn(s) >= 0); } if (!result) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("m = "); mag_print(m); flint_printf("\n\n"); flint_abort(); } arb_clear(a); mag_clear(m); arf_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_mpn_fixed_mod_log2.c000066400000000000000000000056461417376376500211220ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mpn_fixed_mod_log2...."); fflush(stdout); flint_randinit(state); /* _flint_rand_init_gmp(state); */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t x; fmpz_t q; mp_ptr w; arb_t wb, t; mp_size_t wn; slong prec, prec2; int success; mp_limb_t error; prec = 2 + n_randint(state, 10000); wn = 1 + n_randint(state, 200); prec2 = FLINT_MAX(prec, wn * FLINT_BITS) + 100; arf_init(x); arb_init(wb); arb_init(t); fmpz_init(q); w = flint_malloc(sizeof(mp_limb_t) * wn); arf_randtest(x, state, prec, 14); /* this should generate numbers close to multiples of log(2) */ if (n_randint(state, 4) == 0) { arb_const_log2(t, prec); fmpz_randtest(q, state, 200); arb_mul_fmpz(t, t, q, prec); arf_add(x, x, arb_midref(t), prec, ARF_RND_DOWN); } success = _arb_get_mpn_fixed_mod_log2(w, q, &error, x, wn); if (success) { _arf_set_mpn_fixed(arb_midref(wb), w, wn, wn, 0, FLINT_BITS * wn, ARB_RND); mag_set_ui_2exp_si(arb_radref(wb), error, -FLINT_BITS * wn); arb_const_log2(t, prec2); arb_mul_fmpz(t, t, q, prec2); arb_add(t, t, wb, prec2); if (!arb_contains_arf(t, x)) { flint_printf("FAIL (containment)\n"); flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n"); flint_printf("q = "); fmpz_print(q); flint_printf("\n\n"); flint_printf("w = "); arb_printd(wb, 50); flint_printf("\n\n"); flint_printf("t = "); arb_printd(t, 50); flint_printf("\n\n"); flint_abort(); } arb_const_log2(t, prec2); if (arf_sgn(arb_midref(wb)) < 0 || arf_cmp(arb_midref(wb), arb_midref(t)) >= 0) { flint_printf("FAIL (expected 0 <= w < log(2))\n"); flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n"); flint_printf("w = "); arb_printd(wb, 50); flint_printf("\n\n"); flint_abort(); } } flint_free(w); fmpz_clear(q); arf_clear(x); arb_clear(wb); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_mpn_fixed_mod_pi4.c000066400000000000000000000065661417376376500207550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mpn_fixed_mod_pi4...."); fflush(stdout); flint_randinit(state); /* _flint_rand_init_gmp(state); */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t x; int octant; fmpz_t q; mp_ptr w; arb_t wb, t, u; mp_size_t wn; slong prec, prec2; int success; mp_limb_t error; prec = 2 + n_randint(state, 10000); wn = 1 + n_randint(state, 200); prec2 = FLINT_MAX(prec, wn * FLINT_BITS) + 100; arf_init(x); arb_init(wb); arb_init(t); arb_init(u); fmpz_init(q); w = flint_malloc(sizeof(mp_limb_t) * wn); arf_randtest(x, state, prec, 14); /* this should generate numbers close to multiples of pi/4 */ if (n_randint(state, 4) == 0) { arb_const_pi(t, prec); arb_mul_2exp_si(t, t, -2); fmpz_randtest(q, state, 200); arb_mul_fmpz(t, t, q, prec); arf_add(x, x, arb_midref(t), prec, ARF_RND_DOWN); } arf_abs(x, x); success = _arb_get_mpn_fixed_mod_pi4(w, q, &octant, &error, x, wn); if (success) { /* could round differently */ if (fmpz_fdiv_ui(q, 8) != octant) { flint_printf("bad octant\n"); flint_abort(); } _arf_set_mpn_fixed(arb_midref(wb), w, wn, wn, 0, FLINT_BITS * wn, ARB_RND); mag_set_ui_2exp_si(arb_radref(wb), error, -FLINT_BITS * wn); arb_const_pi(u, prec2); arb_mul_2exp_si(u, u, -2); arb_set(t, wb); if (octant % 2 == 1) arb_sub(t, u, t, prec2); arb_addmul_fmpz(t, u, q, prec2); if (!arb_contains_arf(t, x)) { flint_printf("FAIL (containment)\n"); flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n"); flint_printf("q = "); fmpz_print(q); flint_printf("\n\n"); flint_printf("w = "); arb_printd(wb, 50); flint_printf("\n\n"); flint_printf("t = "); arb_printd(t, 50); flint_printf("\n\n"); flint_abort(); } arb_const_pi(t, prec2); arb_mul_2exp_si(t, t, -2); if (arf_sgn(arb_midref(wb)) < 0 || arf_cmp(arb_midref(wb), arb_midref(t)) >= 0) { flint_printf("FAIL (expected 0 <= w < pi/4)\n"); flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n"); flint_printf("w = "); arb_printd(wb, 50); flint_printf("\n\n"); flint_abort(); } } flint_free(w); fmpz_clear(q); arf_clear(x); arb_clear(wb); arb_clear(t); arb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_rand_fmpq.c000066400000000000000000000023651417376376500173310ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_rand_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x; fmpq_t q; arb_init(x); fmpq_init(q); arb_randtest(x, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(q, state, x, 1 + n_randint(state, 200)); if (!arb_contains_fmpq(x, q) || !fmpq_is_canonical(q)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_abort(); } arb_clear(x); fmpq_clear(q); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_str.c000066400000000000000000000075531417376376500161760ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { flint_rand_t state; slong iter; flint_printf("get_str...."); fflush(stdout); flint_randinit(state); /* just test no crashing... */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; char * s; slong n; arb_init(x); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); n = 1 + n_randint(state, 300); s = arb_get_str(x, n, (n_randint(state, 2) * ARB_STR_MORE) | (n_randint(state, 2) * ARB_STR_NO_RADIUS) | (ARB_STR_CONDENSE * n_randint(state, 50))); flint_free(s); arb_clear(x); } for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y; char * s; slong n, prec; int conversion_error; arb_init(x); arb_init(y); arb_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); n = 1 + n_randint(state, 300); prec = 2 + n_randint(state, 1000); s = arb_get_str(x, n, n_randint(state, 2) * ARB_STR_MORE); conversion_error = arb_set_str(y, s, prec); if (conversion_error || !arb_contains(y, x)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("s = %s", s); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } flint_free(s); arb_clear(x); arb_clear(y); } /* test ARB_STR_NO_RADIUS */ { arb_t x; char * s; arb_init(x); arb_set_str(x, "3.1415926535897932", 53); s = arb_get_str(x, 10, ARB_STR_NO_RADIUS); if (strcmp(s, "3.141592654")) { flint_printf("FAIL (ARB_STR_NO_RADIUS)\n"); flint_printf("%s\n", s); flint_abort(); } flint_free(s); arb_set_str(x, "+/- 3.45e-10", 53); s = arb_get_str(x, 10, ARB_STR_NO_RADIUS); if (strcmp(s, "0e-9")) { flint_printf("FAIL (ARB_STR_NO_RADIUS)\n"); flint_printf("%s\n", s); flint_abort(); } flint_free(s); arb_set_str(x, "+/- 3.45e10", 53); s = arb_get_str(x, 10, ARB_STR_NO_RADIUS); if (strcmp(s, "0e+11")) { flint_printf("FAIL (ARB_STR_NO_RADIUS)\n"); flint_printf("%s\n", s); flint_abort(); } flint_free(s); arb_set_str(x, "5e10 +/- 6e10", 53); s = arb_get_str(x, 10, ARB_STR_NO_RADIUS); if (strcmp(s, "0e+12")) { flint_printf("FAIL (ARB_STR_NO_RADIUS)\n"); flint_printf("%s\n", s); flint_abort(); } flint_free(s); arb_set_str(x, "5e-100000000000000000002 +/- 5e-100000000000000000002", 53); s = arb_get_str(x, 10, ARB_STR_NO_RADIUS); if (strcmp(s, "0e-100000000000000000000")) { flint_printf("FAIL (ARB_STR_NO_RADIUS)\n"); flint_printf("%s\n", s); flint_abort(); } flint_free(s); arb_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-get_unique_fmpz.c000066400000000000000000000117761417376376500177320ustar00rootroot00000000000000/* Copyright (C) 2012, 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_unique_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, z; fmpz_t y, a, b, exp; int unique, unique2; arb_init(x); arb_init(z); fmpz_init(y); fmpz_init(a); fmpz_init(b); fmpz_init(exp); arb_randtest(x, state, 2000, 10); /* generate tiny and huge radii */ if (iter % 2 == 0) { mag_randtest_special(arb_radref(x), state, 100); unique = arb_get_unique_fmpz(y, x); arf_get_fmpz(a, arb_midref(x), ARF_RND_FLOOR); fmpz_add_ui(b, a, 1); if (unique) { if (arb_contains_fmpz(x, a) == arb_contains_fmpz(x, b)) { flint_printf("FAIL (1):\n\n"); flint_printf("x = "); arb_printd(x, 100); flint_printf("\n\n"); flint_printf("unique = %d\n\n", unique); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_abort(); } } else { if (arb_contains_fmpz(x, a) != arb_contains_fmpz(x, b)) { flint_printf("FAIL (2):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("unique = %d\n\n", unique); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_abort(); } } } else { unique = arb_get_unique_fmpz(y, x); arb_get_interval_fmpz_2exp(a, b, exp, x); if (fmpz_sgn(exp) >= 0) { fmpz_mul_2exp(a, a, fmpz_get_si(exp)); fmpz_mul_2exp(b, b, fmpz_get_si(exp)); } else { fmpz_cdiv_q_2exp(a, a, -fmpz_get_si(exp)); fmpz_fdiv_q_2exp(b, b, -fmpz_get_si(exp)); } unique2 = fmpz_equal(a, b); if ((unique != unique2) || (unique && !fmpz_equal(y, a))) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("unique = %d, unique2 = %d\n\n", unique, unique2); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf(" exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_abort(); } if (unique) { arb_set_fmpz(z, y); arb_set_round(z, z, 2 + n_randint(state, 1000)); if (!arb_overlaps(x, z)) { flint_printf("FAIL (overlap):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } fmpz_add_ui(b, y, 1); if (arb_contains_fmpz(x, b)) { flint_printf("FAIL (contains a + 1):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_abort(); } fmpz_sub_ui(b, y, 1); if (arb_contains_fmpz(x, b)) { flint_printf("FAIL (contains a - 1):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_abort(); } } } arb_clear(x); arb_clear(z); fmpz_clear(y); fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-hurwitz_zeta.c000066400000000000000000000041141417376376500172540ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "acb.h" int main() { slong iter; flint_rand_t state; flint_printf("hurwitz_zeta...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c; acb_t d, e, f; slong prec; prec = 2 + n_randint(state, 300); arb_init(a); arb_init(b); arb_init(c); acb_init(d); acb_init(e); acb_init(f); arb_randtest_precise(a, state, 1 + n_randint(state, 300), 5); arb_randtest_precise(b, state, 1 + n_randint(state, 300), 5); arb_randtest_precise(c, state, 1 + n_randint(state, 300), 5); acb_set_arb(d, a); acb_set_arb(e, b); arb_hurwitz_zeta(c, a, b, prec); acb_hurwitz_zeta(f, d, e, prec); if (!arb_overlaps(c, acb_realref(f)) || (arb_is_finite(c) && !arb_contains_zero(acb_imagref(f)))) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 15); flint_printf("\n\n"); flint_printf("e = "); acb_printd(e, 15); flint_printf("\n\n"); flint_printf("f = "); acb_printd(f, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-intersection.c000066400000000000000000000132711417376376500172270ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("intersection...."); fflush(stdout); flint_randinit(state); /* check a containment requirement */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y, z, w; arb_t xy, yz; slong pa, pb, pc; int alias; arb_init(x); arb_init(y); arb_init(z); arb_init(w); arb_init(xy); arb_init(yz); arb_randtest_special(x, state, 200, 10); arb_randtest_special(y, state, 200, 10); arb_randtest_special(z, state, 200, 10); arb_randtest_special(w, state, 200, 10); arb_randtest_special(xy, state, 200, 10); arb_randtest_special(yz, state, 200, 10); pa = 2 + n_randint(state, 200); pb = 2 + n_randint(state, 200); pc = 2 + n_randint(state, 200); arb_union(xy, x, y, pa); arb_union(yz, y, z, pb); arb_intersection(w, xy, yz, pc); if (!arb_contains(w, y)) { flint_printf("FAIL (containment):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("w = "); arb_print(w); flint_printf("\n\n"); flint_abort(); } if (n_randint(state, 2)) { arb_intersection(xy, xy, yz, pc); alias = arb_equal(xy, w); } else { arb_intersection(yz, xy, yz, pc); alias = arb_equal(yz, w); } if (!alias) { flint_printf("FAIL (aliasing):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("w = "); arb_print(w); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); arb_clear(w); arb_clear(xy); arb_clear(yz); } /* require that the return value is the same as for arb_overlaps */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, y; fmpq_t am, ar, bm, br, t, u; int c1, c2, c3; slong prec; prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(y); fmpq_init(am); fmpq_init(ar); fmpq_init(bm); fmpq_init(br); fmpq_init(t); fmpq_init(u); arb_randtest(a, state, 1 + n_randint(state, 500), 14); arb_randtest(b, state, 1 + n_randint(state, 500), 14); arf_get_fmpq(am, arb_midref(a)); mag_get_fmpq(ar, arb_radref(a)); arf_get_fmpq(bm, arb_midref(b)); mag_get_fmpq(br, arb_radref(b)); fmpq_sub(t, am, bm); fmpz_abs(fmpq_numref(t), fmpq_numref(t)); fmpq_add(u, ar, br); c1 = arb_overlaps(a, b); c2 = (fmpq_cmp(t, u) <= 0); c3 = arb_intersection(y, a, b, prec); if (c1 != c2 || c1 != c3) { flint_printf("FAIL (compatibility with arb_overlaps):\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("am = "); fmpq_print(am); flint_printf("\n\n"); flint_printf("ar = "); fmpq_print(ar); flint_printf("\n\n"); flint_printf("bm = "); fmpq_print(bm); flint_printf("\n\n"); flint_printf("br = "); fmpq_print(br); flint_printf("\n\n"); flint_printf("t = "); fmpq_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpq_print(u); flint_printf("\n\n"); flint_printf("c1 = %d, c2 = %d, c3 = %d\n\n", c1, c2, c3); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(y); fmpq_clear(am); fmpq_clear(ar); fmpq_clear(bm); fmpq_clear(br); fmpq_clear(t); fmpq_clear(u); } /* check a simple hardcoded example */ { slong prec; arb_t xy, yz, y, v, w; prec = 32; arb_init(xy); arb_init(yz); arb_init(y); arb_init(v); arb_init(w); arb_set_str(xy, "1 +/- 1", prec); arb_set_str(yz, "2 +/- 1", prec); arb_set_str(y, "1.5 +/- 0.6", prec); arb_set_str(v, "1.5 +/- 0.4", prec); arb_intersection(w, xy, yz, prec); if (!arb_contains(y, w) || !arb_contains(w, v)) { flint_printf("FAIL (hardcoded example)\n\n"); flint_printf("xy = "); arb_print(xy); flint_printf("\n\n"); flint_printf("yx = "); arb_print(yz); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("w = "); arb_print(w); flint_printf("\n\n"); flint_abort(); } arb_clear(xy); arb_clear(yz); arb_clear(y); arb_clear(v); arb_clear(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-lambertw.c000066400000000000000000000070721417376376500163400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("lambertw...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x1, x2, t, w1, w2; slong prec1, prec2, ebits; int branch; arb_init(x1); arb_init(x2); arb_init(t); arb_init(w1); arb_init(w2); branch = n_randint(state, 2); if (n_randint(state, 4) == 0) { prec1 = 2 + n_randint(state, 3000); prec2 = 2 + n_randint(state, 3000); ebits = 1 + n_randint(state, 1000); } else { prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 50); } arb_randtest(x1, state, 1 + n_randint(state, 1000), ebits); arb_randtest(x2, state, 1 + n_randint(state, 1000), ebits); arb_randtest(t, state, 1 + n_randint(state, 1000), ebits); arb_randtest(w1, state, 1 + n_randint(state, 1000), ebits); arb_randtest(w2, state, 1 + n_randint(state, 1000), ebits); if (n_randint(state, 4) == 0) { arb_const_e(t, 2 * prec1); arb_inv(t, t, 2 * prec1); arb_sub(x1, x1, t, 2 * prec1); } if (n_randint(state, 2)) { arb_set(x2, x1); } else { arb_add(x2, x1, t, 2 * prec1); arb_sub(x2, x2, t, 2 * prec1); } arb_lambertw(w1, x1, branch, prec1); if (n_randint(state, 2)) { arb_set(w2, x2); arb_lambertw(w2, w2, branch, prec1); } else { arb_lambertw(w2, x2, branch, prec1); } if (!arb_overlaps(w1, w2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("branch = %d, prec1 = %wd, prec2 = %wd\n\n", branch, prec1, prec2); flint_printf("x1 = "); arb_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); arb_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); arb_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); arb_printd(w2, 50); flint_printf("\n\n"); flint_abort(); } arb_exp(t, w1, prec1); arb_mul(t, t, w1, prec1); if (!arb_contains(t, x1)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("branch = %d, prec1 = %wd, prec2 = %wd\n\n", branch, prec1, prec2); flint_printf("x1 = "); arb_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); arb_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); arb_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); arb_printd(w2, 50); flint_printf("\n\n"); flint_printf("t = "); arb_printd(t, 50); flint_printf("\n\n"); flint_abort(); } arb_clear(x1); arb_clear(x2); arb_clear(t); arb_clear(w1); arb_clear(w2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-lgamma.c000066400000000000000000000031061417376376500157530ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("lgamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 3); arb_lgamma(b, a, prec1); arb_lgamma(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_lgamma(a, a, prec2); if (!arb_equal(a, c)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-log.c000066400000000000000000000120221417376376500152730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("log...."); fflush(stdout); flint_randinit(state); /* compare with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); do { arb_randtest(a, state, 1 + n_randint(state, 200), 10); } while (arb_contains_nonpositive(a)); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); /* todo: estimate cancellation precisely */ if (mpfr_cmp_d(t, 1 - 1e-10) > 0 && mpfr_cmp_d(t, 1 + 1e-10) < 0) { mpfr_set_prec(t, prec + 1000); fmpq_get_mpfr(t, q, MPFR_RNDN); } mpfr_log(t, t, MPFR_RNDN); arb_log(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_log(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* compare with mpfr (higher precision) */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 6000); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); do { arb_randtest(a, state, 1 + n_randint(state, 6000), 10); } while (arb_contains_nonpositive(a)); arb_randtest(b, state, 1 + n_randint(state, 6000), 10); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); /* todo: estimate cancellation precisely */ if (mpfr_cmp_d(t, 1 - 1e-10) > 0 && mpfr_cmp_d(t, 1 + 1e-10) < 0) { mpfr_set_prec(t, prec + 10000); fmpq_get_mpfr(t, q, MPFR_RNDN); } mpfr_log(t, t, MPFR_RNDN); arb_log(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_log(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* test large numbers */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, ab, lab, la, lb, lalb; slong prec = 2 + n_randint(state, 6000); arb_init(a); arb_init(b); arb_init(ab); arb_init(lab); arb_init(la); arb_init(lb); arb_init(lalb); arb_randtest(a, state, 1 + n_randint(state, 400), 400); arb_randtest(b, state, 1 + n_randint(state, 400), 400); arb_log(la, a, prec); arb_log(lb, b, prec); arb_mul(ab, a, b, prec); arb_log(lab, ab, prec); arb_add(lalb, la, lb, prec); if (!arb_overlaps(lab, lalb)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("la = "); arb_print(la); flint_printf("\n\n"); flint_printf("lb = "); arb_print(lb); flint_printf("\n\n"); flint_printf("ab = "); arb_print(ab); flint_printf("\n\n"); flint_printf("lab = "); arb_print(lab); flint_printf("\n\n"); flint_printf("lalb = "); arb_print(lalb); flint_printf("\n\n"); flint_abort(); } arb_log(a, a, prec); if (!arb_overlaps(a, la)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(ab); arb_clear(lab); arb_clear(la); arb_clear(lb); arb_clear(lalb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-log1p.c000066400000000000000000000050331417376376500155400ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("log1p...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 20000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec0, prec1, prec2; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); arb_log1p(b, a, prec1); arb_log1p(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* compare with log */ arb_add_ui(d, a, 1, prec2); arb_log(d, d, prec2); if (!arb_overlaps(c, d)) { flint_printf("FAIL: comparison with log\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_log1p(a, a, prec1); if (!arb_overlaps(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-log_arf.c000066400000000000000000000047161417376376500161360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("log_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arf_t x; arb_t y1, y2; slong prec1, prec2, acc1, acc2; prec1 = 2 + n_randint(state, 9000); prec2 = 2 + n_randint(state, 9000); arf_init(x); arb_init(y1); arb_init(y2); arf_randtest_special(x, state, 1 + n_randint(state, 9000), 200); arb_randtest_special(y1, state, 1 + n_randint(state, 9000), 200); arb_randtest_special(y2, state, 1 + n_randint(state, 9000), 200); if (n_randint(state, 2)) arf_add_ui(x, x, 1, 2 + n_randint(state, 9000), ARF_RND_DOWN); arb_log_arf(y1, x, prec1); arb_log_arf(y2, x, prec2); if (!arb_overlaps(y1, y2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y1 = "); arb_print(y1); flint_printf("\n\n"); flint_printf("y2 = "); arb_print(y2); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(y1); acc2 = arb_rel_accuracy_bits(y2); if (arf_sgn(x) > 0) { if (acc1 < prec1 - 2 || acc2 < prec2 - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("acc1 = %wd, acc2 = %wd\n\n", acc1, acc2); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y1 = "); arb_print(y1); flint_printf("\n\n"); flint_printf("y2 = "); arb_print(y2); flint_printf("\n\n"); flint_abort(); } } arf_clear(x); arb_clear(y1); arb_clear(y2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-log_base_ui.c000066400000000000000000000070401417376376500167660ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("log_base_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, bx, lbx, lbx1; ulong n, b, b2, r; slong prec; arb_init(x); arb_init(bx); arb_init(lbx); arb_init(lbx1); prec = 2 + n_randint(state, 500); b = n_randtest(state); b = n_pow(b, 1 + n_randint(state, 4)); if (n_randint(state, 2)) arb_set_ui(x, n_randtest(state)); else arb_randtest(x, state, 2 + n_randint(state, 500), 1 + n_randint(state, 200)); arb_randtest(bx, state, 2 + n_randint(state, 500), 1 + n_randint(state, 200)); arb_randtest(lbx, state, 2 + n_randint(state, 500), 1 + n_randint(state, 200)); arb_set_ui(bx, b); arb_pow(bx, bx, x, 2 + n_randint(state, 500)); arb_log_base_ui(lbx, bx, b, prec); /* test log_b(b^x) = x */ if (!arb_overlaps(lbx, x)) { flint_printf("FAIL: overlap\n\n"); flint_printf("b = %wu\n\n", b); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("bx = "); arb_printd(bx, 30); flint_printf("\n\n"); flint_printf("lbx = "); arb_printd(lbx, 30); flint_printf("\n\n"); flint_abort(); } arb_log_base_ui(bx, bx, b, prec); if (!arb_overlaps(bx, lbx)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("b = %wu\n\n", b); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("bx = "); arb_printd(bx, 30); flint_printf("\n\n"); flint_printf("lbx = "); arb_printd(lbx, 30); flint_printf("\n\n"); flint_abort(); } /* test exact computation of log_{b^(2^r)}(b^n)*/ n = n_randint(state, 100); b = 2 + n_randint(state, 10); r = n_randint(state, 4); b2 = n_pow(b, 1 << r); arb_set_ui(lbx1, n); arb_mul_2exp_si(lbx1, lbx1, -r); for (prec = 20; ; prec *= 2) { arb_set_ui(bx, b); arb_pow_ui(bx, bx, n, prec); arb_log_base_ui(lbx, bx, b2, prec); if (!arb_contains(lbx, lbx1) || prec > 10000) { flint_printf("FAIL: containment or exactness\n\n"); flint_printf("b = %wu\n\n", b); flint_printf("b2 = %wu\n\n", b2); flint_printf("r = %wu\n\n", r); flint_printf("n = %wu\n\n", n); flint_printf("bx = "); arb_printd(bx, 30); flint_printf("\n\n"); flint_printf("lbx = "); arb_printd(lbx, 30); flint_printf("\n\n"); flint_printf("lbx1 = "); arb_printd(lbx1, 30); flint_printf("\n\n"); flint_abort(); } if (arb_is_exact(lbx)) break; } arb_clear(x); arb_clear(bx); arb_clear(lbx); arb_clear(lbx1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-log_hypot.c000066400000000000000000000105571417376376500165310ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("log_hypot...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, r, s; slong prec1, prec2, acc1, acc2; prec1 = 2 + n_randint(state, 400); prec2 = 2 + n_randint(state, 400); arb_init(a); arb_init(b); arb_init(r); arb_init(s); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(r, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_randtest_special(s, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); if (n_randint(state, 2)) { arb_log_hypot(r, a, b, prec1); } else if (n_randint(state, 2)) { arb_set(r, a); arb_log_hypot(r, r, b, prec1); } else { arb_set(r, b); arb_log_hypot(r, a, r, prec1); } arb_hypot(s, a, b, prec2); arb_log(s, s, prec2); /* check consistency */ if (!arb_overlaps(r, s)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_abort(); } if (!arb_is_finite(r) && arb_is_finite(a) && arb_is_finite(b) && (!arb_contains_zero(a) || !arb_contains_zero(b))) { flint_printf("FAIL: not finite\n\n"); flint_printf("prec1 = %wd\n\n", prec1); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(r); acc2 = arb_rel_accuracy_bits(s); if (prec2 <= prec1 && acc1 > 0 && acc2 > 0 && acc1 < acc2 - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd, acc2 = %wd\n\n", prec1, acc1, acc2); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_abort(); } if (!arf_is_nan(arb_midref(a)) && !arf_is_nan(arb_midref(b))) { if ((!arb_is_finite(a) && !arb_contains_zero(a)) || (!arb_is_finite(b) && !arb_contains_zero(b))) { if (arf_is_nan(arb_midref(r)) || arb_is_finite(r) || !arb_is_positive(r)) { flint_printf("FAIL: infinite\n\n"); flint_printf("prec1 = %wd, acc1 = %wd, acc2 = %wd\n\n", prec1, acc1, acc2); flint_printf("a = "); arb_printn(a, 50, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 50, 0); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_abort(); } } } arb_clear(a); arb_clear(b); arb_clear(r); arb_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-log_tab.c000066400000000000000000000153141417376376500161300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong i; mpfr_t tabx, logx, y1, y2; mpz_t tt; flint_printf("log_tab...."); fflush(stdout); { slong prec, bits, num; prec = ARB_LOG_TAB1_LIMBS * FLINT_BITS; bits = ARB_LOG_TAB11_BITS; num = 1 << ARB_LOG_TAB11_BITS; mpfr_init2(tabx, prec); mpfr_init2(logx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_log_tab11[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(logx, i, MPFR_RNDD); mpfr_div_2ui(logx, logx, bits, MPFR_RNDD); mpfr_add_ui(logx, logx, 1, MPFR_RNDD); mpfr_log(logx, logx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, logx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(logx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_LOG_TAB1_LIMBS * FLINT_BITS; bits = ARB_LOG_TAB11_BITS + ARB_LOG_TAB12_BITS; num = 1 << ARB_LOG_TAB12_BITS; mpfr_init2(tabx, prec); mpfr_init2(logx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_log_tab12[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(logx, i, MPFR_RNDD); mpfr_div_2ui(logx, logx, bits, MPFR_RNDD); mpfr_add_ui(logx, logx, 1, MPFR_RNDD); mpfr_log(logx, logx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, logx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(logx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_LOG_TAB2_LIMBS * FLINT_BITS; bits = ARB_LOG_TAB21_BITS; num = 1 << ARB_LOG_TAB21_BITS; mpfr_init2(tabx, prec); mpfr_init2(logx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_log_tab21[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(logx, i, MPFR_RNDD); mpfr_div_2ui(logx, logx, bits, MPFR_RNDD); mpfr_add_ui(logx, logx, 1, MPFR_RNDD); mpfr_log(logx, logx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, logx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(logx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_LOG_TAB2_LIMBS * FLINT_BITS; bits = ARB_LOG_TAB21_BITS + ARB_LOG_TAB22_BITS; num = 1 << ARB_LOG_TAB22_BITS; mpfr_init2(tabx, prec); mpfr_init2(logx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_log_tab22[i]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(logx, i, MPFR_RNDD); mpfr_div_2ui(logx, logx, bits, MPFR_RNDD); mpfr_add_ui(logx, logx, 1, MPFR_RNDD); mpfr_log(logx, logx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, logx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } mpfr_clear(tabx); mpfr_clear(logx); mpfr_clear(y1); mpfr_clear(y2); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-log_ui_from_prev.c000066400000000000000000000037341417376376500200610ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("log_ui_from_prev...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t z1, z2, z3; ulong n1, n2; slong prec, accuracy; prec = 2 + n_randint(state, 3000); n1 = n_randint(state, 100000); n2 = n1 + 1 + n_randint(state, 1000); arb_init(z1); arb_init(z2); arb_init(z3); arb_log_ui(z1, n1, prec); arb_log_ui(z2, n2, prec); arb_log_ui_from_prev(z3, n2, z1, n1, prec); if (!arb_overlaps(z2, z3)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd, n1 = %wu, n2 = %wu\n\n", prec, n1, n2); flint_printf("z1 = "); arb_printd(z1, prec / 3.33); flint_printf("\n\n"); flint_printf("z2 = "); arb_printd(z2, prec / 3.33); flint_printf("\n\n"); flint_printf("z3 = "); arb_printd(z3, prec / 3.33); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(z3); if (accuracy < prec - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec); flint_printf("n1 = %wu, n2 = %wu\n\n", n1, n2); flint_printf("z3 = "); arb_printd(z3, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(z1); arb_clear(z2); arb_clear(z3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-max.c000066400000000000000000000061741417376376500153120ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* sample (x, y) so that x /in y */ void _sample_arf_in_arb(arf_t x, arb_t y, flint_rand_t state) { slong bits, prec, expbits; arf_t a, b; slong i, n; arf_init(a); arf_init(b); bits = 2 + n_randint(state, 1000); prec = 2 + n_randint(state, 1000); expbits = n_randint(state, 14); n = n_randint(state, 3); arf_randtest(x, state, bits, expbits); arf_set(a, x); arf_set(b, x); for (i = 0; i < n; i++) { arf_randtest(x, state, bits, expbits); arf_min(a, a, x); arf_max(b, b, x); } arb_set_interval_arf(y, a, b, prec); arf_clear(a); arf_clear(b); } int main() { slong iter; flint_rand_t state; flint_printf("max...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t a, b, c; arb_t x, y, z; slong prec; arf_init(a); arf_init(b); arf_init(c); arb_init(x); arb_init(y); arb_init(z); _sample_arf_in_arb(a, x, state); _sample_arf_in_arb(b, y, state); prec = 2 + n_randint(state, 200); arf_max(c, a, b); arb_max(z, x, y, prec); if (!arb_contains_arf(x, a) || !arb_contains_arf(y, b) || !arb_contains_arf(z, c)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("c = "); arf_print(c); flint_printf("\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } /* aliasing */ { int alias; if (n_randint(state, 2)) { arb_max(x, x, y, prec); alias = arb_equal(x, z); } else { arb_max(y, x, y, prec); alias = arb_equal(y, z); } if (!alias) { flint_printf("FAIL: aliasing\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } } arf_clear(a); arf_clear(b); arf_clear(c); arb_clear(x); arb_clear(y); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-min.c000066400000000000000000000061741417376376500153100ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* sample (x, y) so that x /in y */ void _sample_arf_in_arb(arf_t x, arb_t y, flint_rand_t state) { slong bits, prec, expbits; arf_t a, b; slong i, n; arf_init(a); arf_init(b); bits = 2 + n_randint(state, 1000); prec = 2 + n_randint(state, 1000); expbits = n_randint(state, 14); n = n_randint(state, 3); arf_randtest(x, state, bits, expbits); arf_set(a, x); arf_set(b, x); for (i = 0; i < n; i++) { arf_randtest(x, state, bits, expbits); arf_min(a, a, x); arf_max(b, b, x); } arb_set_interval_arf(y, a, b, prec); arf_clear(a); arf_clear(b); } int main() { slong iter; flint_rand_t state; flint_printf("min...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t a, b, c; arb_t x, y, z; slong prec; arf_init(a); arf_init(b); arf_init(c); arb_init(x); arb_init(y); arb_init(z); _sample_arf_in_arb(a, x, state); _sample_arf_in_arb(b, y, state); prec = 2 + n_randint(state, 200); arf_min(c, a, b); arb_min(z, x, y, prec); if (!arb_contains_arf(x, a) || !arb_contains_arf(y, b) || !arb_contains_arf(z, c)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("c = "); arf_print(c); flint_printf("\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } /* aliasing */ { int alias; if (n_randint(state, 2)) { arb_min(x, x, y, prec); alias = arb_equal(x, z); } else { arb_min(y, x, y, prec); alias = arb_equal(y, z); } if (!alias) { flint_printf("FAIL: aliasing\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } } arf_clear(a); arf_clear(b); arf_clear(c); arb_clear(x); arb_clear(y); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-mul.c000066400000000000000000000236161417376376500153220ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int mag_close(const mag_t am, const mag_t bm) { arf_t t, a, b; int res1, res2; arf_init(t); arf_init(a); arf_init(b); arf_set_mag(a, am); arf_set_mag(b, bm); arf_mul_ui(t, b, 257, MAG_BITS, ARF_RND_UP); arf_mul_2exp_si(t, t, -8); res1 = arf_cmp(a, t) <= 0; arf_mul_ui(t, a, 257, MAG_BITS, ARF_RND_UP); arf_mul_2exp_si(t, t, -8); res2 = arf_cmp(b, t) <= 0; arf_clear(t); arf_clear(a); arf_clear(b); return res1 && res2; } void arb_mul_naive(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_t zm_exact, zm_rounded, zr, t, u; arf_init(zm_exact); arf_init(zm_rounded); arf_init(zr); arf_init(t); arf_init(u); arf_mul(zm_exact, arb_midref(x), arb_midref(y), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_round(zm_rounded, zm_exact, prec, ARB_RND); /* rounding error */ if (arf_equal(zm_exact, zm_rounded)) { arf_zero(zr); } else { fmpz_t e; fmpz_init(e); /* more accurate, but not what we are testing arf_sub(zr, zm_exact, zm_rounded, MAG_BITS, ARF_RND_UP); arf_abs(zr, zr); */ fmpz_sub_ui(e, ARF_EXPREF(zm_rounded), prec); arf_one(zr); arf_mul_2exp_fmpz(zr, zr, e); fmpz_clear(e); } /* propagated error */ if (!arb_is_exact(x)) { arf_set_mag(t, arb_radref(x)); arf_abs(u, arb_midref(y)); arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP); } if (!arb_is_exact(y)) { arf_set_mag(t, arb_radref(y)); arf_abs(u, arb_midref(x)); arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP); } if (!arb_is_exact(x) && !arb_is_exact(y)) { arf_set_mag(t, arb_radref(x)); arf_set_mag(u, arb_radref(y)); arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP); } arf_set(arb_midref(z), zm_rounded); arf_get_mag(arb_radref(z), zr); arf_clear(zm_exact); arf_clear(zm_rounded); arf_clear(zr); arf_clear(t); arf_clear(u); } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t x, y, z; arb_init(a); arb_init(b); arb_init(c); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_mul(c, a, b, 2 + n_randint(state, 200)); fmpq_mul(z, x, y); if (!arb_contains_fmpq(c, z)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_mul(a, a, b, 2 + n_randint(state, 200)); fmpq_mul(z, x, y); if (!arb_contains_fmpq(a, z)) { flint_printf("FAIL: aliasing (c, a)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and b */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_mul(b, a, b, 2 + n_randint(state, 200)); fmpq_mul(z, x, y); if (!arb_contains_fmpq(b, z)) { flint_printf("FAIL: aliasing (c, b)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* main test */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z, v; slong prec; arb_init(x); arb_init(y); arb_init(z); arb_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arb_randtest_special(x, state, n_randint(state,2) ? 2000 : 200, 200); arb_randtest_special(y, state, n_randint(state,2) ? 2000 : 200, 200); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 5)) { case 0: arb_mul(z, x, y, prec); arb_mul_naive(v, x, y, prec); if (!arf_equal(arb_midref(z), arb_midref(v)) || !mag_close(arb_radref(z), arb_radref(v))) { flint_printf("FAIL!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 1: arb_set(y, x); arb_mul(z, x, y, prec); arb_mul(v, x, x, prec); if (!arf_equal(arb_midref(z), arb_midref(v)) || !mag_close(arb_radref(z), arb_radref(v))) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 2: arb_mul(v, x, x, prec); arb_mul(x, x, x, prec); if (!arb_equal(v, x)) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 3: arb_mul(v, x, y, prec); arb_mul(x, x, y, prec); if (!arb_equal(v, x)) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; default: arb_mul(v, x, y, prec); arb_mul(x, y, x, prec); if (!arf_equal(arb_midref(x), arb_midref(v)) || !mag_close(arb_radref(x), arb_radref(v))) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; } } arb_clear(x); arb_clear(y); arb_clear(z); arb_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-mul_arf.c000066400000000000000000000055671417376376500161570ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_mul_arf(c, a, x, prec); arb_mul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arf_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_mul_arf(c, a, x, prec); arb_mul_arf(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-mul_fmpz.c000066400000000000000000000055531417376376500163560ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_mul_fmpz(c, a, x, prec); arb_mul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_mul_fmpz(c, a, x, prec); arb_mul_fmpz(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpz_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-mul_more.c000066400000000000000000000105131417376376500163340ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_more...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t x, y, z; arb_init(a); arb_init(b); arb_init(c); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_mul(c, a, b, 2 + n_randint(state, 200)); fmpq_mul(z, x, y); if (!arb_contains_fmpq(c, z)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_mul(a, a, b, 2 + n_randint(state, 200)); fmpq_mul(z, x, y); if (!arb_contains_fmpq(a, z)) { flint_printf("FAIL: aliasing (c, a)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and b */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_mul(b, a, b, 2 + n_randint(state, 200)); fmpq_mul(z, x, y); if (!arb_contains_fmpq(b, z)) { flint_printf("FAIL: aliasing (c, b)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-mul_si.c000066400000000000000000000053461417376376500160150ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_mul_si(c, a, x, prec); arb_mul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_mul_si(c, a, x, prec); arb_mul_si(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-mul_ui.c000066400000000000000000000053471417376376500160200ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/ulong_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_mul_ui(c, a, x, prec); arb_mul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_mul_ui(c, a, x, prec); arb_mul_ui(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-overlaps.c000066400000000000000000000045101417376376500163500ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("overlaps...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t am, ar, bm, br, t, u; int c1, c2; arb_init(a); arb_init(b); fmpq_init(am); fmpq_init(ar); fmpq_init(bm); fmpq_init(br); fmpq_init(t); fmpq_init(u); arb_randtest(a, state, 1 + n_randint(state, 500), 14); arb_randtest(b, state, 1 + n_randint(state, 500), 14); arf_get_fmpq(am, arb_midref(a)); mag_get_fmpq(ar, arb_radref(a)); arf_get_fmpq(bm, arb_midref(b)); mag_get_fmpq(br, arb_radref(b)); fmpq_sub(t, am, bm); fmpz_abs(fmpq_numref(t), fmpq_numref(t)); fmpq_add(u, ar, br); c1 = arb_overlaps(a, b); c2 = (fmpq_cmp(t, u) <= 0); if (c1 != c2) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("am = "); fmpq_print(am); flint_printf("\n\n"); flint_printf("ar = "); fmpq_print(ar); flint_printf("\n\n"); flint_printf("bm = "); fmpq_print(bm); flint_printf("\n\n"); flint_printf("br = "); fmpq_print(br); flint_printf("\n\n"); flint_printf("t = "); fmpq_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpq_print(u); flint_printf("\n\n"); flint_printf("c1 = %d, c2 = %d\n\n", c1, c2); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(am); fmpq_clear(ar); fmpq_clear(bm); fmpq_clear(br); fmpq_clear(t); fmpq_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-partitions_fmpz.c000066400000000000000000000043371417376376500177540ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("partitions_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_t b1, b2; fmpz_t n; slong prec1, prec2, acc1, acc2; fmpz_init(n); arb_init(b1); arb_init(b2); if (iter % 100 == 0) fmpz_randtest(n, state, 1 + n_randint(state, 1000)); else fmpz_randtest(n, state, 1 + n_randint(state, 20)); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); arb_partitions_fmpz(b1, n, prec1); arb_partitions_fmpz(b2, n, prec2); if (!arb_overlaps(b1, b2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("b1 = "); arb_printn(b1, 50, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, 50, 0); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(b1); acc2 = arb_rel_accuracy_bits(b2); if (acc1 < prec1 - 4 || acc2 < prec2 - 4) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd\n", prec1, acc1); flint_printf("prec2 = %wd, acc2 = %wd\n", prec2, acc2); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("b1 = "); arb_printn(b1, 50, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(b1); arb_clear(b2); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-pow.c000066400000000000000000000066271417376376500153350ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("pow...."); fflush(stdout); flint_randinit(state); /* check large arguments */ for (iter = 0; iter < 20000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d, e, f; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(e); arb_init(f); arb_randtest(a, state, 1 + n_randint(state, 1000), 200); arb_randtest(b, state, 1 + n_randint(state, 1000), 200); arb_pow(c, a, b, prec1); arb_pow(d, a, b, prec2); if (!arb_overlaps(c, d)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_randtest(c, state, 1 + n_randint(state, 1000), 200); /* check a^(b+c) = a^b*a^c */ arb_add(e, b, c, prec1); arb_pow(d, a, e, prec1); arb_pow(e, a, b, prec1); arb_pow(f, a, c, prec1); arb_mul(e, e, f, prec1); if (!arb_overlaps(d, e)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("e = "); arb_print(e); flint_printf("\n\n"); flint_abort(); } arb_pow(c, a, b, prec1); arb_set(d, a); arb_pow(d, d, b, prec2); if (!arb_overlaps(c, d)) { flint_printf("FAIL: aliasing 1\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_set(d, b); arb_pow(d, a, d, prec2); if (!arb_overlaps(c, d)) { flint_printf("FAIL: aliasing 2\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(e); arb_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-pow_fmpq.c000066400000000000000000000052011417376376500163430ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_fmpq...."); fflush(stdout); flint_randinit(state); /* check large arguments */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpq_t e1, e2, e3; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpq_init(e1); fmpq_init(e2); fmpq_init(e3); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 200); arb_randtest_precise(b, state, 1 + n_randint(state, 1000), 200); fmpq_randtest(e1, state, 200); fmpq_randtest(e2, state, 200); arb_pow_fmpq(b, a, e1, prec1); arb_pow_fmpq(c, a, e1, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("e1 = "); fmpq_print(e1); flint_printf("\n\n"); flint_abort(); } /* check a^(e1+e2) = a^e1*a^e2 */ arb_pow_fmpq(c, a, e2, prec1); arb_mul(d, b, c, prec1); fmpq_add(e3, e1, e2); arb_pow_fmpq(c, a, e3, prec1); if (!arb_overlaps(c, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("e1 = "); fmpq_print(e1); flint_printf("\n\n"); flint_printf("e2 = "); fmpq_print(e2); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpq_clear(e1); fmpq_clear(e2); fmpq_clear(e3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-pow_fmpz.c000066400000000000000000000052011417376376500163540ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_fmpz...."); fflush(stdout); flint_randinit(state); /* check large arguments */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t e1, e2, e3; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(e1); fmpz_init(e2); fmpz_init(e3); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 200); arb_randtest_precise(b, state, 1 + n_randint(state, 1000), 200); fmpz_randtest(e1, state, 200); fmpz_randtest(e2, state, 200); arb_pow_fmpz(b, a, e1, prec1); arb_pow_fmpz(c, a, e1, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("e1 = "); fmpz_print(e1); flint_printf("\n\n"); flint_abort(); } /* check a^(e1+e2) = a^e1*a^e2 */ arb_pow_fmpz(c, a, e2, prec1); arb_mul(d, b, c, prec1); fmpz_add(e3, e1, e2); arb_pow_fmpz(c, a, e3, prec1); if (!arb_overlaps(c, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("e1 = "); fmpz_print(e1); flint_printf("\n\n"); flint_printf("e2 = "); fmpz_print(e2); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(e1); fmpz_clear(e2); fmpz_clear(e3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-power_sum_vec.c000066400000000000000000000036771417376376500174070ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("power_sum_vec...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, s, t; arb_ptr res; slong aa, bb, k, n, len; slong prec; len = n_randint(state, 30); prec = 2 + n_randint(state, 500); aa = n_randint(state, 50) - 50; bb = aa + n_randint(state, 50); arb_init(a); arb_init(b); arb_init(s); arb_init(t); res = _arb_vec_init(len); arb_set_si(a, aa); arb_set_si(b, bb); arb_power_sum_vec(res, a, b, len, prec); for (n = 0; n < len; n++) { arb_zero(s); for (k = aa; k < bb; k++) { arb_set_si(t, k); arb_pow_ui(t, t, n, prec); arb_add(s, s, t, prec); } if (!arb_overlaps(res + n, s)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = %wd, b = %wd, n = %wd\n\n", aa, bb, n); flint_printf("res = "); arb_printd(res + n, 30); flint_printf("\n\n"); flint_printf("s = "); arb_printd(s, 30); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(b); arb_clear(s); arb_clear(t); _arb_vec_clear(res, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-primorial.c000066400000000000000000000037421417376376500165210ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("primorial...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { ulong n, m; fmpz_t y; arb_t x; slong prec; arb_init(x); fmpz_init(y); if (n_randint(state, 10) == 0) n = n_randint(state, 5000); else n = n_randint(state, 500); prec = 2 + n_randint(state, 500); arb_primorial_ui(x, n, prec); fmpz_primorial(y, n); if (!arb_contains_fmpz(x, y)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n", n); flint_printf("x = "); arb_printd(x, 100); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_abort(); } m = n_randint(state, 500); if (m == 0) n = 0; else n = n_nth_prime(m); prec = 2 + n_randint(state, 500); arb_primorial_nth_ui(x, m, prec); fmpz_primorial(y, n); if (!arb_contains_fmpz(x, y)) { flint_printf("FAIL: containment (2)\n\n"); flint_printf("m = %wu\n", m); flint_printf("x = "); arb_printd(x, 100); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_abort(); } arb_clear(x); fmpz_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-rgamma.c000066400000000000000000000036421417376376500157660ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("rgamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 1000), 3); arb_rgamma(b, a, prec1); arb_rgamma(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check 1/gamma(z+1) = 1/gamma(z)/z */ arb_div(b, b, a, prec1); arb_add_ui(c, a, 1, prec1); arb_rgamma(c, c, prec1); if (!arb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-richcmp.c000066400000000000000000000072731417376376500161530ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" static void arb_supremum(arf_t res, const arb_t x) { if (arf_is_nan(arb_midref(x))) { arf_nan(res); } else if (mag_is_inf(arb_radref(x))) { arf_pos_inf(res); } else { arf_set_mag(res, arb_radref(x)); arf_add(res, res, arb_midref(x), ARF_PREC_EXACT, ARF_RND_CEIL); } } static void arb_infimum(arf_t res, const arb_t x) { if (arf_is_nan(arb_midref(x))) { arf_nan(res); } else if (mag_is_inf(arb_radref(x))) { arf_neg_inf(res); } else { arf_set_mag(res, arb_radref(x)); arf_sub(res, arb_midref(x), res, ARF_PREC_EXACT, ARF_RND_FLOOR); } } int arb_richcmp(const arb_t x, const arb_t y, int op) { switch (op) { case 0: return arb_eq(x, y); case 1: return arb_ne(x, y); case 2: return arb_le(x, y); case 3: return arb_lt(x, y); case 4: return arb_ge(x, y); default: return arb_gt(x, y); } } int arb_richcmp_fallback(const arb_t x, const arb_t y, int op) { arf_t xa, xb, ya, yb; int res; arf_init(xa); arf_init(xb); arf_init(ya); arf_init(yb); arb_infimum(xa, x); arb_supremum(xb, x); arb_infimum(ya, y); arb_supremum(yb, y); if (arf_is_nan(xa) || arf_is_nan(ya)) { res = 0; } else { if (op == 0) /* eq */ { res = arf_equal(xa, xb) && arf_equal(ya, yb) && arf_equal(xa, ya); } else if (op == 1) /* ne */ { res = (arf_cmp(yb, xa) < 0) || (arf_cmp(xb, ya) < 0); } else if (op == 2) /* le */ { res = (arf_cmp(xb, ya) <= 0); } else if (op == 3) /* lt */ { res = (arf_cmp(xb, ya) < 0); } else if (op == 4) /* ge */ { res = (arf_cmp(xa, yb) >= 0); } else /* gt */ { res = (arf_cmp(xa, yb) > 0); } } arf_clear(xa); arf_clear(xb); arf_clear(ya); arf_clear(yb); return res; } int main() { slong iter; flint_rand_t state; flint_printf("richcmp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { arb_t a, b; int op, res1, res2; arb_init(a); arb_init(b); arb_randtest_special(a, state, 1 + n_randint(state, 100), 5); arb_randtest_special(b, state, 1 + n_randint(state, 100), 5); op = n_randint(state, 6); res1 = arb_richcmp(a, b, op); res2 = arb_richcmp_fallback(a, b, op); if (res1 != res2) { flint_printf("FAIL:\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 30); flint_printf("\n\n"); flint_printf("op = %d\n\n", op); flint_printf("res1 (cmp) = %d\n\n", res1); flint_printf("res2 (fallback) = %d\n\n", res2); flint_abort(); } arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-rising2_ui.c000066400000000000000000000063571417376376500166020ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rising2_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, u, v, u2, v2; fmpz *f; arb_ptr g; ulong n; slong i, prec; arb_init(a); arb_init(u); arb_init(v); arb_init(u2); arb_init(v2); arb_randtest(a, state, 1 + n_randint(state, 4000), 10); arb_randtest(u, state, 1 + n_randint(state, 4000), 10); arb_randtest(v, state, 1 + n_randint(state, 4000), 10); n = n_randint(state, 120); f = _fmpz_vec_init(n + 1); g = _arb_vec_init(n + 1); prec = 2 + n_randint(state, 4000); arb_rising2_ui(u, v, a, n, prec); arith_stirling_number_1u_vec(f, n, n + 1); for (i = 0; i <= n; i++) arb_set_fmpz(g + i, f + i); _arb_poly_evaluate(u2, g, n + 1, a, prec); _arb_poly_derivative(g, g, n + 1, prec); _arb_poly_evaluate(v2, g, n, a, prec); if (!arb_overlaps(u, u2) || !arb_overlaps(v, v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n", n); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); arb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); arb_printd(u2, 15); flint_printf("\n\n"); flint_printf("v = "); arb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); arb_printd(v2, 15); flint_printf("\n\n"); flint_abort(); } arb_set(u2, a); arb_rising2_ui(u2, v, u2, n, prec); if (!arb_equal(u2, u)) { flint_printf("FAIL: aliasing 1\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); arb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); arb_printd(u2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); flint_abort(); } arb_set(v2, a); arb_rising2_ui(u, v2, v2, n, prec); if (!arb_equal(v2, v)) { flint_printf("FAIL: aliasing 2\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("v = "); arb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); arb_printd(v2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); flint_abort(); } arb_clear(a); arb_clear(u); arb_clear(v); arb_clear(u2); arb_clear(v2); _fmpz_vec_clear(f, n + 1); _arb_vec_clear(g, n + 1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-rising_ui.c000066400000000000000000000053731417376376500165150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("rising_ui...."); fflush(stdout); flint_randinit(state); /* compare with fmpq */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; ulong n; slong i; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 1000), 10); arb_randtest(b, state, 1 + n_randint(state, 1000), 10); n = n_randint(state, 80); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 10)); arb_rising_ui(b, a, n, 2 + n_randint(state, 1000)); fmpq_one(y); for (i = 0; i < n; i++) { fmpq_set_si(z, i, 1); fmpq_add(z, x, z); fmpq_mul(y, y, z); } if (!arb_contains_fmpq(b, y)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n", n); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of y and x */ for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { arb_t x, y; ulong n; slong prec; arb_init(x); arb_init(y); arb_randtest(x, state, 1 + n_randint(state, 200), 10); arb_randtest(y, state, 1 + n_randint(state, 200), 10); n = n_randint(state, 100); prec = 2 + n_randint(state, 1000); arb_rising_ui(y, x, n, prec); arb_rising_ui(x, x, n, prec); if (!arb_equal(x, y)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("n = %wu\n", n); flint_abort(); } arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-root_ui.c000066400000000000000000000033731417376376500162030ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("root_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong k; slong prec; prec = 2 + n_randint(state, 2000); k = n_randtest_not_zero(state); arb_init(a); arb_init(b); arb_init(c); arb_randtest(a, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); arb_randtest(b, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); arb_root_ui(b, a, k, prec); arb_pow_ui(c, b, k, prec); if (!arb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("k = %wu\n", k); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_root_ui(a, a, k, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-rsqrt.c000066400000000000000000000030471417376376500156740ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("rsqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_rsqrt(b, a, prec); arb_inv(c, b, prec); arb_mul(c, c, c, prec); if (!arb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_rsqrt(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sec.c000066400000000000000000000034341417376376500152730ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sec...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 300), 100); arb_randtest_special(a, state, 1 + n_randint(state, 300), 100); arb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { arb_sec(a, x, prec1); } else { arb_set(a, x); arb_sec(a, a, prec1); } arb_cos(b, x, prec2); arb_inv(b, b, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sech.c000066400000000000000000000034401417376376500154400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sech...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, a, b; slong prec1, prec2; prec1 = 2 + n_randint(state, 200); prec2 = prec1 + 30; arb_init(x); arb_init(a); arb_init(b); arb_randtest_special(x, state, 1 + n_randint(state, 300), 100); arb_randtest_special(a, state, 1 + n_randint(state, 300), 100); arb_randtest_special(b, state, 1 + n_randint(state, 300), 100); if (n_randint(state, 2)) { arb_sech(a, x, prec1); } else { arb_set(a, x); arb_sech(a, a, prec1); } arb_cosh(b, x, prec2); arb_inv(b, b, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printn(x, 20, 0); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 20, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 20, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-set_interval_arf.c000066400000000000000000000030311417376376500200410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("set_interval_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x; arf_t a, b; arb_init(x); arf_init(a); arf_init(b); arf_randtest_special(a, state, 200, 10); arf_randtest_special(b, state, 200, 10); if (arf_cmp(a, b) > 0) arf_swap(a, b); arb_set_interval_arf(x, a, b, 2 + n_randint(state, 200)); if ((!arb_contains_arf(x, a) || !arb_contains_arf(x, b)) || (!arf_is_nan(a) && !arf_is_nan(b) && arf_is_nan(arb_midref(x)))) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arf_clear(a); arf_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-set_interval_mag.c000066400000000000000000000032131417376376500200370ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("set_interval_mag...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; mag_t u, v; arf_t a, b; arb_init(x); mag_init(u); mag_init(v); arf_init(a); arf_init(b); mag_randtest_special(u, state, 1 + n_randint(state, 100)); mag_randtest_special(v, state, 1 + n_randint(state, 100)); if (mag_cmp(u, v) > 0) mag_swap(u, v); arf_set_mag(a, u); arf_set_mag(b, v); arb_set_interval_mag(x, u, v, 2 + n_randint(state, 200)); if (!arb_contains_arf(x, a) || !arb_contains_arf(x, b)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arf_clear(a); arf_clear(b); mag_clear(u); mag_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-set_interval_mpfr.c000066400000000000000000000032361417376376500202440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("set_interval_mpfr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x; arf_t a, b; mpfr_t aa, bb; arb_init(x); arf_init(a); arf_init(b); mpfr_init2(aa, 200); mpfr_init2(bb, 200); arf_randtest_special(a, state, 200, 10); arf_randtest_special(b, state, 200, 10); if (arf_cmp(a, b) > 0) arf_swap(a, b); arf_get_mpfr(aa, a, MPFR_RNDD); arf_get_mpfr(bb, b, MPFR_RNDU); arb_set_interval_mpfr(x, aa, bb, 2 + n_randint(state, 200)); if (!arb_contains_arf(x, a) || !arb_contains_arf(x, b)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arf_clear(a); arf_clear(b); mpfr_clear(aa); mpfr_clear(bb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-set_interval_neg_pos_mag.c000066400000000000000000000031671417376376500215610ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("set_interval_neg_pos_mag...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x; mag_t u, v; arf_t a, b; arb_init(x); mag_init(u); mag_init(v); arf_init(a); arf_init(b); mag_randtest_special(u, state, 1 + n_randint(state, 100)); mag_randtest_special(v, state, 1 + n_randint(state, 100)); arf_set_mag(a, u); arf_neg(a, a); arf_set_mag(b, v); arb_set_interval_neg_pos_mag(x, u, v, 2 + n_randint(state, 200)); if (!arb_contains_arf(x, a) || !arb_contains_arf(x, b)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arf_clear(a); arf_clear(b); mag_clear(u); mag_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-set_str.c000066400000000000000000000141351417376376500162040ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" const char * testdata_floats[] = { "0", /* repeated to test empty string later */ "0", "0.0", "0.", ".0", "+0", "+0.0", "+0.", " +.0 ", "-0", "-0.0", "-0.", "-.0", " 0e3", "0.0e3", "0.e3", " .0e3", "+0e3", "+0.0e3", "+0.e3", "+.0e3", "-0e3", "-0.0e3", "-0.e3", "-.0e3", "0e+3", "0.0e+3", "0.e+3", " .0e+3", "+0e+3", "+0.0e+3", "+0.e+3", "+.0e+3", "-0E+3", "-0.0E+3 ", "-0.e+3", "-.0e+3", "0e-3", "0.0e-3", "0.e-3", ".0E-3", "+0e-3", "+0.0e-3", "+0.E-3", "+.0e-3", "-0e-3", "-0.0e-3", "-0.e-3", "-.0e-3", "03.125", "+03.125", "-03.125", "03.12500", "+03.12500", "-03.12500", "03.125e+3", "+03.125e+3", " -03.125e+3 ", "03.12500e+3", "+03.12500e+3", "-03.12500e+3", "03.125e3", "+03.125E3", "-03.125e3", "03.12500e3", "+03.12500E3", "-03.12500E3", "25000.0e-2", "-25000.0e-2", " 25000.0000000000000000000e-2", "-25000.0000000000000000000e-2", " 000025000.0000000000000000000e-2 ", "-000025000.0000000000000000000e-2", "25000.e-2", "-25000.e-2", "12345.125", "-12345.125", "+12345.125", "inf", "-inf", "+inf", "Inf", "-INF", "+Inf", "NAN", "-NaN", "+NAN", NULL, }; const char * testdata_invalid[] = { "", ".", "+.", "-.", ".e+3", "-.e+5", "+.e-5", "2+3", "150a.25", "-e+4", "10.25x", "10.3.5", "125e3.6", "125e-3.6", "3.14 e+5", "3.140 e3", "3.14+e5", "3.14e+ 5", " 3.14e- 5", "3.14e+-5", "3.14e+/-5", ".0.", "..", ":)", " +/- ", " 0 0", " +/- EEE ", "-3.5e+x5 +/-", "4.7 +/- -3.5e+x5", "4.7 +/-", NULL, }; int main() { flint_rand_t state; arb_t t, u, v; double x; int error, bracket; char tmp[256]; slong i, j; flint_printf("set_str...."); fflush(stdout); flint_randinit(state); arb_init(t); arb_init(u); arb_init(v); flint_randinit(state); for (i = 0; testdata_floats[i] != NULL; i++) { arb_const_pi(t, 53); error = arb_set_str(t, testdata_floats[i], 53); x = strtod(testdata_floats[i], NULL); if (x != x) { arb_indeterminate(u); } else { arf_set_d(arb_midref(u), x); mag_zero(arb_radref(u)); } if (error != 0 || !arb_equal(t, u)) { flint_printf("FAIL (valid input): %s\n", testdata_floats[i]); arb_printd(t, 15); flint_printf("\n"); arb_printd(u, 15); flint_printf("\n"); flint_abort(); } } for (i = 0; testdata_floats[i] != NULL; i++) { for (j = 0; testdata_floats[j] != NULL; j++) { for (bracket = 0; bracket < 2; bracket++) { arb_const_pi(t, 53); bracket = n_randint(state, 2); strcpy(tmp, ""); if (bracket) strcat(tmp, "["); /* allow empty string for midpoint */ strcat(tmp, (i == 0) ? "" : testdata_floats[i]); strcat(tmp, "+/-"); strcat(tmp, testdata_floats[j]); if (bracket) strcat(tmp, "]"); error = arb_set_str(t, tmp, 53); x = strtod((i == 0) ? "0" : testdata_floats[i], NULL); if (x != x) { arb_indeterminate(u); } else { arf_set_d(arb_midref(u), x); mag_zero(arb_radref(u)); } x = strtod(testdata_floats[j], NULL); arf_set_d(arb_midref(v), x); mag_zero(arb_radref(v)); arb_abs(v, v); arb_add_error(u, v); if (error != 0 || !arb_equal(t, u)) { flint_printf("FAIL (valid input): %s\n", tmp); arb_printd(t, 15); flint_printf("\n"); arb_printd(u, 15); flint_printf("\n"); flint_abort(); } } } } for (i = 0; testdata_invalid[i] != NULL; i++) { arb_const_pi(t, 53); error = arb_set_str(t, testdata_invalid[i], 53); if (error == 0) { flint_printf("FAIL (invalid input): %s\n", testdata_invalid[i]); arb_printd(t, 15); flint_printf("\n"); flint_abort(); } } for (i = 0; testdata_invalid[i] != NULL; i++) { for (j = 0; testdata_invalid[j] != NULL; j++) { for (bracket = 0; bracket < 2; bracket++) { arb_const_pi(t, 53); bracket = n_randint(state, 2); strcpy(tmp, ""); if (bracket) strcat(tmp, "["); strcat(tmp, testdata_invalid[i]); strcat(tmp, "+/-"); strcat(tmp, testdata_invalid[j]); if (bracket) strcat(tmp, "]"); error = arb_set_str(t, tmp, 53); if (error == 0) { flint_printf("FAIL (invalid input): %s\n", tmp); arb_printd(t, 15); flint_printf("\n"); flint_abort(); } } } } arb_clear(t); arb_clear(u); arb_clear(v); flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sgn.c000066400000000000000000000030071417376376500153040ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sgn...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b; int result; arb_init(a); arb_init(b); arb_randtest_special(a, state, 1 + n_randint(state, 200), 10); arb_randtest_special(b, state, 1 + n_randint(state, 200), 10); arb_sgn(b, a); result = 1; if (arb_contains_zero(a)) result = result & arb_contains_si(b, 0); if (arb_contains_positive(a)) result = result & arb_contains_si(b, 1); if (arb_contains_negative(a)) result = result & arb_contains_si(b, -1); if (!result) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin.c000066400000000000000000000070621417376376500153130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec0, prec; prec0 = 400; if (iter % 100 == 0) prec0 = 8000; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec0 + 100); arb_randtest(a, state, 1 + n_randint(state, prec0), 6); arb_randtest(b, state, 1 + n_randint(state, prec0), 6); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, prec0)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_sin(t, t, MPFR_RNDN); arb_sin(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_sin(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } /* check large arguments */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec0, prec1, prec2; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec0), prec0); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(d, state, 1 + n_randint(state, prec0), 100); arb_sin(b, a, prec1); arb_sin(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* check sin(2a) = 2sin(a)cos(a) */ arb_mul_2exp_si(c, a, 1); arb_sin(c, c, prec1); arb_cos(d, a, prec1); arb_mul(b, b, d, prec1); arb_mul_2exp_si(b, b, 1); if (!arb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos.c000066400000000000000000000137021417376376500161550ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t q; mpfr_t t, u; slong prec0, prec; prec0 = 400; if (iter % 100 == 0) prec0 = 8000; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); fmpq_init(q); mpfr_init2(t, prec + 200); mpfr_init2(u, prec + 200); arb_randtest(a, state, 1 + n_randint(state, prec0), 6); arb_randtest(b, state, 1 + n_randint(state, prec0), 6); arb_randtest(c, state, 1 + n_randint(state, prec0), 6); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, prec0)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_sin_cos(t, u, t, MPFR_RNDN); arb_sin_cos(b, c, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment (sin)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } if (!arb_contains_mpfr(c, u)) { flint_printf("FAIL: containment (cos)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(q); mpfr_clear(t); mpfr_clear(u); } /* check large arguments */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d, e; slong prec0, prec1, prec2, prec3; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); if (iter % 10 == 0) prec3 = 50000; else prec3 = 100; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(e); arb_randtest_special(a, state, 1 + n_randint(state, prec0), prec3); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(d, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(e, state, 1 + n_randint(state, prec0), 100); arb_sin_cos(b, c, a, prec1); arb_sin_cos(d, e, a, prec2); if (!arb_overlaps(b, d) || !arb_overlaps(c, e)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("e = "); arb_print(e); flint_printf("\n\n"); flint_abort(); } /* check sin(a)^2 + cos(a)^2 = 1 */ arb_mul(d, b, b, prec1); arb_mul(e, c, c, prec1); arb_add(d, d, e, prec1); arb_sub_ui(d, d, 1, prec1); if (!arb_contains_zero(d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(e); } /* check accuracy */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, s, c; slong prec0, prec; mag_t allow; if (iter % 10 == 0) prec0 = 10000; else prec0 = 400; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(s); arb_init(c); mag_init(allow); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 12); arb_randtest_special(s, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); if (n_randint(state, 2)) { arb_sin_cos(s, c, a, prec); } else { arb_sin_cos(s, NULL, a, prec); arb_sin_cos(NULL, c, a, prec); } if (!arb_is_finite(a)) { mag_inf(allow); } else { mag_set_ui_2exp_si(allow, 1, -prec + 1); mag_max(allow, allow, arb_radref(a)); mag_mul_2exp_si(allow, allow, 1); } if (mag_cmp(arb_radref(s), allow) > 0 || mag_cmp(arb_radref(c), allow) > 0) { flint_printf("FAIL: accuracy\n\n"); flint_printf("a = "); arb_printn(a, 500, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 500, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 500, 0); flint_printf("\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("allow = "); mag_printd(allow, 5); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(s); arb_clear(c); mag_clear(allow); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_arf_bb.c000066400000000000000000000124171417376376500174520ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_sin_cos_fmpz_div_2exp_bsplit(arb_t wsin, arb_t wcos, const fmpz_t x, flint_bitcnt_t r, slong prec); int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_arf_bb...."); fflush(stdout); flint_randinit(state); /* test the series evaluation code directly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpz_t x; slong r; arb_t t, s1, s2, c1, c2; slong prec1, prec2; fmpz_init(x); arb_init(t); arb_init(s1); arb_init(s2); arb_init(c1); arb_init(c2); prec1 = 10 + n_randint(state, 2000); prec2 = 10 + n_randint(state, 2000); r = n_randint(state, prec2); r = FLINT_MAX(r, 4); fmpz_randtest(x, state, r - 3); arb_set_fmpz(t, x); arb_mul_2exp_si(t, t, -r); arb_sin_cos(s1, c1, t, prec1); arb_sin_cos_fmpz_div_2exp_bsplit(s2, c2, x, r, prec2); if (!arb_overlaps(s1, s2) || !arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec1 = %wd, prec2 = %wd\n\n", prec1, prec2); flint_printf("t = "); arb_printn(t, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_printf("c1 = "); arb_printn(c1, 500, 0); flint_printf("\n\n"); flint_printf("c2 = "); arb_printn(c2, 500, 0); flint_printf("\n\n"); flint_abort(); } fmpz_clear(x); arb_clear(t); arb_clear(s1); arb_clear(s2); arb_clear(c1); arb_clear(c2); } /* test the bb algorithm */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, s1, s2, c1, c2; slong prec = 2 + n_randint(state, 4000); arb_init(x); arb_init(s1); arb_init(s2); arb_init(c1); arb_init(c2); arb_randtest(x, state, 1 + n_randint(state, 4000), 0); mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_mul_2exp_si(x, x, -n_randint(state, 2 * prec)); while (arf_cmpabs_d(arb_midref(x), 3.141) > 0) arb_mul_2exp_si(x, x, -1); arb_sin_cos(s1, c1, x, prec); switch (n_randint(state, 6)) { case 0: arb_sin_cos_arf_bb(s2, c2, arb_midref(x), prec); break; case 1: arb_sin_cos_arf_bb(s2, NULL, arb_midref(x), prec); arb_sin_cos_arf_bb(NULL, c2, arb_midref(x), prec); break; case 2: arb_set(s2, x); arb_sin_cos_arf_bb(NULL, c2, arb_midref(s2), prec); arb_sin_cos_arf_bb(s2, NULL, arb_midref(s2), prec); break; case 3: arb_set(c2, x); arb_sin_cos_arf_bb(s2, NULL, arb_midref(c2), prec); arb_sin_cos_arf_bb(NULL, c2, arb_midref(c2), prec); break; case 4: arb_set(c2, x); arb_sin_cos_arf_bb(s2, c2, arb_midref(c2), prec); break; default: arb_set(s2, x); arb_sin_cos_arf_bb(s2, c2, arb_midref(s2), prec); break; } if (!arb_overlaps(s1, s2) || !arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_printf("c1 = "); arb_printn(c1, 500, 0); flint_printf("\n\n"); flint_printf("c2 = "); arb_printn(c2, 500, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(s2) < prec - 2 || arb_rel_accuracy_bits(c2) < prec - 2) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd, acc1 = %wd, acc2 = %wd\n\n", prec, arb_rel_accuracy_bits(s2), arb_rel_accuracy_bits(c2)); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_printf("c1 = "); arb_printn(c1, 500, 0); flint_printf("\n\n"); flint_printf("c2 = "); arb_printn(c2, 500, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(s1); arb_clear(s2); arb_clear(c1); arb_clear(c2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_arf_generic.c000066400000000000000000000207531417376376500205050ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* these functions are not exposed to the public for now, but it still makes sense to test them explicitly */ void arb_sin_cos_arf_rs_generic(arb_t res_sin, arb_t res_cos, const arf_t x, slong prec); void arb_sin_cos_taylor_sum_rs(arb_t s, const arb_t x, slong N, int cosine, slong prec); int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_arf_generic...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, s1, s2, c1, c2; slong prec = 2 + n_randint(state, 2000); arb_init(x); arb_init(s1); arb_init(s2); arb_init(c1); arb_init(c2); if (n_randint(state, 2)) arb_randtest(x, state, 1 + n_randint(state, 2000), 15); else arb_randtest(x, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 10000)); mag_zero(arb_radref(x)); arb_sin_cos(s1, c1, x, prec); switch (n_randint(state, 6)) { case 0: arb_sin_cos_arf_generic(s2, c2, arb_midref(x), prec); break; case 1: arb_sin_cos_arf_generic(s2, NULL, arb_midref(x), prec); arb_sin_cos_arf_generic(NULL, c2, arb_midref(x), prec); break; case 2: arb_set(s2, x); arb_sin_cos_arf_generic(NULL, c2, arb_midref(s2), prec); arb_sin_cos_arf_generic(s2, NULL, arb_midref(s2), prec); break; case 3: arb_set(c2, x); arb_sin_cos_arf_generic(s2, NULL, arb_midref(c2), prec); arb_sin_cos_arf_generic(NULL, c2, arb_midref(c2), prec); break; case 4: arb_set(c2, x); arb_sin_cos_arf_generic(s2, c2, arb_midref(c2), prec); break; default: arb_set(s2, x); arb_sin_cos_arf_generic(s2, c2, arb_midref(s2), prec); break; } if (!arb_overlaps(s1, s2) || !arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_printf("c1 = "); arb_printn(c1, 500, 0); flint_printf("\n\n"); flint_printf("c2 = "); arb_printn(c2, 500, 0); flint_printf("\n\n"); flint_abort(); } if (arf_cmpabs_ui(arb_midref(x), 1) <= 0 && (arb_rel_accuracy_bits(s2) < prec - 2 || arb_rel_accuracy_bits(c2) < prec - 2)) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd, acc1 = %wd, acc2 = %wd\n\n", prec, arb_rel_accuracy_bits(s2), arb_rel_accuracy_bits(c2)); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_printf("c1 = "); arb_printn(c1, 500, 0); flint_printf("\n\n"); flint_printf("c2 = "); arb_printn(c2, 500, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(s1); arb_clear(s2); arb_clear(c1); arb_clear(c2); } /* test the rs algorithm explicitly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, s1, s2, c1, c2; slong prec = 2 + n_randint(state, 2000); arb_init(x); arb_init(s1); arb_init(s2); arb_init(c1); arb_init(c2); arb_randtest(x, state, 1 + n_randint(state, 2000), 0); mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_mul_2exp_si(x, x, -n_randint(state, 2 * prec)); while (arf_cmpabs_d(arb_midref(x), 3.141) > 0) arb_mul_2exp_si(x, x, -1); arb_sin_cos(s1, c1, x, prec); switch (n_randint(state, 6)) { case 0: arb_sin_cos_arf_rs_generic(s2, c2, arb_midref(x), prec); break; case 1: arb_sin_cos_arf_rs_generic(s2, NULL, arb_midref(x), prec); arb_sin_cos_arf_rs_generic(NULL, c2, arb_midref(x), prec); break; case 2: arb_set(s2, x); arb_sin_cos_arf_rs_generic(NULL, c2, arb_midref(s2), prec); arb_sin_cos_arf_rs_generic(s2, NULL, arb_midref(s2), prec); break; case 3: arb_set(c2, x); arb_sin_cos_arf_rs_generic(s2, NULL, arb_midref(c2), prec); arb_sin_cos_arf_rs_generic(NULL, c2, arb_midref(c2), prec); break; case 4: arb_set(c2, x); arb_sin_cos_arf_rs_generic(s2, c2, arb_midref(c2), prec); break; default: arb_set(s2, x); arb_sin_cos_arf_rs_generic(s2, c2, arb_midref(s2), prec); break; } if (!arb_overlaps(s1, s2) || !arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_printf("c1 = "); arb_printn(c1, 500, 0); flint_printf("\n\n"); flint_printf("c2 = "); arb_printn(c2, 500, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(s2) < prec - 2 || arb_rel_accuracy_bits(c2) < prec - 2) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd, acc1 = %wd, acc2 = %wd\n\n", prec, arb_rel_accuracy_bits(s2), arb_rel_accuracy_bits(c2)); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 500, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 500, 0); flint_printf("\n\n"); flint_printf("c1 = "); arb_printn(c1, 500, 0); flint_printf("\n\n"); flint_printf("c2 = "); arb_printn(c2, 500, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(s1); arb_clear(s2); arb_clear(c1); arb_clear(c2); } /* test the series evaluation code directly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z; slong prec; slong N; int cosine; arb_init(x); arb_init(y); arb_init(z); prec = 2 + n_randint(state, 2000); N = n_randint(state, 100); cosine = n_randint(state, 2); arb_randtest(x, state, 1 + n_randint(state, 2000), 1); mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_mul_2exp_si(x, x, -n_randint(state, 2 * prec)); if (cosine) { arb_cos(y, x, prec); arb_sin_cos_taylor_sum_rs(z, x, N, 1, prec); } else { arb_sin(y, x, prec); arb_sin_cos_taylor_sum_rs(z, x, N, 0, prec); } if (!arb_overlaps(z, y)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd, N = %wd, cosine = %d\n\n", prec, N, cosine); flint_printf("x = "); arb_printn(x, 500, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 500, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 500, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_generic.c000066400000000000000000000137711417376376500176570ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_generic...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t q; mpfr_t t, u; slong prec0, prec; prec0 = 400; if (iter % 100 == 0) prec0 = 8000; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); fmpq_init(q); mpfr_init2(t, prec + 200); mpfr_init2(u, prec + 200); arb_randtest(a, state, 1 + n_randint(state, prec0), 6); arb_randtest(b, state, 1 + n_randint(state, prec0), 6); arb_randtest(c, state, 1 + n_randint(state, prec0), 6); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, prec0)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_sin_cos(t, u, t, MPFR_RNDN); arb_sin_cos_generic(b, c, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment (sin)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } if (!arb_contains_mpfr(c, u)) { flint_printf("FAIL: containment (cos)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(q); mpfr_clear(t); mpfr_clear(u); } /* check large arguments */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d, e; slong prec0, prec1, prec2, prec3; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); if (iter % 10 == 0) prec3 = 50000; else prec3 = 100; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(e); arb_randtest_special(a, state, 1 + n_randint(state, prec0), prec3); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(d, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(e, state, 1 + n_randint(state, prec0), 100); arb_sin_cos_generic(b, c, a, prec1); arb_sin_cos_generic(d, e, a, prec2); if (!arb_overlaps(b, d) || !arb_overlaps(c, e)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("e = "); arb_print(e); flint_printf("\n\n"); flint_abort(); } /* check sin(a)^2 + cos(a)^2 = 1 */ arb_mul(d, b, b, prec1); arb_mul(e, c, c, prec1); arb_add(d, d, e, prec1); arb_sub_ui(d, d, 1, prec1); if (!arb_contains_zero(d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(e); } /* check accuracy */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, s, c; slong prec0, prec; mag_t allow; if (iter % 10 == 0) prec0 = 10000; else prec0 = 400; prec = 2 + n_randint(state, prec0); arb_init(a); arb_init(s); arb_init(c); mag_init(allow); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 12); arb_randtest_special(s, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); if (n_randint(state, 2)) { arb_sin_cos_generic(s, c, a, prec); } else { arb_sin_cos_generic(s, NULL, a, prec); arb_sin_cos_generic(NULL, c, a, prec); } if (!arb_is_finite(a)) { mag_inf(allow); } else { mag_set_ui_2exp_si(allow, 1, -prec + 1); mag_max(allow, allow, arb_radref(a)); mag_mul_2exp_si(allow, allow, 1); } if (mag_cmp(arb_radref(s), allow) > 0 || mag_cmp(arb_radref(c), allow) > 0) { flint_printf("FAIL: accuracy\n\n"); flint_printf("a = "); arb_printn(a, 500, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 500, 0); flint_printf("\n\n"); flint_printf("c = "); arb_printn(c, 500, 0); flint_printf("\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("allow = "); mag_printd(allow, 5); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(s); arb_clear(c); mag_clear(allow); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_pi.c000066400000000000000000000036701417376376500166500ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d, e; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(e); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_randtest(d, state, 1 + n_randint(state, 200), 10); arb_randtest(e, state, 1 + n_randint(state, 200), 10); arb_const_pi(b, prec); arb_mul(b, b, a, prec); arb_sin_cos(b, d, b, prec); arb_sin_cos_pi(c, e, a, prec); if (!arb_overlaps(b, c) || !arb_overlaps(d, e)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("e = "); arb_print(e); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_pi_fmpq.c000066400000000000000000000035321417376376500176700ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_pi_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t s1, c1, s2, c2; fmpq_t x; slong prec; prec = 2 + n_randint(state, 5000); arb_init(s1); arb_init(c1); arb_init(s2); arb_init(c2); fmpq_init(x); fmpq_randtest(x, state, 1 + n_randint(state, 200)); arb_sin_cos_pi_fmpq(s1, c1, x, prec); arb_const_pi(s2, prec); arb_mul_fmpz(s2, s2, fmpq_numref(x), prec); arb_div_fmpz(s2, s2, fmpq_denref(x), prec); arb_sin_cos(s2, c2, s2, prec); if (!arb_overlaps(s1, s2) || !arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("s1 = "); arb_printd(s1, 15); flint_printf("\n\n"); flint_printf("c1 = "); arb_printd(c1, 15); flint_printf("\n\n"); flint_printf("s2 = "); arb_printd(s2, 15); flint_printf("\n\n"); flint_printf("c2 = "); arb_printd(c2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(c1); arb_clear(s2); arb_clear(c2); fmpq_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_pi_fmpq_algebraic.c000066400000000000000000000056611417376376500216660ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_pi_fmpq_algebraic...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t s1, s2, c1, c2; ulong p, q, g; slong prec; prec = 2 + n_randint(state, 5000); q = 1 + n_randint(state, 500); p = n_randint(state, q / 2 + 1); g = n_gcd(q, p); q /= g; p /= g; arb_init(s1); arb_init(s2); arb_init(c1); arb_init(c2); _arb_sin_cos_pi_fmpq_algebraic(s1, c1, p, q, prec); arb_const_pi(s2, prec); arb_mul_ui(s2, s2, p, prec); arb_div_ui(s2, s2, q, prec); arb_sin_cos(s2, c2, s2, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("s1 = "); arb_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); arb_printd(s2, 15); flint_printf("\n\n"); flint_abort(); } if (!arb_overlaps(c1, c2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("c1 = "); arb_printd(c1, 15); flint_printf("\n\n"); flint_printf("c2 = "); arb_printd(c2, 15); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(s1) < prec - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("prec=%wd eff=%wd\n", prec, arb_rel_accuracy_bits(s1)); flint_printf("s1 = "); arb_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); arb_printd(s2, 15); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(c1) < prec - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("prec=%wd eff=%wd\n", prec, arb_rel_accuracy_bits(c1)); flint_printf("c1 = "); arb_printd(c1, 15); flint_printf("\n\n"); flint_printf("c2 = "); arb_printd(c2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(c1); arb_clear(c2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_tab.c000066400000000000000000000155301417376376500170040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong i, which; mpfr_t tabx, sinx, y1, y2; mpz_t tt; flint_printf("sin_cos_tab...."); fflush(stdout); { slong prec, bits, num; prec = ARB_SIN_COS_TAB1_LIMBS * FLINT_BITS; bits = ARB_SIN_COS_TAB1_BITS; num = ARB_SIN_COS_TAB1_NUM; mpfr_init2(tabx, prec); mpfr_init2(sinx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (which = 0; which < 2; which++) { for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_sin_cos_tab1[2 * i + which]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(sinx, i, MPFR_RNDD); mpfr_div_2ui(sinx, sinx, bits, MPFR_RNDD); if (which) mpfr_cos(sinx, sinx, MPFR_RNDD); else mpfr_sin(sinx, sinx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, sinx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (which && i == 0) /* special case */ { mpfr_set_ui(y2, 1, MPFR_RNDD); mpfr_mul_2ui(y2, y2, prec, MPFR_RNDD); mpfr_sub_ui(y2, y2, 1, MPFR_RNDD); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); } if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: which = %wd, i = %wd, bits = %wd, prec = %wd\n", which, i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } } mpfr_clear(tabx); mpfr_clear(sinx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_SIN_COS_TAB2_LIMBS * FLINT_BITS; bits = ARB_SIN_COS_TAB21_BITS; num = ARB_SIN_COS_TAB21_NUM; mpfr_init2(tabx, prec); mpfr_init2(sinx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (which = 0; which < 2; which++) { for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_sin_cos_tab21[2 * i + which]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(sinx, i, MPFR_RNDD); mpfr_div_2ui(sinx, sinx, bits, MPFR_RNDD); if (which) mpfr_cos(sinx, sinx, MPFR_RNDD); else mpfr_sin(sinx, sinx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, sinx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (which && i == 0) /* special case */ { mpfr_set_ui(y2, 1, MPFR_RNDD); mpfr_mul_2ui(y2, y2, prec, MPFR_RNDD); mpfr_sub_ui(y2, y2, 1, MPFR_RNDD); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); } if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } } mpfr_clear(tabx); mpfr_clear(sinx); mpfr_clear(y1); mpfr_clear(y2); } { slong prec, bits, num; prec = ARB_SIN_COS_TAB2_LIMBS * FLINT_BITS; bits = ARB_SIN_COS_TAB21_BITS + ARB_SIN_COS_TAB22_BITS; num = ARB_SIN_COS_TAB22_NUM; mpfr_init2(tabx, prec); mpfr_init2(sinx, prec); mpfr_init2(y1, prec); mpfr_init2(y2, prec); for (which = 0; which < 2; which++) { for (i = 0; i < num; i++) { tt->_mp_d = (mp_ptr) arb_sin_cos_tab22[2 * i + which]; tt->_mp_size = prec / FLINT_BITS; tt->_mp_alloc = tt->_mp_size; while (tt->_mp_size > 0 && tt->_mp_d[tt->_mp_size-1] == 0) tt->_mp_size--; mpfr_set_z(tabx, tt, MPFR_RNDD); mpfr_div_2ui(tabx, tabx, prec, MPFR_RNDD); mpfr_set_ui(sinx, i, MPFR_RNDD); mpfr_div_2ui(sinx, sinx, bits, MPFR_RNDD); if (which) mpfr_cos(sinx, sinx, MPFR_RNDD); else mpfr_sin(sinx, sinx, MPFR_RNDD); mpfr_mul_2ui(y1, tabx, prec, MPFR_RNDD); mpfr_floor(y1, y1); mpfr_div_2ui(y1, y1, prec, MPFR_RNDD); mpfr_mul_2ui(y2, sinx, prec, MPFR_RNDD); mpfr_floor(y2, y2); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); if (which && i == 0) /* special case */ { mpfr_set_ui(y2, 1, MPFR_RNDD); mpfr_mul_2ui(y2, y2, prec, MPFR_RNDD); mpfr_sub_ui(y2, y2, 1, MPFR_RNDD); mpfr_div_2ui(y2, y2, prec, MPFR_RNDD); } if (!mpfr_equal_p(y1, y2)) { flint_printf("FAIL: i = %wd, bits = %wd, prec = %wd\n", i, bits, prec); mpfr_printf("y1 = %.1500Rg\n", y1); mpfr_printf("y2 = %.1500Rg\n", y2); flint_abort(); } } } mpfr_clear(tabx); mpfr_clear(sinx); mpfr_clear(y1); mpfr_clear(y2); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_cos_taylor_rs.c000066400000000000000000000066071417376376500202610ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/mpn_extras.h" #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_taylor_rs...."); fflush(stdout); flint_randinit(state); _flint_rand_init_gmp(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mp_ptr x, y1s, y1c, y2s, y2c, t; mp_limb_t err1, err2; ulong N; mp_size_t xn; int cmp, result; N = n_randint(state, 144 - 1); xn = 1 + n_randint(state, 20); x = flint_malloc(sizeof(mp_limb_t) * xn); y1s = flint_malloc(sizeof(mp_limb_t) * xn); y1c = flint_malloc(sizeof(mp_limb_t) * xn); y2s = flint_malloc(sizeof(mp_limb_t) * xn); y2c = flint_malloc(sizeof(mp_limb_t) * xn); t = flint_malloc(sizeof(mp_limb_t) * xn); flint_mpn_rrandom(x, state->gmp_state, xn); flint_mpn_rrandom(y1s, state->gmp_state, xn); flint_mpn_rrandom(y1c, state->gmp_state, xn); flint_mpn_rrandom(y2s, state->gmp_state, xn); flint_mpn_rrandom(y2c, state->gmp_state, xn); x[xn - 1] &= (LIMB_ONES >> 4); _arb_sin_cos_taylor_naive(y1s, y1c, &err1, x, xn, N); _arb_sin_cos_taylor_rs(y2s, y2c, &err2, x, xn, N, 0, 1); cmp = mpn_cmp(y1s, y2s, xn); if (cmp == 0) { result = 1; } else if (cmp > 0) { mpn_sub_n(t, y1s, y2s, xn); result = flint_mpn_zero_p(t + 1, xn - 1) && (t[0] <= err2); } else { mpn_sub_n(t, y2s, y1s, xn); result = flint_mpn_zero_p(t + 1, xn - 1) && (t[0] <= err2); } if (!result) { flint_printf("FAIL\n"); flint_printf("N = %wd xn = %wd\n", N, xn); flint_printf("x ="); flint_mpn_debug(x, xn); flint_printf("y1s ="); flint_mpn_debug(y1s, xn); flint_printf("y2s ="); flint_mpn_debug(y2s, xn); flint_abort(); } cmp = mpn_cmp(y1c, y2c, xn); if (cmp == 0) { result = 1; } else if (cmp > 0) { mpn_sub_n(t, y1c, y2c, xn); result = flint_mpn_zero_p(t + 1, xn - 1) && (t[0] <= err2); } else { mpn_sub_n(t, y2c, y1c, xn); result = flint_mpn_zero_p(t + 1, xn - 1) && (t[0] <= err2); } if (!result) { flint_printf("FAIL\n"); flint_printf("N = %wd xn = %wd\n", N, xn); flint_printf("x ="); flint_mpn_debug(x, xn); flint_printf("y1c ="); flint_mpn_debug(y1c, xn); flint_printf("y2c ="); flint_mpn_debug(y2c, xn); flint_abort(); } flint_free(x); flint_free(y1s); flint_free(y1c); flint_free(y2s); flint_free(y2c); flint_free(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_pi.c000066400000000000000000000030511417376376500157750ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_const_pi(b, prec); arb_mul(b, b, a, prec); arb_sin(b, b, prec); arb_sin_pi(c, a, prec); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_pi_fmpq.c000066400000000000000000000030611417376376500170210ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_pi_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t s1, s2; fmpq_t x; slong prec; prec = 2 + n_randint(state, 5000); arb_init(s1); arb_init(s2); fmpq_init(x); fmpq_randtest(x, state, 1 + n_randint(state, 200)); arb_sin_pi_fmpq(s1, x, prec); arb_const_pi(s2, prec); arb_mul_fmpz(s2, s2, fmpq_numref(x), prec); arb_div_fmpz(s2, s2, fmpq_denref(x), prec); arb_sin(s2, s2, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("s1 = "); arb_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); arb_printd(s2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); fmpq_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sin_pi_fmpq_algebraic.c000066400000000000000000000040241417376376500210120ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_pi_fmpq_algebraic...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t s1, s2; ulong p, q, g; slong prec; prec = 2 + n_randint(state, 5000); q = 1 + n_randint(state, 500); p = n_randint(state, q / 2 + 1); g = n_gcd(q, p); q /= g; p /= g; arb_init(s1); arb_init(s2); _arb_sin_pi_fmpq_algebraic(s1, p, q, prec); arb_const_pi(s2, prec); arb_mul_ui(s2, s2, p, prec); arb_div_ui(s2, s2, q, prec); arb_sin(s2, s2, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("s1 = "); arb_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); arb_printd(s2, 15); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(s1) < prec - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("p/q = %wu/%wu", p, q); flint_printf("\n\n"); flint_printf("prec=%wd eff=%wd\n", prec, arb_rel_accuracy_bits(s1)); flint_printf("s1 = "); arb_printd(s1, 15); flint_printf("\n\n"); flint_printf("s2 = "); arb_printd(s2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sinc.c000066400000000000000000000076171417376376500154640ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sinc...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, a; slong prec, mag_bits; prec = 2 + n_randint(state, 500); mag_bits = 6 + n_randint(state, 500); arb_init(x); arb_randtest(x, state, 1 + n_randint(state, prec), mag_bits); arb_init(a); arb_sinc(a, x, prec); /* sinc(x) approximately in [-2, 2] */ { arb_t b; arb_init(b); arb_zero(b); mag_set_d(arb_radref(b), 1.01); mag_mul_2exp_si(arb_radref(b), arb_radref(b), 1); if (!arb_contains(b, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(b); } /* sinc(x) * x = sin(x) */ { arb_t b, c; arb_init(b); arb_init(c); arb_mul(b, a, x, prec); arb_sin(c, x, prec); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap (sin)\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(b); arb_clear(c); } /* aliasing */ { arb_t b; arb_init(b); arb_set(b, x); arb_sinc(b, b, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(b); } arb_clear(x); arb_clear(a); } /* Check a few special intervals. */ { arb_t x, y; slong prec; arb_init(x); arb_init(y); prec = 32; arb_neg_inf(x); arb_sinc(y, x, prec); if (!arb_is_zero(y)) { flint_printf("FAIL: negative infinity\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } arb_pos_inf(x); arb_sinc(y, x, prec); if (!arb_is_zero(y)) { flint_printf("FAIL: positive infinity\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } arb_zero_pm_inf(x); arb_sinc(y, x, prec); if (!(arb_is_finite(y) && arb_contains_negative(y) && arb_contains_positive(y) && arb_contains_zero(y))) { flint_printf("FAIL: the whole extended real line\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sinc_pi.c000066400000000000000000000100051417376376500161350ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sinc_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, y, z; slong prec; arb_init(x); arb_init(y); arb_init(z); prec = 2 + n_randint(state, 200); arb_randtest(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest(y, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); if (n_randint(state, 2)) { arb_set(y, x); arb_sinc_pi(y, y, prec); } else arb_sinc_pi(y, x, prec); arb_const_pi(z, prec); arb_mul(z, z, x, prec); arb_sinc(z, z, prec); if (!arb_overlaps(y, z)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_abort(); } if (arb_is_int(x)) { if (arb_is_zero(x) && !arb_is_one(y)) { flint_printf("FAIL: zero\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } if (arb_is_positive(x) && !arb_is_zero(y)) { flint_printf("FAIL: positive integer\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } if (arb_is_negative(x) && !arb_is_zero(y)) { flint_printf("FAIL: negative integer\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } } arb_clear(x); arb_clear(y); arb_clear(z); } /* Check a few special intervals. */ { arb_t x, y; slong prec; arb_init(x); arb_init(y); prec = 32; arb_neg_inf(x); arb_sinc_pi(y, x, prec); if (!arb_is_zero(y)) { flint_printf("FAIL: negative infinity\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } arb_pos_inf(x); arb_sinc_pi(y, x, prec); if (!arb_is_zero(y)) { flint_printf("FAIL: positive infinity\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } arb_zero_pm_inf(x); arb_sinc_pi(y, x, prec); if (!(arb_is_finite(y) && arb_contains_negative(y) && arb_contains_positive(y) && arb_contains_zero(y))) { flint_printf("FAIL: the whole extended real line\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sinh.c000066400000000000000000000033201417376376500154540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sinh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t q; mpfr_t t; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); fmpq_init(q); mpfr_init2(t, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_sinh(t, t, MPFR_RNDN); arb_sinh(b, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_sinh(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(q); mpfr_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sinh_cosh.c000066400000000000000000000040211417376376500164670ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sinh_cosh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t q; mpfr_t t, u; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); fmpq_init(q); mpfr_init2(t, prec + 100); mpfr_init2(u, prec + 100); arb_randtest(a, state, 1 + n_randint(state, 200), 3); arb_randtest(b, state, 1 + n_randint(state, 200), 3); arb_randtest(c, state, 1 + n_randint(state, 200), 3); arb_get_rand_fmpq(q, state, a, 1 + n_randint(state, 200)); fmpq_get_mpfr(t, q, MPFR_RNDN); mpfr_sinh_cosh(t, u, t, MPFR_RNDN); arb_sinh_cosh(b, c, a, prec); if (!arb_contains_mpfr(b, t)) { flint_printf("FAIL: containment (sin)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } if (!arb_contains_mpfr(c, u)) { flint_printf("FAIL: containment (cos)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(q); mpfr_clear(t); mpfr_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-special.c000066400000000000000000000672661417376376500161560ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define ASSERT(cond) if (!(cond)) { flint_printf("FAIL: %d\n", __LINE__); flint_abort(); } int main() { arb_t zero, pos, neg, pos_inf, neg_inf, pos_inf_err, neg_inf_err, zero_pm_inf, pos_pm_inf, neg_pm_inf, indet_exact, indet_pos_rad, indet_inf_rad; flint_printf("special...."); fflush(stdout); arb_init(zero); arb_init(pos); arb_init(neg); arb_init(pos_inf); arb_init(neg_inf); arb_init(pos_inf_err); arb_init(neg_inf_err); arb_init(zero_pm_inf); arb_init(pos_pm_inf); arb_init(neg_pm_inf); arb_init(indet_exact); arb_init(indet_pos_rad); arb_init(indet_inf_rad); arb_set_si(pos, 3); arb_div_ui(pos, pos, 5, 53); arb_neg(neg, pos); arb_pos_inf(pos_inf); arb_neg_inf(neg_inf); arb_pos_inf(pos_inf_err); arf_get_mag(arb_radref(pos_inf_err), arb_midref(pos)); arb_neg(neg_inf_err, pos_inf_err); arb_zero_pm_inf(zero_pm_inf); arf_set_si(arb_midref(pos_pm_inf), 3); mag_inf(arb_radref(pos_pm_inf)); arf_set_si(arb_midref(neg_pm_inf), -3); mag_inf(arb_radref(neg_pm_inf)); arf_nan(arb_midref(indet_exact)); mag_zero(arb_radref(indet_exact)); arf_nan(arb_midref(indet_pos_rad)); arf_get_mag(arb_radref(indet_pos_rad), arb_midref(pos)); arf_nan(arb_midref(indet_inf_rad)); arf_get_mag(arb_radref(indet_inf_rad), arb_midref(pos)); ASSERT(arb_is_zero(zero)); ASSERT(!arb_is_zero(pos)); ASSERT(!arb_is_zero(neg)); ASSERT(!arb_is_zero(pos_inf)); ASSERT(!arb_is_zero(neg_inf)); ASSERT(!arb_is_zero(pos_inf_err)); ASSERT(!arb_is_zero(neg_inf_err)); ASSERT(!arb_is_zero(zero_pm_inf)); ASSERT(!arb_is_zero(pos_pm_inf)); ASSERT(!arb_is_zero(neg_pm_inf)); ASSERT(!arb_is_zero(indet_exact)); ASSERT(!arb_is_zero(indet_pos_rad)); ASSERT(!arb_is_zero(indet_inf_rad)); ASSERT(!arb_is_nonzero(zero)); ASSERT(arb_is_nonzero(pos)); ASSERT(arb_is_nonzero(neg)); ASSERT(arb_is_nonzero(pos_inf)); ASSERT(arb_is_nonzero(neg_inf)); ASSERT(arb_is_nonzero(pos_inf_err)); ASSERT(arb_is_nonzero(neg_inf_err)); ASSERT(!arb_is_nonzero(zero_pm_inf)); ASSERT(!arb_is_nonzero(pos_pm_inf)); ASSERT(!arb_is_nonzero(neg_pm_inf)); ASSERT(!arb_is_nonzero(indet_exact)); ASSERT(!arb_is_nonzero(indet_pos_rad)); ASSERT(!arb_is_nonzero(indet_inf_rad)); ASSERT(!arb_is_positive(zero)); ASSERT(arb_is_positive(pos)); ASSERT(!arb_is_positive(neg)); ASSERT(arb_is_positive(pos_inf)); ASSERT(!arb_is_positive(neg_inf)); ASSERT(arb_is_positive(pos_inf_err)); ASSERT(!arb_is_positive(neg_inf_err)); ASSERT(!arb_is_positive(zero_pm_inf)); ASSERT(!arb_is_positive(pos_pm_inf)); ASSERT(!arb_is_positive(neg_pm_inf)); ASSERT(!arb_is_positive(indet_exact)); ASSERT(!arb_is_positive(indet_pos_rad)); ASSERT(!arb_is_positive(indet_inf_rad)); ASSERT(!arb_is_negative(zero)); ASSERT(!arb_is_negative(pos)); ASSERT(arb_is_negative(neg)); ASSERT(!arb_is_negative(pos_inf)); ASSERT(arb_is_negative(neg_inf)); ASSERT(!arb_is_negative(pos_inf_err)); ASSERT(arb_is_negative(neg_inf_err)); ASSERT(!arb_is_negative(zero_pm_inf)); ASSERT(!arb_is_negative(pos_pm_inf)); ASSERT(!arb_is_negative(neg_pm_inf)); ASSERT(!arb_is_negative(indet_exact)); ASSERT(!arb_is_negative(indet_pos_rad)); ASSERT(!arb_is_negative(indet_inf_rad)); ASSERT(arb_is_nonnegative(zero)); ASSERT(arb_is_nonnegative(pos)); ASSERT(!arb_is_nonnegative(neg)); ASSERT(arb_is_nonnegative(pos_inf)); ASSERT(!arb_is_nonnegative(neg_inf)); ASSERT(arb_is_nonnegative(pos_inf_err)); ASSERT(!arb_is_nonnegative(neg_inf_err)); ASSERT(!arb_is_nonnegative(zero_pm_inf)); ASSERT(!arb_is_nonnegative(pos_pm_inf)); ASSERT(!arb_is_nonnegative(neg_pm_inf)); ASSERT(!arb_is_nonnegative(indet_exact)); ASSERT(!arb_is_nonnegative(indet_pos_rad)); ASSERT(!arb_is_nonnegative(indet_inf_rad)); ASSERT(arb_is_nonpositive(zero)); ASSERT(!arb_is_nonpositive(pos)); ASSERT(arb_is_nonpositive(neg)); ASSERT(!arb_is_nonpositive(pos_inf)); ASSERT(arb_is_nonpositive(neg_inf)); ASSERT(!arb_is_nonpositive(pos_inf_err)); ASSERT(arb_is_nonpositive(neg_inf_err)); ASSERT(!arb_is_nonpositive(zero_pm_inf)); ASSERT(!arb_is_nonpositive(pos_pm_inf)); ASSERT(!arb_is_nonpositive(neg_pm_inf)); ASSERT(!arb_is_nonpositive(indet_exact)); ASSERT(!arb_is_nonpositive(indet_pos_rad)); ASSERT(!arb_is_nonpositive(indet_inf_rad)); ASSERT(!arb_contains_negative(zero)); ASSERT(!arb_contains_negative(pos)); ASSERT(arb_contains_negative(neg)); ASSERT(!arb_contains_negative(pos_inf)); ASSERT(arb_contains_negative(neg_inf)); ASSERT(!arb_contains_negative(pos_inf_err)); ASSERT(arb_contains_negative(neg_inf_err)); ASSERT(arb_contains_negative(zero_pm_inf)); ASSERT(arb_contains_negative(pos_pm_inf)); ASSERT(arb_contains_negative(neg_pm_inf)); ASSERT(arb_contains_negative(indet_exact)); ASSERT(arb_contains_negative(indet_pos_rad)); ASSERT(arb_contains_negative(indet_inf_rad)); ASSERT(arb_contains_nonpositive(zero)); ASSERT(!arb_contains_nonpositive(pos)); ASSERT(arb_contains_nonpositive(neg)); ASSERT(!arb_contains_nonpositive(pos_inf)); ASSERT(arb_contains_nonpositive(neg_inf)); ASSERT(!arb_contains_nonpositive(pos_inf_err)); ASSERT(arb_contains_nonpositive(neg_inf_err)); ASSERT(arb_contains_nonpositive(zero_pm_inf)); ASSERT(arb_contains_nonpositive(pos_pm_inf)); ASSERT(arb_contains_nonpositive(neg_pm_inf)); ASSERT(arb_contains_nonpositive(indet_exact)); ASSERT(arb_contains_nonpositive(indet_pos_rad)); ASSERT(arb_contains_nonpositive(indet_inf_rad)); ASSERT(!arb_contains_positive(zero)); ASSERT(arb_contains_positive(pos)); ASSERT(!arb_contains_positive(neg)); ASSERT(arb_contains_positive(pos_inf)); ASSERT(!arb_contains_positive(neg_inf)); ASSERT(arb_contains_positive(pos_inf_err)); ASSERT(!arb_contains_positive(neg_inf_err)); ASSERT(arb_contains_positive(zero_pm_inf)); ASSERT(arb_contains_positive(pos_pm_inf)); ASSERT(arb_contains_positive(neg_pm_inf)); ASSERT(arb_contains_positive(indet_exact)); ASSERT(arb_contains_positive(indet_pos_rad)); ASSERT(arb_contains_positive(indet_inf_rad)); ASSERT(arb_contains_nonnegative(zero)); ASSERT(arb_contains_nonnegative(pos)); ASSERT(!arb_contains_nonnegative(neg)); ASSERT(arb_contains_nonnegative(pos_inf)); ASSERT(!arb_contains_nonnegative(neg_inf)); ASSERT(arb_contains_nonnegative(pos_inf_err)); ASSERT(!arb_contains_nonnegative(neg_inf_err)); ASSERT(arb_contains_nonnegative(zero_pm_inf)); ASSERT(arb_contains_nonnegative(pos_pm_inf)); ASSERT(arb_contains_nonnegative(neg_pm_inf)); ASSERT(arb_contains_nonnegative(indet_exact)); ASSERT(arb_contains_nonnegative(indet_pos_rad)); ASSERT(arb_contains_nonnegative(indet_inf_rad)); ASSERT(arb_is_finite(zero)); ASSERT(arb_is_finite(pos)); ASSERT(arb_is_finite(neg)); ASSERT(!arb_is_finite(pos_inf)); ASSERT(!arb_is_finite(neg_inf)); ASSERT(!arb_is_finite(pos_inf_err)); ASSERT(!arb_is_finite(neg_inf_err)); ASSERT(!arb_is_finite(zero_pm_inf)); ASSERT(!arb_is_finite(pos_pm_inf)); ASSERT(!arb_is_finite(neg_pm_inf)); ASSERT(!arb_is_finite(indet_exact)); ASSERT(!arb_is_finite(indet_pos_rad)); ASSERT(!arb_is_finite(indet_inf_rad)); ASSERT(arb_contains(zero, zero)); ASSERT(!arb_contains(zero, pos)); ASSERT(!arb_contains(zero, neg)); ASSERT(!arb_contains(zero, pos_inf)); ASSERT(!arb_contains(zero, neg_inf)); ASSERT(!arb_contains(zero, pos_inf_err)); ASSERT(!arb_contains(zero, neg_inf_err)); ASSERT(!arb_contains(zero, zero_pm_inf)); ASSERT(!arb_contains(zero, pos_pm_inf)); ASSERT(!arb_contains(zero, neg_pm_inf)); ASSERT(!arb_contains(zero, indet_exact)); ASSERT(!arb_contains(zero, indet_pos_rad)); ASSERT(!arb_contains(zero, indet_inf_rad)); ASSERT(!arb_contains(pos, zero)); ASSERT(arb_contains(pos, pos)); ASSERT(!arb_contains(pos, neg)); ASSERT(!arb_contains(pos, pos_inf)); ASSERT(!arb_contains(pos, neg_inf)); ASSERT(!arb_contains(pos, pos_inf_err)); ASSERT(!arb_contains(pos, neg_inf_err)); ASSERT(!arb_contains(pos, zero_pm_inf)); ASSERT(!arb_contains(pos, pos_pm_inf)); ASSERT(!arb_contains(pos, neg_pm_inf)); ASSERT(!arb_contains(pos, indet_exact)); ASSERT(!arb_contains(pos, indet_pos_rad)); ASSERT(!arb_contains(pos, indet_inf_rad)); ASSERT(!arb_contains(neg, zero)); ASSERT(!arb_contains(neg, pos)); ASSERT(arb_contains(neg, neg)); ASSERT(!arb_contains(neg, pos_inf)); ASSERT(!arb_contains(neg, neg_inf)); ASSERT(!arb_contains(neg, pos_inf_err)); ASSERT(!arb_contains(neg, neg_inf_err)); ASSERT(!arb_contains(neg, zero_pm_inf)); ASSERT(!arb_contains(neg, pos_pm_inf)); ASSERT(!arb_contains(neg, neg_pm_inf)); ASSERT(!arb_contains(neg, indet_exact)); ASSERT(!arb_contains(neg, indet_pos_rad)); ASSERT(!arb_contains(neg, indet_inf_rad)); ASSERT(!arb_contains(pos_inf, zero)); ASSERT(!arb_contains(pos_inf, pos)); ASSERT(!arb_contains(pos_inf, neg)); ASSERT(arb_contains(pos_inf, pos_inf)); ASSERT(!arb_contains(pos_inf, neg_inf)); ASSERT(arb_contains(pos_inf, pos_inf_err)); ASSERT(!arb_contains(pos_inf, neg_inf_err)); ASSERT(!arb_contains(pos_inf, zero_pm_inf)); ASSERT(!arb_contains(pos_inf, pos_pm_inf)); ASSERT(!arb_contains(pos_inf, neg_pm_inf)); ASSERT(!arb_contains(pos_inf, indet_exact)); ASSERT(!arb_contains(pos_inf, indet_pos_rad)); ASSERT(!arb_contains(pos_inf, indet_inf_rad)); ASSERT(!arb_contains(neg_inf, zero)); ASSERT(!arb_contains(neg_inf, pos)); ASSERT(!arb_contains(neg_inf, neg)); ASSERT(!arb_contains(neg_inf, pos_inf)); ASSERT(arb_contains(neg_inf, neg_inf)); ASSERT(!arb_contains(neg_inf, pos_inf_err)); ASSERT(arb_contains(neg_inf, neg_inf_err)); ASSERT(!arb_contains(neg_inf, zero_pm_inf)); ASSERT(!arb_contains(neg_inf, pos_pm_inf)); ASSERT(!arb_contains(neg_inf, neg_pm_inf)); ASSERT(!arb_contains(neg_inf, indet_exact)); ASSERT(!arb_contains(neg_inf, indet_pos_rad)); ASSERT(!arb_contains(neg_inf, indet_inf_rad)); ASSERT(!arb_contains(pos_inf_err, zero)); ASSERT(!arb_contains(pos_inf_err, pos)); ASSERT(!arb_contains(pos_inf_err, neg)); ASSERT(arb_contains(pos_inf_err, pos_inf)); ASSERT(!arb_contains(pos_inf_err, neg_inf)); ASSERT(arb_contains(pos_inf_err, pos_inf_err)); ASSERT(!arb_contains(pos_inf_err, neg_inf_err)); ASSERT(!arb_contains(pos_inf_err, zero_pm_inf)); ASSERT(!arb_contains(pos_inf_err, pos_pm_inf)); ASSERT(!arb_contains(pos_inf_err, neg_pm_inf)); ASSERT(!arb_contains(pos_inf_err, indet_exact)); ASSERT(!arb_contains(pos_inf_err, indet_pos_rad)); ASSERT(!arb_contains(pos_inf_err, indet_inf_rad)); ASSERT(!arb_contains(neg_inf_err, zero)); ASSERT(!arb_contains(neg_inf_err, pos)); ASSERT(!arb_contains(neg_inf_err, neg)); ASSERT(!arb_contains(neg_inf_err, pos_inf)); ASSERT(arb_contains(neg_inf_err, neg_inf)); ASSERT(!arb_contains(neg_inf_err, pos_inf_err)); ASSERT(arb_contains(neg_inf_err, neg_inf_err)); ASSERT(!arb_contains(neg_inf_err, zero_pm_inf)); ASSERT(!arb_contains(neg_inf_err, pos_pm_inf)); ASSERT(!arb_contains(neg_inf_err, neg_pm_inf)); ASSERT(!arb_contains(neg_inf_err, indet_exact)); ASSERT(!arb_contains(neg_inf_err, indet_pos_rad)); ASSERT(!arb_contains(neg_inf_err, indet_inf_rad)); ASSERT(arb_contains(zero_pm_inf, zero)); ASSERT(arb_contains(zero_pm_inf, pos)); ASSERT(arb_contains(zero_pm_inf, neg)); ASSERT(arb_contains(zero_pm_inf, pos_inf)); ASSERT(arb_contains(zero_pm_inf, neg_inf)); ASSERT(arb_contains(zero_pm_inf, pos_inf_err)); ASSERT(arb_contains(zero_pm_inf, neg_inf_err)); ASSERT(arb_contains(zero_pm_inf, zero_pm_inf)); ASSERT(arb_contains(zero_pm_inf, pos_pm_inf)); ASSERT(arb_contains(zero_pm_inf, neg_pm_inf)); ASSERT(!arb_contains(zero_pm_inf, indet_exact)); ASSERT(!arb_contains(zero_pm_inf, indet_pos_rad)); ASSERT(!arb_contains(zero_pm_inf, indet_inf_rad)); ASSERT(arb_contains(pos_pm_inf, zero)); ASSERT(arb_contains(pos_pm_inf, pos)); ASSERT(arb_contains(pos_pm_inf, neg)); ASSERT(arb_contains(pos_pm_inf, pos_inf)); ASSERT(arb_contains(pos_pm_inf, neg_inf)); ASSERT(arb_contains(pos_pm_inf, pos_inf_err)); ASSERT(arb_contains(pos_pm_inf, neg_inf_err)); ASSERT(arb_contains(pos_pm_inf, zero_pm_inf)); ASSERT(arb_contains(pos_pm_inf, pos_pm_inf)); ASSERT(arb_contains(pos_pm_inf, neg_pm_inf)); ASSERT(!arb_contains(pos_pm_inf, indet_exact)); ASSERT(!arb_contains(pos_pm_inf, indet_pos_rad)); ASSERT(!arb_contains(pos_pm_inf, indet_inf_rad)); ASSERT(arb_contains(neg_pm_inf, zero)); ASSERT(arb_contains(neg_pm_inf, pos)); ASSERT(arb_contains(neg_pm_inf, neg)); ASSERT(arb_contains(neg_pm_inf, pos_inf)); ASSERT(arb_contains(neg_pm_inf, neg_inf)); ASSERT(arb_contains(neg_pm_inf, pos_inf_err)); ASSERT(arb_contains(neg_pm_inf, neg_inf_err)); ASSERT(arb_contains(neg_pm_inf, zero_pm_inf)); ASSERT(arb_contains(neg_pm_inf, pos_pm_inf)); ASSERT(arb_contains(neg_pm_inf, neg_pm_inf)); ASSERT(!arb_contains(neg_pm_inf, indet_exact)); ASSERT(!arb_contains(neg_pm_inf, indet_pos_rad)); ASSERT(!arb_contains(neg_pm_inf, indet_inf_rad)); ASSERT(arb_contains(indet_exact, zero)); ASSERT(arb_contains(indet_exact, pos)); ASSERT(arb_contains(indet_exact, neg)); ASSERT(arb_contains(indet_exact, pos_inf)); ASSERT(arb_contains(indet_exact, neg_inf)); ASSERT(arb_contains(indet_exact, pos_inf_err)); ASSERT(arb_contains(indet_exact, neg_inf_err)); ASSERT(arb_contains(indet_exact, zero_pm_inf)); ASSERT(arb_contains(indet_exact, pos_pm_inf)); ASSERT(arb_contains(indet_exact, neg_pm_inf)); ASSERT(arb_contains(indet_exact, indet_exact)); ASSERT(arb_contains(indet_exact, indet_pos_rad)); ASSERT(arb_contains(indet_exact, indet_inf_rad)); ASSERT(arb_contains(indet_pos_rad, zero)); ASSERT(arb_contains(indet_pos_rad, pos)); ASSERT(arb_contains(indet_pos_rad, neg)); ASSERT(arb_contains(indet_pos_rad, pos_inf)); ASSERT(arb_contains(indet_pos_rad, neg_inf)); ASSERT(arb_contains(indet_pos_rad, pos_inf_err)); ASSERT(arb_contains(indet_pos_rad, neg_inf_err)); ASSERT(arb_contains(indet_pos_rad, zero_pm_inf)); ASSERT(arb_contains(indet_pos_rad, pos_pm_inf)); ASSERT(arb_contains(indet_pos_rad, neg_pm_inf)); ASSERT(arb_contains(indet_pos_rad, indet_exact)); ASSERT(arb_contains(indet_pos_rad, indet_pos_rad)); ASSERT(arb_contains(indet_pos_rad, indet_inf_rad)); ASSERT(arb_contains(indet_inf_rad, zero)); ASSERT(arb_contains(indet_inf_rad, pos)); ASSERT(arb_contains(indet_inf_rad, neg)); ASSERT(arb_contains(indet_inf_rad, pos_inf)); ASSERT(arb_contains(indet_inf_rad, neg_inf)); ASSERT(arb_contains(indet_inf_rad, pos_inf_err)); ASSERT(arb_contains(indet_inf_rad, neg_inf_err)); ASSERT(arb_contains(indet_inf_rad, zero_pm_inf)); ASSERT(arb_contains(indet_inf_rad, pos_pm_inf)); ASSERT(arb_contains(indet_inf_rad, neg_pm_inf)); ASSERT(arb_contains(indet_inf_rad, indet_exact)); ASSERT(arb_contains(indet_inf_rad, indet_pos_rad)); ASSERT(arb_contains(indet_inf_rad, indet_inf_rad)); ASSERT(arb_overlaps(zero, zero)); ASSERT(!arb_overlaps(zero, pos)); ASSERT(!arb_overlaps(zero, neg)); ASSERT(!arb_overlaps(zero, pos_inf)); ASSERT(!arb_overlaps(zero, neg_inf)); ASSERT(!arb_overlaps(zero, pos_inf_err)); ASSERT(!arb_overlaps(zero, neg_inf_err)); ASSERT(arb_overlaps(zero, zero_pm_inf)); ASSERT(arb_overlaps(zero, pos_pm_inf)); ASSERT(arb_overlaps(zero, neg_pm_inf)); ASSERT(arb_overlaps(zero, indet_exact)); ASSERT(arb_overlaps(zero, indet_pos_rad)); ASSERT(arb_overlaps(zero, indet_inf_rad)); ASSERT(!arb_overlaps(pos, zero)); ASSERT(arb_overlaps(pos, pos)); ASSERT(!arb_overlaps(pos, neg)); ASSERT(!arb_overlaps(pos, pos_inf)); ASSERT(!arb_overlaps(pos, neg_inf)); ASSERT(!arb_overlaps(pos, pos_inf_err)); ASSERT(!arb_overlaps(pos, neg_inf_err)); ASSERT(arb_overlaps(pos, zero_pm_inf)); ASSERT(arb_overlaps(pos, pos_pm_inf)); ASSERT(arb_overlaps(pos, neg_pm_inf)); ASSERT(arb_overlaps(pos, indet_exact)); ASSERT(arb_overlaps(pos, indet_pos_rad)); ASSERT(arb_overlaps(pos, indet_inf_rad)); ASSERT(!arb_overlaps(neg, zero)); ASSERT(!arb_overlaps(neg, pos)); ASSERT(arb_overlaps(neg, neg)); ASSERT(!arb_overlaps(neg, pos_inf)); ASSERT(!arb_overlaps(neg, neg_inf)); ASSERT(!arb_overlaps(neg, pos_inf_err)); ASSERT(!arb_overlaps(neg, neg_inf_err)); ASSERT(arb_overlaps(neg, zero_pm_inf)); ASSERT(arb_overlaps(neg, pos_pm_inf)); ASSERT(arb_overlaps(neg, neg_pm_inf)); ASSERT(arb_overlaps(neg, indet_exact)); ASSERT(arb_overlaps(neg, indet_pos_rad)); ASSERT(arb_overlaps(neg, indet_inf_rad)); ASSERT(!arb_overlaps(pos_inf, zero)); ASSERT(!arb_overlaps(pos_inf, pos)); ASSERT(!arb_overlaps(pos_inf, neg)); ASSERT(arb_overlaps(pos_inf, pos_inf)); ASSERT(!arb_overlaps(pos_inf, neg_inf)); ASSERT(arb_overlaps(pos_inf, pos_inf_err)); ASSERT(!arb_overlaps(pos_inf, neg_inf_err)); ASSERT(arb_overlaps(pos_inf, zero_pm_inf)); ASSERT(arb_overlaps(pos_inf, pos_pm_inf)); ASSERT(arb_overlaps(pos_inf, neg_pm_inf)); ASSERT(arb_overlaps(pos_inf, indet_exact)); ASSERT(arb_overlaps(pos_inf, indet_pos_rad)); ASSERT(arb_overlaps(pos_inf, indet_inf_rad)); ASSERT(!arb_overlaps(neg_inf, zero)); ASSERT(!arb_overlaps(neg_inf, pos)); ASSERT(!arb_overlaps(neg_inf, neg)); ASSERT(!arb_overlaps(neg_inf, pos_inf)); ASSERT(arb_overlaps(neg_inf, neg_inf)); ASSERT(!arb_overlaps(neg_inf, pos_inf_err)); ASSERT(arb_overlaps(neg_inf, neg_inf_err)); ASSERT(arb_overlaps(neg_inf, zero_pm_inf)); ASSERT(arb_overlaps(neg_inf, pos_pm_inf)); ASSERT(arb_overlaps(neg_inf, neg_pm_inf)); ASSERT(arb_overlaps(neg_inf, indet_exact)); ASSERT(arb_overlaps(neg_inf, indet_pos_rad)); ASSERT(arb_overlaps(neg_inf, indet_inf_rad)); ASSERT(!arb_overlaps(pos_inf_err, zero)); ASSERT(!arb_overlaps(pos_inf_err, pos)); ASSERT(!arb_overlaps(pos_inf_err, neg)); ASSERT(arb_overlaps(pos_inf_err, pos_inf)); ASSERT(!arb_overlaps(pos_inf_err, neg_inf)); ASSERT(arb_overlaps(pos_inf_err, pos_inf_err)); ASSERT(!arb_overlaps(pos_inf_err, neg_inf_err)); ASSERT(arb_overlaps(pos_inf_err, zero_pm_inf)); ASSERT(arb_overlaps(pos_inf_err, pos_pm_inf)); ASSERT(arb_overlaps(pos_inf_err, neg_pm_inf)); ASSERT(arb_overlaps(pos_inf_err, indet_exact)); ASSERT(arb_overlaps(pos_inf_err, indet_pos_rad)); ASSERT(arb_overlaps(pos_inf_err, indet_inf_rad)); ASSERT(!arb_overlaps(neg_inf_err, zero)); ASSERT(!arb_overlaps(neg_inf_err, pos)); ASSERT(!arb_overlaps(neg_inf_err, neg)); ASSERT(!arb_overlaps(neg_inf_err, pos_inf)); ASSERT(arb_overlaps(neg_inf_err, neg_inf)); ASSERT(!arb_overlaps(neg_inf_err, pos_inf_err)); ASSERT(arb_overlaps(neg_inf_err, neg_inf_err)); ASSERT(arb_overlaps(neg_inf_err, zero_pm_inf)); ASSERT(arb_overlaps(neg_inf_err, pos_pm_inf)); ASSERT(arb_overlaps(neg_inf_err, neg_pm_inf)); ASSERT(arb_overlaps(neg_inf_err, indet_exact)); ASSERT(arb_overlaps(neg_inf_err, indet_pos_rad)); ASSERT(arb_overlaps(neg_inf_err, indet_inf_rad)); ASSERT(arb_overlaps(zero_pm_inf, zero)); ASSERT(arb_overlaps(zero_pm_inf, pos)); ASSERT(arb_overlaps(zero_pm_inf, neg)); ASSERT(arb_overlaps(zero_pm_inf, pos_inf)); ASSERT(arb_overlaps(zero_pm_inf, neg_inf)); ASSERT(arb_overlaps(zero_pm_inf, pos_inf_err)); ASSERT(arb_overlaps(zero_pm_inf, neg_inf_err)); ASSERT(arb_overlaps(zero_pm_inf, zero_pm_inf)); ASSERT(arb_overlaps(zero_pm_inf, pos_pm_inf)); ASSERT(arb_overlaps(zero_pm_inf, neg_pm_inf)); ASSERT(arb_overlaps(zero_pm_inf, indet_exact)); ASSERT(arb_overlaps(zero_pm_inf, indet_pos_rad)); ASSERT(arb_overlaps(zero_pm_inf, indet_inf_rad)); ASSERT(arb_overlaps(pos_pm_inf, zero)); ASSERT(arb_overlaps(pos_pm_inf, pos)); ASSERT(arb_overlaps(pos_pm_inf, neg)); ASSERT(arb_overlaps(pos_pm_inf, pos_inf)); ASSERT(arb_overlaps(pos_pm_inf, neg_inf)); ASSERT(arb_overlaps(pos_pm_inf, pos_inf_err)); ASSERT(arb_overlaps(pos_pm_inf, neg_inf_err)); ASSERT(arb_overlaps(pos_pm_inf, zero_pm_inf)); ASSERT(arb_overlaps(pos_pm_inf, pos_pm_inf)); ASSERT(arb_overlaps(pos_pm_inf, neg_pm_inf)); ASSERT(arb_overlaps(pos_pm_inf, indet_exact)); ASSERT(arb_overlaps(pos_pm_inf, indet_pos_rad)); ASSERT(arb_overlaps(pos_pm_inf, indet_inf_rad)); ASSERT(arb_overlaps(neg_pm_inf, zero)); ASSERT(arb_overlaps(neg_pm_inf, pos)); ASSERT(arb_overlaps(neg_pm_inf, neg)); ASSERT(arb_overlaps(neg_pm_inf, pos_inf)); ASSERT(arb_overlaps(neg_pm_inf, neg_inf)); ASSERT(arb_overlaps(neg_pm_inf, pos_inf_err)); ASSERT(arb_overlaps(neg_pm_inf, neg_inf_err)); ASSERT(arb_overlaps(neg_pm_inf, zero_pm_inf)); ASSERT(arb_overlaps(neg_pm_inf, pos_pm_inf)); ASSERT(arb_overlaps(neg_pm_inf, neg_pm_inf)); ASSERT(arb_overlaps(neg_pm_inf, indet_exact)); ASSERT(arb_overlaps(neg_pm_inf, indet_pos_rad)); ASSERT(arb_overlaps(neg_pm_inf, indet_inf_rad)); ASSERT(arb_overlaps(indet_exact, zero)); ASSERT(arb_overlaps(indet_exact, pos)); ASSERT(arb_overlaps(indet_exact, neg)); ASSERT(arb_overlaps(indet_exact, pos_inf)); ASSERT(arb_overlaps(indet_exact, neg_inf)); ASSERT(arb_overlaps(indet_exact, pos_inf_err)); ASSERT(arb_overlaps(indet_exact, neg_inf_err)); ASSERT(arb_overlaps(indet_exact, zero_pm_inf)); ASSERT(arb_overlaps(indet_exact, pos_pm_inf)); ASSERT(arb_overlaps(indet_exact, neg_pm_inf)); ASSERT(arb_overlaps(indet_exact, indet_exact)); ASSERT(arb_overlaps(indet_exact, indet_pos_rad)); ASSERT(arb_overlaps(indet_exact, indet_inf_rad)); ASSERT(arb_overlaps(indet_pos_rad, zero)); ASSERT(arb_overlaps(indet_pos_rad, pos)); ASSERT(arb_overlaps(indet_pos_rad, neg)); ASSERT(arb_overlaps(indet_pos_rad, pos_inf)); ASSERT(arb_overlaps(indet_pos_rad, neg_inf)); ASSERT(arb_overlaps(indet_pos_rad, pos_inf_err)); ASSERT(arb_overlaps(indet_pos_rad, neg_inf_err)); ASSERT(arb_overlaps(indet_pos_rad, zero_pm_inf)); ASSERT(arb_overlaps(indet_pos_rad, pos_pm_inf)); ASSERT(arb_overlaps(indet_pos_rad, neg_pm_inf)); ASSERT(arb_overlaps(indet_pos_rad, indet_exact)); ASSERT(arb_overlaps(indet_pos_rad, indet_pos_rad)); ASSERT(arb_overlaps(indet_pos_rad, indet_inf_rad)); ASSERT(arb_overlaps(indet_inf_rad, zero)); ASSERT(arb_overlaps(indet_inf_rad, pos)); ASSERT(arb_overlaps(indet_inf_rad, neg)); ASSERT(arb_overlaps(indet_inf_rad, pos_inf)); ASSERT(arb_overlaps(indet_inf_rad, neg_inf)); ASSERT(arb_overlaps(indet_inf_rad, pos_inf_err)); ASSERT(arb_overlaps(indet_inf_rad, neg_inf_err)); ASSERT(arb_overlaps(indet_inf_rad, zero_pm_inf)); ASSERT(arb_overlaps(indet_inf_rad, pos_pm_inf)); ASSERT(arb_overlaps(indet_inf_rad, neg_pm_inf)); ASSERT(arb_overlaps(indet_inf_rad, indet_exact)); ASSERT(arb_overlaps(indet_inf_rad, indet_pos_rad)); ASSERT(arb_overlaps(indet_inf_rad, indet_inf_rad)); { fmpz_t t; fmpz_init(t); ASSERT(arb_get_unique_fmpz(t, zero)); ASSERT(!arb_get_unique_fmpz(t, pos_inf)); ASSERT(!arb_get_unique_fmpz(t, neg_inf)); ASSERT(!arb_get_unique_fmpz(t, pos_inf_err)); ASSERT(!arb_get_unique_fmpz(t, neg_inf_err)); ASSERT(!arb_get_unique_fmpz(t, zero_pm_inf)); ASSERT(!arb_get_unique_fmpz(t, pos_pm_inf)); ASSERT(!arb_get_unique_fmpz(t, neg_pm_inf)); ASSERT(!arb_get_unique_fmpz(t, indet_exact)); ASSERT(!arb_get_unique_fmpz(t, indet_pos_rad)); ASSERT(!arb_get_unique_fmpz(t, indet_inf_rad)); fmpz_clear(t); } { arf_t b; slong wp = 30; arf_init(b); arb_get_abs_ubound_arf(b, zero, wp); ASSERT(arf_is_zero(b)); arb_get_abs_ubound_arf(b, pos, wp); ASSERT(arf_sgn(b) > 0); arb_get_abs_ubound_arf(b, neg, wp); ASSERT(arf_sgn(b) > 0); arb_get_abs_ubound_arf(b, pos_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_ubound_arf(b, neg_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_ubound_arf(b, pos_inf_err, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_ubound_arf(b, neg_inf_err, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_ubound_arf(b, zero_pm_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_ubound_arf(b, indet_exact, wp); ASSERT(arf_is_nan(b)); arb_get_abs_ubound_arf(b, indet_pos_rad, wp); ASSERT(arf_is_nan(b)); arb_get_abs_ubound_arf(b, indet_inf_rad, wp); ASSERT(arf_is_nan(b)); arb_get_abs_lbound_arf(b, zero, wp); ASSERT(arf_is_zero(b)); arb_get_abs_lbound_arf(b, pos, wp); ASSERT(arf_sgn(b) > 0); arb_get_abs_lbound_arf(b, neg, wp); ASSERT(arf_sgn(b) > 0); arb_get_abs_lbound_arf(b, pos_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_lbound_arf(b, neg_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_lbound_arf(b, pos_inf_err, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_lbound_arf(b, neg_inf_err, wp); ASSERT(arf_is_pos_inf(b)); arb_get_abs_lbound_arf(b, zero_pm_inf, wp); ASSERT(arf_is_zero(b)); arb_get_abs_lbound_arf(b, indet_exact, wp); ASSERT(arf_is_nan(b)); arb_get_abs_lbound_arf(b, indet_pos_rad, wp); ASSERT(arf_is_nan(b)); arb_get_abs_lbound_arf(b, indet_inf_rad, wp); ASSERT(arf_is_nan(b)); arb_get_ubound_arf(b, zero, wp); ASSERT(arf_is_zero(b)); arb_get_ubound_arf(b, pos, wp); ASSERT(arf_sgn(b) > 0); arb_get_ubound_arf(b, pos_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_ubound_arf(b, neg_inf, wp); ASSERT(arf_is_neg_inf(b)); arb_get_ubound_arf(b, pos_inf_err, wp); ASSERT(arf_is_pos_inf(b)); arb_get_ubound_arf(b, neg_inf_err, wp); ASSERT(arf_is_neg_inf(b)); arb_get_ubound_arf(b, zero_pm_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_ubound_arf(b, indet_exact, wp); ASSERT(arf_is_nan(b)); arb_get_ubound_arf(b, indet_pos_rad, wp); ASSERT(arf_is_nan(b)); arb_get_ubound_arf(b, indet_inf_rad, wp); ASSERT(arf_is_nan(b)); arb_get_lbound_arf(b, zero, wp); ASSERT(arf_is_zero(b)); arb_get_lbound_arf(b, neg, wp); ASSERT(arf_sgn(b) < 0); arb_get_lbound_arf(b, pos_inf, wp); ASSERT(arf_is_pos_inf(b)); arb_get_lbound_arf(b, neg_inf, wp); ASSERT(arf_is_neg_inf(b)); arb_get_lbound_arf(b, pos_inf_err, wp); ASSERT(arf_is_pos_inf(b)); arb_get_lbound_arf(b, neg_inf_err, wp); ASSERT(arf_is_neg_inf(b)); arb_get_lbound_arf(b, zero_pm_inf, wp); ASSERT(arf_is_neg_inf(b)); arb_get_lbound_arf(b, indet_exact, wp); ASSERT(arf_is_nan(b)); arb_get_lbound_arf(b, indet_pos_rad, wp); ASSERT(arf_is_nan(b)); arb_get_lbound_arf(b, indet_inf_rad, wp); ASSERT(arf_is_nan(b)); arf_clear(b); } arb_clear(zero); arb_clear(pos); arb_clear(neg); arb_clear(pos_inf); arb_clear(neg_inf); arb_clear(pos_inf_err); arb_clear(neg_inf_err); arb_clear(zero_pm_inf); arb_clear(pos_pm_inf); arb_clear(neg_pm_inf); arb_clear(indet_exact); arb_clear(indet_pos_rad); arb_clear(indet_inf_rad); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sqrt.c000066400000000000000000000030171417376376500155070ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 200), 100); arb_sqrt(b, a, prec); arb_mul(c, b, b, prec); if (!arb_contains(c, a)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_sqrt(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sqrt1pm1.c000066400000000000000000000051151417376376500162070ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt1pm1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 20000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong prec0, prec1, prec2; if (iter % 10 == 0) prec0 = 10000; else prec0 = 1000; prec1 = 2 + n_randint(state, prec0); prec2 = 2 + n_randint(state, prec0); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(b, state, 1 + n_randint(state, prec0), 100); arb_randtest_special(c, state, 1 + n_randint(state, prec0), 100); arb_sqrt1pm1(b, a, prec1); arb_sqrt1pm1(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } /* compare with sqrt */ arb_add_ui(d, a, 1, prec2); arb_sqrt(d, d, prec2); arb_sub_ui(d, d, 1, prec2); if (!arb_overlaps(c, d)) { flint_printf("FAIL: comparison with log\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_sqrt1pm1(a, a, prec1); if (!arb_overlaps(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sqrtpos.c000066400000000000000000000031661417376376500162360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrtpos...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); do { arb_randtest(a, state, 1 + n_randint(state, 200), 10); } while (arb_contains_negative(a)); arb_sqrtpos(b, a, prec); arb_mul(c, b, b, prec); if (!arb_contains(c, a) || arb_contains_negative(b)) { flint_printf("FAIL: containment / positivity\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_sqrtpos(a, a, prec); if (!arb_equal(a, b)) { flint_printf("FAIL: aliasing\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sub.c000066400000000000000000000105061417376376500153100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sub...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t x, y, z; arb_init(a); arb_init(b); arb_init(c); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_sub(c, a, b, 2 + n_randint(state, 200)); fmpq_sub(z, x, y); if (!arb_contains_fmpq(c, z)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_sub(a, a, b, 2 + n_randint(state, 200)); fmpq_sub(z, x, y); if (!arb_contains_fmpq(a, z)) { flint_printf("FAIL: aliasing (c, a)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and b */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_sub(b, a, b, 2 + n_randint(state, 200)); fmpq_sub(z, x, y); if (!arb_contains_fmpq(b, z)) { flint_printf("FAIL: aliasing (c, b)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sub_arf.c000066400000000000000000000055671417376376500161530ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_sub_arf(c, a, x, prec); arb_sub(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arf_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_sub_arf(c, a, x, prec); arb_sub_arf(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sub_fmpz.c000066400000000000000000000055531417376376500163520ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_sub_fmpz(c, a, x, prec); arb_sub(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_sub_fmpz(c, a, x, prec); arb_sub_fmpz(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpz_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sub_si.c000066400000000000000000000053461417376376500160110ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_sub_si(c, a, x, prec); arb_sub(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_sub_si(c, a, x, prec); arb_sub_si(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-sub_ui.c000066400000000000000000000053471417376376500160140ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/ulong_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_sub_ui(c, a, x, prec); arb_sub(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_sub_ui(c, a, x, prec); arb_sub_ui(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-submul.c000066400000000000000000000221011417376376500160200ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int mag_close(const mag_t am, const mag_t bm) { arf_t t, a, b; int res1, res2; arf_init(t); arf_init(a); arf_init(b); arf_set_mag(a, am); arf_set_mag(b, bm); arf_mul_ui(t, b, 257, MAG_BITS, ARF_RND_UP); arf_mul_2exp_si(t, t, -8); res1 = arf_cmp(a, t) <= 0; arf_mul_ui(t, a, 257, MAG_BITS, ARF_RND_UP); arf_mul_2exp_si(t, t, -8); res2 = arf_cmp(b, t) <= 0; arf_clear(t); arf_clear(a); arf_clear(b); return res1 && res2; } void arb_submul_naive(arb_t z, const arb_t x, const arb_t y, slong prec) { arb_t t; arb_init(t); arb_mul(t, x, y, ARF_PREC_EXACT); arb_sub(z, z, t, prec); arb_clear(t); } int main() { slong iter, iter2; flint_rand_t state; flint_printf("submul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpq_t x, y, z; arb_init(a); arb_init(b); arb_init(c); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); arb_get_rand_fmpq(z, state, c, 1 + n_randint(state, 200)); arb_submul(c, a, b, 2 + n_randint(state, 200)); fmpq_submul(z, x, y); if (!arb_contains_fmpq(c, z)) { flint_printf("FAIL: containment\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and a */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); fmpq_set(z, x); arb_submul(a, a, b, 2 + n_randint(state, 200)); fmpq_submul(z, x, y); if (!arb_contains_fmpq(a, z)) { flint_printf("FAIL: aliasing (c, a)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* aliasing of c and b */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b; fmpq_t x, y, z; arb_init(a); arb_init(b); fmpq_init(x); fmpq_init(y); fmpq_init(z); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_get_rand_fmpq(x, state, a, 1 + n_randint(state, 200)); arb_get_rand_fmpq(y, state, b, 1 + n_randint(state, 200)); fmpq_set(z, y); arb_submul(b, a, b, 2 + n_randint(state, 200)); fmpq_submul(z, x, y); if (!arb_contains_fmpq(b, z)) { flint_printf("FAIL: aliasing (c, b)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); fmpq_print(x); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpq_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); fmpq_clear(x); fmpq_clear(y); fmpq_clear(z); } /* main test */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z, v; slong prec; arb_init(x); arb_init(y); arb_init(z); arb_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arb_randtest_special(x, state, n_randint(state,2) ? 2000 : 200, 200); arb_randtest_special(y, state, n_randint(state,2) ? 2000 : 200, 200); arb_randtest_special(z, state, n_randint(state,2) ? 2000 : 200, 200); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 5)) { case 0: arb_set(v, z); arb_submul(z, x, y, prec); arb_submul_naive(v, x, y, prec); if (!arf_equal(arb_midref(z), arb_midref(v)) || !mag_close(arb_radref(z), arb_radref(v))) { flint_printf("FAIL!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 1: arb_set(y, x); arb_set(z, v); arb_submul(z, x, y, prec); arb_submul(v, x, x, prec); if (!arf_equal(arb_midref(z), arb_midref(v)) || !mag_close(arb_radref(z), arb_radref(v))) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 2: arb_set(v, x); arb_submul(v, x, x, prec); arb_submul(x, x, x, prec); if (!arf_equal(arb_midref(x), arb_midref(v)) || !mag_close(arb_radref(x), arb_radref(v))) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; case 3: arb_set(v, x); arb_submul(v, x, y, prec); arb_submul(x, x, y, prec); if (!arf_equal(arb_midref(x), arb_midref(v)) || !mag_close(arb_radref(x), arb_radref(v))) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; default: arb_set(v, x); arb_submul(v, x, y, prec); arb_submul(x, y, x, prec); if (!arf_equal(arb_midref(x), arb_midref(v)) || !mag_close(arb_radref(x), arb_radref(v))) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("v = "); arb_print(v); flint_printf("\n\n"); flint_abort(); } break; } } arb_clear(x); arb_clear(y); arb_clear(z); arb_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-submul_arf.c000066400000000000000000000056641417376376500166670ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("submul_arf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_set(d, c); arb_submul_arf(c, a, x, prec); arb_submul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arf_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; arf_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arf_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); arf_randtest_special(x, state, 1 + n_randint(state, 2000), 100); prec = 2 + n_randint(state, 2000); arb_set_arf(b, x); arb_set(c, a); arb_submul_arf(c, a, x, prec); arb_submul_arf(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-submul_fmpz.c000066400000000000000000000056501417376376500170660ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("submul_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_set(d, c); arb_submul_fmpz(c, a, x, prec); arb_submul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); fmpz_clear(x); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; fmpz_t x; slong prec; arb_init(a); arb_init(b); arb_init(c); fmpz_init(x); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); fmpz_randtest(x, state, 1 + n_randint(state, 2000)); prec = 2 + n_randint(state, 2000); arb_set_fmpz(b, x); arb_set(c, a); arb_submul_fmpz(c, a, x, prec); arb_submul_fmpz(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); fmpz_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-submul_si.c000066400000000000000000000054431417376376500165250ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("submul_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_set(d, c); arb_submul_si(c, a, x, prec); arb_submul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = z_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_si(b, x); arb_set(c, a); arb_submul_si(c, a, x, prec); arb_submul_si(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-submul_ui.c000066400000000000000000000054441417376376500165300ustar00rootroot00000000000000/* Copyright (C) 2012-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "flint/ulong_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("submul_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_set(d, c); arb_submul_ui(c, a, x, prec); arb_submul(d, a, b, prec); if (!arb_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } /* aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; ulong x; slong prec; arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 100); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 100); x = n_randtest(state); prec = 2 + n_randint(state, 2000); arb_set_ui(b, x); arb_set(c, a); arb_submul_ui(c, a, x, prec); arb_submul_ui(a, a, x, prec); if (!arb_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-tan_pi.c000066400000000000000000000066201417376376500157730ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("tan_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(y); arb_init(a); arb_init(b); arb_init(c); arb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); arb_tan_pi(a, x, prec1); arb_tan_pi(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } /* compare with tan */ arb_const_pi(c, prec1); arb_mul(y, x, c, prec1); arb_tan(c, y, prec1); if (!arb_overlaps(a, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_tan_pi(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(a); arb_clear(b); arb_clear(c); } /* Check a few special points. */ { arb_t x, y; slong i, prec; arb_init(x); arb_init(y); prec = 32; for (i = -1; i <= 1; i++) { int arbitrary_integer = 7; arb_set_d(x, arbitrary_integer*i); arb_tan_pi(y, x, prec); if (!arb_is_zero(y)) { flint_printf("FAIL: (integer)\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } arb_set_d(x, arbitrary_integer*i + 0.5); arb_tan_pi(y, x, prec); if (arb_is_finite(y)) { flint_printf("FAIL: (integer + 1/2)\n"); flint_printf("x = "); arb_printd(x, 30); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 30); flint_printf("\n\n"); flint_abort(); } } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-tanh.c000066400000000000000000000052341417376376500154530ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("tanh...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(y); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_precise(x, state, 1 + n_randint(state, 1000), 100); arb_randtest_precise(y, state, 1 + n_randint(state, 1000), 100); arb_tanh(a, x, prec1); arb_tanh(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_abort(); } /* check tanh(x+y) = (tanh(x) + tanh(y)) / (1 + tanh(x) tanh(y)) */ arb_add(b, x, y, prec1); arb_tanh(b, b, prec1); arb_tanh(c, y, prec1); arb_add(d, a, c, prec1); arb_mul(c, a, c, prec1); arb_add_ui(c, c, 1, prec1); arb_div(d, d, c, prec1); if (!arb_overlaps(b, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_abort(); } arb_tanh(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-trim.c000066400000000000000000000037161417376376500154770ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("trim...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y; slong acc1, acc2; int accuracy_ok; arb_init(x); arb_init(y); arb_randtest_special(x, state, 1000, 100); arb_trim(y, x); if (!arb_contains(y, x)) { flint_printf("FAIL (containment):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(x); acc2 = arb_rel_accuracy_bits(y); accuracy_ok = (acc1 < 0 && acc2 <= acc1) || (acc2 >= acc1 - 1); if (!accuracy_ok) { flint_printf("FAIL (accuracy):\n\n"); flint_printf("x: %wd, y = %wd\n\n", acc1, acc2); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_abort(); } arb_trim(x, x); if (!arb_equal(y, x)) { flint_printf("FAIL (aliasing):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-ui_pow_ui.c000066400000000000000000000033171417376376500165200ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("ui_pow_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t r1, r2; ulong a, exp; slong prec; a = n_randtest(state); exp = n_randtest(state); if (n_randint(state, 10) == 0) prec = 2 + n_randint(state, 5000); else prec = 2 + n_randint(state, 500); arb_init(r1); arb_init(r2); arb_randtest(r1, state, 1 + n_randint(state, 1000), 200); arb_randtest(r2, state, 1 + n_randint(state, 1000), 200); arb_set_ui(r1, a); arb_pow_ui(r1, r1, exp, prec); arb_ui_pow_ui(r2, a, exp, prec); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = %wu\n\n", a); flint_printf("exp = %wu\n\n", exp); flint_printf("prec = %wd\n\n", prec); flint_printf("r1 = "); arb_print(r1); flint_printf("\n\n"); flint_printf("r2 = "); arb_print(r2); flint_printf("\n\n"); flint_abort(); } arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-union.c000066400000000000000000000040041417376376500156430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("union...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, y, z; slong prec; int alias; arb_init(x); arb_init(y); arb_init(z); arb_randtest_special(x, state, 200, 10); arb_randtest_special(y, state, 200, 10); arb_randtest_special(z, state, 200, 10); prec = 2 + n_randint(state, 200); arb_union(z, x, y, prec); if (!arb_contains(z, x) || !arb_contains(z, y)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } if (n_randint(state, 2)) { arb_union(x, x, y, prec); alias = arb_equal(x, z); } else { arb_union(y, x, y, prec); alias = arb_equal(y, z); } if (!alias) { flint_printf("FAIL (aliasing):\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("z = "); arb_print(z); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-urandom.c000066400000000000000000000035401417376376500161640ustar00rootroot00000000000000/* Copyright (C) 2021 Albin Ahlbäck This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define N 10000 int main() { slong iter; slong prec; flint_rand_t state; arb_ptr rand; arb_t m; /* mean */ arb_t s; /* variance */ arb_t mp; arb_t sp; arb_t tmp; flint_printf("urandom...."); fflush(stdout); flint_randinit(state); arb_init(m); arb_init(s); arb_init(mp); arb_init(sp); arb_init(tmp); rand = _arb_vec_init(N); prec = 299; for (iter = 0; iter < N; iter++) { arb_urandom(rand + iter, state, prec); arb_add(m, m, rand + iter, prec); } arb_div_si(m, m, N, prec); for (iter = 0; iter < N; iter++) { arb_sub(tmp, rand + iter, m, prec); arb_sqr(tmp, tmp, prec); arb_add(s, s, tmp, prec); } arb_div_si(s, s, N, prec); /* one percent deviation */ arb_set_str(mp, "0.5 +/- 0.005", prec); arb_set_str(sp, "0.083333 +/- 0.00083", prec); if (!arb_contains(mp, m)) { flint_printf("FAIL: mean\n\n"); flint_printf("m = "); arb_printd(m, 15); flint_printf("\n\n"); flint_abort(); } if (!arb_contains(sp, s)) { flint_printf("FAIL: variance\n\n"); flint_printf("s = "); arb_printd(s, 15); flint_printf("\n\n"); flint_abort(); } _arb_vec_clear(rand, N); arb_clear(m); arb_clear(s); arb_clear(mp); arb_clear(sp); arb_clear(tmp); flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta.c000066400000000000000000000026441417376376500154660ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 500); prec2 = prec1 + 30; arb_init(a); arb_init(b); arb_init(c); arb_randtest_precise(a, state, 1 + n_randint(state, 500), 5); arb_zeta(b, a, prec1); arb_zeta(c, a, prec2); if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta_ui.c000066400000000000000000000034161417376376500161610ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t r; ulong n; mpfr_t s; slong prec, accuracy; prec = 2 + n_randint(state, 1 << n_randint(state, 14)); arb_init(r); mpfr_init2(s, prec + 100); do { n = n_randint(state, 1 << n_randint(state, 10)); } while (n == 1); arb_zeta_ui(r, n, prec); mpfr_zeta_ui(s, n, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); mpfr_printf("%.275Rf\n", s); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec); flint_printf("n = %wu\n\n", n); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta_ui_asymp.c000066400000000000000000000026541417376376500173750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_ui_asymp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t r; ulong n; mpfr_t s; slong prec; prec = 2 + n_randint(state, 1 << n_randint(state, 10)); arb_init(r); mpfr_init2(s, prec + 100); n = 2 + n_randint(state, 1 << n_randint(state, 10)); arb_zeta_ui_asymp(r, n, prec); mpfr_zeta_ui(s, n, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); mpfr_printf("%.275Rf\n", s); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta_ui_bernoulli.c000066400000000000000000000034121417376376500202300ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_ui_bernoulli...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t r; ulong n; mpfr_t s; slong prec, accuracy; prec = 2 + n_randint(state, 1 << n_randint(state, 14)); arb_init(r); mpfr_init2(s, prec + 100); do { n = n_randint(state, 1 << n_randint(state, 10)); } while (n % 2 || n == 0); arb_zeta_ui_bernoulli(r, n, prec); mpfr_zeta_ui(s, n, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); mpfr_printf("%.275Rf\n", s); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta_ui_borwein_bsplit.c000066400000000000000000000033771417376376500212710ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_ui_borwein_bsplit...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t r; ulong n; mpfr_t s; slong prec, accuracy; prec = 2 + n_randint(state, 1 << n_randint(state, 14)); arb_init(r); mpfr_init2(s, prec + 100); do { n = n_randint(state, 1 << n_randint(state, 10)); } while (n == 1); arb_zeta_ui_borwein_bsplit(r, n, prec); mpfr_zeta_ui(s, n, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); mpfr_printf("%.275Rf\n", s); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta_ui_euler_product.c000066400000000000000000000034461417376376500211200ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_ui_euler_product...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t r; ulong n; mpfr_t s; slong prec, accuracy; do { n = n_randint(state, 1 << n_randint(state, 10)); } while (n < 6); prec = 2 + n_randint(state, n * FLINT_BIT_COUNT(n)); arb_init(r); mpfr_init2(s, prec + 100); arb_zeta_ui_euler_product(r, n, prec); mpfr_zeta_ui(s, n, MPFR_RNDN); if (!arb_contains_mpfr(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); mpfr_printf("%.275Rf\n", s); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec); flint_printf("n = %wu\n\n", n); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } arb_clear(r); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta_ui_vec.c000066400000000000000000000040041417376376500170100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_ui_vec...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_ptr r; ulong n; slong i, num; mpfr_t s; slong prec, accuracy; prec = 2 + n_randint(state, 1 << n_randint(state, 13)); num = 1 + n_randint(state, 20); r = _arb_vec_init(num); mpfr_init2(s, prec + 100); do { n = n_randint(state, 1 << n_randint(state, 10)); } while (n < 2); arb_zeta_ui_vec(r, n, num, prec); for (i = 0; i < num; i++) { mpfr_zeta_ui(s, n + i, MPFR_RNDN); if (!arb_contains_mpfr(r + i, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n\n", n + i); flint_printf("r = "); arb_printd(r + i, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); mpfr_printf("%.275Rf\n", s); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r + i); if (accuracy < prec - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec); flint_printf("n = %wu\n\n", n + i); flint_printf("r = "); arb_printd(r + i, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } _arb_vec_clear(r, num); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test/t-zeta_ui_vec_borwein.c000066400000000000000000000041351417376376500205420ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_ui_vec_borwein...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_ptr r; ulong n; slong i, num, step; mpfr_t s; slong prec, accuracy; prec = 2 + n_randint(state, 1 << n_randint(state, 13)); num = 1 + n_randint(state, 20); step = 1 + n_randint(state, 5); r = _arb_vec_init(num); mpfr_init2(s, prec + 100); do { n = n_randint(state, 1 << n_randint(state, 10)); } while (n < 2); arb_zeta_ui_vec_borwein(r, n, num, step, prec); for (i = 0; i < num; i++) { mpfr_zeta_ui(s, n + i * step, MPFR_RNDN); if (!arb_contains_mpfr(r + i, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("n = %wu\n\n", n + i * step); flint_printf("r = "); arb_printd(r + i, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); mpfr_printf("%.275Rf\n", s); flint_printf("\n\n"); flint_abort(); } accuracy = arb_rel_accuracy_bits(r + i); if (accuracy < prec - 4) { flint_printf("FAIL: accuracy = %wd, prec = %wd\n\n", accuracy, prec); flint_printf("n = %wu\n\n", n + i * step); flint_printf("r = "); arb_printd(r + i, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } _arb_vec_clear(r, num); mpfr_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb/test_multiplier.c000066400000000000000000000016351417376376500165270ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" double _arb_test_multiplier = -1.0; double arb_test_multiplier() { if (_arb_test_multiplier == -1.0) { const char * s = getenv("ARB_TEST_MULTIPLIER"); if (s == NULL) { _arb_test_multiplier = 1.0; } else { _arb_test_multiplier = strtod(s, NULL); if (!(_arb_test_multiplier >= 0.0 && _arb_test_multiplier <= 1000.0)) _arb_test_multiplier = 1.0; } } return _arb_test_multiplier; } arb-2.22.1/arb/trim.c000066400000000000000000000025001417376376500142450ustar00rootroot00000000000000/* Copyright (C) 2013-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #define TRIM_PADDING 16 void arb_trim(arb_t y, const arb_t x) { if (mag_is_zero(arb_radref(x)) || arf_is_special(arb_midref(x))) { arb_set(y, x); } else if (mag_is_special(arb_radref(x))) { /* midpoint must be finite, so set to 0 +/- inf */ arb_zero_pm_inf(y); } else { slong bits, accuracy; bits = arb_bits(x); accuracy = arb_rel_accuracy_bits(x); if (accuracy < -TRIM_PADDING) { mag_t t; /* set to 0 +/- r */ mag_init(t); arf_get_mag(t, arb_midref(x)); mag_add(arb_radref(y), t, arb_radref(x)); mag_clear(t); arf_zero(arb_midref(y)); } else if (accuracy < bits - TRIM_PADDING) { arb_set_round(y, x, FLINT_MAX(0, accuracy) + TRIM_PADDING); } else { arb_set(y, x); } } } arb-2.22.1/arb/ui_pow_ui.c000066400000000000000000000233471417376376500153050ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_si_pow_ui(arb_t res, slong b, ulong e, slong prec) { arb_ui_pow_ui(res, UI_ABS_SI(b), e, prec); if ((e & 1) && b < 0) arb_neg(res, res); } void arb_set_round_ui(arb_t res, ulong lo, slong prec) { if (lo == 0) { arb_zero(res); } else { int inexact; inexact = _arf_set_round_ui(arb_midref(res), lo, 0, prec, ARB_RND); if (inexact) arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec); else mag_zero(arb_radref(res)); } } void arb_set_round_uiui(arb_t res, ulong hi, ulong lo, slong prec) { if (hi == 0 && lo == 0) { arb_zero(res); } else { int inexact; slong fix; inexact = _arf_set_round_uiui(arb_midref(res), &fix, hi, lo, 0, prec, ARB_RND); _fmpz_demote(ARF_EXPREF(arb_midref(res))); ARF_EXP(arb_midref(res)) = 2 * FLINT_BITS + fix; if (inexact) arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec); else mag_zero(arb_radref(res)); } } void arb_ui_pow_ui(arb_t res, ulong a, ulong exp, slong prec) { slong wp, aexp, awidth, trailing, wp_limbs; slong exp_fix, alloc, leading; int inexact, i, ebits; mp_ptr yman, tmp; mp_size_t yn; mp_limb_t yexp_hi, yexp_lo, aman, aodd, hi, lo; ARF_MUL_TMP_DECL if (exp <= 2) { if (exp == 0) { arb_one(res); } else if (exp == 1) { arb_set_round_ui(res, a, prec); } else { mp_limb_t hi, lo; umul_ppmm(hi, lo, a, a); arb_set_round_uiui(res, hi, lo, prec); } return; } if (a <= 1) { arb_set_ui(res, a); return; } aexp = FLINT_BIT_COUNT(a); count_trailing_zeros(trailing, a); awidth = aexp - trailing; /* a = power of two */ if (awidth == 1) { fmpz_t t; fmpz_init(t); fmpz_set_ui(t, exp); fmpz_mul_ui(t, t, aexp - 1); arb_one(res); arb_mul_2exp_fmpz(res, res, t); fmpz_clear(t); return; } umul_ppmm(hi, lo, awidth, exp); if (hi == 0) prec = FLINT_MIN(prec, lo); wp = prec + 2 * FLINT_BIT_COUNT(exp) + 4; wp_limbs = (wp + FLINT_BITS - 1) / FLINT_BITS; if (FLINT_BITS == 32 && wp_limbs % 2) wp_limbs++; /* Algorithm: as long as the result is exact, work with powers of the odd part of a as an integer. As soon as we exceed wp_limbs, switch to a floating-point product with exactly wp_limbs (it is possible that we get trailing zero limbs after this point so that the number of limbs could be reduced temporarily, but this is not worth the trouble). */ alloc = 4 * (wp_limbs + 2); ARF_MUL_TMP_ALLOC(tmp, alloc) yman = tmp + 2 * (wp_limbs + 2); /* a as a top-aligned mantissa */ aman = a << (FLINT_BITS - aexp); /* a as a bottom-aligned mantissa */ aodd = a >> trailing; /* y = a */ yn = 1; yman[0] = aodd; /* yexp will initially be the bottom exponent. we convert to a floating-point (top) exponent only when the result becomes inexact */ yexp_lo = trailing; /* the exponent can be two words wide (we only need this in the inexact case) */ yexp_hi = 0; inexact = 0; ebits = FLINT_BIT_COUNT(exp); for (i = ebits - 2; i >= 0; i--) { /* Integer case */ if (!inexact) { /* Inline code for small integers */ if (yn == 1) { yexp_lo *= 2; umul_ppmm(yman[1], yman[0], yman[0], yman[0]); yn += (yman[1] != 0); if (exp & (UWORD(1) << i)) { yexp_lo += trailing; if (yn == 1) { umul_ppmm(yman[1], yman[0], yman[0], aodd); yn += (yman[1] != 0); } else { mp_limb_t y0, y1; y0 = yman[0]; y1 = yman[1]; nn_mul_2x1(yman[2], yman[1], yman[0], y1, y0, aodd); yn += (yman[2] != 0); } } } else { /* todo: if 2 * yn is significantly larger than wp_limbs, we might want to go to the floating-point code here */ yexp_lo *= 2; mpn_sqr(tmp, yman, yn); yn = 2 * yn; yn -= (tmp[yn - 1] == 0); if (exp & (UWORD(1) << i)) { yexp_lo += trailing; yman[yn] = mpn_mul_1(yman, tmp, yn, aodd); yn += (yman[yn] != 0); } else { flint_mpn_copyi(yman, tmp, yn); } } /* convert to floating-point form */ /* todo: redundant if this is the last iteration */ if (yn > wp_limbs) { inexact = 1; count_leading_zeros(leading, yman[yn - 1]); yexp_lo = yexp_lo + yn * FLINT_BITS - leading; if (leading == 0) flint_mpn_copyi(yman, yman + yn - wp_limbs, wp_limbs); else mpn_rshift(yman, yman + yn - wp_limbs - 1, wp_limbs + 1, FLINT_BITS - leading); yn = wp_limbs; } continue; } /* y = y^2: exponent */ yexp_hi = (yexp_hi << 1) | (yexp_lo >> (FLINT_BITS - 1)); yexp_lo <<= 1; /* special case for 1-limb precision */ /* note: we must have yn == 1 here if wp_limbs == 1 */ if (wp_limbs == 1) { mp_limb_t hi, lo; /* y = y^2: mantissa */ umul_ppmm(hi, lo, yman[0], yman[0]); if (!(hi >> (FLINT_BITS - 1))) { hi = (hi << 1) | (lo >> (FLINT_BITS - 1)); sub_ddmmss(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, 1); } yman[0] = hi; if (exp & (UWORD(1) << i)) { /* y = y * a: exponent */ add_ssaaaa(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, aexp); /* y = y * a: mantissa */ umul_ppmm(hi, lo, yman[0], aman); if (!(hi >> (FLINT_BITS - 1))) { hi = (hi << 1) | (lo >> (FLINT_BITS - 1)); sub_ddmmss(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, 1); } yman[0] = hi; } continue; } /* y = y^2: mantissa */ if (yn >= 25 && yn <= 10000) /* use mpfr for sqrhi */ { mpfr_t zf, xf; zf->_mpfr_d = tmp; zf->_mpfr_prec = wp_limbs * FLINT_BITS; zf->_mpfr_sign = 1; zf->_mpfr_exp = 0; xf->_mpfr_d = yman; xf->_mpfr_prec = yn * FLINT_BITS; xf->_mpfr_sign = 1; xf->_mpfr_exp = 0; mpfr_sqr(zf, xf, MPFR_RNDD); if (zf->_mpfr_exp != 0) sub_ddmmss(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, 1); yn = wp_limbs; } else /* or exactly */ { mpn_sqr(tmp, yman, yn); yn = 2 * yn; } if (yn < wp_limbs) flint_abort(); /* y = y * a */ if (exp & (UWORD(1) << i)) { tmp[yn] = mpn_mul_1(tmp + yn - wp_limbs, tmp + yn - wp_limbs, wp_limbs, aman); yn++; add_ssaaaa(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, aexp); } /* move result from tmp to yman, and normalize; at this point there can be 0, 1 or 2 leading zeros */ if (tmp[yn - 1] >> (FLINT_BITS - 1)) { flint_mpn_copyi(yman, tmp + yn - wp_limbs, wp_limbs); } else { /* assumed so that we can read one extra limb with mpn_rshift */ /* yn == wp_limbs is only possible if we used mpfr_sqr above and there was no multiplication by a, but in that case there are 0 leading zeros anyway */ if (yn == wp_limbs) flint_abort(); if (tmp[yn - 1] >> (FLINT_BITS - 2)) { mpn_rshift(yman, tmp + yn - wp_limbs - 1, wp_limbs + 1, FLINT_BITS - 1); sub_ddmmss(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, 1); } else { mpn_rshift(yman, tmp + yn - wp_limbs - 1, wp_limbs + 1, FLINT_BITS - 2); sub_ddmmss(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, 2); } } yn = wp_limbs; } /* convert bottom exponent to floating-point (top) exponent */ if (!inexact) yexp_lo = yexp_lo + yn * FLINT_BITS; inexact |= _arf_set_round_mpn(arb_midref(res), &exp_fix, yman, yn, 0, prec, ARF_RND_DOWN); if (exp_fix) sub_ddmmss(yexp_hi, yexp_lo, yexp_hi, yexp_lo, 0, -exp_fix); fmpz_set_uiui(ARF_EXPREF(arb_midref(res)), yexp_hi, yexp_lo); if (inexact) arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec - 1); else mag_zero(arb_radref(res)); ARF_MUL_TMP_FREE(tmp, alloc) } arb-2.22.1/arb/union.c000066400000000000000000000024311417376376500144250ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_union(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_t left, right, t, xr, yr; if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y))) { arb_indeterminate(z); return; } if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y))) { arb_zero_pm_inf(z); return; } arf_init(left); arf_init(right); arf_init(t); arf_init_set_mag_shallow(xr, arb_radref(x)); arf_init_set_mag_shallow(yr, arb_radref(y)); arf_sub(left, arb_midref(x), xr, prec, ARF_RND_FLOOR); arf_sub(t, arb_midref(y), yr, prec, ARF_RND_FLOOR); arf_min(left, left, t); arf_add(right, arb_midref(x), xr, prec, ARF_RND_CEIL); arf_add(t, arb_midref(y), yr, prec, ARF_RND_CEIL); arf_max(right, right, t); arb_set_interval_arf(z, left, right, prec); arf_clear(left); arf_clear(right); arf_clear(t); } arb-2.22.1/arb/urandom.c000066400000000000000000000013701417376376500147430ustar00rootroot00000000000000/* Copyright (C) 2021 Albin Ahlbäck This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_urandom(arb_t x, flint_rand_t state, slong bits) { slong prec = bits; fmpz_t n; fmpz_t t; prec += 128; fmpz_init(n); fmpz_one(n); fmpz_mul_2exp(n, n, (ulong) prec); fmpz_init(t); fmpz_randm(t, state, n); arb_set_round_fmpz(x, t, bits); arb_mul_2exp_si(x, x, -prec); fmpz_clear(n); fmpz_clear(t); } arb-2.22.1/arb/vec_clear.c000066400000000000000000000010201417376376500152110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_vec_clear(arb_ptr v, slong n) { slong i; for (i = 0; i < n; i++) arb_clear(v + i); flint_free(v); } arb-2.22.1/arb/vec_get_mag.c000066400000000000000000000014121417376376500155330ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_vec_get_mag(mag_t bound, arb_srcptr vec, slong len) { if (len < 1) { mag_zero(bound); } else { mag_t t; slong i; arb_get_mag(bound, vec); mag_init(t); for (i = 1; i < len; i++) { arb_get_mag(t, vec + i); mag_max(bound, bound, t); } mag_clear(t); } } arb-2.22.1/arb/vec_init.c000066400000000000000000000011031417376376500150700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" arb_ptr _arb_vec_init(slong n) { slong i; arb_ptr v = (arb_ptr) flint_malloc(sizeof(arb_struct) * n); for (i = 0; i < n; i++) arb_init(v + i); return v; } arb-2.22.1/arb/vec_set_powers.c000066400000000000000000000014421417376376500163250ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void _arb_vec_set_powers(arb_ptr xs, const arb_t x, slong len, slong prec) { slong i; for (i = 0; i < len; i++) { if (i == 0) arb_one(xs + i); else if (i == 1) arb_set_round(xs + i, x, prec); else if (i % 2 == 0) arb_mul(xs + i, xs + i / 2, xs + i / 2, prec); else arb_mul(xs + i, xs + i - 1, x, prec); } } arb-2.22.1/arb/version.c000066400000000000000000000006631417376376500147670ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" const char * arb_version = "2.22.1"; arb-2.22.1/arb/zero.c000066400000000000000000000007431417376376500142600ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_zero(arb_t x) { arf_zero(arb_midref(x)); mag_zero(arb_radref(x)); } arb-2.22.1/arb/zeta.c000066400000000000000000000011271417376376500142410ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "acb.h" void arb_zeta(arb_t y, const arb_t s, slong prec) { acb_t t; acb_init(t); acb_set_arb(t, s), acb_zeta(t, t, prec); arb_set(y, acb_realref(t)); acb_clear(t); } arb-2.22.1/arb/zeta_ui.c000066400000000000000000000040501417376376500147340ustar00rootroot00000000000000/* Copyright (C) 2012, 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "flint/arith.h" #include "arb.h" /* The constant factor is nearly optimal up to at least 300000 bits. */ static double euler_product_cutoff(double prec) { if (prec > 200 && prec < 15000) /* This range has a slight "bulge". */ return 0.39 * pow(prec, 0.8); else return 7 + 0.535 * prec / log(prec); } void arb_zeta_ui(arb_t x, ulong n, slong prec) { if (n == 0) { arb_set_si(x, -1); arb_mul_2exp_si(x, x, -1); } else if (n == 1) { arb_indeterminate(x); } /* fast detection of asymptotic case */ else if (n > 0.7 * prec) { arb_zeta_ui_asymp(x, n, prec); } else { /* even */ if (n % 2 == 0) { if (((prec < 10000) && (n < 40 + 0.11*prec)) || ((prec >= 10000) && (arith_bernoulli_number_size(n) * 0.9 < prec))) { arb_zeta_ui_bernoulli(x, n, prec); } else { arb_zeta_ui_euler_product(x, n, prec); } } else { if (n == 3) { arb_const_apery(x, prec); } else if (n < prec * 0.0006) { /* small odd n, extremely high precision */ arb_zeta_ui_borwein_bsplit(x, n, prec); } else if (n > euler_product_cutoff(prec)) { /* large n */ arb_zeta_ui_euler_product(x, n, prec); } else { /* fallback */ arb_zeta_ui_vec_borwein(x, n, 1, 0, prec); } } } } arb-2.22.1/arb/zeta_ui_bernoulli.c000066400000000000000000000017351417376376500170160ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "bernoulli.h" void arb_zeta_ui_bernoulli(arb_t x, ulong n, slong prec) { fmpq_t b; arb_t t, f; slong wp; if (n % 2) flint_abort(); wp = prec + FLINT_BIT_COUNT(n) + 2; fmpq_init(b); arb_init(t); arb_init(f); bernoulli_fmpq_ui(b, n); arb_set_fmpq(x, b, wp); arb_const_pi(t, wp); arb_mul_2exp_si(t, t, 1); arb_pow_ui(t, t, n, wp); arb_fac_ui(f, n, wp); arb_div(t, t, f, wp); arb_mul(x, x, t, wp); arb_abs(x, x); arb_mul_2exp_si(x, x, -1); arb_clear(t); arb_clear(f); fmpq_clear(b); } arb-2.22.1/arb/zeta_ui_borwein_bsplit.c000066400000000000000000000076711417376376500200520ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* With parameter n, the error is bounded by 3/(3+sqrt(8))^n */ #define ERROR_A 1.5849625007211561815 /* log2(3) */ #define ERROR_B 2.5431066063272239453 /* log2(3+sqrt(8)) */ typedef struct { arb_t A; arb_t B; arb_t C; arb_t D; arb_t Q1; arb_t Q2; arb_t Q3; } zeta_bsplit_state; typedef zeta_bsplit_state zeta_bsplit_t[1]; static __inline__ void zeta_bsplit_init(zeta_bsplit_t S) { arb_init(S->A); arb_init(S->B); arb_init(S->C); arb_init(S->D); arb_init(S->Q1); arb_init(S->Q2); arb_init(S->Q3); } static __inline__ void zeta_bsplit_clear(zeta_bsplit_t S) { arb_clear(S->A); arb_clear(S->B); arb_clear(S->C); arb_clear(S->D); arb_clear(S->Q1); arb_clear(S->Q2); arb_clear(S->Q3); } static __inline__ void zeta_coeff_k(zeta_bsplit_t S, slong k, slong n, slong s) { arb_set_si(S->D, 2 * (n + k)); arb_mul_si(S->D, S->D, n - k, ARF_PREC_EXACT); arb_set_si(S->Q1, k + 1); arb_mul_si(S->Q1, S->Q1, 2*k + 1, ARF_PREC_EXACT); if (k == 0) { arb_zero(S->A); arb_one(S->Q2); } else { arb_set_si(S->A, k % 2 ? 1 : -1); arb_mul(S->A, S->A, S->Q1, ARF_PREC_EXACT); arb_ui_pow_ui(S->Q2, k, s, ARF_PREC_EXACT); } arb_mul(S->Q3, S->Q1, S->Q2, ARF_PREC_EXACT); arb_zero(S->B); arb_set(S->C, S->Q1); } static void zeta_bsplit(zeta_bsplit_t L, slong a, slong b, slong n, slong s, int cont, slong bits) { if (a + 1 == b) { zeta_coeff_k(L, a, n, s); } else { zeta_bsplit_t R; slong m = (a + b) / 2; zeta_bsplit(L, m, b, n, s, 1, bits); zeta_bsplit_init(R); zeta_bsplit(R, a, m, n, s, 1, bits); arb_mul(L->B, L->B, R->D, bits); arb_addmul(L->B, L->A, R->C, bits); arb_mul(L->B, L->B, R->Q2, bits); arb_addmul(L->B, R->B, L->Q3, bits); arb_mul(L->A, L->A, R->Q3, bits); arb_addmul(L->A, R->A, L->Q3, bits); arb_mul(L->C, L->C, R->D, bits); arb_addmul(L->C, R->C, L->Q1, bits); if (cont) { arb_mul(L->D, L->D, R->D, bits); arb_mul(L->Q2, L->Q2, R->Q2, bits); } arb_mul(L->Q1, L->Q1, R->Q1, bits); arb_mul(L->Q3, L->Q3, R->Q3, bits); zeta_bsplit_clear(R); } } /* The error for eta(s) is bounded by 3/(3+sqrt(8))^n */ void mag_borwein_error(mag_t err, slong n) { /* upper bound for 1/(3+sqrt(8)) */ mag_set_ui_2exp_si(err, 736899889, -32); mag_pow_ui(err, err, n); mag_mul_ui(err, err, 3); } void arb_zeta_ui_borwein_bsplit(arb_t x, ulong s, slong prec) { zeta_bsplit_t sum; mag_t err; slong wp, n; /* zeta(0) = -1/2 */ if (s == 0) { arb_set_si(x, -1); arb_mul_2exp_si(x, x, -1); return; } if (s == 1) { flint_printf("zeta_ui_borwein_bsplit: zeta(1)"); flint_abort(); } n = prec / ERROR_B + 2; wp = prec + 30; zeta_bsplit_init(sum); zeta_bsplit(sum, 0, n + 1, n, s, 0, wp); /* A/Q3 - B/Q3 / (C/Q1) = (A*C - B*Q1) / (Q3*C) */ arb_mul(sum->A, sum->A, sum->C, wp); arb_mul(sum->B, sum->B, sum->Q1, wp); arb_sub(sum->A, sum->A, sum->B, wp); arb_mul(sum->Q3, sum->Q3, sum->C, wp); arb_div(sum->C, sum->A, sum->Q3, wp); mag_init(err); mag_borwein_error(err, n); mag_add(arb_radref(sum->C), arb_radref(sum->C), err); mag_clear(err); /* convert from eta(s) to zeta(s) */ arb_div_2expm1_ui(x, sum->C, s - 1, wp); arb_mul_2exp_si(x, x, s - 1); zeta_bsplit_clear(sum); } arb-2.22.1/arb/zeta_ui_euler_product.c000066400000000000000000000016321417376376500176730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" #include "acb_dirichlet.h" void arb_zeta_inv_ui_euler_product(arb_t z, ulong s, slong prec) { const signed char chi[1] = {1}; _acb_dirichlet_euler_product_real_ui(z, s, chi, 1, 1, prec); } void arb_zeta_ui_euler_product(arb_t z, ulong s, slong prec) { const signed char chi[1] = {1}; _acb_dirichlet_euler_product_real_ui(z, s, chi, 1, 0, prec); } void arb_zeta_ui_asymp(arb_t z, ulong s, slong prec) { const signed char chi[1] = {1}; _acb_dirichlet_euler_product_real_ui(z, s, chi, 1, 0, prec); } arb-2.22.1/arb/zeta_ui_vec.c000066400000000000000000000021611417376376500155720ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_zeta_ui_vec(arb_ptr x, ulong start, slong num, slong prec) { slong i, num_odd, num_even, start_odd; arb_ptr tmp; num_odd = num / 2 + (start & num & 1); num_even = num - num_odd; start_odd = start % 2; arb_zeta_ui_vec_even(x, start + start_odd, num_even, prec); arb_zeta_ui_vec_odd(x + num_even, start + !start_odd, num_odd, prec); /* interleave */ tmp = flint_malloc(sizeof(arb_struct) * num); for (i = 0; i < num_even; i++) tmp[i] = x[i]; for (i = 0; i < num_odd; i++) tmp[num_even + i] = x[num_even + i]; for (i = 0; i < num_even; i++) x[start_odd + 2 * i] = tmp[i]; for (i = 0; i < num_odd; i++) x[!start_odd + 2 * i] = tmp[num_even + i]; flint_free(tmp); } arb-2.22.1/arb/zeta_ui_vec_borwein.c000066400000000000000000000045401417376376500173220ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" /* With parameter n, the error is bounded by 3/(3+sqrt(8))^n */ #define ERROR_A 1.5849625007211561815 /* log2(3) */ #define ERROR_B 2.5431066063272239453 /* log2(3+sqrt(8)) */ void mag_borwein_error(mag_t err, slong n); void arb_zeta_ui_vec_borwein(arb_ptr z, ulong start, slong num, ulong step, slong prec) { slong j, k, s, n, wp; fmpz_t c, d, t, u; fmpz * zeta; mag_t err; if (num < 1) return; wp = prec + FLINT_BIT_COUNT(prec); n = wp / 2.5431066063272239453 + 1; fmpz_init(c); fmpz_init(d); fmpz_init(t); fmpz_init(u); zeta = _fmpz_vec_init(num); fmpz_set_ui(c, 1); fmpz_mul_2exp(c, c, 2 * n - 1); fmpz_set(d, c); for (k = n; k > 0; k--) { /* divide by first k^s */ fmpz_ui_pow_ui(u, k, start); fmpz_tdiv_q(t, d, u); if (k % 2 == 0) fmpz_neg(t, t); fmpz_add(zeta, zeta, t); /* remaining k^s */ fmpz_ui_pow_ui(u, k, step); for (j = 1; j < num; j++) { fmpz_tdiv_q(t, t, u); fmpz_add(zeta + j, zeta + j, t); } /* hypergeometric recurrence */ fmpz_mul2_uiui(c, c, k, 2 * k - 1); fmpz_divexact2_uiui(c, c, 2 * (n - k + 1), n + k - 1); fmpz_add(d, d, c); } mag_init(err); mag_borwein_error(err, n); for (k = 0; k < num; k++) { arb_ptr x = z + k; s = start + step * k; arb_set_fmpz(x, zeta + k); /* the error in each term in the main loop is < 2 */ mag_set_ui(arb_radref(x), 2 * n); arb_div_fmpz(x, x, d, wp); /* mathematical error for eta(s), bounded by 3/(3+sqrt(8))^n */ mag_add(arb_radref(x), arb_radref(x), err); /* convert from eta(s) to zeta(s) */ arb_div_2expm1_ui(x, x, s - 1, wp); arb_mul_2exp_si(x, x, s - 1); } mag_clear(err); fmpz_clear(c); fmpz_clear(d); fmpz_clear(t); fmpz_clear(u); _fmpz_vec_clear(zeta, num); } arb-2.22.1/arb/zeta_ui_vec_even.c000066400000000000000000000010771417376376500166140ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_zeta_ui_vec_even(arb_ptr x, ulong start, slong num, slong prec) { slong i; for (i = 0; i < num; i++) arb_zeta_ui(x + i, start + 2 * i, prec); } arb-2.22.1/arb/zeta_ui_vec_odd.c000066400000000000000000000015551417376376500164260ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb.h" void arb_zeta_ui_vec_odd(arb_ptr x, ulong start, slong num, slong prec) { slong i, num_borwein; ulong cutoff; cutoff = 40 + 0.3 * prec; if (cutoff > start) { num_borwein = 1 + (cutoff - start) / 2; num_borwein = FLINT_MIN(num_borwein, num); } else num_borwein = 0; arb_zeta_ui_vec_borwein(x, start, num_borwein, 2, prec); for (i = num_borwein; i < num; i++) arb_zeta_ui(x + i, start + 2 * i, prec); } arb-2.22.1/arb_calc.h000066400000000000000000000067031417376376500142720ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARB_CALC_H #define ARB_CALC_H #include #include "arb.h" #include "arb_poly.h" #include "arb_mat.h" #ifdef __cplusplus extern "C" { #endif extern TLS_PREFIX int arb_calc_verbose; typedef int (*arb_calc_func_t)(arb_ptr out, const arb_t inp, void * param, slong order, slong prec); #define ARB_CALC_SUCCESS 0 #define ARB_CALC_IMPRECISE_INPUT 1 #define ARB_CALC_NO_CONVERGENCE 2 /* Root-finding */ typedef struct { arf_struct a; arf_struct b; } arf_interval_struct; typedef arf_interval_struct arf_interval_t[1]; typedef arf_interval_struct * arf_interval_ptr; typedef const arf_interval_struct * arf_interval_srcptr; static __inline__ void arf_interval_init(arf_interval_t v) { arf_init(&v->a); arf_init(&v->b); } static __inline__ void arf_interval_clear(arf_interval_t v) { arf_clear(&v->a); arf_clear(&v->b); } static __inline__ arf_interval_ptr _arf_interval_vec_init(slong n) { slong i; arf_interval_ptr v = (arf_interval_ptr) flint_malloc(sizeof(arf_interval_struct) * n); for (i = 0; i < n; i++) arf_interval_init(v + i); return v; } static __inline__ void _arf_interval_vec_clear(arf_interval_ptr v, slong n) { slong i; for (i = 0; i < n; i++) arf_interval_clear(v + i); flint_free(v); } static __inline__ void arf_interval_set(arf_interval_t v, const arf_interval_t u) { arf_set(&v->a, &u->a); arf_set(&v->b, &u->b); } static __inline__ void arf_interval_swap(arf_interval_t v, arf_interval_t u) { arf_swap(&v->a, &u->a); arf_swap(&v->b, &u->b); } static __inline__ void arf_interval_get_arb(arb_t x, const arf_interval_t v, slong prec) { arb_set_interval_arf(x, &v->a, &v->b, prec); } static __inline__ void arf_interval_fprintd(FILE * file, const arf_interval_t v, slong n) { flint_fprintf(file, "["); arf_fprintd(file, &v->a, n); flint_fprintf(file, ", "); arf_fprintd(file, &v->b, n); flint_fprintf(file, "]"); } static __inline__ void arf_interval_printd(const arf_interval_t v, slong n) { arf_interval_fprintd(stdout, v, n); } /* bisection */ int arb_calc_partition(arf_interval_t L, arf_interval_t R, arb_calc_func_t func, void * param, const arf_interval_t block, slong prec); slong arb_calc_isolate_roots(arf_interval_ptr * blocks, int ** flags, arb_calc_func_t func, void * param, const arf_interval_t block, slong maxdepth, slong maxeval, slong maxfound, slong prec); int arb_calc_refine_root_bisect(arf_interval_t r, arb_calc_func_t func, void * param, const arf_interval_t start, slong iter, slong prec); /* newton iteration */ void arb_calc_newton_conv_factor(arf_t conv_factor, arb_calc_func_t func, void * param, const arb_t conv_region, slong prec); int arb_calc_newton_step(arb_t xnew, arb_calc_func_t func, void * param, const arb_t x, const arb_t conv_region, const arf_t conv_factor, slong prec); int arb_calc_refine_root_newton(arb_t r, arb_calc_func_t func, void * param, const arb_t start, const arb_t conv_region, const arf_t conv_factor, slong eval_extra_prec, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/arb_calc/000077500000000000000000000000001417376376500141135ustar00rootroot00000000000000arb-2.22.1/arb_calc/isolate_roots.c000066400000000000000000000112651417376376500171520ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_calc.h" #define BLOCK_NO_ZERO 0 #define BLOCK_ISOLATED_ZERO 1 #define BLOCK_UNKNOWN 2 static int check_block(arb_calc_func_t func, void * param, const arf_interval_t block, int asign, int bsign, slong prec) { arb_struct t[2]; arb_t x; int result; arb_init(t + 0); arb_init(t + 1); arb_init(x); arf_interval_get_arb(x, block, prec); func(t, x, param, 1, prec); result = BLOCK_UNKNOWN; if (arb_is_positive(t) || arb_is_negative(t)) { result = BLOCK_NO_ZERO; } else { if ((asign < 0 && bsign > 0) || (asign > 0 && bsign < 0)) { func(t, x, param, 2, prec); if (arb_is_finite(t + 1) && !arb_contains_zero(t + 1)) { result = BLOCK_ISOLATED_ZERO; } } } arb_clear(t + 0); arb_clear(t + 1); arb_clear(x); return result; } #define ADD_BLOCK \ if (*length >= *alloc) \ { \ slong new_alloc; \ new_alloc = (*alloc == 0) ? 1 : 2 * (*alloc); \ *blocks = flint_realloc(*blocks, sizeof(arf_interval_struct) * new_alloc); \ *flags = flint_realloc(*flags, sizeof(int) * new_alloc); \ *alloc = new_alloc; \ } \ arf_interval_init((*blocks) + *length); \ arf_interval_set((*blocks) + *length, block); \ (*flags)[*length] = status; \ (*length)++; \ static void isolate_roots_recursive(arf_interval_ptr * blocks, int ** flags, slong * length, slong * alloc, arb_calc_func_t func, void * param, const arf_interval_t block, int asign, int bsign, slong depth, slong * eval_count, slong * found_count, slong prec) { int status; if (*found_count <= 0 || *eval_count <= 0) { status = BLOCK_UNKNOWN; ADD_BLOCK } else { *eval_count -= 1; status = check_block(func, param, block, asign, bsign, prec); if (status != BLOCK_NO_ZERO) { if (status == BLOCK_ISOLATED_ZERO || depth <= 0) { if (status == BLOCK_ISOLATED_ZERO) { if (arb_calc_verbose) { flint_printf("found isolated root in: "); arf_interval_printd(block, 15); flint_printf("\n"); } *found_count -= 1; } ADD_BLOCK } else { arf_interval_t L, R; int msign; arf_interval_init(L); arf_interval_init(R); msign = arb_calc_partition(L, R, func, param, block, prec); if (msign == 0 && arb_calc_verbose) { flint_printf("possible zero at midpoint: "); arf_interval_printd(block, 15); flint_printf("\n"); } isolate_roots_recursive(blocks, flags, length, alloc, func, param, L, asign, msign, depth - 1, eval_count, found_count, prec); isolate_roots_recursive(blocks, flags, length, alloc, func, param, R, msign, bsign, depth - 1, eval_count, found_count, prec); arf_interval_clear(L); arf_interval_clear(R); } } } } slong arb_calc_isolate_roots(arf_interval_ptr * blocks, int ** flags, arb_calc_func_t func, void * param, const arf_interval_t block, slong maxdepth, slong maxeval, slong maxfound, slong prec) { int asign, bsign; slong length, alloc; arb_t m, v; *blocks = NULL; *flags = NULL; length = 0; alloc = 0; arb_init(m); arb_init(v); arb_set_arf(m, &block->a); func(v, m, param, 1, prec); asign = arb_sgn_nonzero(v); arb_set_arf(m, &block->b); func(v, m, param, 1, prec); bsign = arb_sgn_nonzero(v); arb_clear(m); arb_clear(v); isolate_roots_recursive(blocks, flags, &length, &alloc, func, param, block, asign, bsign, maxdepth, &maxeval, &maxfound, prec); *blocks = flint_realloc(*blocks, length * sizeof(arf_interval_struct)); *flags = flint_realloc(*flags, length * sizeof(int)); return length; } arb-2.22.1/arb_calc/newton_conv_factor.c000066400000000000000000000015171417376376500201600ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_calc.h" void arb_calc_newton_conv_factor(arf_t conv_factor, arb_calc_func_t func, void * param, const arb_t conv_region, slong prec) { arb_struct t[3]; arb_init(t); arb_init(t + 1); arb_init(t + 2); func(t, conv_region, param, 3, prec); arb_div(t, t + 2, t + 1, prec); arb_mul_2exp_si(t, t, -1); arb_get_abs_ubound_arf(conv_factor, t, prec); arb_clear(t); arb_clear(t + 1); arb_clear(t + 2); } arb-2.22.1/arb_calc/newton_step.c000066400000000000000000000026241417376376500166300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_calc.h" int arb_calc_newton_step(arb_t xnew, arb_calc_func_t func, void * param, const arb_t x, const arb_t conv_region, const arf_t conv_factor, slong prec) { mag_t err, v; arb_t t; arb_struct u[2]; int result; mag_init(err); mag_init(v); arb_init(t); arb_init(u + 0); arb_init(u + 1); mag_mul(err, arb_radref(x), arb_radref(x)); arf_get_mag(v, conv_factor); mag_mul(err, err, v); arf_set(arb_midref(t), arb_midref(x)); mag_zero(arb_radref(t)); func(u, t, param, 2, prec); arb_div(u, u, u + 1, prec); arb_sub(u, t, u, prec); mag_add(arb_radref(u), arb_radref(u), err); if (arb_contains(conv_region, u) && (mag_cmp(arb_radref(u), arb_radref(x)) < 0)) { arb_swap(xnew, u); result = ARB_CALC_SUCCESS; } else { arb_set(xnew, x); result = ARB_CALC_NO_CONVERGENCE; } arb_clear(t); arb_clear(u); arb_clear(u + 1); mag_clear(err); mag_clear(v); return result; } arb-2.22.1/arb_calc/refine_root_bisect.c000066400000000000000000000050441417376376500201260ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_calc.h" /* TODO: refactor/combine some of this code with isolate_roots.c */ int arb_calc_partition(arf_interval_t L, arf_interval_t R, arb_calc_func_t func, void * param, const arf_interval_t block, slong prec) { arb_t t, m; arf_t u; int msign; arb_init(t); arb_init(m); arf_init(u); /* Compute the midpoint (TODO: try other points) */ arf_add(u, &block->a, &block->b, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul_2exp_si(u, u, -1); /* Evaluate and get sign at midpoint */ arb_set_arf(m, u); func(t, m, param, 1, prec); msign = arb_sgn_nonzero(t); /* L, R = block, split at midpoint */ arf_set(&L->a, &block->a); arf_set(&R->b, &block->b); arf_set(&L->b, u); arf_set(&R->a, u); arb_clear(t); arb_clear(m); arf_clear(u); return msign; } int arb_calc_refine_root_bisect(arf_interval_t r, arb_calc_func_t func, void * param, const arf_interval_t start, slong iter, slong prec) { int asign, bsign, msign, result; slong i; arf_interval_t t, u; arb_t m, v; arf_interval_init(t); arf_interval_init(u); arb_init(m); arb_init(v); arb_set_arf(m, &start->a); func(v, m, param, 1, prec); asign = arb_sgn_nonzero(v); arb_set_arf(m, &start->b); func(v, m, param, 1, prec); bsign = arb_sgn_nonzero(v); /* must have proper sign changes */ if (asign == 0 || bsign == 0 || asign == bsign) { result = ARB_CALC_IMPRECISE_INPUT; } else { arf_interval_set(r, start); result = ARB_CALC_SUCCESS; for (i = 0; i < iter; i++) { msign = arb_calc_partition(t, u, func, param, r, prec); /* the algorithm fails if the value at the midpoint cannot be distinguished from zero */ if (msign == 0) { result = ARB_CALC_NO_CONVERGENCE; break; } if (msign == asign) arf_interval_swap(r, u); else arf_interval_swap(r, t); } } arf_interval_clear(t); arf_interval_clear(u); arb_clear(m); arb_clear(v); return result; } arb-2.22.1/arb_calc/refine_root_newton.c000066400000000000000000000033071417376376500201670ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_calc.h" int arb_calc_refine_root_newton(arb_t r, arb_calc_func_t func, void * param, const arb_t start, const arb_t conv_region, const arf_t conv_factor, slong eval_extra_prec, slong prec) { slong precs[FLINT_BITS]; slong i, iters, wp, padding, start_prec; int result; start_prec = arb_rel_accuracy_bits(start); if (arb_calc_verbose) flint_printf("newton initial accuracy: %wd\n", start_prec); padding = arf_abs_bound_lt_2exp_si(conv_factor); padding = FLINT_MIN(padding, prec) + 5; padding = FLINT_MAX(0, padding); precs[0] = prec + padding; iters = 1; while ((iters < FLINT_BITS) && (precs[iters-1] + padding > 2*start_prec)) { precs[iters] = (precs[iters-1] / 2) + padding; iters++; if (iters == FLINT_BITS) { return ARB_CALC_IMPRECISE_INPUT; } } arb_set(r, start); for (i = iters - 1; i >= 0; i--) { wp = precs[i] + eval_extra_prec; if (arb_calc_verbose) flint_printf("newton step: wp = %wd + %wd = %wd\n", precs[i], eval_extra_prec, wp); if ((result = arb_calc_newton_step(r, func, param, r, conv_region, conv_factor, wp)) != ARB_CALC_SUCCESS) { return result; } } return ARB_CALC_SUCCESS; } arb-2.22.1/arb_calc/test/000077500000000000000000000000001417376376500150725ustar00rootroot00000000000000arb-2.22.1/arb_calc/test/t-isolate_roots.c000066400000000000000000000077171417376376500204010ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_calc.h" /* sin((pi/2)x) */ static int sin_pi2_x(arb_ptr out, const arb_t inp, void * params, slong order, slong prec) { arb_ptr x; x = _arb_vec_init(2); arb_set(x, inp); arb_one(x + 1); arb_const_pi(out, prec); arb_mul_2exp_si(out, out, -1); _arb_vec_scalar_mul(x, x, 2, out, prec); _arb_poly_sin_series(out, x, order, order, prec); _arb_vec_clear(x, 2); return 0; } int main() { slong iter; flint_rand_t state; flint_printf("isolate_roots...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 40 * arb_test_multiplier(); iter++) { slong m, r, a, b, maxdepth, maxeval, maxfound, prec, i, j, num; arf_interval_ptr blocks; int * info; arf_interval_t interval; arb_t t; fmpz_t nn; prec = 2 + n_randint(state, 50); m = n_randint(state, 80); r = 1 + n_randint(state, 80); a = m - r; b = m + r; maxdepth = 1 + n_randint(state, 60); maxeval = 1 + n_randint(state, 5000); maxfound = 1 + n_randint(state, 100); arf_interval_init(interval); arb_init(t); fmpz_init(nn); arf_set_si(&interval->a, a); arf_set_si(&interval->b, b); num = arb_calc_isolate_roots(&blocks, &info, sin_pi2_x, NULL, interval, maxdepth, maxeval, maxfound, prec); /* check that all roots are accounted for */ for (i = a; i <= b; i++) { if (i % 2 == 0) { int found = 0; for (j = 0; j < num; j++) { arf_interval_get_arb(t, blocks + j, ARF_PREC_EXACT); if (arb_contains_si(t, i)) { found = 1; break; } } if (!found) { flint_printf("FAIL: missing root %wd\n", i); flint_printf("a = %wd, b = %wd, maxdepth = %wd, maxeval = %wd, maxfound = %wd, prec = %wd\n", a, b, maxdepth, maxeval, maxfound, prec); for (j = 0; j < num; j++) { arf_interval_printd(blocks + j, 15); flint_printf(" %d \n", info[i]); } flint_abort(); } } } /* check that all reported single roots are good */ for (i = 0; i < num; i++) { if (info[i] == 1) { /* b contains unique 2n -> b/2 contains unique n */ arf_interval_get_arb(t, blocks + i, ARF_PREC_EXACT); arb_mul_2exp_si(t, t, -1); if (!arb_get_unique_fmpz(nn, t)) { flint_printf("FAIL: bad root %wd\n", i); flint_printf("a = %wd, b = %wd, maxdepth = %wd, maxeval = %wd, maxfound = %wd, prec = %wd\n", a, b, maxdepth, maxeval, maxfound, prec); for (j = 0; j < num; j++) { arf_interval_printd(blocks + j, 15); flint_printf(" %d \n", info[i]); } flint_abort(); } } } _arf_interval_vec_clear(blocks, num); flint_free(info); arf_interval_clear(interval); arb_clear(t); fmpz_clear(nn); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_calc/verbose.c000066400000000000000000000006711417376376500157300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_calc.h" int TLS_PREFIX arb_calc_verbose = 0; arb-2.22.1/arb_fmpz_poly.h000066400000000000000000000047031417376376500154050ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARB_FMPZ_POLY_H #define ARB_FMPZ_POLY_H #ifdef ARB_FMPZ_POLY_INLINES_C #define ARB_FMPZ_POLY_INLINE #else #define ARB_FMPZ_POLY_INLINE static __inline__ #endif #include "flint/ulong_extras.h" #include "flint/fmpz.h" #include "flint/fmpz_poly.h" #include "arb.h" #include "acb.h" #include "arb_poly.h" #include "acb_poly.h" #ifdef __cplusplus extern "C" { #endif #define ARB_FMPZ_POLY_ROOTS_VERBOSE 1 void _arb_fmpz_poly_evaluate_acb_horner(acb_t res, const fmpz * f, slong len, const acb_t x, slong prec); void arb_fmpz_poly_evaluate_acb_horner(acb_t res, const fmpz_poly_t f, const acb_t a, slong prec); void _arb_fmpz_poly_evaluate_acb_rectangular(acb_t res, const fmpz * f, slong len, const acb_t x, slong prec); void arb_fmpz_poly_evaluate_acb_rectangular(acb_t res, const fmpz_poly_t f, const acb_t a, slong prec); void _arb_fmpz_poly_evaluate_acb(acb_t res, const fmpz * f, slong len, const acb_t x, slong prec); void arb_fmpz_poly_evaluate_acb(acb_t res, const fmpz_poly_t f, const acb_t a, slong prec); void _arb_fmpz_poly_evaluate_arb_horner(arb_t res, const fmpz * f, slong len, const arb_t x, slong prec); void arb_fmpz_poly_evaluate_arb_horner(arb_t res, const fmpz_poly_t f, const arb_t a, slong prec); void _arb_fmpz_poly_evaluate_arb_rectangular(arb_t res, const fmpz * f, slong len, const arb_t x, slong prec); void arb_fmpz_poly_evaluate_arb_rectangular(arb_t res, const fmpz_poly_t f, const arb_t a, slong prec); void _arb_fmpz_poly_evaluate_arb(arb_t res, const fmpz * f, slong len, const arb_t x, slong prec); void arb_fmpz_poly_evaluate_arb(arb_t res, const fmpz_poly_t f, const arb_t a, slong prec); void arb_fmpz_poly_deflate(fmpz_poly_t result, const fmpz_poly_t input, ulong deflation); ulong arb_fmpz_poly_deflation(const fmpz_poly_t input); void arb_fmpz_poly_complex_roots(acb_ptr roots, const fmpz_poly_t poly, int flags, slong target_prec); ARB_FMPZ_POLY_INLINE void arb_fmpz_poly_cos_minpoly(fmpz_poly_t res, ulong n) { fmpz_poly_cos_minpoly(res, n); } void arb_fmpz_poly_gauss_period_minpoly(fmpz_poly_t res, ulong q, ulong n); #ifdef __cplusplus } #endif #endif arb-2.22.1/arb_fmpz_poly/000077500000000000000000000000001417376376500152305ustar00rootroot00000000000000arb-2.22.1/arb_fmpz_poly/complex_roots.c000066400000000000000000000145471417376376500203040ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" #include "flint/profiler.h" static int check_accuracy(acb_ptr vec, slong len, slong prec) { slong i; for (i = 0; i < len; i++) { if (acb_rel_accuracy_bits(vec + i) < prec) return 0; } return 1; } static int check_isolation(acb_srcptr roots, slong len) { slong i, j; for (i = 0; i < len; i++) { if (arf_sgn(arb_midref(acb_imagref(roots + i))) >= 0) { for (j = i + 1; j < len; j++) { if (arf_sgn(arb_midref(acb_imagref(roots + j))) >= 0) { if (acb_overlaps(roots + i, roots + j)) return 0; } } } } return 1; } void arb_fmpz_poly_complex_roots(acb_ptr roots, const fmpz_poly_t poly, int flags, slong target_prec) { slong i, j, prec, deg, deg_deflated, isolated, maxiter, deflation; slong initial_prec, num_real; acb_poly_t cpoly, cpoly_deflated; fmpz_poly_t poly_deflated; acb_ptr roots_deflated; int removed_zero; if (fmpz_poly_degree(poly) < 1) return; initial_prec = 32; fmpz_poly_init(poly_deflated); acb_poly_init(cpoly); acb_poly_init(cpoly_deflated); /* try to write poly as poly_deflated(x^deflation), possibly multiplied by x */ removed_zero = fmpz_is_zero(poly->coeffs); if (removed_zero) fmpz_poly_shift_right(poly_deflated, poly, 1); else fmpz_poly_set(poly_deflated, poly); deflation = arb_fmpz_poly_deflation(poly_deflated); arb_fmpz_poly_deflate(poly_deflated, poly_deflated, deflation); deg = fmpz_poly_degree(poly); deg_deflated = fmpz_poly_degree(poly_deflated); if (flags & ARB_FMPZ_POLY_ROOTS_VERBOSE) { flint_printf("searching for %wd roots, %wd deflated\n", deg, deg_deflated); } /* we only need deg_deflated entries, but the remainder will be useful as scratch space */ roots_deflated = _acb_vec_init(deg); for (prec = initial_prec; ; prec *= 2) { acb_poly_set_fmpz_poly(cpoly_deflated, poly_deflated, prec); maxiter = FLINT_MIN(4 * deg_deflated + 64, prec); if (flags & ARB_FMPZ_POLY_ROOTS_VERBOSE) { TIMEIT_ONCE_START flint_printf("prec=%wd: ", prec); isolated = acb_poly_find_roots(roots_deflated, cpoly_deflated, prec == initial_prec ? NULL : roots_deflated, maxiter, prec); flint_printf("%wd isolated roots | ", isolated); TIMEIT_ONCE_STOP } else { isolated = acb_poly_find_roots(roots_deflated, cpoly_deflated, prec == initial_prec ? NULL : roots_deflated, maxiter, prec); } if (isolated == deg_deflated) { if (!check_accuracy(roots_deflated, deg_deflated, target_prec)) continue; if (deflation == 1) { _acb_vec_set(roots, roots_deflated, deg_deflated); } else /* compute all nth roots */ { acb_t w, w2; acb_init(w); acb_init(w2); acb_unit_root(w, deflation, prec); acb_unit_root(w2, 2 * deflation, prec); for (i = 0; i < deg_deflated; i++) { if (arf_sgn(arb_midref(acb_realref(roots_deflated + i))) > 0) { acb_root_ui(roots + i * deflation, roots_deflated + i, deflation, prec); } else { acb_neg(roots + i * deflation, roots_deflated + i); acb_root_ui(roots + i * deflation, roots + i * deflation, deflation, prec); acb_mul(roots + i * deflation, roots + i * deflation, w2, prec); } for (j = 1; j < deflation; j++) { acb_mul(roots + i * deflation + j, roots + i * deflation + j - 1, w, prec); } } acb_clear(w); acb_clear(w2); } /* by assumption that poly is squarefree, must be just one */ if (removed_zero) acb_zero(roots + deg_deflated * deflation); if (!check_accuracy(roots, deg, target_prec)) continue; acb_poly_set_fmpz_poly(cpoly, poly, prec); if (!acb_poly_validate_real_roots(roots, cpoly, prec)) continue; for (i = 0; i < deg; i++) { if (arb_contains_zero(acb_imagref(roots + i))) arb_zero(acb_imagref(roots + i)); } if (!check_isolation(roots, deg)) { /* extremely unlikely */ if (flags & ARB_FMPZ_POLY_ROOTS_VERBOSE) flint_printf("isolation failure!\n"); continue; } if (flags & ARB_FMPZ_POLY_ROOTS_VERBOSE) flint_printf("done!\n"); break; } } _acb_vec_sort_pretty(roots, deg); /* pair conjugates */ num_real = 0; for (i = 0; i < deg; i++) if (acb_is_real(roots + i)) num_real++; if (deg != num_real) { for (i = num_real, j = 0; i < deg; i++) { if (arb_is_positive(acb_imagref(roots + i))) { acb_swap(roots_deflated + j, roots + i); j++; } } for (i = 0; i < (deg - num_real) / 2; i++) { acb_swap(roots + num_real + 2 * i, roots_deflated + i); acb_conj(roots + num_real + 2 * i + 1, roots + num_real + 2 * i); } } fmpz_poly_clear(poly_deflated); acb_poly_clear(cpoly); acb_poly_clear(cpoly_deflated); _acb_vec_clear(roots_deflated, deg); } arb-2.22.1/arb_fmpz_poly/deflate.c000066400000000000000000000017671417376376500170130ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" void arb_fmpz_poly_deflate(fmpz_poly_t result, const fmpz_poly_t input, ulong deflation) { slong res_length, i; if (deflation == 0) { flint_printf("Exception (fmpz_poly_deflate). Division by zero.\n"); flint_abort(); } if (input->length <= 1 || deflation == 1) { fmpz_poly_set(result, input); return; } res_length = (input->length - 1) / deflation + 1; fmpz_poly_fit_length(result, res_length); for (i = 0; i < res_length; i++) fmpz_set(result->coeffs + i, input->coeffs + i*deflation); result->length = res_length; } arb-2.22.1/arb_fmpz_poly/deflation.c000066400000000000000000000020161417376376500173400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" ulong arb_fmpz_poly_deflation(const fmpz_poly_t input) { slong i, coeff, deflation; if (input->length <= 1) return input->length; coeff = 1; while (fmpz_is_zero(input->coeffs + coeff)) coeff++; deflation = n_gcd(input->length - 1, coeff); while ((deflation > 1) && (coeff + deflation < input->length)) { for (i = 0; i < deflation - 1; i++) { coeff++; if (!fmpz_is_zero(input->coeffs + coeff)) deflation = n_gcd(coeff, deflation); } if (i == deflation - 1) coeff++; } return deflation; } arb-2.22.1/arb_fmpz_poly/evaluate_acb.c000066400000000000000000000016701417376376500200130ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" void _arb_fmpz_poly_evaluate_acb(acb_t res, const fmpz * f, slong len, const acb_t x, slong prec) { if (acb_is_real(x)) { _arb_fmpz_poly_evaluate_arb(acb_realref(res), f, len, acb_realref(x), prec); arb_zero(acb_imagref(res)); } else { _arb_fmpz_poly_evaluate_acb_rectangular(res, f, len, x, prec); } } void arb_fmpz_poly_evaluate_acb(acb_t res, const fmpz_poly_t f, const acb_t a, slong prec) { _arb_fmpz_poly_evaluate_acb(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_fmpz_poly/evaluate_acb_horner.c000066400000000000000000000025431417376376500213700ustar00rootroot00000000000000/* Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" void _arb_fmpz_poly_evaluate_acb_horner(acb_t y, const fmpz * f, slong len, const acb_t x, slong prec) { if (len == 0) { acb_zero(y); } else if (len == 1 || acb_is_zero(x)) { acb_set_round_fmpz(y, f, prec); } else if (len == 2) { acb_mul_fmpz(y, x, f + 1, prec); acb_add_fmpz(y, y, f + 0, prec); } else { slong i = len - 1; acb_t t, u; acb_init(t); acb_init(u); acb_set_fmpz(u, f + i); for (i = len - 2; i >= 0; i--) { acb_mul(t, u, x, prec); acb_add_fmpz(u, t, f + i, prec); } acb_swap(y, u); acb_clear(t); acb_clear(u); } } void arb_fmpz_poly_evaluate_acb_horner(acb_t res, const fmpz_poly_t f, const acb_t a, slong prec) { _arb_fmpz_poly_evaluate_acb_horner(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_fmpz_poly/evaluate_acb_rectangular.c000066400000000000000000000030021417376376500223710ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" void _arb_fmpz_poly_evaluate_acb_rectangular(acb_t y, const fmpz * poly, slong len, const acb_t x, slong prec) { slong i, m, r; acb_ptr xs; acb_t s, t, c; if (len < 3) { _arb_fmpz_poly_evaluate_acb_horner(y, poly, len, x, prec); return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); acb_init(c); _acb_vec_set_powers(xs, x, m + 1, prec); acb_set_fmpz(y, poly + (r - 1) * m); acb_dot_fmpz(y, y, 0, xs + 1, 1, poly + (r - 1) * m + 1, 1, len - (r - 1) * m - 1, prec); for (i = r - 2; i >= 0; i--) { acb_set_fmpz(s, poly + i * m); acb_dot_fmpz(s, s, 0, xs + 1, 1, poly + i * m + 1, 1, m - 1, prec); acb_mul(y, y, xs + m, prec); acb_add(y, y, s, prec); } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); acb_clear(c); } void arb_fmpz_poly_evaluate_acb_rectangular(acb_t res, const fmpz_poly_t f, const acb_t a, slong prec) { _arb_fmpz_poly_evaluate_acb_rectangular(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_fmpz_poly/evaluate_arb.c000066400000000000000000000024121417376376500200250ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" void _arb_fmpz_poly_evaluate_arb(arb_t res, const fmpz * f, slong len, const arb_t x, slong prec) { if (len >= 6 && len >= 5 + 2500 / (FLINT_MAX(prec, 64) + 64)) { /* todo: improve this tuning? */ if (prec > 1024) { slong fbits; fbits = _fmpz_vec_max_bits(f, len); fbits = FLINT_ABS(fbits); if (fbits > prec / 2) { _arb_fmpz_poly_evaluate_arb_horner(res, f, len, x, prec); return; } } _arb_fmpz_poly_evaluate_arb_rectangular(res, f, len, x, prec); return; } _arb_fmpz_poly_evaluate_arb_horner(res, f, len, x, prec); } void arb_fmpz_poly_evaluate_arb(arb_t res, const fmpz_poly_t f, const arb_t a, slong prec) { _arb_fmpz_poly_evaluate_arb(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_fmpz_poly/evaluate_arb_horner.c000066400000000000000000000025431417376376500214070ustar00rootroot00000000000000/* Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" void _arb_fmpz_poly_evaluate_arb_horner(arb_t y, const fmpz * f, slong len, const arb_t x, slong prec) { if (len == 0) { arb_zero(y); } else if (len == 1 || arb_is_zero(x)) { arb_set_round_fmpz(y, f, prec); } else if (len == 2) { arb_mul_fmpz(y, x, f + 1, prec); arb_add_fmpz(y, y, f + 0, prec); } else { slong i = len - 1; arb_t t, u; arb_init(t); arb_init(u); arb_set_fmpz(u, f + i); for (i = len - 2; i >= 0; i--) { arb_mul(t, u, x, prec); arb_add_fmpz(u, t, f + i, prec); } arb_swap(y, u); arb_clear(t); arb_clear(u); } } void arb_fmpz_poly_evaluate_arb_horner(arb_t res, const fmpz_poly_t f, const arb_t a, slong prec) { _arb_fmpz_poly_evaluate_arb_horner(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_fmpz_poly/evaluate_arb_rectangular.c000066400000000000000000000030021417376376500224100ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" void _arb_fmpz_poly_evaluate_arb_rectangular(arb_t y, const fmpz * poly, slong len, const arb_t x, slong prec) { slong i, m, r; arb_ptr xs; arb_t s, t, c; if (len < 3) { _arb_fmpz_poly_evaluate_arb_horner(y, poly, len, x, prec); return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _arb_vec_init(m + 1); arb_init(s); arb_init(t); arb_init(c); _arb_vec_set_powers(xs, x, m + 1, prec); arb_set_fmpz(y, poly + (r - 1) * m); arb_dot_fmpz(y, y, 0, xs + 1, 1, poly + (r - 1) * m + 1, 1, len - (r - 1) * m - 1, prec); for (i = r - 2; i >= 0; i--) { arb_set_fmpz(s, poly + i * m); arb_dot_fmpz(s, s, 0, xs + 1, 1, poly + i * m + 1, 1, m - 1, prec); arb_mul(y, y, xs + m, prec); arb_add(y, y, s, prec); } _arb_vec_clear(xs, m + 1); arb_clear(s); arb_clear(t); arb_clear(c); } void arb_fmpz_poly_evaluate_arb_rectangular(arb_t res, const fmpz_poly_t f, const arb_t a, slong prec) { _arb_fmpz_poly_evaluate_arb_rectangular(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_fmpz_poly/gauss_period_minpoly.c000066400000000000000000000100321417376376500216230ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" #include "acb_dirichlet.h" void arb_fmpz_poly_gauss_period_minpoly(fmpz_poly_t res, ulong q, ulong n) { ulong k, d, e, g, gk, qinv; ulong * es; slong prec, initial_prec; int done, real; if (n == 0 || !n_is_prime(q) || ((q - 1) % n) != 0 || n_gcd_full(n, (q - 1) / n) != 1) { fmpz_poly_zero(res); return; } d = (q - 1) / n; /* this is much faster */ if (d == 1) { fmpz_poly_cyclotomic(res, q); return; } g = n_primitive_root_prime(q); qinv = n_preinvert_limb(q); es = flint_malloc(sizeof(ulong) * d); for (e = 0; e < d; e++) es[e] = n_powmod2(g, n * e, q); /* either all roots are real, or all roots are complex */ real = (n % 2) == 1; /* first estimate precision crudely based on d and n */ initial_prec = n * log(2 * d) * 1.4426950408889 * 1.03 + 20; initial_prec = FLINT_MAX(initial_prec, 48); /* if high, start lower to get a good estimate */ if (initial_prec > 200) initial_prec = 48; for (prec = initial_prec, done = 0; !done; ) { acb_dirichlet_roots_t zeta; arb_poly_t pz; arb_ptr roots; acb_ptr croots; acb_t t, u; arb_t v; acb_dirichlet_roots_init(zeta, q, (n * d) / 2, prec); roots = _arb_vec_init(n); croots = (acb_ptr) roots; acb_init(t); if (!real) acb_init(u); else arb_init(v); arb_poly_init(pz); for (k = 0; k < (real ? n : n / 2); k++) { gk = n_powmod2(g, k, q); if (real) { arb_zero(v); for (e = 0; e < d / 2; e++) { acb_dirichlet_root(t, zeta, n_mulmod2_preinv(gk, es[e], q, qinv), prec); arb_add(v, v, acb_realref(t), prec); } arb_mul_2exp_si(v, v, 1); /* compute conjugates */ arb_set(roots + k, v); } else { acb_zero(u); for (e = 0; e < d; e++) { acb_dirichlet_root(t, zeta, n_mulmod2_preinv(gk, es[e], q, qinv), prec); acb_add(u, u, t, prec); } if (arb_contains_zero(acb_imagref(u))) { /* todo: could increase precision */ flint_printf("fail! imaginary part should be nonzero\n"); flint_abort(); } else { acb_set(croots + k, u); } } } if (real) arb_poly_product_roots(pz, roots, n, prec); else arb_poly_product_roots_complex(pz, NULL, 0, croots, n / 2, prec); done = arb_poly_get_unique_fmpz_poly(res, pz); if (!done && prec == initial_prec) { mag_t m, mmax; mag_init(m); mag_init(mmax); for (k = 0; k < n; k++) { arb_get_mag(m, pz->coeffs + k); mag_max(mmax, mmax, m); } prec = mag_get_d_log2_approx(mmax) * 1.03 + 20; if (prec < 2 * initial_prec) prec = 2 * initial_prec; mag_clear(m); mag_clear(mmax); } else if (!done) { prec *= 2; } acb_dirichlet_roots_clear(zeta); _arb_vec_clear(roots, n); acb_clear(t); if (!real) acb_clear(u); else arb_clear(v); arb_poly_clear(pz); } flint_free(es); } arb-2.22.1/arb_fmpz_poly/inlines.c000066400000000000000000000006701417376376500170400ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ARB_FMPZ_POLY_INLINES_C #include "arb_fmpz_poly.h" arb-2.22.1/arb_fmpz_poly/test/000077500000000000000000000000001417376376500162075ustar00rootroot00000000000000arb-2.22.1/arb_fmpz_poly/test/t-complex_roots.c000066400000000000000000000137061417376376500215200ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "arb_fmpz_poly.h" void check_roots(const fmpz_poly_t poly, acb_srcptr roots, slong prec) { arb_ptr real; acb_ptr upper; arb_poly_t rpoly; arb_t lead; slong i, j, num_real, num_upper, deg; deg = fmpz_poly_degree(poly); num_real = 0; for (i = 0; i < deg; i++) if (acb_is_real(roots + i)) num_real++; num_upper = (deg - num_real) / 2; real = _arb_vec_init(num_real); upper = _acb_vec_init(num_upper); arb_poly_init(rpoly); arb_init(lead); for (i = 0; i < num_real; i++) arb_set(real + i, acb_realref(roots + i)); for (i = 0; i < num_upper; i++) acb_set(upper + i, roots + num_real + 2 * i); arb_poly_product_roots_complex(rpoly, real, num_real, upper, num_upper, prec); arb_set_fmpz(lead, poly->coeffs + deg); arb_poly_scalar_mul(rpoly, rpoly, lead, prec); if (!arb_poly_contains_fmpz_poly(rpoly, poly)) { flint_printf("FAIL!\n"); flint_printf("deg = %wd, num_real = %wd, num_upper = %wd\n\n", deg, num_real, num_upper); for (i = 0; i < deg; i++) { acb_printn(roots + i, 30, 0); flint_printf("\n"); } flint_printf("\npoly:\n"); fmpz_poly_print(poly); flint_printf("\n\n"); flint_printf("rpoly:\n"); arb_poly_printd(rpoly, 30); flint_printf("\n\n"); flint_abort(); } for (i = 0; i < deg; i++) { for (j = i + 1; j < deg; j++) { if (acb_overlaps(roots + i, roots + j)) { flint_printf("FAIL! (isolation)\n"); flint_printf("deg = %wd, num_real = %wd, num_upper = %wd\n\n", deg, num_real, num_upper); for (i = 0; i < deg; i++) { acb_printn(roots + i, 30, 0); flint_printf("\n"); } } } } _arb_vec_clear(real, num_real); _acb_vec_clear(upper, num_upper); arb_poly_clear(rpoly); arb_clear(lead); } int main() { slong iter; flint_rand_t state; flint_printf("complex_roots...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { fmpz_poly_t f, g; fmpq_poly_t h; fmpz_poly_factor_t fac; fmpz_t t; acb_ptr roots; slong i, j, n, deg, prec, num_factors; int flags; prec = 20 + n_randint(state, 1000); flags = 0; /* ARB_FMPZ_POLY_ROOTS_VERBOSE; */ fmpz_poly_init(f); fmpz_poly_init(g); fmpq_poly_init(h); fmpz_init(t); fmpz_poly_one(f); num_factors = 1 + n_randint(state, 3); for (i = 0; i < num_factors; i++) { n = n_randint(state, 18); switch (n_randint(state, 12)) { case 0: fmpz_poly_zero(g); for (j = 0; j <= n; j++) fmpz_poly_set_coeff_ui(g, j, j+1); break; case 1: arith_chebyshev_t_polynomial(g, n); break; case 2: arith_chebyshev_u_polynomial(g, n); break; case 3: arith_legendre_polynomial(h, n); fmpq_poly_get_numerator(g, h); break; case 4: arith_cyclotomic_polynomial(g, n); break; case 5: arith_swinnerton_dyer_polynomial(g, n % 4); break; case 6: arith_bernoulli_polynomial(h, n); fmpq_poly_get_numerator(g, h); break; case 7: fmpz_poly_zero(g); fmpz_poly_fit_length(g, n+2); arith_stirling_number_1_vec(g->coeffs, n+1, n+2); _fmpz_poly_set_length(g, n+2); fmpz_poly_shift_right(g, g, 1); break; case 8: fmpq_poly_zero(h); fmpq_poly_set_coeff_si(h, 0, 0); fmpq_poly_set_coeff_si(h, 1, 1); fmpq_poly_exp_series(h, h, n + 1); fmpq_poly_get_numerator(g, h); break; case 9: fmpz_poly_zero(g); fmpz_poly_set_coeff_ui(g, 0, 1); fmpz_poly_set_coeff_ui(g, 1, 100); fmpz_poly_pow(g, g, n_randint(state, 5)); fmpz_poly_set_coeff_ui(g, n, 1); break; default: fmpz_poly_randtest(g, state, 1 + n, 1 + n_randint(state, 300)); break; } fmpz_poly_mul(f, f, g); } if (!fmpz_poly_is_zero(f)) { fmpz_poly_factor_init(fac); fmpz_poly_factor_squarefree(fac, f); for (i = 0; i < fac->num; i++) { deg = fmpz_poly_degree(fac->p + i); roots = _acb_vec_init(deg); arb_fmpz_poly_complex_roots(roots, fac->p + i, flags, prec); check_roots(fac->p + i, roots, prec); _acb_vec_clear(roots, deg); } fmpz_poly_factor_clear(fac); } fmpz_poly_clear(f); fmpz_poly_clear(g); fmpq_poly_clear(h); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_fmpz_poly/test/t-evaluate_acb.c000066400000000000000000000067171417376376500212420ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_acb...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { fmpz_poly_t f, g, h; acb_t x, fx, gx, hx, fxgx; slong prec1, prec2, prec3; fmpz_poly_init(f); fmpz_poly_init(g); fmpz_poly_init(h); acb_init(x); acb_init(fx); acb_init(gx); acb_init(hx); acb_init(fxgx); fmpz_poly_randtest(f, state, 1 + n_randint(state, 50), 1 + n_randint(state, 1000)); fmpz_poly_randtest(g, state, 1 + n_randint(state, 50), 1 + n_randint(state, 1000)); fmpz_poly_add(h, f, g); acb_randtest(x, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); acb_randtest(fx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); acb_randtest(gx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); acb_randtest(hx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); acb_randtest(fxgx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); prec3 = 2 + n_randint(state, 2000); switch (n_randint(state, 6)) { case 0: arb_fmpz_poly_evaluate_acb_horner(fx, f, x, prec1); break; case 1: arb_fmpz_poly_evaluate_acb_rectangular(fx, f, x, prec1); break; case 2: arb_fmpz_poly_evaluate_acb(fx, f, x, prec1); break; case 3: acb_set(fx, x); arb_fmpz_poly_evaluate_acb_horner(fx, f, fx, prec1); break; case 4: acb_set(fx, x); arb_fmpz_poly_evaluate_acb_rectangular(fx, f, fx, prec1); break; default: acb_set(fx, x); arb_fmpz_poly_evaluate_acb(fx, f, fx, prec1); break; } arb_fmpz_poly_evaluate_acb(gx, g, x, prec2); arb_fmpz_poly_evaluate_acb(hx, h, x, prec3); acb_add(fxgx, fx, gx, prec3); if (!acb_overlaps(fxgx, hx)) { flint_printf("FAIL\n"); fmpz_poly_print(f); flint_printf("\n\n"); fmpz_poly_print(g); flint_printf("\n\n"); fmpz_poly_print(h); flint_printf("\n\n"); acb_printd(x, 30); flint_printf("\n\n"); acb_printd(fx, 30); flint_printf("\n\n"); acb_printd(gx, 30); flint_printf("\n\n"); acb_printd(hx, 30); flint_printf("\n\n"); acb_printd(fxgx, 30); flint_printf("\n\n"); flint_abort(); } fmpz_poly_clear(f); fmpz_poly_clear(g); fmpz_poly_clear(h); acb_clear(x); acb_clear(fx); acb_clear(gx); acb_clear(hx); acb_clear(fxgx); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_fmpz_poly/test/t-evaluate_arb.c000066400000000000000000000067171417376376500212610ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_arb...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { fmpz_poly_t f, g, h; arb_t x, fx, gx, hx, fxgx; slong prec1, prec2, prec3; fmpz_poly_init(f); fmpz_poly_init(g); fmpz_poly_init(h); arb_init(x); arb_init(fx); arb_init(gx); arb_init(hx); arb_init(fxgx); fmpz_poly_randtest(f, state, 1 + n_randint(state, 50), 1 + n_randint(state, 1000)); fmpz_poly_randtest(g, state, 1 + n_randint(state, 50), 1 + n_randint(state, 1000)); fmpz_poly_add(h, f, g); arb_randtest(x, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); arb_randtest(fx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); arb_randtest(gx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); arb_randtest(hx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); arb_randtest(fxgx, state, 1 + n_randint(state, 2000), 1 + n_randint(state, 100)); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); prec3 = 2 + n_randint(state, 2000); switch (n_randint(state, 6)) { case 0: arb_fmpz_poly_evaluate_arb_horner(fx, f, x, prec1); break; case 1: arb_fmpz_poly_evaluate_arb_rectangular(fx, f, x, prec1); break; case 2: arb_fmpz_poly_evaluate_arb(fx, f, x, prec1); break; case 3: arb_set(fx, x); arb_fmpz_poly_evaluate_arb_horner(fx, f, fx, prec1); break; case 4: arb_set(fx, x); arb_fmpz_poly_evaluate_arb_rectangular(fx, f, fx, prec1); break; default: arb_set(fx, x); arb_fmpz_poly_evaluate_arb(fx, f, fx, prec1); break; } arb_fmpz_poly_evaluate_arb(gx, g, x, prec2); arb_fmpz_poly_evaluate_arb(hx, h, x, prec3); arb_add(fxgx, fx, gx, prec3); if (!arb_overlaps(fxgx, hx)) { flint_printf("FAIL\n"); fmpz_poly_print(f); flint_printf("\n\n"); fmpz_poly_print(g); flint_printf("\n\n"); fmpz_poly_print(h); flint_printf("\n\n"); arb_printd(x, 30); flint_printf("\n\n"); arb_printd(fx, 30); flint_printf("\n\n"); arb_printd(gx, 30); flint_printf("\n\n"); arb_printd(hx, 30); flint_printf("\n\n"); arb_printd(fxgx, 30); flint_printf("\n\n"); flint_abort(); } fmpz_poly_clear(f); fmpz_poly_clear(g); fmpz_poly_clear(h); arb_clear(x); arb_clear(fx); arb_clear(gx); arb_clear(hx); arb_clear(fxgx); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_fmpz_poly/test/t-gauss_period_minpoly.c000066400000000000000000000061401417376376500230500ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_fmpz_poly.h" #include "acb_dirichlet.h" int main() { slong iter; flint_rand_t state; flint_printf("gauss_period_minpoly...."); fflush(stdout); flint_randinit(state); { slong prec; ulong n, q; fmpz_poly_t pol; fmpz_poly_init(pol); /* test q = 0 separately; see issue #194 */ for (n = 0; n < 100; n++) { fmpz_poly_one(pol); arb_fmpz_poly_gauss_period_minpoly(pol, 0, n); if (!fmpz_poly_is_zero(pol)) { flint_printf("FAIL (q = 0)\n"); flint_abort(); } } for (q = 1; q < 1000; q++) { acb_dirichlet_roots_t zeta; prec = 100 + n_randint(state, 500); if (n_is_prime(q)) acb_dirichlet_roots_init(zeta, q, 30, prec); for (n = 0; n < 1000; n++) { arb_fmpz_poly_gauss_period_minpoly(pol, q, n); if (!fmpz_poly_is_zero(pol)) { ulong k, g, gk, e, d; acb_t t, u; acb_init(t); acb_init(u); d = (q - 1) / n; g = n_primitive_root_prime(q); for (iter = 0; iter < 3; iter++) { k = n_randint(state, n); gk = n_powmod2(g, k, 2 * q); acb_zero(u); for (e = 0; e < d; e++) { acb_dirichlet_root(t, zeta, n_mulmod2_preinv(gk, n_powmod2(g, n * e, 2 * q), 2 * q, n_preinvert_limb(2 * q)), prec); acb_add(u, u, t, prec); } arb_fmpz_poly_evaluate_acb(t, pol, u, prec); if (!acb_contains_zero(t) || fmpz_poly_degree(pol) != n) { flint_printf("FAIL\n"); flint_printf("q = %wu, n = %wu, k = %wu\n\n", q, n, k); fmpz_poly_print(pol); flint_printf("\n\n"); acb_printn(u, 30, 0); flint_printf("\n\n"); acb_printn(t, 30, 0); flint_printf("\n\n"); flint_abort(); } } acb_clear(t); acb_clear(u); } } if (n_is_prime(q)) acb_dirichlet_roots_clear(zeta); } fmpz_poly_clear(pol); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_fpwrap.h000066400000000000000000000434711417376376500146720ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARB_FPWRAP_H #define ARB_FPWRAP_H #ifdef ARB_FPWRAP_INLINES_C #define ARB_FPWRAP_INLINE #else #define ARB_FPWRAP_INLINE static __inline__ #endif #include "flint/double_extras.h" #include "arb.h" #include "acb.h" #ifdef __cplusplus extern "C" { #endif #define FPWRAP_SUCCESS 0 #define FPWRAP_UNABLE 1 #define FPWRAP_ACCURATE_PARTS 1 #define FPWRAP_CORRECT_ROUNDING 2 #define FPWRAP_WORK_LIMIT 65536 typedef struct { double real; double imag; } complex_double; int arb_fpwrap_double_exp(double * res, double x, int flags); int arb_fpwrap_cdouble_exp(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_expm1(double * res, double x, int flags); int arb_fpwrap_cdouble_expm1(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_log(double * res, double x, int flags); int arb_fpwrap_cdouble_log(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_log1p(double * res, double x, int flags); int arb_fpwrap_cdouble_log1p(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_pow(double * res, double x, double y, int flags); int arb_fpwrap_cdouble_pow(complex_double * res, complex_double x, complex_double y, int flags); int arb_fpwrap_double_sqrt(double * res, double x, int flags); int arb_fpwrap_cdouble_sqrt(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_rsqrt(double * res, double x, int flags); int arb_fpwrap_cdouble_rsqrt(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_cbrt(double * res, double x, int flags); int arb_fpwrap_cdouble_cbrt(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_sin(double * res, double x, int flags); int arb_fpwrap_cdouble_sin(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_cos(double * res, double x, int flags); int arb_fpwrap_cdouble_cos(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_tan(double * res, double x, int flags); int arb_fpwrap_cdouble_tan(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_cot(double * res, double x, int flags); int arb_fpwrap_cdouble_cot(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_sec(double * res, double x, int flags); int arb_fpwrap_cdouble_sec(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_csc(double * res, double x, int flags); int arb_fpwrap_cdouble_csc(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_sinc(double * res, double x, int flags); int arb_fpwrap_cdouble_sinc(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_sin_pi(double * res, double x, int flags); int arb_fpwrap_cdouble_sin_pi(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_cos_pi(double * res, double x, int flags); int arb_fpwrap_cdouble_cos_pi(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_tan_pi(double * res, double x, int flags); int arb_fpwrap_cdouble_tan_pi(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_cot_pi(double * res, double x, int flags); int arb_fpwrap_cdouble_cot_pi(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_sinc_pi(double * res, double x, int flags); int arb_fpwrap_cdouble_sinc_pi(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_asin(double * res, double x, int flags); int arb_fpwrap_cdouble_asin(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_acos(double * res, double x, int flags); int arb_fpwrap_cdouble_acos(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_atan(double * res, double x, int flags); int arb_fpwrap_cdouble_atan(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_atan2(double * res, double x1, double x2, int flags); int arb_fpwrap_double_asinh(double * res, double x, int flags); int arb_fpwrap_cdouble_asinh(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_acosh(double * res, double x, int flags); int arb_fpwrap_cdouble_acosh(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_atanh(double * res, double x, int flags); int arb_fpwrap_cdouble_atanh(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_lambertw(double * res, double x, slong branch, int flags); int arb_fpwrap_cdouble_lambertw(complex_double * res, complex_double x, slong branch, int flags); int arb_fpwrap_double_rising(double * res, double x, double n, int flags); int arb_fpwrap_cdouble_rising(complex_double * res, complex_double x, complex_double n, int flags); int arb_fpwrap_double_gamma(double * res, double x, int flags); int arb_fpwrap_cdouble_gamma(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_rgamma(double * res, double x, int flags); int arb_fpwrap_cdouble_rgamma(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_lgamma(double * res, double x, int flags); int arb_fpwrap_cdouble_lgamma(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_digamma(double * res, double x, int flags); int arb_fpwrap_cdouble_digamma(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_zeta(double * res, double x, int flags); int arb_fpwrap_cdouble_zeta(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_hurwitz_zeta(double * res, double s, double z, int flags); int arb_fpwrap_cdouble_hurwitz_zeta(complex_double * res, complex_double s, complex_double z, int flags); int arb_fpwrap_double_barnes_g(double * res, double x, int flags); int arb_fpwrap_cdouble_barnes_g(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_log_barnes_g(double * res, double x, int flags); int arb_fpwrap_cdouble_log_barnes_g(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_polygamma(double * res, double s, double z, int flags); int arb_fpwrap_cdouble_polygamma(complex_double * res, complex_double s, complex_double z, int flags); int arb_fpwrap_double_polylog(double * res, double s, double z, int flags); int arb_fpwrap_cdouble_polylog(complex_double * res, complex_double s, complex_double z, int flags); int arb_fpwrap_cdouble_dirichlet_eta(complex_double * res, complex_double s, int flags); int arb_fpwrap_cdouble_riemann_xi(complex_double * res, complex_double s, int flags); int arb_fpwrap_cdouble_hardy_theta(complex_double * res, complex_double z, int flags); int arb_fpwrap_cdouble_hardy_z(complex_double * res, complex_double z, int flags); int arb_fpwrap_cdouble_zeta_zero(complex_double * res, ulong n, int flags); int arb_fpwrap_double_erf(double * res, double x, int flags); int arb_fpwrap_cdouble_erf(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_erfc(double * res, double x, int flags); int arb_fpwrap_cdouble_erfc(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_erfi(double * res, double x, int flags); int arb_fpwrap_cdouble_erfi(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_erfinv(double * res, double x, int flags); int arb_fpwrap_double_erfcinv(double * res, double x, int flags); int arb_fpwrap_double_fresnel_s(double * res, double x, int normalized, int flags); int arb_fpwrap_cdouble_fresnel_s(complex_double * res, complex_double x, int normalized, int flags); int arb_fpwrap_double_fresnel_c(double * res, double x, int normalized, int flags); int arb_fpwrap_cdouble_fresnel_c(complex_double * res, complex_double x, int normalized, int flags); int arb_fpwrap_double_gamma_upper(double * res, double s, double z, int regularized, int flags); int arb_fpwrap_cdouble_gamma_upper(complex_double * res, complex_double s, complex_double z, int regularized, int flags); int arb_fpwrap_double_gamma_lower(double * res, double s, double z, int regularized, int flags); int arb_fpwrap_cdouble_gamma_lower(complex_double * res, complex_double s, complex_double z, int regularized, int flags); int arb_fpwrap_double_beta_lower(double * res, double a, double b, double z, int regularized, int flags); int arb_fpwrap_cdouble_beta_lower(complex_double * res, complex_double a, complex_double b, complex_double z, int regularized, int flags); int arb_fpwrap_double_exp_integral_e(double * res, double s, double z, int flags); int arb_fpwrap_cdouble_exp_integral_e(complex_double * res, complex_double s, complex_double z, int flags); int arb_fpwrap_double_exp_integral_ei(double * res, double x, int flags); int arb_fpwrap_cdouble_exp_integral_ei(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_sin_integral(double * res, double x, int flags); int arb_fpwrap_cdouble_sin_integral(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_cos_integral(double * res, double x, int flags); int arb_fpwrap_cdouble_cos_integral(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_sinh_integral(double * res, double x, int flags); int arb_fpwrap_cdouble_sinh_integral(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_cosh_integral(double * res, double x, int flags); int arb_fpwrap_cdouble_cosh_integral(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_log_integral(double * res, double x, int offset, int flags); int arb_fpwrap_cdouble_log_integral(complex_double * res, complex_double x, int offset, int flags); int arb_fpwrap_double_bessel_j(double * res, double nu, double x, int flags); int arb_fpwrap_cdouble_bessel_j(complex_double * res, complex_double nu, complex_double x, int flags); int arb_fpwrap_double_bessel_y(double * res, double nu, double x, int flags); int arb_fpwrap_cdouble_bessel_y(complex_double * res, complex_double nu, complex_double x, int flags); int arb_fpwrap_double_bessel_i(double * res, double nu, double x, int flags); int arb_fpwrap_cdouble_bessel_i(complex_double * res, complex_double nu, complex_double x, int flags); int arb_fpwrap_double_bessel_k(double * res, double nu, double x, int flags); int arb_fpwrap_cdouble_bessel_k(complex_double * res, complex_double nu, complex_double x, int flags); int arb_fpwrap_double_bessel_k_scaled(double * res, double nu, double x, int flags); int arb_fpwrap_cdouble_bessel_k_scaled(complex_double * res, complex_double nu, complex_double x, int flags); int arb_fpwrap_double_airy_ai(double * res, double x, int flags); int arb_fpwrap_cdouble_airy_ai(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_airy_ai_prime(double * res, double x, int flags); int arb_fpwrap_cdouble_airy_ai_prime(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_airy_bi(double * res, double x, int flags); int arb_fpwrap_cdouble_airy_bi(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_airy_bi_prime(double * res, double x, int flags); int arb_fpwrap_cdouble_airy_bi_prime(complex_double * res, complex_double x, int flags); int arb_fpwrap_double_airy_ai_zero(double * res, ulong n, int flags); int arb_fpwrap_double_airy_ai_prime_zero(double * res, ulong n, int flags); int arb_fpwrap_double_airy_bi_zero(double * res, ulong n, int flags); int arb_fpwrap_double_airy_bi_prime_zero(double * res, ulong n, int flags); int arb_fpwrap_double_coulomb_f(double * res, double l, double eta, double x, int flags); int arb_fpwrap_cdouble_coulomb_f(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags); int arb_fpwrap_double_coulomb_g(double * res, double l, double eta, double x, int flags); int arb_fpwrap_cdouble_coulomb_g(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags); int arb_fpwrap_cdouble_coulomb_hpos(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags); int arb_fpwrap_cdouble_coulomb_hneg(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags); int arb_fpwrap_double_chebyshev_t(double * res, double n, double x, int flags); int arb_fpwrap_cdouble_chebyshev_t(complex_double * res, complex_double n, complex_double x, int flags); int arb_fpwrap_double_chebyshev_u(double * res, double n, double x, int flags); int arb_fpwrap_cdouble_chebyshev_u(complex_double * res, complex_double n, complex_double x, int flags); int arb_fpwrap_double_jacobi_p(double * res, double n, double a, double b, double x, int flags); int arb_fpwrap_cdouble_jacobi_p(complex_double * res, complex_double n, complex_double a, complex_double b, complex_double x, int flags); int arb_fpwrap_double_gegenbauer_c(double * res, double n, double m, double x, int flags); int arb_fpwrap_cdouble_gegenbauer_c(complex_double * res, complex_double n, complex_double m, complex_double x, int flags); int arb_fpwrap_double_laguerre_l(double * res, double n, double m, double x, int flags); int arb_fpwrap_cdouble_laguerre_l(complex_double * res, complex_double n, complex_double m, complex_double x, int flags); int arb_fpwrap_double_hermite_h(double * res, double n, double x, int flags); int arb_fpwrap_cdouble_hermite_h(complex_double * res, complex_double n, complex_double x, int flags); int arb_fpwrap_double_legendre_p(double * res, double n, double m, double x, int type, int flags); int arb_fpwrap_cdouble_legendre_p(complex_double * res, complex_double n, complex_double m, complex_double x, int type, int flags); int arb_fpwrap_double_legendre_q(double * res, double n, double m, double x, int type, int flags); int arb_fpwrap_cdouble_legendre_q(complex_double * res, complex_double n, complex_double m, complex_double x, int type, int flags); int arb_fpwrap_double_legendre_root(double * res1, double * res2, ulong n, ulong k, int flags); int arb_fpwrap_cdouble_spherical_y(complex_double * res, slong n, slong m, complex_double x1, complex_double x2, int flags); int arb_fpwrap_double_hypgeom_0f1(double * res, double a, double x, int regularized, int flags); int arb_fpwrap_cdouble_hypgeom_0f1(complex_double * res, complex_double a, complex_double x, int regularized, int flags); int arb_fpwrap_double_hypgeom_1f1(double * res, double a, double b, double x, int regularized, int flags); int arb_fpwrap_cdouble_hypgeom_1f1(complex_double * res, complex_double a, complex_double b, complex_double x, int regularized, int flags); int arb_fpwrap_double_hypgeom_u(double * res, double a, double b, double x, int flags); int arb_fpwrap_cdouble_hypgeom_u(complex_double * res, complex_double a, complex_double b, complex_double x, int flags); int arb_fpwrap_double_hypgeom_2f1(double * res, double a, double b, double c, double x, int regularized, int flags); int arb_fpwrap_cdouble_hypgeom_2f1(complex_double * res, complex_double a, complex_double b, complex_double c, complex_double x, int regularized, int flags); int arb_fpwrap_double_hypgeom_pfq(double * res, const double * a, slong p, const double * b, slong q, double z, int regularized, int flags); int arb_fpwrap_cdouble_hypgeom_pfq(complex_double * res, const complex_double * a, slong p, const complex_double * b, slong q, complex_double z, int regularized, int flags); int arb_fpwrap_double_agm(double * res, double x, double y, int flags); int arb_fpwrap_cdouble_agm(complex_double * res, complex_double x, complex_double y, int flags); int arb_fpwrap_cdouble_elliptic_k(complex_double * res, complex_double m, int flags); int arb_fpwrap_cdouble_elliptic_e(complex_double * res, complex_double m, int flags); int arb_fpwrap_cdouble_elliptic_pi(complex_double * res, complex_double n, complex_double m, int flags); int arb_fpwrap_cdouble_elliptic_f(complex_double * res, complex_double phi, complex_double m, int pi, int flags); int arb_fpwrap_cdouble_elliptic_e_inc(complex_double * res, complex_double phi, complex_double m, int pi, int flags); int arb_fpwrap_cdouble_elliptic_pi_inc(complex_double * res, complex_double n, complex_double phi, complex_double m, int pi, int flags); int arb_fpwrap_cdouble_elliptic_rf(complex_double * res, complex_double x, complex_double y, complex_double z, int option, int flags); int arb_fpwrap_cdouble_elliptic_rg(complex_double * res, complex_double x, complex_double y, complex_double z, int option, int flags); int arb_fpwrap_cdouble_elliptic_rj(complex_double * res, complex_double x, complex_double y, complex_double z, complex_double w, int option, int flags); int arb_fpwrap_cdouble_elliptic_p(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_elliptic_p_prime(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_elliptic_inv_p(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_elliptic_zeta(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_elliptic_sigma(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_jacobi_theta_1(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_jacobi_theta_2(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_jacobi_theta_3(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_jacobi_theta_4(complex_double * res, complex_double z, complex_double tau, int flags); int arb_fpwrap_cdouble_dedekind_eta(complex_double * res, complex_double tau, int flags); int arb_fpwrap_cdouble_modular_j(complex_double * res, complex_double tau, int flags); int arb_fpwrap_cdouble_modular_lambda(complex_double * res, complex_double tau, int flags); int arb_fpwrap_cdouble_modular_delta(complex_double * res, complex_double tau, int flags); #ifdef __cplusplus } #endif #endif arb-2.22.1/arb_fpwrap/000077500000000000000000000000001417376376500145105ustar00rootroot00000000000000arb-2.22.1/arb_fpwrap/fpwrap.c000066400000000000000000001211311417376376500161520ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb.h" #include "acb.h" #include "arb_fpwrap.h" #include "arb_hypgeom.h" #include "acb_hypgeom.h" #include "acb_dirichlet.h" #include "acb_elliptic.h" #include "acb_modular.h" static int _acb_vec_is_finite(acb_srcptr x, slong len) { slong i; for (i = 0; i < len; i++) if (!acb_is_finite(x + i)) return 0; return 1; } int arb_accurate_enough_d(const arb_t x, int flags) { if (flags & FPWRAP_CORRECT_ROUNDING) { return arb_can_round_arf(x, 53, ARF_RND_NEAR); } if (arb_rel_accuracy_bits(x) >= 53 + 1) return 1; /* Rounding will give +/- 0 (we don't worry which) */ if (mag_cmp_2exp_si(arb_radref(x), -1077) < 0 && arf_cmpabs_2exp_si(arb_midref(x), -1077) < 0) { return 1; } /* Rounding will give +/- inf */ if (arb_rel_accuracy_bits(x) > 2 && arf_cmpabs_2exp_si(arb_midref(x), 1024) > 0) { return 1; } return 0; } int acb_accurate_enough_d(const acb_t x, int flags) { if (flags & FPWRAP_CORRECT_ROUNDING) { return arb_can_round_arf(acb_realref(x), 53, ARF_RND_NEAR) && arb_can_round_arf(acb_imagref(x), 53, ARF_RND_NEAR); } if (flags & FPWRAP_ACCURATE_PARTS) { return arb_accurate_enough_d(acb_realref(x), flags) && arb_accurate_enough_d(acb_imagref(x), flags); } if (acb_rel_accuracy_bits(x) >= 53 + 1) return 1; /* Rounding will give +/- 0 (we don't worry which) */ if (mag_cmp_2exp_si(arb_radref(acb_realref(x)), -1077) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_realref(x)), -1077) < 0 && mag_cmp_2exp_si(arb_radref(acb_imagref(x)), -1077) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(x)), -1077) < 0) { return 1; } /* Rounding will give +/- inf */ if (acb_rel_accuracy_bits(x) > 2 && (arf_cmpabs_2exp_si(arb_midref(acb_realref(x)), 1024) > 0 || arf_cmpabs_2exp_si(arb_midref(acb_imagref(x)), 1024) > 0)) { return 1; } return 0; } #define WP_INITIAL 64 #define DOUBLE_CHECK_RESULT \ if (arb_accurate_enough_d(arb_res, flags)) \ { \ *res = arf_get_d(arb_midref(arb_res), ARF_RND_NEAR); \ status = FPWRAP_SUCCESS; \ break; \ } \ if (wp >= double_wp_max(flags)) \ { \ *res = D_NAN; \ status = FPWRAP_UNABLE; \ break; \ } \ #define DOUBLE_CHECK_RESULT2 \ if (arb_accurate_enough_d(arb_res1, flags) && arb_accurate_enough_d(arb_res2, flags)) \ { \ *res1 = arf_get_d(arb_midref(arb_res1), ARF_RND_NEAR); \ *res2 = arf_get_d(arb_midref(arb_res2), ARF_RND_NEAR); \ status = FPWRAP_SUCCESS; \ break; \ } \ if (wp >= double_wp_max(flags)) \ { \ *res1 = D_NAN; \ *res2 = D_NAN; \ status = FPWRAP_UNABLE; \ break; \ } \ #define CDOUBLE_CHECK_RESULT \ if (acb_accurate_enough_d(acb_res, flags)) \ { \ res->real = arf_get_d(arb_midref(acb_realref(acb_res)), ARF_RND_NEAR); \ res->imag = arf_get_d(arb_midref(acb_imagref(acb_res)), ARF_RND_NEAR); \ status = FPWRAP_SUCCESS; \ break; \ } \ if (wp >= double_wp_max(flags)) \ { \ res->real = D_NAN; \ res->imag = D_NAN; \ status = FPWRAP_UNABLE; \ break; \ } static slong double_wp_max(int flags) { int iters; iters = flags / FPWRAP_WORK_LIMIT; if (iters <= 0) return 64 << 7; if (iters >= 25) return 64 << 24; return 64 << iters; } typedef void (*arb_func_1)(arb_t, const arb_t, slong prec); typedef void (*arb_func_2)(arb_t, const arb_t, const arb_t, slong prec); typedef void (*arb_func_3)(arb_t, const arb_t, const arb_t, const arb_t, slong prec); typedef void (*arb_func_4)(arb_t, const arb_t, const arb_t, const arb_t, const arb_t, slong prec); typedef void (*acb_func_1)(acb_t, const acb_t, slong prec); typedef void (*acb_func_2)(acb_t, const acb_t, const acb_t, slong prec); typedef void (*acb_func_3)(acb_t, const acb_t, const acb_t, const acb_t, slong prec); typedef void (*acb_func_4)(acb_t, const acb_t, const acb_t, const acb_t, const acb_t, slong prec); typedef void (*arb_func_1_int)(arb_t, const arb_t, int, slong prec); typedef void (*arb_func_2_int)(arb_t, const arb_t, const arb_t, int, slong prec); typedef void (*arb_func_3_int)(arb_t, const arb_t, const arb_t, const arb_t, int, slong prec); typedef void (*arb_func_4_int)(arb_t, const arb_t, const arb_t, const arb_t, const arb_t, int, slong prec); typedef void (*acb_func_1_int)(acb_t, const acb_t, int, slong prec); typedef void (*acb_func_2_int)(acb_t, const acb_t, const acb_t, int, slong prec); typedef void (*acb_func_3_int)(acb_t, const acb_t, const acb_t, const acb_t, int, slong prec); typedef void (*acb_func_4_int)(acb_t, const acb_t, const acb_t, const acb_t, const acb_t, int, slong prec); int arb_fpwrap_double_1(double * res, arb_func_1 func, double x, int flags) { arb_t arb_res, arb_x; slong wp; int status; arb_init(arb_res); arb_init(arb_x); arb_set_d(arb_x, x); if (!arb_is_finite(arb_x)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x); arb_clear(arb_res); return status; } int arb_fpwrap_double_2(double * res, arb_func_2 func, double x1, double x2, int flags) { arb_t arb_res, arb_x1, arb_x2; slong wp; int status; arb_init(arb_res); arb_init(arb_x1); arb_init(arb_x2); arb_set_d(arb_x1, x1); arb_set_d(arb_x2, x2); if (!arb_is_finite(arb_x1) || !arb_is_finite(arb_x2)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x1, arb_x2, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x1); arb_clear(arb_x2); arb_clear(arb_res); return status; } int arb_fpwrap_double_3(double * res, arb_func_3 func, double x1, double x2, double x3, int flags) { arb_t arb_res, arb_x1, arb_x2, arb_x3; slong wp; int status; arb_init(arb_res); arb_init(arb_x1); arb_init(arb_x2); arb_init(arb_x3); arb_set_d(arb_x1, x1); arb_set_d(arb_x2, x2); arb_set_d(arb_x3, x3); if (!arb_is_finite(arb_x1) || !arb_is_finite(arb_x2) || !arb_is_finite(arb_x3)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x1, arb_x2, arb_x3, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x1); arb_clear(arb_x2); arb_clear(arb_x3); arb_clear(arb_res); return status; } int arb_fpwrap_double_4(double * res, arb_func_4 func, double x1, double x2, double x3, double x4, int flags) { arb_t arb_res, arb_x1, arb_x2, arb_x3, arb_x4; slong wp; int status; arb_init(arb_res); arb_init(arb_x1); arb_init(arb_x2); arb_init(arb_x3); arb_init(arb_x4); arb_set_d(arb_x1, x1); arb_set_d(arb_x2, x2); arb_set_d(arb_x3, x3); arb_set_d(arb_x3, x4); if (!arb_is_finite(arb_x1) || !arb_is_finite(arb_x2) || !arb_is_finite(arb_x3) || !arb_is_finite(arb_x4)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x1, arb_x2, arb_x3, arb_x4, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x1); arb_clear(arb_x2); arb_clear(arb_x3); arb_clear(arb_x4); arb_clear(arb_res); return status; } int arb_fpwrap_cdouble_1(complex_double * res, acb_func_1 func, complex_double x, int flags) { acb_t acb_res, acb_x; slong wp; int status; acb_init(acb_res); acb_init(acb_x); acb_set_d_d(acb_x, x.real, x.imag); if (!acb_is_finite(acb_x)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x); acb_clear(acb_res); return status; } int arb_fpwrap_cdouble_2(complex_double * res, acb_func_2 func, complex_double x1, complex_double x2, int flags) { acb_t acb_res, acb_x1, acb_x2; slong wp; int status; acb_init(acb_res); acb_init(acb_x1); acb_init(acb_x2); acb_set_d_d(acb_x1, x1.real, x1.imag); acb_set_d_d(acb_x2, x2.real, x2.imag); if (!acb_is_finite(acb_x1) || !acb_is_finite(acb_x2)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x1, acb_x2, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x1); acb_clear(acb_x2); acb_clear(acb_res); return status; } int arb_fpwrap_cdouble_3(complex_double * res, acb_func_3 func, complex_double x1, complex_double x2, complex_double x3, int flags) { acb_t acb_res, acb_x1, acb_x2, acb_x3; slong wp; int status; acb_init(acb_res); acb_init(acb_x1); acb_init(acb_x2); acb_init(acb_x3); acb_set_d_d(acb_x1, x1.real, x1.imag); acb_set_d_d(acb_x2, x2.real, x2.imag); acb_set_d_d(acb_x3, x3.real, x3.imag); if (!acb_is_finite(acb_x1) || !acb_is_finite(acb_x2) || !acb_is_finite(acb_x3)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x1, acb_x2, acb_x3, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x1); acb_clear(acb_x2); acb_clear(acb_x3); acb_clear(acb_res); return status; } int arb_fpwrap_cdouble_4(complex_double * res, acb_func_4 func, complex_double x1, complex_double x2, complex_double x3, complex_double x4, int flags) { acb_t acb_res, acb_x1, acb_x2, acb_x3, acb_x4; slong wp; int status; acb_init(acb_res); acb_init(acb_x1); acb_init(acb_x2); acb_init(acb_x3); acb_init(acb_x4); acb_set_d_d(acb_x1, x1.real, x1.imag); acb_set_d_d(acb_x2, x2.real, x2.imag); acb_set_d_d(acb_x3, x3.real, x3.imag); acb_set_d_d(acb_x4, x4.real, x4.imag); if (!acb_is_finite(acb_x1) || !acb_is_finite(acb_x2) || !acb_is_finite(acb_x3) || !acb_is_finite(acb_x4)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x1, acb_x2, acb_x3, acb_x4, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x1); acb_clear(acb_x2); acb_clear(acb_x3); acb_clear(acb_x4); acb_clear(acb_res); return status; } int arb_fpwrap_double_1_int(double * res, arb_func_1_int func, double x, int intx, int flags) { arb_t arb_res, arb_x; slong wp; int status; arb_init(arb_res); arb_init(arb_x); arb_set_d(arb_x, x); if (!arb_is_finite(arb_x)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x, intx, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x); arb_clear(arb_res); return status; } int arb_fpwrap_double_2_int(double * res, arb_func_2_int func, double x1, double x2, int intx, int flags) { arb_t arb_res, arb_x1, arb_x2; slong wp; int status; arb_init(arb_res); arb_init(arb_x1); arb_init(arb_x2); arb_set_d(arb_x1, x1); arb_set_d(arb_x2, x2); if (!arb_is_finite(arb_x1) || !arb_is_finite(arb_x2)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x1, arb_x2, intx, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x1); arb_clear(arb_x2); arb_clear(arb_res); return status; } int arb_fpwrap_double_3_int(double * res, arb_func_3_int func, double x1, double x2, double x3, int intx, int flags) { arb_t arb_res, arb_x1, arb_x2, arb_x3; slong wp; int status; arb_init(arb_res); arb_init(arb_x1); arb_init(arb_x2); arb_init(arb_x3); arb_set_d(arb_x1, x1); arb_set_d(arb_x2, x2); arb_set_d(arb_x3, x3); if (!arb_is_finite(arb_x1) || !arb_is_finite(arb_x2) || !arb_is_finite(arb_x3)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x1, arb_x2, arb_x3, intx, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x1); arb_clear(arb_x2); arb_clear(arb_x3); arb_clear(arb_res); return status; } int arb_fpwrap_double_4_int(double * res, arb_func_4_int func, double x1, double x2, double x3, double x4, int intx, int flags) { arb_t arb_res, arb_x1, arb_x2, arb_x3, arb_x4; slong wp; int status; arb_init(arb_res); arb_init(arb_x1); arb_init(arb_x2); arb_init(arb_x3); arb_init(arb_x4); arb_set_d(arb_x1, x1); arb_set_d(arb_x2, x2); arb_set_d(arb_x3, x3); arb_set_d(arb_x4, x4); if (!arb_is_finite(arb_x1) || !arb_is_finite(arb_x2) || !arb_is_finite(arb_x3) || !arb_is_finite(arb_x4)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(arb_res, arb_x1, arb_x2, arb_x3, arb_x4, intx, wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x1); arb_clear(arb_x2); arb_clear(arb_x3); arb_clear(arb_x4); arb_clear(arb_res); return status; } int arb_fpwrap_cdouble_1_int(complex_double * res, acb_func_1_int func, complex_double x, int intx, int flags) { acb_t acb_res, acb_x; slong wp; int status; acb_init(acb_res); acb_init(acb_x); acb_set_d_d(acb_x, x.real, x.imag); if (!acb_is_finite(acb_x)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x, intx, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x); acb_clear(acb_res); return status; } int arb_fpwrap_cdouble_2_int(complex_double * res, acb_func_2_int func, complex_double x1, complex_double x2, int intx, int flags) { acb_t acb_res, acb_x1, acb_x2; slong wp; int status; acb_init(acb_res); acb_init(acb_x1); acb_init(acb_x2); acb_set_d_d(acb_x1, x1.real, x1.imag); acb_set_d_d(acb_x2, x2.real, x2.imag); if (!acb_is_finite(acb_x1) || !acb_is_finite(acb_x2)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x1, acb_x2, intx, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x1); acb_clear(acb_x2); acb_clear(acb_res); return status; } int arb_fpwrap_cdouble_3_int(complex_double * res, acb_func_3_int func, complex_double x1, complex_double x2, complex_double x3, int intx, int flags) { acb_t acb_res, acb_x1, acb_x2, acb_x3; slong wp; int status; acb_init(acb_res); acb_init(acb_x1); acb_init(acb_x2); acb_init(acb_x3); acb_set_d_d(acb_x1, x1.real, x1.imag); acb_set_d_d(acb_x2, x2.real, x2.imag); acb_set_d_d(acb_x3, x3.real, x3.imag); if (!acb_is_finite(acb_x1) || !acb_is_finite(acb_x2) || !acb_is_finite(acb_x3)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x1, acb_x2, acb_x3, intx, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x1); acb_clear(acb_x2); acb_clear(acb_x3); acb_clear(acb_res); return status; } int arb_fpwrap_cdouble_4_int(complex_double * res, acb_func_4_int func, complex_double x1, complex_double x2, complex_double x3, complex_double x4, int intx, int flags) { acb_t acb_res, acb_x1, acb_x2, acb_x3, acb_x4; slong wp; int status; acb_init(acb_res); acb_init(acb_x1); acb_init(acb_x2); acb_init(acb_x3); acb_init(acb_x4); acb_set_d_d(acb_x1, x1.real, x1.imag); acb_set_d_d(acb_x2, x2.real, x2.imag); acb_set_d_d(acb_x3, x3.real, x3.imag); acb_set_d_d(acb_x4, x4.real, x4.imag); if (!acb_is_finite(acb_x1) || !acb_is_finite(acb_x2) || !acb_is_finite(acb_x3) || !acb_is_finite(acb_x4)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { func(acb_res, acb_x1, acb_x2, acb_x3, acb_x4, intx, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x1); acb_clear(acb_x2); acb_clear(acb_x3); acb_clear(acb_x4); acb_clear(acb_res); return status; } #define DEF_DOUBLE_FUN_1(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x, int flags) \ { \ return arb_fpwrap_double_1(res, arb_fun, x, flags); \ } \ #define DEF_DOUBLE_FUN_2(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x1, double x2, int flags) \ { \ return arb_fpwrap_double_2(res, arb_fun, x1, x2, flags); \ } \ #define DEF_DOUBLE_FUN_3(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x1, double x2, double x3, int flags) \ { \ return arb_fpwrap_double_3(res, arb_fun, x1, x2, x3, flags); \ } \ #define DEF_DOUBLE_FUN_4(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x1, double x2, double x3, double x4, int flags) \ { \ return arb_fpwrap_double_4(res, arb_fun, x1, x2, x3, x4, flags); \ } \ #define DEF_CDOUBLE_FUN_1(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x, int flags) \ { \ return arb_fpwrap_cdouble_1(res, acb_fun, x, flags); \ } \ #define DEF_CDOUBLE_FUN_2(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x1, complex_double x2, int flags) \ { \ return arb_fpwrap_cdouble_2(res, acb_fun, x1, x2, flags); \ } \ #define DEF_CDOUBLE_FUN_3(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x1, complex_double x2, complex_double x3, int flags) \ { \ return arb_fpwrap_cdouble_3(res, acb_fun, x1, x2, x3, flags); \ } \ #define DEF_CDOUBLE_FUN_4(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x1, complex_double x2, complex_double x3, complex_double x4, int flags) \ { \ return arb_fpwrap_cdouble_4(res, acb_fun, x1, x2, x3, x4, flags); \ } \ #define DEF_DOUBLE_FUN_1_INT(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x, int intx, int flags) \ { \ return arb_fpwrap_double_1_int(res, arb_fun, x, intx, flags); \ } \ #define DEF_DOUBLE_FUN_2_INT(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x1, double x2, int intx, int flags) \ { \ return arb_fpwrap_double_2_int(res, arb_fun, x1, x2, intx, flags); \ } \ #define DEF_DOUBLE_FUN_3_INT(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x1, double x2, double x3, int intx, int flags) \ { \ return arb_fpwrap_double_3_int(res, arb_fun, x1, x2, x3, intx, flags); \ } \ #define DEF_DOUBLE_FUN_4_INT(name, arb_fun) \ int arb_fpwrap_double_ ## name(double * res, double x1, double x2, double x3, double x4, int intx, int flags) \ { \ return arb_fpwrap_double_4_int(res, arb_fun, x1, x2, x3, x4, intx, flags); \ } \ #define DEF_CDOUBLE_FUN_1_INT(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x, int intx, int flags) \ { \ return arb_fpwrap_cdouble_1_int(res, acb_fun, x, intx, flags); \ } \ #define DEF_CDOUBLE_FUN_2_INT(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x1, complex_double x2, int intx, int flags) \ { \ return arb_fpwrap_cdouble_2_int(res, acb_fun, x1, x2, intx, flags); \ } \ #define DEF_CDOUBLE_FUN_3_INT(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x1, complex_double x2, complex_double x3, int intx, int flags) \ { \ return arb_fpwrap_cdouble_3_int(res, acb_fun, x1, x2, x3, intx, flags); \ } \ #define DEF_CDOUBLE_FUN_4_INT(name, acb_fun) \ int arb_fpwrap_cdouble_ ## name(complex_double * res, complex_double x1, complex_double x2, complex_double x3, complex_double x4, int intx, int flags) \ { \ return arb_fpwrap_cdouble_4_int(res, acb_fun, x1, x2, x3, x4, intx, flags); \ } \ DEF_DOUBLE_FUN_1(exp, arb_exp) DEF_CDOUBLE_FUN_1(exp, acb_exp) DEF_DOUBLE_FUN_1(expm1, arb_expm1) DEF_CDOUBLE_FUN_1(expm1, acb_expm1) DEF_DOUBLE_FUN_1(log, arb_log) DEF_CDOUBLE_FUN_1(log, acb_log) DEF_DOUBLE_FUN_1(log1p, arb_log1p) DEF_CDOUBLE_FUN_1(log1p, acb_log1p) DEF_DOUBLE_FUN_2(pow, arb_pow) DEF_CDOUBLE_FUN_2(pow, acb_pow) DEF_DOUBLE_FUN_1(sqrt, arb_sqrt) DEF_CDOUBLE_FUN_1(sqrt, acb_sqrt) DEF_DOUBLE_FUN_1(rsqrt, arb_rsqrt) DEF_CDOUBLE_FUN_1(rsqrt, acb_rsqrt) static void _arb_cbrt(arb_t res, const arb_t x, slong prec) { arb_root_ui(res, x, 3, prec); } static void _acb_cbrt(acb_t res, const acb_t x, slong prec) { acb_root_ui(res, x, 3, prec); } DEF_DOUBLE_FUN_1(cbrt, _arb_cbrt) DEF_CDOUBLE_FUN_1(cbrt, _acb_cbrt) DEF_DOUBLE_FUN_1(sin, arb_sin) DEF_CDOUBLE_FUN_1(sin, acb_sin) DEF_DOUBLE_FUN_1(cos, arb_cos) DEF_CDOUBLE_FUN_1(cos, acb_cos) DEF_DOUBLE_FUN_1(tan, arb_tan) DEF_CDOUBLE_FUN_1(tan, acb_tan) DEF_DOUBLE_FUN_1(cot, arb_cot) DEF_CDOUBLE_FUN_1(cot, acb_cot) DEF_DOUBLE_FUN_1(sec, arb_sec) DEF_CDOUBLE_FUN_1(sec, acb_sec) DEF_DOUBLE_FUN_1(csc, arb_csc) DEF_CDOUBLE_FUN_1(csc, acb_csc) DEF_DOUBLE_FUN_1(sinc, arb_sinc) DEF_CDOUBLE_FUN_1(sinc, acb_sinc) DEF_DOUBLE_FUN_1(sin_pi, arb_sin_pi) DEF_CDOUBLE_FUN_1(sin_pi, acb_sin_pi) DEF_DOUBLE_FUN_1(cos_pi, arb_cos_pi) DEF_CDOUBLE_FUN_1(cos_pi, acb_cos_pi) DEF_DOUBLE_FUN_1(tan_pi, arb_tan_pi) DEF_CDOUBLE_FUN_1(tan_pi, acb_tan_pi) DEF_DOUBLE_FUN_1(cot_pi, arb_cot_pi) DEF_CDOUBLE_FUN_1(cot_pi, acb_cot_pi) DEF_DOUBLE_FUN_1(sinc_pi, arb_sinc_pi) DEF_CDOUBLE_FUN_1(sinc_pi, acb_sinc_pi) DEF_DOUBLE_FUN_1(asin, arb_asin) DEF_CDOUBLE_FUN_1(asin, acb_asin) DEF_DOUBLE_FUN_1(acos, arb_acos) DEF_CDOUBLE_FUN_1(acos, acb_acos) DEF_DOUBLE_FUN_1(atan, arb_atan) DEF_CDOUBLE_FUN_1(atan, acb_atan) DEF_DOUBLE_FUN_2(atan2, arb_atan2) DEF_DOUBLE_FUN_1(asinh, arb_asinh) DEF_CDOUBLE_FUN_1(asinh, acb_asinh) DEF_DOUBLE_FUN_1(acosh, arb_acosh) DEF_CDOUBLE_FUN_1(acosh, acb_acosh) DEF_DOUBLE_FUN_1(atanh, arb_atanh) DEF_CDOUBLE_FUN_1(atanh, acb_atanh) DEF_DOUBLE_FUN_2(rising, arb_rising) DEF_CDOUBLE_FUN_2(rising, acb_rising) DEF_DOUBLE_FUN_1(gamma, arb_gamma) DEF_CDOUBLE_FUN_1(gamma, acb_gamma) DEF_DOUBLE_FUN_1(rgamma, arb_rgamma) DEF_CDOUBLE_FUN_1(rgamma, acb_rgamma) DEF_DOUBLE_FUN_1(lgamma, arb_lgamma) DEF_CDOUBLE_FUN_1(lgamma, acb_lgamma) DEF_DOUBLE_FUN_1(digamma, arb_digamma) DEF_CDOUBLE_FUN_1(digamma, acb_digamma) DEF_DOUBLE_FUN_1(zeta, arb_zeta) DEF_CDOUBLE_FUN_1(zeta, acb_zeta) DEF_DOUBLE_FUN_2(hurwitz_zeta, arb_hurwitz_zeta) DEF_CDOUBLE_FUN_2(hurwitz_zeta, acb_hurwitz_zeta) static void _arb_polygamma(arb_t res, const arb_t s, const arb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); acb_set_arb(t, s); acb_set_arb(u, z); acb_polygamma(v, t, u, prec); if (acb_is_real(v)) arb_set(res, acb_realref(v)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } static void _arb_barnes_g(arb_t res, const arb_t x, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_set_arb(t, x); acb_barnes_g(u, t, prec); arb_set(res, acb_realref(u)); acb_clear(t); acb_clear(u); } static void _arb_log_barnes_g(arb_t res, const arb_t x, slong prec) { if (!arb_is_positive(x)) { arb_indeterminate(res); } else { acb_t t, u; acb_init(t); acb_init(u); acb_set_arb(t, x); acb_log_barnes_g(u, t, prec); arb_set(res, acb_realref(u)); acb_clear(t); acb_clear(u); } } DEF_DOUBLE_FUN_1(barnes_g, _arb_barnes_g) DEF_CDOUBLE_FUN_1(barnes_g, acb_barnes_g) DEF_DOUBLE_FUN_1(log_barnes_g, _arb_log_barnes_g) DEF_CDOUBLE_FUN_1(log_barnes_g, acb_log_barnes_g) DEF_DOUBLE_FUN_2(polygamma, _arb_polygamma) DEF_CDOUBLE_FUN_2(polygamma, acb_polygamma) DEF_DOUBLE_FUN_2(polylog, arb_polylog) DEF_CDOUBLE_FUN_2(polylog, acb_polylog) DEF_DOUBLE_FUN_1(dilog, arb_hypgeom_dilog) DEF_CDOUBLE_FUN_1(dilog, acb_hypgeom_dilog) DEF_DOUBLE_FUN_1(erf, arb_hypgeom_erf) DEF_CDOUBLE_FUN_1(erf, acb_hypgeom_erf) DEF_DOUBLE_FUN_1(erfc, arb_hypgeom_erfc) DEF_CDOUBLE_FUN_1(erfc, acb_hypgeom_erfc) DEF_DOUBLE_FUN_1(erfi, arb_hypgeom_erfi) DEF_CDOUBLE_FUN_1(erfi, acb_hypgeom_erfi) DEF_DOUBLE_FUN_1(erfinv, arb_hypgeom_erfinv) DEF_DOUBLE_FUN_1(erfcinv, arb_hypgeom_erfcinv) static void _arb_hypgeom_fresnel_s(arb_t res, const arb_t x, int normalized, slong prec) { arb_hypgeom_fresnel(res, NULL, x, normalized, prec); } static void _arb_hypgeom_fresnel_c(arb_t res, const arb_t x, int normalized, slong prec) { arb_hypgeom_fresnel(NULL, res, x, normalized, prec); } static void _acb_hypgeom_fresnel_s(acb_t res, const acb_t x, int normalized, slong prec) { acb_hypgeom_fresnel(res, NULL, x, normalized, prec); } static void _acb_hypgeom_fresnel_c(acb_t res, const acb_t x, int normalized, slong prec) { acb_hypgeom_fresnel(NULL, res, x, normalized, prec); } DEF_DOUBLE_FUN_1_INT(fresnel_s, _arb_hypgeom_fresnel_s) DEF_CDOUBLE_FUN_1_INT(fresnel_s, _acb_hypgeom_fresnel_s) DEF_DOUBLE_FUN_1_INT(fresnel_c, _arb_hypgeom_fresnel_c) DEF_CDOUBLE_FUN_1_INT(fresnel_c, _acb_hypgeom_fresnel_c) DEF_DOUBLE_FUN_2_INT(gamma_upper, arb_hypgeom_gamma_upper) DEF_CDOUBLE_FUN_2_INT(gamma_upper, acb_hypgeom_gamma_upper) DEF_DOUBLE_FUN_2_INT(gamma_lower, arb_hypgeom_gamma_lower) DEF_CDOUBLE_FUN_2_INT(gamma_lower, acb_hypgeom_gamma_lower) DEF_DOUBLE_FUN_3_INT(beta_lower, arb_hypgeom_beta_lower) DEF_CDOUBLE_FUN_3_INT(beta_lower, acb_hypgeom_beta_lower) DEF_DOUBLE_FUN_2(exp_integral_e, arb_hypgeom_expint) DEF_CDOUBLE_FUN_2(exp_integral_e, acb_hypgeom_expint) DEF_DOUBLE_FUN_1(exp_integral_ei, arb_hypgeom_ei) DEF_CDOUBLE_FUN_1(exp_integral_ei, acb_hypgeom_ei) DEF_DOUBLE_FUN_1(sin_integral, arb_hypgeom_si) DEF_CDOUBLE_FUN_1(sin_integral, acb_hypgeom_si) DEF_DOUBLE_FUN_1(cos_integral, arb_hypgeom_ci) DEF_CDOUBLE_FUN_1(cos_integral, acb_hypgeom_ci) DEF_DOUBLE_FUN_1(sinh_integral, arb_hypgeom_shi) DEF_CDOUBLE_FUN_1(sinh_integral, acb_hypgeom_shi) DEF_DOUBLE_FUN_1(cosh_integral, arb_hypgeom_chi) DEF_CDOUBLE_FUN_1(cosh_integral, acb_hypgeom_chi) DEF_DOUBLE_FUN_1_INT(log_integral, arb_hypgeom_li) DEF_CDOUBLE_FUN_1_INT(log_integral, acb_hypgeom_li) DEF_DOUBLE_FUN_2(bessel_j, arb_hypgeom_bessel_j) DEF_CDOUBLE_FUN_2(bessel_j, acb_hypgeom_bessel_j) DEF_DOUBLE_FUN_2(bessel_y, arb_hypgeom_bessel_y) DEF_CDOUBLE_FUN_2(bessel_y, acb_hypgeom_bessel_y) DEF_DOUBLE_FUN_2(bessel_i, arb_hypgeom_bessel_i) DEF_CDOUBLE_FUN_2(bessel_i, acb_hypgeom_bessel_i) DEF_DOUBLE_FUN_2(bessel_k, arb_hypgeom_bessel_k) DEF_CDOUBLE_FUN_2(bessel_k, acb_hypgeom_bessel_k) DEF_DOUBLE_FUN_2(bessel_k_scaled, arb_hypgeom_bessel_k_scaled) DEF_CDOUBLE_FUN_2(bessel_k_scaled, acb_hypgeom_bessel_k_scaled) static void _arb_hypgeom_airy_ai(arb_t res, const arb_t x, slong prec) { arb_hypgeom_airy(res, NULL, NULL, NULL, x, prec); } static void _arb_hypgeom_airy_ai_prime(arb_t res, const arb_t x, slong prec) { arb_hypgeom_airy(NULL, res, NULL, NULL, x, prec); } static void _arb_hypgeom_airy_bi(arb_t res, const arb_t x, slong prec) { arb_hypgeom_airy(NULL, NULL, res, NULL, x, prec); } static void _arb_hypgeom_airy_bi_prime(arb_t res, const arb_t x, slong prec) { arb_hypgeom_airy(NULL, NULL, NULL, res, x, prec); } static void _acb_hypgeom_airy_ai(acb_t res, const acb_t x, slong prec) { acb_hypgeom_airy(res, NULL, NULL, NULL, x, prec); } static void _acb_hypgeom_airy_ai_prime(acb_t res, const acb_t x, slong prec) { acb_hypgeom_airy(NULL, res, NULL, NULL, x, prec); } static void _acb_hypgeom_airy_bi(acb_t res, const acb_t x, slong prec) { acb_hypgeom_airy(NULL, NULL, res, NULL, x, prec); } static void _acb_hypgeom_airy_bi_prime(acb_t res, const acb_t x, slong prec) { acb_hypgeom_airy(NULL, NULL, NULL, res, x, prec); } DEF_DOUBLE_FUN_1(airy_ai, _arb_hypgeom_airy_ai) DEF_CDOUBLE_FUN_1(airy_ai, _acb_hypgeom_airy_ai) DEF_DOUBLE_FUN_1(airy_ai_prime, _arb_hypgeom_airy_ai_prime) DEF_CDOUBLE_FUN_1(airy_ai_prime, _acb_hypgeom_airy_ai_prime) DEF_DOUBLE_FUN_1(airy_bi, _arb_hypgeom_airy_bi) DEF_CDOUBLE_FUN_1(airy_bi, _acb_hypgeom_airy_bi) DEF_DOUBLE_FUN_1(airy_bi_prime, _arb_hypgeom_airy_bi_prime) DEF_CDOUBLE_FUN_1(airy_bi_prime, _acb_hypgeom_airy_bi_prime) static void _arb_hypgeom_coulomb_f(arb_t res, const arb_t l, const arb_t eta, const arb_t z, slong prec) { arb_hypgeom_coulomb(res, NULL, l, eta, z, prec); } static void _arb_hypgeom_coulomb_g(arb_t res, const arb_t l, const arb_t eta, const arb_t z, slong prec) { arb_hypgeom_coulomb(NULL, res, l, eta, z, prec); } static void _acb_hypgeom_coulomb_f(acb_t res, const acb_t l, const acb_t eta, const acb_t z, slong prec) { acb_hypgeom_coulomb(res, NULL, NULL, NULL, l, eta, z, prec); } static void _acb_hypgeom_coulomb_g(acb_t res, const acb_t l, const acb_t eta, const acb_t z, slong prec) { acb_hypgeom_coulomb(NULL, res, NULL, NULL, l, eta, z, prec); } static void _acb_hypgeom_coulomb_hpos(acb_t res, const acb_t l, const acb_t eta, const acb_t z, slong prec) { acb_hypgeom_coulomb(NULL, NULL, res, NULL, l, eta, z, prec); } static void _acb_hypgeom_coulomb_hneg(acb_t res, const acb_t l, const acb_t eta, const acb_t z, slong prec) { acb_hypgeom_coulomb(NULL, NULL, NULL, res, l, eta, z, prec); } DEF_DOUBLE_FUN_3(coulomb_f, _arb_hypgeom_coulomb_f) DEF_CDOUBLE_FUN_3(coulomb_f, _acb_hypgeom_coulomb_f) DEF_DOUBLE_FUN_3(coulomb_g, _arb_hypgeom_coulomb_g) DEF_CDOUBLE_FUN_3(coulomb_g, _acb_hypgeom_coulomb_g) DEF_CDOUBLE_FUN_3(coulomb_hpos, _acb_hypgeom_coulomb_hpos) DEF_CDOUBLE_FUN_3(coulomb_hneg, _acb_hypgeom_coulomb_hneg) DEF_DOUBLE_FUN_2(chebyshev_t, arb_hypgeom_chebyshev_t) DEF_CDOUBLE_FUN_2(chebyshev_t, acb_hypgeom_chebyshev_t) DEF_DOUBLE_FUN_2(chebyshev_u, arb_hypgeom_chebyshev_u) DEF_CDOUBLE_FUN_2(chebyshev_u, acb_hypgeom_chebyshev_u) DEF_DOUBLE_FUN_4(jacobi_p, arb_hypgeom_jacobi_p) DEF_CDOUBLE_FUN_4(jacobi_p, acb_hypgeom_jacobi_p) DEF_DOUBLE_FUN_3(gegenbauer_c, arb_hypgeom_gegenbauer_c) DEF_CDOUBLE_FUN_3(gegenbauer_c, acb_hypgeom_gegenbauer_c) DEF_DOUBLE_FUN_3(laguerre_l, arb_hypgeom_laguerre_l) DEF_CDOUBLE_FUN_3(laguerre_l, acb_hypgeom_laguerre_l) DEF_DOUBLE_FUN_2(hermite_h, arb_hypgeom_hermite_h) DEF_CDOUBLE_FUN_2(hermite_h, acb_hypgeom_hermite_h) DEF_DOUBLE_FUN_3_INT(legendre_p, arb_hypgeom_legendre_p) DEF_CDOUBLE_FUN_3_INT(legendre_p, acb_hypgeom_legendre_p) DEF_DOUBLE_FUN_3_INT(legendre_q, arb_hypgeom_legendre_q) DEF_CDOUBLE_FUN_3_INT(legendre_q, acb_hypgeom_legendre_q) int arb_fpwrap_cdouble_spherical_y(complex_double * res, slong n, slong m, complex_double x1, complex_double x2, int flags) { acb_t acb_res, acb_x1, acb_x2; slong wp; int status; acb_init(acb_res); acb_init(acb_x1); acb_init(acb_x2); acb_set_d_d(acb_x1, x1.real, x1.imag); acb_set_d_d(acb_x2, x2.real, x2.imag); if (!acb_is_finite(acb_x1) || !acb_is_finite(acb_x2)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { acb_hypgeom_spherical_y(acb_res, n, m, acb_x1, acb_x2, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x1); acb_clear(acb_x2); acb_clear(acb_res); return status; } DEF_DOUBLE_FUN_2_INT(hypgeom_0f1, arb_hypgeom_0f1) DEF_CDOUBLE_FUN_2_INT(hypgeom_0f1, acb_hypgeom_0f1) DEF_DOUBLE_FUN_3_INT(hypgeom_1f1, arb_hypgeom_1f1) DEF_CDOUBLE_FUN_3_INT(hypgeom_1f1, acb_hypgeom_1f1) DEF_DOUBLE_FUN_3(hypgeom_u, arb_hypgeom_u) DEF_CDOUBLE_FUN_3(hypgeom_u, acb_hypgeom_u) DEF_DOUBLE_FUN_4_INT(hypgeom_2f1, arb_hypgeom_2f1) DEF_CDOUBLE_FUN_4_INT(hypgeom_2f1, acb_hypgeom_2f1) int arb_fpwrap_double_hypgeom_pfq(double * res, const double * a, slong p, const double * b, slong q, double z, int regularized, int flags) { arb_t arb_res; arb_ptr t; slong wp; slong i; int status; arb_init(arb_res); t = _arb_vec_init(p + q + 1); for (i = 0; i < p; i++) arb_set_d(t + i, a[i]); for (i = 0; i < q; i++) arb_set_d(t + p + i, b[i]); arb_set_d(t + p + q, z); if (!_arb_vec_is_finite(t, p + q + 1)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { arb_hypgeom_pfq(arb_res, t, p, t + p, q, t + p + q, regularized, wp); DOUBLE_CHECK_RESULT } } _arb_vec_clear(t, p + q + 1); arb_clear(arb_res); return status; } int arb_fpwrap_cdouble_hypgeom_pfq(complex_double * res, const complex_double * a, slong p, const complex_double * b, slong q, complex_double z, int regularized, int flags) { acb_t acb_res; acb_ptr t; slong wp; slong i; int status; acb_init(acb_res); t = _acb_vec_init(p + q + 1); for (i = 0; i < p; i++) acb_set_d_d(t + i, a[i].real, a[i].imag); for (i = 0; i < q; i++) acb_set_d_d(t + p + i, b[i].real, b[i].imag); acb_set_d_d(t + p + q, z.real, z.imag); if (!_acb_vec_is_finite(t, p + q + 1)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { acb_hypgeom_pfq(acb_res, t, p, t + p, q, t + p + q, regularized, wp); CDOUBLE_CHECK_RESULT } } _acb_vec_clear(t, p + q + 1); acb_clear(acb_res); return status; } DEF_DOUBLE_FUN_2(agm, arb_agm) DEF_CDOUBLE_FUN_2(agm, acb_agm) DEF_CDOUBLE_FUN_1(elliptic_k, acb_elliptic_k) DEF_CDOUBLE_FUN_1(elliptic_e, acb_elliptic_e) DEF_CDOUBLE_FUN_2(elliptic_pi, acb_elliptic_pi) DEF_CDOUBLE_FUN_2_INT(elliptic_f, acb_elliptic_f) DEF_CDOUBLE_FUN_2_INT(elliptic_e_inc, acb_elliptic_e_inc) DEF_CDOUBLE_FUN_3_INT(elliptic_pi_inc, acb_elliptic_pi_inc) DEF_CDOUBLE_FUN_3_INT(elliptic_rf, acb_elliptic_rf) DEF_CDOUBLE_FUN_3_INT(elliptic_rg, acb_elliptic_rg) DEF_CDOUBLE_FUN_4_INT(elliptic_rj, acb_elliptic_rj) DEF_CDOUBLE_FUN_2(elliptic_p, acb_elliptic_p) DEF_CDOUBLE_FUN_2(elliptic_p_prime, acb_elliptic_p_prime) DEF_CDOUBLE_FUN_2(elliptic_inv_p, acb_elliptic_inv_p) DEF_CDOUBLE_FUN_2(elliptic_zeta, acb_elliptic_zeta) DEF_CDOUBLE_FUN_2(elliptic_sigma, acb_elliptic_sigma) static void _acb_theta1(acb_t res, const acb_t z, const acb_t tau, slong prec) { acb_t a, b, c; acb_init(a); acb_init(b); acb_init(c); acb_modular_theta(res, a, b, c, z, tau, prec); acb_clear(a); acb_clear(b); acb_clear(c); } static void _acb_theta2(acb_t res, const acb_t z, const acb_t tau, slong prec) { acb_t a, b, c; acb_init(a); acb_init(b); acb_init(c); acb_modular_theta(a, res, b, c, z, tau, prec); acb_clear(a); acb_clear(b); acb_clear(c); } static void _acb_theta3(acb_t res, const acb_t z, const acb_t tau, slong prec) { acb_t a, b, c; acb_init(a); acb_init(b); acb_init(c); acb_modular_theta(a, b, res, c, z, tau, prec); acb_clear(a); acb_clear(b); acb_clear(c); } static void _acb_theta4(acb_t res, const acb_t z, const acb_t tau, slong prec) { acb_t a, b, c; acb_init(a); acb_init(b); acb_init(c); acb_modular_theta(a, b, c, res, z, tau, prec); acb_clear(a); acb_clear(b); acb_clear(c); } DEF_CDOUBLE_FUN_2(jacobi_theta_1, _acb_theta1) DEF_CDOUBLE_FUN_2(jacobi_theta_2, _acb_theta2) DEF_CDOUBLE_FUN_2(jacobi_theta_3, _acb_theta3) DEF_CDOUBLE_FUN_2(jacobi_theta_4, _acb_theta4) DEF_CDOUBLE_FUN_1(dedekind_eta, acb_modular_eta) DEF_CDOUBLE_FUN_1(modular_j, acb_modular_j) DEF_CDOUBLE_FUN_1(modular_lambda, acb_modular_lambda) DEF_CDOUBLE_FUN_1(modular_delta, acb_modular_delta) DEF_CDOUBLE_FUN_1(dirichlet_eta, acb_dirichlet_eta) DEF_CDOUBLE_FUN_1(riemann_xi, acb_dirichlet_xi) static void _acb_hardy_theta(acb_t res, const acb_t t, slong prec) { acb_dirichlet_hardy_theta(res, t, NULL, NULL, 1, prec); } static void _acb_hardy_z(acb_t res, const acb_t t, slong prec) { acb_dirichlet_hardy_z(res, t, NULL, NULL, 1, prec); } DEF_CDOUBLE_FUN_1(hardy_theta, _acb_hardy_theta) DEF_CDOUBLE_FUN_1(hardy_z, _acb_hardy_z) int arb_fpwrap_cdouble_zeta_zero(complex_double * res, ulong n, int flags) { fmpz_t t; acb_t acb_res; slong wp; int status; if (n == 0) { res->real = D_NAN; res->imag = D_NAN; return FPWRAP_UNABLE; } acb_init(acb_res); fmpz_init(t); fmpz_set_ui(t, n); for (wp = WP_INITIAL; ; wp *= 2) { acb_dirichlet_zeta_zero(acb_res, t, wp); CDOUBLE_CHECK_RESULT } acb_clear(acb_res); return status; } int arb_fpwrap_double_legendre_root(double * res1, double * res2, ulong n, ulong k, int flags) { arb_t arb_res1, arb_res2; slong wp; int status; if (k >= n) { *res1 = D_NAN; *res2 = D_NAN; return FPWRAP_UNABLE; } arb_init(arb_res1); arb_init(arb_res2); for (wp = WP_INITIAL; ; wp *= 2) { arb_hypgeom_legendre_p_ui_root(arb_res1, arb_res2, n, k, wp); DOUBLE_CHECK_RESULT2 } arb_clear(arb_res1); arb_clear(arb_res2); return status; } int _arb_fpwrap_double_airy_zero(double * res, ulong n, int which, int flags) { fmpz_t t; arb_t arb_res; slong wp; int status; if (n == 0) { *res = D_NAN; return FPWRAP_UNABLE; } arb_init(arb_res); fmpz_init(t); fmpz_set_ui(t, n); for (wp = WP_INITIAL; ; wp *= 2) { if (which == 0) arb_hypgeom_airy_zero(arb_res, NULL, NULL, NULL, t, wp); else if (which == 1) arb_hypgeom_airy_zero(NULL, arb_res, NULL, NULL, t, wp); else if (which == 2) arb_hypgeom_airy_zero(NULL, NULL, arb_res, NULL, t, wp); else arb_hypgeom_airy_zero(NULL, NULL, NULL, arb_res, t, wp); DOUBLE_CHECK_RESULT } arb_clear(arb_res); fmpz_clear(t); return status; } int arb_fpwrap_double_airy_ai_zero(double * res, ulong n, int flags) { return _arb_fpwrap_double_airy_zero(res, n, 0, flags); } int arb_fpwrap_double_airy_ai_prime_zero(double * res, ulong n, int flags) { return _arb_fpwrap_double_airy_zero(res, n, 1, flags); } int arb_fpwrap_double_airy_bi_zero(double * res, ulong n, int flags) { return _arb_fpwrap_double_airy_zero(res, n, 2, flags); } int arb_fpwrap_double_airy_bi_prime_zero(double * res, ulong n, int flags) { return _arb_fpwrap_double_airy_zero(res, n, 3, flags); } int arb_fpwrap_double_lambertw(double * res, double x, slong branch, int flags) { arb_t arb_res, arb_x; slong wp; int status; arb_init(arb_res); arb_init(arb_x); arb_set_d(arb_x, x); if (!arb_is_finite(arb_x) || !(branch == 0 || branch == -1)) { *res = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { arb_lambertw(arb_res, arb_x, (branch == -1), wp); DOUBLE_CHECK_RESULT } } arb_clear(arb_x); arb_clear(arb_res); return status; } int arb_fpwrap_cdouble_lambertw(complex_double * res, complex_double x, slong branch, int flags) { fmpz_t t; acb_t acb_res, acb_x; slong wp; int status; acb_init(acb_res); acb_init(acb_x); fmpz_init(t); acb_set_d_d(acb_x, x.real, x.imag); fmpz_set_si(t, branch); if (!acb_is_finite(acb_x)) { res->real = D_NAN; res->imag = D_NAN; status = FPWRAP_UNABLE; } else { for (wp = WP_INITIAL; ; wp *= 2) { acb_lambertw(acb_res, acb_x, t, 0, wp); CDOUBLE_CHECK_RESULT } } acb_clear(acb_x); acb_clear(acb_res); fmpz_clear(t); return status; } /* todo: functions with multiple outputs */ /* todo: elliptic invariants, roots */ /* todo: eisenstein series */ /* todo: dirichlet functions requiring characters */ arb-2.22.1/arb_fpwrap/test/000077500000000000000000000000001417376376500154675ustar00rootroot00000000000000arb-2.22.1/arb_fpwrap/test/t-fpwrap.c000066400000000000000000000446071417376376500174060ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arb_fpwrap.h" #define CHECK_DOUBLE(fcall) \ do { \ int fail = fcall; \ if (fail || res != res) \ { \ flint_printf("FAIL\n"); \ flint_printf("%d\n", __LINE__); \ flint_abort(); \ } \ } while (0) #define CHECK_CDOUBLE(fcall) \ do { \ int fail = fcall; \ if (fail || cres.real != cres.real || cres.imag != cres.imag) \ { \ flint_printf("FAIL\n"); \ flint_printf("%d\n", __LINE__); \ flint_abort(); \ } \ } while (0) int main() { slong iter; flint_rand_t state; flint_printf("fpwrap...."); fflush(stdout); flint_randinit(state); /* correct rounding test */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mpfr_t t; double x, y, z; mpfr_init2(t, 53); x = d_randtest(state) + n_randint(state, 100); mpfr_set_d(t, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: arb_fpwrap_double_log1p(&y, x, FPWRAP_CORRECT_ROUNDING); mpfr_log1p(t, t, MPFR_RNDN); break; case 1: arb_fpwrap_double_sqrt(&y, x, FPWRAP_CORRECT_ROUNDING); mpfr_sqrt(t, t, MPFR_RNDN); break; case 2: arb_fpwrap_double_exp(&y, x, FPWRAP_CORRECT_ROUNDING); mpfr_exp(t, t, MPFR_RNDN); break; default: arb_fpwrap_double_sin(&y, x, FPWRAP_CORRECT_ROUNDING); mpfr_sin(t, t, MPFR_RNDN); break; } z = mpfr_get_d(t, MPFR_RNDN); if (z != y) { flint_printf("FAIL: correct rounding\n\n"); flint_abort(); } mpfr_clear(t); } { double a[1], b[2]; double z, y; z = 1.75; a[0] = 0.25; b[0] = 1.5; b[1] = -2.125; arb_fpwrap_double_hypgeom_pfq(&y, a, 1, b, 2, z, 0, 0); if (fabs(y - 0.68910385124070327187) > 1e-16) { flint_printf("FAIL: value 1\n\n"); flint_abort(); } arb_fpwrap_double_hypgeom_pfq(&y, a, 1, b, 2, z, 1, 0); if (fabs(y - (-0.21324224371323783595)) > 1e-16) { flint_printf("FAIL: value 2\n\n"); flint_abort(); } } { complex_double y, z; arb_fpwrap_cdouble_zeta_zero(&y, 1, FPWRAP_CORRECT_ROUNDING); arb_fpwrap_cdouble_zeta(&z, y, 0); if (fabs(z.real - (-1.0483650805588237388e-16)) > 1e-31) { flint_printf("FAIL: value 3\n\n"); flint_abort(); } if (fabs(z.imag - 6.5852592776051578103e-16) > 1e-31) { flint_printf("FAIL: value 4\n\n"); flint_abort(); } } { complex_double x, y; x.real = 1.0; x.imag = 1e-100; arb_fpwrap_cdouble_erf(&y, x, FPWRAP_ACCURATE_PARTS); if (fabs(y.imag - 4.1510749742059471164e-101) > 1e-116) { flint_printf("FAIL: value 5\n\n"); flint_abort(); } } { double y; arb_fpwrap_double_hypgeom_2f1(&y, 0.1, 0.2, 0.3, 0.4, 0, FPWRAP_CORRECT_ROUNDING); if (fabs(y - 1.0341794015503748492) > 1e-16) { flint_printf("FAIL: value 6\n\n"); flint_abort(); } arb_fpwrap_double_hypgeom_2f1(&y, 0.1, 0.2, 0.3, 0.4, 1, FPWRAP_CORRECT_ROUNDING); if (fabs(y - 0.34569799520143110351) > 1e-16) { flint_printf("FAIL: value 6\n\n"); flint_abort(); } } { double x, y, z; complex_double cx, cy, cz, ctau; double res, res2; complex_double cres; int flags; x = 0.25; y = 0.625; z = 0.75; cx.real = 0.25; cx.imag = 0.125; cy.real = 0.5; cy.imag = 0.625; cz.real = 0.75; cz.imag = 0.125; ctau.real = 0.25; ctau.imag = 1.0; flags = 0; CHECK_DOUBLE(arb_fpwrap_double_exp(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_exp(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_expm1(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_expm1(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_log(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_log(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_log1p(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_log1p(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_pow(&res, x, y, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_pow(&cres, cx, cy, flags)); CHECK_DOUBLE(arb_fpwrap_double_sqrt(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sqrt(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_rsqrt(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_rsqrt(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_cbrt(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_cbrt(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_sin(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sin(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_cos(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_cos(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_tan(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_tan(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_cot(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_cot(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_sec(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sec(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_csc(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_csc(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_sinc(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sinc(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_sin_pi(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sin_pi(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_cos_pi(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_cos_pi(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_tan_pi(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_tan_pi(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_cot_pi(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_cot_pi(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_sinc_pi(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sinc_pi(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_asin(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_asin(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_acos(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_acos(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_atan(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_atan(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_atan2(&res, x, y, flags)); CHECK_DOUBLE(arb_fpwrap_double_asinh(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_asinh(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_acosh(&res, 1.0 + x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_acosh(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_atanh(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_atanh(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_lambertw(&res, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_lambertw(&cres, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_lambertw(&res, -0.2, -1, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_lambertw(&cres, cx, -1, flags)); CHECK_DOUBLE(arb_fpwrap_double_rising(&res, x, y, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_rising(&cres, cx, cy, flags)); CHECK_DOUBLE(arb_fpwrap_double_gamma(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_gamma(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_rgamma(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_rgamma(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_lgamma(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_lgamma(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_digamma(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_digamma(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_zeta(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_zeta(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_hurwitz_zeta(&res, x, z, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hurwitz_zeta(&cres, cx, cz, flags)); CHECK_DOUBLE(arb_fpwrap_double_barnes_g(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_barnes_g(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_log_barnes_g(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_log_barnes_g(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_polygamma(&res, x, z, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_polygamma(&cres, cx, cz, flags)); CHECK_DOUBLE(arb_fpwrap_double_polylog(&res, x, z, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_polylog(&cres, cx, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_dirichlet_eta(&cres, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_riemann_xi(&cres, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hardy_theta(&cres, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hardy_z(&cres, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_zeta_zero(&cres, 2, flags)); CHECK_DOUBLE(arb_fpwrap_double_erf(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_erf(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_erfc(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_erfc(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_erfi(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_erfi(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_erfinv(&res, x, flags)); CHECK_DOUBLE(arb_fpwrap_double_erfcinv(&res, x, flags)); CHECK_DOUBLE(arb_fpwrap_double_fresnel_s(&res, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_fresnel_s(&cres, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_fresnel_c(&res, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_fresnel_c(&cres, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_gamma_upper(&res, x, z, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_gamma_upper(&cres, cx, cz, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_gamma_lower(&res, x, z, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_gamma_lower(&cres, cx, cz, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_beta_lower(&res, x, y, z, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_beta_lower(&cres, cx, cy, cz, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_exp_integral_e(&res, x, z, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_exp_integral_e(&cres, cx, cz, flags)); CHECK_DOUBLE(arb_fpwrap_double_exp_integral_ei(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_exp_integral_ei(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_sin_integral(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sin_integral(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_cos_integral(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_cos_integral(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_sinh_integral(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_sinh_integral(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_cosh_integral(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_cosh_integral(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_log_integral(&res, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_log_integral(&cres, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_bessel_j(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_bessel_j(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_bessel_y(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_bessel_y(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_bessel_i(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_bessel_i(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_bessel_k(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_bessel_k(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_bessel_k_scaled(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_bessel_k_scaled(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_ai(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_airy_ai(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_ai_prime(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_airy_ai_prime(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_bi(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_airy_bi(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_bi_prime(&res, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_airy_bi_prime(&cres, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_ai_zero(&res, 1, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_ai_prime_zero(&res, 1, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_bi_zero(&res, 1, flags)); CHECK_DOUBLE(arb_fpwrap_double_airy_bi_prime_zero(&res, 1, flags)); CHECK_DOUBLE(arb_fpwrap_double_coulomb_f(&res, y, z, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_coulomb_f(&cres, cy, cz, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_coulomb_g(&res, y, z, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_coulomb_g(&cres, cy, cz, cx, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_coulomb_hpos(&cres, cy, cz, cx, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_coulomb_hneg(&cres, cy, cz, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_chebyshev_t(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_chebyshev_t(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_chebyshev_u(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_chebyshev_u(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_jacobi_p(&res, y, x, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_jacobi_p(&cres, cy, cx, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_gegenbauer_c(&res, y, z, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_gegenbauer_c(&cres, cy, cz, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_laguerre_l(&res, y, z, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_laguerre_l(&cres, cy, cz, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_hermite_h(&res, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hermite_h(&cres, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_legendre_p(&res, y, z, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_legendre_p(&cres, cy, cz, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_legendre_q(&res, y, z, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_legendre_q(&cres, cy, cz, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_legendre_root(&res, &res2, 2, 1, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_spherical_y(&cres, 2, 1, cx, cy, flags)); CHECK_DOUBLE(arb_fpwrap_double_hypgeom_0f1(&res, y, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hypgeom_0f1(&cres, cy, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_hypgeom_1f1(&res, x, y, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hypgeom_1f1(&cres, cx, cy, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_hypgeom_u(&res, x, y, x, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hypgeom_u(&cres, cx, cy, cx, flags)); CHECK_DOUBLE(arb_fpwrap_double_hypgeom_2f1(&res, x, y, z, x, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hypgeom_2f1(&cres, cx, cy, cz, cx, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_hypgeom_pfq(&res, &x, 1, &y, 1, z, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_hypgeom_pfq(&cres, &cx, 1, &cy, 1, cz, 0, flags)); CHECK_DOUBLE(arb_fpwrap_double_agm(&res, x, y, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_agm(&cres, cx, cy, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_k(&cres, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_e(&cres, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_pi(&cres, cy, cz, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_f(&cres, cx, cz, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_e_inc(&cres, cx, cz, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_pi_inc(&cres, cx, cy, cz, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_rf(&cres, cx, cy, cz, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_rg(&cres, cx, cy, cz, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_rj(&cres, cx, cy, cz, cx, 0, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_p(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_p_prime(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_inv_p(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_zeta(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_elliptic_sigma(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_jacobi_theta_1(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_jacobi_theta_2(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_jacobi_theta_3(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_jacobi_theta_4(&cres, cz, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_dedekind_eta(&cres, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_modular_j(&cres, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_modular_lambda(&cres, ctau, flags)); CHECK_CDOUBLE(arb_fpwrap_cdouble_modular_delta(&cres, ctau, flags)); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom.h000066400000000000000000000331251417376376500150360ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARB_HYPGEOM_H #define ARB_HYPGEOM_H #include "arb.h" #include "arb_poly.h" #ifdef __cplusplus extern "C" { #endif void _arb_hypgeom_rising_coeffs_1(ulong * c, ulong k, slong l); void _arb_hypgeom_rising_coeffs_2(ulong * c, ulong k, slong l); void _arb_hypgeom_rising_coeffs_fmpz(fmpz * c, ulong k, slong l); void arb_hypgeom_rising_ui_forward(arb_t res, const arb_t x, ulong n, slong prec); void arb_hypgeom_rising_ui_rs(arb_t res, const arb_t x, ulong n, ulong m, slong prec); void arb_hypgeom_rising_ui_bs(arb_t res, const arb_t x, ulong n, slong prec); void arb_hypgeom_rising_ui_rec(arb_t res, const arb_t x, ulong n, slong prec); void arb_hypgeom_rising_ui(arb_t y, const arb_t x, ulong n, slong prec); void arb_hypgeom_rising(arb_t y, const arb_t x, const arb_t n, slong prec); void arb_hypgeom_rising_ui_jet_powsum(arb_ptr res, const arb_t x, ulong n, slong len, slong prec); void arb_hypgeom_rising_ui_jet_rs(arb_ptr res, const arb_t x, ulong n, ulong m, slong len, slong prec); void arb_hypgeom_rising_ui_jet_bs(arb_ptr res, const arb_t x, ulong n, slong len, slong prec); void arb_hypgeom_rising_ui_jet(arb_ptr res, const arb_t x, ulong n, slong len, slong prec); void _arb_hypgeom_gamma_stirling_term_bounds(slong * bound, const mag_t zinv, slong N); void arb_hypgeom_gamma_stirling_sum_horner(arb_t s, const arb_t z, slong N, slong prec); void arb_hypgeom_gamma_stirling_sum_improved(arb_t s, const arb_t z, slong N, slong K, slong prec); #define ARB_HYPGEOM_GAMMA_TAB_NUM 536 #define ARB_HYPGEOM_GAMMA_TAB_PREC 3456 typedef struct { short exp; short tab_pos; char nlimbs; char negative; } arb_hypgeom_gamma_coeff_t; ARB_DLL extern arb_hypgeom_gamma_coeff_t arb_hypgeom_gamma_coeffs[ARB_HYPGEOM_GAMMA_TAB_NUM]; int _arb_hypgeom_gamma_coeff_shallow(arf_t c, mag_t err, slong i, slong prec); void arb_hypgeom_gamma_stirling(arb_t res, const arb_t x, int reciprocal, slong prec); int arb_hypgeom_gamma_taylor(arb_t res, const arb_t x, int reciprocal, slong prec); void arb_hypgeom_gamma(arb_t y, const arb_t x, slong prec); void arb_hypgeom_rgamma(arb_t y, const arb_t x, slong prec); void arb_hypgeom_lgamma(arb_t y, const arb_t x, slong prec); void arb_hypgeom_gamma_fmpq(arb_t y, const fmpq_t x, slong prec); void arb_hypgeom_gamma_fmpz(arb_t y, const fmpz_t x, slong prec); void arb_hypgeom_pfq(arb_t res, arb_srcptr a, slong p, arb_srcptr b, slong q, const arb_t z, int regularized, slong prec); void arb_hypgeom_0f1(arb_t res, const arb_t a, const arb_t z, int regularized, slong prec); void arb_hypgeom_m(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec); void arb_hypgeom_1f1(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec); void arb_hypgeom_u(arb_t res, const arb_t a, const arb_t b, const arb_t z, slong prec); void arb_hypgeom_2f1(arb_t res, const arb_t a, const arb_t b, const arb_t c, const arb_t z, int regularized, slong prec); void arb_hypgeom_1f1_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec); void arb_hypgeom_u_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, slong prec); void arb_hypgeom_2f1_integration(arb_t res, const arb_t a, const arb_t b, const arb_t c, const arb_t z, int regularized, slong prec); void arb_hypgeom_erf(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_erf_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_erf_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void arb_hypgeom_erfc(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_erfc_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_erfc_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void arb_hypgeom_erfi(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_erfi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_erfi_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void arb_hypgeom_erfinv(arb_t res, const arb_t x, slong prec); void arb_hypgeom_erfcinv(arb_t res, const arb_t x, slong prec); void arb_hypgeom_fresnel(arb_t res1, arb_t res2, const arb_t z, int normalized, slong prec); void _arb_hypgeom_fresnel_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, int normalized, slong len, slong prec); void arb_hypgeom_fresnel_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, int normalized, slong len, slong prec); void arb_hypgeom_ei(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_ei_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_ei_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void _arb_hypgeom_si_asymp(arb_t res, const arb_t z, slong N, slong prec); void _arb_hypgeom_si_1f2(arb_t res, const arb_t z, slong N, slong wp, slong prec); void arb_hypgeom_si(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_si_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_si_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void _arb_hypgeom_ci_asymp(arb_t res, const arb_t z, slong N, slong prec); void _arb_hypgeom_ci_2f3(arb_t res, const arb_t z, slong N, slong wp, slong prec); void arb_hypgeom_ci(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_ci_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_ci_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void arb_hypgeom_shi(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_shi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_shi_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void arb_hypgeom_chi(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_chi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_hypgeom_chi_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec); void arb_hypgeom_li(arb_t res, const arb_t z, int offset, slong prec); void _arb_hypgeom_li_series(arb_ptr g, arb_srcptr h, slong hlen, int offset, slong len, slong prec); void arb_hypgeom_li_series(arb_poly_t g, const arb_poly_t h, int offset, slong len, slong prec); void arb_hypgeom_bessel_j(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_bessel_y(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_bessel_jy(arb_t res1, arb_t res2, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_bessel_i(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_bessel_k(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_bessel_i_scaled(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_bessel_k_scaled(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_bessel_i_integration(arb_t res, const arb_t nu, const arb_t z, int scaled, slong prec); void arb_hypgeom_bessel_k_integration(arb_t res, const arb_t nu, const arb_t z, int scaled, slong prec); void arb_hypgeom_airy(arb_t ai, arb_t aip, arb_t bi, arb_t bip, const arb_t z, slong prec); void arb_hypgeom_airy_jet(arb_ptr ai, arb_ptr bi, const arb_t z, slong len, slong prec); void arb_hypgeom_airy_series(arb_poly_t ai, arb_poly_t ai_prime, arb_poly_t bi, arb_poly_t bi_prime, const arb_poly_t z, slong len, slong prec); void _arb_hypgeom_airy_series(arb_ptr ai, arb_ptr ai_prime, arb_ptr bi, arb_ptr bi_prime, arb_srcptr z, slong zlen, slong len, slong prec); void arb_hypgeom_airy_zero(arb_t ai, arb_t aip, arb_t bi, arb_t bip, const fmpz_t n, slong prec); void arb_hypgeom_coulomb(arb_t F, arb_t G, const arb_t l, const arb_t eta, const arb_t z, slong prec); void arb_hypgeom_coulomb_jet(arb_ptr F, arb_ptr G, const arb_t l, const arb_t eta, const arb_t z, slong len, slong prec); void _arb_hypgeom_coulomb_series(arb_ptr F, arb_ptr G, const arb_t l, const arb_t eta, arb_srcptr z, slong zlen, slong len, slong prec); void arb_hypgeom_coulomb_series(arb_poly_t F, arb_poly_t G, const arb_t l, const arb_t eta, const arb_poly_t z, slong len, slong prec); void arb_hypgeom_expint(arb_t res, const arb_t s, const arb_t z, slong prec); void arb_hypgeom_gamma_lower(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec); void _arb_hypgeom_gamma_lower_series(arb_ptr g, const arb_t s, arb_srcptr h, slong hlen, int regularized, slong n, slong prec); void arb_hypgeom_gamma_lower_series(arb_poly_t g, const arb_t s, const arb_poly_t h, int regularized, slong n, slong prec); void arb_hypgeom_gamma_upper(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec); void _arb_hypgeom_gamma_upper_series(arb_ptr g, const arb_t s, arb_srcptr h, slong hlen, int regularized, slong n, slong prec); void arb_hypgeom_gamma_upper_series(arb_poly_t g, const arb_t s, const arb_poly_t h, int regularized, slong n, slong prec); void arb_hypgeom_gamma_upper_integration(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec); void arb_hypgeom_beta_lower(arb_t res, const arb_t a, const arb_t c, const arb_t z, int regularized, slong prec); void arb_hypgeom_beta_lower_series(arb_poly_t res, const arb_t a, const arb_t b, const arb_poly_t z, int regularized, slong len, slong prec); void _arb_hypgeom_beta_lower_series(arb_ptr res, const arb_t a, const arb_t b, arb_srcptr z, slong zlen, int regularized, slong len, slong prec); void arb_hypgeom_chebyshev_t(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_chebyshev_u(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_jacobi_p(arb_t res, const arb_t n, const arb_t a, const arb_t b, const arb_t z, slong prec); void arb_hypgeom_gegenbauer_c(arb_t res, const arb_t n, const arb_t m, const arb_t z, slong prec); void arb_hypgeom_laguerre_l(arb_t res, const arb_t n, const arb_t m, const arb_t z, slong prec); void arb_hypgeom_hermite_h(arb_t res, const arb_t nu, const arb_t z, slong prec); void arb_hypgeom_legendre_p(arb_t res, const arb_t n, const arb_t m, const arb_t z, int type, slong prec); void arb_hypgeom_legendre_q(arb_t res, const arb_t n, const arb_t m, const arb_t z, int type, slong prec); void arb_hypgeom_legendre_p_ui_deriv_bound(mag_t dp, mag_t dp2, ulong n, const arb_t x, const arb_t x2sub1); void arb_hypgeom_legendre_p_ui_rec(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong prec); void arb_hypgeom_legendre_p_ui_asymp(arb_t res, arb_t res2, ulong n, const arb_t x, slong K, slong prec); void arb_hypgeom_legendre_p_ui_one(arb_t res, arb_t res2, ulong n, const arb_t x, slong K, slong prec); void arb_hypgeom_legendre_p_ui_zero(arb_t res, arb_t res2, ulong n, const arb_t x, slong K, slong prec); void arb_hypgeom_legendre_p_ui(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong prec); void arb_hypgeom_legendre_p_ui_root(arb_t res, arb_t weight, ulong n, ulong k, slong prec); void arb_hypgeom_central_bin_ui(arb_t res, ulong n, slong prec); void arb_hypgeom_dilog(arb_t res, const arb_t z, slong prec); void _arb_hypgeom_gamma_lower_sum_rs_1(arb_t res, ulong p, ulong q, const arb_t z, slong N, slong prec); void _arb_hypgeom_gamma_upper_sum_rs_1(arb_t res, ulong p, ulong q, const arb_t z, slong N, slong prec); slong _arb_hypgeom_gamma_upper_fmpq_inf_choose_N(mag_t err, const fmpq_t a, const arb_t z, const mag_t abs_tol); void _arb_hypgeom_gamma_upper_fmpq_inf_bsplit(arb_t res, const fmpq_t a, const arb_t z, slong N, slong prec); slong _arb_hypgeom_gamma_lower_fmpq_0_choose_N(mag_t err, const fmpq_t a, const arb_t z, const mag_t abs_tol); void _arb_hypgeom_gamma_lower_fmpq_0_bsplit(arb_t res, const fmpq_t a, const arb_t z, slong N, slong prec); void _arb_gamma_upper_fmpq_step_bsplit(arb_t Gz1, const fmpq_t a, const arb_t z0, const arb_t z1, const arb_t Gz0, const arb_t expmz0, const mag_t abs_tol, slong prec); slong _arb_hypgeom_gamma_upper_singular_si_choose_N(mag_t err, slong n, const arb_t z, const mag_t abs_tol); void _arb_hypgeom_gamma_upper_singular_si_bsplit(arb_t res, slong n, const arb_t z, slong N, slong prec); int arb_hypgeom_erf_bb(arb_t res, const arb_t z, int complementary, slong prec); void arb_hypgeom_sum_fmpq_arb_forward(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); void arb_hypgeom_sum_fmpq_arb_rs(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); void arb_hypgeom_sum_fmpq_arb_bs(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); void arb_hypgeom_sum_fmpq_arb(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); void arb_hypgeom_sum_fmpq_imag_arb_forward(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); void arb_hypgeom_sum_fmpq_imag_arb_rs(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); void arb_hypgeom_sum_fmpq_imag_arb_bs(arb_t res_real, arb_t res_imag, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); void arb_hypgeom_sum_fmpq_imag_arb(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/arb_hypgeom/000077500000000000000000000000001417376376500146615ustar00rootroot00000000000000arb-2.22.1/arb_hypgeom/1f1_integration.c000066400000000000000000000225001417376376500200160ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_calc.h" #include "double_interval.h" /* Integrand: exp(f(t)) where f(z) = z*t + (a-1)*log(t) + (b-a-1)*log(1-t) Magnitude bound: |exp(f(t))| = exp(Re(f(t))) = exp(g(u,v)), t = u+v*i g(u,v) = z*u + 0.5*[(a-1)*log(u^2+v^2) + (b-a-1)*log((u-1)^2+v^2)] Evaluating g(u,v) directly gives poor results; we get better bounds using linearization. d/du g(u,v) = z + u*(a-1)/(u^2+v^2) + (u-1)*(b-a-1)/(v^2+(1-u)^2) d/dv g(u,v) = v*(a-1)/(u^2+v^2) + v*(b-a-1)/(v^2+(1-u)^2) Finding the extrema of g(u,v) is doable (solutions of a degree-4 polynomial) but for simplicity we just do interval arithmetic. */ /* z*u + 0.5 [(a-1) log(u^2+v^2) + (b-a-1) log((u-1)^2+v^2)] */ static di_t di_integrand_edge(di_t u, di_t v, di_t a1, di_t ba1, di_t z) { di_t X, Y, Z; X = di_fast_mul(z, u); Y = di_fast_mul(a1, di_fast_log_nonnegative(di_fast_add(di_fast_sqr(u), di_fast_sqr(v)))); Z = di_fast_mul(ba1, di_fast_log_nonnegative(di_fast_add(di_fast_sqr(di_fast_sub_d(u, 1.0)), di_fast_sqr(v)))); return di_fast_add(X, di_fast_mul_d(di_fast_add(Y, Z), 0.5)); } /* which == 0 - d/du g(u,v) = z + u*(a-1)/(u^2+v^2) + (u-1)*(b-a-1)/(v^2+(1-u)^2) which == 1 - d/dv g(u,v) = v*(a-1)/(u^2+v^2) + v*(b-a-1)/(v^2+(1-u)^2) */ static di_t di_integrand_edge_diff(di_t u, di_t v, di_t a1, di_t ba1, di_t z, int which) { di_t Y, Z; Y = di_fast_div(a1, di_fast_add(di_fast_sqr(u), di_fast_sqr(v))); Z = di_fast_div(ba1, di_fast_add(di_fast_sqr(di_fast_sub_d(u, 1.0)), di_fast_sqr(v))); if (which == 0) return di_fast_add(z, di_fast_add(di_fast_mul(u, Y), di_fast_mul(di_fast_sub_d(u, 1.0), Z))); else return di_fast_mul(v, di_fast_add(Y, Z)); } static di_t di_subinterval(di_t x, slong i, slong N) { di_t res; double step; step = (x.b - x.a) / N; res.a = x.a + step * i; res.b = (i == N - 1) ? x.b : x.a + step * (i + 1); return res; } static void integrand_wide_bound5(acb_t res, const acb_t t, const arb_t a1, const arb_t ba1, const arb_t z, slong prec) { slong i, N; di_t du, dv, da1, dba1, dz, dg, dgprime; double radius, bound; double start, end; int which; arb_t abound; N = 8; bound = -D_INF; da1 = arb_get_di(a1); dba1 = arb_get_di(ba1); dz = arb_get_di(z); /* left edge: left(u) + [0, right(v)] */ /* right edge: right(u) + [0, right(v)] */ for (which = 0; which < 2; which++) { du = arb_get_di(acb_realref(t)); if (which == 0) du.b = du.a; else du.a = du.b; dv = arb_get_di(acb_imagref(t)); start = 0.0; end = dv.b; for (i = 0; i < N; i++) { dv = di_subinterval(di_interval(start, end), i, N); radius = di_fast_ubound_radius(dv); /* g(u,mid(v)) + g'(u,v) * [0, radius] */ #if 1 dg = di_integrand_edge(du, di_fast_mid(dv), da1, dba1, dz); dgprime = di_integrand_edge_diff(du, dv, da1, dba1, dz, 1); dg = di_fast_add(dg, di_fast_mul(dgprime, di_interval(0.0, radius))); #else dg = di_integrand_edge(du, dv, da1, dba1, dz); #endif bound = FLINT_MAX(bound, dg.b); } } du = arb_get_di(acb_realref(t)); start = du.a; end = du.b; dv = arb_get_di(acb_imagref(t)); dv.a = dv.b; /* top edge: [left(u), right(u)] + right(v) */ for (i = 0; i < N; i++) { du = di_subinterval(di_interval(start, end), i, N); radius = di_fast_ubound_radius(du); /* g(mid(u),v) + g'(u,v) * [0, radius] */ #if 1 dg = di_integrand_edge(di_fast_mid(du), dv, da1, dba1, dz); dgprime = di_integrand_edge_diff(du, dv, da1, dba1, dz, 0); dg = di_fast_add(dg, di_fast_mul(dgprime, di_interval(0.0, radius))); #else dg = di_integrand_edge(du, dv, da1, dba1, dz); #endif bound = FLINT_MAX(bound, dg.b); } arb_init(abound); arb_set_d(abound, bound); arb_exp(abound, abound, prec); acb_zero(res); arb_add_error(acb_realref(res), abound); arb_add_error(acb_imagref(res), abound); arb_clear(abound); } /* todo: fix acb_pow(_arb) */ static void acb_my_pow_arb(acb_t res, const acb_t a, const arb_t b, slong prec) { if (acb_contains_zero(a) && arb_is_positive(b)) { /* |a^b| <= |a|^b */ arb_t t, u; arb_init(t); arb_init(u); acb_abs(t, a, prec); arb_get_abs_ubound_arf(arb_midref(t), t, prec); mag_zero(arb_radref(t)); if (arf_cmpabs_2exp_si(arb_midref(t), 0) < 0) arb_get_abs_lbound_arf(arb_midref(u), b, prec); else arb_get_abs_ubound_arf(arb_midref(u), b, prec); arb_pow(t, t, u, prec); acb_zero(res); acb_add_error_arb(res, t); arb_clear(t); arb_clear(u); } else { acb_pow_arb(res, a, b, prec); } } static int integrand(acb_ptr out, const acb_t t, void * param, slong order, slong prec) { arb_srcptr a1, ba1, z; acb_t s, u, v; a1 = ((arb_srcptr) param) + 0; ba1 = ((arb_srcptr) param) + 1; z = ((arb_srcptr) param) + 2; acb_init(s); acb_init(u); acb_init(v); acb_sub_ui(v, t, 1, prec); acb_neg(v, v); if (order == 1) { if (!arb_is_positive(acb_realref(t)) || !arb_is_positive(acb_realref(v))) acb_indeterminate(out); else integrand_wide_bound5(out, t, a1, ba1, z, prec); } else { if (acb_contains_zero(t) || acb_contains_zero(v)) { /* exp(z t) */ acb_mul_arb(s, t, z, prec); acb_exp(s, s, prec); /* t^(a-1) */ acb_my_pow_arb(u, t, a1, prec); /* (1-t)^(b-a-1) */ acb_my_pow_arb(v, v, ba1, prec); acb_mul(out, s, u, prec); acb_mul(out, out, v, prec); } else { acb_mul_arb(s, t, z, prec); /* t^(a-1) */ acb_log(u, t, prec); acb_mul_arb(u, u, a1, prec); /* (1-t)^(b-a-1) */ acb_log(v, v, prec); acb_mul_arb(v, v, ba1, prec); acb_add(out, s, u, prec); acb_add(out, out, v, prec); acb_exp(out, out, prec); } } acb_clear(s); acb_clear(u); acb_clear(v); return 0; } /* estimate integral by magnitude at peak */ static void estimate_magnitude(mag_t res, const arb_t ra, const arb_t rb, const arb_t rz) { double a, b, z, t1, t2, u, m; fmpz_t e; a = arf_get_d(arb_midref(ra), ARF_RND_NEAR); b = arf_get_d(arb_midref(rb), ARF_RND_NEAR); z = arf_get_d(arb_midref(rz), ARF_RND_NEAR); u = 4 - 4*b + b*b + 4*a*z - 2*b*z + z*z; if (u >= 0.0) { t1 = (2 - b + z + sqrt(u)) / (2 * z); t2 = (2 - b + z - sqrt(u)) / (2 * z); } else { t1 = 1e-8; t2 = 1 - 1e-8; } m = -1e300; if (t1 > 0.0 && t1 < 1.0) { t1 = z * t1 + (a - 1) * log(t1) + (b - a - 1) * log(1 - t1); m = FLINT_MAX(m, t1); } if (t2 > 0.0 && t2 < 1.0) { t2 = z * t2 + (a - 1) * log(t2) + (b - a - 1) * log(1 - t2); m = FLINT_MAX(m, t2); } m /= log(2); if (fabs(m) < 1e300) { fmpz_init(e); fmpz_set_d(e, m); mag_set_d_2exp_fmpz(res, 1.0, e); fmpz_clear(e); } else { mag_zero(res); } } void arb_hypgeom_1f1_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) { acb_calc_integrate_opt_t opt; arb_struct param[3]; arb_t t, a1, ba1; acb_t zero, one, I; mag_t abs_tol; int ok; arb_init(t); arb_init(a1); arb_init(ba1); arb_sub_ui(a1, a, 1, prec); arb_sub(ba1, b, a, prec); arb_sub_ui(ba1, ba1, 1, prec); ok = arb_is_finite(z); ok = ok && arb_is_nonnegative(a1); ok = ok && arb_is_nonnegative(ba1); if (!ok) { arb_indeterminate(res); } else { mag_init(abs_tol); acb_init(zero); acb_init(one); acb_init(I); param[0] = *a1; param[1] = *ba1; param[2] = *z; acb_calc_integrate_opt_init(opt); /* opt->verbose = 2; */ /* opt->eval_limit = WORD_MAX; */ acb_one(one); estimate_magnitude(abs_tol, a, b, z); mag_mul_2exp_si(abs_tol, abs_tol, -prec); acb_calc_integrate(I, integrand, param, zero, one, prec, abs_tol, opt, prec); if (!regularized) { arb_gamma(t, b, prec); arb_mul(acb_realref(I), acb_realref(I), t, prec); } arb_rgamma(t, a, prec); arb_mul(acb_realref(I), acb_realref(I), t, prec); arb_sub(t, b, a, prec); arb_rgamma(t, t, prec); arb_mul(acb_realref(I), acb_realref(I), t, prec); arb_set(res, acb_realref(I)); mag_clear(abs_tol); acb_clear(zero); acb_clear(one); acb_clear(I); } arb_clear(t); arb_clear(a1); arb_clear(ba1); } arb-2.22.1/arb_hypgeom/2f1_integration.c000066400000000000000000000300641417376376500200230ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_calc.h" #include "double_interval.h" /* Integrand: exp(f(t)) where f(z) = (b-1)*log(t) + (c-b-1)*log(1-t) - a*log(1-z*t) Magnitude bound: |exp(f(t))| = exp(Re(f(t))) = exp(g(u,v)), t = u+v*i g(u,v) = 0.5*[(b-1)*log(u^2+v^2) + (c-b-1)*log((u-1)^2+v^2) + (-a)*log((v*z)^2+(u*z-1)^2)] Evaluating g(u,v) directly gives poor results; we get better bounds using linearization. d/du g(u,v) = u*(b-1)/(u^2+v^2) + (u-1)*(c-b-1)/(v^2+(1-u)^2) + (-a)*z*(uz-1)/((vz)^2+(uz-1)^2) d/dv g(u,v) = v*[(b-1)/(u^2+v^2) + (c-b-1)/(v^2+(1-u)^2) + (-a)*z^2/((vz)^2+(1-uz)^2)] */ /* 0.5*[(b-1)*log(u^2+v^2) + (c-b-1)*log((u-1)^2+v^2) + (-a)*log((v*z)^2+(u*z-1)^2)] */ static di_t di_integrand_edge(di_t u, di_t v, di_t b1, di_t cb1, di_t nega, di_t z) { di_t X, Y, Z; X = di_fast_mul(b1, di_fast_log_nonnegative(di_fast_add(di_fast_sqr(u), di_fast_sqr(v)))); if (cb1.a == 0 && cb1.b == 0) Y = di_interval(0.0, 0.0); else Y = di_fast_mul(cb1, di_fast_log_nonnegative(di_fast_add(di_fast_sqr(di_fast_sub_d(u, 1.0)), di_fast_sqr(v)))); Z = di_fast_mul(nega, di_fast_log_nonnegative(di_fast_add( di_fast_sqr(di_fast_mul(v, z)), di_fast_sqr(di_fast_sub_d(di_fast_mul(u, z), 1.0))))); return di_fast_mul_d(di_fast_add(X, di_fast_add(Y, Z)), 0.5); } /* which == 0 - d/du g(u,v) = u*(b-1)/(u^2+v^2) + (u-1)*(c-b-1)/(v^2+(1-u)^2) + (-a)*z*(uz-1)/((vz)^2+(uz-1)^2) which == 1 - d/dv g(u,v) = v*[(b-1)/(u^2+v^2) + (c-b-1)/(v^2+(1-u)^2) + (-a)*z^2/((vz)^2+(1-uz)^2)] */ static di_t di_integrand_edge_diff(di_t u, di_t v, di_t b1, di_t cb1, di_t nega, di_t z, int which) { di_t X, Y, Z, uz1; uz1 = di_fast_sub_d(di_fast_mul(u, z), 1.0); X = di_fast_div(b1, di_fast_add(di_fast_sqr(u), di_fast_sqr(v))); if (cb1.a == 0 && cb1.b == 0) Y = di_interval(0.0, 0.0); else Y = di_fast_div(cb1, di_fast_add(di_fast_sqr(di_fast_sub_d(u, 1.0)), di_fast_sqr(v))); Z = di_fast_div(nega, di_fast_add(di_fast_sqr(di_fast_mul(v, z)), di_fast_sqr(uz1))); if (which == 0) { X = di_fast_mul(X, u); Y = di_fast_mul(Y, di_fast_sub_d(u, 1.0)); Z = di_fast_mul(Z, di_fast_mul(z, uz1)); return di_fast_add(X, di_fast_add(Y, Z)); } else { Z = di_fast_mul(Z, di_fast_sqr(z)); return di_fast_mul(di_fast_add(X, di_fast_add(Y, Z)), v); } } static di_t di_subinterval(di_t x, slong i, slong N) { di_t res; double step; step = (x.b - x.a) / N; res.a = x.a + step * i; res.b = (i == N - 1) ? x.b : x.a + step * (i + 1); return res; } static void integrand_wide_bound5(acb_t res, const acb_t t, const arb_t b1, const arb_t cb1, const arb_t nega, const arb_t z, slong prec) { slong i, N; di_t du, dv, db1, dcb1, dnega, dz, dg, dgprime; double radius, bound; double start, end; int which; arb_t abound; N = 8; bound = -D_INF; db1 = arb_get_di(b1); dcb1 = arb_get_di(cb1); dnega = arb_get_di(nega); dz = arb_get_di(z); /* left edge: left(u) + [0, right(v)] */ /* right edge: right(u) + [0, right(v)] */ for (which = 0; which < 2; which++) { du = arb_get_di(acb_realref(t)); if (which == 0) du.b = du.a; else du.a = du.b; dv = arb_get_di(acb_imagref(t)); start = 0.0; end = dv.b; for (i = 0; i < N; i++) { dv = di_subinterval(di_interval(start, end), i, N); radius = di_fast_ubound_radius(dv); /* g(u,mid(v)) + g'(u,v) * [0, radius] */ #if 1 dg = di_integrand_edge(du, di_fast_mid(dv), db1, dcb1, dnega, dz); dgprime = di_integrand_edge_diff(du, dv, db1, dcb1, dnega, dz, 1); dg = di_fast_add(dg, di_fast_mul(dgprime, di_interval(0.0, radius))); #else dg = di_integrand_edge(du, dv, db1, dcb1, dnega, dz); #endif bound = FLINT_MAX(bound, dg.b); } } du = arb_get_di(acb_realref(t)); start = du.a; end = du.b; dv = arb_get_di(acb_imagref(t)); dv.a = dv.b; /* top edge: [left(u), right(u)] + right(v) */ for (i = 0; i < N; i++) { du = di_subinterval(di_interval(start, end), i, N); radius = di_fast_ubound_radius(du); /* g(mid(u),v) + g'(u,v) * [0, radius] */ #if 1 dg = di_integrand_edge(di_fast_mid(du), dv, db1, dcb1, dnega, dz); dgprime = di_integrand_edge_diff(du, dv, db1, dcb1, dnega, dz, 0); dg = di_fast_add(dg, di_fast_mul(dgprime, di_interval(0.0, radius))); #else dg = di_integrand_edge(du, dv, db1, dcb1, dnega, dz); #endif bound = FLINT_MAX(bound, dg.b); } arb_init(abound); arb_set_d(abound, bound); arb_exp(abound, abound, prec); acb_zero(res); arb_add_error(acb_realref(res), abound); arb_add_error(acb_imagref(res), abound); arb_clear(abound); } /* todo: fix acb_pow(_arb) */ static void acb_my_pow_arb(acb_t res, const acb_t a, const arb_t b, slong prec) { if (acb_contains_zero(a) && arb_is_positive(b)) { /* |a^b| <= |a|^b */ arb_t t, u; arb_init(t); arb_init(u); acb_abs(t, a, prec); arb_get_abs_ubound_arf(arb_midref(t), t, prec); mag_zero(arb_radref(t)); if (arf_cmpabs_2exp_si(arb_midref(t), 0) < 0) arb_get_abs_lbound_arf(arb_midref(u), b, prec); else arb_get_abs_ubound_arf(arb_midref(u), b, prec); arb_pow(t, t, u, prec); acb_zero(res); acb_add_error_arb(res, t); arb_clear(t); arb_clear(u); } else { acb_pow_arb(res, a, b, prec); } } static int integrand(acb_ptr out, const acb_t t, void * param, slong order, slong prec) { arb_srcptr b1, cb1, nega, z; acb_t s, u, v; b1 = ((arb_srcptr) param) + 0; cb1 = ((arb_srcptr) param) + 1; nega = ((arb_srcptr) param) + 2; z = ((arb_srcptr) param) + 3; acb_init(s); acb_init(u); acb_init(v); acb_sub_ui(v, t, 1, prec); acb_neg(v, v); acb_mul_arb(u, t, z, prec); acb_sub_ui(u, u, 1, prec); acb_neg(u, u); if (order == 1) { if (!arb_is_positive(acb_realref(t)) || !arb_is_positive(acb_realref(u)) || (!(arb_is_positive(acb_realref(v)) || arb_is_zero(cb1)))) acb_indeterminate(out); else { integrand_wide_bound5(out, t, b1, cb1, nega, z, prec); #if 0 /* t^(b-1) */ acb_log(s, t, prec); acb_mul_arb(s, s, b1, prec); /* (1-t)^(c-b-1) */ acb_log(v, v, prec); acb_mul_arb(v, v, cb1, prec); /* (1-zt)^(-a) */ acb_log(u, u, prec); acb_mul_arb(u, u, nega, prec); acb_add(out, s, u, prec); acb_add(out, out, v, prec); acb_exp(out, out, prec); #endif } } else { if (acb_contains_zero(t) || acb_contains_zero(v)) { /* t^(b-1) */ acb_my_pow_arb(s, t, b1, prec); /* (1-t)^(c-b-1) */ acb_my_pow_arb(v, v, cb1, prec); /* (1-zt)^(-a) */ acb_my_pow_arb(u, u, nega, prec); acb_mul(out, s, u, prec); acb_mul(out, out, v, prec); } else { /* t^(b-1) */ acb_log(s, t, prec); acb_mul_arb(s, s, b1, prec); /* (1-t)^(c-b-1) */ acb_log(v, v, prec); acb_mul_arb(v, v, cb1, prec); /* (1-zt)^(-a) */ if (arb_is_zero(nega)) { acb_zero(u); } else { acb_log(u, u, prec); acb_mul_arb(u, u, nega, prec); } acb_add(out, s, u, prec); acb_add(out, out, v, prec); acb_exp(out, out, prec); } } acb_clear(s); acb_clear(u); acb_clear(v); return 0; } /* estimate integral by magnitude at peak */ static void estimate_magnitude(mag_t res, const arb_t ra, const arb_t rb, const arb_t rc, const arb_t rz) { double a, b, c, z, t1, t2, u, m; fmpz_t e; a = arf_get_d(arb_midref(ra), ARF_RND_NEAR); b = arf_get_d(arb_midref(rb), ARF_RND_NEAR); c = arf_get_d(arb_midref(rc), ARF_RND_NEAR); z = arf_get_d(arb_midref(rz), ARF_RND_NEAR); u = 4*(b-1)*(2+a-c)*z + (2-c+(1+a-b)*z)*(2-c+(1+a-b)*z); if (u >= 0.0) { t1 = (2-c+z*(1+a-b) + sqrt(u)) / (2 * (2+a-c) * z); t2 = (2-c+z*(1+a-b) - sqrt(u)) / (2 * (2+a-c) * z); } else { t1 = 1e-8; t2 = 1 - 1e-8; } /* todo: more reliable solution when peak is at (or close to) 0 or 1 */ t1 = FLINT_MAX(t1, 1e-10); t2 = FLINT_MAX(t2, 1e-10); t1 = FLINT_MIN(t1, 1 - 1e-10); t2 = FLINT_MIN(t2, 1 - 1e-10); m = -1e300; if (t1 > 0.0 && t1 < 1.0 && z * t1 < 1.0) { t1 = (b - 1) * log(t1) + (c - b - 1) * log(1 - t1) - a * log(1 - z * t1); m = FLINT_MAX(m, t1); } if (t2 > 0.0 && t2 < 1.0 && z * t2 < 1.0) { t2 = (b - 1) * log(t2) + (c - b - 1) * log(1 - t2) - a * log(1 - z * t2); m = FLINT_MAX(m, t2); } m /= log(2); if (fabs(m) < 1e300) { fmpz_init(e); fmpz_set_d(e, m); mag_set_d_2exp_fmpz(res, 1.0, e); fmpz_clear(e); } else { mag_zero(res); } } int _arb_hypgeom_2f1_integration(arb_t res, const arb_t a, const arb_t b, const arb_t c, const arb_t z, int regularized, slong prec) { acb_calc_integrate_opt_t opt; arb_struct param[4]; arb_t t, b1, cb1, nega; acb_t zero, one, I; mag_t abs_tol; int ok; arb_init(t); arb_init(b1); arb_init(cb1); arb_init(nega); arb_sub_ui(b1, b, 1, prec); arb_sub(cb1, c, b, prec); arb_sub_ui(cb1, cb1, 1, prec); arb_neg(nega, a); arb_one(t); ok = arb_is_finite(z) && arb_lt(z, t); ok = ok && arb_is_nonnegative(b1); ok = ok && arb_is_nonnegative(cb1); if (!ok) { arb_indeterminate(res); } else { mag_init(abs_tol); acb_init(zero); acb_init(one); acb_init(I); param[0] = *b1; param[1] = *cb1; param[2] = *nega; param[3] = *z; acb_calc_integrate_opt_init(opt); /* opt->verbose = 2; */ /* opt->eval_limit = WORD_MAX; */ acb_one(one); estimate_magnitude(abs_tol, a, b, c, z); mag_mul_2exp_si(abs_tol, abs_tol, -prec); acb_calc_integrate(I, integrand, param, zero, one, prec, abs_tol, opt, prec); if (!(regularized & 1)) { arb_gamma(t, c, prec); arb_mul(acb_realref(I), acb_realref(I), t, prec); } arb_rgamma(t, b, prec); arb_mul(acb_realref(I), acb_realref(I), t, prec); arb_sub(t, c, b, prec); arb_rgamma(t, t, prec); arb_mul(acb_realref(I), acb_realref(I), t, prec); arb_set(res, acb_realref(I)); mag_clear(abs_tol); acb_clear(zero); acb_clear(one); acb_clear(I); } arb_clear(t); arb_clear(b1); arb_clear(cb1); arb_clear(nega); return ok; } void arb_hypgeom_2f1_integration(arb_t res, const arb_t a, const arb_t b, const arb_t c, const arb_t z, int regularized, slong prec) { arb_t res2; arb_init(res2); if (arf_cmp(arb_midref(a), arb_midref(b)) < 0) { if (!_arb_hypgeom_2f1_integration(res2, a, b, c, z, regularized, prec)) _arb_hypgeom_2f1_integration(res2, b, a, c, z, regularized, prec); } else { if (!_arb_hypgeom_2f1_integration(res2, b, a, c, z, regularized, prec)) _arb_hypgeom_2f1_integration(res2, a, b, c, z, regularized, prec); } arb_swap(res, res2); arb_clear(res2); } arb-2.22.1/arb_hypgeom/airy.c000066400000000000000000000025271417376376500157770ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void arb_hypgeom_airy(arb_t ai, arb_t aip, arb_t bi, arb_t bip, const arb_t z, slong prec) { acb_struct tmp[5]; if (ai != NULL) acb_init(tmp); if (aip != NULL) acb_init(tmp + 1); if (bi != NULL) acb_init(tmp + 2); if (bip != NULL) acb_init(tmp + 3); acb_init(tmp + 4); acb_set_arb(tmp + 4, z); acb_hypgeom_airy(ai ? tmp : NULL, aip ? tmp + 1 : NULL, bi ? tmp + 2 : NULL, bip ? tmp + 3 : NULL, tmp + 4, prec); if (ai != NULL) arb_set(ai, acb_realref(tmp)); if (aip != NULL) arb_set(aip, acb_realref(tmp + 1)); if (bi != NULL) arb_set(bi, acb_realref(tmp + 2)); if (bip != NULL) arb_set(bip, acb_realref(tmp + 3)); if (ai != NULL) acb_clear(tmp); if (aip != NULL) acb_clear(tmp + 1); if (bi != NULL) acb_clear(tmp + 2); if (bip != NULL) acb_clear(tmp + 3); acb_clear(tmp + 4); } arb-2.22.1/arb_hypgeom/airy_jet.c000066400000000000000000000023231417376376500166330ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static void airy_recurrence(arb_ptr ai, const arb_t z, slong len, slong prec) { slong k; if (len >= 3) { arb_mul(ai + 2, ai, z, prec); arb_mul_2exp_si(ai + 2, ai + 2, -1); } for (k = 3; k < len; k++) { arb_mul(ai + k, ai + k - 2, z, prec); arb_add(ai + k, ai + k, ai + k - 3, prec); arb_div_ui(ai + k, ai + k, k * (k - 1), prec); } } void arb_hypgeom_airy_jet(arb_ptr ai, arb_ptr bi, const arb_t z, slong len, slong prec) { if (len <= 0) return; if (len == 1) { arb_hypgeom_airy(ai, NULL, bi, NULL, z, prec); return; } arb_hypgeom_airy(ai, ai ? (ai + 1) : NULL, bi, bi ? (bi + 1) : NULL, z, prec); if (ai != NULL) airy_recurrence(ai, z, len, prec); if (bi != NULL) airy_recurrence(bi, z, len, prec); } arb-2.22.1/arb_hypgeom/airy_series.c000066400000000000000000000065611417376376500173530ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_airy_series(arb_ptr ai, arb_ptr ai_prime, arb_ptr bi, arb_ptr bi_prime, arb_srcptr z, slong zlen, slong len, slong prec) { arb_ptr t, u, v; slong tlen = len + ((ai_prime != NULL) || (bi_prime != NULL)); zlen = FLINT_MIN(zlen, len); if (zlen <= 0) return; if (zlen == 1) { arb_hypgeom_airy(ai, ai_prime, bi, bi_prime, z, prec); return; } t = _arb_vec_init(tlen); u = _arb_vec_init(tlen); v = _arb_vec_init(len); arb_hypgeom_airy_jet((ai || ai_prime) ? t : NULL, (bi || bi_prime) ? u : NULL, z, tlen, prec); /* compose with nonconstant part */ arb_zero(v); _arb_vec_set(v + 1, z + 1, zlen - 1); if (ai != NULL) _arb_poly_compose_series(ai, t, len, v, zlen, len, prec); if (bi != NULL) _arb_poly_compose_series(bi, u, len, v, zlen, len, prec); /* todo: use chain rule to avoid compositions for derivatives? */ if (ai_prime != NULL) { _arb_poly_derivative(t, t, len + 1, prec); _arb_poly_compose_series(ai_prime, t, len, v, zlen, len, prec); } if (bi_prime != NULL) { _arb_poly_derivative(u, u, len + 1, prec); _arb_poly_compose_series(bi_prime, u, len, v, zlen, len, prec); } _arb_vec_clear(t, tlen); _arb_vec_clear(u, tlen); _arb_vec_clear(v, len); } void arb_hypgeom_airy_series(arb_poly_t ai, arb_poly_t ai_prime, arb_poly_t bi, arb_poly_t bi_prime, const arb_poly_t z, slong len, slong prec) { if (len == 0) { if (ai != NULL) arb_poly_zero(ai); if (ai_prime != NULL) arb_poly_zero(ai_prime); if (bi != NULL) arb_poly_zero(bi); if (bi_prime != NULL) arb_poly_zero(bi_prime); return; } if (z->length <= 1) len = 1; if (ai != NULL) arb_poly_fit_length(ai, len); if (ai_prime != NULL) arb_poly_fit_length(ai_prime, len); if (bi != NULL) arb_poly_fit_length(bi, len); if (bi_prime != NULL) arb_poly_fit_length(bi_prime, len); if (z->length == 0) { arb_t t; arb_init(t); _arb_hypgeom_airy_series( ai ? ai->coeffs : NULL, ai_prime ? ai_prime->coeffs : NULL, bi ? bi->coeffs : NULL, bi_prime ? bi_prime->coeffs : NULL, t, 1, len, prec); arb_clear(t); } else { _arb_hypgeom_airy_series( ai ? ai->coeffs : NULL, ai_prime ? ai_prime->coeffs : NULL, bi ? bi->coeffs : NULL, bi_prime ? bi_prime->coeffs : NULL, z->coeffs, z->length, len, prec); } if (ai != NULL) { _arb_poly_set_length(ai, len); _arb_poly_normalise(ai); } if (ai_prime != NULL) { _arb_poly_set_length(ai_prime, len); _arb_poly_normalise(ai_prime); } if (bi != NULL) { _arb_poly_set_length(bi, len); _arb_poly_normalise(bi); } if (bi_prime != NULL) { _arb_poly_set_length(bi_prime, len); _arb_poly_normalise(bi_prime); } } arb-2.22.1/arb_hypgeom/airy_zero.c000066400000000000000000000201511417376376500170270ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" /* https://dlmf.nist.gov/9.9 a_k ~ -T(3/8 pi (4k-1)) a'_k ~ -U(3/8 pi (4k-3)) b_k ~ -T(3/8 pi (4k-3)) b'_k ~ -U(3/8 pi (4k-1)) For a_k and b_k, the u^8 and u^10 truncations are known to give lower bounds. [G. Pittaluga and L. Sacripante (1991) Inequalities for the zeros of the Airy functions. SIAM J. Math. Anal. 22 (1), pp. 260–267.] We don't have proofs for a'_k and b'_k. However, in that case, we can just do a single interval Newton step to verify that we have isolated a zero (the enclosure must be for the correct zero due to sandwiching). */ #define AI 0 #define BI 1 #define AI_PRIME 2 #define BI_PRIME 3 static const double initial[4][10] = {{ -658118728906175.0,-1150655474581104.0,-1553899449042978.0,-1910288501594969.0, -2236074816421182.0,-2539650438812533.0,-2826057838960988.0, -3098624122012011.0,-3359689702679955.0,-3610979637739094.0},{ -330370902027041.0,-920730911234245.0,-1359731821477101.0,-1736658984124319.0, -2076373934490092.0,-2390271103799312.0,-2684763040788193.0, -2963907159065113.0,-3230475233555475.0,-3486466475611047.0},{ -286764727967452.0,-914286338795679.0,-1356737313209586.0,-1734816794389239.0, -2075083421171399.0,-2389296605766914.0,-2683990299959380.0, -2963272965051282.0,-3229941298662311.0,-3486008018531685.0},{ -645827356227815.0,-1146491233835383.0,-1551601459626981.0,-1908764696253222.0, -2234961611612173.0,-2538787015856429.0,-2825360342097020.0, -3098043823061022.0,-3359196018589429.0,-3610552233837226.0, }}; void _arb_hypgeom_airy_zero(arb_t res, const fmpz_t n, int which, slong prec) { slong asymp_accuracy, wp; if (fmpz_cmp_ui(n, 10) <= 0) { if (fmpz_sgn(n) <= 0) { flint_printf("Airy zero only defined for index >= 1\n"); flint_abort(); } /* The asymptotic expansions work well except when n == 1, so use precomputed starting intervals (also for the first few larger n as a small optimization). */ arf_set_d(arb_midref(res), ldexp(initial[which][fmpz_get_ui(n)-1], -48)); mag_set_d(arb_radref(res), ldexp(1.0, -48)); asymp_accuracy = 48; } else { arb_t z, u, u2, u4, s; fmpz_t c; arb_init(z); arb_init(u); arb_init(u2); arb_init(u4); arb_init(s); fmpz_init(c); if (which == AI || which == BI_PRIME) asymp_accuracy = 13 + 10 * (fmpz_bits(n) - 1); else { fmpz_sub_ui(c, n, 1); asymp_accuracy = 13 + 10 * (fmpz_bits(c) - 1); } wp = asymp_accuracy + 8; /* Reduce precision since we may not need to do any Newton steps. */ if (which == AI || which == BI) wp = FLINT_MIN(wp, prec + 8); arb_const_pi(z, wp); fmpz_mul_2exp(c, n, 2); if (which == AI || which == BI_PRIME) fmpz_sub_ui(c, c, 1); else fmpz_sub_ui(c, c, 3); fmpz_mul_ui(c, c, 3); arb_mul_fmpz(z, z, c, wp); arb_mul_2exp_si(z, z, -3); arb_inv(u, z, wp); arb_mul(u2, u, u, wp); arb_mul(u4, u2, u2, wp); if (which == AI || which == BI) { /* u^8 truncation gives lower bound */ arb_mul_si(s, u4, -108056875, wp); arb_addmul_si(s, u2, 6478500, wp); arb_add_si(s, s, -967680, wp); arb_mul(s, s, u4, wp); arb_addmul_si(s, u2, 725760, wp); arb_div_ui(s, s, 6967296, wp); /* u^10 term gives upper bound */ arb_mul(u4, u4, u4, 10); arb_mul(u4, u4, u2, 10); arb_mul_ui(u4, u4, 486, 10); } else { /* u^8 truncation gives upper bound */ arb_mul_si(s, u4, 18683371, wp); arb_addmul_si(s, u2, -1087338, wp); arb_add_si(s, s, 151200, wp); arb_mul(s, s, u4, wp); arb_addmul_si(s, u2, -181440, wp); arb_div_ui(s, s, 1244160, wp); /* u^10 term gives lower bound */ arb_mul(u4, u4, u4, 10); arb_mul(u4, u4, u2, 10); arb_mul_ui(u4, u4, 477, 10); arb_neg(u4, u4); } arb_mul_2exp_si(u4, u4, -1); arb_add(s, s, u4, wp); arb_add_error(s, u4); arb_add_ui(s, s, 1, wp); arb_root_ui(z, z, 3, wp); arb_mul(z, z, z, wp); arb_mul(res, z, s, wp); arb_neg(res, res); arb_clear(z); arb_clear(u); arb_clear(u2); arb_clear(u4); arb_clear(s); fmpz_clear(c); } /* Do interval Newton steps for refinement. Important: for the primed zeros, we need to do at least one interval Newton step to validate the initial (tentative) inclusion. */ if (asymp_accuracy < prec || (which == AI_PRIME || which == BI_PRIME)) { arb_t f, fprime, root; mag_t C, r; slong * steps; slong step, extraprec; arb_init(f); arb_init(fprime); arb_init(root); mag_init(C); mag_init(r); steps = flint_malloc(sizeof(slong) * FLINT_BITS); extraprec = 0.25 * fmpz_bits(n) + 8; wp = asymp_accuracy + extraprec; /* C = |f''| or |f'''| on the initial interval given by res */ /* f''(x) = xf(x) */ /* f'''(x) = xf'(x) + f(x) */ if (which == AI || which == AI_PRIME) arb_hypgeom_airy(f, fprime, NULL, NULL, res, wp); else arb_hypgeom_airy(NULL, NULL, f, fprime, res, wp); if (which == AI || which == BI) arb_mul(f, f, res, wp); else arb_addmul(f, fprime, res, wp); arb_get_mag(C, f); step = 0; steps[step] = prec; while (steps[step] / 2 > asymp_accuracy - extraprec) { steps[step + 1] = steps[step] / 2; step++; } arb_set(root, res); for ( ; step >= 0; step--) { wp = steps[step] + extraprec; wp = FLINT_MAX(wp, arb_rel_accuracy_bits(root) + extraprec); /* store radius, set root to the midpoint */ mag_set(r, arb_radref(root)); mag_zero(arb_radref(root)); if (which == AI || which == AI_PRIME) arb_hypgeom_airy(f, fprime, NULL, NULL, root, wp); else arb_hypgeom_airy(NULL, NULL, f, fprime, root, wp); /* f, f' = f', xf */ if (which == AI_PRIME || which == BI_PRIME) { arb_mul(f, f, root, wp); arb_swap(f, fprime); } /* f'([m+/-r]) = f'(m) +/- f''([m +/- r]) * r */ mag_mul(r, C, r); arb_add_error_mag(fprime, r); arb_div(f, f, fprime, wp); arb_sub(root, root, f, wp); /* Verify inclusion so that C is still valid, and for the primed zeros also to make sure that the initial intervals really were correct. */ if (!arb_contains(res, root)) { flint_printf("unexpected: no containment of Airy zero\n"); arb_indeterminate(root); break; } } arb_set(res, root); arb_clear(f); arb_clear(fprime); arb_clear(root); mag_clear(C); mag_clear(r); flint_free(steps); } arb_set_round(res, res, prec); } void arb_hypgeom_airy_zero(arb_t ai, arb_t aip, arb_t bi, arb_t bip, const fmpz_t n, slong prec) { if (ai != NULL) _arb_hypgeom_airy_zero(ai, n, AI, prec); if (aip != NULL) _arb_hypgeom_airy_zero(aip, n, AI_PRIME, prec); if (bi != NULL) _arb_hypgeom_airy_zero(bi, n, BI, prec); if (bip != NULL) _arb_hypgeom_airy_zero(bip, n, BI_PRIME, prec); } arb-2.22.1/arb_hypgeom/bessel_i_integration.c000066400000000000000000000027401417376376500212200ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_bessel_i_integration(arb_t res, const arb_t nu, const arb_t z, int scaled, slong prec) { arb_t t, a, b, w; arb_init(t); arb_init(a); arb_init(b); arb_init(w); arb_one(a); arb_mul_2exp_si(a, a, -1); arb_add(a, a, nu, prec); arb_mul_2exp_si(b, nu, 1); arb_add_ui(b, b, 1, prec); arb_mul_2exp_si(w, z, 1); arb_hypgeom_1f1_integration(t, a, b, w, 0, prec); if (arb_is_finite(t)) { if (!scaled) { arb_neg(a, z); arb_exp(a, a, prec); arb_mul(t, t, a, prec); } else { arb_neg(a, z); arb_mul_2exp_si(a, a, 1); arb_exp(a, a, prec); arb_mul(t, t, a, prec); } arb_mul_2exp_si(w, z, -1); arb_pow(w, w, nu, prec); arb_mul(t, t, w, prec); arb_add_ui(w, nu, 1, prec); arb_rgamma(w, w, prec); arb_mul(res, t, w, prec); } else { arb_indeterminate(res); } arb_clear(t); arb_clear(a); arb_clear(b); arb_clear(w); } arb-2.22.1/arb_hypgeom/bessel_k_integration.c000066400000000000000000000024271417376376500212240ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_bessel_k_integration(arb_t res, const arb_t nu, const arb_t z, int scaled, slong prec) { arb_t t, a, b, w; arb_init(t); arb_init(a); arb_init(b); arb_init(w); arb_one(a); arb_mul_2exp_si(a, a, -1); arb_add(a, a, nu, prec); arb_mul_2exp_si(b, nu, 1); arb_add_ui(b, b, 1, prec); arb_mul_2exp_si(w, z, 1); arb_hypgeom_u_integration(t, a, b, w, prec); if (arb_is_finite(t)) { if (!scaled) { arb_neg(a, z); arb_exp(a, a, prec); arb_mul(t, t, a, prec); } arb_mul_2exp_si(w, z, 1); arb_pow(w, w, nu, prec); arb_mul(res, t, w, prec); arb_const_sqrt_pi(w, prec); arb_mul(res, res, w, prec); } else { arb_indeterminate(res); } arb_clear(t); arb_clear(a); arb_clear(b); arb_clear(w); } arb-2.22.1/arb_hypgeom/beta_lower_series.c000066400000000000000000000054701417376376500205300ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_beta_lower_series(arb_ptr res, const arb_t a, const arb_t b, arb_srcptr z, slong zlen, int regularized, slong len, slong prec) { arb_ptr t, u, v; arb_t c, d, e; zlen = FLINT_MIN(zlen, len); if (zlen == 1) { arb_hypgeom_beta_lower(res, a, b, z, regularized, prec); _arb_vec_zero(res + 1, len - 1); return; } t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(zlen - 1); arb_init(c); arb_init(d); arb_init(e); arb_hypgeom_beta_lower(d, a, b, z, regularized, prec); if (regularized) { /* todo: except in special cases, we already compute a bunch of gamma functions in beta_lower, so we could avoid recomputing them */ arb_add(e, a, b, prec); arb_gamma(e, e, prec); arb_rgamma(c, a, prec); arb_mul(e, e, c, prec); arb_rgamma(c, b, prec); arb_mul(e, e, c, prec); } /* u = (1-z)^(b-1) */ _arb_vec_neg(t, z, zlen); arb_add_ui(t, t, 1, prec); arb_sub_ui(c, b, 1, prec); _arb_poly_pow_arb_series(u, t, FLINT_MIN(zlen, len - 1), c, len - 1, prec); /* t = z^(a-1) */ arb_sub_ui(c, a, 1, prec); _arb_poly_pow_arb_series(t, z, FLINT_MIN(zlen, len - 1), c, len - 1, prec); /* v = z' */ _arb_poly_derivative(v, z, zlen, prec); _arb_poly_mullow(res, t, len - 1, u, len - 1, len - 1, prec); _arb_poly_mullow(t, res, len - 1, v, zlen - 1, len - 1, prec); _arb_poly_integral(res, t, len, prec); if (regularized) { _arb_vec_scalar_mul(res, res, len, e, prec); } arb_set(res, d); _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, zlen - 1); arb_clear(c); arb_clear(d); arb_clear(e); } void arb_hypgeom_beta_lower_series(arb_poly_t res, const arb_t a, const arb_t b, const arb_poly_t z, int regularized, slong len, slong prec) { if (len == 0) { arb_poly_zero(res); return; } arb_poly_fit_length(res, len); if (z->length == 0) { arb_t t; arb_init(t); _arb_hypgeom_beta_lower_series(res->coeffs, a, b, t, 1, regularized, len, prec); arb_clear(t); } else { _arb_hypgeom_beta_lower_series(res->coeffs, a, b, z->coeffs, z->length, regularized, len, prec); } _arb_poly_set_length(res, len); _arb_poly_normalise(res); } arb-2.22.1/arb_hypgeom/central_bin_ui.c000066400000000000000000000064021417376376500200040ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "bernoulli.h" static const unsigned int central_bin_tab[] = { 1, 2, 6, 20, 70, 252, 924, 3432, 12870, 48620, 184756, 705432, 2704156, 10400600, 40116600, 155117520, 601080390, 2333606220U, }; void arb_gamma_stirling_coeff(arb_t b, ulong k, int digamma, slong prec); /* See Richard P. Brent, "Asymptotic approximation of central binomial coefficients with rigorous error bounds". https://arxiv.org/abs/1608.04834 */ static void arb_hypgeom_central_bin_ui_asymp(arb_t res, ulong n, slong prec) { arb_t s, t, u; fmpz_t n2; slong j, k, term_prec, wp; double term_mag, n2_mag; mag_t err, err2; arb_init(s); arb_init(t); arb_init(u); fmpz_init(n2); mag_init(err); mag_init(err2); wp = prec + 8; n2_mag = log(n) * 1.44269504088896; for (k = 1; k < prec; k++) { term_mag = bernoulli_bound_2exp_si(2 * k + 2) - (2 * k + 1) * n2_mag; term_mag -= (FLINT_BIT_COUNT((k + 1)*(2*k+1)) - 1); if (term_mag < -wp) break; } wp += 2 * FLINT_BIT_COUNT(k); BERNOULLI_ENSURE_CACHED(2*k) fmpz_set_ui(n2, n); fmpz_mul_ui(n2, n2, n); n2_mag *= 2; for (j = 0; j <= k - 1; j++) { term_mag = bernoulli_bound_2exp_si(2 * j + 2); term_mag -= j * n2_mag; term_prec = wp + term_mag; term_prec = FLINT_MIN(term_prec, wp); term_prec = FLINT_MAX(term_prec, 10); arb_gamma_stirling_coeff(t, j + 1, 0, term_prec); arb_mul_2exp_si(u, t, -2*j - 2); arb_sub(t, u, t, term_prec); arb_mul_2exp_si(t, t, 1); arb_addmul_fmpz(t, s, n2, wp); arb_swap(s, t); } arb_set_fmpz(t, n2); arb_pow_ui(t, t, k - 1, wp); arb_mul_ui(t, t, n, wp); arb_div(s, s, t, wp); /* error term: bernoulli(2k+2) / ((k+1)(2k+1)) / n^(2k+1) */ mag_bernoulli_div_fac_ui(err, 2 * k + 2); mag_fac_ui(err2, 2 * k + 2); mag_mul(err, err, err2); mag_set_ui_lower(err2, n); mag_pow_ui_lower(err2, err2, 2 * k + 1); mag_mul_ui_lower(err2, err2, k + 1); mag_div(err, err, err2); arb_add_error_mag(s, err); arb_exp(s, s, wp); arb_const_pi(t, wp); arb_mul_ui(t, t, n, wp); arb_rsqrt(t, t, wp); arb_mul(res, s, t, prec); fmpz_set_ui(n2, n); fmpz_mul_2exp(n2, n2, 1); arb_mul_2exp_fmpz(res, res, n2); arb_clear(s); arb_clear(t); arb_clear(u); fmpz_clear(n2); mag_clear(err); mag_clear(err2); } void arb_hypgeom_central_bin_ui(arb_t res, ulong n, slong prec) { if (n <= 17) { arb_set_ui(res, central_bin_tab[n]); arb_set_round(res, res, prec); } else if (n < 6.0 * prec + 200.0) { fmpz_t t; fmpz_init(t); fmpz_bin_uiui(t, 2 * n, n); arb_set_round_fmpz(res, t, prec); fmpz_clear(t); } else { arb_hypgeom_central_bin_ui_asymp(res, n, prec); } } arb-2.22.1/arb_hypgeom/chi_series.c000066400000000000000000000034651417376376500171520ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_chi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { arb_t c; if (!arb_is_positive(h)) { _arb_vec_indeterminate(g, len); return; } arb_init(c); arb_hypgeom_chi(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u, v; t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(len); /* Chi(h(x)) = integral([h'(x) / h(x)] cosh(h(x)) */ _arb_poly_cosh_series(t, h, hlen, len - 1, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(v, t, len - 1, u, len - 1, len - 1, prec); _arb_poly_div_series(u, v, len - 1, h, hlen, len - 1, prec); _arb_poly_integral(g, u, len, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, len); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_chi_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_inv_series(g, h, len, prec); return; } arb_poly_fit_length(g, len); _arb_hypgeom_chi_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/ci.c000066400000000000000000000117771417376376500154350ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arb_hypgeom.h" #define LOG2 0.69314718055994531 #define INV_LOG2 1.4426950408889634074 #define EXP1 2.7182818284590452 double arf_get_d_log2_abs_approx_clamped(const arf_t x); void _arb_hypgeom_ci_asymp(arb_t res, const arb_t z, slong N, slong prec) { arb_t s, c, sz, cz, u; fmpq a[1]; slong wp; mag_t err, t; N = FLINT_MAX(N, 1); arb_init(s); arb_init(c); arb_init(sz); arb_init(cz); arb_init(u); mag_init(err); mag_init(t); /* Error is bounded by first omitted term, N! / z^N */ arb_get_mag_lower(err, z); mag_inv(err, err); mag_pow_ui(err, err, N); mag_fac_ui(t, N); mag_mul(err, err, t); wp = prec * 1.001 + 5; arb_set(u, z); *fmpq_numref(&a[0]) = 1; *fmpq_denref(&a[0]) = 1; arb_hypgeom_sum_fmpq_imag_arb(c, s, a, 1, NULL, 0, u, 1, N, wp); arb_add_error_mag(c, err); arb_add_error_mag(s, err); arb_sin_cos(sz, cz, z, wp); arb_mul(c, c, sz, wp); arb_submul(c, s, cz, wp); arb_div(res, c, z, prec); arb_clear(s); arb_clear(c); arb_clear(sz); arb_clear(cz); arb_clear(u); mag_clear(err); mag_clear(t); } void _arb_hypgeom_ci_2f3(arb_t res, const arb_t z, slong N, slong wp, slong prec) { mag_t err, t; arb_t s, u; fmpq a[1]; fmpq b[3]; N = FLINT_MAX(N, 1); mag_init(err); mag_init(t); arb_init(s); arb_init(u); arb_sqr(u, z, wp); arb_mul_2exp_si(u, u, -2); arb_neg(u, u); *fmpq_numref(&a[0]) = 1; *fmpq_denref(&a[0]) = 1; *fmpq_numref(&b[0]) = 2; *fmpq_denref(&b[0]) = 1; *fmpq_numref(&b[1]) = 2; *fmpq_denref(&b[1]) = 1; *fmpq_numref(&b[2]) = 3; *fmpq_denref(&b[2]) = 2; /* Terms are bounded by u^N / (4 (N!)^2) */ arb_get_mag(err, u); /* u^N */ mag_set(t, err); mag_pow_ui(t, t, N); /* geometric factor for u/N^2 */ mag_div_ui(err, err, N); mag_div_ui(err, err, N); mag_geom_series(err, err, 0); mag_mul(t, t, err); /* 1/(N!)^2 */ mag_rfac_ui(err, N); mag_mul(err, err, err); mag_mul(err, err, t); /* 1/4 */ mag_mul_2exp_si(err, err, -2); arb_hypgeom_sum_fmpq_arb(s, a, 1, b, 3, u, 0, N, wp); arb_add_error_mag(s, err); arb_mul(s, s, u, wp); arb_log(u, z, wp); arb_add(s, s, u, wp); arb_const_euler(u, wp); arb_add(res, s, u, prec); mag_clear(err); mag_clear(t); arb_clear(u); arb_clear(s); } void arb_hypgeom_ci(arb_t res, const arb_t z, slong prec) { slong wp, N, acc; double dz, du; if (!arb_is_positive(z) || !arb_is_finite(z)) { arb_indeterminate(res); return; } if (ARF_IS_LAGOM(arb_midref(z))) { acc = arb_rel_accuracy_bits(z); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); acc += FLINT_MAX(0, -ARF_EXP(arb_midref(z))); prec = FLINT_MIN(prec, acc + 32); } dz = fabs(arf_get_d(arb_midref(z), ARF_RND_DOWN)); dz = FLINT_MIN(dz, 1e300); if (dz > 2.0) { double log2_err, err_prev, log2dz; log2dz = arf_get_d_log2_abs_approx_clamped(arb_midref(z)); err_prev = 0.0; for (N = 1; N < 2 * prec; N++) { log2_err = ((N + 1.0) * (log(N + 1.0) - 1.0)) * INV_LOG2 - N * log2dz; if (log2_err > err_prev) break; if (log2_err < -prec - 2) { _arb_hypgeom_ci_asymp(res, z, N, prec); return; } err_prev = log2_err; } } if (arf_cmpabs_2exp_si(arb_midref(z), -30) < 0) { N = -arf_abs_bound_lt_2exp_si(arb_midref(z)); wp = prec * 1.001 + 10; N = (prec + N - 1) / N; } else { du = 0.25 * dz * dz; wp = prec * 1.001 + 10; if (du > 1.0) wp += dz * 1.4426950408889634; N = (prec + 5) * LOG2 / (2 * d_lambertw((prec + 5) * LOG2 / (2 * EXP1 * sqrt(du)))) + 1; } if (arb_is_exact(z)) { _arb_hypgeom_ci_2f3(res, z, N, wp, prec); } else { mag_t err; mag_init(err); /* |ci'(z)| = |cos(z)/z| <= 1/z */ arb_get_mag_lower(err, z); if (mag_cmp_2exp_si(err, 0) >= 0 || 1) { arb_t zmid; arb_init(zmid); arb_get_mid_arb(zmid, z); mag_inv(err, err); mag_mul(err, err, arb_radref(z)); _arb_hypgeom_ci_2f3(res, zmid, N, wp, prec); arb_add_error_mag(res, err); arb_clear(zmid); } else { _arb_hypgeom_ci_2f3(res, z, N, wp, prec); } mag_clear(err); } } arb-2.22.1/arb_hypgeom/ci_series.c000066400000000000000000000034561417376376500170020ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_ci_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { arb_t c; if (!arb_is_positive(h)) { _arb_vec_indeterminate(g, len); return; } arb_init(c); arb_hypgeom_ci(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u, v; t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(len); /* Ci(h(x)) = integral([h'(x) / h(x)] cos(h(x)) */ _arb_poly_cos_series(t, h, hlen, len - 1, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(v, t, len - 1, u, len - 1, len - 1, prec); _arb_poly_div_series(u, v, len - 1, h, hlen, len - 1, prec); _arb_poly_integral(g, u, len, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, len); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_ci_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_inv_series(g, h, len, prec); return; } arb_poly_fit_length(g, len); _arb_hypgeom_ci_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/coulomb.c000066400000000000000000000021501417376376500164630ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void arb_hypgeom_coulomb(arb_t F, arb_t G, const arb_t l, const arb_t eta, const arb_t z, slong prec) { acb_ptr tmp; tmp = _acb_vec_init(5); acb_set_arb(tmp + 2, l); acb_set_arb(tmp + 3, eta); acb_set_arb(tmp + 4, z); acb_hypgeom_coulomb(F ? tmp : NULL, G ? tmp + 1 : NULL, NULL, NULL, tmp + 2, tmp + 3, tmp + 4, prec); if (F != NULL) { if (acb_is_real(tmp)) arb_set(F, acb_realref(tmp)); else arb_indeterminate(F); } if (G != NULL) { if (acb_is_real(tmp + 1)) arb_set(G, acb_realref(tmp + 1)); else arb_indeterminate(G); } _acb_vec_clear(tmp, 5); } arb-2.22.1/arb_hypgeom/coulomb_jet.c000066400000000000000000000030111417376376500173220ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void arb_hypgeom_coulomb_jet(arb_ptr F, arb_ptr G, const arb_t l, const arb_t eta, const arb_t z, slong len, slong prec) { acb_ptr tmp, tmpF, tmpG; slong k; if (len <= 0) return; if (len == 1) { arb_hypgeom_coulomb(F, G, l, eta, z, prec); return; } tmp = _acb_vec_init(3); tmpF = _acb_vec_init(len); tmpG = _acb_vec_init(len); acb_set_arb(tmp, l); acb_set_arb(tmp + 1, eta); acb_set_arb(tmp + 2, z); acb_hypgeom_coulomb_jet(F ? tmpF : NULL, G ? tmpG : NULL, NULL, NULL, tmp, tmp + 1, tmp + 2, len, prec); if (F != NULL) { if (acb_is_real(tmpF)) for (k = 0; k < len; k++) arb_set(F + k, acb_realref(tmpF + k)); else _arb_vec_indeterminate(F, len); } if (G != NULL) { if (acb_is_real(tmpG)) for (k = 0; k < len; k++) arb_set(G + k, acb_realref(tmpG + k)); else _arb_vec_indeterminate(G, len); } _acb_vec_clear(tmpF, len); _acb_vec_clear(tmpG, len); _acb_vec_clear(tmp, 3); } arb-2.22.1/arb_hypgeom/coulomb_series.c000066400000000000000000000045141417376376500200430ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "arb_hypgeom.h" void _arb_hypgeom_coulomb_series(arb_ptr F, arb_ptr G, const arb_t l, const arb_t eta, arb_srcptr z, slong zlen, slong len, slong prec) { arb_ptr t, v; if (len == 0) return; zlen = FLINT_MIN(zlen, len); if (zlen == 1) { arb_hypgeom_coulomb(F, G, l, eta, z, prec); if (F != NULL) _arb_vec_zero(F + 1, len - 1); if (G != NULL) _arb_vec_zero(G + 1, len - 1); return; } t = _arb_vec_init(len); v = _arb_vec_init(zlen); /* copy nonconstant part first to allow aliasing */ arb_zero(v); _arb_vec_set(v + 1, z + 1, zlen - 1); arb_hypgeom_coulomb_jet(F, G, l, eta, z, len, prec); if (F != NULL) { _arb_vec_set(t, F, len); _arb_poly_compose_series(F, t, len, v, zlen, len, prec); } if (G != NULL) { _arb_vec_set(t, G, len); _arb_poly_compose_series(G, t, len, v, zlen, len, prec); } _arb_vec_clear(t, len); _arb_vec_clear(v, zlen); } void arb_hypgeom_coulomb_series(arb_poly_t F, arb_poly_t G, const arb_t l, const arb_t eta, const arb_poly_t z, slong len, slong prec) { arb_srcptr zptr; slong zlen; arb_t t; if (len == 0) { if (F != NULL) arb_poly_zero(F); if (G != NULL) arb_poly_zero(G); return; } zlen = z->length; if (zlen <= 1) len = 1; if (F != NULL) arb_poly_fit_length(F, len); if (G != NULL) arb_poly_fit_length(G, len); if (zlen == 0) { arb_init(t); zptr = t; zlen = 1; } else { zptr = z->coeffs; } _arb_hypgeom_coulomb_series( F ? F->coeffs : NULL, G ? G->coeffs : NULL, l, eta, zptr, zlen, len, prec); if (F != NULL) _arb_poly_set_length(F, len); if (G != NULL) _arb_poly_set_length(G, len); if (F != NULL) _arb_poly_normalise(F); if (G != NULL) _arb_poly_normalise(G); } arb-2.22.1/arb_hypgeom/ei_series.c000066400000000000000000000034571417376376500170050ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_ei_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { arb_t c; if (arb_contains_zero(h)) { _arb_vec_indeterminate(g, len); return; } arb_init(c); arb_hypgeom_ei(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u, v; t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(len); /* Ei(h(x)) = integral([h'(x) / h(x)] exp(h(x)) */ _arb_poly_exp_series(t, h, hlen, len - 1, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(v, t, len - 1, u, len - 1, len - 1, prec); _arb_poly_div_series(u, v, len - 1, h, hlen, len - 1, prec); _arb_poly_integral(g, u, len, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, len); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_ei_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_inv_series(g, h, len, prec); return; } arb_poly_fit_length(g, len); _arb_hypgeom_ei_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/erf.c000066400000000000000000000351131417376376500156040ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arb_hypgeom.h" #define LOG2 0.69314718055994530942 #define EXP1 2.7182818284590452354 #define INV_LOG2 1.4426950408889634074 void arb_hypgeom_erf_one_eps(arb_t res, const arb_t z) { mag_t t, u; mag_init(t); mag_init(u); arb_get_mag_lower(t, z); mag_mul_lower(u, t, t); mag_expinv(u, u); mag_div(u, u, t); /* 1/sqrt(pi) < 289/512 */ mag_mul_ui(u, u, 289); mag_mul_2exp_si(arb_radref(res), u, -9); if (mag_cmp_2exp_si(arb_radref(res), 1) > 0) { mag_one(arb_radref(res)); mag_mul_2exp_si(arb_radref(res), arb_radref(res), 2); } if (arf_sgn(arb_midref(z)) > 0) arf_one(arb_midref(res)); else { arf_one(arb_midref(res)); arf_neg(arb_midref(res), arb_midref(res)); } mag_clear(t); mag_clear(u); } void arb_hypgeom_erf_propagated_error(mag_t err, const arb_t z) { mag_t x; mag_init(x); /* exp(-z^2) */ arb_get_mag_lower(x, z); mag_mul_lower(x, x, x); mag_expinv(err, x); mag_mul(err, err, arb_radref(z)); /* 2/sqrt(pi) < 289/256 */ mag_mul_ui(err, err, 289); mag_mul_2exp_si(err, err, -8); /* |erf(a) - erf(b)| <= 2 */ mag_set_ui(x, 2); mag_min(err, err, x); mag_clear(x); } void arb_hypgeom_erf_1f1b(arb_t res, const arb_t z, slong prec) { arb_t t, u; slong N; mag_t err; arb_init(t); arb_init(u); mag_init(err); if (arf_cmpabs_2exp_si(arb_midref(z), -32) < 0) { if (arf_cmpabs_2exp_si(arb_midref(z), -prec) < 0) N = 1; else N = -prec / (2 * ARF_EXP(arb_midref(z))) + 1; } else { double u, dz; dz = arf_get_d(arb_midref(z), ARF_RND_DOWN); dz = fabs(dz); u = -dz * dz + prec * LOG2 + log(dz); u = u / d_lambertw(u / (EXP1 * dz * dz)); N = u + 1; } N = FLINT_MAX(N, 1); arb_sqr(t, z, prec); _arb_hypgeom_gamma_lower_sum_rs_1(u, 3, 2, t, N, prec); /* z^(2k) / rf(3/2,k) <= (z^2)^k / k! */ arb_get_mag(err, t); mag_exp_tail(err, err, N); arb_add_error_mag(u, err); arb_neg(t, t); arb_exp(t, t, prec); arb_mul(u, u, t, prec); arb_const_sqrt_pi(t, prec); arb_div(u, u, t, prec); arb_mul(u, u, z, prec); arb_mul_2exp_si(res, u, 1); arb_clear(t); arb_clear(u); mag_clear(err); } void arb_hypgeom_erf_asymp(arb_t res, const arb_t z, slong N, int complementary, slong prec, slong prec2) { arb_t t, u; int sgn; mag_t err, tm; if (!arb_is_exact(z) && (arf_cmpabs_ui(arb_midref(z), prec) < 0 || (complementary && arb_rel_accuracy_bits(z) < prec))) { arb_t zmid; mag_t err; arb_init(zmid); mag_init(err); arb_hypgeom_erf_propagated_error(err, z); arf_set(arb_midref(zmid), arb_midref(z)); arb_hypgeom_erf_asymp(res, zmid, N, complementary, prec, prec2); arb_add_error_mag(res, err); arb_clear(zmid); mag_clear(err); return; } arb_init(t); arb_init(u); mag_init(err); mag_init(tm); sgn = arf_sgn(arb_midref(z)); arb_sqr(t, z, prec2); arb_neg(t, t); _arb_hypgeom_gamma_upper_sum_rs_1(u, 1, 2, t, N, prec2); /* Error is bounded by first omitted term, rf(1/2,N) / z^(2N) <= N! / z^(2N) */ arb_get_mag_lower(err, t); mag_inv(err, err); mag_pow_ui(err, err, N); mag_fac_ui(tm, N); mag_mul(err, err, tm); arb_add_error_mag(u, err); arb_exp(t, t, prec2); arb_mul(u, u, t, prec2); arb_const_sqrt_pi(t, prec2); arb_mul(t, t, z, prec2); arb_div(res, u, t, prec2); if (!complementary) { if (sgn == 1) arb_sub_ui(res, res, 1, prec); else arb_add_ui(res, res, 1, prec); arb_neg(res, res); } arb_clear(t); arb_clear(u); mag_clear(err); mag_clear(tm); } void arb_hypgeom_erf_1f1(arb_t res, const arb_t z, slong prec, slong wp) { if (arb_rel_accuracy_bits(z) >= wp) { arb_hypgeom_erf_1f1b(res, z, wp); } else { arb_t zmid; mag_t err; arb_init(zmid); mag_init(err); arb_hypgeom_erf_propagated_error(err, z); arf_set(arb_midref(zmid), arb_midref(z)); arb_hypgeom_erf_1f1b(res, zmid, wp); arb_add_error_mag(res, err); arb_clear(zmid); mag_clear(err); } arb_set_round(res, res, prec); } static void _arf_trunc(arf_t x) { if (arf_sgn(x) < 0) arf_ceil(x, x); else arf_floor(x, x); } static void arb_extract_bits(arb_t t, const arb_t z, slong b) { arb_mul_2exp_si(t, z, b); _arf_trunc(arb_midref(t)); mag_zero(arb_radref(t)); arb_mul_2exp_si(t, t, -b); } /* Compute Gamma(a,z) using the bit-burst algorithm. Todo: allow passing precomputed Gamma(a) as input. */ void _arb_gamma_upper_fmpq_bb(arb_t res, const fmpq_t a, const arb_t z, const mag_t abs_tol, slong prec_lower, slong prec_upper) { slong start_bits, bits, wp, NN; arb_t Gz0, Gz1, z0, z1, expmz0, t; mag_t AE; arb_init(t); arb_init(z0); arb_init(z1); arb_init(Gz0); arb_init(Gz1); arb_init(expmz0); mag_init(AE); start_bits = 64; wp = prec_upper; /* Hack: the error bound for the local Taylor series assumes that the step size is much smaller than the expansion point, even when the expansion point is close to zero. So when close to zero, we need to take more initial bits. */ while (arf_cmpabs_2exp_si(arb_midref(z), -start_bits / 4) < 0) { if (start_bits > prec_lower) { NN = _arb_hypgeom_gamma_lower_fmpq_0_choose_N(AE, a, z, abs_tol); _arb_hypgeom_gamma_lower_fmpq_0_bsplit(Gz0, a, z, NN, prec_lower); arb_add_error_mag(Gz0, AE); arb_gamma_fmpq(t, a, FLINT_MAX(prec_lower, prec_upper)); arb_sub(res, t, Gz0, prec_upper); goto bb_cleanup; } start_bits *= 2; } arb_extract_bits(z0, z, start_bits); NN = _arb_hypgeom_gamma_upper_fmpq_inf_choose_N(AE, a, z0, abs_tol); if (NN != -1) { _arb_hypgeom_gamma_upper_fmpq_inf_bsplit(Gz0, a, z0, NN, wp); arb_add_error_mag(Gz0, AE); } else { NN = _arb_hypgeom_gamma_lower_fmpq_0_choose_N(AE, a, z0, abs_tol); _arb_hypgeom_gamma_lower_fmpq_0_bsplit(Gz0, a, z0, NN, prec_lower); arb_add_error_mag(Gz0, AE); arb_gamma_fmpq(t, a, FLINT_MAX(prec_lower, prec_upper)); arb_sub(Gz0, t, Gz0, prec_upper); } arb_neg(expmz0, z0); arb_exp(expmz0, expmz0, wp); for (bits = start_bits * 2; bits < wp / 8; bits *= 2) { arb_extract_bits(z1, z, bits); _arb_gamma_upper_fmpq_step_bsplit(Gz1, a, z0, z1, Gz0, expmz0, abs_tol, wp); arb_sub(t, z0, z1, wp); arb_exp(t, t, wp); arb_mul(expmz0, expmz0, t, wp); arb_set(Gz0, Gz1); arb_set(z0, z1); } /* Final step, including error bound */ _arb_gamma_upper_fmpq_step_bsplit(Gz1, a, z0, z, Gz0, expmz0, abs_tol, wp); arb_set(res, Gz1); bb_cleanup: arb_clear(t); arb_clear(z0); arb_clear(z1); arb_clear(Gz0); arb_clear(Gz1); arb_clear(expmz0); mag_clear(AE); } int arb_hypgeom_erf_bb(arb_t res, const arb_t z, int complementary, slong prec) { mag_t tol, tm; double x; arb_t t; fmpq_t a; slong wp_lower, wp_upper; int sgn; /* Avoid bit-burst algorithm for huge input and very close to 0. */ /* With better error bounds, this exit shouldn't be necessary. */ if (!arb_is_finite(z) || arf_cmpabs_ui(arb_midref(z), prec) > 0 || arf_cmpabs_2exp_si(arb_midref(z), -prec / 16) < 0) { return 0; } sgn = arf_sgn(arb_midref(z)); x = arf_get_d(arb_midref(z), ARF_RND_DOWN); x = fabs(x); if (!arb_is_exact(z)) { arb_t zmid; mag_t err; int success; arb_init(zmid); mag_init(err); arb_hypgeom_erf_propagated_error(err, z); arf_set(arb_midref(zmid), arb_midref(z)); success = arb_hypgeom_erf_bb(res, zmid, complementary, prec); if (success) arb_add_error_mag(res, err); arb_clear(zmid); mag_clear(err); return success; } mag_init(tol); mag_init(tm); arb_init(t); fmpq_init(a); /* Near 0, need to convert relative to absolute precision for erf */ if (x < 0.25 && !complementary) { wp_lower = prec + 20 + 0.001 * prec; arb_get_mag(tol, z); mag_mul_2exp_si(tol, tol, -wp_lower); wp_upper = wp_lower + (-MAG_EXP(tol)); } else if (complementary && sgn == 1 && x > 1.0) { wp_upper = prec + 20 + 0.001 * prec; /* We will have cancellation with the lower series */ arb_get_mag_lower(tm, z); mag_mul(tol, tm, tm); mag_expinv(tol, tol); mag_div(tol, tol, tm); mag_mul_2exp_si(tol, tol, -wp_upper); wp_lower = wp_upper + x * x * INV_LOG2; if (x >= 1) wp_lower = wp_lower - log(x) * INV_LOG2; wp_lower = FLINT_MAX(wp_lower, 30); wp_upper = FLINT_MAX(wp_upper, 30); } else { wp_lower = prec + 20 + 0.001 * prec; wp_upper = wp_lower; /* Can reduce precision with the upper series */ mag_set_ui_2exp_si(tol, 1, -wp_lower); if (x >= 1) wp_upper = wp_upper - x * x * INV_LOG2 - log(x) * INV_LOG2; wp_upper = FLINT_MAX(wp_upper, 30); } fmpq_set_si(a, 1, 2); arb_sqr(t, z, FLINT_MAX(wp_lower, wp_upper)); _arb_gamma_upper_fmpq_bb(res, a, t, tol, wp_lower, wp_upper); arb_const_sqrt_pi(t, wp_upper); arb_div(res, res, t, wp_upper); if (complementary) { if (sgn < 0) { arb_sub_ui(res, res, 2, prec); arb_neg(res, res); } } else { arb_sub_ui(res, res, 1, prec); if (sgn > 0) arb_neg(res, res); } mag_clear(tol); mag_clear(tm); arb_clear(t); fmpq_clear(a); return 1; } void arb_hypgeom_erf(arb_t res, const arb_t z, slong prec) { double abs_z2, log_z; double log2_err, err_prev; slong acc, prec2, wp, N; double x; if (!arb_is_finite(z)) { arb_indeterminate(res); return; } if (arb_is_zero(z)) { arb_zero(res); return; } if (arf_cmpabs_2exp_si(arb_midref(z), -prec / 16) < 0) { wp = prec + 20 + FLINT_BIT_COUNT(prec); arb_hypgeom_erf_1f1(res, z, prec, wp); return; } if (arf_cmpabs_2exp_si(arb_midref(z), 60) > 0) { arb_hypgeom_erf_one_eps(res, z); return; } /* exp(-z^2) / z * N! / z^(2N) < 2^p */ x = arf_get_d(arb_midref(z), ARF_RND_DOWN); x = fabs(x); acc = arb_rel_accuracy_bits(z); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + x * x * INV_LOG2 + 32); if (x * x * INV_LOG2 > prec) { arb_hypgeom_erf_one_eps(res, z); return; } if (prec > 30000 && x > 150.0 / exp(4e-3 * sqrt(prec)) && x < 0.6 * sqrt(prec)) { if (arb_hypgeom_erf_bb(res, z, 0, prec)) return; } /* Can we use the asymptotic expansion? */ if (x > 2.0) { prec2 = prec + 5 + FLINT_BIT_COUNT(prec); abs_z2 = x * x; log_z = 0.5 * log(abs_z2); if ((x * x + log_z) * INV_LOG2 > prec) { arb_hypgeom_erf_one_eps(res, z); return; } wp = prec - x * x * INV_LOG2 - log_z * INV_LOG2 + 10; wp = FLINT_MAX(wp, 30); err_prev = 0.0; for (N = 1; ; N++) { log2_err = -x * x - (2 * N + 1) * log_z + N * (log(N) - 1.0); log2_err *= INV_LOG2; if (log2_err > err_prev) break; if (log2_err < -prec2 - 10) { arb_hypgeom_erf_asymp(res, z, N, 0, prec, wp); return; } err_prev = log2_err; } } wp = prec + 10 + FLINT_BIT_COUNT(prec); arb_hypgeom_erf_1f1(res, z, prec, wp); } void arb_hypgeom_erfc(arb_t res, const arb_t z, slong prec) { double x, abs_z2, log_z; slong acc, prec2, wp, N; if (!arb_is_finite(z)) { arb_indeterminate(res); return; } if (arb_is_zero(z)) { arb_one(res); return; } if (arf_cmp_si(arb_midref(z), 1) <= 0) { arb_hypgeom_erf(res, z, prec + 5); arb_sub_ui(res, res, 1, prec); arb_neg(res, res); return; } acc = arb_rel_accuracy_bits(z); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); prec = FLINT_MIN(prec, acc + 32); /* Super-huge -- we only need one term of the asymptotic expansion */ if (arf_cmpabs_2exp_si(arb_midref(z), prec / 2 + 10) > 0) { arb_hypgeom_erf_asymp(res, z, 1, 1, prec, prec); return; } x = arf_get_d(arb_midref(z), ARF_RND_DOWN); x = fabs(x); if (prec > 30000 && x > 150.0 / exp(4e-3 * sqrt(prec)) && x < 0.8 * sqrt(prec) + 0.65e-14 * pow(prec, 3) + 1.5e-33*pow(prec, 6)) { if (arb_hypgeom_erf_bb(res, z, 1, prec)) return; } if (arf_cmpabs_2exp_si(arb_midref(z), 30) > 0) { log_z = ARF_EXP(arb_midref(z)) * LOG2; } else { abs_z2 = x * x; log_z = 0.5 * log(abs_z2); } /* Can we use the asymptotic expansion? */ /* N! / z^(2N) < 2^p */ if (x > 2.0) { double log2_err, err_prev; prec2 = prec + 5 + FLINT_BIT_COUNT(prec); err_prev = 0.0; for (N = 1; ; N++) { log2_err = -(2 * N) * log_z + N * (log(N) - 1.0); log2_err *= INV_LOG2; if (log2_err > err_prev) break; if (log2_err < -prec - 5) { arb_hypgeom_erf_asymp(res, z, N, 1, prec, prec2); return; } err_prev = log2_err; } } /* Compute via 1F1 - with cancellation */ if (x >= 1.0) wp = prec + (x * x + log_z) * INV_LOG2; else wp = prec - log_z * INV_LOG2; wp = wp + 10 + FLINT_BIT_COUNT(prec); arb_hypgeom_erf_1f1(res, z, wp, wp); arb_sub_ui(res, res, 1, prec); arb_neg(res, res); } arb-2.22.1/arb_hypgeom/erf_series.c000066400000000000000000000034531417376376500171600ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_erf_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { arb_t c; arb_init(c); arb_hypgeom_erf(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u; slong ulen; t = _arb_vec_init(len); u = _arb_vec_init(len); /* erf(h(x)) = integral(h'(x) exp(-h(x)^2)) * (2/sqrt(pi)) */ ulen = FLINT_MIN(len, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); _arb_vec_neg(u, u, ulen); _arb_poly_exp_series(u, u, ulen, len, prec); _arb_poly_derivative(t, h, hlen, prec); _arb_poly_mullow(g, u, len, t, hlen - 1, len, prec); _arb_poly_integral(g, g, len, prec); arb_const_sqrt_pi(t, prec); arb_inv(t, t, prec); arb_mul_2exp_si(t, t, 1); _arb_vec_scalar_mul(g, g, len, t, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, len); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_erf_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, len); _arb_hypgeom_erf_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/erfc_series.c000066400000000000000000000036161417376376500173240ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_erfc_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { arb_t c; arb_init(c); arb_hypgeom_erfc(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u; slong ulen; t = _arb_vec_init(len); u = _arb_vec_init(len); /* erfc(h(x)) = integral(-h'(x) exp(-h(x)^2)) * (2/sqrt(pi)) */ ulen = FLINT_MIN(len, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); _arb_vec_neg(u, u, ulen); _arb_poly_exp_series(u, u, ulen, len, prec); _arb_poly_derivative(t, h, hlen, prec); _arb_poly_mullow(g, u, len, t, hlen - 1, len, prec); _arb_poly_integral(g, g, len, prec); arb_const_sqrt_pi(t, prec); arb_inv(t, t, prec); arb_mul_2exp_si(t, t, 1); _arb_vec_scalar_mul(g, g, len, t, prec); _arb_vec_neg(g, g, len); _arb_vec_clear(t, len); _arb_vec_clear(u, len); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_erfc_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (len == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_one(g); return; } arb_poly_fit_length(g, len); _arb_hypgeom_erfc_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/erfi_series.c000066400000000000000000000034151417376376500173270ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_erfi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { arb_t c; arb_init(c); arb_hypgeom_erfi(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u; slong ulen; t = _arb_vec_init(len); u = _arb_vec_init(len); /* erfi(h(x)) = integral(h'(x) exp(h(x)^2)) * (2/sqrt(pi)) */ ulen = FLINT_MIN(len, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); _arb_poly_exp_series(u, u, ulen, len, prec); _arb_poly_derivative(t, h, hlen, prec); _arb_poly_mullow(g, u, len, t, hlen - 1, len, prec); _arb_poly_integral(g, g, len, prec); arb_const_sqrt_pi(t, prec); arb_inv(t, t, prec); arb_mul_2exp_si(t, t, 1); _arb_vec_scalar_mul(g, g, len, t, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, len); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_erfi_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, len); _arb_hypgeom_erfi_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/erfinv.c000066400000000000000000000323411417376376500163210ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "arb_fmpz_poly.h" /* Actually an enclosure for |x| < 0.99. */ static void arb_erfinv_approx_tiny(arb_t res, const arb_t x, slong prec) { arb_t t; mag_t err; arb_init(t); mag_init(err); arb_get_mag(err, x); mag_pow_ui(err, err, 3); arb_const_sqrt_pi(t, prec); arb_mul_2exp_si(t, t, -1); arb_mul(res, x, t, prec); arb_add_error_mag(res, err); arb_clear(t); mag_clear(err); } /* First terms of asymptotic expansion. */ /* http://www.ams.org/journals/mcom/1976-30-136/S0025-5718-1976-0421040-7/S0025-5718-1976-0421040-7.pdf */ static double erfinv_approx_big(double one_sub_x) { double eta, l, y; eta = -log(one_sub_x*sqrt(3.1415926535897932)); l = log(eta); y = sqrt(eta - 0.5*l + (0.25*l - 0.5)/eta + (1/16.*l*l - 3/8.*l + 7./8)/(eta*eta) + (l*l*l/48 - 7*l*l/32 + 17*l/16 - 107./48)/(eta*eta*eta) + (l*l*l*l/128 - 23*l*l*l/192 + 29*l*l/32 - 31*l/8 + 1489/192.)/(eta*eta*eta*eta)); return y; } /* First terms of asymptotic expansion, when a double can overflow. */ static void arb_erfinv_approx_huge(arb_t res, const arb_t one_minus_x, slong prec) { arb_t eta, l, y; fmpz c[5]; arb_ptr poly; mag_t err; arb_init(eta); arb_init(l); arb_init(y); mag_init(err); poly = _arb_vec_init(5); arb_const_sqrt_pi(eta, prec); arb_mul(eta, eta, one_minus_x, prec); arb_log(eta, eta, prec); arb_neg(eta, eta); arb_log(l, eta, prec); arb_mul_ui(y, eta, 12, prec); arb_inv(y, y, prec); arb_mul_2exp_si(poly + 0, l, -1); arb_neg(poly + 0, poly + 0); c[0] = -2 * 3; c[1] = 3; _arb_fmpz_poly_evaluate_arb(poly + 1, c, 2, l, prec); c[0] = 14 * 9; c[1] = -6 * 9; c[2] = 9; _arb_fmpz_poly_evaluate_arb(poly + 2, c, 3, l, prec); c[0] = -214 * 18; c[1] = 102 * 18; c[2] = -21 * 18; c[3] = 2 * 18; _arb_fmpz_poly_evaluate_arb(poly + 3, c, 4, l, prec); c[0] = 2978 * 54; c[1] = -1488 * 54; c[2] = 348 * 54; c[3] = -46 * 54; c[4] = 3 * 54; _arb_fmpz_poly_evaluate_arb(poly + 4, c, 5, l, prec); _arb_poly_evaluate(res, poly, 5, y, prec); arb_add(res, res, eta, prec); arb_sqrt(res, res, prec); /* Should be an enclosure for 1-x < 1e-300 (but not proved). */ arb_get_mag(err, res); mag_mul_2exp_si(err, err, -50); arb_clear(eta); arb_clear(l); arb_clear(y); mag_clear(err); _arb_vec_clear(poly, 5); } /* Adapted from https://people.maths.ox.ac.uk/gilesm/codes/erfinv/ with permission */ /* Only good up to about 1 - 1e-15 */ /* Todo: use a good approximation for erfcinv */ static double erfinv_approx(double x, double one_sub_x) { double w, p; w = -log(one_sub_x * (1.0 + x)); if (w < 6.250000) { w = w - 3.125000; p = -3.6444120640178196996e-21; p = -1.685059138182016589e-19 + p*w; p = 1.2858480715256400167e-18 + p*w; p = 1.115787767802518096e-17 + p*w; p = -1.333171662854620906e-16 + p*w; p = 2.0972767875968561637e-17 + p*w; p = 6.6376381343583238325e-15 + p*w; p = -4.0545662729752068639e-14 + p*w; p = -8.1519341976054721522e-14 + p*w; p = 2.6335093153082322977e-12 + p*w; p = -1.2975133253453532498e-11 + p*w; p = -5.4154120542946279317e-11 + p*w; p = 1.051212273321532285e-09 + p*w; p = -4.1126339803469836976e-09 + p*w; p = -2.9070369957882005086e-08 + p*w; p = 4.2347877827932403518e-07 + p*w; p = -1.3654692000834678645e-06 + p*w; p = -1.3882523362786468719e-05 + p*w; p = 0.0001867342080340571352 + p*w; p = -0.00074070253416626697512 + p*w; p = -0.0060336708714301490533 + p*w; p = 0.24015818242558961693 + p*w; p = 1.6536545626831027356 + p*w; } else if (w < 16.000000) { w = sqrt(w) - 3.250000; p = 2.2137376921775787049e-09; p = 9.0756561938885390979e-08 + p*w; p = -2.7517406297064545428e-07 + p*w; p = 1.8239629214389227755e-08 + p*w; p = 1.5027403968909827627e-06 + p*w; p = -4.013867526981545969e-06 + p*w; p = 2.9234449089955446044e-06 + p*w; p = 1.2475304481671778723e-05 + p*w; p = -4.7318229009055733981e-05 + p*w; p = 6.8284851459573175448e-05 + p*w; p = 2.4031110387097893999e-05 + p*w; p = -0.0003550375203628474796 + p*w; p = 0.00095328937973738049703 + p*w; p = -0.0016882755560235047313 + p*w; p = 0.0024914420961078508066 + p*w; p = -0.0037512085075692412107 + p*w; p = 0.005370914553590063617 + p*w; p = 1.0052589676941592334 + p*w; p = 3.0838856104922207635 + p*w; } else { w = sqrt(w) - 5.000000; p = -2.7109920616438573243e-11; p = -2.5556418169965252055e-10 + p*w; p = 1.5076572693500548083e-09 + p*w; p = -3.7894654401267369937e-09 + p*w; p = 7.6157012080783393804e-09 + p*w; p = -1.4960026627149240478e-08 + p*w; p = 2.9147953450901080826e-08 + p*w; p = -6.7711997758452339498e-08 + p*w; p = 2.2900482228026654717e-07 + p*w; p = -9.9298272942317002539e-07 + p*w; p = 4.5260625972231537039e-06 + p*w; p = -1.9681778105531670567e-05 + p*w; p = 7.5995277030017761139e-05 + p*w; p = -0.00021503011930044477347 + p*w; p = -0.00013871931833623122026 + p*w; p = 1.0103004648645343977 + p*w; p = 4.8499064014085844221 + p*w; } return p*x; } /* floating-point approximation of erfinv(x), to be validated */ static void arb_hypgeom_erfinv_guess(arb_t res, const arb_t x, const arb_t one_sub_x, slong extraprec) { if (arf_cmpabs_2exp_si(arb_midref(x), -30) < 0) { arb_erfinv_approx_tiny(res, x, 128); } else if (arf_cmpabs_2exp_si(arb_midref(one_sub_x), -52) >= 0) { double y; y = erfinv_approx(arf_get_d(arb_midref(x), ARF_RND_NEAR), arf_get_d(arb_midref(one_sub_x), ARF_RND_NEAR)); arf_set_d(arb_midref(res), y); mag_set_d(arb_radref(res), ldexp(y, -50)); } else if (arf_cmpabs_2exp_si(arb_midref(one_sub_x), -1000) >= 0) { double t, y; t = arf_get_d(arb_midref(one_sub_x), ARF_RND_NEAR); y = erfinv_approx_big(t); arf_set_d(arb_midref(res), y); mag_set_d(arb_radref(res), ldexp(y, -26 + 0.1 * log(t))); } else { arb_erfinv_approx_huge(res, one_sub_x, 30 + extraprec); } } void arb_hypgeom_erfinv_precise(arb_t res, const arb_t x, const arb_t one_sub_x, int near_one, slong prec) { slong wp; arb_t f, fprime, root, mid, t; slong extraprec, goal; int validated; if (arb_is_zero(x)) { arb_zero(res); return; } arb_init(f); arb_init(fprime); arb_init(root); arb_init(mid); arb_init(t); goal = prec * 1.001 + 5; extraprec = fmpz_bits(ARF_EXPREF(arb_midref(one_sub_x))); extraprec += 15; /* Start with a guess */ arb_hypgeom_erfinv_guess(root, x, one_sub_x, extraprec); validated = 0; while (!validated || arb_rel_accuracy_bits(root) <= goal) { /* We should get double the accuracy. */ wp = arb_rel_accuracy_bits(root) * 2 + extraprec; /* But don't set the precision unrealistically high. */ wp = FLINT_MIN(wp, 4 * (goal + extraprec)); /* In case of quadratic convergence, avoid doing the penultimate iteration at higher precision than needed. */ if (validated && wp < goal && wp > 0.7 * goal + 2 * extraprec) wp = goal / 2 + 2 * extraprec; arb_set(mid, root); mag_zero(arb_radref(mid)); /* f(y) = erf(y) - x OR (1 - x) - erfc(y) */ /* 1/f'(y) = exp(y^2) * sqrt(pi)/2 */ if (near_one) { arb_hypgeom_erfc(f, mid, wp); arb_sub(f, one_sub_x, f, wp); } else { arb_hypgeom_erf(f, mid, wp); arb_sub(f, f, x, wp); } arb_sqr(fprime, root, wp); arb_exp(fprime, fprime, wp); arb_const_sqrt_pi(t, wp); arb_mul(fprime, fprime, t, wp); arb_mul_2exp_si(fprime, fprime, -1); arb_mul(t, f, fprime, wp); arb_sub(t, mid, t, wp); if (arb_contains_interior(root, t)) { /* Interval Newton proves inclusion. */ /* printf("newton %d -> 1 %ld: ", validated, wp); arb_printd(t, 50); printf("\n"); */ validated = 1; arb_swap(root, t); } else { /* Try to improve the guess with a floating-point Newton step. */ /* printf("newton %d -> 0 %ld: ", validated, wp); arb_printd(t, 50); printf("\n"); */ arb_sqr(fprime, mid, wp); arb_exp(fprime, fprime, wp); arb_const_sqrt_pi(t, wp); arb_mul(fprime, fprime, t, wp); arb_mul_2exp_si(fprime, fprime, -1); arb_mul(t, f, fprime, wp); /* The Newton correction is a good guess for the error. */ arb_get_mag(arb_radref(root), t); mag_mul_2exp_si(arb_radref(root), arb_radref(root), 1); arb_sub(t, mid, t, wp); arf_swap(arb_midref(root), arb_midref(t)); /* Use more working precision to get out of any numerical difficulties */ extraprec = extraprec * 1.05 + 10; validated = 0; } /* Something went wrong. Could fall back to bisection if we want to guarantee convergence? */ if (extraprec > 10 * prec + 10000) { arb_indeterminate(root); break; } } arb_set_round(res, root, prec); arb_clear(f); arb_clear(fprime); arb_clear(root); arb_clear(mid); arb_clear(t); } static slong arb_adjust_precision(slong prec, slong acc) { acc = FLINT_MIN(acc, prec); acc = FLINT_MAX(acc, 0); prec = FLINT_MIN(prec, acc + MAG_BITS); prec = FLINT_MAX(prec, 2); return prec; } void arb_hypgeom_erfinv(arb_t res, const arb_t x, slong prec) { arb_t x1; int near_one; if (arb_is_zero(x)) { arb_zero(res); return; } if (arf_sgn(arb_midref(x)) < 0) { arb_neg(res, x); arb_hypgeom_erfinv(res, res, prec); arb_neg(res, res); return; } if (arb_is_one(x)) { arb_pos_inf(res); return; } arb_init(x1); near_one = ARF_EXP(arb_midref(x)) == 0; if (near_one) { arb_sub_ui(x1, x, 1, ARF_PREC_EXACT); arb_neg(x1, x1); } else { arb_sub_ui(x1, x, 1, prec + 30); arb_neg(x1, x1); } if (arb_is_positive(x1)) { mag_t err; slong acc; arb_t xm; mag_init(err); arb_init(xm); /* Propagated error bound based on derivative. */ /* erfinv'(x) <= (1/2) sqrt(pi) / (1 - |x|) */ arb_get_mag_lower(err, x1); mag_inv(err, err); mag_mul(err, err, arb_radref(x)); mag_mul_ui(err, err, 227); mag_mul_2exp_si(err, err, -8); acc = arb_rel_accuracy_bits(x); prec = arb_adjust_precision(prec, acc); arb_get_mid_arb(xm, x); if (near_one) { arb_sub_ui(x1, xm, 1, ARF_PREC_EXACT); arb_neg(x1, x1); } else { arb_sub_ui(x1, xm, 1, prec + 30); arb_neg(x1, x1); } arb_hypgeom_erfinv_precise(res, xm, x1, near_one, prec); arb_add_error_mag(res, err); mag_clear(err); arb_clear(xm); } else { arb_indeterminate(res); } arb_clear(x1); } void arb_hypgeom_erfcinv(arb_t res, const arb_t x1, slong prec) { arb_t x; if (arb_is_one(x1)) { arb_zero(res); return; } arb_init(x); if (arf_cmp_d(arb_midref(x1), 0.01) <= 0 && arb_is_positive(x1)) { mag_t err; slong acc; arb_t x1m, xm; mag_init(err); arb_init(x1m); arb_init(xm); /* Propagated error bound based on derivative. */ /* erfinv'(x) <= (1/2) sqrt(pi) / (1 - |x|) */ arb_get_mag_lower(err, x1); mag_inv(err, err); mag_mul(err, err, arb_radref(x1)); mag_mul_ui(err, err, 227); mag_mul_2exp_si(err, err, -8); acc = arb_rel_accuracy_bits(x1); prec = arb_adjust_precision(prec, acc); arb_get_mid_arb(x1m, x1); arb_sub_ui(xm, x1m, 1, 2 * prec + 100); arb_neg(xm, xm); arb_hypgeom_erfinv_precise(res, xm, x1m, 1, prec); arb_add_error_mag(res, err); mag_clear(err); arb_clear(xm); arb_clear(x1m); } else { arb_sub_ui(x, x1, 1, 2 * prec + 100); arb_neg(x, x); arb_hypgeom_erfinv(res, x, prec); } arb_clear(x); } arb-2.22.1/arb_hypgeom/fresnel_series.c000066400000000000000000000057571417376376500200530ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_fresnel_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, int normalized, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_hypgeom_fresnel(s, c, h, normalized, prec); if (s != NULL) _arb_vec_zero(s + 1, len - 1); if (c != NULL) _arb_vec_zero(c + 1, len - 1); } else { arb_t s0, c0; arb_ptr t, u, v; slong ulen; arb_init(s0); arb_init(c0); arb_hypgeom_fresnel((s != NULL) ? s0 : NULL, (c != NULL) ? c0 : NULL, h, normalized, prec); t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(len); /* normalized: */ /* C(h(x)) = integral(h'(x) cos(-(pi/2) h(x)^2)) */ /* S(h(x)) = -integral(h'(x) sin(-(pi/2) h(x)^2)) */ ulen = FLINT_MIN(len, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); _arb_vec_neg(u, u, ulen); if (normalized) { _arb_vec_scalar_mul_2exp_si(u, u, ulen, -1); _arb_poly_sin_cos_pi_series(u, v, u, ulen, len, prec); } else { _arb_poly_sin_cos_series(u, v, u, ulen, len, prec); } _arb_poly_derivative(t, h, hlen, prec); if (s != NULL) { _arb_poly_mullow(s, u, len, t, hlen - 1, len, prec); _arb_poly_integral(s, s, len, prec); _arb_vec_neg(s, s, len); arb_swap(s, s0); } if (c != NULL) { _arb_poly_mullow(c, v, len, t, hlen - 1, len, prec); _arb_poly_integral(c, c, len, prec); arb_swap(c, c0); } _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, len); arb_clear(s0); arb_clear(c0); } } void arb_hypgeom_fresnel_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, int normalized, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { if (s != NULL) arb_poly_zero(s); if (c != NULL) arb_poly_zero(c); return; } if (s != NULL) arb_poly_fit_length(s, len); if (c != NULL) arb_poly_fit_length(c, len); _arb_hypgeom_fresnel_series((s != NULL) ? s->coeffs : NULL, (c != NULL) ? c->coeffs : NULL, h->coeffs, hlen, normalized, len, prec); if (s != NULL) _arb_poly_set_length(s, len); if (c != NULL) _arb_poly_set_length(c, len); if (s != NULL) _arb_poly_normalise(s); if (c != NULL) _arb_poly_normalise(c); } arb-2.22.1/arb_hypgeom/gamma.c000066400000000000000000000235011417376376500161100ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "bernoulli.h" /* tuning factor */ double GAMMA_STIRLING_BETA = 0.0; #define PI 3.1415926535897932385 static slong choose_n(double log2z, double argz, int digamma, slong prec) { double argf, boundn, boundn_best; slong n, nbest; argf = 1.0 / cos(0.5 * argz); argf = log(argf) * (1. / log(2)); boundn_best = 1e300; nbest = 1; for (n = 1; ; n++) { if (digamma) boundn = bernoulli_bound_2exp_si(2*n) - (2*n)*log2z + (2*n+1)*argf; else boundn = bernoulli_bound_2exp_si(2*n) - (2*n-1)*log2z + (2*n)*argf; /* success */ if (boundn <= -prec) return n; if (boundn < boundn_best) { nbest = n; boundn_best = boundn; } /* if the term magnitude does not decrease, r is too small */ if (boundn > 1) { /* printf("failure: prec = %ld, nbound_best = %f [%ld, %ld]\n", prec, boundn_best, n, nbest); */ return nbest; } } } static void choose_small(int * reflect, slong * r, slong * n, double x, double y, int use_reflect, int digamma, slong prec) { double w, argz, log2z, BETA; slong rr; /* use reflection formula if very negative */ if (x < -5.0 && use_reflect) { *reflect = 1; x = 1.0 - x; } else { *reflect = 0; } BETA = GAMMA_STIRLING_BETA; if (BETA < 0.12) { if (prec <= 32768) BETA = 0.17; else if (prec <= 131072) BETA = 0.20; else BETA = 0.24; } /* argument reduction until |z| >= w */ w = FLINT_MAX(1.0, BETA * prec); rr = 0; while (x < 1.0 || x*x + y*y < w*w) { x++; rr++; } log2z = 0.5 * log(x*x + y*y) * 1.44269504088896341; argz = atan2(y, x); *r = rr; *n = choose_n(log2z, argz, digamma, prec); } static void choose_large(int * reflect, slong * r, slong * n, const arf_t a, const arf_t b, int use_reflect, int digamma, slong prec) { if (use_reflect && arf_sgn(a) < 0) *reflect = 1; else *reflect = 0; *r = 0; /* so big that we will certainly have n = 0 */ if (arf_cmpabs_2exp_si(a, WORD_MAX / 8) >= 0 || arf_cmpabs_2exp_si(b, WORD_MAX / 8) >= 0) { *n = 0; } else { slong ab, bb; double log2z, argz; ab = arf_abs_bound_lt_2exp_si(a); bb = arf_abs_bound_lt_2exp_si(b); log2z = FLINT_MAX(ab, bb); /* piecewise approximation of the argument */ if (arf_is_zero(b)) { if ((arf_sgn(a) < 0) && !(*reflect)) argz = PI; else argz = 0.0; } else { if ((arf_sgn(a) < 0) && !(*reflect)) if (arf_cmpabs(a, b) <= 0) argz = PI * 0.75; else argz = PI; else if (arf_cmpabs(a, b) <= 0) argz = PI * 0.25; else argz = PI * 0.5; } if (argz == PI) *n = 0; else *n = choose_n(log2z, argz, digamma, prec); } } void acb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const acb_t z, int use_reflect, int digamma, slong prec) { const arf_struct * a = arb_midref(acb_realref(z)); const arf_struct * b = arb_midref(acb_imagref(z)); if (!arf_is_finite(a) || !arf_is_finite(b)) { *reflect = *r = *n = 0; } else if (arf_cmpabs_2exp_si(a, 40) > 0 || arf_cmpabs_2exp_si(b, 40) > 0) { choose_large(reflect, r, n, a, b, use_reflect, digamma, prec); } else { choose_small(reflect, r, n, arf_get_d(a, ARF_RND_UP), arf_get_d(b, ARF_RND_UP), use_reflect, digamma, prec); } } void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec) { const arf_struct * a = arb_midref(x); if (arf_is_inf(a) || arf_is_nan(a)) { *reflect = *r = *n = 0; } else if (arf_cmpabs_2exp_si(a, 40) > 0) { arf_t b; arf_init(b); choose_large(reflect, r, n, a, b, use_reflect, digamma, prec); arf_clear(b); } else { choose_small(reflect, r, n, arf_get_d(a, ARF_RND_UP), 0.0, use_reflect, digamma, prec); } } void arb_gamma_stirling_bound(mag_ptr err, const arb_t x, slong k0, slong knum, slong n); void arb_hypgeom_gamma_stirling_inner(arb_t s, const arb_t z, slong N, slong prec) { arb_t logz, t; mag_t err; mag_init(err); arb_init(t); arb_init(logz); arb_gamma_stirling_bound(err, z, 0, 1, N); /* t = (z-0.5)*log(z) - z + log(2*pi)/2 */ arb_log(logz, z, prec); arb_one(t); arb_mul_2exp_si(t, t, -1); arb_sub(t, z, t, prec); arb_mul(t, logz, t, prec); arb_sub(t, t, z, prec); arb_const_log_sqrt2pi(logz, prec); arb_add(t, t, logz, prec); /* sum part */ if (prec <= 128 || (prec <= 768 && N <= 40) || (prec <= 2048 && N <= 16)) arb_hypgeom_gamma_stirling_sum_horner(s, z, N, prec); else arb_hypgeom_gamma_stirling_sum_improved(s, z, N, 0, prec); arb_add(s, s, t, prec); mag_add(arb_radref(s), arb_radref(s), err); arb_clear(t); arb_clear(logz); mag_clear(err); } int arb_hypgeom_gamma_exact(arb_t res, const arb_t x, int reciprocal, slong prec) { if (arb_is_exact(x)) { const arf_struct * mid = arb_midref(x); if (arf_is_special(mid)) { if (!reciprocal && arf_is_pos_inf(mid)) arb_set(res, x); else if (arf_is_nan(mid) || arf_is_neg_inf(mid) || !reciprocal) arb_indeterminate(res); else arb_zero(res); return 1; } else if (reciprocal && arf_is_int(mid) && arf_sgn(mid) < 0) { arb_zero(res); return 1; } else { /* todo: cutoffs for larger denominators */ /* fast gamma(n), gamma(n/2) or gamma(n/4), ... */ if (arf_cmpabs_2exp_si(mid, prec) < 0 && (arf_is_int_2exp_si(mid, -2) || (prec > 1000 && arf_is_int_2exp_si(mid, -prec / 50)))) { fmpq_t a; fmpq_init(a); arf_get_fmpq(a, mid); arb_gamma_fmpq(res, a, prec + 2 * reciprocal); if (reciprocal) arb_inv(res, res, prec); fmpq_clear(a); return 1; } } } return 0; } void arb_hypgeom_gamma_stirling(arb_t y, const arb_t x, int reciprocal, slong prec) { int reflect; slong r, n, wp; arb_t t, u, v; double acc; /* todo: for large x (if exact or accurate enough), increase precision */ acc = arb_rel_accuracy_bits(x); acc = FLINT_MAX(acc, 0); wp = FLINT_MIN(prec, acc + 20); wp = FLINT_MAX(wp, 2); wp = wp + FLINT_BIT_COUNT(wp); if (acc < 3) /* try to avoid divisions blowing up */ { if (arf_cmp_d(arb_midref(x), -0.5) < 0) { reflect = 1; r = 0; } else if (arf_cmp_si(arb_midref(x), 1) < 0) { reflect = 0; r = 1; } else { reflect = 0; r = 0; } n = 1; } else { arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 0, wp); } arb_init(t); arb_init(u); arb_init(v); if (reflect) { arb_sub_ui(t, x, 1, wp); arb_neg(t, t); arb_hypgeom_rising_ui_rec(u, t, r, wp); arb_const_pi(v, wp); arb_mul(u, u, v, wp); arb_add_ui(t, t, r, wp); arb_hypgeom_gamma_stirling_inner(v, t, n, wp); if (reciprocal) { /* rgamma(x) = gamma(1-x+r) sin(pi x) / ((rf(1-x, r) * pi) */ arb_exp(v, v, wp); arb_sin_pi(t, x, wp); arb_mul(v, v, t, wp); arb_mul(y, u, v, wp); arb_div(y, v, u, prec); } else { /* gamma(x) = (rf(1-x, r) * pi) rgamma(1-x+r) csc(pi x) */ arb_neg(v, v); arb_exp(v, v, wp); arb_csc_pi(t, x, wp); arb_mul(v, v, t, wp); arb_mul(y, v, u, prec); } } else { arb_add_ui(t, x, r, wp); arb_hypgeom_gamma_stirling_inner(u, t, n, wp); if (reciprocal) { /* rgamma(x) = rf(x,r) rgamma(x+r) */ arb_neg(u, u); arb_exp(u, u, prec); arb_hypgeom_rising_ui_rec(v, x, r, wp); arb_mul(y, v, u, prec); } else { /* gamma(x) = gamma(x+r) / rf(x,r) */ arb_exp(u, u, prec); arb_hypgeom_rising_ui_rec(v, x, r, wp); arb_div(y, u, v, prec); } } arb_clear(t); arb_clear(u); arb_clear(v); } void arb_hypgeom_gamma(arb_t y, const arb_t x, slong prec) { if (arb_hypgeom_gamma_exact(y, x, 0, prec)) return; if (arb_hypgeom_gamma_taylor(y, x, 0, prec)) return; arb_hypgeom_gamma_stirling(y, x, 0, prec); } void arb_hypgeom_rgamma(arb_t y, const arb_t x, slong prec) { if (arb_hypgeom_gamma_exact(y, x, 1, prec)) return; if (arb_hypgeom_gamma_taylor(y, x, 1, prec)) return; arb_hypgeom_gamma_stirling(y, x, 1, prec); } arb-2.22.1/arb_hypgeom/gamma_fmpq.c000066400000000000000000000400171417376376500171340ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arb_hypgeom.h" #include "hypgeom.h" void arb_gamma_const_1_3_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t, u; slong wp = prec + 4 + 2 * FLINT_BIT_COUNT(prec); arb_init(t); arb_init(u); hypgeom_init(series); fmpz_poly_set_str(series->A, "1 1"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "4 5 -46 108 -72"); fmpz_poly_set_str(series->Q, "4 0 0 0 512000"); prec += FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, wp, wp); arb_sqrt_ui(u, 10, wp); arb_mul(t, t, u, wp); arb_const_pi(u, wp); arb_pow_ui(u, u, 4, wp); arb_mul_ui(u, u, 12, wp); arb_mul(s, s, u, wp); arb_div(s, s, t, wp); arb_root_ui(s, s, 2, wp); arb_root_ui(s, s, 3, prec); hypgeom_clear(series); arb_clear(t); arb_clear(u); } ARB_DEF_CACHED_CONSTANT(arb_gamma_const_1_3, arb_gamma_const_1_3_eval) void arb_gamma_const_1_4_eval(arb_t x, slong prec) { arb_t t, u; slong wp = prec + 4 + 2 * FLINT_BIT_COUNT(prec); arb_init(t); arb_init(u); arb_one(t); arb_sqrt_ui(u, 2, wp); arb_agm(x, t, u, wp); arb_const_pi(t, wp); arb_mul_2exp_si(t, t, 1); arb_sqrt(u, t, wp); arb_mul(u, u, t, wp); arb_div(x, u, x, wp); arb_sqrt(x, x, wp); arb_clear(t); arb_clear(u); } ARB_DEF_CACHED_CONSTANT(arb_gamma_const_1_4, arb_gamma_const_1_4_eval) void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec); void arb_hypgeom_gamma_stirling_inner(arb_t s, const arb_t z, slong N, slong prec); void arb_hypgeom_gamma_fmpq_stirling(arb_t y, const fmpq_t a, slong prec) { int reflect; slong r, n, wp; arb_t x, t, u, v; wp = prec + FLINT_BIT_COUNT(prec); arb_init(x); arb_init(t); arb_init(u); arb_init(v); arb_set_fmpq(x, a, wp); arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 0, wp); if (reflect) { /* gamma(x) = (rf(1-x, r) * pi) / (gamma(1-x+r) sin(pi x)) */ fmpq_t b; fmpq_init(b); fmpz_sub(fmpq_numref(b), fmpq_denref(a), fmpq_numref(a)); fmpz_set(fmpq_denref(b), fmpq_denref(a)); arb_rising_fmpq_ui(u, b, r, wp); fmpq_clear(b); arb_const_pi(v, wp); arb_mul(u, u, v, wp); arb_sub_ui(t, x, 1, wp); arb_neg(t, t); arb_add_ui(t, t, r, wp); arb_hypgeom_gamma_stirling_inner(v, t, n, wp); arb_exp(v, v, wp); arb_sin_pi_fmpq(t, a, wp); arb_mul(v, v, t, wp); } else { /* gamma(x) = gamma(x+r) / rf(x,r) */ arb_add_ui(t, x, r, wp); arb_hypgeom_gamma_stirling_inner(u, t, n, wp); arb_exp(u, u, prec); arb_rising_fmpq_ui(v, a, r, wp); } arb_div(y, u, v, prec); arb_clear(t); arb_clear(u); arb_clear(v); arb_clear(x); } void arb_hypgeom_gamma_small_frac(arb_t y, unsigned int p, unsigned int q, slong prec) { slong wp = prec + 4; if (q == 1) { arb_one(y); } else if (q == 2) /* p = 1 */ { arb_const_sqrt_pi(y, prec); } else if (q == 3) { if (p == 1) { arb_gamma_const_1_3(y, prec); } else /* p = 2 */ { arb_t t; arb_init(t); arb_gamma_const_1_3(y, wp); arb_sqrt_ui(t, 3, wp); arb_mul(y, y, t, wp); arb_const_pi(t, wp); arb_div(y, t, y, prec); arb_mul_2exp_si(y, y, 1); arb_clear(t); } } else if (q == 4) { if (p == 1) { arb_gamma_const_1_4(y, prec); } else /* p = 3 */ { arb_t t; arb_init(t); arb_sqrt_ui(y, 2, wp); arb_const_pi(t, wp); arb_mul(y, y, t, wp); arb_gamma_const_1_4(t, wp); arb_div(y, y, t, prec); arb_clear(t); } } else if (q == 6) { arb_t t; arb_init(t); arb_const_pi(t, wp); arb_div_ui(t, t, 3, wp); arb_sqrt(t, t, wp); arb_set_ui(y, 2); arb_root_ui(y, y, 3, wp); arb_mul(t, t, y, wp); arb_gamma_const_1_3(y, wp); arb_mul(y, y, y, prec); if (p == 1) { arb_div(y, y, t, prec); } else /* p = 5 */ { arb_div(y, t, y, wp); arb_const_pi(t, wp); arb_mul(y, y, t, prec); arb_mul_2exp_si(y, y, 1); } arb_clear(t); } else { flint_printf("small fraction not implemented!\n"); flint_abort(); } } slong _arb_compute_bs_exponents(slong * tab, slong n); slong _arb_get_exp_pos(const slong * tab, slong step); static void bsplit2(arb_t P, arb_t Q, const fmpz_t zp, const fmpz_t zq, const slong * xexp, arb_srcptr xpow, ulong N, slong a, slong b, int cont, slong prec) { if (b - a == 1) { fmpz_t t; fmpz_init(t); fmpz_set(t, zp); fmpz_addmul_ui(t, zq, a + 1); arb_set_fmpz(P, t); arb_set(Q, P); fmpz_clear(t); } else { arb_t Pb, Qb; slong step, i, m; arb_init(Pb); arb_init(Qb); step = (b - a) / 2; m = a + step; bsplit2(P, Q, zp, zq, xexp, xpow, N, a, m, 1, prec); bsplit2(Pb, Qb, zp, zq, xexp, xpow, N, m, b, 1, prec); arb_mul(P, P, Pb, prec); arb_mul(Q, Q, Pb, prec); i = (step == 1) ? 0 : _arb_get_exp_pos(xexp, step); arb_addmul(Q, Qb, xpow + i, prec); arb_clear(Pb); arb_clear(Qb); } } static void bsplit3(arb_t P, arb_t Q, const fmpz_t zp, const fmpz_t zq, const slong * xexp, arb_srcptr xpow, ulong N, slong a, slong b, int cont, slong prec) { if (b - a == 1) { fmpz_t t; fmpz_init(t); arb_set(P, xpow + 0); /* N zq */ fmpz_set(t, zp); fmpz_submul_ui(t, zq, a + 1); /* zp - (a + 1) zq */ arb_set_fmpz(Q, t); fmpz_clear(t); } else { arb_t Pb, Qb; slong step, i, m; arb_init(Pb); arb_init(Qb); step = (b - a) / 2; m = a + step; bsplit3(P, Q, zp, zq, xexp, xpow, N, a, m, 1, prec); bsplit3(Pb, Qb, zp, zq, xexp, xpow, N, m, b, 1, prec); i = _arb_get_exp_pos(xexp, m - a); arb_mul(P, P, xpow + i, prec); if (b - m != m - a) arb_mul(P, P, xpow + 0, prec); arb_addmul(P, Q, Pb, prec); if (cont) { arb_mul(Q, Q, Qb, prec); } else { i = _arb_get_exp_pos(xexp, m - a); arb_mul(Q, xpow + i, xpow + i, prec); if (b - m != m - a) arb_mul(Q, Q, xpow + 0, prec); } arb_clear(Pb); arb_clear(Qb); } } double d_lambertw_branch1(double x); static ulong more_trailing_zeros(ulong N) { ulong bc, N2; bc = FLINT_BIT_COUNT(N); if (bc >= 8) { N2 = (N >> (bc - 5)) << (bc - 5); N2 += ((N2 != N) << (bc - 5)); return N2; } else { return N; } } #define C_LOG2 0.69314718055994530942 #define C_EXP1 2.7182818284590452354 static void build_bsplit_power_table(arb_ptr xpow, const slong * xexp, slong len, slong prec) { slong i; for (i = 1; i < len; i++) { if (xexp[i] == 2 * xexp[i-1]) { arb_mul(xpow + i, xpow + i - 1, xpow + i - 1, prec); } else if (xexp[i] == 2 * xexp[i-2]) /* prefer squaring if possible */ { arb_mul(xpow + i, xpow + i - 2, xpow + i - 2, prec); } else if (xexp[i] == 2 * xexp[i-1] + 1) { arb_mul(xpow + i, xpow + i - 1, xpow + i - 1, prec); arb_mul(xpow + i, xpow + i, xpow, prec); } else if (xexp[i] == 2 * xexp[i-2] + 1) { arb_mul(xpow + i, xpow + i - 2, xpow + i - 2, prec); arb_mul(xpow + i, xpow + i, xpow, prec); } else { flint_printf("power table has the wrong structure!\n"); flint_abort(); } } } /* assumes z in [1, 2] */ static void arb_hypgeom_gamma_fmpq_general_off1(arb_t res, const fmpq_t z, slong prec) { slong wp, N, n, n2, length, length2, wp2; double alpha; arb_t P, Q; slong *xexp, *xexp2; arb_ptr xpow; mag_t err, err2; wp = prec + 30; alpha = 0.52; /* tuning parameter between 0.5 and 1 */ N = alpha * C_LOG2 * wp; N = more_trailing_zeros(N); alpha = N / (C_LOG2 * wp); /* Terms in convergent series */ n = (1 - alpha) / d_lambertw((1 - alpha) / (alpha * C_EXP1)) * C_LOG2 * wp; /* Precision and terms in asymptotic series */ wp2 = wp * (1 - alpha); wp2 = FLINT_MAX(wp2, 30); n2 = (alpha - 1) / d_lambertw_branch1((alpha - 1) / (alpha * C_EXP1)) * C_LOG2 * wp; n2 = FLINT_MAX(n2, 2); /* binary splitting correctness */ mag_init(err); mag_init(err2); arb_init(P); arb_init(Q); /* compute the powers of x = N*zq that will appear (at least x^1) */ xexp = flint_calloc(2 * FLINT_BITS, sizeof(slong)); xexp2 = flint_calloc(2 * FLINT_BITS, sizeof(slong)); length = _arb_compute_bs_exponents(xexp, n); length2 = _arb_compute_bs_exponents(xexp2, n2); xpow = _arb_vec_init(FLINT_MAX(length, length2)); arb_set_fmpz(xpow + 0, fmpq_denref(z)); arb_mul_ui(xpow + 0, xpow + 0, N, wp); build_bsplit_power_table(xpow, xexp, length, wp); /* 1F1(1, 1+z, N) */ bsplit2(P, Q, fmpq_numref(z), fmpq_denref(z), xexp, xpow, N, 0, n, 0, wp); arb_div(P, Q, P, wp); /* Convergent series error bound: N^n / n! (1 + (N/n) + ...) */ mag_set_ui(err, N); mag_pow_ui(err, err, n); mag_rfac_ui(err2, n); mag_mul(err, err, err2); mag_set_ui(err2, N); mag_div_ui(err2, err2, n); mag_geom_series(err2, err2, 0); mag_mul(err, err, err2); arb_add_error_mag(P, err); /* divide 1F1 by z */ arb_mul_fmpz(P, P, fmpq_denref(z), wp); arb_div_fmpz(P, P, fmpq_numref(z), wp); arb_swap(res, P); build_bsplit_power_table(xpow, xexp2, length2, wp2); bsplit3(P, Q, fmpq_numref(z), fmpq_denref(z), xexp2, xpow, N, 0, n2, 0, wp2); arb_div(P, P, Q, wp2); /* 2F0 error bound (bounded by first omitted term) */ mag_fac_ui(err, n2); mag_set_ui_lower(err2, N); mag_pow_ui_lower(err2, err2, n2); mag_div(err, err, err2); arb_add_error_mag(P, err); /* N^z * exp(-N) * (1F1/z + 2F0/N) */ arb_div_ui(P, P, N, wp2); arb_add(res, res, P, wp); arb_set_ui(Q, N); arb_pow_fmpq(Q, Q, z, wp); arb_mul(res, res, Q, wp); arb_set_si(Q, -N); arb_exp(Q, Q, wp); arb_mul(res, res, Q, wp); _arb_vec_clear(xpow, FLINT_MAX(length, length2)); flint_free(xexp); flint_free(xexp2); arb_clear(P); arb_clear(Q); mag_clear(err); mag_clear(err2); } /* assumes z in (0, 1] */ void arb_hypgeom_gamma_fmpq_hyp(arb_t res, const fmpq_t z, slong prec) { fmpq_t t; fmpq_init(t); fmpq_add_ui(t, z, 1); arb_hypgeom_gamma_fmpq_general_off1(res, t, prec); arb_mul_fmpz(res, res, fmpq_denref(z), prec + 30); arb_div_fmpz(res, res, fmpq_numref(z), prec); fmpq_clear(t); } void arb_hypgeom_gamma_fmpq_outward(arb_t y, const fmpq_t x, slong prec) { fmpq_t a; fmpz_t n; fmpz p, q; slong m; arb_t t, u; fmpq_init(a); fmpz_init(n); arb_init(t); arb_init(u); /* write x = a + n with 0 < a <= 1 */ if (fmpz_is_one(fmpq_denref(x))) { fmpq_one(a); fmpz_sub_ui(n, fmpq_numref(x), 1); } else { fmpz_fdiv_qr(n, fmpq_numref(a), fmpq_numref(x), fmpq_denref(x)); fmpz_set(fmpq_denref(a), fmpq_denref(x)); } if (!fmpz_fits_si(n)) { flint_printf("gamma: too large fmpq to reduce to 0!\n"); flint_abort(); } m = fmpz_get_si(n); /* evaluate gamma(a) */ p = *fmpq_numref(a); q = *fmpq_denref(a); if (q == 1 || q == 2 || q == 3 || q == 4 || q == 6) { arb_hypgeom_gamma_small_frac(t, p, q, prec + 4 * (m != 0)); } else { arb_hypgeom_gamma_fmpq_hyp(t, a, prec + 4 * (m != 0)); } /* argument reduction */ if (m >= 0) { arb_rising_fmpq_ui(u, a, m, prec + 4); arb_mul(y, t, u, prec); } else { arb_rising_fmpq_ui(u, x, -m, prec + 4); arb_div(y, t, u, prec); } fmpq_clear(a); fmpz_clear(n); arb_clear(t); arb_clear(u); } int arb_hypgeom_gamma_fmpq_taylor(arb_t y, const fmpq_t x, slong prec) { fmpq_t a; fmpz_t n; slong m; arb_t t; int success; fmpq_init(a); fmpz_init(n); arb_init(t); success = 1; /* write x = a + n with 0 < a <= 1 */ if (fmpz_is_one(fmpq_denref(x))) { fmpq_one(a); fmpz_sub_ui(n, fmpq_numref(x), 1); } else { fmpz_fdiv_qr(n, fmpq_numref(a), fmpq_numref(x), fmpq_denref(x)); fmpz_set(fmpq_denref(a), fmpq_denref(x)); } if (!fmpz_fits_si(n)) { success = 0; goto cleanup; } m = fmpz_get_si(n); if (m < -(40 + (prec - 40) / 4)) { success = 0; goto cleanup; } if (m > 70 + (prec - 40) / 8) { success = 0; goto cleanup; } arb_set_fmpq(t, a, prec + 4); success = arb_hypgeom_gamma_taylor(t, t, 0, prec + 4); if (success) { arb_t u; arb_init(u); if (m >= 0) { arb_rising_fmpq_ui(u, a, m, prec + 4); arb_mul(y, t, u, prec); } else { arb_rising_fmpq_ui(u, x, -m, prec + 4); arb_div(y, t, u, prec); } arb_clear(u); } cleanup: fmpq_clear(a); fmpz_clear(n); arb_clear(t); return success; } void arb_hypgeom_gamma_fmpq(arb_t y, const fmpq_t x, slong prec) { fmpz p, q; p = *fmpq_numref(x); q = *fmpq_denref(x); if ((q == 1 || q == 2 || q == 3 || q == 4 || q == 6) && !COEFF_IS_MPZ(p)) { if (q == 1) { if (p <= 0) { arb_indeterminate(y); return; } if (p < 1200 || 1.44265 * (p*log(p) - p) < 15.0 * prec) { fmpz_t t; fmpz_init(t); fmpz_fac_ui(t, p - 1); arb_set_round_fmpz(y, t, prec); fmpz_clear(t); return; } } p = FLINT_ABS(p); if (p < q * 500.0 || p < q * (500.0 + 0.1 * prec * sqrt(prec))) { arb_hypgeom_gamma_fmpq_outward(y, x, prec); return; } } if (q != 1 && prec > 7000 + 300 * fmpz_bits(fmpq_denref(x)) && (slong) fmpz_bits(fmpq_numref(x)) - (slong) fmpz_bits(fmpq_denref(x)) < FLINT_BITS && fabs(fmpq_get_d(x)) < 0.03 * prec * sqrt(prec)) { arb_hypgeom_gamma_fmpq_outward(y, x, prec); return; } if (fmpz_bits(fmpq_denref(x)) > 0.1 * prec || fmpz_bits(fmpq_numref(x)) > 0.1 * prec) { slong wp; wp = (slong) fmpz_bits(fmpq_numref(x)) - (slong) fmpz_bits(fmpq_denref(x)); wp = FLINT_MAX(wp, 0); wp = FLINT_MIN(wp, 4 * prec); wp += prec + 4; arb_set_fmpq(y, x, wp); if (!arb_hypgeom_gamma_taylor(y, y, 0, prec)) arb_hypgeom_gamma_stirling(y, y, 0, prec); return; } if (arb_hypgeom_gamma_fmpq_taylor(y, x, prec)) return; arb_hypgeom_gamma_fmpq_stirling(y, x, prec); } void arb_hypgeom_gamma_fmpz(arb_t y, const fmpz_t x, slong prec) { fmpq_t t; *fmpq_numref(t) = *x; *fmpq_denref(t) = WORD(1); arb_hypgeom_gamma_fmpq(y, t, prec); } arb-2.22.1/arb_hypgeom/gamma_lower_series.c000066400000000000000000000061741417376376500207010ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "arb_hypgeom.h" void _arb_hypgeom_gamma_lower_series(arb_ptr g, const arb_t s, arb_srcptr h, slong hlen, int regularized, slong n, slong prec) { arb_t c; hlen = FLINT_MIN(hlen, n); if (regularized == 2 && arb_is_int(s) && arb_is_nonpositive(s)) { arb_t ns; arb_init(ns); arb_neg(ns, s); if (g == h) { arb_ptr t = _arb_vec_init(hlen); _arb_vec_set(t, h, hlen); _arb_poly_pow_arb_series(g, t, hlen, ns, n, prec); _arb_vec_clear(t, hlen); } else { _arb_poly_pow_arb_series(g, h, hlen, ns, n, prec); } arb_clear(ns); return; } arb_init(c); arb_hypgeom_gamma_lower(c, s, h, regularized, prec); if (hlen == 1) { _arb_vec_zero(g + 1, n - 1); } else { arb_ptr t, u, v; arb_ptr w = NULL; t = _arb_vec_init(n); u = _arb_vec_init(n); v = _arb_vec_init(n); if (regularized == 2) { w = _arb_vec_init(n); arb_neg(t, s); _arb_poly_pow_arb_series(w, h, hlen, t, n, prec); } /* gamma(s, h(x)) = integral(h'(x) h(x)^(s-1) exp(-h(x)) */ arb_sub_ui(u, s, 1, prec); _arb_poly_pow_arb_series(t, h, hlen, u, n, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(v, t, n, u, hlen - 1, n, prec); _arb_vec_neg(t, h, hlen); _arb_poly_exp_series(t, t, hlen, n, prec); _arb_poly_mullow(g, v, n, t, n, n, prec); _arb_poly_integral(g, g, n, prec); if (regularized == 1) { arb_rgamma(t, s, prec); _arb_vec_scalar_mul(g, g, n, t, prec); } else if (regularized == 2) { arb_rgamma(t, s, prec); _arb_vec_scalar_mul(g, g, n, t, prec); _arb_vec_set(u, g, n); _arb_poly_mullow(g, u, n, w, n, n, prec); _arb_vec_clear(w, n); } _arb_vec_clear(t, n); _arb_vec_clear(u, n); _arb_vec_clear(v, n); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_gamma_lower_series(arb_poly_t g, const arb_t s, const arb_poly_t h, int regularized, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, n); if (hlen == 0) { arb_t t; arb_init(t); _arb_hypgeom_gamma_lower_series(g->coeffs, s, t, 1, regularized, n, prec); arb_clear(t); } else { _arb_hypgeom_gamma_lower_series( g->coeffs, s, h->coeffs, hlen, regularized, n, prec); } _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/gamma_lower_sum_rs.c000066400000000000000000000064301417376376500207120ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static slong exp_series_prec(slong k, double dz, double logdz, slong prec) { double gain; if (prec <= 128) return prec; if (k <= dz + 5 || k <= 5) return prec; gain = (dz - k * logdz + k * (log(k) - 1.0)) * 1.4426950408889634; gain = FLINT_MAX(gain, 0); prec = prec - gain; prec = FLINT_MAX(prec, 32); return prec; } void _arb_hypgeom_gamma_lower_sum_rs_1(arb_t res, ulong p, ulong q, const arb_t z, slong N, slong prec) { slong m, j, k, jlen, jbot, wp; double dz, logdz; mp_limb_t c, chi, clo; arb_t s; arb_ptr zpow; mp_ptr cs; m = n_sqrt(N); m = FLINT_MAX(m, 2); k = N - 1; j = k % m; jlen = 0; jbot = j; c = 1; dz = arf_get_d(arb_midref(z), ARF_RND_UP); dz = fabs(dz); if (arf_cmpabs_2exp_si(arb_midref(z), prec) >= 0) { dz = ldexp(1.0, prec); logdz = ARF_EXP(arb_midref(z)) * log(2); } else if (arf_cmpabs_2exp_si(arb_midref(z), -32) >= 0) { logdz = log(dz); } else if (arf_cmpabs_2exp_si(arb_midref(z), -prec) <= 0) { logdz = -prec * log(2); } else { logdz = ARF_EXP(arb_midref(z)) * log(2); } arb_init(s); zpow = _arb_vec_init(m + 1); cs = flint_malloc(sizeof(mp_limb_t) * (m + 1)); arb_mul_ui(zpow + m, z, q, prec); _arb_vec_set_powers(zpow, zpow + m, m + 1, prec); while (k >= 0) { if (k != 0) { /* Check if new coefficient will overflow limb */ umul_ppmm(chi, clo, c, p + (k - 1) * q); if (chi != 0) { wp = exp_series_prec(k, dz, logdz, prec); /* Denominator will change, so evaluate current dot product */ if (jlen != 0) { arb_dot_ui(s, s, 0, zpow + jbot, 1, cs + jbot, 1, jlen, wp); jlen = 0; } arb_div_ui(s, s, c, wp); c = 1; } } /* Update dot product */ cs[j] = c; jlen++; jbot = j; if (k != 0) { c = c * (p + (k - 1) * q); /* Giant-step time. */ if (j == 0) { wp = exp_series_prec(k, dz, logdz, prec); /* Evaluate current dot product */ if (jlen != 0) { arb_dot_ui(s, s, 0, zpow + jbot, 1, cs + jbot, 1, jlen, wp); jlen = 0; } arb_mul(s, s, zpow + m, wp); j = m - 1; } else { j--; } } k--; } if (jlen != 0) { arb_dot_ui(s, s, 0, zpow + jbot, 1, cs + jbot, 1, jlen, prec); jlen = 0; } arb_div_ui(res, s, c, prec); _arb_vec_clear(zpow, m + 1); arb_clear(s); flint_free(cs); } arb-2.22.1/arb_hypgeom/gamma_stirling_sum_horner.c000066400000000000000000000033031417376376500222620ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_gamma_stirling_coeff(arb_t b, ulong k, int digamma, slong prec); void arb_hypgeom_gamma_stirling_sum_horner(arb_t s, const arb_t z, slong N, slong prec) { arb_t b, t, zinv, w; mag_t zinv_mag; slong n, term_mag, term_prec; slong * term_mags; if (N <= 1) { arb_zero(s); return; } arb_init(b); arb_init(t); arb_init(zinv); arb_init(w); mag_init(zinv_mag); arb_inv(zinv, z, prec); arb_mul(w, zinv, zinv, prec); arb_get_mag(zinv_mag, zinv); term_mags = flint_malloc(sizeof(ulong) * N); _arb_hypgeom_gamma_stirling_term_bounds(term_mags, zinv_mag, N); arb_zero(s); for (n = N - 1; n >= 1; n--) { term_mag = term_mags[n]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); if (prec - term_prec > 200) { arb_set_round(t, w, term_prec); arb_mul(s, s, t, term_prec); } else arb_mul(s, s, w, term_prec); arb_gamma_stirling_coeff(b, n, 0, term_prec); arb_add(s, s, b, term_prec); } arb_mul(s, s, zinv, prec); flint_free(term_mags); arb_clear(t); arb_clear(b); arb_clear(zinv); arb_clear(w); mag_clear(zinv_mag); } arb-2.22.1/arb_hypgeom/gamma_stirling_sum_improved.c000066400000000000000000000303751417376376500226230ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "bernoulli.h" void arb_hypgeom_gamma_stirling_sum_improved(arb_t s, const arb_t z, slong N, slong K, slong prec) { arb_t b, t, zinv, w, u, S2, S3, S4; mag_t zinv_mag, err; slong n, term_mag, term_prec; slong * term_mags; slong i, j, k, M; slong * Mk; arb_ptr upow, ukpow; slong kodd, kpow_exp, wp; fmpz_t kpow; slong m; if (N <= 1) { arb_zero(s); return; } if (N == 2) { arb_mul_ui(s, z, 12, prec); arb_inv(s, s, prec); return; } if (K == 0) { if (prec <= 128) K = 1; else if (prec <= 1024) K = 2; else { K = 4 + 0.1 * sqrt(FLINT_MAX(prec - 4096, 0)); K = FLINT_MIN(K, 100); } } arb_init(b); arb_init(t); arb_init(zinv); arb_init(w); arb_init(u); arb_init(S2); arb_init(S3); arb_init(S4); mag_init(zinv_mag); mag_init(err); arb_inv(zinv, z, prec); arb_mul(w, zinv, zinv, prec); arb_get_mag(zinv_mag, zinv); term_mags = flint_malloc(sizeof(ulong) * (N + 1)); /* Avoid possible overflow. (This case is not interesting to handle well, but we need to handle it.) */ if (mag_cmp_2exp_si(zinv_mag, 10) > 0) K = 1; /* Avoid possible underflow. */ if (mag_cmp_2exp_si(zinv_mag, -100000) < 0) mag_set_ui_2exp_si(zinv_mag, 1, -100000); _arb_hypgeom_gamma_stirling_term_bounds(term_mags, zinv_mag, N + 1); /* We will assume below that term_mags is nonincreasing */ for (n = N - 2; n >= 1; n--) { if (term_mags[n] < term_mags[n + 1]) term_mags[n] = term_mags[n + 1]; } Mk = NULL; if (K > 1) { Mk = flint_malloc(sizeof(slong) * (K + 1)); Mk[0] = Mk[1] = N; for (k = 2; k <= K; k++) { double log2_k; Mk[k] = N; log2_k = log(k) * (1.0 / 0.693147180559945309); while (Mk[k] > 2) { slong err, Mnew; Mnew = Mk[k] - 1; err = term_mags[Mnew] - log2_k * (2 * Mnew) + FLINT_BIT_COUNT(N - Mnew); if (err < -prec) Mk[k] = Mnew; else break; } } /* We will assume that Mk is nonincreasing. */ for (k = 2; k <= K; k++) { if (Mk[k] > Mk[k - 1]) Mk[k] = Mk[k - 1]; } while (K >= 2 && Mk[K] == Mk[K - 1]) K--; M = Mk[K]; mag_hurwitz_zeta_uiui(err, 2 * M, K); mag_mul_ui(err, err, N - M); mag_mul_2exp_si(err, err, term_mags[M]); for (k = 1; k < K; k++) { mag_t t; mag_init(t); mag_set_ui_lower(t, k); mag_inv(t, t); mag_pow_ui(t, t, 2 * Mk[k]); mag_mul_ui(t, t, N - Mk[k]); mag_mul_2exp_si(t, t, term_mags[Mk[k]]); mag_add(err, err, t); mag_clear(t); } } else { M = N; } m = sqrt(N - M); m = FLINT_MAX(m, 1); /* S3 precision */ wp = prec + term_mags[M]; wp = FLINT_MIN(wp, prec); wp = FLINT_MAX(wp, 10); arb_zero(S3); /* todo: could avoid one mul + div with precomputation here */ /* u = -1 / (2 pi z)^2 */ arb_const_pi(u, wp); arb_mul(u, u, z, wp); arb_mul_2exp_si(u, u, 1); arb_mul(u, u, u, wp); arb_inv(u, u, wp); arb_neg(u, u); fmpz_init(kpow); upow = _arb_vec_init(m + 1); ukpow = _arb_vec_init(m + 1); _arb_vec_set_powers(upow, u, m + 1, wp); for (kodd = 1; kodd < K; kodd += 2) { for (k = kodd; k < K; k *= 2) { if (k == 1) { _arb_vec_set(ukpow, upow, m + 1); fmpz_one(kpow); kpow_exp = 0; } else if (k == kodd) { arb_set(ukpow + 0, upow + 0); for (j = 1; j <= FLINT_MIN(Mk[k] - M - 1, m); j++) { if (j == 1) fmpz_set_ui(kpow, k * k); else fmpz_mul_ui(kpow, kpow, k * k); arb_div_fmpz(ukpow + j, upow + j, kpow, wp); } /* set kpow = k^(2M) */ fmpz_ui_pow_ui(kpow, k * k, M); kpow_exp = 0; } else { /* compute x / k^(2j) given x / (k/2)^(2j) */ for (j = 1; j <= FLINT_MIN(Mk[k] - M - 1, m); j++) arb_mul_2exp_si(ukpow + j, ukpow + j, -2 * j); kpow_exp += 2 * M; } arb_zero(S4); for (n = Mk[k] - 1; n >= M; n--) { i = n - M; term_prec = prec + term_mags[n]; term_prec = FLINT_MIN(wp, prec); term_prec = FLINT_MAX(term_prec, 10); /* note: set_round makes small difference here */ arb_fma_ui(S4, S4, (2 * n) * (2 * n - 1), ukpow + i % m, term_prec); if (i != 0 && i % m == 0) { /* note: set_round makes small difference here */ arb_mul(S4, S4, ukpow + m, term_prec); } } /* divide by k^(2M) */ if (k != 1) { if (!fmpz_is_one(kpow)) arb_div_fmpz(S4, S4, kpow, wp); arb_mul_2exp_si(S4, S4, -kpow_exp); } arb_add(S3, S3, S4, wp); } } /* multiply by -2 (2M-2)! u^M z */ fmpz_fac_ui(kpow, 2 * M - 2); arb_mul_fmpz(S3, S3, kpow, wp); arb_pow_ui(u, u, M, wp); arb_mul(S3, S3, u, wp); arb_set_round(t, z, wp); arb_mul(S3, S3, t, wp); arb_mul_2exp_si(S3, S3, 1); arb_neg(S3, S3); arb_add_error_mag(S3, err); _arb_vec_clear(upow, m + 1); _arb_vec_clear(ukpow, m + 1); fmpz_clear(kpow); arb_zero(S2); m = sqrt(M); upow = _arb_vec_init(m + 1); _arb_vec_set_powers(upow, w, m + 1, prec); BERNOULLI_ENSURE_CACHED(2 * M - 2); { fmpz_t d, e, f, g, h; fmpz q[4]; fmpz_init(d); fmpz_init(e); fmpz_init(f); fmpz_init(g); fmpz_init(h); fmpz_init(q); fmpz_init(q + 1); fmpz_init(q + 2); fmpz_init(q + 3); for (n = M - 1; n >= 1; n--) { i = n - 1; if (i >= 4 && i % m >= 3 && prec >= 512 && prec <= 4096) { term_mag = term_mags[n - 3]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * (n - 0)), 2 * (n - 0) * (2 * (n - 0) - 1)); fmpz_mul_ui(e, fmpq_denref(bernoulli_cache + 2 * (n - 1)), 2 * (n - 1) * (2 * (n - 1) - 1)); fmpz_mul_ui(g, fmpq_denref(bernoulli_cache + 2 * (n - 2)), 2 * (n - 2) * (2 * (n - 2) - 1)); fmpz_mul_ui(h, fmpq_denref(bernoulli_cache + 2 * (n - 3)), 2 * (n - 3) * (2 * (n - 3) - 1)); /* q3 = egh q2 = dgh q1 = deh q0 = deg d = degh */ fmpz_mul(q + 3, e, g); fmpz_mul(q + 0, q + 3, d); fmpz_mul(q + 3, q + 3, h); fmpz_mul(q + 2, d, h); fmpz_mul(q + 1, q + 2, e); fmpz_mul(q + 2, q + 2, g); fmpz_mul(d, q + 3, d); fmpz_mul(q + 3, q + 3, fmpq_numref(bernoulli_cache + 2 * (n - 0))); fmpz_mul(q + 2, q + 2, fmpq_numref(bernoulli_cache + 2 * (n - 1))); fmpz_mul(q + 1, q + 1, fmpq_numref(bernoulli_cache + 2 * (n - 2))); fmpz_mul(q + 0, q + 0, fmpq_numref(bernoulli_cache + 2 * (n - 3))); arb_dot_fmpz(t, NULL, 0, upow + i % m - 3, 1, q, 1, 4, term_prec); arb_div_fmpz(t, t, d, term_prec); arb_add(S2, S2, t, term_prec); n -= 3; i -= 3; } else if (i >= 3 && i % m >= 2) { term_mag = term_mags[n - 2]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * (n - 0)), 2 * (n - 0) * (2 * (n - 0) - 1)); fmpz_mul_ui(e, fmpq_denref(bernoulli_cache + 2 * (n - 1)), 2 * (n - 1) * (2 * (n - 1) - 1)); fmpz_mul_ui(g, fmpq_denref(bernoulli_cache + 2 * (n - 2)), 2 * (n - 2) * (2 * (n - 2) - 1)); fmpz_mul(q + 2, e, g); fmpz_mul(q + 2, q + 2, fmpq_numref(bernoulli_cache + 2 * (n - 0))); fmpz_mul(q + 1, d, g); fmpz_mul(q + 1, q + 1, fmpq_numref(bernoulli_cache + 2 * (n - 1))); fmpz_mul(q + 0, d, e); fmpz_mul(d, q + 0, g); fmpz_mul(q + 0, q + 0, fmpq_numref(bernoulli_cache + 2 * (n - 2))); arb_dot_fmpz(t, NULL, 0, upow + i % m - 2, 1, q, 1, 3, term_prec); arb_div_fmpz(t, t, d, term_prec); arb_add(S2, S2, t, term_prec); n -= 2; i -= 2; } else if (i >= 1 && i % m >= 1) { term_mag = term_mags[n - 1]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * (n - 0)), 2 * (n - 0) * (2 * (n - 0) - 1)); fmpz_mul_ui(e, fmpq_denref(bernoulli_cache + 2 * (n - 1)), 2 * (n - 1) * (2 * (n - 1) - 1)); fmpz_mul(f, fmpq_numref(bernoulli_cache + 2 * (n - 0)), e); arb_set_round(u, upow + i % m, term_prec); arb_mul_fmpz(t, u, f, term_prec); /* todo: output-sensitive mul */ fmpz_mul(f, fmpq_numref(bernoulli_cache + 2 * (n - 1)), d); arb_set_round(u, upow + i % m - 1, term_prec); arb_mul_fmpz(u, u, f, term_prec); /* todo: output-sensitive mul */ arb_add(t, t, u, term_prec); fmpz_mul(d, d, e); arb_div_fmpz(t, t, d, term_prec); arb_add(S2, S2, t, term_prec); n--; i--; } else { term_mag = term_mags[n]; term_prec = prec + term_mag; term_prec = FLINT_MIN(term_prec, prec); term_prec = FLINT_MAX(term_prec, 10); arb_set_round(u, upow + i % m, term_prec); arb_mul_fmpz(t, u, fmpq_numref(bernoulli_cache + 2 * n), term_prec); /* todo: output-sensitive mul */ fmpz_mul_ui(d, fmpq_denref(bernoulli_cache + 2 * n), 2 * n * (2 * n - 1)); arb_div_fmpz(t, t, d, term_prec); arb_add(S2, S2, t, term_prec); } if (i != 0 && i % m == 0) { arb_set_round(u, upow + m, term_prec); /* todo: output-sensitive mul */ arb_mul(S2, S2, u, term_prec); } } fmpz_clear(q); fmpz_clear(q + 1); fmpz_clear(q + 2); fmpz_clear(q + 3); fmpz_clear(d); fmpz_clear(e); fmpz_clear(f); fmpz_clear(g); fmpz_clear(h); } _arb_vec_clear(upow, m + 1); arb_mul(S2, S2, zinv, prec); arb_add(s, S2, S3, prec); flint_free(term_mags); if (Mk != NULL) flint_free(Mk); arb_clear(b); arb_clear(t); arb_clear(zinv); arb_clear(w); arb_clear(u); arb_clear(S2); arb_clear(S3); arb_clear(S4); mag_clear(zinv_mag); mag_clear(err); } arb-2.22.1/arb_hypgeom/gamma_stirling_term_bounds.c000066400000000000000000000022061417376376500224230ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_gamma_stirling_term_bounds(slong * bound, const mag_t zinv, slong N) { mag_t b, u; slong n; mag_init(b); mag_init(u); /* bound[0] = WORD_MAX; -- should not be used */ /* first term 1/(12z) */ mag_set(b, zinv); mag_div_ui(b, b, 12); bound[1] = MAG_EXP(b); /* u = 1/(2 pi z)^2 */ mag_const_pi_lower(u); mag_mul_2exp_si(u, u, 1); mag_inv(u, u); mag_mul(u, u, zinv); mag_mul(u, u, u); /* zeta(2n) 2 (2n-2)! / (2pi)^(2n) / z^(2n-1) */ /* ratio bounded by (2n-2)(2n-3)/(2 pi z)^2 */ for (n = 2; n < N; n++) { mag_mul_ui(b, b, (2*n-2) * (2*n-3)); mag_mul(b, b, u); bound[n] = MAG_EXP(b); } mag_clear(b); mag_clear(u); } arb-2.22.1/arb_hypgeom/gamma_tab.c000066400000000000000000011701071417376376500167440ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #if FLINT_BITS == 64 #define Z2(a,b) UWORD(0x ## b ## a) #else #define Z2(a,b) UWORD(0x ## a), UWORD(0x ## b) #endif #define Z8(a,b,c,d,e,f,g,h) Z2(a,b), Z2(c,d), Z2(e,f), Z2(g,h), arb_hypgeom_gamma_coeff_t arb_hypgeom_gamma_coeffs[ARB_HYPGEOM_GAMMA_TAB_NUM] = { {1, 0, 54, 0}, {0, 54, 54, 0}, {0, 108, 54, 1}, {-4, 162, 54, 1}, {-2, 216, 54, 0}, {-4, 270, 54, 1}, {-6, 324, 54, 1}, {-7, 378, 54, 0}, {-9, 432, 54, 1}, {-12, 486, 54, 1}, {-12, 540, 54, 0}, {-15, 594, 54, 1}, {-19, 648, 54, 1}, {-19, 702, 54, 0}, {-22, 756, 54, 1}, {-27, 810, 54, 0}, {-27, 864, 54, 0}, {-29, 918, 54, 1}, {-33, 972, 54, 0}, {-36, 1026, 54, 0}, {-37, 1080, 54, 1}, {-40, 1134, 54, 0}, {-45, 1188, 54, 1}, {-47, 1242, 54, 1}, {-49, 1296, 54, 0}, {-52, 1350, 53, 1}, {-59, 1403, 53, 0}, {-59, 1456, 53, 0}, {-61, 1509, 53, 1}, {-65, 1562, 53, 0}, {-72, 1615, 53, 0}, {-72, 1668, 53, 1}, {-74, 1721, 53, 0}, {-78, 1774, 53, 1}, {-85, 1827, 53, 1}, {-85, 1880, 53, 0}, {-88, 1933, 53, 1}, {-92, 1986, 53, 0}, {-99, 2039, 53, 0}, {-99, 2092, 52, 1}, {-102, 2144, 52, 0}, {-106, 2196, 52, 1}, {-116, 2248, 52, 0}, {-114, 2300, 52, 0}, {-117, 2352, 52, 1}, {-121, 2404, 52, 0}, {-127, 2456, 52, 1}, {-129, 2508, 52, 1}, {-132, 2560, 52, 0}, {-136, 2612, 52, 1}, {-141, 2664, 52, 0}, {-144, 2716, 52, 0}, {-147, 2768, 52, 1}, {-151, 2820, 51, 0}, {-156, 2871, 51, 1}, {-161, 2922, 51, 1}, {-163, 2973, 51, 0}, {-167, 3024, 51, 1}, {-171, 3075, 51, 0}, {-179, 3126, 51, 1}, {-179, 3177, 51, 1}, {-183, 3228, 51, 0}, {-187, 3279, 51, 1}, {-192, 3330, 51, 0}, {-197, 3381, 51, 0}, {-199, 3432, 51, 1}, {-203, 3483, 50, 0}, {-208, 3533, 50, 1}, {-217, 3583, 50, 1}, {-216, 3633, 50, 0}, {-220, 3683, 50, 1}, {-224, 3733, 50, 0}, {-230, 3783, 50, 1}, {-234, 3833, 50, 1}, {-237, 3883, 50, 0}, {-241, 3933, 50, 1}, {-246, 3983, 50, 0}, {-256, 4033, 49, 1}, {-255, 4082, 49, 1}, {-259, 4131, 49, 0}, {-263, 4180, 49, 1}, {-269, 4229, 49, 0}, {-274, 4278, 49, 0}, {-277, 4327, 49, 1}, {-281, 4376, 49, 0}, {-285, 4425, 49, 1}, {-292, 4474, 49, 0}, {-295, 4523, 49, 0}, {-299, 4572, 49, 1}, {-303, 4621, 49, 0}, {-308, 4670, 48, 1}, {-317, 4718, 48, 1}, {-317, 4766, 48, 0}, {-321, 4814, 48, 1}, {-326, 4862, 48, 0}, {-331, 4910, 48, 1}, {-337, 4958, 48, 1}, {-340, 5006, 48, 0}, {-344, 5054, 48, 1}, {-349, 5102, 48, 0}, {-355, 5150, 48, 1}, {-359, 5198, 47, 1}, {-363, 5245, 47, 0}, {-367, 5292, 47, 1}, {-372, 5339, 47, 0}, {-379, 5386, 47, 1}, {-382, 5433, 47, 1}, {-386, 5480, 47, 0}, {-391, 5527, 47, 1}, {-396, 5574, 47, 0}, {-405, 5621, 47, 1}, {-406, 5668, 47, 1}, {-410, 5715, 46, 0}, {-415, 5761, 46, 1}, {-420, 5807, 46, 0}, {-428, 5853, 46, 0}, {-429, 5899, 46, 1}, {-434, 5945, 46, 0}, {-439, 5991, 46, 1}, {-444, 6037, 46, 0}, {-451, 6083, 46, 0}, {-454, 6129, 46, 1}, {-458, 6175, 46, 0}, {-463, 6221, 45, 1}, {-469, 6266, 45, 0}, {-475, 6311, 45, 0}, {-478, 6356, 45, 1}, {-482, 6401, 45, 0}, {-488, 6446, 45, 1}, {-494, 6491, 45, 0}, {-500, 6536, 45, 0}, {-503, 6581, 45, 1}, {-507, 6626, 45, 0}, {-512, 6671, 45, 1}, {-518, 6716, 44, 0}, {-524, 6760, 44, 0}, {-527, 6804, 44, 1}, {-532, 6848, 44, 0}, {-537, 6892, 44, 1}, {-543, 6936, 44, 0}, {-549, 6980, 44, 0}, {-553, 7024, 44, 1}, {-557, 7068, 44, 0}, {-562, 7112, 44, 1}, {-569, 7156, 44, 0}, {-575, 7200, 43, 0}, {-578, 7243, 43, 1}, {-583, 7286, 43, 0}, {-588, 7329, 43, 1}, {-594, 7372, 43, 0}, {-601, 7415, 43, 0}, {-604, 7458, 43, 1}, {-608, 7501, 43, 0}, {-613, 7544, 43, 1}, {-619, 7587, 43, 0}, {-627, 7630, 42, 0}, {-629, 7672, 42, 1}, {-634, 7714, 42, 0}, {-639, 7756, 42, 1}, {-645, 7798, 42, 0}, {-656, 7840, 42, 0}, {-655, 7882, 42, 1}, {-660, 7924, 42, 0}, {-665, 7966, 42, 1}, {-671, 8008, 42, 0}, {-679, 8050, 41, 1}, {-682, 8091, 41, 1}, {-686, 8132, 41, 0}, {-691, 8173, 41, 1}, {-697, 8214, 41, 0}, {-704, 8255, 41, 1}, {-708, 8296, 41, 1}, {-713, 8337, 41, 0}, {-718, 8378, 41, 1}, {-723, 8419, 41, 0}, {-730, 8460, 41, 1}, {-735, 8501, 40, 1}, {-739, 8541, 40, 0}, {-744, 8581, 40, 1}, {-750, 8621, 40, 0}, {-756, 8661, 40, 1}, {-763, 8701, 40, 1}, {-766, 8741, 40, 0}, {-771, 8781, 40, 1}, {-776, 8821, 40, 0}, {-782, 8861, 40, 1}, {-791, 8901, 39, 1}, {-793, 8940, 39, 0}, {-798, 8979, 39, 1}, {-803, 9018, 39, 0}, {-809, 9057, 39, 1}, {-817, 9096, 39, 0}, {-820, 9135, 39, 0}, {-825, 9174, 39, 1}, {-830, 9213, 39, 0}, {-836, 9252, 39, 1}, {-843, 9291, 38, 0}, {-848, 9329, 38, 0}, {-852, 9367, 38, 1}, {-857, 9405, 38, 0}, {-863, 9443, 38, 1}, {-869, 9481, 38, 0}, {-876, 9519, 38, 0}, {-880, 9557, 38, 1}, {-885, 9595, 38, 0}, {-890, 9633, 38, 1}, {-896, 9671, 37, 0}, {-906, 9708, 37, 1}, {-908, 9745, 37, 1}, {-912, 9782, 37, 0}, {-918, 9819, 37, 1}, {-924, 9856, 37, 0}, {-931, 9893, 37, 1}, {-936, 9930, 37, 1}, {-940, 9967, 37, 0}, {-945, 10004, 37, 1}, {-951, 10041, 36, 0}, {-958, 10077, 36, 1}, {-965, 10113, 36, 1}, {-968, 10149, 36, 0}, {-973, 10185, 36, 1}, {-979, 10221, 36, 0}, {-985, 10257, 36, 1}, {-994, 10293, 36, 0}, {-997, 10329, 36, 0}, {-1001, 10365, 35, 1}, {-1007, 10400, 35, 0}, {-1013, 10435, 35, 1}, {-1020, 10470, 35, 0}, {-1025, 10505, 35, 0}, {-1030, 10540, 35, 1}, {-1035, 10575, 35, 0}, {-1041, 10610, 35, 1}, {-1047, 10645, 35, 0}, {-1056, 10680, 34, 0}, {-1058, 10714, 34, 1}, {-1063, 10748, 34, 0}, {-1069, 10782, 34, 1}, {-1075, 10816, 34, 0}, {-1082, 10850, 34, 1}, {-1087, 10884, 34, 1}, {-1092, 10918, 34, 0}, {-1097, 10952, 34, 1}, {-1103, 10986, 34, 0}, {-1110, 11020, 33, 1}, {-1117, 11053, 33, 1}, {-1121, 11086, 33, 0}, {-1126, 11119, 33, 1}, {-1131, 11152, 33, 0}, {-1138, 11185, 33, 1}, {-1145, 11218, 33, 0}, {-1150, 11251, 33, 0}, {-1155, 11284, 33, 1}, {-1160, 11317, 33, 0}, {-1166, 11350, 32, 1}, {-1173, 11382, 32, 0}, {-1180, 11414, 32, 0}, {-1184, 11446, 32, 1}, {-1189, 11478, 32, 0}, {-1195, 11510, 32, 1}, {-1201, 11542, 32, 0}, {-1209, 11574, 32, 1}, {-1213, 11606, 32, 1}, {-1218, 11638, 32, 0}, {-1223, 11670, 31, 1}, {-1230, 11701, 31, 0}, {-1236, 11732, 31, 1}, {-1244, 11763, 31, 1}, {-1247, 11794, 31, 0}, {-1253, 11825, 31, 1}, {-1258, 11856, 31, 0}, {-1265, 11887, 31, 1}, {-1273, 11918, 31, 0}, {-1277, 11949, 30, 0}, {-1282, 11979, 30, 1}, {-1288, 12009, 30, 0}, {-1294, 12039, 30, 1}, {-1300, 12069, 30, 0}, {-1309, 12099, 30, 0}, {-1312, 12129, 30, 1}, {-1317, 12159, 30, 0}, {-1323, 12189, 30, 1}, {-1329, 12219, 29, 0}, {-1337, 12248, 29, 1}, {-1342, 12277, 29, 1}, {-1347, 12306, 29, 0}, {-1352, 12335, 29, 1}, {-1358, 12364, 29, 0}, {-1365, 12393, 29, 1}, {-1378, 12422, 29, 1}, {-1377, 12451, 29, 0}, {-1382, 12480, 29, 1}, {-1388, 12509, 28, 0}, {-1394, 12537, 28, 1}, {-1401, 12565, 28, 0}, {-1407, 12593, 28, 0}, {-1412, 12621, 28, 1}, {-1417, 12649, 28, 0}, {-1423, 12677, 28, 1}, {-1430, 12705, 28, 0}, {-1438, 12733, 27, 1}, {-1442, 12760, 27, 1}, {-1447, 12787, 27, 0}, {-1453, 12814, 27, 1}, {-1459, 12841, 27, 0}, {-1466, 12868, 27, 1}, {-1474, 12895, 27, 1}, {-1477, 12922, 27, 0}, {-1483, 12949, 27, 1}, {-1489, 12976, 27, 0}, {-1495, 13003, 26, 1}, {-1503, 13029, 26, 0}, {-1508, 13055, 26, 0}, {-1513, 13081, 26, 1}, {-1519, 13107, 26, 0}, {-1525, 13133, 26, 1}, {-1531, 13159, 26, 0}, {-1541, 13185, 26, 1}, {-1544, 13211, 26, 1}, {-1549, 13237, 25, 0}, {-1555, 13262, 25, 1}, {-1561, 13287, 25, 0}, {-1568, 13312, 25, 1}, {-1576, 13337, 25, 1}, {-1580, 13362, 25, 0}, {-1585, 13387, 25, 1}, {-1591, 13412, 25, 0}, {-1598, 13437, 25, 1}, {-1605, 13462, 24, 0}, {-1611, 13486, 24, 0}, {-1616, 13510, 24, 1}, {-1621, 13534, 24, 0}, {-1628, 13558, 24, 1}, {-1634, 13582, 24, 0}, {-1643, 13606, 24, 1}, {-1647, 13630, 24, 1}, {-1652, 13654, 24, 0}, {-1658, 13678, 23, 1}, {-1664, 13701, 23, 0}, {-1671, 13724, 23, 1}, {-1680, 13747, 23, 1}, {-1683, 13770, 23, 0}, {-1688, 13793, 23, 1}, {-1694, 13816, 23, 0}, {-1701, 13839, 23, 1}, {-1708, 13862, 23, 0}, {-1715, 13885, 22, 0}, {-1719, 13907, 22, 1}, {-1725, 13929, 22, 0}, {-1731, 13951, 22, 1}, {-1738, 13973, 22, 0}, {-1746, 13995, 22, 1}, {-1751, 14017, 22, 1}, {-1756, 14039, 22, 0}, {-1762, 14061, 22, 1}, {-1768, 14083, 21, 0}, {-1775, 14104, 21, 1}, {-1785, 14125, 21, 0}, {-1788, 14146, 21, 0}, {-1793, 14167, 21, 1}, {-1799, 14188, 21, 0}, {-1805, 14209, 21, 1}, {-1812, 14230, 21, 0}, {-1821, 14251, 21, 0}, {-1824, 14272, 20, 1}, {-1830, 14292, 20, 0}, {-1836, 14312, 20, 1}, {-1843, 14332, 20, 0}, {-1850, 14352, 20, 1}, {-1857, 14372, 20, 1}, {-1861, 14392, 20, 0}, {-1867, 14412, 20, 1}, {-1873, 14432, 20, 0}, {-1880, 14452, 19, 1}, {-1888, 14471, 19, 0}, {-1893, 14490, 19, 0}, {-1898, 14509, 19, 1}, {-1904, 14528, 19, 0}, {-1911, 14547, 19, 1}, {-1918, 14566, 19, 0}, {-1926, 14585, 19, 1}, {-1930, 14604, 19, 1}, {-1936, 14623, 18, 0}, {-1942, 14641, 18, 1}, {-1948, 14659, 18, 0}, {-1955, 14677, 18, 1}, {-1967, 14695, 18, 1}, {-1968, 14713, 18, 0}, {-1973, 14731, 18, 1}, {-1979, 14749, 18, 0}, {-1986, 14767, 18, 1}, {-1993, 14785, 17, 0}, {-2001, 14802, 17, 0}, {-2005, 14819, 17, 1}, {-2011, 14836, 17, 0}, {-2017, 14853, 17, 1}, {-2024, 14870, 17, 0}, {-2031, 14887, 17, 1}, {-2038, 14904, 17, 1}, {-2043, 14921, 16, 0}, {-2048, 14937, 16, 1}, {-2055, 14953, 16, 0}, {-2062, 14969, 16, 1}, {-2069, 14985, 16, 0}, {-2076, 15001, 16, 0}, {-2080, 15017, 16, 1}, {-2086, 15033, 16, 0}, {-2093, 15049, 16, 1}, {-2100, 15065, 15, 0}, {-2108, 15080, 15, 1}, {-2113, 15095, 15, 1}, {-2118, 15110, 15, 0}, {-2124, 15125, 15, 1}, {-2131, 15140, 15, 0}, {-2138, 15155, 15, 1}, {-2147, 15170, 15, 0}, {-2151, 15185, 15, 0}, {-2156, 15200, 14, 1}, {-2162, 15214, 14, 0}, {-2169, 15228, 14, 1}, {-2176, 15242, 14, 0}, {-2186, 15256, 14, 1}, {-2189, 15270, 14, 1}, {-2194, 15284, 14, 0}, {-2201, 15298, 14, 1}, {-2207, 15312, 14, 0}, {-2214, 15326, 13, 1}, {-2225, 15339, 13, 1}, {-2227, 15352, 13, 0}, {-2233, 15365, 13, 1}, {-2239, 15378, 13, 0}, {-2245, 15391, 13, 1}, {-2253, 15404, 13, 0}, {-2262, 15417, 13, 0}, {-2265, 15430, 12, 1}, {-2271, 15442, 12, 0}, {-2277, 15454, 12, 1}, {-2284, 15466, 12, 0}, {-2291, 15478, 12, 1}, {-2300, 15490, 12, 1}, {-2304, 15502, 12, 0}, {-2309, 15514, 12, 1}, {-2316, 15526, 12, 0}, {-2322, 15538, 11, 1}, {-2330, 15549, 11, 0}, {-2338, 15560, 11, 0}, {-2342, 15571, 11, 1}, {-2348, 15582, 11, 0}, {-2354, 15593, 11, 1}, {-2361, 15604, 11, 0}, {-2369, 15615, 11, 1}, {-2376, 15626, 10, 1}, {-2381, 15636, 10, 0}, {-2387, 15646, 10, 1}, {-2393, 15656, 10, 0}, {-2400, 15666, 10, 1}, {-2408, 15676, 10, 0}, {-2415, 15686, 10, 0}, {-2419, 15696, 10, 1}, {-2425, 15706, 10, 0}, {-2432, 15716, 9, 1}, {-2439, 15725, 9, 0}, {-2447, 15734, 9, 1}, {-2453, 15743, 9, 1}, {-2458, 15752, 9, 0}, {-2464, 15761, 9, 1}, {-2471, 15770, 9, 0}, {-2478, 15779, 9, 1}, {-2486, 15788, 8, 0}, {-2492, 15796, 8, 0}, {-2497, 15804, 8, 1}, {-2503, 15812, 8, 0}, {-2510, 15820, 8, 1}, {-2517, 15828, 8, 0}, {-2525, 15836, 8, 1}, {-2531, 15844, 8, 1}, {-2536, 15852, 8, 0}, {-2542, 15860, 7, 1}, {-2549, 15867, 7, 0}, {-2556, 15874, 7, 1}, {-2564, 15881, 7, 0}, {-2570, 15888, 7, 0}, {-2575, 15895, 7, 1}, {-2581, 15902, 7, 0}, {-2588, 15909, 7, 1}, {-2595, 15916, 7, 0}, {-2603, 15923, 6, 1}, {-2609, 15929, 6, 1}, {-2614, 15935, 6, 0}, {-2621, 15941, 6, 1}, {-2627, 15947, 6, 0}, {-2634, 15953, 6, 1}, {-2642, 15959, 6, 0}, {-2649, 15965, 6, 0}, {-2654, 15971, 5, 1}, {-2660, 15976, 5, 0}, {-2667, 15981, 5, 1}, {-2674, 15986, 5, 0}, {-2682, 15991, 5, 1}, {-2688, 15996, 5, 1}, {-2693, 16001, 5, 0}, {-2699, 16006, 5, 1}, {-2706, 16011, 5, 0}, {-2713, 16016, 4, 1}, {-2721, 16020, 4, 0}, {-2728, 16024, 4, 0}, {-2733, 16028, 4, 1}, {-2739, 16032, 4, 0}, {-2745, 16036, 4, 1}, {-2752, 16040, 4, 0}, {-2761, 16044, 4, 1}, {-2767, 16048, 3, 1}, {-2772, 16051, 3, 0}, {-2778, 16054, 3, 1}, {-2785, 16057, 3, 0}, {-2792, 16060, 3, 1}, {-2800, 16063, 3, 0}, {-2807, 16066, 3, 0}, {-2812, 16069, 3, 1}, {-2818, 16072, 3, 0}, {-2825, 16075, 2, 1}, {-2832, 16077, 2, 0}, {-2840, 16079, 2, 1}, {-2847, 16081, 2, 1}, {-2852, 16083, 2, 0}, {-2858, 16085, 2, 1}, {-2865, 16087, 2, 0}, {-2872, 16089, 2, 1}, {-2879, 16091, 1, 0}, {-2887, 16092, 1, 0}, {-2892, 16093, 1, 1}, {-2898, 16094, 1, 0}, {-2904, 16095, 1, 1}, {-2911, 16096, 1, 0}, {-2919, 16097, 1, 1}, {-2927, 16098, 1, 1}, }; const mp_limb_t arb_hypgeom_gamma_tab_limbs[] = { Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000) Z8(00000000,00000000,00000000,80000000,d44c6937,0c3f5be7,e0421838,31072b10) Z8(e1f3a067,f17903f4,7ec1b6d0,98bb22aa,ba5f3a57,9ad030aa,d8036214,1b32e5e8) Z8(512b3051,81ccae83,a8427633,81b5753e,2bce15a3,542e9f72,5a2b38e6,92bf5222) Z8(439cd03a,81c1a48e,b6612b78,1baf84db,37fb2817,e9cc3d17,5ad1f5c7,818bd307) Z8(fea32a67,4068bbca,c26e5421,b7a661e5,f5389130,7f18b93e,17fcc003,d0d62342) Z8(69ddf172,9f9c7ccc,9215f371,6223b2f0,b05e5b25,e528fdf1,6fe9554e,aea1c4bb) Z8(7031f9c0,af289048,744db679,c5d238d0,4f1b66c2,e11df242,d2238d8c,7c555302) Z8(13edf604,4c4d8c4f,5c40bf30,8e704b7c,65f004cc,2741e538,ee52e018,7db2db49) Z8(448f2a05,32fab2c7,d3ee591c,c083f22a,c9b31959,6fcaabcc,64b83989,03655949) Z8(31ced822,5a7bd469,e741e5d8,7cfde60e,e80567a4,8fc28658,63e6d09f,b54fe70e) Z8(ce3bea5d,961542a3,bd61c746,5e6ac2f0,82797722,3ec7c271,e62ff864,d2a1ea1d) Z8(b6b7b86f,0c09d4c8,7899aaae,8a96d156,154b36cf,dbe7bf38,cc86d733,58deb878) Z8(d74bafea,e43b4673,32135a08,1056ae91,621057d1,d0649ccb,03a9f0ee,8e4b59fa) Z8(709affbd,0c03df34,f65cc019,a1cecc3a,0152cb56,d1be3f81,7db0c7a4,93c467e3) Z8(8f1877ab,5c379a00,f9580af6,76b55cc4,f35f61ce,ef1c2900,294dca79,6885062b) Z8(021a094b,4756ca11,1a11d46e,04920c54,b41a7dfc,f0288d8a,2f09194b,14f2cd2a) Z8(83d8d9cf,690c95ad,8781a84d,cdb6fa0a,2302cf3a,c58aee6e,977add8d,db3059f0) Z8(19f9bd13,806423c3,8fbff045,2cffd33a,4ba3c3ef,1588a81e,182a865c,d4bad52a) Z8(6ff3e41b,59c80c6a,2359b8a7,55df6b32,5cf9734f,1388b48e,81ad3ffe,456e5d05) Z8(3956f4b4,698ca360,ad128bca,12c4585a,f72f5b25,8c2a1b45,5ec1b718,f1e5778b) Z8(af21a29d,a63ad266,e1674d69,1a937aac,7e92b6d0,a3b7721f,96f573ad,03525173) Z8(8002e7d8,6595d953,83a8e1e0,862a96a3,d8b597b8,9a1f90dd,0ade1e9e,09791289) Z8(812e6230,c51d77bb,135f63b9,725da3a8,5f42c8eb,803422ee,31d4b4c0,eb323ed6) Z8(dd941d01,4e335234,3f65391b,fa7cabd2,42fed427,e6f2cd93,08f7e03d,94ef0edb) Z8(d8eedaf9,30bc3e04,ba7acbaf,1af586d0,4a1e52bc,2d89f1e9,8f1a86ec,645ef92e) Z8(9ec407ed,d25818cf,c7473287,86f93595,edf114df,ec1ee8cf,e44ad789,5977a634) Z8(232bf00f,e15a6cbb,96dcd8c5,1e0a48ef,bcff260a,2d816c1d,d08fb45c,8ed05db9) Z8(bd611d64,c24856f3,57d16e75,a7e7a013,565580c5,909e6e1e,365bca4b,b95e7dbc) Z8(309115e1,856dde8e,a83da736,2d6cac75,714edf38,a1f3ff04,593c3b9e,791e06e8) Z8(859911dc,b7579e07,67a6c86d,233427d7,ff625deb,d2b87c32,faf32c0a,a18aec7a) Z8(3e7bcea8,3b920d0d,582e38c2,38594742,a4605c64,a6f5d49f,f60c0df7,1d8b96ba) Z8(532bac68,38bd9b08,94205465,c3478ad6,dae2519e,291e5de3,aff8e561,1b69edae) Z8(f78ca6c9,4786c982,bc0da507,930256fa,97fa264c,9325e453,f8be9c9f,d8913717) Z8(a3a4b94c,d424bb8f,84f82135,c56fc7e4,7b86b03e,8b11fcbe,9702df3c,d03a085a) Z8(22044511,fdbd1f91,1ce99bcb,be7783f9,38bb5e92,3e247510,8a82e06b,9e1f9306) Z8(30f90470,3378bb76,35174f52,00c4393a,4ebf5695,ac34dcbc,ae33cc14,3d794b9c) Z8(988a127b,8cb9a696,af813a36,4322ca0f,b6e6b7b9,e0bb7ea2,8c603663,9bf2daee) Z8(310e33ac,e5c9ce60,a293a76d,7c1e561f,9abff0db,2731a5a6,b829d246,047b6a05) Z8(043eb9c3,2273f947,21208155,b8d50305,f4b4d62a,6cda2bea,0e94d288,b1361145) Z8(69abc0cb,a9824b0e,d0377dba,09547d0d,3f0060e4,f8d3efe8,359777d7,89b4393c) Z8(b5a0bec2,dfc931dc,a9b55a20,1403ab71,9c84b042,a15a643c,13823e47,ac0af47d) Z8(e0642cde,1869cecf,717ccc7a,91b4eb03,fffd9154,834f5d81,36be40ce,9aa37f25) Z8(f86f8a67,51e24cc0,b60a3f15,f720b040,d82353fc,14d339de,e83d8700,51552cdc) Z8(fbe2f86c,e380d534,95cbba62,361a1523,e62be0f9,02053756,ce7a1475,f20dbdc1) Z8(9f32751d,ddfa310c,929b5b2e,1c97d15d,333ab386,b0bc2711,ef122799,5eecdc56) Z8(0b8c42d1,110ca5b6,6cfcda46,ca5f2ce8,862ee895,7cd9ea63,6de4bd45,73cd0446) Z8(0ff62ff2,ceb489b1,5ea0e2ec,0a84dfee,6c130226,5b095b0b,d4d5a198,33c4871b) Z8(4ad6da3d,7068516d,2c180a0a,d7f0a18f,671d0d1e,c68c2d88,3c07662b,69c9fcf8) Z8(0d37c0d9,5b4e086a,6d0b0000,babd4fd4,b0739e11,0b509a61,8d03d499,fe63031c) Z8(a54f47a8,fc60f9da,0a15abc8,de1146eb,6717e210,104e1c9d,321fd882,93acc37a) Z8(94336c18,6e146396,a4f1c553,eb7594cb,4bb48380,9fbc4857,9a8f9528,4171ba3f) Z8(2dab48ff,40854a9b,b1f527b9,dab9a53b,282c86ba,860906ab,f7cac3bd,58b5e567) Z8(7e632403,79e8932e,b8e2545a,85c569c0,5c7e176b,0beb919b,1d1cf655,821fd014) Z8(bb6b0d86,503b89b8,001b7660,b73265f9,bb596b64,acd16f79,08740560,c0b5dd3d) Z8(1ef84da1,d37fb09a,a1fdf2ef,aa891905,feece581,98b763c2,ba5ca445,b3d64aa7) Z8(0fd4e2a5,0972a12f,6aac09d6,98e5ee2a,a3745a94,7ba78b40,bbecd2f6,bc7b7024) Z8(98be1ae1,2911d234,c2569eb3,f57d6799,0327f952,b82ae4c6,270d7a73,dd839ec7) Z8(5c7c94c1,ec6a5b11,e817cf1b,020e7db2,904463b3,3a8fcebf,a3773246,e4d656c0) Z8(e7049c56,0020189c,8a673965,5b9323ab,558e48eb,d72712c7,3dc0f6fd,6cbffcd5) Z8(b079cd5b,6cb536d1,092176be,11092edd,13678662,aacf3c36,a2b1bed6,420070ce) Z8(3754b9ab,cd6a6ef1,b9738d6e,f26d4c47,529b13f4,90e40980,5bb6b5ce,9023077e) Z8(15aef90f,3955943c,e76d045a,ae63c7f2,400c9a60,51a613da,0add4e25,c2b42db0) Z8(6dadaf3e,be977b61,9f5049ba,1ea4af96,789d0620,df9c4243,425a08ac,c110359c) Z8(ad0b16d5,39e5a5c9,4831dbf4,cb823de9,ec66c0cf,d356669c,787e18d7,1769cf66) Z8(e683edc7,de95560a,987e12bd,0aac72ab,063c8c94,85de1f4f,ad06066c,35eef6d5) Z8(bbfcad39,42075aeb,de6827de,8d795ba8,6c1a14ff,ca0c1834,9297ffe5,fec1c959) Z8(3ac35dcc,eb9ec7d8,fd9a3f9f,78f4f977,9310b40b,a5d22363,18040b7f,2968ad39) Z8(5b6a43ee,e04c83b2,10646d87,b1fd891b,8caca42e,1b404838,1a0493df,acd7881e) Z8(3e6f60ed,3bb7330c,e901cb17,d36142cf,0d2ea48b,6ab5ee30,ae785c4f,73b0fcd0) Z8(90ae8a01,c7c0b55f,c28b572f,c1858400,6a0fab0e,2839fbfa,216fdab8,07db2b53) Z8(e5b926e1,6dc36d7f,b9ee08ec,2611dd53,963d2452,6cdb1158,27c7af28,0875bca6) Z8(984ff2af,604dbba7,4a820dd7,d3aa0f13,dd72e299,a9f9f273,bf8d1eca,dcf91bf8) Z8(23b2824e,0e31bd46,d247fb0b,09169797,3b285547,abc74ef1,cdd6da23,58297ccb) Z8(8d5ded39,a688b400,d60bce25,b55eff49,c50060ca,f6771ed6,32c5d186,12db0465) Z8(ccd08fac,7b79d989,5e78c1a6,d2a6d559,6419d6d1,d4e1026f,b0cab006,dc4c7db5) Z8(63f4b360,5e9b3db1,124a4299,bfe4e9a0,98103075,182268bc,0d16c2e5,8bcc2984) Z8(3e8191b3,aaf37c4d,ad12bc60,88079562,cdcfdc07,fd313971,338f9c96,4112a3ed) Z8(bc61a309,61d3c3e8,58d23a00,5807a6f1,9ba8bd61,b3c3d210,b68a49d8,b2185343) Z8(5e2c9a26,62d81332,c96257e3,60b9e78a,5e6d3f05,780df480,a8ba60d6,148d3612) Z8(8f195d8a,994cc75d,03bddb2e,32eda7b9,60b65fd3,bda99c32,fc5f362b,b868103d) Z8(bc7158db,48be4222,042e74d6,a225b4d6,b3af63d8,90e7687f,afb99a05,1f3ac55f) Z8(73539adc,b79e8182,41f10a71,9da57942,8c2e8516,49af9cff,3a6d761f,cf7beb09) Z8(5132eb17,e8f45072,de062054,51a7841f,1370dfc1,bd0ef793,5b837f7d,c508f8ec) Z8(a97d388d,2259ed32,6f1f7776,e0f7232a,2ecc9dec,7e1e9375,9717da37,33b4c61f) Z8(29f483b3,84cf5384,97a76481,17431cd3,533f7e0c,3f577698,fb727c05,60382a7b) Z8(50344115,d7316c03,2d83b31b,2e62fcba,1b8b106b,519d508d,11a47c48,5169ce92) Z8(29382723,260d6507,c20fbdf5,e33a3000,95e4b3c0,5817a304,892c9f22,9fda369d) Z8(1ffcb718,41be5a02,230a86e7,bfe7828e,7af6b3e0,f043722a,4783486e,2a0f82da) Z8(2db4313a,334bc6ee,e57d1f29,861653da,088e4428,bd150f74,1c88bbbc,9467ac30) Z8(d9b5f686,d7eb3477,1e55669e,ac5a7da4,624a73c9,e356003b,9f781f5d,cade496c) Z8(12bfa4af,9492ba7d,4dc1bb27,ebe4445e,2663befe,95e55fec,cae4902a,c7e28bbd) Z8(8b7250c1,00646f4a,77fcc751,5ebb615b,b2c655fe,689bca3f,59ca5dbd,0a3cd2b2) Z8(5e5d4ab0,f31d843f,aff5c48d,77a9699c,19e0eff1,a0f5a34f,3c6938e6,e01f5da7) Z8(88a2107a,034c5609,758c244d,bf277bce,e74ad959,5c0111c2,8f991ede,ac0cd025) Z8(e44cfe84,743ebcef,01f16923,6807e2e3,dc1e1318,d1d69dd3,fb058cad,ec8ce293) Z8(824cff8a,e3f1815f,ef92e17e,9d460c8a,a5441529,de0690f4,a2ea416d,820db6ac) Z8(561901f5,2fbc5992,c291526d,ffe3e781,04b745ec,37a21341,31ce6e2c,5887dd80) Z8(1b923790,1b9ec225,ce794fcf,393e1e10,1bfd4673,f7b73eea,c6b54e79,090de562) Z8(619958da,9fa99c16,a36b3064,758a34f6,2fa22d00,27df471c,1ccca829,f900de36) Z8(0a5dacd0,5a5ed6b7,c86f1ef8,c5e96904,f077ae83,76759f33,3b51736b,c19b532b) Z8(2288f908,2836525c,c96c7f91,c51c84a9,759f02dc,307f8cb3,6a651062,376d5a4f) Z8(69445ee6,b2aca171,77579525,e8fbe8aa,6567136b,457f0c30,9521426f,bf2961c8) Z8(3420b417,9229d3b8,3a0c5db6,783d7d76,74f987d7,7d22bf66,1147ef5f,80d1a5f1) Z8(bd8d2d69,8ed8f88f,132a0ffa,cf82f086,f9d2d4a7,e2c315b7,c27737fe,922d095b) Z8(177d8efa,2ac3ae70,a919ddb7,22a3efdb,601bb55d,95b5a93d,276b2be7,74ab206b) Z8(700db34d,ab76a034,043444a2,78a261df,9c6a0695,010f2cfc,234a2f61,cc5f0a26) Z8(3d2d949a,0063b274,7fc901f4,0b1d8ab6,3464aa67,65ecd4d1,2dd22196,3577bc51) Z8(17911e3c,f81b118e,81ddf8e3,cba8cd28,05b73bde,613a4285,9bfe7718,eac597f7) Z8(88e959c6,6edba835,1d153de9,98b88967,ba98774a,875f1318,9c6bf8b9,8a411b3a) Z8(386c1c19,ee237372,a2804472,0a3bc950,6ae598ca,c07f1177,dff9e1bf,7f5789c8) Z8(8b9989d9,6bea06c9,852aa3ce,14bb28ca,090682cd,f1679b5a,1d0ed549,8297c3e6) Z8(b3035811,1666f2d2,2b44d2ef,5616461e,eecfb86d,0760e0ed,4ca94bba,4913452f) Z8(73ecf00c,8b1e7224,06ccbb31,632b5b81,4f31a7bb,982505ae,381c25dd,9d8de329) Z8(514b33ec,6ea2a87f,010d9244,1f1e8f49,87b44cb8,1f35d5eb,e0362bac,b4786abf) Z8(0c8040b3,e80c449d,d4708327,57de11f9,258652e9,138817ad,b56dea4d,2e1ef1e2) Z8(6ce9b487,05b86ca9,39c2f841,dd5e1d18,fede1321,c9bfdf75,d8418eb7,082cd32b) Z8(6e5060e8,a2306f73,288c9835,4cd9f820,be636232,c19e2458,70661cc3,c904f3c2) Z8(029a9a0e,48cb8fc1,c24e7114,d57fc6a8,93b97c7f,f5570290,5e1c0abf,692ef2c6) Z8(773383e8,8583904c,975c80ef,97806c4f,0ae5e341,ce231541,a03cc804,78cf3b15) Z8(9687782a,51fec398,53bbc32f,5b54b2f8,a65b4201,b4463e2b,d2fd2a7b,ac1fb2ee) Z8(963e8b55,18fac703,3752d7aa,4acf480b,b2f5710d,71387366,3c303f3f,d18da812) Z8(c8ed8f57,bef3be7f,879d0688,6b46c976,8691b6ed,7c04703c,8ab1e74c,e1b27f37) Z8(71904391,ca30d70d,3dec9233,08643fc4,01b9a90f,2fab53f3,707e8941,b50a13de) Z8(aeb7c641,7f9498aa,d4cfb64e,422ef7fb,633ca9a8,cdc4b472,2496b512,8240985b) Z8(e8141cb8,c43fd3e0,ccf64e0c,8a34b11d,a9c12594,9dbb2baf,55c526b6,31348935) Z8(be4b8ecb,80eb7ec4,8b4c1f4c,484e9a70,48a53726,91f27187,fb74b71b,bffa0717) Z8(ae8ba841,adb71820,0ab1be1a,096182ea,67801cf3,1fe10129,b94933da,17cf4a23) Z8(52344e75,e1185265,4170bcfb,5cb3ea32,b274138a,dbdc048b,840b9be0,ca168459) Z8(2e80d8c8,b81f3f00,3b28de86,2ff2b406,887be281,b39d68cc,703e46f2,3b074329) Z8(8fe359ae,210b80ee,649154db,53824836,37fb02b9,4b4da73e,36883c2e,04610819) Z8(ee06b9d8,cdcf9547,a7b240ed,85e48d48,2c9089bc,cafcaf7e,babbc550,853a2b46) Z8(a79a10a7,81161907,3501846b,e0740aba,f47b540a,6ff1ac62,62177184,4f38190c) Z8(e7669481,122c4170,21fe9a28,673e3a30,26f506b4,eb519c43,6d3b6cc0,3703e87e) Z8(9aa57986,50548ae0,9a1b822b,a1046ef8,dac9c8ae,190a1b13,9eeb9e4e,580d16fa) Z8(accbfae6,fd07d290,c1c2fe74,16a22d6c,552dc83b,0814ad95,27b1abb2,a4b18b2b) Z8(cdb927f8,d83432fa,cfce8d3c,86453c66,417db143,c8e968fa,4acc61a2,da2c6db7) Z8(d1acbaaa,f4b569cd,f4276425,4a3dc2d3,58fdcc4d,4b951b14,4798f56d,51ac9e88) Z8(ee452e6b,e563f90e,77f58fb3,0d485708,033201e5,a5422c79,8574fb5a,dbb86fb3) Z8(d90a5716,6a72590c,9e9d9649,e62152b8,8b6a6b0d,ffe7525f,1dc2ae11,93618386) Z8(c3665344,b58aa6c6,53452496,04085f2d,41fb800a,c2399a66,60bd1d29,8513293e) Z8(28bf7140,fb024a7d,8ffcc437,bc8d6296,a2dc0a23,87874e30,2865b7ce,a80a7c8a) Z8(018b5b16,7f742b36,d9174f75,4e392763,8b3a1edd,fb46a158,14dedff6,0d2b8cef) Z8(b8f343cf,dc75df89,1fd2365c,98f25a77,a3653233,ea13eb11,e3689ee5,81cefe21) Z8(402445a8,6a36a885,1a4fd92f,dec1073b,131223b1,7f5353a4,862fe775,5650e6c9) Z8(35b2c2c8,3e598b22,68d71601,0c4f62f9,14944a93,d61a9765,8d10ac4b,2df4519c) Z8(9cf023be,37115c61,51859791,12690855,df8e5902,4add3e25,e0991538,322aba35) Z8(59e4bf5a,f2c4bf07,f7269612,bc633b57,ce3d177a,a31e9613,ba4d4691,2c90c164) Z8(b7ed9d5b,f452f8cf,2f6de019,eb27e870,37f0c3ed,80e8eefa,5c160015,2c1bc14d) Z8(9fb44b73,ddbbda77,8468170a,a78edf4e,34b827da,92173afe,3f55efed,a8e7457a) Z8(d6c7453a,31724824,f6cd81c1,64c046d1,26b99c14,cf3d900f,80bb424a,74472a60) Z8(a0ec0dbf,d932ee71,c34c44c5,a5648343,2d4cde24,a036ddf2,bd64d46d,ad1485c0) Z8(979cfe09,5dbef230,3674f69c,9c04754c,021306de,59e38f14,65a6caef,1fb9ec0e) Z8(99ee65de,96f8c46f,ae4b994b,0053aaeb,17593b83,3cc24c67,fe54e8fe,0ef07c5e) Z8(d85c28ca,7bb4c14f,40b8f013,4adf0cdc,2e1a3420,c8034e32,e193ee3f,95fbda7e) Z8(a2131cae,abfd1059,e645550a,58cec677,80e88d62,d610483c,da790950,08cdba6b) Z8(45a70085,b7c5cdeb,32d258a2,474c4555,c1fb8f03,468cbf8c,92adceb3,1b22809c) Z8(a1cb3de8,567bf625,74d93b0e,79de52d9,2f9c9c45,262cef5a,6197f010,825906e9) Z8(5af9aec1,bcd99b48,97118482,93e09059,4553d04b,b521706f,c174e809,65af81c6) Z8(3946a98e,94675d45,ccb143f8,cc2c969c,553fb20e,f6c19fb6,d633f4f7,402c4653) Z8(acb42b76,9e8ef8c9,10dc994d,a461b151,aaf44049,016c6405,23f8d36a,91d11b0b) Z8(177dddb7,07a086ee,4e90cac0,31d61bbf,a198fe81,db06fb79,7de6ae26,2ccfdec2) Z8(93b48254,a4882e9b,18dc91cc,58912581,06503f14,3caa142f,8c3903ca,87cf94f9) Z8(dc7ccb6c,776ab160,1a7dd901,a7d6a0fe,7b0668e5,883f3dd8,ea1c7b18,6715bf65) Z8(21456aab,3339d49a,70055fa7,32db82bd,9509b69b,65ce2a6f,5b1930ef,e426137f) Z8(67fdedd2,b1e9e4b9,7551caa4,9b33ef04,54267c98,042c6ca5,db5aa9d9,9c38599c) Z8(974b7017,58003677,9ee00b81,c978c57c,4c530300,1f9b560e,df0e4b3f,cff707cd) Z8(0bc2656f,bc23f982,a74f12aa,849aac59,c45287b7,80a580ed,c94b12b1,e843a996) Z8(530a6887,3029bdbc,53fb1e2d,1633a4d8,919f7c6d,bc153c72,9c4adabc,6102e7aa) Z8(35e6dd8b,d459f2b5,e9e8def8,6ac8599e,15bff119,e196b789,a8115e0c,58d26680) Z8(501717f4,f148bf97,f0b2ee7e,d0419128,924abf62,06b98490,c1677e10,dc0b7352) Z8(e818c113,23455571,f62e1479,70ec1c15,de72dede,b82dc5f0,ceecf3a1,e9b26631) Z8(60cbc58d,3afa494b,f85e2f7f,fcb4fd5b,08b62d40,7669dd3f,dd4abdab,0bababcc) Z8(4cefd2f0,ef33c8c6,d7d3be3c,362b4fe7,bc56e6d2,d37c63a3,41cad63e,d66c55b0) Z8(2862ac4f,11982f5a,f20f014d,da7bba60,b2206dbb,1ca8d84b,fe2e2dd1,67776002) Z8(ca270e4f,cec415a9,4636d5bc,385c3f9f,04ab7b60,02e423ee,7675749e,f8cfa777) Z8(38ba5e2d,4fe8b9f0,089cf725,72d97c3e,4e64f0b8,f6ffcb7e,e06f1640,981284ed) Z8(2a545858,e3cfa2aa,4b087f06,5a0510b5,a2dca245,0c9d6ee9,3ffbbd91,ffe2a1b1) Z8(8b3ae0e9,53b7fdfb,86183f63,b14a642d,2a369ab4,0e50b3ec,2415000b,4a20abae) Z8(674a4cb0,1df9e334,ab3d1e52,1b6799ad,09010604,3f271889,59b1ba9c,5fe6bcd2) Z8(a27f64d9,6f10d68f,09a53e53,62a051a5,27d0d7a7,696313e6,fc92fa5c,9073b402) Z8(1661d23c,703b7465,ba6a85bf,9a2ce73b,4f107f69,fe60e39b,6c557d40,aef1e5fc) Z8(84c25fa4,3c47d9ef,c4d2aeee,dad6c61f,a268b689,420f7029,37489a25,4e121ed4) Z8(3b234dde,7044587d,782a3162,2e2fcb01,592ddc10,f3e81a10,41c115f2,5579186b) Z8(e5a8f47b,849fa3ef,855f1fd1,f1bac200,5e343dff,2e2cfcdd,78a07c65,a621484f) Z8(7eb9cdf2,e518f6b1,8997e991,d9400b97,ebfd5f50,9486f827,5c379f79,321aace2) Z8(838f0ede,a81c65ed,79a8db09,ba62c507,04664879,af8b0f1b,850e54ce,37a2f13f) Z8(aa48df62,81295f39,ebae09a8,4e952a58,220a67f5,a0c2c0a0,274ba938,bc88fb06) Z8(8d09c8b4,e2d161af,bc464f11,fbf41bea,e9d636d4,bc9d598d,3966d13e,f101a4f1) Z8(4fa2bf1a,0d5c5a9d,2dec2065,6a9ed9e4,6f4f606f,3a10a560,49bcd39b,9375b64f) Z8(e809707c,9722ef2c,6112e8e8,dccc3333,b8ad8128,5562275e,e38df4ec,4c01473f) Z8(071045f3,3554d086,b574e03d,3dcb7c41,a2e64dac,94add171,68ff330e,bd020296) Z8(96d876bb,15a8f054,63a89867,9407cd41,b2b9003c,14042357,8f229ffd,97669e30) Z8(d4198f64,16f3982a,86d73878,f22f00e4,d039682a,9226c81d,01237758,82732822) Z8(3e469d18,a83fe6b8,bfb68386,1146d412,3a03a104,17f69581,5c1d7f2f,acc6a152) Z8(c047dc32,16e9ae91,e87a7325,66547d69,1b75e157,8e2e9934,43e3d3ec,1ed389f3) Z8(d5247431,4329ba83,04716c3f,192f2d4c,69eef066,a9b45d84,3d480095,573e9ee0) Z8(2e166f31,370e6f8d,3135f416,eca10709,aa412112,9ab920c9,71cfc7d5,2ac723eb) Z8(29fe827f,3a867440,3b8c4d76,d3fbcaf9,ee930bb1,3c6a2051,eeeae4d1,3df76f22) Z8(724e00fc,00a9d8de,2dbe8921,ebe5189e,0957e03b,6c4f34ce,0f3b7e37,28a7d4c7) Z8(6ec9a92e,d28fee8e,9ed145ea,c52d8614,7718c012,74104ed1,f5670614,0fbafea6) Z8(f23a8236,d6d715d1,36777389,c1b2d26d,c851fe2c,db9c753c,b947c9f1,b5b1fcdc) Z8(d3cbec78,a1742a3d,e097c05b,9f61f15e,0c9d32f9,746877b8,8172fec4,d5503879) Z8(7d5b2cb5,aeec3bd6,65b6e9e9,21c575eb,3419dc08,21cc6fd9,16b14565,d225bdd1) Z8(5245ef31,be9aa946,d2238972,34d44cbe,2caaac5d,8ab539bc,d85a0026,9e25b566) Z8(7a778618,39446cbd,9da3b989,bac0350c,79897b42,a0a08142,afbfcfdc,6af2b036) Z8(5c6fffcd,2a62f9ad,bcfe2140,0b2546d7,ef60b780,6511329e,d52a28ed,edb0e71f) Z8(07293273,d040016e,36cdb0e1,6e9155cd,979ed26b,7c887fd6,73f34935,cddda157) Z8(72aa1cb7,2614012b,47048167,5eee09cb,576a8376,30a008e1,7fc74a1e,fce74637) Z8(7e803728,63bf97e0,528bc7cf,72fdbba3,3100286f,313c56a3,e749f324,fec4fca3) Z8(0523aa81,6aba7a62,19d8698b,341f98c8,651cb191,aafef9a1,935aad11,2931c44d) Z8(761a8d46,e572fe69,f9d7aaaf,12bbe393,ec255b65,ee571552,8e61e2bb,14d76b21) Z8(52c396c6,09cc2dca,7c3486ed,e1c3fb0a,aa79c85f,202d0adf,6573e03e,d2748ad5) Z8(98f5609c,86cb914f,590ba3ee,a1ecdc59,84bd1dbb,6a01d520,8df603d7,8f433e3c) Z8(997a6d8b,6b887aac,cd9ce1df,68f56761,74fa1fda,bf11b00e,fab51efe,3bd457a7) Z8(85cb8f08,8a0a84a5,4f120fa9,94053818,7e8f9e25,31ecdf9a,ba526855,a1c8b028) Z8(3bbf2854,9e425486,ccf010f9,a5d3fd83,0f8da642,6d6d05c4,48359ff5,4447e34f) Z8(6e76d1e0,eafbbf41,c2199fd9,abde1fe1,d9e03b78,59db812d,5fc7d1e8,32da60a3) Z8(9b8443ae,a9bd8478,6d4fefa5,4323da20,3328f276,bed8394f,a3aa20a5,cc86ee7b) Z8(7806d88e,4e7c527a,ff879a04,fabc36d6,c22a64e3,f40196be,a410aa71,a74d44b3) Z8(3d337cac,472d1a34,b86b74dd,dd559082,b62f2138,ae33ae97,d0fe7495,8b7e43cf) Z8(b560a3ec,db9c77c4,aa93b59b,a2b2b853,86c1d87c,0825997c,1ff09480,0e225e25) Z8(bf98dfbb,0cd3c494,39fda330,c47735b4,68b3e92b,677c8e94,fc363ba2,87304eae) Z8(a5c93f82,5f08e819,05b85120,cc6ddff7,422d6d85,2ae06a4d,3dcdda1a,dae20c69) Z8(0473eb14,11489cc4,c6255040,2eff173d,81b45c4d,cec02831,9ed865de,8cb817ff) Z8(4105feec,4a879c90,cb9d46a2,6b16ca71,4ca330d7,c6b5c1d3,4719ee8d,4398c456) Z8(319d33ee,ef465d0e,72db532e,935d0b76,ef428db0,5dcb4f67,67a75077,45a9b1a8) Z8(0f74b1bf,2aff0faf,d6aa7d70,c7a52b42,d9daac7e,058efa80,e814c224,33038a03) Z8(cdc08abf,7bec9c36,c35059cc,b2e577b6,bdf5fe89,c5089a06,ee56dfd2,fa65579e) Z8(11bdca8e,b3471cb3,34112a78,7b5463b3,8e9f87c0,3f000f04,b124e76f,b4c0188f) Z8(ba5338e7,81b1f949,362e5a55,6aeb2772,3897ffde,89819c39,51c47be3,a25a676e) Z8(add51fff,1f3802e7,9a59711b,35287ebd,9ca20b8f,6a55bd83,b7edbb2d,c36191fa) Z8(2ac38a26,ce8bd81d,b955639e,80c23e1a,f59538fc,0df32298,e566300e,9470fca0) Z8(50c77d4a,ab9237a6,dd5b2d90,8042171e,e4d9d54e,127192b9,9afee7b2,1f881e78) Z8(dc1aad62,0f8dea33,9947d8c7,d84cbdbd,fc82fad1,1e9a850e,e1c08b30,7efbc0b3) Z8(83fac85d,0cfe9492,5a60afb3,5e917e15,c7e2c0a6,b43a3fc9,6e9992a6,26a40dcc) Z8(c0b6cd7c,dc29d874,490a9691,d1b2fbcb,70822fcf,ebdbb8df,0f0de925,b446cd5c) Z8(0ba7b0d9,15f53fec,11ac20d6,ea6ee286,c642e10e,458d7ad4,fc9513d6,4d24a8b3) Z8(afc14710,a256fe37,ab59aa8d,9dc7de22,f90a86bd,71456d41,59b02d27,9b6a0762) Z8(c3b77fad,f18820f7,b60ea211,e4c2d9b4,4c34997b,30d84003,ec1313f5,3e284292) Z8(e164928f,ed7217e7,50f9b146,060e3735,1ae6671c,4c2b80ab,ce6c5cf7,6154f916) Z8(cb174b1d,e8a2c804,9e8c3d39,1daa1f0f,fdf88c8c,ed06d60d,b8beb9ec,403d3acd) Z8(1452b436,82281f9e,c7264052,47c41f11,e06fbeca,af85e71b,794a9d2a,3dccc2c3) Z8(c0d12673,6992dcf3,f3f5a85d,fe4c77ec,8a3e243c,819b63a1,6ca458b4,5f316fb5) Z8(9563b603,bf7d3839,0c30362f,e573b3ae,9e9a2d10,e5a4ec10,4b36da3d,cec745a6) Z8(8c156914,ed81e976,d54665e5,2fe201aa,b07dcc44,e395b974,5457ea19,4412a7f4) Z8(dc99c22a,063a2695,c8ecf1fa,ddea54a8,69164be2,19f9c4fe,78efcf3a,248e6dde) Z8(babb2635,725a218d,83ad02f8,be9a51e4,37f40376,354ce094,fe653d9d,333ac2f2) Z8(d6fc9c3f,7ad92d4e,56af163f,7b65a8e4,0251999f,6142d49e,78c910f2,b269591b) Z8(6530bf38,334e2f52,7920014a,0371ba95,915e2b0f,f6da9411,f437ceef,c3242664) Z8(13120af5,45cdfe4a,34df4804,4fa5caef,031edb3a,c3a764d3,535f37a2,037ce182) Z8(7a774777,077149d2,6c8b0f61,c613e457,446a5195,3fb56ddf,4285f9bb,38119391) Z8(593266a7,0f4e9fe3,2e9865e0,fd99933f,aba19d5b,dd6484e7,8e09073d,826986cc) Z8(bd556e67,85ea82da,95d0c141,b27d0147,b60f0103,3e2e5fe4,5536b7ac,e7b5ee82) Z8(8d1f2e1c,c8c72d66,35c578a4,b940d44a,09c7a3f6,dba58117,6453dd1d,56947615) Z8(bb5e0d83,57d0934b,2c565994,53960d0d,a7225f5c,242e456b,5374557c,6e0a75ac) Z8(61990bc4,75908e5d,8ee49443,245cdcfc,b6bacb97,ecfa87b7,1abda1fa,6fa185df) Z8(a0f4e7ff,b6b7b3d1,def531ce,c0b0146e,7e71c665,6b19f0b7,d7833a2d,88e832df) Z8(bf364bdb,255cf0ad,a6dc43b1,9f4957a7,8068ba08,62043a04,3ec023b9,6cc8e699) Z8(f29d9fef,be8e422b,03b78383,01d7d7d4,319da696,e1bac4d7,644d9a9b,524064a6) Z8(51bcc378,d3ccd8e7,91a18352,56f88cae,6b67ff9f,9ccfe66c,54079417,03d802f9) Z8(0fb6ec2d,64c8ac2a,0e3a81ec,38183b05,67c509c5,268ab93b,e1422f36,5859d7f7) Z8(0333e55f,2b332493,cfc57410,9c00803a,4490b329,a69506a8,3c7c8005,2cc472d7) Z8(610a2a54,9e03eaca,ee446427,63469aee,8d9eb2cc,4815db52,dfb2a4b3,5da5234a) Z8(2fa81c4f,5b93a4f7,4981205e,25fa87be,655790e5,74250d4d,290d062f,ca17eaf1) Z8(ad76a0cf,753feb13,86b3fa5a,60cd9e6e,a1784e20,58ad488c,1e777ea7,f19e5afb) Z8(5f44e128,7a6c1d69,282c8c0e,85ef3b4f,3d8e10b9,2978a42c,7d520e68,3a22ac5c) Z8(16787a6e,a913fc9a,8b2b0900,e6942d2d,0485c40b,20c94470,efa45bfd,2fbe9e68) Z8(e0c16af2,0abbf073,f5d6bf94,6cfc6395,60b6b19a,65d1bf29,7812e263,81724f15) Z8(d6dd4be4,acc8e4e1,040bf9ca,6aa87c48,752b13c9,6e207697,64f97aa7,49bad747) Z8(e318856a,362bb7f6,55fb34e1,257f1def,828fe68b,fef81f03,f1a795cb,60f9c568) Z8(89fa0414,333c5e6f,651fd552,8211dd64,e4120a56,6d264133,74c9a54b,80bb2305) Z8(5b11cb97,59c9165d,1f65011c,0e2b72e3,9d167ab0,db9b4729,b1eeecd2,6af5bf0c) Z8(2f9605e5,a80fbea1,81ad2f63,5bcfaaa5,4c7f5af0,dabb0f5a,c88b926c,0a4289cb) Z8(1edc041d,8196331b,887a104d,4ad5ff75,e840ed15,972576ef,08ddae5a,c1d5ae3a) Z8(924f1d81,35628452,ade4432f,edaa4083,34c0eabb,d04ea2e7,e4f06e04,a73c9800) Z8(7de7648f,6fabc0da,6c9f0187,11cdcc1d,a44032e9,4edd46a2,eefda105,0d6f2b04) Z8(09348209,3a8e2c0f,f04e3e80,61016297,6af1ebb0,69753a6b,6113e8a7,86869ec1) Z8(02c322ee,fc64bb48,c24a72d0,4ce86d0e,4bf84854,65d6915d,95441441,b545c9b0) Z8(e1c0d8d9,11ca9b5a,dcc771a8,952181ea,d8be314b,680754e2,5fe634ef,42fd8083) Z8(b6c21561,8a33a328,a2fc4672,7caace45,f7de5cbf,c2b5d4f0,16e52e07,cb4dd2f6) Z8(0a3d726b,44150391,dba4f2c1,c1c375e5,79b5f27e,38f707f6,46f10dd6,99bc3b62) Z8(928e3376,279e47a7,84004249,5cc33ddc,2a387cf6,eb470539,c186d2c4,a3bc8f5a) Z8(fd9f40d5,21219b40,39f70763,813cddb0,d598fe1e,d7cd052c,ce05866e,4d1c71e9) Z8(3ffeb8b3,ce3bdcd2,aa26d3cc,38b667c6,ddba9233,f6862a8b,91e681c8,8f900a89) Z8(819ad4a5,a31e663c,027b8001,4cf5014b,18ec47b1,898a2c81,60f7420d,b22f1f01) Z8(64081ef5,c5677ffc,cccaa2b9,49506dbf,c83ab954,aa305a3d,7d5f2ac9,6fa5ee04) Z8(bd00a01f,a38d9852,485d1cfd,63893e13,3260eb86,2624de1f,970c74b2,3bc14e6f) Z8(26d4fe5c,162c495a,335bc7fa,085f62c7,ffa94d1b,2884be51,8affe4ef,2b9e4a10) Z8(8ce98941,005461ea,8a2c516e,183127c3,0b011936,35c18ee6,e40abee9,6df3bb64) Z8(0931b7eb,47a92fa0,9b449153,6de1b799,612dd296,a05f104f,30d0997d,509835f4) Z8(83d064b1,ba3062d8,b3fbbe80,0284e29c,2fee0176,d4d00d0f,3d204abf,e2db2124) Z8(517c73b4,0a0ba981,f3aae28c,cb73f073,aaf5d0da,b87390ff,d4f55752,a06f9130) Z8(71a1cab5,46645a6d,055c8cde,cc8cd986,70807b57,05c938f9,a6f907c7,18351486) Z8(d28e2d06,17a03091,b46824d3,04826338,f080559a,83a48684,29a9caa5,8fe94a8f) Z8(1f64c387,549534ad,0cacf352,1a7960a9,84c40816,35ef8038,e198faf2,8cd4749a) Z8(3fc35705,b4456a74,3aaf0be5,cdd96a83,d31ae6e2,0b4b1e1b,8f7bfb45,fa65c53f) Z8(506babf1,72b176c7,8b6d5eae,da74bb88,4854ccd2,da0aab69,1087d023,88272d7e) Z8(7f9f6a64,2a90da41,2d7373bd,b965c475,89970ec2,35b4d313,a2cda40b,22f36ed8) Z8(00fd6841,a0782276,09fe0f88,9196df7a,9ab4a758,9c94f271,e3be5439,e9f0f7a2) Z8(14096571,ca3d9b10,465bae56,d2354d09,1e78a2df,f734761f,5df73a94,653a45fd) Z8(d2e791f9,da42c901,9d33e512,7c1bec6d,c0ab7a20,ab4bb5b2,0556410c,2da2d912) Z8(3979d55a,91e94bee,bcc920dd,f24dc6f9,9c304167,51d7181d,5cd731d3,1bb9a5e6) Z8(fdee6b54,3976d6ef,afefab93,838935d0,3ad4f90a,ca36e333,af9cfd75,cd42d74c) Z8(873dbc02,ba0416de,0c600969,2ecf15f8,2faf275b,58475376,05efcae9,66475a02) Z8(ef11c4e3,a5ecbf7e,b213e4cb,9d059fd5,a2d47c4f,49b21ac2,a2fa1a21,0be897e1) Z8(0f9645ef,37448d50,c20f40c7,ec4f1c85,749840c6,12fe38a5,c7fa0911,41f83871) Z8(96cdfe6a,75daa9ae,37cde45b,315e71f3,fd3f4efe,df9ae38b,1700fc0a,2b388b92) Z8(de2590b1,1f431ec2,4d18a81c,7a6cc118,a5133d26,4b874563,b96306d1,31da3bd9) Z8(1c2e86e9,5a92bf4e,f2799c5c,885aba65,ef3f077f,a80f855b,6c742aaa,25558053) Z8(ff1c76b6,ca92ab77,9a0a592e,93a4a4da,9f2370af,9d2eab5c,2fa2b955,65da0ca9) Z8(e719dfb4,03fac65d,83c634fd,7ce1e57f,047d37d7,cb318673,2f8b79a4,c0afb950) Z8(012a81b3,a8f4d3e3,9218f1e4,1a70e020,6ac524ed,52aa6254,d6a37ce8,a998641d) Z8(f9cebbef,5d4f7698,f4f48a41,a02b7a38,51f224c9,5f732f35,7fdf432a,e5504fbe) Z8(a88e2f05,4e295ce9,3de5ab56,5670395f,80c02609,ee2423b1,9fec35c0,b902bd10) Z8(a5a02878,76e1979f,662f12ce,9b265cd7,fc96deeb,1d5ccc02,0f681d63,5eb6b6b0) Z8(f5ad88e4,b3005299,43cdd351,2fc844d3,9038ae8e,1da5fce8,3a35f93d,3e1f9879) Z8(93500a30,3f3481f9,ca0f3d1e,d1228c81,a29b994d,e7b1c973,08b8b290,435148d5) Z8(b64aca15,b59e62f0,376dcaf2,dcf4db8a,9a9ddeac,6ce2de8c,d376426e,c58f9ca1) Z8(b2bfe777,ec0be667,e6e13388,ba8c4aaa,b4dbbc32,e3433e7c,38ca798f,620ec5c3) Z8(8c774ab7,82c56d95,bdbd9e49,355c3303,f2e90307,a88738f7,2b8d332b,754837c4) Z8(0ae0310f,f5e79f78,51dc847c,49b75621,24992230,7a0b37e0,6c5bf081,2bdf3081) Z8(96489218,3b0003a5,6b8677d4,046b0ad6,d92d0a0f,f437810b,07c3d7f5,c8bb8fc4) Z8(8975d8c0,73525641,c562e3ff,fed2caef,7f0f391c,a06e76fc,b3bb1a79,b3167291) Z8(d678a207,18508254,8d03c20a,2a4bfbdb,956021cc,15ed9dbb,d953d941,455fc5ba) Z8(19748662,32c889d7,41de65f1,b0cc248d,70ed1b51,c05de5cd,a4bb95ee,4a885848) Z8(22670cf5,6f742c2a,799b494e,63447a5a,f3d456c5,7b3dd99b,71a4ad6c,8c93b4bd) Z8(41a521e0,d1b398ab,6cebfdd5,8e137ee4,7d6d144b,2faf9270,7c493d43,b02d70c3) Z8(96d12cdd,790210cb,4fa711fb,4bbe550c,4cc1c4e3,670d8e62,798ac5c5,97269f22) Z8(6a31ae8f,bc09e0b6,674c7561,45c135b3,a5eebcb4,dcc4ad8d,cf160a2b,1de4610f) Z8(dc43c0b3,fb1b3a76,36451a2f,33bf867a,fab8a543,c442c303,0246b72e,02235eb0) Z8(5a39bf41,7fb8e4ca,a7c4d286,cf81208d,62d1c65f,4812a716,ee93ca35,b6354d4b) Z8(920c0177,32c6cc16,299c14cd,bd7f15ef,346f5ac8,2d13f323,c32a48a3,30ea3925) Z8(aa4c169c,bacec4ce,160e11de,df96e25c,8988dce4,01a986f2,eb42ab5b,a12092e6) Z8(8e290691,f78f45cf,e6682a09,60ee289a,0bbe0d1b,049c0d2e,fd979819,74784a16) Z8(f7ff5380,72323d62,ce2f5757,38083a10,bddced5c,ff96efb5,2249f807,980e8f30) Z8(5620cd87,a4b2b116,01753cc7,a2fd0e89,94df8174,cd067049,424205a2,71dca628) Z8(15359599,84b5117a,eef608b7,4d503fa6,21cf3dc8,9613e554,0b79f89b,590c9c94) Z8(157f2143,900736d9,86820761,75ae6e02,2bd445ea,88309eef,6c2c3f12,103fd3d5) Z8(48a83352,f293f8a5,5083c400,2c4a1d55,2739f9be,8f3001a1,ac6b5f95,48e0ecb1) Z8(2ee3eeca,9e70375a,09c50d49,7578d538,33f85be4,7916ee55,06907ae6,a1a26fcf) Z8(2e24c445,cf80c99f,88c68402,19027320,82102ba2,3feb41b3,4e97d9b0,f8ce8ed9) Z8(0b7149f5,1b9ed568,b1df1c60,527eff8e,0899a18e,eafb8c50,a06b411b,51bdb36b) Z8(9c7200b3,57a49e61,630e1aac,8e455ebb,af793770,b2131ca7,923c900c,e9417816) Z8(5d72dd51,aa3a3d14,766837d8,656f919e,793b4b2a,a64306e9,aa1a9642,00bfa5e2) Z8(16c222b7,a8837cfa,63065529,977f2d0b,5184c500,e567e35d,6cf5ddf3,cea84345) Z8(9a656110,ac3ba59e,86651415,88f39a78,93b7de7c,9ad5210e,214621ec,adb1af3a) Z8(a50ce5c4,4a39b873,04618c27,98f3d112,f2ea6877,1121d963,791864ae,85f3476c) Z8(2b9e53b3,a257fce7,76943f0d,eb940e3c,b97f9163,0b65f0c6,3444e927,a2723ed3) Z8(e995a3a9,bc72abe0,c03185bf,b98be86d,e4a040c6,c0854bbb,3aa7585c,9cf286e0) Z8(dc974f9a,e842258e,40c98f11,ebc60262,37681905,38eee755,c9d9a699,44b24ca0) Z8(a26f3314,9fde180e,91dd5fda,b78d2500,567cf4c2,fbadaaf6,ef074e40,af1ff740) Z8(9d7efcdd,b7634c33,fa542641,6d197262,44d351cd,fe8f0136,324bec11,6d2176ce) Z8(6fa6fb31,0d171391,2b5c713e,09484346,0c7c7c34,ceb4d9d8,2c7cfa85,a15a7667) Z8(773fac44,09d29096,7e1af9e0,e36a6a54,0f611fff,47ecbf65,e8b88ad1,782b678b) Z8(42e0de73,c87bd2b6,2b3a440b,1a2883d1,104f9cdf,552048a8,8a30336c,32359f20) Z8(b8b6da84,986c328b,ec28c8dc,6d6cbd12,732a3b88,014e3795,e3d2a945,10cd66c6) Z8(34eb9a54,44642866,baa78aaa,b4fbe210,29c4f58e,23a9f811,a6a209a2,4e3f939d) Z8(2da8fbef,fe779e58,78fc754a,dc0ad026,7407466c,a2d947ae,c9145112,97474282) Z8(87f6c5a0,7804c5a9,f2d8466c,c435c9fd,5a10e825,b31c0738,71fe322a,093c2c22) Z8(dc03ee40,ed26d33d,a9b25d26,2e5e9836,9c0adbe4,d2b0c42a,9b7fc4f8,14337368) Z8(032fc35a,e9d550b3,8a482575,6a738d55,87567bd0,26ca0775,3788b71a,db3b666a) Z8(054e4e69,edab20c2,a3397ae8,cf2bf34a,b0012618,942ac74e,f05fe227,39c08c40) Z8(78fde40f,8a31056d,0887cd49,9d864f27,320ae003,bf4b8e10,d2630cb6,0e0b49fa) Z8(888d8c40,7ffa5c66,4b154cda,5833dc33,db77ce73,16623764,3c3b6f75,47e432d8) Z8(dc524cda,d06e3b87,db9615ab,a67e3e4d,f6fa153a,ab1ae872,f421d738,2ec9c2f8) Z8(66750ac4,4356d8b2,d364877b,470d310e,4d8dac3c,9a41057a,5a872b33,9c75712d) Z8(5634fda6,90f3a8bb,6909c9a8,e1f34c38,e042ec17,ccfd6b40,5ffb3cf0,3fda7a6d) Z8(a9f08b22,b79b50ed,873caf4f,f9a2b5bf,704e2b81,43943ffa,a5ab6aa1,3133b641) Z8(fc0945a5,c568f3f5,dcd58989,d8c8f252,0dc04c3b,ef9b85f9,2c55f416,581eb7c9) Z8(acc0c38b,40216de4,52df8bfa,627f6dea,a109da7f,d52722c5,f5a2fd6a,0cd2f0e8) Z8(a5aa9488,596f9884,1104dea9,c8535ea0,97985f47,150f959f,63f5bfd6,e960465d) Z8(e047dde7,6a8f3e1c,ad1355c4,04695165,4a7efe51,837903ea,36a9393b,3598f8b1) Z8(06e6f4f2,7ec41821,50e8b0b3,8841c284,ccc44173,1228f51f,d8df8842,63d89b82) Z8(8a48cf46,06167261,55af6088,f61fedcb,3a5ef9ef,f7f76ca3,93c42407,60b78669) Z8(d6b9947d,1de40880,78c6feaa,0e260616,0bf9eedb,45ef0a68,92b37630,479f6b14) Z8(3dda20eb,450c32a2,26ba2ba0,b38f211c,b5916ef5,1f428920,474c5790,86db5931) Z8(3e1f65b4,4b149f6d,fc6258c3,19074999,9b8497b2,07717189,2ad87f46,77d920ca) Z8(15c0cecd,46f23223,514f4fc7,87b1a9a2,7d60c675,85314f1d,8437fcf0,4af76589) Z8(c28c2417,680b5bbc,6fb24f10,9aca6a10,1d1cbc73,47595c9c,96397988,42e91099) Z8(31f7f77c,c664b323,66f66721,6041fece,b172444c,e58892c9,39bd245a,8372c4fe) Z8(e543fab6,58d81014,09c18e6e,f0e8e588,7f1955ca,266095d9,8c3072bd,c6598bea) Z8(03dabc5e,62a152b6,c24fd364,2aa7cb2f,47bc2cbb,80fc28d5,e203d1a0,65a93d99) Z8(907c3ec3,539b277a,df9b4c96,24c6cc17,c4e1f20f,43bb6911,ee61f093,2800d0f5) Z8(a61addfe,40d06325,fee43fef,1efc2691,fea11954,4f409032,dc598665,87c38e0a) Z8(0b5d0200,dc82a4b1,272cef4c,dcd90ddc,bed33f6f,4c95a282,c3d463e2,3cb3519c) Z8(664a5b84,337f4690,425f387f,0775ea3d,430e2ee5,2879f5c7,3818551f,15e9a53a) Z8(952a8c45,05ded2e5,53f3f0f6,6b0011b2,58fd4979,b8e33cf7,ba0c4e81,09e247b5) Z8(ee36adab,b56cb17d,83894ecc,91b9f7fc,8841d510,3c112afc,1f6bbd1b,d460ba5a) Z8(11f3d8ff,b896b844,ecfedef6,c07902ab,8564ae15,a2f9d9e1,43547967,4630504c) Z8(f8ad197c,ba91e7a5,8b461c47,08fcd404,9b098c76,cede1256,1b9af659,7df0a648) Z8(f2015b5e,09a4ef35,35e39803,9930ea5f,c8674023,a1ebcd25,32108959,02b7b5f8) Z8(7bc30d40,62c4315d,28c51420,20b12869,57361b18,ee6a3312,ecdcb1c7,e9b5ff60) Z8(e0262563,9c277f3d,adf2205a,277d101b,095f234c,b9a57105,ddecba8e,589f3a27) Z8(f23ac397,2f9c584e,2cc376f0,ba86e66b,c2b54ef2,71dc7add,5e10b017,522bdd66) Z8(0c513a4f,83886884,c2ebe392,fc97e263,aa5098b4,6d8f413d,fc499e94,5f467b48) Z8(35a27276,0087091a,c8162cb2,88a436b8,96cc26f7,f7c20c92,dd3b6407,c3204908) Z8(3bfa564a,234f93ac,e9e5f435,398e36ef,7b4245eb,7e7c7645,45f5f978,e955d3cf) Z8(6a364ce9,bfaa4dd4,93cd7b93,62d29670,e3e026ed,dc8fe1ca,eaa1c8a4,c8a3dca8) Z8(9f045891,0c9ad13e,bc29a613,d6fa50c3,224acf7b,04847f6d,0d92af70,62103175) Z8(61763c0a,7121042c,d50c9aae,9f1965df,ac92dd8f,0c6a4e74,99b4b1d4,a237a8ec) Z8(26815795,1d7e24cc,8e2330c5,d9377421,3fa6d4b9,daef41db,45f872dd,324c8c66) Z8(f87ef469,6bb9562a,4bddf664,6a63eace,f7aff23f,1dc82c8c,514ed7a4,aab89149) Z8(302ba5ee,bdb7df42,b6bf2968,2206e32d,d2bca852,5b27dea8,88fd4952,62305775) Z8(9076b5ac,7c856ac3,70b83fe7,1c611742,dc3d48fa,45ec41d7,33da10e6,a1ad0806) Z8(6cc3bb53,fe05e2d5,e451bfbd,1b5a8406,a098a341,ad72bf01,d911c27d,aca47a2f) Z8(ab733cca,486522f4,eef289e1,77fc2bde,8eb59787,3ee7f5c4,08457078,371429a5) Z8(7ff20dd9,14bfab5b,5aca1111,cc105d8d,64c6b0b1,8e9c5e59,797587cc,842ed74b) Z8(57f3ed4f,e4538437,b9dff58e,516393dd,b01e34ad,9a8e7d43,09853e16,0b1d6ef3) Z8(aa9074b0,b958ce3d,22f1d65e,d96d66e6,bb8ae192,93f51eba,7ad073af,f5e72971) Z8(39709c24,1df19224,bccf70d1,256afbfd,f859c6ae,81657f41,0cf90abe,d49c0cfe) Z8(1504b22a,a850c024,79229abe,fb279cc2,6b02971d,e8338ce9,4ad08065,a8fbf930) Z8(401f1e7d,2977f5d1,b2bd651a,c51c5657,2275b035,07d21737,9341f412,8d2121e9) Z8(71a3900c,6b19c103,0e56b370,ebd1dfb0,25ae6ea9,22d60633,229b8d18,9b3a92df) Z8(48cdbc4a,e50686b8,e94d020a,018c3093,d2d0ee61,a5b8af9a,0413abd8,64d1c02d) Z8(f332d6ba,1d0bf071,b579674e,e13af63b,8ec9d2e6,cc1f8772,10ce7e44,93661cb3) Z8(11a3518f,1fc5278e,13c5b070,e09cdf2e,9c098df1,6c2eb2f4,2b13f45d,cde8f30f) Z8(ef6f4963,66b954d8,e4f38a08,395c8b05,181581c9,92c76845,d385ff98,ee622174) Z8(d97e5ebe,f85772f7,8c642474,f39a8076,869e814e,0da01871,62f3e547,985cb394) Z8(06755492,c2db51d3,f965aad0,bda43815,84615baf,c899395e,76653a95,11b0e4e0) Z8(aa06bab5,495cc2d8,fb375309,8834a8e6,d98b5726,38d484e0,600bed68,ea8c6004) Z8(afc20a15,493143ba,916c0490,bcf22ff0,51d7602e,9a307a5a,f858c7ae,51b3fbec) Z8(84daf57a,14fbe122,7fd87549,d97dcc9b,1c674161,cd85ce86,ef167391,4ec83d36) Z8(b78c5f48,ec5fb40c,4e336dd4,9bc0b6cf,6f5eef05,3331202e,5f6b5690,68f4e690) Z8(cafc54cd,8431df00,9a4cd177,576beee0,f5afc3b0,96d1fe51,4bbdf8cf,e7d8aca2) Z8(c744c8b3,1076aedf,0d517aae,76525d26,b1b432c9,3970ea56,7e5eba36,9e264ec1) Z8(a5d171bf,24d90d96,e2fcffb1,011bf68f,00713a09,ecf69073,cc80b90a,60385e93) Z8(c7c9dc19,e175e995,7524defd,22ccb565,8dbb1885,24bde171,380f8acf,bb2a89d9) Z8(12ce9801,813d7e01,56b00700,bc0d34ec,06b4938c,b93ad22f,a8e769c8,8fcff3e1) Z8(7164a8bf,f5ae384c,52896d12,e661ed45,633d559a,8df8ac78,04b7e20d,1995aff2) Z8(f2895967,b16b535d,7c79f2de,c7978c06,0f81390c,70af22cf,c97a26b1,4b656a73) Z8(e974def6,7594e4f4,59c4b41b,844e6955,f30ea252,3ba2ad86,56e6bb84,e9fb75eb) Z8(3dab3a6a,d07e950c,cc3dd9ea,c76ef1a0,11e44ca3,28b96adb,85e8b436,cd92fd3b) Z8(aad4923e,28be47ea,2acc6205,d7f74de8,fcfbaddb,79d1b07b,87d598ca,5a95af25) Z8(979b04d7,4836c21f,83d8c3e8,34c3473d,362bbbab,83c8d7bb,8c09aa82,e0247d2b) Z8(6e964600,fceba3cd,2a115632,8c4943fb,45675ec1,8f35f457,4cbd2bc5,8fa2ffed) Z8(aedb478e,c0b0db8d,21fe9ee5,ff4cb772,b8db5fb2,73f6c64b,3ad183f8,f7be6065) Z8(ee7c65c9,4a7e0e9e,4c6bcbfb,3c2e3909,3b099536,2bccc9d3,cae91107,edb358c7) Z8(c0a791a9,9b2c52e7,30ae06f2,86164755,612cc1ad,5413c82f,17d6ede9,b446b534) Z8(6c58be20,3d91b4cc,5ba33888,53d755e1,6cc8d237,ade7bb8f,a4e4fbee,3144ef5e) Z8(6c358d76,c8348fbf,d30ae2cf,3da73773,e4aec310,0667efc4,e3fd37f5,43a00221) Z8(8a552c28,109d3ff3,49bc6f35,6dd88076,86d3ec85,d199de5a,56945b1b,e028d1a9) Z8(f22e1218,5cc58e22,d2bb5963,8a956e19,14930f07,acb66b91,42a731c8,fa32e874) Z8(99c4a7fb,28666c29,e0ccbf26,0ba46327,f59ee1bd,cd1f9e1b,adcc80e6,c0d36853) Z8(12eb7628,2923276f,e1199c4a,efdaeb2c,fdadd3d1,8608dac0,ca39ca20,a7019ede) Z8(2936aadc,6ee60c79,425e4440,fa2f5df8,998aef93,48741035,76afa27b,0e70170a) Z8(5bf2cdc6,005b9b14,1d919d74,545b7577,d13c67ad,01d0d222,856ca329,8d74bacc) Z8(72062ab8,22b0fe46,cd4a6cd4,10f2878d,d7715e15,ff7346f9,b330f0c7,e020efd9) Z8(d54773d4,2ecd8206,92b8304e,3f6e3665,4b972c9f,9df28d7e,845e8174,d4a150e9) Z8(20e149ad,cc0e5f12,af1f09dc,043f14c2,00b50ade,31886ec3,a343b364,488b7c00) Z8(ee30e398,39038916,21e33e10,2578889e,6637a911,d919c6ab,e57cf1c4,4621b73f) Z8(02a032a4,1ce6d4c8,1db9865c,a50cdc5d,c9bac550,b9719778,06653be3,4e8f7167) Z8(0847fc7d,316154b3,66035dbc,0fab2949,91658bf0,d5aaad87,90f35d7a,ec2a9a1e) Z8(217d764b,b0c9bdad,b5287f24,5b1d3a90,ec94a44b,5f976ddb,962a48cd,319f2fbf) Z8(e6a8c301,636f3a5b,b3fb63a0,905c6d03,2137d4df,c758fc04,b765b662,d2484e0c) Z8(829b303d,b3a48b66,31f9badf,098b2f28,bf315328,362ad68e,ddca5f4a,9315e3b4) Z8(e4f00bec,97ba6fbc,122fc48f,b3d3811f,7b4ee276,c7584b8f,29e8fbb6,7c21a4c4) Z8(e0b6bb59,f0b08d1c,ea6589f5,5cb9e60c,5bd008e2,539d9fb3,6f049383,e9c8cd6e) Z8(07edaac4,b8aeb6a1,2939940a,5d9ea6f3,cb2e1f02,6d049ef5,5d8da069,9eea5ede) Z8(406ca77a,9f724f3b,83a3e939,e1b27f9f,7c547041,b532267f,5331ad21,91b86857) Z8(67ff16c8,13d4179c,fd1b02de,673f0c50,460dbd36,473980d8,ab87611f,b6b290d7) Z8(5e705203,b7c85154,8229dec0,42133979,d463b65d,85a3737c,2c8f85b5,e430c302) Z8(5b3d46fc,f3ed3812,a678bc86,43e42c3a,26174347,929b59a0,9e49e59b,3567c9c6) Z8(74d3caf9,019dd823,7d7c46c8,6411e72d,e22bfdbc,945c5f3a,5e978e82,729a2a1f) Z8(a71421cc,78f5f7c5,c198c253,a1559b8c,0ecca69d,155f6547,36569ebe,0e7a61f1) Z8(e1191ff5,2bba553c,da22daf2,e47291bb,f553bb2f,0ade31ae,65b82954,85a759c5) Z8(b1a5524a,4eb8221c,5525e540,66e433e9,cea1387d,651d9b48,bc4ae3b1,4c3a037f) Z8(402c3990,bdf27b08,b1d23d82,4cd93856,ab2edaed,adbb2b1f,1d273e30,872574d9) Z8(d7fc34a5,e2a0c4a6,9dce5d39,1e77bbca,ed219ce4,5ded478e,16dec3e3,58780e49) Z8(c5e7f0e9,0ae16ba2,375d6e19,5ba080c9,075887ed,5bfbe4e4,5bb8baa2,deb6451a) Z8(342c1bc8,8f41dcd9,b1523c1b,5fb51d5e,a52ce86d,696adf3b,6d1f0696,305c94ff) Z8(3d6b6272,b8b2ef56,c5736ad9,6dd04673,a788a2dc,b92acfec,4001a471,6b86c695) Z8(7c7b0606,29bbdbc5,7bced649,f59e1cc5,931fbf9a,4214e0e4,633ce226,d98daac9) Z8(4208d152,9033fe17,f64f3541,9f5cc28f,c0b8ef8d,f0f77fce,4e0b6ded,ea8d8ec2) Z8(3a368607,bd1c15a5,5f2735eb,83fae826,c11b61a3,3d6ea890,2b00bafe,04e38275) Z8(a5f7abbf,a1c27f75,7df495d5,45708d42,19b051d8,a83c6256,debe718b,645ba8f3) Z8(88a8ed29,a11e2c89,90ceed96,05af61e5,ddc96626,6f87d260,1359b63a,4b0f6681) Z8(32da7d01,7a953318,144b6fa9,68dc2068,edc4ba95,775d69cb,5c047408,b0efa623) Z8(5f78d889,f87f5869,76ff1b2f,1f840d24,b31ba5bd,a5e72b53,47a04f10,0729cce6) Z8(89be9628,b209eb36,db812b0c,9fe3a8d8,1cec1aba,29fea239,769ce66f,fa4d2378) Z8(ca67401b,aea7b89b,28a7fdc7,45f8a728,cccdb83f,6fe5f7ed,88f5d1ca,bef87b40) Z8(f6d8a8d2,8fc76060,ba5b3933,37a1d510,a3d623cb,763c895e,1d44efbe,78728e2c) Z8(d3ee9459,8d11c07c,2b6933ed,deda871d,70dbd17a,be137ad6,579b73b7,3e90481e) Z8(dad0a3d8,73c61008,9034f434,b6a55e6d,b1b5e13f,f61e23d5,43f150f3,9cd52de9) Z8(6c57926e,3cfecbef,0633967b,afbc52f1,e58ea230,36466e8a,fe7ff80c,43869d1b) Z8(8b47e18b,f337208a,a1431164,cfe94dc5,5b1c428c,fb509344,95fc5689,0f4ae06b) Z8(e286063b,38ae3230,6e9c71ea,8409483e,8ebf1258,f1534409,173c68fa,4fec18bf) Z8(87f7f809,17ccb67d,771bb279,4d7b761a,382fbab6,bce838e4,f551c1b0,f8e00900) Z8(ba059f72,8d3b3de1,8a133c94,05781da3,a840c21c,8a78b14d,c7d32270,e029c1b4) Z8(da7a85f8,46c7a9a1,0e417c08,149e1893,8917ebf2,52031172,7bd66dec,6e97f076) Z8(fac8cd48,923f5120,226a5bc1,b9a0cf64,de128515,9bf14a39,be0e8475,deefe8b1) Z8(e98e4f76,eedb1d3d,a263b129,de30bc5a,47a3d9d7,5b426966,62a45aee,930d7749) Z8(e57e32b2,514be446,a94b8be8,3dc97181,0cf39765,4c7a11dc,48db1385,8143be8f) Z8(afecc86d,e85872fa,a4674253,6bd49108,df62e534,9c1d4b49,a832d845,aec55fe6) Z8(715b762c,738885bc,c5b04f1b,6a22967b,9e1253f5,ed49d668,8d98e350,aab7067a) Z8(c47e18c7,0e0ce093,902b3c2f,96ed0678,2006e282,89c81f69,1ce0c437,8ae66600) Z8(cae9fa6e,26338d5f,ad4f1047,d87ec9db,8de0f3a2,0b814935,9a9382a9,14451b93) Z8(78a0ec32,c53e2385,d9e77b76,37eb9454,a4369ed0,a4836ed5,7d97495f,b12843bc) Z8(ced9ca9c,04eb27e3,bad5b6ea,ff4020ff,f35a00a5,22701f7a,71725988,2617eb1a) Z8(ce6c94d7,fcb7e576,38d9fb31,a0973b5f,a6b643a9,0a8fad22,8ce60f57,41e0f9f5) Z8(08e7e4ef,4de85f7e,037e69ed,2443f8df,3f68496b,26d893b4,8afb0cb4,e51b182b) Z8(d6868f17,f413ab7f,9a465144,e5e268db,9896a976,8c45fcb7,4d2f1a6f,75135af1) Z8(2e1eab5b,7178bd61,dd20c588,4fcef5ba,e210c351,ee8c76cb,15793d0c,ec23299b) Z8(146d91cb,2bf15a03,cb74ca34,27dbc5bf,8bfb991e,dc222529,91e65de6,cf13a59e) Z8(f4dafa29,bcbeecb0,7eeed60d,2745ef1c,a0325d23,6e3e16ba,f2a6c9df,ea72b0cd) Z8(e551aed6,db88d709,b01ff673,b7b2724f,b493371c,90e45a8a,2a87d6c0,911a5951) Z8(6c3b5453,b7fd2ccb,8efaf860,d88c832c,d506bf79,8b131c97,8e56c8a0,befe194a) Z8(6e628ad3,e59020aa,8fd62e08,2cea55d5,928831b4,9c6134d5,b3d7a107,89e381ab) Z8(610b35b0,552af8ad,2b57aacd,cdbb911b,6b6101bd,86972773,031aa1c3,c0038604) Z8(671e46ad,628b811f,c9e0bc66,09d56cdc,7362cf83,af2451c8,1d888668,08347285) Z8(5fad1279,f8168863,a6455464,99551309,9a4f1ce2,11cbf2aa,31884fcf,bf94411b) Z8(f9407695,328e877d,254cf631,7cfae701,3c119069,9dba7202,7196b8d2,d90885dd) Z8(27e3043c,c79bc297,a06f0f62,254b80cd,1f8a7202,11e16a63,6e178fda,0eb344df) Z8(cf093f01,a0bb2192,c1a15531,569f406a,8693e780,b6aa28f5,ed279834,d4d89405) Z8(5e23da36,e797ccea,ef3410cd,74683042,5a8d64f7,dbc693b8,887adce0,4b9d9384) Z8(37444bb0,c1861c99,f0acc618,d277a212,c0529d15,e816fd98,2083af71,d2fce3ba) Z8(044e7e7c,a3b027fc,8bfd1670,ccbc2ee4,6c77ce45,19890f16,9c3766a0,d57747e2) Z8(b8e49b25,76247f82,cdcff962,28088802,c0fa5aa5,13e42a03,a250e54a,a4d59b5d) Z8(b1d38d77,26d2a612,40a48ec3,933e162b,4ad0bea9,67676e00,4c462745,03006c98) Z8(84f3663d,f784222e,a92f2431,7a369efb,cbc0636d,1996a4c7,d9a47887,a517cf18) Z8(4c7af17f,808c7f64,aa5fa14c,d7d01850,ceebfcf4,58e3717a,f34f00ca,11270d43) Z8(c226f4ce,74bc96e5,ab20d76b,0d278922,e4ca0879,6a112cd3,fcbab1d5,79976359) Z8(36d255ef,ab39b1ce,c75daccb,f230436a,d6d36831,43722ddb,453e3fe1,e3c90d84) Z8(cd29b207,e805dc7d,83a0bf69,202b2fac,ceca1988,feb0bc08,64dda8eb,b6796801) Z8(b171ef24,459a01a4,b2f922ad,4c7ad50f,8fbcd4a6,777212b6,5cae0f2e,69bb9cd5) Z8(67c8a88d,198fc0f4,36570e78,6f171f64,d71c0a30,4d2c8515,cc60ab38,fd2f9877) Z8(cc10fec3,13eecb4a,af8ed210,382a32de,2748a46d,1a87bab9,b341f987,d9954d0b) Z8(8bb0c828,c5f12fe8,d3c67bb4,e57e7395,ae786d8e,76f5a99d,52a10f04,16d96149) Z8(08a061ac,47d44b83,1a51b785,d964298e,0504be82,2cc2cb2e,17a9eab0,22a482fe) Z8(b0fa8008,898c527e,4324ecbe,908291cc,3a89d5c3,fff21a21,fdc057f9,79ff6720) Z8(1e5b25e8,87602c68,955c6cc1,58733cd8,0769ad3f,e7e920de,4f83dd49,f717cd3c) Z8(f0902d79,4ffcbd3f,09c6a089,12dc12ed,c3c1063b,4c8aad29,c09fbad3,7ad4fde6) Z8(c91023ea,aa285feb,d7dd6467,201a06e9,2a06fd24,889802e6,d30166ee,dee6048a) Z8(01f89035,a7daa758,0b371211,474bb586,e6f987dd,3b9a914d,1721e96f,6627a798) Z8(fbc3812c,f29d1319,cb6d16c7,6d3272b6,15c7d715,78fa0a4f,6707aa46,1a0fd266) Z8(7ed2c204,6a8d44ff,083f8563,82fb46d6,8f2cab99,077b706b,6248714c,8e6d80c7) Z8(262a1d9d,2db98b0a,1c79b792,c451a151,b3195ca0,76467ef3,66eecbd9,a5c66f27) Z8(a34398df,61fac6d5,4dff5419,d622c939,c3db45fe,b9b3f051,80356c2f,223fec13) Z8(aa411163,d57d7db2,78367aff,520d96b8,ac123857,8df6ad66,69996ecf,ebb227ca) Z8(47158733,7d1473d0,8dcf4c31,1178fc31,d30105d9,966c7a59,31cab3d6,2808484d) Z8(94dadfc3,ca03caec,4f0d9899,f262032c,66a80bec,e93ec759,be1d08a6,2f686d09) Z8(930a25c1,efc6cc9c,133c1d01,adba45f5,7ae22e37,49773382,b7037632,abb16f03) Z8(1b09d5fe,9fd54b43,30739d64,ed61ab55,8aa8635c,e3efaf02,fa6ca516,53f465d2) Z8(a1ebd856,ab5439ff,487db5ba,6d69c679,ad9495ee,d0141459,e924758e,c9c7232d) Z8(ab987f7e,ed751648,4825452d,5c728756,f81e7dc0,7c89b1ed,99f9987c,54f35104) Z8(c13e6740,eacccdba,ce3533f7,16894321,4ca26ccb,2a3c868e,98d3406d,e3eecda1) Z8(d3e61919,daa99a22,e15f3178,7adbc2ee,5df8715b,f82aa212,21e57fef,515fbde6) Z8(51d61bd2,6581a14a,23520a97,88566024,6e625b1f,b090b33d,36490dcb,17fbab08) Z8(b9e38bf5,0a22026c,626148e4,5b45a394,17d30867,e77f932c,50d5d277,eec20a4e) Z8(f56cd72d,6290c332,28f02100,602ea9c1,c98d9a12,e7f816f4,f3dfa6f0,9983b1fe) Z8(397e20a9,a9face81,35bf6508,301a9f0c,30da21ee,97ee751a,c2255a92,302ce07c) Z8(574ba65b,1712b487,61404a2f,1cce5007,aa1bb6da,a8243ef7,aac8e8b9,88734b40) Z8(720d721e,8cd086df,32486ada,d0faba63,17cdfae0,7864457d,5386bb98,64d8ad73) Z8(effe2d44,a70a4e04,c180ea9f,0786ff3b,ed29af0b,20c7d9e6,1f226342,c69b21f6) Z8(7c5cd7ad,2c0641da,0f9961c6,bab8c081,f9a21ea2,dffeda26,f6379310,26d0f1af) Z8(6fbef26c,892aace0,230a56d8,8da528dd,47798c73,154f7754,f2ee88e7,ba98a9c2) Z8(aa7ea837,da919a86,3b87aa85,c82579fe,38b91fab,94e3e43c,f42b5924,045b26bd) Z8(5a8ddffd,7b076f46,8624b69e,bb1688ca,bb84aad1,826ba890,0dff15f1,e81fc192) Z8(c164ea12,f34fb3a8,6e81ff06,defec575,3ac4a1f8,4cde6f82,8fa9e5ce,01ec1b11) Z8(cf9bf99e,213ced49,c4118115,cd8f3dbb,d90fba0c,7dda0911,d0812a38,52ac24da) Z8(811c3e04,095eab7c,f12199ef,3399ca34,7a0daaf0,75987d8b,0ab43839,900aa6d6) Z8(e18cea66,8329cc91,dfbef02f,e59aa0db,942e7554,332eda9a,0b6dd799,be01e806) Z8(07e082b9,7cc0550b,58dafab0,7ba69b5d,ea0cb108,f4496de7,3ab80504,f155ae39) Z8(0c2625cf,d11d0e01,d804b39b,4abbc7fe,c7e2952c,bbca70fa,9f6e7272,d6143d83) Z8(fa76936e,00bacf3c,6be2faae,039d9e82,5fcf40f6,fe4fa437,45c280c8,21175726) Z8(e6139128,f7c27583,681d1d98,f89ec99e,560b7a7b,f86faff5,f4636074,352b40a6) Z8(6d24e2f3,791d0baf,2312bae4,d8fe656d,089bad10,1be68196,717eaa22,755622ed) Z8(a1e29ce9,19fa4ef7,f07cdb49,120e937b,e1cf5767,e0b85703,bf66ea3d,e567d89c) Z8(c746c4f5,468cec20,c37fe1af,248dd683,3e61f62c,edfd78c5,41b2a815,68d5e5db) Z8(e75cb285,2cffeabc,7218455b,29a3b105,7f82a34f,148e4c17,3a58143f,548151ee) Z8(a5013826,1cd47535,8a83486b,8d3691c4,4f284c8b,ed60aae7,4627fdc3,dc7a3256) Z8(ec8c4f95,e4dd454d,17fa7f70,683800eb,6008d264,622d3105,ac4ee246,52297f66) Z8(ff977801,9c19e5ae,96f69800,03e84d66,43fde5b8,da324265,6798a2bf,5e96f93c) Z8(5f1b54b1,e6e36a69,17d30baa,23db82f3,0847720f,fa088cba,6280fcf9,213632fe) Z8(22af392e,98bb85ea,096a9ebe,d7444bed,d025dd23,01bd11d8,337c0e88,dfc1125f) Z8(fda70f6d,2bc4fca6,b8d0bf84,c7296894,43d17eb9,c4949220,e0895063,f6a8a0ee) Z8(483582e2,7e544a8b,15a232db,c36e3cda,98a6a38c,5991dfef,eb5b5743,fc68e012) Z8(7c908853,222142a6,18bf0a20,a04118b4,51611479,f3178440,0be348a1,0c9251fc) Z8(5ff1ee18,69dcaa6c,a8b11991,d5c6b9af,5cee51c8,10bcb274,09a6fd50,8824a730) Z8(fd24e89b,b11d3f5f,0f7e22ac,ae4fdf8e,6c7f812f,4c26a8e7,b2c73fe5,b0c57e36) Z8(dee53acc,0bc68250,2baaa8cc,0208f2bc,add666bd,d19b99f3,8480fa2e,462bf5c5) Z8(cc4ba397,2cd30f71,0ebcde52,fb3c816c,c4aec712,6550484c,7afed51a,2dc76549) Z8(f0a69683,6a4937df,bba6afa1,52498901,5c359819,82da8b95,395780e7,529ee403) Z8(9b8ac2ff,6ae9b114,5db249bc,e1079b43,12914f36,c07d10eb,2b727a8b,ec0f21d0) Z8(cbc6806f,bb8ca632,652fc8e0,fc5b4419,9d9894b8,5f09621b,83dbb96c,ecc88148) Z8(0a42e62a,5ca4e88a,59f61e67,c7dfd92a,2a0c4dbd,c1102ef3,5a894430,d132f24d) Z8(e3d2282e,627b99ac,d5ec687a,167807f2,177ada19,a5ae9429,32b0a9ba,27cb42cc) Z8(df2512fc,1d0068fb,71d8fa44,58abd59e,ccf8b086,5b066a5d,d946e01f,36c12df7) Z8(38ce18d1,ddd3e72e,ad0c64eb,65a46a7d,42e75cd0,68fa3913,1e96bac4,e373577c) Z8(fb6d60fe,0d3617cc,73446759,9ba5464d,bdd2121c,8906a162,d2bb2ffa,e3158284) Z8(16b2e4d4,53e11093,986d9999,c39f8c3c,f8fe1051,b37a3216,b73c960c,5a162266) Z8(560b4dc5,2c67d626,de9f1fc4,1b47f91d,64662bd2,45d9126d,cce5d5a6,d20262ec) Z8(218546a6,d3441175,3e7ecb2c,c16aea72,842d981e,9d6df2dd,f3609795,b046fb53) Z8(63d7de6f,21656038,8ce6790f,faef4ec3,0ec6c005,4f927376,8275e1b4,84b69493) Z8(0e4599c8,3100712f,36b72595,2ae07542,a28d4175,bb60cc7c,99d54908,f581db18) Z8(74184a4e,5e0860e5,0d4c7359,886b6310,1722075d,bf3c761c,4c60b61a,e6817706) Z8(8d22327a,72c102c1,3c2e1eba,92308a59,15fc88e6,be1e4359,3a7793eb,652f9081) Z8(a78438c3,3b3fd53d,b339755e,e8972046,b112f4b9,45741d97,9884f109,8842c4e7) Z8(993bd03a,ad701555,fb2c2202,e43f8385,c4941d2c,2b40e53e,f0f3bb4b,29875053) Z8(7c9d429d,b16b5916,9a6e4405,55aebe93,9d5f9d1f,c65a8327,7739173a,029e1a56) Z8(2fdf6144,9d66a736,8bd6f7de,c51e4b9e,f25770d5,5e798c7b,9be37040,915771f8) Z8(f482f33a,9ea1dd8f,db061a3a,7bd85d80,39d158db,12cbf015,265afbd6,da532bf0) Z8(54c454d2,97b92d81,e0c2ed3c,a105c8ce,00d1e82b,8723064e,10ec5bec,7a1b1e81) Z8(77c9dc89,e8a1ffa0,f6209708,012ad82b,af1ccb05,c9e051cf,2fc59a3b,cc8fcb02) Z8(c34779d7,d944e91e,4933f1b9,e0111c6c,0cdd1f96,d29758f7,9c2d893e,6f7b69bb) Z8(f1ee0c03,7e52e2bd,4dd397b8,731d977a,d58f1b3f,1c6fda4f,0e80a4b7,13eef8d8) Z8(6df4bcee,9ac41d15,d0f0ae16,4684c484,2baf731d,a11b1052,e0766414,dd180b1c) Z8(fe596ac7,077e0cc2,c789b6c7,aeeeddc4,3ea2686a,7a4585f6,92901bc4,038c1ca5) Z8(f321f50b,617d2442,3dc4b55a,3bec6279,41261935,24b3ccd2,1784f71d,3fe55064) Z8(6cf2fe99,9bf10249,b0173236,a7d623f1,4e27bf7b,3423bbe7,3621c63a,2ee4510c) Z8(ab573c0a,9c7b4f14,818c3028,32783458,fe54540b,9b9021d7,99705f44,c41ad29c) Z8(8a1f7c63,12a46625,2f4232d0,d389de5e,1f20fe7d,77dd21fc,bdcde05b,3a314ad1) Z8(f3f530a1,b9d08324,f7792abd,321bbd00,6c33f585,614c9885,291ca1b3,4b417ec1) Z8(d20a52ee,fe5f89fe,bcd96a7f,2b4a68b5,0a4dae89,eaf3c271,0cd608a1,ab767b50) Z8(f6d60f25,ce5a9f5b,c2642828,fda286d9,834fd0bd,4ee61392,a1b562b9,c1a4a877) Z8(f3797a18,27594946,1d260118,e5530ffb,c3eaa4e7,0e9a464f,22d3faa4,0a027085) Z8(0dbff58c,6b33725a,0801785a,4375683f,3dab76f5,8030259a,f4962146,57daf2c8) Z8(0ce15496,d76c5170,eff02254,e71e9747,c63c4ea5,9945c480,a457c807,5e0d3acd) Z8(e91e0b09,21ff1152,11fefaa9,a0e4dac5,88dc59e9,16d6ff7e,7b0f6d11,973c0441) Z8(50b11b9d,3e786ba8,94f407d6,5970f160,dc09f55f,3a437dac,b65cf062,2ded035f) Z8(e7bdbe63,d04a051a,81a1fc7a,03b42683,a08c6123,fca18bcd,0e1162f3,9d2810a9) Z8(08401a08,2c7a466b,fd1ca7bf,c7ca31ac,7f78b496,6b52e539,e69f5066,3e09fa01) Z8(d9da9945,5a26e38d,3685db3e,345731f4,2236f2c9,a5adace8,8de7858b,e6adef08) Z8(df5bcae0,28826dd5,290f1e6a,8ab7e8f5,1844d775,4931b4b6,98375d01,6589338e) Z8(29701874,b7dc826e,d094b2f2,969539f4,732f031a,4a066680,ab67eeb6,19a9fe8c) Z8(9a146fdd,1c73c423,022e62c1,5f076cef,a5cad330,fbcaaac4,a0c25b1b,135a6266) Z8(674094f0,4674a4ee,72a9ec3b,de017f93,74acf836,882ded2b,5302ed27,6ef0824c) Z8(69e744d1,e5a15552,3787e4d1,f87c480e,dcda61fb,f84cf908,585d1cac,e4705674) Z8(d520a977,047d7758,3e2adfb9,051ef955,e3bb7119,5a1ee996,8650a21e,9c9f9947) Z8(61c3df9d,b039a942,dfe25505,4b671736,344cefbe,7c15621e,b9f61ac3,5797fad8) Z8(217fcd3e,8177b05a,1abc7629,ef34f8f6,ac1346d3,61e5487b,41e8293c,ba79b96d) Z8(1fc33113,515dcfdd,c7789198,c090c0d9,b0ffeb04,2fed368b,389e3c64,263a4561) Z8(a79d7e98,85177e23,b7319177,111d9420,f41f9c30,d810f002,6d473ee9,63287910) Z8(f6cad06e,b31b80fc,3be4a06b,a2d7c20a,891acab2,b1087c04,00c9f584,bfbd79c2) Z8(f08a7089,aaa07c19,9a8ba0ed,0a6bf0fa,61b5378d,27e0ee18,64139abc,fbcdf9af) Z8(ed1ef64d,a138da4d,53ea0ea6,9514e5ac,6462d7b0,16bb4f18,aa6cf379,6001f094) Z8(6f869913,54eb1b15,1ce290a1,4892a4d8,0829d362,196a5744,245f8b16,7c4f1cc0) Z8(bda5c16d,ede58784,71321c47,a48e4ae7,f9af92f6,f245fe07,f6f53064,5086eb7b) Z8(84331ea7,c6e4e1b2,a08713a7,71157e2e,1519ce0a,e7776cee,3daed979,e08f65f8) Z8(46058801,04d305d3,307ffefd,707333a6,f776a651,4f9a3027,f36184a8,a5be4582) Z8(97b3c6d2,71e10ca6,49452f20,7039c248,2e188eef,a96e953b,5ec706cb,e5901d22) Z8(2e79104d,7e15588e,66843d03,9e306e89,11ab5412,69e967b4,8c815a09,fc1abed2) Z8(eb80c88d,10c2e53d,d5ef1431,c37d1da4,d24cb669,079a0a54,18839075,a9588308) Z8(26263fda,fd633a0f,7fe321cf,b0081acc,9da0c3dc,f9478964,fbdb5c59,d670daf9) Z8(76a3419b,04caa3ed,3bcae8b1,e6246c16,e118bcf9,bb836d61,b3d23fa3,bd544f41) Z8(f97f7c0d,a8aa7634,70c572ad,53472c5d,1655f293,1c2d8384,710025d5,802fb335) Z8(8533131c,73f7be7b,3f193ecb,a94830a2,d548173f,4bcf735b,6e9d0433,79f1f8e0) Z8(c1e7293d,68b8fefb,d83b39cd,ce0b4087,5be6cce1,a66866a7,b44ab155,af10a21d) Z8(a8018e18,ba3b13e1,163967cf,9b920be0,887efb09,a341faf8,cc0a789e,72a6fa36) Z8(543382a7,e72da19e,9ff9db2d,8d8dbb06,4fe6b95e,ba57a10b,e1ada9e8,10d3f8a4) Z8(0f00847c,477cdf38,c997a160,6492c252,aab46b5e,5cd89aa3,17234a4c,1592149e) Z8(e41d5b2f,8d0ec53e,f07c80bf,d336ffe1,56825f91,77bcd105,99380bdc,83ac8460) Z8(691c22d5,1a165108,8dbe1121,267549f7,8e1e0813,b5ca7548,8f2192b3,f2a81992) Z8(3117dbea,4f78dc66,bb85c626,2577b781,a4020ef5,80d64655,a716d23b,eb8c4132) Z8(d1884877,0ebf0393,4268d350,c657878d,212fe5ba,a08cb6d3,ffdb08cb,d00046f9) Z8(50a14b65,d4e685af,1ed971ef,e88ba4bc,8d904ae0,dd4ccb6d,b6c917d0,e37db276) Z8(ed2dd9fb,97e72c1e,77073528,3ccb77e5,1113f809,cf461cb7,17780b54,984766b3) Z8(bd202b25,ab09031d,e00b82e6,39f78913,16afb9f1,b2b2f38c,d955c760,47b9b920) Z8(3b63ea4f,435a5850,aa48a450,570766a7,3079fd9c,56c6e691,c43a3449,fd8dcd5e) Z8(caf4f624,6352b492,415625f7,12652840,0a399b9d,3b313445,748cda99,4c22b501) Z8(fc165947,e0ac4c2a,0a814318,6cb071d8,b4eab9bb,59508e75,2706cf8b,29235d81) Z8(6ae48585,814c0eb8,8644091d,49a7ffde,e1e83260,910b25b9,8cd18eca,34a6fd1f) Z8(3e2acbde,d12f448c,5a1045e9,46e85107,c9e74687,79ce1f20,a4027ef3,4ae94ac6) Z8(7521ace2,811c9269,a43553cc,25e5f94a,9aab05ac,6127a4be,d91c3712,d846ad50) Z8(de27e1d3,50b75b56,95cd8f8e,a1455a3e,85dc59d1,1b9f400a,d9071038,233d2233) Z8(cd6935d6,26545305,cb505560,05628416,b77da63c,110603bb,bbddfc9f,6a90502c) Z8(bb2e13a2,2c6dbff5,35c2bb1d,f0a94c51,3fffbe4a,21abe592,c0cd0a10,bf23dc2c) Z8(f55fbfcc,6318d89c,b8a98eb5,c667969a,c70b40f8,87118cc4,9ce0b142,c161bcd9) Z8(38ef5847,4448f8e9,255ddd22,c557e548,39a42e74,6f11874b,d7e3cef9,4d430132) Z8(afb426c9,34a0efbe,70fbf983,716b2a7c,3bd3ca15,56463faa,bc285e11,191e739a) Z8(76f4506d,7c1ec286,f356151f,82a85854,40536370,f2a0c0c1,4aba38b7,6980e9e8) Z8(117cc462,7be89bf0,edafb40c,aa2ac99a,5530a649,6d751302,9fec52c3,b5fe6ec8) Z8(37c8f4c6,42f074fd,e489d229,8e1944ae,a0a8fe86,12c9b6c1,717d0afc,539941ba) Z8(020043dc,49b30b5a,6ce30c9b,7c130719,85a92717,4d49d6c2,27093567,e5161ffe) Z8(2a88d168,be7e4e5e,127166f9,c43fc883,5ee37d6d,b9023d51,a8e5c36c,94d4bc6d) Z8(72d07160,95c03676,b933260e,89a5d419,5d51836c,167f2ba9,d7f8fc05,5324cf2a) Z8(0fa8ba41,12a91d21,14130044,8f28b23d,6a9089cb,e5b16f5c,71d83c31,4ae0a2bc) Z8(fe4a5bc1,f82d16f3,bf15911d,05bf7242,88eaef29,f0add78a,e5e9b9a3,1bcd9fae) Z8(4f20e3f8,31b011f2,8af87a6e,e2b7edd7,b1327726,2e6c320a,1279d8f9,e1594656) Z8(da293ac3,4609c318,d38d3625,def60e69,8181429e,35abd232,549afecb,8a6d41b4) Z8(a74149f2,bdfce6b8,8ee699b7,d784853b,6abbb060,1208d521,332d9907,b68870ec) Z8(e1482016,0dcde3d7,abfd968c,57979e11,dab5f990,895419fd,7f65df8a,a136c1a5) Z8(fe018a6e,aa687dee,76ff4d37,761cf1d2,76306ae6,e214f89c,84108f78,6aa0cbbd) Z8(a5706346,b28f9d14,2e5cf9a4,525f8902,ee8f57d4,bec873ad,30384b78,c93ae472) Z8(5d51f2a9,cce8ce56,8673894a,c98b2f98,e1bbbffd,8529ab1b,87de7613,e0ed4987) Z8(44d9ea90,1d1a7c25,67c52cdd,3911138d,1d003f3b,22cf6bb9,be499a67,a9a7ba99) Z8(3407f126,9e73cdf1,13177818,4c76b2cd,28315356,149e907a,b8aedeb7,0d4076f2) Z8(df61066d,7b06a5bf,87723a80,edee59a4,e2fb6e5e,eba0c445,c7bb6c7e,a9a667eb) Z8(e4244ea0,02f24910,a0f6036b,866dfac7,b10d8c96,88ccc137,b435b3cb,da1ba43a) Z8(141ddcfb,1b624a65,6222fe58,c0344625,6eddf2aa,743aa936,9dcc56b1,db0f47e7) Z8(b32655b0,fa3862cf,7b011e4f,2e261666,6eb85a17,43a4ce4a,be5421c9,4d85effc) Z8(a15ff84a,822bd87a,fdbdecd9,7162b044,02baf45f,a4884e7a,a04669ce,6c434d94) Z8(de6e1cf0,51de6191,4e1c72da,9cdb9887,f1ca58a6,e448a57c,3d620663,aaa83be1) Z8(43cc2fe1,40d0ea99,013fd238,069de9cc,f2e83a89,535907e0,586f6fa9,b5f90198) Z8(53b8beb0,2552e103,acfff366,ef717787,80462b8e,47416b22,40c8675f,46614808) Z8(7e3c98bf,6773b560,399020dd,e5056b9d,35d1dcff,2fa62ab8,53298854,99134ac3) Z8(ee668421,089fa296,17be0e30,41395bf1,56e98e53,2a8b9a4e,08680c16,230245ca) Z8(caec42af,57a5955a,4a317925,e42f898a,3cbfae47,4a4fae2a,a90a4269,9ba3b67d) Z8(791d58f0,7f59e538,c2789d6a,4070c77c,aa948ffb,256df53c,795c5133,e6c22248) Z8(53fb3ad8,016b8189,b08bd9bd,907e9d7b,f5d5a370,4b50af36,d35b6627,f16389b4) Z8(5aa4383d,af379425,404cd677,80a5b242,57e8988b,5a721895,37de7292,79eb6760) Z8(ad2f1196,1ba7de7a,a9cf354f,2594a260,6dd73dd1,b6da7d55,61b6933e,f67dc569) Z8(7744c7fb,ea3e93dc,7c2e9c88,5fa34eba,22b543f2,72458ccf,aee57ff4,6e8f75ea) Z8(41b46150,e8ae1768,69ea7467,6a49aebe,0828f2c9,3c658566,d76f9feb,22ca586a) Z8(266d2a22,73e51576,554ff29e,0690d264,5b0dfe81,b14ce557,a0f49051,b7e2fc91) Z8(ed5c8b43,71a618b9,fa4d7ed3,b418dd16,8faffb60,c010ce4a,20244474,c7f84e60) Z8(e7742d52,f605217a,ad1b67ac,e0c23c5f,6be426e8,b2e240c2,636fad7a,6158c8a0) Z8(c4fefdf0,57c30c5e,be4d08d4,3bbe2cb8,6cfb75ca,2cfc0cac,926add00,3805f10e) Z8(813ee7c9,0b3fac5d,6518a8a5,260daed8,c495f840,59bad400,6f76ebf3,fd29d22a) Z8(1187585f,2b28904f,0a376f26,2ebfacda,295b5c3a,63440b9b,c233ff69,5c8fac0c) Z8(375fee3c,cc6e8b8b,0c2ba223,f88b39c5,08647914,c9042699,258eef1c,90ae2414) Z8(7a2a9a6e,77030f2d,641d3748,a3dd9d9a,a0170b2f,6df1ff4b,64e440bc,12cb1997) Z8(6ed0b258,ec2d524f,5439cf9f,f0c99fb8,e2dd2ec2,39c1ea25,9ee8b0f0,680b0c0d) Z8(c660f792,943b0688,6f312529,80f1c8b0,db7f52f0,d1c832e6,d79fadee,469f6aed) Z8(5cbbd14d,f5565ee4,82fdece3,de65a828,6ff706f1,f68042be,2ecdc6e4,eeb79f0b) Z8(ea202155,5a50ff0d,e76f79bb,e04ee07e,b38c35c1,03d0d0d9,97edb2c4,c9ef5324) Z8(2a558477,bb4797d6,c22e28b1,b4f2d8cf,91acfe48,e18dcf87,e7d8648c,29243f5c) Z8(7682bb54,6328e8bd,010d685d,4285b74a,46b66797,788e4186,7781ea84,bcc6c1ac) Z8(96f7b431,c815cca8,482d2e98,d96dc540,5321cf31,792dd00a,aa0ff60b,ee90a2de) Z8(d0f32a40,08c297a8,48ca550c,48e323b2,6a89ee91,67e5aa12,4861bf8f,cff7513f) Z8(048a7fcb,770399c5,e7b522d2,427b7cec,a964e634,d888c265,551d1ecf,440fcf9d) Z8(ca731c92,822d639a,73433643,fa274f2a,0be7a07c,57d64d65,01d4c745,813ee404) Z8(fae17aff,e07d01e7,47f4318c,b1b90983,10410001,54401330,1cd1de52,45800d25) Z8(04d85feb,baf4db47,524e45a2,ad7bca98,e2d8a7ef,09a30e01,b206702a,503ee857) Z8(1c64036a,00977a93,ba0e0c30,59a86628,c926fe7e,001569bc,6c61dd0d,b440da7b) Z8(68c3c3bd,8bdab9c4,70a75e65,7c395874,9c05d288,4754fb10,9a4982ce,7c80862c) Z8(4a0770f9,f55bb59d,d3cad0d9,a8b8b4ef,f548fcd5,042f675f,2ccdba65,538c35c1) Z8(f3831e55,9a437fb9,fb25cc63,2985459f,6c5d9414,9a9e8192,d6fd77a7,1b1fd16b) Z8(abcdfb7a,831c8ff0,b5426fdc,ce4e9d02,cf859981,ea3697c2,2021c351,3bb716eb) Z8(4ef697a2,d20fa3cc,f3c94bf6,0952122b,40cc689c,16191c78,74cd3fda,fe001609) Z8(7935bb6f,b77fb5d9,07d502e5,8cd5cb42,2de9c18d,2c4c0d88,39346711,7db21376) Z8(427e80b1,ae328467,8fbdadd7,13deda93,4386788c,0250ac36,08ce7557,e005cc58) Z8(33006ba1,9ba11893,b22a6bf3,b6364aec,c311fa6f,f3414520,781912d1,d61a0b75) Z8(a98ed7a4,333b9a36,f2cea1fa,1379eed1,e3d465a1,afb25e64,2fa3b1bd,823355ae) Z8(748e7e82,cedd2e4f,155b5014,caffa6af,cce078ef,b2ad4cf7,33a7ef35,ba4aae7f) Z8(41c7ccf7,10a5973e,869828d6,78fd3370,e216dfd9,d7443783,7f3635e8,82044fea) Z8(422739b8,b0c0b7d3,c16ffa27,f6854e77,48d72a89,8c1a54ac,149816da,2b98d2ff) Z8(ad95b90b,41e945f1,5c33d277,d1b48aa1,b0862a95,04de73fd,563bb610,7fcc6044) Z8(96d5f0f8,84667dd3,847dbb8a,1e81c942,db76233b,f6bd319f,18ad1c64,f7d30fb3) Z8(b870766c,009d08dc,690e04b2,d3ba0eac,f648cab8,7836c8c5,2be2cbf6,a7c60b65) Z8(8d65ac02,01da00e3,d7c66c15,1f121d20,a89a5937,19bfaa9a,0866514f,b8c6cc7b) Z8(22b45632,6cb6f256,1736a34b,167c0776,2ad8c7c9,599acf06,e7238ce2,877aca0d) Z8(c415de32,198d6cc5,2d7263c3,b040144a,6f18606a,730560cc,19170952,4bda528f) Z8(5cceb92b,1761ea50,b55fa777,8ae6aaff,341bc125,5ef0a593,20921a9e,b8aa9504) Z8(c0531781,4d0896a0,df9fbc8f,7fb070f5,2e3bb085,6ad7bb36,2796a186,8047e1bd) Z8(92d66aab,10a8d0bc,aa091b18,28ef8002,496befaf,37ef27c4,35c27f3a,ac506873) Z8(c11b6772,c9b7d0f7,e84b9418,7e07493c,83887c4f,38826985,42842463,aedb2047) Z8(2bda874d,d59c8933,9acd3af4,bb3393a4,97fa4fb9,61415c31,c011d296,0e58d04d) Z8(43b9699b,f54459bb,ce7e9dd9,066e9faa,0a7d2429,f7d428b8,11d04f43,6daad4a4) Z8(598cdae7,11dc349b,d4a79046,69f9216d,bd29a456,b00044e5,9fc46399,507b5545) Z8(731dd1d1,38982526,2f6d297f,682a2642,1f00a584,405a5457,822312c5,c7acd1d5) Z8(d5b01ce3,39d38fa3,223250a5,f0ca7fbd,48dafecc,8376f1c6,a791c344,200e7152) Z8(f3c3ac58,a8cdaa10,03abef50,0afa4378,34a30f4e,5c8324e3,18dfcfe5,89714ca9) Z8(dee7fcbe,09817e5b,8dd236c8,69c99f3b,790ef06b,d87de194,8fc1d483,91396a68) Z8(66fae68a,5c83f529,7bfb3cf5,59a07c27,58e589bb,aa3ff8aa,969c4c2f,00fa0238) Z8(e00b3d1c,e17dfa88,77520d83,249cbc4e,ec9e44c1,369dcf16,47a18c76,c1697864) Z8(2d3ba74e,9ec0604c,dbae22e5,2b36bcb5,de34d65a,ec04ba63,b6ff9b88,851c4df1) Z8(f77c3c5e,96f0b55e,2ea90eaf,b0888ade,c46ec328,9b87ce73,23c489a6,0b0daf28) Z8(90b762ed,b93b9333,10a9bd0e,0dc08a91,6bfbcab2,a1064e97,ec9f4aec,0f1af0ff) Z8(a0c546b2,fb89448e,a6991627,44fd03a3,e2a538fb,a51b4f90,ac77c521,18d2ac72) Z8(2df88bb8,af617ed0,f9874556,f4314eac,00374f52,f25a1100,3ddcf5c7,75c90330) Z8(7cd9f8fb,86758dc4,116db27e,2975a373,5ae164e5,84bfa9fd,f6f7d242,0b71aa0a) Z8(45b52047,df8dd472,fcbe1260,6639f9c9,5067e0d5,ea0d5ec0,3fceb47c,cc52b7bd) Z8(9db9298a,583fbcfb,2fa80754,66f574f5,f4743d4b,0ac85039,a54bf5e1,721fd6ee) Z8(808893c6,2f767a2f,99af253e,7c50025e,0b28e49c,fcdccffe,48a97769,7bbf6268) Z8(cd8a3751,5e6346dd,6358793d,88a7e60d,ed180863,572ba2a9,00baa7e2,6db82c66) Z8(b8cb9749,d9a4bc49,d4906ef3,b04672aa,f9275db2,9ea72170,e83eb5e6,895554b6) Z8(a8befffd,22501925,370f945f,1846358e,ebc4e382,03b5aa8c,e0106774,2bc539fd) Z8(630d3888,4fd63433,fc615ce6,6e9361bd,dd8d0583,759be3b9,26f734c6,a65e0092) Z8(b26afcba,68417945,a7e70110,a74fab83,9e731d7f,0b72f549,f4d43bfa,cda64ddc) Z8(7c90bd24,c8cb940e,bba180dd,6295c497,660663dd,a8356887,87f86b73,17cba26b) Z8(041fc681,6e7acff0,ac773e7d,bb9fa0af,a60657a5,a6b75b61,a64ccc6f,b40bc174) Z8(2d6db811,c65cece4,33031f42,ccd68348,e01ccf07,e94f3ff6,b10bb018,5d57dc6f) Z8(23fe1134,ec55176c,9b8e1ab8,3d695069,726b7d3d,7f42b509,f4d35e4b,2376676b) Z8(411ddaed,f3fd1099,d8d01652,024f9894,c93be0fa,80f7bc4b,aab3efcb,42c47d3e) Z8(bd23daf2,8291b463,251309f4,987fb636,f710a9f7,78cd954c,d861f553,bddccad9) Z8(0dce5e35,a6d8430c,46385ee2,2540555d,456f1545,829a3080,5c30b85c,2348036b) Z8(a338eeb9,7fc1ddb9,0b1a258e,ccf57673,748c4cc8,83245191,1b682ac8,c720d96e) Z8(7e3c9463,bee86e8f,d6e10fff,63dbb030,895af1e9,96935c99,ed1cbcba,b1f648d4) Z8(8bfacf0f,60841f72,3b5f012c,2a50c0da,02166cca,0dff2d4a,f0e05f74,761c0f35) Z8(bef1d8bd,3f0319e3,479e1ee9,589a9862,ae09a958,1ef8126d,3f179d75,4eb6c16a) Z8(f0ae9759,0812515e,016bf128,1e866a4a,3c22d920,8947a031,58ba9c23,77e0d92a) Z8(b390f6f5,ef105868,74925c84,81ce322b,95eb1f52,d78f0be4,10eab1f9,0d9a50ab) Z8(34a12c9f,c2af4637,e9ac5cba,f9370af2,cd745f43,31479640,f434914e,3b66e8a9) Z8(37dc6feb,6c62efbc,2cab26cc,b9fe2898,10acbfb6,cff85243,897a29fd,cadd1e67) Z8(5a370222,03adb8c2,875b515d,43a7152d,1245ad0f,b6f65339,34698d3d,7aef7ec7) Z8(4f27104f,1d6eac70,d426bbbf,004de056,e33233aa,50ff3d0a,2291a7da,bf05dde6) Z8(76b5c563,a10315dd,acc1535c,7e31895f,058b44ca,cdcf5ed9,509c4d44,6098137d) Z8(d5617c40,92edfd1a,af205b38,27b0c179,28ef28f5,b76bcdb7,4acd6984,e04296a8) Z8(973088e0,5fc56642,7ab2c2d5,fc3b2904,52af82e9,a2c83474,5c71e660,e9a7db39) Z8(34cdb37b,78f97dba,e2289c66,63461839,5d053fc5,8be0725b,91f59f6c,7f86a1e1) Z8(c14fe5ca,b3c65369,22518361,95738621,c10f0499,a448652b,a8afc11d,d16961d7) Z8(b66a5f70,19080a0a,405df19d,f46700d7,5146913d,0c2407dc,07e84ae2,71cad6d6) Z8(2c834886,b17ff548,b9e9010c,75236b77,f09ea8fd,d7232e6c,91ebcf54,67f37225) Z8(065ea348,b571fb2b,99f8bf98,187c3c31,f2ba231b,6f13f53a,c80de4dc,8b9bda5e) Z8(2945dd4f,30ae13c6,47489ce6,12e4dacd,f053af50,dd10d007,0a69be6d,ccc6d63d) Z8(0ec5ec45,be9f65b2,02884af0,dac83f4e,1ac17135,8e33693d,f3c440ea,978f89bd) Z8(234aca2f,88bbb2e4,81aa4b01,eb07404e,da18e223,9a325569,262a9101,c5e2c794) Z8(28dbe1e5,242ed9d5,3e78c92b,3a21937f,4b0d6090,5416843b,7b88cc6e,13b37e69) Z8(1dffad53,95d46a3b,7da51012,2c229f71,619570b6,68c31645,6fa2ca94,c4780abc) Z8(8a048ef0,a6b61f71,571de6c9,d4be5aa1,5121a905,51e0122a,7a5006c9,f2e0d180) Z8(69448794,2da0b277,33b4bba5,133663ff,c8363ad4,af156697,6d1f45bd,3dfd994e) Z8(37fc71f5,948c2718,8060eef3,d6659632,7dc1266d,68877117,788c3af6,d81cfe7d) Z8(fccad251,1e791950,a9f5813a,0e484841,68571e42,404bb3b1,dee73fed,fd98a747) Z8(82a8329e,8c0ddb66,a92b8504,9a4501a8,0fe33f3f,c4b8168e,d9cf0fa6,69f4147a) Z8(377638d8,7b843369,9e8b4144,d4aadf65,be713533,e7fe2251,30d27ceb,885fbdc3) Z8(da2e944d,bc8570e0,1a6308cb,e446f6b9,f3c9705a,dd20b0a7,92bd4926,c1b45017) Z8(6d0d3961,315d24d5,b23f6fd5,4ef220de,50819509,d9341b33,e75204f9,bcbd1db2) Z8(a8265d03,92dd04a2,2e8c9d10,5f5c32db,ed5dd915,8c76a00d,3fd3958b,995c3034) Z8(273c7f50,51e9d844,e230f662,c9012cb7,19a7dce4,9ed40b7e,77b3d98c,7125dff1) Z8(49294e74,99d65720,81bd80a8,b6edf984,cf463229,738e650c,40357374,097468b0) Z8(5479b2c9,f50494d4,a9a337f8,b51ef439,43f820ba,a1e16fdd,dcf08419,bc987732) Z8(0ba6e370,52f3816f,bd0c2c76,9a2a5c41,8bd6411f,fabe790e,036126db,41f0b956) Z8(1862feab,b5ed48bb,cb4ae90f,60488345,8c7f29a7,e67be464,03094180,9c04cae8) Z8(c42627c6,8881662b,6c093098,d9dce969,9b8b8ea9,9840ee21,1e1ff856,79c8f543) Z8(e3c86592,3ddd1f12,6b99b854,f75e0403,750201b5,19549f7e,f0410f38,7a35a470) Z8(3fd2fe72,4f73ed16,7141754a,c28c15fc,0cc77608,df87b86d,071c068c,74264606) Z8(be8611d3,baf9df4f,6ee1b303,21d41194,d2c44836,6465b9f7,56fc23db,b6dcea6d) Z8(7b69c199,113bd6c7,12908219,e03b8e45,4552fef9,4e4bbb34,2081f51a,391a560c) Z8(e54aa52a,a6b6f679,f8e987f3,e58bc627,22c7e802,1ed7f111,7578b583,4e752531) Z8(8c448583,d13a8e71,3fa7e488,b89e7882,77227ec5,f25b17f7,b53e706c,8d2b38a7) Z8(1ac98f2d,e42443c0,91948924,c7d5c80d,1ef679db,0e09df7f,927cac5f,3baead6d) Z8(e082fe89,bcd2e3ba,c6cde42b,6e2fdd38,d39f1442,c195b375,d032990f,3163a79d) Z8(6f53b9e7,582e3015,cdfc029a,d76990df,96fb9107,839b9b8f,cfd31c0b,728fa373) Z8(352e12c0,b6de4201,8e2976e7,05c8f3c5,a92be1fb,946ede29,4a699659,55264d98) Z8(c5f7cc3a,4a61751a,fe0aa645,bce3c912,7af61dc8,f10638e3,dce0f4f4,5bc0dd9f) Z8(78bf2635,dcc0a319,044ed4c6,fc9ce7ff,13a62404,6f27fd24,ed2e33da,5ee6b90f) Z8(3b3ff878,8e7ce9b4,e3ce55cf,0d8644d3,2d9afb5d,58894603,d33a20f8,dbe1a874) Z8(f251fa9f,c030ef9c,71e213a0,3127c3d7,6ae61724,275afe54,4c06355f,ab35a276) Z8(8e7b83ee,85960e6d,6dc01534,850c2493,a84856eb,2de3ee88,74222cfc,4d4edfe8) Z8(86e7fed4,4834c6ba,eb3dc5c5,f743aa7e,52936042,f0b36adb,df6732fe,2ac64fd1) Z8(3ea35646,637c0206,d7de53b7,531c06dc,4a0eed7f,469c41a5,fd93bf63,da7ec99d) Z8(3bdbcaa9,85844f90,034c53e5,d192d7aa,1330e758,d55946fe,2a5b60aa,5502fb21) Z8(07194796,899a8acd,dd83543a,a3606728,06bd48a1,53dec2df,2c30d21e,84501cc1) Z8(f407cf9e,3e910bc4,905d3666,29b175be,c2c045be,997489e1,ae8ac909,5f982299) Z8(e52cb294,bd3b8108,455349ae,a0d62fc1,b888e0a9,00644d13,9e7c232c,411b3356) Z8(b80fd13f,eb91c402,cb145ada,815d071a,983de4d1,fcd7cc93,cf2be3f2,db71f795) Z8(600770e6,415b6fbf,6a3bf86b,85286400,cea9cc75,1702b8ce,2c6c2469,19a84711) Z8(c5e16f23,73e4a959,144fb276,29b1a74d,ff6014c2,fd494170,4a2bfeef,4754fc76) Z8(6b573143,56c0a817,6603f909,ae3c9fed,e71c58c9,c2c9eb2a,6b1fd591,468f019d) Z8(fb1fec5e,7aece16b,d66844d9,313708c5,dbc3a947,0420c8a6,38be94ea,5306637e) Z8(038a477d,e9956b1f,3aa5e583,06b8526f,ef23a74c,7bcdb679,29fd1fe4,37c2c0bf) Z8(f14d9e9f,22c27e70,a58cbb4b,2cc1e67e,25092a73,034c38c9,2703e03a,1fb21990) Z8(037571bd,822b5239,9a9743b5,8aad128b,52af2db9,1570b175,0d47c1fc,9d29d02d) Z8(969ab65b,46f441bd,43065b43,fd71e95b,2bc24468,e0436af9,923423c5,c637a033) Z8(97c6906f,fe9102b4,d3b27116,b2e17dde,ac7330a5,dd5006f5,c5f79e8d,ff35b601) Z8(9d0690ca,bc076cc1,d9901715,c85d2c01,b886afd2,0ee85e7e,83ba61bc,cc613661) Z8(f9d25229,8a185094,3fda3021,bc6d24d5,f3836fc0,74e426ec,6ead71e5,d76d2256) Z8(59a4229c,53ff1d78,c8a6dce7,f9d230cd,c4c96b3e,86610a65,0c04b8d4,9a6bf568) Z8(594cba1d,d887d560,d7add407,dcffb2f1,1db11c0b,f9c3ec7d,85dfa887,b6235a58) Z8(4eff3a9b,b1bc432a,7fc72814,41734688,c3f23d0d,d6108548,43071f8e,7fdd1661) Z8(1363f282,a20520e3,d3eaf7d7,bb46f7d4,8bd8940c,70029354,dbf4be1d,573e0723) Z8(746723a5,ca1b726f,53d887ae,7d812d35,34b3b81d,a7847d39,3616a7d8,d6cca136) Z8(2a335402,449cae80,6d4fc678,409606b9,464f6f96,d1852648,f99303e9,669e8a24) Z8(38dea4d5,01baa201,c2e4e63c,827c1fe7,411bdc1d,4f5a8b24,8ff877de,25cf642e) Z8(8ca87ca2,d288aa81,b4b7a793,d755b21f,217bb733,4b32066b,0167d08e,0c94a06f) Z8(33e31cf7,6c267976,6cda4a20,48e54861,a3faea87,cfa78099,1a1e7c40,92873c28) Z8(1378a966,31028e02,b57600ba,7b0a20fd,22def5f0,d6a3c561,416aa555,183acc26) Z8(bf3833a7,5ff2c51a,8c0d943d,a5794670,0fd405fa,9327c203,d48973ba,b1488393) Z8(9f5f2aec,e42de389,c7458d46,17ed2458,6941085b,0a4c2fa6,b65b0dd5,5cf646b0) Z8(e5ed7119,d26f88ed,1c90f13d,d59807fe,bc757228,17cd5774,a0b3038c,a30d3896) Z8(abcc4bef,21b14b72,f7f058c6,d318bf0d,59cc641a,5d2c7f54,7160e11a,a190338a) Z8(3fcd901b,11755aaa,fa64df7d,94aeaa9a,4203b81f,8e9d5942,978f6d9b,db35d11a) Z8(200481a7,e6fcc863,b6b74f94,ed177ce4,e9ace9d8,1dfc3c38,2a909fbb,1ef5d676) Z8(5d0644c8,643e78e0,dc9a3723,b428bba2,6d366f75,f0875b84,29d0125a,7b4561e0) Z8(42c15d07,c5154037,7242f4c4,b2e9877e,f3c4587a,510e7474,3b232715,15dbe128) Z8(53c0f731,006208fc,6a989bfd,1973b2c2,cadf0cf5,1b8ebba9,50aa441f,7463d86f) Z8(e8117b1e,c820723b,ea1ad5db,079b9214,04f2289d,a70d2433,dea322bd,daa698c4) Z8(25391552,baf5842d,10dc442b,eb20005f,9873732c,78886507,62a2cf7b,eb03da48) Z8(dfd0b5c3,ed4b5ed3,aeac8027,eda58084,cf4db008,f3c6ae9e,14a26c7a,2b8f8e9b) Z8(851a5b82,8d2f69c6,66305968,a19dc640,40d78303,881b9605,c28becb4,f5b273f3) Z8(faebf7a2,95cc3adb,6c36cd2c,f59964fb,05c1540a,aab636ad,6e8b9795,1d615fe6) Z8(409bb91e,aeede91f,bbed24cf,c743f6f3,77bab28a,08edb7f0,aec5da49,9683cecc) Z8(f85a2dfe,3c493b37,1c978134,47e829f3,b43c7620,b04d0e26,8983d70f,d37bcac2) Z8(9c68408d,9a423224,7247aa44,2dd13d29,7bfd70e4,106576da,5e909d05,70863195) Z8(097afb89,fc9c562a,dfcee028,a2aae63d,ecbbc134,9fc3e1c0,6c869625,09369180) Z8(d2521351,24583718,5ccc11a7,338e5c85,167bd3b8,12b60587,4a81cd2f,c62a65b2) Z8(9947768f,a1f85aa7,978c79e4,c9c7a3c1,15caf99d,4e17e23c,bf1701b8,6e17a9a6) Z8(97fdc967,343c07c5,c6fe559c,199ce32d,30ea04fb,6a851072,903052af,917857d0) Z8(a697e51c,3420da56,c110c00e,5e6e6ca6,62cdb86e,82f7acd4,b0c9387b,71b98c75) Z8(eddd15a6,7f526f4c,8937883a,dc39e74c,b73b07bb,998894d6,b5f2e738,c295159d) Z8(9fce1950,03d51b16,a1252325,fc928a75,e596298c,151c2660,bd3dfebc,650b938b) Z8(64f22a1b,2db39c58,71f3b3c7,2d33959e,fabd76f5,4d0e7ded,820bec96,6edd83d7) Z8(b0329c05,d63274ec,948215db,3721580a,3e9a128d,aa6ff57e,c1ed4fad,44b69183) Z8(8d67d02e,af6429fd,99e56677,ca5c1d2e,61d84f32,40ed9273,1e32d672,21aa643d) Z8(e21c2a8b,e9fed43f,dfcaa41e,e44a3c92,8e9adaa2,7ccaafec,720bb770,c50dd48e) Z8(a296afd9,2b4df343,ddf8aadb,fa177547,8f461442,bed699b6,51e77ed2,ad0440ee) Z8(b7915de5,c91aff8c,af71d87b,7240dc7e,0e1a86b3,e26e3290,1beae849,71cbfce0) Z8(c784df6c,65272cb1,a727c0e6,16ed3101,d06ae845,595adcdc,1b3e9d32,93dbd00a) Z8(08547516,4071b030,b86f985f,c0916505,2e3c99c8,df146fcd,166b4b94,475b995b) Z8(dd1c2e7b,682e73a5,b4c5048a,7be03d0a,67695a6b,4bf20871,16422f27,088afee6) Z8(f07ec64d,3f1c9b93,f759c525,b80b0faa,26c1ad98,c24036b7,036644bd,45b497d1) Z8(eff48d24,432baee5,13df1e26,6aca3a03,b79b229f,4c3ca48f,dbcdc748,a328cb23) Z8(226b8b56,b81572f8,cb7fd0f1,e52edaa0,3d40b3da,7d5c398a,d146c0ed,fa1a1b1a) Z8(46d71949,02bdbe54,55570161,5a07d6bb,0b0f0326,696a0e5d,0b314a86,5b5651a1) Z8(e17d4073,8fef5c4c,efaf1de7,36a4fff7,e3e5ba78,8a9de13a,8cd68d43,06854a80) Z8(9c227bb2,cdde55a2,0c7088b0,e77ad698,bef5915a,fd297e4f,615cec36,9a7d3608) Z8(0e932ce2,03965240,21dee819,b469dd02,afc106d9,0fa98ade,c7bc424d,27cf27ac) Z8(e71602c9,39cb4800,9be30796,93e588da,851fb1fa,843d8ff5,a4166d67,798249c5) Z8(659eaa0a,6d3cc401,3e89ffb2,e489be58,e2bae238,95ae99fc,68bc4c89,0cd48280) Z8(70d4e962,d610bfa5,5e81bcef,f7d70f40,b6d468d1,10ed0bbd,6ff4fa82,06bb98b9) Z8(5ce28b99,a8b6cbb1,6047b0e8,2a6d1226,23e43a43,c5c334da,b25b547e,081a8a54) Z8(7f0f45b6,85196964,918a8e43,a7865a5a,0396324f,a1a19866,95234dab,0257dd43) Z8(f102b4cc,cdb51882,8a0d6719,560e376e,1aca28b1,71860ada,70f1c98a,32168f87) Z8(d98527d8,13d1e00d,9e2ca477,5536002e,173021d3,d13267cb,5486b0c9,64782f4e) Z8(4b8cd341,74213c29,13aae1b8,6e7af832,aef0a20b,27885e0d,b00309aa,dddb790f) Z8(f9282e08,af91cf97,aa23a82a,a06ed6f6,c262673c,0c5fb6f4,7f09aa6a,fa648466) Z8(609455f6,cb1e2ee7,570a95fb,cca80795,27bbff0c,96c50c45,08745d4b,d6d7cba6) Z8(bca1727b,ca128b94,c39f576a,05fd8a12,7b9044c4,8bc9eaa2,ed67cfdb,35fbc1d2) Z8(42463a6a,34d59a1b,66cc711e,ed22b460,75162bbc,fc77d87e,fb26a033,09d05255) Z8(9b035d08,1665b5a3,69950ade,1a4c556d,bff16be4,a9fd0f4f,b23df377,bcbdcf0e) Z8(9a63bae9,64857e63,628319fd,0ceffdca,b481c25d,424a9b50,2935571c,58349d5b) Z8(3de9123a,62c6a0f9,fe008384,9a8a5273,287633b8,b6ccfa2e,d4c46cde,5c16b842) Z8(dd360c3d,aafbded1,6c16afba,530fb1cb,ee9ee3d1,494fbb02,12d836e4,325433ce) Z8(4bc0c24b,9163842d,6509ecdf,8c83e30f,23b138a4,2e8a30f2,2676a5f5,e6be4d96) Z8(7f08fb28,44fc781a,b27c5cc1,b0d92839,11278928,86db8e3c,93cddb58,570d23f6) Z8(3789c881,fff73036,ddd28685,5d193d3f,247ebda2,838fbe01,1f3ee707,258f62e9) Z8(d2dea49b,b195f39a,a78a72e3,e99c1353,dda894ef,c9375eed,f5722ade,5b127aad) Z8(1ccb7ffd,2e311775,edb307d8,e28cbabf,85723772,3cd8aef3,8f875112,71699dbc) Z8(17134dda,7f4b58c2,e8f91e60,e4714f94,32aa4fbf,36dd2933,21a791a4,d080dd0d) Z8(35b32f29,a94cdb28,51b37960,406267c3,c63f3a8a,8f4636f7,d4d80fc2,ff8c8a1f) Z8(fc6b098c,b3c0d580,085d14a5,b94a91ad,fb48a262,9f5d2d2a,f1b35da2,9a469623) Z8(457860ec,aa3a9767,8dfa267b,9323a879,9cc8b0ae,494255a6,a774b15f,09d7681d) Z8(4d6b5876,889ee15b,6f8516f8,16ed5194,5060ed45,a259cb94,e4d9f15f,906c75fa) Z8(c74a296e,02f248bb,ef45f840,e6a73cac,b352c85c,158c0a81,8d48683f,41691803) Z8(0655838b,1a545ee6,3c877d32,42347994,1c1e4692,910cf953,02846c81,fc3c8ba6) Z8(8179a55f,a883a996,d0b38871,765d2d74,0f859d20,7b85903a,bd2baac0,09e45481) Z8(17acb4a2,298652b3,578a4684,0bac8bc6,142a72be,cb1699bd,a04f9266,60ade071) Z8(ea6873f4,b1a0aad3,873e131c,94de6524,268d334b,9032513d,fb129fc7,e65881c3) Z8(f62f1c71,2e0718a8,874a06f7,ca98e056,6a366499,1f06733a,bfdc725f,088c23e6) Z8(bb8aa694,8209632d,58b3d28f,3b29f32a,bff4cd3b,d7af88d2,555f8230,3c88ae1f) Z8(3d6ec30e,e2595c56,a5a90145,8bbeaca0,cd4aa45e,899be9a4,eb2876ba,b6067b95) Z8(523f4d95,cbc1d9f9,6799fdfc,7c1d879e,106ad7ee,4f7807ab,1d27b7e9,3adb995e) Z8(2fbfdfd2,b63db525,c25c717d,3f46b735,3662dcdd,8441ed05,154997e3,5cc9259b) Z8(c5c363cd,210f448f,5affc41d,19a8bbb2,fbb10a6f,7c11ff84,0686b7ba,97b39208) Z8(183f8de6,c7b8ac27,a9b577e3,0ec91dda,e8aa64ea,b6519c39,f40cdf0f,3620d70b) Z8(3d5e76b6,c6ce4df3,063d7ffb,aafa4dfc,9108ac91,a994e6f6,536672c4,6dee9547) Z8(80a6a047,3021444d,a74fa06a,83bf50e9,39f43a20,7109a95b,1c3b0382,20242b2e) Z8(afeb3d7c,116e134e,3474fe93,f3cbae10,7b3d4444,f90e5056,ca8c974d,e51c00c4) Z8(75cf5c7b,afe40656,f41d4674,3c094201,2afe61bd,a97b85f9,3091073b,2f502792) Z8(870685b9,36e03878,d2d27968,b7e1f389,9df3033f,1fb23834,ff943d6f,71c7e4cf) Z8(d4a76e82,4431ce1f,2d2e9cf4,47a80314,de994e26,a9e41245,653387fa,21bae49a) Z8(f893d9b7,6ce4c917,4dc2e153,76241b62,ddc91be7,e59ef086,266b28ff,da936d5b) Z8(efe83c35,62b8c3f1,cfd0a097,490f5f93,a7cf1b12,54cd9c40,b0f6239f,df24dcf4) Z8(a27495e0,77ea6629,b702a2ae,96cd05b2,d131ef8b,5fd0881f,d83350a6,2fcd5d09) Z8(4efd6f88,41c6cfad,52d2ab4d,bd3b4077,b34ae921,56bb3b75,b1181e7f,a2fb4a37) Z8(c3df6255,a83eada7,e9f45fc7,f32993b7,53bb1ced,c06b98a4,b4e7dde4,01cd762b) Z8(10cbc766,3a3fa42e,6a83c709,4d170f45,8bec2394,f71c8fa5,17dd29db,f806542d) Z8(5b46049e,dd2e0de7,23933a96,80df7778,1e412239,b2919465,d711538f,1057e2a9) Z8(9d1bbe4a,82b19b48,77b38f12,8773ed26,1580787c,64a9fae4,95c9ad0e,98e06332) Z8(0cca196b,30258abe,927b986d,63847ebd,ec1aba78,8f2f2d1f,68680eae,06d37c0f) Z8(36283fbc,f3e619ca,1b662364,dbd0bbc2,43ece335,536602ab,6c7db599,795eb3d8) Z8(06bdbf7c,acf32bb2,a4d07a76,f85b1f44,829e0922,0080f5dc,58d2b4bf,7daccde0) Z8(cedf93d4,fd436441,cb6c99c8,0bf04fa4,f35abe28,a6e8615c,50d95d9b,19738d89) Z8(add2ed8d,f1edbb85,64fcf0d0,cd394ef4,11e7fc02,74d55892,2c3c63bd,4bc8db33) Z8(714ff7ac,e4ceb5bf,34d868e8,1fb4e049,da4bfe3d,446d0142,11361852,857e1bb0) Z8(0af67d36,01586305,af4cf067,1259b26d,15a4d609,8bf7cdae,e3d98955,a937c3a0) Z8(29926dbc,e0456ba7,a22369bb,4a56e822,f32be0b2,a5b50ccc,65451b7c,d780995b) Z8(19511fbc,880e1eae,1bd39297,fb6ba5ee,f25a1179,9bef1245,10144e2b,0efd6fe5) Z8(833b325e,87c9a5ff,2da23382,a49e5d86,012f4b11,6f285c21,a9dc33f7,09d64f89) Z8(21f8c3d5,a8f8879c,97065c50,15c2ac62,985b81cf,f91a22a2,0f90c0b1,0fc2c0ee) Z8(5327ad8e,184313c4,39b0bfea,05ac2020,f034ae2c,0500c809,b4723f45,0c2869d3) Z8(a40c4f1f,044a434d,de3ff27d,3c434098,73cb45b4,ed40fec3,ec6c2085,42d44786) Z8(eec9c6ec,ed9420d1,67838913,f2417baa,8f75a300,c60d07d7,47464a95,6bafd81c) Z8(cc04a724,31c9adfb,c2e90837,7f2dc70c,4fbb31d2,8b5a844f,483ac05d,1f289c21) Z8(54a1d59c,e8017c14,895de30c,e3c8a540,6292462d,7caf60a5,93c583bc,6495347f) Z8(a00b99c5,58438d0b,68a47a9b,dc8fcbdb,816adae6,ac4e2e37,2b3976e1,0de1b5a3) Z8(14f0a5a4,e9f002f4,8afb6d3e,ce9f24db,e2216fc0,3c22d43c,e2218797,847b081b) Z8(e406d4ed,a44250ca,406fdef9,ff7a52a1,4ad5d690,ba096ded,2d9ea549,aefc100c) Z8(f85c6271,c985aa1d,ba5b1057,15553e55,00a4bfca,06b41a92,5ee1df49,dbdb4c0a) Z8(5d285860,be654eba,ab9be541,58013a3b,e64ed514,6e033c73,071f38a1,cb4d5d4f) Z8(4ae864c1,9cbd4dc6,0ae326ae,e82123c5,f543e1b5,bafc3915,f7cfb396,a2a507c2) Z8(8fa5757d,07a8f4e8,dd8f91b2,36a4445c,5d6169ac,0bbbd75b,7b09c68e,b315a94e) Z8(cbd71bed,e739ab7f,2056dead,e7abeac0,593eaeb6,99f5e674,474bb1c0,1e154bd6) Z8(30ccb976,3e59222f,546c6bf4,6a2ca1e0,b0e803b3,be483c6a,b14d130b,76ef2f06) Z8(0491509e,7fdc8bbd,666c09b5,53ae470f,0cfa9c44,291b6684,5b8ebb1c,7abe4a32) Z8(022978d7,cbbd4dcd,3424faf0,9533af8e,6f3fdd54,e49c12cd,3f7645df,45555bdb) Z8(f8ff5c01,790c88a3,0fcbda5b,da978b72,9a362fb0,27b6aa33,7d8f9085,f06eb674) Z8(73e1b94f,666bbb3a,7224e99e,eb3fbb3a,782453f9,fa99d81b,48ff82fa,31724d5d) Z8(55420e5b,10be7814,0b05931a,0ee57d89,d9a8fc8f,27ea620d,725f81c4,689412c7) Z8(f3e0d55e,ec0ceb4e,43d19b5a,78712960,e55d7475,9101031f,a0295bf1,15a3cc47) Z8(6771de93,e85048ec,36315d55,29c48686,e316eb02,556df11c,75262f14,510e7ff2) Z8(5e497da1,7d54dd89,09768bee,47507c2c,b127c090,571e8279,5d297f96,3081ad86) Z8(4cd9de95,ecda9711,43a2cfc2,ff3c57f7,9d7060a8,90a0e465,0fcf9f79,64e25539) Z8(b322825e,352b3b0a,3bf45ec8,c9bc8448,8a3653b1,67bdc5f2,7eb67b25,d6cf372d) Z8(8ad8dd10,2692051e,1506e3f9,ade2d90e,5073c07f,b8a22a29,6f51dc55,61450660) Z8(4039951c,4d30b5b4,b0b6019f,e077d3c3,586d3872,886a1c76,4d58a51b,c9a36cb8) Z8(ea5e6e61,5aa1bd7c,6b5ad8bf,b4de893c,d5c64edd,352f7d23,d1f02741,a0b99983) Z8(3af7d32e,94a44876,ab086d42,32c4ae97,abd4fb4b,7c8d7736,7a2dcf1e,306c23ad) Z8(39053155,d13eb794,35792abf,29681628,6325dfa0,59e393d6,071b4981,c61b9d9d) Z8(a9bd42be,73cfeb6d,0bd84d6a,9f6255cb,42b187da,00a88c75,879c5988,9802d536) Z8(e172f101,b41b1d3f,6f9aa4bf,837c5dee,d8223918,991c4caf,90b88399,fc43be5f) Z8(4114826f,e40e978e,a0ecf3ec,3eade0cf,97ad5ec7,b5f0856c,e6ad357c,c595841a) Z8(94f42170,f95260a2,3967b320,9a2dc0af,35057e54,20849449,5f95c718,71c4f319) Z8(c3a6bd6f,a3efa109,23a07f0b,a8910025,786235ca,a696fdce,f9b4d91a,5699115b) Z8(9e2beaf1,4ecc1871,8365975e,7afe32d0,632359a3,bc32fc44,4a127650,9f1b1f0f) Z8(887c5bd3,99fee53b,f6751a08,7dcb26b9,13d13dff,1e62793e,a166fff6,1ab02ac3) Z8(473db31a,65cbf1e6,b403a01b,a9d1230a,0efd35bc,1463c090,a4edf762,7bf8e15c) Z8(0ec24d96,463758a9,2f11b148,780ad4a3,c1c21673,7067b6c7,e377c849,817daa29) Z8(eddeb113,f5c0fc54,fe8cac65,75041442,eb40fb4c,03b40842,0a0ddfd2,b9469bbb) Z8(1a786af8,53dc0fe1,ea8be441,59e23291,88d14d32,8fd2fb6b,be89288f,c29d9054) Z8(f3fcda10,34b572d4,2a8e3df0,4f1bd03b,18f89da6,b006b029,ac4c11cb,90dcdb0e) Z8(1454bc44,5e691670,3ebf3c1f,467bce1c,a2e0545b,34ca69c1,e6455722,4c966885) Z8(43132697,983c2f66,d4721a73,eacefcd3,afb16394,25256f02,f09882c5,f17a55b4) Z8(8c3b47ed,12ed5fe8,32305940,eda40c49,55f62f77,823a07a2,4684878c,62ac5afe) Z8(1e20490d,5acbd26d,d5c09ec2,3f2f2057,ad00b7fb,038841d7,c04a356d,c212d7c3) Z8(e7b1fe0b,3aaa1cbd,7c66ff13,26fd10f7,0068444f,8844fb98,b00b1f5a,978023b0) Z8(e10b718d,8a67ac25,68ee937a,4b6e20e1,63afff40,6811bc50,cf1b67a6,9cc42d0d) Z8(63651dd7,ceac0cb5,eeb2f6a6,eead14c1,cb5fb6c3,bf04e41c,b31acdb9,3d9d44af) Z8(7f0e4be5,208ebb48,48d1bafe,3d2064d2,21899d61,515ff9f0,36bb2544,3e6886e6) Z8(51cd006b,fa42e770,4be9d286,04887843,dda9e5ac,057f4d62,194f70c7,1836812e) Z8(d539648b,02344fa5,f459136c,d0968987,7ee79cc5,75d3327d,70c95959,852d05c4) Z8(682c21bd,01e44d67,0cedcb6a,19c2db78,68021beb,f843afdf,a943cd81,bb092949) Z8(ee7281f8,f04980f7,6efaa7c0,2184b9d4,855442e8,21163fff,b5e20a1c,9b5ac6e0) Z8(b9d17a61,fed2ad0e,60e33d63,d8717f7e,137c1660,0a4f017a,1ba7dc50,190d48e7) Z8(7ec05bbc,579179db,51164d66,754d4dce,280a73f8,3e6ab416,51888b53,98709578) Z8(a80611ee,e7313678,d47b314b,57c4dff9,4a7b6119,e7c4831a,37da31ed,b857631c) Z8(8b774a44,5d3982a3,a89380cf,99c79f51,470f5e5e,7c86872f,2d502ea2,caf7a7a2) Z8(43ce8827,600f8280,f5948658,eee77e6a,9265fedc,d28517d8,78f73f60,d7827e5c) Z8(9922a2ab,d7ee9a73,8008fad0,20ffdefa,425f51df,1a45afe8,aca9c4e8,88b44aa6) Z8(2483f318,d2137ddc,3c40abaa,a1807b70,4f2ab79f,b90a1efb,06fbb84b,1111d43a) Z8(9777ca11,82e6e9a1,e7874ff4,a1760cff,1e9db818,7868d3f5,fc5813da,d08f0b59) Z8(ac8207e1,95a6d918,29a0fe54,c8ad0eaa,54d2607b,30717cf2,ce40d167,4ed7a144) Z8(565b8223,0d9c5feb,3fa7dedb,9a948f29,dba50bc5,befcc145,65b2de36,1ff19bc9) Z8(f459d989,755fb0f5,b5ae55d4,8672fc6a,595e607a,13a95faf,51304f18,cbaf5aa1) Z8(e7f5a113,74c87b23,c7c801a4,b6a802c9,f9a21979,ace184c8,f84933b1,da54cd45) Z8(99a6e139,998062f2,7d517a6e,67d50696,a065d5d6,7208edd1,6be0783e,fffd1ffc) Z8(15ffa111,cd5ad73e,c2d38cf1,0c984a87,df3fb69b,0581f8ec,612efcd4,f90e191b) Z8(75cc8ad8,d4b13fca,81b23591,94491c38,8e42a03e,110ced88,a4a1af57,8a8d3acf) Z8(edadf2b7,625f0b76,6f5e3ad7,61e6b6c2,74b43370,7de92545,56898f7a,1340cc47) Z8(a3fb976f,4f18359a,80a0f3a9,b06328fb,1ba5a3b6,e56d5138,216e9cb8,104763d1) Z8(75c51dd3,4690a8c0,65ab06de,d7cd7058,be6e0a71,83a2d6d9,69d9e80f,9fb6a4ba) Z8(ddce7487,23c00d0c,f48d7a6f,21249081,849cf9f9,5b2c4c68,16b1737c,e4ae4246) Z8(daebff05,6b6b2059,8bec06b3,dc582992,8a993f14,facea004,b727a3d0,7ed11df1) Z8(42c08e50,d75f3b24,657ac1d2,b709864c,eaa24286,ea7048dd,f5981974,d9360fb4) Z8(1f5f09fc,66cd94e0,c00dc021,c9febf13,a546bbf3,40eb3682,9f1ce2b5,aee96554) Z8(37709216,e260c583,df1dc93e,eb28757f,94a2f5dd,48f24d27,b521cd57,ff964711) Z8(84fe3992,632ab8c0,485dea16,91bc3f93,2b2a3302,91ca86a1,12899699,11698ff8) Z8(db1ab4d5,7abac182,085e216f,3193740b,ccee9bc2,a080f447,56cddb6b,8d1999b2) Z8(61695627,6cca0d9c,26946db9,b9109846,4439bf13,3f4ee2b9,c0dd103c,a1aafef3) Z8(7d48fed7,0be4ff06,fee86825,816649ba,e837dfcf,0a8ae742,4f46adb6,d22df86b) Z8(4900160a,c07b974c,b3eeb184,897c32d8,695b80fa,26363171,048ccb1d,8a50f92b) Z8(d525f728,c4fe4211,e77c8cd2,932fb704,c3ac7a92,9aada34b,cf9e34d2,51ccb430) Z8(1df291e3,4085466f,90ceddc0,dd613ffd,341b40bd,72bdd279,f036b2d3,546f8a30) Z8(6742f95e,a6d713fb,f5e090c3,4ea7ef8b,e4754b7a,2fe223a6,0d55fd0d,f5333090) Z8(6d433a27,a2804aee,3e2e193c,efd269ad,70b1081f,78d7df03,8f302143,a69d5ba9) Z8(71d6bf30,7f8e78f0,f90ab530,f8d3e7bf,15b06396,3cea57bf,9ea2a66e,ed77f854) Z8(f8f9ccd3,eeb62fe1,482cccfe,63afa43d,7146be0f,fd64d0b6,d8b4ff1d,67a476ee) Z8(eaf19d53,91c7457b,a4b144b9,62246b05,12a20092,d1d1910f,9325793b,50c396db) Z8(bd9c39e9,41c68662,766a7954,ce27ce99,ab5b2533,db5d10ff,f375c85d,bbd618a1) Z8(d95c4f71,f732cca2,5f849e74,1d94bed1,155b952c,accb093c,54b46750,0004f1fe) Z8(707c7c76,bfc8a7ec,9623e0cb,85dad892,b1ee574e,0487f2b0,43a8e139,d0a8d879) Z8(f18a1d32,35292a02,6ad2d4f3,9b1e59fd,4a2bf337,a015b197,f3ae330d,55394851) Z8(d8865bbb,fa6c4019,a5b3aac3,4b23c1ec,6bf91d24,9b96be97,e5e99477,795f34e0) Z8(20e99d3c,d574bcaa,a7a8353f,1e681d5c,fd2dd2a9,023ff03e,c31e940d,be9e65b1) Z8(2f5eded2,b393c45d,b08b0cec,52604c56,8f2bfbbc,2783f8de,49bd7206,321efbb8) Z8(1f70fe19,2230c0eb,87dbe674,29003f53,61cfef78,655e6c8e,329fc38e,cfb9d4d3) Z8(863ef892,7b73cd2d,d9e0a595,e6e74e85,e48ec654,4ed0f47b,ff248243,6a430c0b) Z8(3fd2ea1e,e6982c93,75a07c23,a59b5293,8548b069,633cecfd,925ff51f,8adedacc) Z8(8cb6dc8e,27665aa8,fb1dd34b,1066f12a,7be8843a,eb4564f0,f2feb11c,4e9c0620) Z8(f0a53da1,65918ec1,9cea9a28,ea0a9f92,d19bd358,1b528451,57968b4b,7a4175b8) Z8(d9271135,4cd480ec,24c0a42f,07f4095f,b49a3afd,81206daf,eb30dd7a,37eed4ae) Z8(e6649320,6e6e316c,d3ee4178,01fbd5cd,0a6c1bc0,f4487894,c2bf66d8,29bd14b2) Z8(81b94ae4,702e3775,7b10dbbc,1adfa17f,8f39cfa9,45d4adbd,7e2aa2f2,dbbcf13e) Z8(11708b3d,d4a5dc58,5a6ac2e4,a4d4c255,5856e203,589cec29,c6cbb52a,63b2fd7b) Z8(56d96df5,a64e734e,1c1e5c0d,7b9e95a0,61ed13ea,984064c1,947d3c06,619a6be6) Z8(e92cc32d,0ee321ef,0abbe35e,91233634,b24a5bca,7e25ac90,bc3789c8,3df21ef7) Z8(4978bf3c,c7be7c43,a6d66904,28ca1ff4,2ac602a8,f2bc8d1c,5c7e388a,5cf9ccd1) Z8(8315854a,16300c2d,c2bc7405,3b88051f,fe5c74d6,7befd1c0,6c0a639f,e0fa28f8) Z8(0d110806,7d0e3c4e,953808d1,21a59a3d,f8c6ca37,d2d44977,6708bed5,710992af) Z8(6f65eee2,187ecb19,aef96e1a,e166f1d1,eec34c3b,e40a1b41,3e0d8c2f,d10e6cc2) Z8(78719c90,60078865,08c49261,4d0f32ef,df1c765d,ba8cb146,35ce5992,6c9d6703) Z8(d8cf3599,3587b144,bbd26ebe,cea29740,ac8e94fe,aa21afe0,bf042ed7,7774bced) Z8(b813b580,1e20201b,72c4fc5e,75f00619,d55ae56b,2f3d3318,1364701c,4b1f42bc) Z8(accea3bf,1cea5897,4e0381e4,84ea2d73,37efb700,ae520f69,4f82d598,dbbb72d6) Z8(7ec19c68,ad64745b,a17515f3,92e45e0a,0f2ce7da,3b843dae,ac4f1a5e,cbf960dd) Z8(1ed5bcb7,1a8aa82d,10fe1cb4,1458991c,80cc1713,2e21d15f,0e557163,36ad5f9d) Z8(281ed812,972cb8d5,4c3c4887,69429482,372b0461,06da6830,6cbffb94,c5c9b8b4) Z8(f1c1b34d,63f8b7f7,783a5100,fefabfd4,67b8edfb,86015b4a,0ca212a3,38be2f32) Z8(9518f10b,93ed7534,b3b4e499,0abc36df,dfbc5cac,df8a9fcc,16cd5b3d,5b9628bb) Z8(8cd4acf8,d6698335,1da137d5,91870a8e,4497598c,a67c1423,349c0a0c,80399fee) Z8(591d2d24,0f9ab945,851207b1,a5ad4144,a17e9723,25a81a91,d723b9c7,feaf1f83) Z8(1e482207,d8f94106,2bbcf6cf,95bda6cb,18eb481b,893a5867,e0974425,443006b0) Z8(97f7d527,e8041309,3c93cf8b,1374ed0f,d56f0fc4,d9e9c259,ff5a7346,933711d2) Z8(3eb12e05,cffc104c,33fd5576,1ae6f855,d9f6344f,addce3c1,f3e8e5ff,8fcf5b5e) Z8(319c7a72,de69d9d7,283e1d0c,fd9bb0bf,18a0ba57,b4dc1b0f,a08ed831,81e56986) Z8(29597619,a316fa62,6dccb52b,c94d5b71,959043cd,64639412,88880a3f,a24b4f07) Z8(b09cb99f,02667d6b,927d4b63,2e5f12fc,490c397a,157ba9ca,3451f25d,9f74864f) Z8(dad2ef0d,1ecb3701,c9862554,65c1dd61,af2dabe3,1f784d18,700c40a8,c539187c) Z8(7cdff604,9146d965,5559ca84,5d96a815,8899e85b,4fc9723a,8239b5cd,4184a1f4) Z8(fb179d49,8d1511d6,e2198d02,44100e48,69fccdf2,9c93adc8,e3a7f956,970a41a1) Z8(81ece8cc,f80ae81d,bb02901c,967b4f4c,18d69cac,1ab85b1a,d7910c7b,9832588c) Z8(46a30f68,2df03633,57621bca,94595a0c,3538559f,11551d80,80d6443b,8a90b44f) Z8(e685b19a,8b133050,219eb233,f3ba8b38,b6401b3f,5130fdf5,3a0a8f71,ecdc4f5a) Z8(75e22f67,ec28a16f,dd7ec3d4,8884d3df,c6021582,79205bd7,8c29a887,20022b8e) Z8(bb79bf2d,61618f97,efff8f75,c175ed29,81fabc2f,90a293f9,1f28f5bd,3093824d) Z8(65453358,4b12c895,f49cd15c,b4000661,0bfa83ee,51811312,f7e0a2ee,4bcf2e00) Z8(b7ad4f40,bdab0323,6c6cd756,bad454b5,f1a7f1cd,86352a2b,1f898da5,ecc02c3a) Z8(ea6e82a7,ac9ce282,cf8e88a5,0d8acfeb,7f301c7a,88d383bd,ca6435eb,f623c5f2) Z8(19a975fd,3a76cdce,786b94a8,6c965661,23b558a7,140c741b,debd643f,b11687d6) Z8(d1e764f1,620d1e31,d51a940c,8dea0fac,5cf770b1,508e70e0,7be1d8f7,5dfdd635) Z8(6e259b7f,11f128f3,e92e6487,fd8f7800,058f5841,31570e54,72295731,f983aa5b) Z8(e469432d,960ff56f,fb32e061,0c5bb07c,3b465346,e28c1082,32de6edb,1805cb5c) Z8(f1202545,ab555219,d7fb931f,640110c0,c54a617c,1eee7ee7,72c1bf7a,5e33c49b) Z8(84c3a776,8df9cec2,ef38d18a,69c4cdb5,8ffa4896,1ece70b0,4c5eba54,f31cc291) Z8(ba7d2af3,f725f0d1,c90d5dfb,d3892912,1a862895,7e588770,a08d15ce,2eb668c0) Z8(34efaa96,fd7768ba,811d73d1,83b974cb,e4e6dcca,e34f2f05,43071c43,cc3832d1) Z8(098da0c1,a14a448d,cbd7e3dc,aeacd0c4,2af53153,489aaa7d,a75b1ea5,b7ef4f34) Z8(71dca9ab,a8abe881,321947ca,dc544137,98fec1fc,d56ae93b,7cff14e8,a57d7c06) Z8(555ed278,8ded75b7,6147f63c,0a9ee22f,6eeb50d9,4a95f587,34b0ef94,45829bc6) Z8(2c121812,1d9781a9,555fd93b,73361733,3b191dd1,a2cb6cde,bc9a14d1,fdcef086) Z8(5cfc4d59,632cf194,a05db085,7806a933,fe954323,e82e5283,2e8b78a3,e6fc100d) Z8(7f6ace3f,11f20fb3,23c6cc78,94da158c,fbdecfb5,77ea44ed,02535bf3,476d6a1e) Z8(64d10835,d32b30ec,6ddefdc9,2fea6435,7471d352,03af6be8,d538cdba,0821b04b) Z8(29638181,24db0337,c17014aa,41cd5233,55f6d445,d5172102,ccb4bcbd,5e9ebca2) Z8(5952262c,66793e53,e835834d,02942edd,29bfbe95,2d65003d,b09f21d1,18339c3d) Z8(d22119eb,1d46239a,c9c7233d,b252e08c,bf011931,6e5dabef,3da98563,9e93ad70) Z8(8269f958,44ccea74,2a273de6,e1a6c79e,207bc70d,d3a40ead,e4931058,fe0eef84) Z8(d9117ac2,6b1ea815,1e377818,e0c38c01,586c47a4,b8cf5ecc,58c87681,c00ba529) Z8(28962720,f335a2c4,f050e591,9767d6e6,e064f209,21618579,80b234d4,89203fee) Z8(8b280839,b0436afa,be0f5b75,cd0e59df,a243017a,926f1b9f,c5df795c,69b64ea8) Z8(a4d87d65,e1291e33,927f6c9b,fa7280f4,baf39933,afea4730,61eae7d8,031a06d1) Z8(d46db5a2,1a2b14c3,156ab644,afcf0d0c,99f5bb03,da253042,7ad67e5f,94abcd6d) Z8(96879937,9954ada1,96154976,c95a100c,04d2c143,f493c5c3,4d3c49bc,44fe6d04) Z8(aba3311f,9cc421fc,c79bb796,277cb528,e491c927,e6c1ccde,1a3aad0f,beda8a51) Z8(50b5267f,4655c363,b4b66a27,6ce65a3a,68351f0e,538f0387,921a889e,21fd0747) Z8(6bae497c,3b8a980e,b025695a,118e2176,eb71f628,949bdd8e,ddcc51fb,b78dd828) Z8(52887880,42a03db3,05db6953,a17b8d0c,b6fb8890,268bdaf7,6b820913,e82e67ca) Z8(78fe90bb,76417375,aca15b76,c722313b,732c1a0f,6b039d3c,eb518c97,b38123db) Z8(51b10704,6d3ed8aa,55358ef9,6c214bba,1fd7f870,95b39ea3,a9bb8546,e02f42f7) Z8(27ee5cab,bbbe1dc3,1677ec4e,603900d5,7ce117e7,e91fe18d,b95c36a9,ad7bab25) Z8(5578785e,b8eaaf35,76ec223c,bf9949ac,f75979c5,7a1efa9e,60d15dce,91fecc60) Z8(758754b2,6238cba5,b762dd73,364d677f,37eca352,f02d2374,aecb653f,7d55ff31) Z8(10614994,2383ed5e,57a9e026,0ad27019,e56d072e,f378a2c6,5e35bdd9,f3e39db0) Z8(5ce2e454,ceb69ebc,eda4dd20,87011ad8,60266fe0,f1f8e077,47bdec4e,271dfc84) Z8(8cf4d650,b12b9ad8,0fc9da07,a3e50fa8,f21f3476,67e05630,2aadcdc9,2d32b661) Z8(c147ca79,6e777b8c,dcf961de,623b38cb,1a455c06,ac235445,4da824d2,102e07e0) Z8(15e4ed0f,99cdf865,99c4eeb9,bed8b4d4,4509190c,3738f82f,eec99626,b71cb75d) Z8(b3b85229,64e3f040,2203152f,9d45360b,3a0f086b,cff82e38,c6f0cbec,77430549) Z8(67413bb3,00651a5e,0ca29623,aa436bd0,94a2b9bb,1217e0cb,07769fbd,03c31469) Z8(b29816dc,1160eace,2e48aba5,94c84ea8,c9115fbf,8cd67f7f,c02308cd,fa88fe57) Z8(25859d89,89d5f829,91d9ce69,63899108,19b684a0,983bfa90,4413a657,36084b1d) Z8(befbbb3f,e7e231d1,b1cac89e,27658436,848d9764,c472bc16,a0338ef7,b1cb5410) Z8(c4308cf6,f21b3d34,08589e8d,269464ab,b3a2cbf9,2bac2c48,89bbddec,66435dfa) Z8(9c82b553,74856e3c,cc86c436,872e8ee2,c1121e6d,28a070d3,b799d9ba,02f50f68) Z8(7dfca024,1fdfb991,2b41e315,47747e2b,b3d0bd56,150c706d,56147655,f4d9e9f0) Z8(0c7e9c96,04c832ed,5618d166,a3733712,06591876,0cdadb21,924befc4,9f6db52f) Z8(7f78f9e9,aaacf08d,f2d5f9c2,daf0d157,15309848,10e3c770,2fa03911,ded72656) Z8(901f7247,15c222cb,a128e7f6,33729c1c,ed066f0c,6d0fac05,18958fbe,b76604c1) Z8(8b998b42,ab55835b,584506c5,aa287fe1,f3c5b4f4,84a57edc,dff76022,1cd8a7f8) Z8(e02d154f,d9dec870,ebf2139e,93c067a3,9c6aa6c0,03923b45,410853e4,d6524a2b) Z8(f7d82352,c372d0ff,ed2b3ac9,ddbbca3f,58a04713,c6ce9e6b,e8ca1b2f,975e03f6) Z8(0f47b4c8,802414fb,86157d1c,a134555d,5270f11a,ea104d86,b65c8de9,bae2e447) Z8(c7349815,0160e65e,82df1bf1,6858b990,4e4d85e9,218f87c6,3974087e,c391312d) Z8(e74f1cd7,397c120a,c95f33b4,b681e439,9980a37e,8c913194,9e881513,b5b3462b) Z8(6998a217,c54ee01a,d83e8631,b4c7821e,48dd2077,451767a4,bc4c1ac9,6351ec75) Z8(8411a18c,d6ea5b77,485ec700,ec4ee4fa,17c0356e,7f0887ba,08fdde3d,fa10fb83) Z8(7c2adf1e,b88b1386,70ad58eb,22e7d7ce,a1216533,5d2840e4,1d491ff4,cfc77d9b) Z8(c88200ed,033e0951,f8934cb9,d89fd19c,542c5130,257266b4,c5a01b4a,cd9604d7) Z8(4b6a1848,d2c2af62,0d3bdefa,7d9d60b5,5174b6f8,af48de4c,95a11293,8ba4af2c) Z8(062a715f,8dd2da65,442c63e6,4d7bbf16,5062fbf5,f6b2bc8d,fd8602ed,b8c5af7b) Z8(3d47b922,7c2b6f4b,c15dfb85,1c073af4,e20632ec,8aba9fc4,8d935aec,96bcd18b) Z8(9e7f9049,1bcbc84b,91dc5610,c072142e,6b199ea6,b25b8df6,4361eb1e,ba983f79) Z8(268f5b4c,bf75f4dd,75c119be,f4807e59,ff46868d,59e92f50,dcb89de4,8e000af8) Z8(1bce3f02,e967b29c,8695a6e1,03cd5875,fa418155,dd81f161,b2751c80,ddcb754b) Z8(505fd732,59c1e17a,7ee13b91,79eed108,994b8458,400600a7,f6f7e985,d01af557) Z8(1e17a4b6,db23b237,d0a65f19,467f8094,2a876649,8e9ea412,017526eb,f19f59e7) Z8(d9b6c13d,a5102b67,2d6fc9c6,9ccd8a63,a8d75223,c6cc91f3,eff263e2,653af79f) Z8(b2a3358d,d180c8a5,a02c2855,856cd4d9,897d2783,fb540d1f,62e81f26,be845b2e) Z8(dc3bf5c2,c7174ebc,75995259,dead9ef0,72a66b4c,e3e61943,f058daa4,208b9db4) Z8(63c8dabb,245a5b90,27837d53,e91603f3,c4d5b5f7,0f0aebd4,ffd0ce72,dbdf7acd) Z8(cd05891c,59075901,95c9c647,9bea3bb9,88edd749,78cc2ab5,2dbad4c6,7273c87f) Z8(26e4fc8c,0af6f8ab,d7e3a74b,76f8b464,8bb81240,2484bf39,6828ba2b,087f3a02) Z8(afc44c7b,75d995cb,4d1027de,4fe93b72,939843d5,e0a22434,cbadf258,a079fb79) Z8(963bfae8,da7d8360,2784483d,010ac61c,5e51ea71,f87c39be,5b38177c,7b9467f7) Z8(fd683b56,72375a05,2d68c3c7,1785242a,67ea97aa,13b2736c,fe7d95d0,3b31061d) Z8(22686fea,317aaf2e,ad0c6b26,d3c716c8,57fbaa5b,f13cef93,556f6cb7,6b688d83) Z8(4c348455,0b2a1c30,05ad32ea,7a2b1ea3,b9eaba3b,0d780ccd,c1f50087,4f77e39f) Z8(1caf02c0,57fa9070,d953f422,090a1108,0d85e2a4,aa1f9b94,821364f1,66fc84b1) Z8(c8afbb22,235f870f,fad2cfa6,b7eba71e,ca53c09e,6254971f,f5e2a470,e8cf6a4c) Z8(40cae7c0,2884ec6c,86a9b874,b14bc36c,f1f256d9,e4e5ae63,70a9a532,e963b7df) Z8(362377f1,1bcfd9bc,bb3aa87b,f17e822b,81d544bf,a4816ab5,7c009bfa,dd917ae9) Z8(5c9e4fdf,463d2e83,e42997fd,3033a194,21d81310,41d65e32,5956da38,925fbc2f) Z8(2ebda0e1,62475719,2e6dac8e,c7ca825c,8119afb7,bcb1c956,2931caca,85723a36) Z8(136e66fc,fc642407,4d6e7afc,3a6db1ec,98ae8d86,e400c82f,620bd8a0,1941def6) Z8(16e68267,907ea7e0,40859c2c,5f233042,6f78b9eb,734d89d1,24ad8655,4d389c69) Z8(fc30dc08,55923d69,24d26c28,f7ad38aa,1e1ae198,8e5c4b3a,1d5e264d,a492ec44) Z8(4d695f11,f28f5138,dc7f4ffd,0ea98c38,481c7e6e,d4db5aa4,8480e8bf,81981404) Z8(f04c3619,7dd28219,65562742,92358274,f586e018,c19edc5e,30f7d844,54915d5a) Z8(db2526af,781b309e,b661e62d,d9148c0a,0af719dd,8ebd6820,6ff2622c,c068244e) Z8(d8a492e3,63ab552f,427527fa,31e85e30,a1cd57e5,15e31260,c6c944ae,3aa1d00c) Z8(e97ec2cf,e82bf2d5,132dc3f2,a35a66d1,6260a914,3df5417f,93338f5a,d1886f84) Z8(30af4a89,cf2eb536,20eb90cc,c897d34b,b53952b8,b6e2ab02,761e8503,efaa1bcf) Z8(4e4f52dd,2d7dece8,e046d33b,9d30248f,bda00fbe,e3969963,c33528e6,f3b436e9) Z8(f524831b,0ebdbcee,977751a8,bf57cb5c,8fddcac6,86aee555,4991a480,6bc2397a) Z8(117c4d41,23e54355,9d46d3db,432ed3a8,a2783a7c,1796a7ed,594497c5,91f586a7) Z8(38763744,95531389,45b255e1,5dd4d8e3,4d649d88,b4d39e53,289c202f,0ce7d97c) Z8(1f261956,dc4a4073,318f5419,4846d9ea,45332765,f655ca2e,a60eb1a6,5a7dff86) Z8(23744f38,6492eb2c,b79da006,714df221,0984d306,70e2e1d8,1244027f,817cd12a) Z8(8b48c456,c63c93aa,bfcec52e,14122b03,6091a5fb,17f47241,3d4b0431,8997f615) Z8(83ade652,47445204,0446c9f3,205fecd5,065e42b1,279c7151,0fabd42c,2fe25761) Z8(1c52acfb,1934875e,ea54430e,bbd342a6,c62fe634,c363c11a,b323e60a,ace2cdd8) Z8(7edc8843,1f4d3c76,acb00a94,5ac26560,171fd27b,9d0955cb,74031852,4e0992a4) Z8(d7b6245b,a3e15fd4,f753a150,aa453e59,5a47992b,2e4fb601,99b9c6c2,ac135a40) Z8(4f254378,c6e6250c,e68ed0c5,f2a4141c,8db7c9d7,76f40aaf,89e123b5,9d227d07) Z8(e15b2c99,2548606a,74a6d1ca,39e88039,d6be9208,a877ba39,af09cd2d,e2769751) Z8(714e9eea,18a1f523,cc013b62,497dcccd,a4cf7a8c,8b07f5e7,8135a013,b787ee15) Z8(63c09667,b3bd8a3c,fe0ce629,ae9f81ed,28adcd7c,1612c963,bb3b7aa1,1837ec72) Z8(79323731,1e9bfdd9,07aad183,4539adf7,59a64365,ce728949,7e3782a8,2f5ce182) Z8(001c15bf,e86ee62a,08c0e147,76bfef95,2871c270,45543943,0b9ce26e,7da078da) Z8(cd73d66c,13e68864,d641f715,a6f9e8bd,3fa3d370,529469da,7c790885,efa982da) Z8(710191c0,50ab2623,d8d23179,838541da,c5800ab1,bd6a5330,e899bd2a,e18580d1) Z8(62e2fcbe,8f06ca99,0e4def12,e83ff630,fea264f3,2ae786ae,f5df6929,666274e4) Z8(4d007241,b71976aa,5d89b385,fa784db9,acdded9f,43402be3,daabf4e8,271920ab) Z8(e35e3126,8e953fa7,44b0c00f,2efc9cfa,2c1de10c,24c04c53,fbbe1384,80b3d717) Z8(f46e0ea2,938e9e47,3900bea5,d3afbe07,4f4d2510,a164fa30,9edfd6d3,febad840) Z8(c404188b,e2e71d1d,d0ac1cce,5cd27722,c857e447,a9a4e462,302213e2,6f98987c) Z8(0a336d94,39549ef9,f0d16458,5b047ae6,ec69f6eb,0f752d86,799b3c44,c539d47e) Z8(f2794f46,7cd35101,1368e9df,b3145365,b5869d41,fff938c1,978101af,07e24ed3) Z8(9c2251bd,324137fe,c024ca40,f20e5a67,84516c34,eecae227,cf35e8c9,021ff73e) Z8(86055c6c,ba5e976e,787da722,19053cc1,ff83849b,3b93c4d1,bd44b744,93009410) Z8(0639cd03,a5214273,cfd62755,bb1253b8,98d17474,f607a5a0,49b7bc5c,9b1d28e3) Z8(780708f0,6bf8107e,216d8104,bbfc0f29,fa3eb9fe,3560d91a,74947fc9,90020ff9) Z8(732bfe8d,52684573,a89e6738,4f348342,7f779c7f,251dbe5c,222cf016,687fda9f) Z8(6de2bf99,13d27d2a,91af5105,36cb901f,646a9a13,181f6eaa,079cc034,473acdad) Z8(77dd652e,e3e22501,4024bd33,96f27719,2d938989,3b4f9392,a6d50df4,c5f01a8b) Z8(8546f104,7c499967,8e58bd9c,5bf178af,52f731a4,4ddf0b2a,ecb8390b,712fed65) Z8(c8592854,2172cb96,9e38e1e8,897232b1,efc16d38,02742504,d56df423,3eb2ec63) Z8(b5cdff18,8ca727ff,e401bb41,e2d18c23,1282e091,674e9f16,6a7f4e6f,ab02cfe8) Z8(40c0553a,3ae1662c,5188b182,69ccc617,5ea8931b,57be5814,cd717988,f5b2918b) Z8(03b0ce4e,dbb93120,6969ecae,e22334e1,115ac805,10abea2b,5c4997bf,eef19a9f) Z8(b710d889,a6b2f057,50a80170,35409450,3070ac04,faa2eb99,d6ed8419,857ee505) Z8(87f81cb7,691c9f69,36d659cd,2d681486,85dfb6f9,8b7ad15b,cc19df9a,c9ebc639) Z8(70ce381c,4df36ec3,466dea5b,b3ab97d6,19a5ceb0,230b7349,589903f1,8ff85ddf) Z8(7dbdcd4a,dc8a54fa,3225170a,3bc0e4ad,1f00b519,f88f9dd7,dc352406,a549269f) Z8(cd078dc3,a4381f72,b8b0a80c,53f249ae,bd3a5b56,646f3ea7,2dfd61ca,1275bf0a) Z8(fc4be8d2,96901301,1f1c2fa2,599e8914,d3ca89ad,5506757d,c2c23c0d,3ff77bbe) Z8(e0e10639,7c3ba00d,39f63f00,3d15255d,4608453e,436f69ee,08557697,9d3b4502) Z8(4730a873,c0511349,42b7624f,88d224f9,04a9690a,2e486b6f,6febc5c1,1c82245b) Z8(f3e13254,9f27e43a,23aba80a,b61972c4,02efdb24,5599d1f5,7b648343,813d23c7) Z8(88c99668,981245bb,3bb44a0b,a5af62f3,59cf7011,a124221b,97566b20,6bd7382d) Z8(1a042461,dcd83ead,9cfe3ce5,176b3f51,b70dfc13,15c62375,0a36ec2d,283fa20b) Z8(08edf53e,4beffbb2,37cd8309,cde8c10c,6f606b14,b4b6a8ed,5c1070ae,23e6abf5) Z8(1aba7bdb,98905887,e9c5cafb,9a8e17b9,636d1eb2,f108730d,ae252184,aa55ba8e) Z8(2b073aa6,8f807db7,8654e88a,4dcca0da,7599baaf,eacd85fd,c73d9a75,447161aa) Z8(424cf602,274a9bd6,32be174f,501c8d13,c44d85ba,9e05e1a9,b089cc9b,eead7aef) Z8(cd973439,2316c0dc,0690a1f3,46da2374,70357fe6,712725f7,d3292acd,5da5010e) Z8(21c0e188,76107e9c,96543df4,72989d97,09521404,52a956ee,5d7d97a8,bdaa0900) Z8(7123f7c1,b912de49,3b27623d,ad069709,a5c745f1,79712589,24f1c98d,c38801db) Z8(fa108ad6,68743d53,97706b2c,42ec549d,0ca67057,2b29aa7b,8e487384,c3abd56e) Z8(567f761e,c9a0a856,19722fab,e83bec7f,d1f1f650,ae0d3b9d,49d23e34,0636eb19) Z8(ad33a1c8,bdbc42bb,25a6cf17,d83673f7,c6d1113b,5575e890,fd870f5d,cd94f8d1) Z8(4059787e,3d736fa9,7f2b129d,e53626ac,db1ed883,e75d458f,f922e250,fdf95703) Z8(f72483cb,f62b2fc7,1a11eb8f,bdfe158c,5fc907f6,1c293f68,1a5ceeac,b757b0f9) Z8(a37c6987,969240b3,e58ab60e,8ba172c6,4b332069,a5ec417a,579d86f7,a837df05) Z8(e858b7bb,53b8b60c,89f10a5f,fb230dce,6fa6263d,32a8db37,f6367dde,e5458e28) Z8(0636ada8,96c28fae,6aad3ff2,db8b6a3b,003562bd,c8d77356,7ede1f06,b5594e52) Z8(f06d9d39,bf727c08,ef145876,ba950c3d,8c85cce9,2bdfa68c,b603e9d6,7ede721e) Z8(262e556b,75bdc115,ad789318,7cd26e3b,9c5a214d,84825f3f,4821ad88,e52af8da) Z8(73797e0d,f2e10e9c,b2be81c9,ac222c88,152b0e16,17ce4886,a7e7dbe8,07e1758b) Z8(80524efe,454879a4,505b29fb,bb1f61f9,48ecd832,4325b6a7,c4147f4f,d25eab3f) Z8(a39253a2,5e52aa44,3ef6ff1e,bc782900,dec49381,a54b709d,c9380ac4,0f797f38) Z8(3e0df34a,730ceff8,533caefb,82645526,9abea011,6fbde1ba,a2208942,196adab7) Z8(b00f53b5,26e4a2d0,a9f58885,b84c7c8b,b8f28691,47f64841,220089a0,9dba738f) Z8(239a15ef,98090186,de8a7020,96a04a15,c6b10667,a3128437,0e55e016,1b3b3f2f) Z8(544263dd,a310d393,4a03145b,9b3f31c4,e900bfc2,8536c1af,f9f2f5dd,bd06feec) Z8(55e05aa5,c96e39dd,c4537767,66918b7d,8ae56024,53e2920c,a64c57f7,318b5795) Z8(a2d5f73f,cb0f5cc7,0c8faff3,3fcf0543,81c55f24,7e395be9,f7cd62e9,85c68ef9) Z8(0d272ce7,f2fa70d1,f5579c87,8f732dd1,de487d6f,eaad0b8c,ff18f425,5e63e5ef) Z8(2f29bd18,0b360281,ccfa08d3,1fb346ee,63006920,4dcac38b,5233426b,aeebb506) Z8(170ebde4,05268f9f,202df2a5,fbc4162f,2ed530b8,943be3d5,6145d9f3,516697d1) Z8(50eea761,c3d175ab,7429163c,1dc02218,4c90927e,860e41d6,b5c49f85,8d5e05b8) Z8(4a0d3863,98747fae,3f2527c5,7c09e6e6,3b93d9e8,661f83c1,d181f371,7dcd1a6a) Z8(17048087,71c6ff3f,f8a13fda,f4a3a2ca,f981573f,085feac7,b0f5f63d,e40fa605) Z8(53373b0b,6ba755cc,36cbe753,c0e5c623,89452be9,7ffe4a37,02cb4e66,291ba851) Z8(be972b16,a26878e3,9173e475,c2380999,3a75a8e7,01ddbafb,c62d742d,3ce3a85c) Z8(eba0c1b2,ebd230b2,0f206011,00d2ef92,0c126e90,6f2229df,363f9874,54c8df70) Z8(e5e9e294,26e9d675,6e24e54e,0098d942,6da5d965,c7169dcf,9e0a8563,ec2db046) Z8(b31ba9e2,421b1e6d,bfc4b5ac,011a231a,679bad92,24313528,a81afbcc,22c74166) Z8(9d61e1dc,bc7296f9,7bfb943c,7b5471bf,f784e940,c5aaba59,fffed1ee,6a8d5aa3) Z8(cdd14393,4e76c420,a8d7e6a4,b4284232,0ff2a8d1,0e7b0cb4,fe39f8b8,091afc64) Z8(f49bfc88,7afed6f6,53c4f243,96e56c19,cd95f46c,73f42f01,e968a65d,6fcc35db) Z8(0547e284,4192abdf,a5489a2e,813fd150,8bd78a06,cc14eb88,d8feadee,56819174) Z8(3651bc64,9ad449a3,86a9ab06,00341387,cc711092,a5782d24,701b00a3,7d8e7da5) Z8(f49d15f8,0c3f004b,04ac4a3a,1d4fd4fe,38255c44,4ee2d3b9,93c83663,de330ac8) Z8(23242aab,04b89e4e,2cfefae7,bb8aa63a,74aab751,d479bcd3,9d8d1ba9,ffb2a307) Z8(e77d653f,d8b1983e,f1307588,5a97c946,569a55be,661de221,13a768f0,9f1b5e72) Z8(902ef8c6,58a4a252,52406d87,ad9cf441,65480203,37a0e1e9,7fd93a2e,559ff47d) Z8(4c8d5215,5bd71d1f,a83b93d3,4e506170,97d13875,03df3622,e151df1a,556c6aae) Z8(cf931bcf,8a1a7c0b,67e1cb04,9d8d73c7,dc246210,7b66f121,fec7125b,51230001) Z8(d3e8f91e,a9d25c90,b2e05589,8ea29b35,1a2121b2,90da2a58,6f12f9ed,ccb986f6) Z8(716fd0da,e5b99404,fc5b8f23,3e7a545a,e0e1fd19,d1fd1bed,976c0199,14682872) Z8(4ac8752f,960a5413,0e6a3cc6,62a19b54,eed60084,b28f3df4,51422837,6b04a4cd) Z8(b02aad01,d0dec652,762c8a43,69748a1f,4716a26d,62bbce54,18408143,3c14d163) Z8(5380fc89,fb282bc8,cf6713a2,6de2e902,d87c1b1e,6e0ee632,41ef8d4c,f63a4a92) Z8(76ea1ea5,1bab7979,69dad99b,d0b0972b,e8f245ec,7b7f2836,b92a4ff0,831c2f1a) Z8(62a58184,dfb72847,d64840f8,f3a01315,8d36d95d,8394cf93,65c6fed5,6e32adb1) Z8(e89ae6d8,1fe96403,6b4a0796,3e239ed8,b2063f00,f3214bee,282b7317,f83fac8e) Z8(627c8229,8c069722,a6048960,8a376184,8bddeb44,42b6191f,6890f36b,906f8ec9) Z8(44cf655a,90ead655,0c24c74e,e9627fc9,916ffb25,28713e3c,760bd3f3,9693e1d7) Z8(4c5e0f0f,95050137,a21d1cb9,ba720644,c6f872be,8928302a,6a26b00b,66547394) Z8(607000c7,fbcc75f4,4f6638e9,eb8a93b5,dd9400d8,edbc53d3,b64de2db,b5775855) Z8(6ef524f4,888a1ecc,09227c50,d87bf90a,6cdcefd4,157ab593,e1ddd4c9,95b4b602) Z8(622cc639,a016eb5c,401364cb,aca65b30,a0aec251,4b1a434a,1986884d,bc62181a) Z8(95c3a337,0c5c096f,0d386a5b,3b91a99b,1fc0a5c1,6fad40c8,2e85e7ad,d6d6ac6b) Z8(ba9e71b0,a39283b7,0b45dd27,6fac20f8,046e111d,abd878b3,2ef9f400,a4f7eec7) Z8(1e4213d2,3ef624a4,feda5097,c34e85b9,348c4309,7ae80437,c8b38914,190bd041) Z8(8aba95a6,e4d5ffa5,4c8fa8f8,ce03cba7,f89a8f1d,bcd647c0,34d2d34d,eeb742c8) Z8(797a9c6b,57d08190,94929481,f917a480,a3e8af6a,bdbef089,5bd88e6c,f11ed253) Z8(7962ceb4,e6e1cade,9db63c13,6fe99ea1,ef97e327,fb8b25fa,0d95e3eb,63c0d8b1) Z8(249e46c2,50eb5448,8b7dd1ec,cdf41334,c31a6c20,08fca2f3,620f32a6,d825d623) Z8(270c604e,aee745b4,86d41c35,b9dc10fb,a683f736,a85e0974,ee222b86,19cda2dd) Z8(89d822c2,6b2f6b5e,c032ffa4,70dc4f5f,c5fa6dc8,21352f90,399eecc6,0ea0b745) Z8(65b2ae7e,f38dd844,634f0d3c,ba629d4d,c6c118a3,12549887,4afcc2fb,92e9158a) Z8(8bbd984f,b221afb6,e6db0177,a5280dfb,87cb2f75,1d893663,a5b470f8,4b473748) Z8(44364124,744619b5,e30cc63c,996d9ce7,544c1e09,8c07c857,fae8308a,45ca60ef) Z8(94a9af74,8a3a5a1c,159a7049,4c0c6950,703010c2,ba626a84,501ea295,df7b37cf) Z8(89bdc6cb,9cdfe9b1,2bf94ae3,291a3744,ed1660e1,4ed99d45,c18e44a0,5ea2a289) Z8(7136a1d8,a7afe5f9,d9cf0f08,07358f85,04837218,0f9de99d,4a3e605a,ee277b86) Z8(64709497,ead451ea,99def992,38c92cf1,d0900126,9bfbe4a3,86ab3852,74c5f0be) Z8(2902e218,7f5ecbd6,a8bd5c73,ac0671bc,5075a3d0,ddf87b9a,42195f70,0b05bb90) Z8(cb257300,099a691b,e0e4371f,d9bfba0a,26bd12c7,74697af3,0dbc32cf,19c2f56e) Z8(03df8d64,45adc4d5,da125dfb,2e1f9161,06c258ce,9dbeb359,e7082cd7,80a59273) Z8(5812a4a2,8ba18dd6,a14cc22f,cde15de3,beeda686,b00ae6d4,d83749bb,a94a7177) Z8(25bf6822,caf47c3a,324dc2ba,47515a2a,002d2445,c43c647a,a2e62e4e,11d1d3b4) Z8(5c6d12fe,4989973e,f628bfb4,62227827,f849353f,5544a556,c46f57d9,5f1d64bd) Z8(53dccf96,8d8916c3,a61dc8b2,560d792b,7061c43d,01209655,61f9d5fc,8c6bb70b) Z8(26202855,83378405,338c9c42,5b265795,335251a0,587ae378,7bd925dd,5a8877c6) Z8(2c06c3c2,112f161f,af8df44c,c4e83582,61e65e76,95e06828,24d8f5d5,2750fd22) Z8(cd066f77,1bd7f6e0,f7920027,6721eb63,fce8785c,6a2a4488,0ab03033,60a265d5) Z8(18f039a6,a036a529,e1969b3f,ed3d8383,905e519f,0a9e7ab8,9f8aa1ef,8fe47dac) Z8(020ae2fd,a125ce9e,34fef9a7,d4e77816,a2138074,e29661c6,685a7b76,2f9a93c8) Z8(5951094d,7f869658,aac95376,5e023399,f66b7f29,551c2920,0c7bf813,a59126c3) Z8(c4795568,6072d800,dda81ce8,77977769,21f1d0b1,3359db9d,8533bc39,a4d5e97b) Z8(e7ae833f,73302f85,ff386a6f,8e7e8c43,cc6f9b33,20fdc4ba,eb135134,032d8cf1) Z8(bb45cf31,9a2c7cc3,418ee32f,f6f1201b,3c3d681b,2382b2f3,6d8c922d,f61bbaf4) Z8(158835a6,8c2fe866,8d3e1a92,45a8c052,6e061630,4405e012,5521f46c,7578c723) Z8(fc19ac64,aad634aa,1d1dd46a,feef6f87,004e721d,c01fa38d,4e7f9b10,04302593) Z8(039f36d0,13d11db7,57adbd5a,fbcbd8b8,922f5eda,059ccdc5,ed8e15f2,283e9a67) Z8(7ae1d410,33c258c8,e392a82e,9491a0a4,0e3e2eda,5be829ae,040697f9,af714338) Z8(8c256305,f8d7fdc1,8eac7d19,0441f702,5f9506dd,019245da,40e10b34,dbdeb1da) Z8(d6503fed,ed577f29,57808b65,2cb8344d,5ce337d8,b47c6833,49bf5bfc,83acd365) Z8(6d26e729,9bd721d9,19724fde,6a6664ee,291a064d,ff949d3e,7ba11d65,25875130) Z8(fdffcf18,aecb4366,0f5aada1,fef1ab6d,6e6f4b1f,ca88e98e,5e04b492,a321876f) Z8(304095b1,161a0384,281eff11,0bff6d1f,396fd0a3,90284c3b,74e36f63,8518235b) Z8(cfe0b28f,5ba00fcd,b61f1de9,4cced297,cb281b73,477a6c1e,b56402e3,8a978309) Z8(0e55c559,900b210f,735713fb,4930a4d5,afb63241,6d6056b2,37bb63fa,d4e8da71) Z8(8bc223b5,037af640,9693d21e,4d009f5e,cc80cf26,cdb726b3,023f4dbf,6ed2bd25) Z8(634d9928,25d758a3,7fb7027d,e256ba8d,79c07867,af868ac0,9059fcbb,0cfd4cc4) Z8(5f96f2a4,47827691,3b064822,bbabf7cf,75c10f6b,266b1e5e,37f6cb84,34090f70) Z8(1671dfaa,521185df,d6a309eb,111ca154,1a6e25ac,a15390aa,a220fcfd,fc57326a) Z8(18eb6f5c,3cfc7fde,bd55a681,a6fc721a,62656dc8,de36d26c,1a837770,63578531) Z8(cc99ca81,e705fd00,9c635996,f21a28f8,087fc076,d2ba8d43,9c16be2b,28fd7f83) Z8(7ac486c5,eb631523,21b9f6f4,dccdf6c1,aa40df50,7fdb2747,0f80640c,26ca6322) Z8(bb8fc7af,b6662f95,372d0f8b,bd1777b8,563a2575,a656d499,e97d7d57,bcc27280) Z8(4a318c50,e420663a,c840d3b0,9365bb44,8b9d155d,20e8a53f,79ebc6b7,48f82af4) Z8(31c96a0a,22ec4246,8287d2c2,dfaf9214,1087a33e,92c92350,8880aa46,43515c60) Z8(7fb68a58,aa93145b,6220a898,6de91753,0c57bbde,3c892e62,38706560,92ef3972) Z8(d301aad3,fc82d2dc,97806abf,e9d115b9,9b176573,0c927165,6a3cb503,6ee1359a) Z8(b0b16ecf,f657f780,03b68478,a3f7a935,a593199e,a3b434fc,1a4d6ea0,39fdb8b9) Z8(623fef98,7fb7947a,a91a1d7c,d5eab813,025b3fd1,a842293d,8ae7b398,7b4d4b6e) Z8(f71e26b2,59ee8214,f55ac98f,26714665,e24c0c80,340503df,d6ed94ea,12e897fb) Z8(b92a2b95,31fdd14a,fb08a24b,38254794,c64fe437,1dbd364c,857ea8bb,ee4798de) Z8(c461b00a,85d5753b,54cf5fb8,59e4bb51,c2078022,0a28cd0a,32abb5c5,6eb32e38) Z8(9fa7eb6f,bb76d3be,ba27fc00,5134403f,abd8c97f,54669238,502ea8e4,563591cb) Z8(d34cc34f,e65cbb8b,b8ea57a8,ab219061,17c77790,ca2004fe,2caa06a9,19256df5) Z8(dfa1efd9,5ff3e937,da731fa9,3b359cbf,62c03724,b2294e21,65f1aa60,e3100cb6) Z8(2b5c649e,27e16eb8,95b86ee3,24e9da5e,3d12f371,98434f28,63cc4aa0,7a0e0537) Z8(7332dcee,09c5d148,62d58e02,ea47600f,5a39b742,25e3208f,84a0be7e,c5b2fa00) Z8(30bb32d9,4d5af477,a8f6a343,d0614ee3,33327990,a9900380,30512208,2a78734b) Z8(941297bd,67bee25c,1dba4a80,389b38d5,d7a18e6f,53897349,f2c00033,9fa9eb4a) Z8(8e4a8c27,672a29ec,cf30e3c7,a49a5d25,e4d63fe0,b96cd567,6e3d45be,2cd18b41) Z8(cfe59545,62e080b2,72e4c638,4571797c,37c44ed0,7cd1d1a1,8131d90d,0df056cf) Z8(c5462dbc,540b9fb9,e4521e25,8a098b25,92061f85,b330e89a,6a73ea75,909dd777) Z8(cbc30e09,0c27d6a6,d9a7babe,a668077a,19e235c3,44566edc,9f402cac,687a909f) Z8(247e88d5,dfd205f7,af0b6e8b,14ef6687,9594f6b7,11709563,5cd5b2f1,ca5f9594) Z8(f1058e79,e04ecc00,1dd47f9a,c9577682,a29ae593,0d7a5e16,9deb14a1,18aa3fef) Z8(0088cd84,648ec802,cac71dbe,2cf29060,6c274143,df4bdf11,3e7e9971,4eaf842b) Z8(92363865,5b51b787,d9acec17,a827a841,3a777bfc,e58adce2,23859641,aabd438f) Z8(8ce9a5b1,7814bdd5,1ba3f206,cf8964bc,fc142b62,bebfd5eb,b70575bb,fb445441) Z8(f302a6a8,c68b63c8,853c177b,d50cb98b,8bbe3744,b1a14f1f,011c14e4,31ec7af9) Z8(9b9c6868,b6fd3f9b,52e636bc,da0fec92,f40b434b,6fba40a9,6f133860,0ca30121) Z8(b9f4dca0,879ccded,6549e1f8,34c889a7,7ec9468a,383b1fc9,391c22b7,8f1b2b38) Z8(cf88bc24,37489b32,f5e64d6c,6e6e7c27,24aa54c9,be1ef999,d0c03cd0,b4b02aa0) Z8(be6f297a,c3888222,f17c5085,fe7a08bd,f44c8bd6,746f7618,e20ea9e9,a0c45505) Z8(304df305,b5eea4c5,84adfa5d,9e77e2cd,5837d25f,a2273a88,9eb75948,fd6ca853) Z8(923df237,52db13ee,4f988d10,fbb2caa1,90466fbf,7a75c8ea,5dd39d3a,435db652) Z8(3b9796c3,d79b158b,d3742660,a5be50f5,4494d259,2db3f4ae,7ce70195,e7b65354) Z8(d0bd1b77,3b977044,e90707bd,a59b44f2,20753875,80823269,18d6fe2a,eed7de4d) Z8(f76d44e4,fad69e49,960bcebf,ad42a379,dd3ed328,e748209c,caee1cbd,f106b1e2) Z8(29e322c1,ec0c8beb,9158b2fc,864c0d45,bc37cfd3,fc85fdf1,5cd280a3,8aebd95c) Z8(365e38f0,820e1a55,12a80d1e,7d9c47ad,c40f9a60,6ad83b3a,17cf8363,743621d6) Z8(3cff0be7,bee72213,46fc3f7c,93adaa7e,4b17da6b,bcdb1528,e78a0091,6a915482) Z8(2bf17679,aa5488f7,3f3d8af1,33dd4bbf,9acb29b2,b711d45a,f274aeb4,4f267830) Z8(3ef8e1c9,8e31790b,813bb19d,705daf8c,8203ad3e,ad8a0d86,ca9e402e,8c7bdb6a) Z8(c32ef618,a0ceda6b,fb6ed5c2,7d814beb,46dbb906,6250ef02,fe0f6a6c,eec1c0cb) Z8(7ab36ff7,ce701644,cdd7090a,bc4d613d,7481f83e,97b8393e,d028388a,88c5c9dd) Z8(a49b7ec8,a4d4f74f,f42477c0,c61022ad,ff508686,e136400b,3b979530,07e966a9) Z8(f85402ae,54b36be4,038de0f6,818a026f,808c63d4,42ac08d5,a8d9919e,c7ada550) Z8(cd81eeba,0acd0548,6b4d7396,5b5b2b1d,229e0d34,23434d91,448af11d,bc5df138) Z8(af265635,a466e08d,2b05340f,f9a50e18,3925ddab,3e4fb6c8,d9f26235,9a4d777a) Z8(3839adba,9815fba5,d9df0755,b67a2354,d20bbb67,de1bb1ee,b0da9fdd,9918b6ce) Z8(c20b20a1,fca992b2,aab0beb3,230d2f86,4c2cca32,f7999eef,166a62d0,fdb10a3c) Z8(24c484c7,dc60fd03,2437de2e,722ab150,17981405,82637471,d9e7fb08,d1fa2a46) Z8(49b9369d,a1f46f2f,46208c43,0a4f3a86,99b64c6d,2b6ad99a,b48dd161,ae6a60b3) Z8(aeabd842,bde0679c,2380c922,976a1e75,93168ea1,1a9b31be,e1b2cb46,94c56a25) Z8(929236f2,0d5f3128,576af2c5,936d7f74,7a920bc3,07c6c45e,0ba270e3,2e408e30) Z8(1f7ada45,ce29a409,4a033932,f82c9a99,fb3a6cb7,44c1b2c8,6f8f8277,8ed23610) Z8(9a15657c,b0862b25,e4f6f615,4d47985d,c858dd6e,ba18121e,77787233,1261ca22) Z8(c9d15ec3,1abc4752,02144900,70765014,b72d9c4d,7d4613be,53adad2b,92334314) Z8(ad402231,f9bfb9cf,17211cbf,713bab68,010c9524,369e13d8,3c306e45,2b032f31) Z8(a2417925,b70defe4,30c578ef,7512a2e6,51e299d1,c6157154,b6622fce,fd673540) Z8(cab2bbcd,1999016f,15783201,2c45ded9,3e938b76,3c4e7945,1dc47c6b,388bbf83) Z8(eccf1bd8,84875c39,a0151b9a,51e8069e,6eaae180,50a55c6d,6c8265e2,bb1cc0fa) Z8(e2ab2b6b,680363f5,18bb0826,2735e4bd,8527cbfd,ec2f306b,52f95fd6,fa4022c3) Z8(11a8dede,dd95778f,e24523f9,17c9fda5,41399cda,64754bf3,e077c214,5c9093b0) Z8(dc2c16aa,ea3612b4,f2545644,5a3a254e,5e11a573,dc27eb90,d6215db1,e1af90ee) Z8(d84418c0,963f8c0c,f455070d,00f90d91,334660d1,0654ca9a,a72d8bb0,f06e3989) Z8(c7a402dc,35713543,992e0544,d7164cfd,e8e9c716,ad96e2f6,6a0e37c0,56a97069) Z8(ab9acde6,e3802114,8bdeaad1,b8a3b3fc,60caa9d1,7e706e52,1c388e17,7c2efad4) Z8(8f8c9c55,969ca9fe,72b4c292,d3cf56e9,f27303df,d559cc12,451e56f3,a5852c8e) Z8(417419d5,a20a9cc5,ae739fa2,b1113f5d,a94dc1e4,a2fafdd8,1a350afc,3422a695) Z8(dde7772f,82f97329,6614dc88,d67e4cbb,36cb1191,5bcfb591,c98faee5,c65d3034) Z8(28b8cccb,3e89e88e,031672be,9655de0a,26106812,c112b1b2,a3ef7e90,75507475) Z8(bc6639b2,d837b311,29d482f5,a96f6e43,84055efc,4677754d,316c3a37,fd33f258) Z8(f882291f,1735e719,2ce6e7f2,8d44c44a,8add33f6,8a6e5866,a7857342,eadb8a1a) Z8(9981523f,b9dcdcbf,891cc8dc,e64282d5,5fecb3ac,ed2840f8,f924c821,53d738e7) Z8(85c997cd,eb88277c,ce125fe8,17f6aa1e,2676c88a,1be9d8e8,e10b7989,77977ea5) Z8(38f8aae1,d605244d,a9e51b62,9efb5d17,08c0804c,47d6c2b4,286a1bf7,e22456d1) Z8(9e9bd14e,e1a3c61f,8be919a2,2e1af62e,c1b5a523,7922ab2e,a6bf3685,ee26ed17) Z8(d8684a11,d491182d,7f7176e1,30176923,1eb94c60,3720b2fc,eebdd349,27816341) Z8(f1ecfb73,d08c2f8f,60be4a6e,01fe5481,a0e937a5,98266955,82529290,f2cfdaef) Z8(84d6b5c6,a94c32c7,635affa4,960d822c,d5afc34c,ec570a5f,34695a12,6478a993) Z8(4d832eaa,f38b1d5b,d3a829c8,f19d7613,c08d53c2,7875e720,345762d1,dd5020be) Z8(15ed8308,14c1c4aa,b56c891f,9e7b5e14,4f251692,4531a3a9,89d599ba,ca1acfdb) Z8(04f57918,074061d1,e2256d7a,6ca4258f,120f70bc,33ef05e6,c3da0a69,46fd6178) Z8(9eab1817,df0722be,70b7933f,70a5ad61,1d70f001,12baab88,ff30387c,69b4734d) Z8(f5a88191,c7d95cb1,af3af6eb,8a4e44ea,45b94188,c2663b6d,159a547c,ab71ac31) Z8(8e64dc92,8211d5e6,c5525d44,13e62232,e80ae705,640e56db,60ea1fa3,8c78ca8c) Z8(9d7fabba,0f41c568,44983036,ebb12e26,44527f11,f7a44fb7,cbe0d63a,11bb952b) Z8(d16b2429,a222e3d7,8affc27b,dedd4b6b,c523abcf,459abd6b,ed23179a,a29b7401) Z8(4210f18d,7b94915d,4db2a165,e09a6496,d5b9b4a0,53d10fb9,8f0aa441,65a61d1f) Z8(be3e0160,df71c137,8f89c578,1ccd504c,04a12c0a,80d61890,f8f8b67c,8c652fbf) Z8(87a6427a,715dea98,cd53a354,0f396334,afa686a0,92942826,a0b2a889,ede932a0) Z8(52f5ed6f,d865e852,2b1905b5,bae3d71a,f7ac0bf7,752520dc,38bb5422,4f61214a) Z8(9ba8a740,b67c4c40,4b8baee1,7f076271,e7be7261,20fae518,dd83de36,2a7f4d9d) Z8(ad1809eb,44300e09,f76ecdb8,03db5a49,25f3442f,0a93735c,3be94f05,60f32084) Z8(54ece803,d2d7e2e1,2ddab7a8,9ef6689f,8d56aca9,91c3cf7d,bca38690,46e5a728) Z8(633e5b8a,75bb351b,6e05d50f,6b693903,75725b3f,535f4476,2cd85e63,a4cbf5e6) Z8(40a06294,35e9271f,7298ddeb,737c3a28,7a86763b,0afc8e77,40d0af67,f924d5b3) Z8(1656258c,40bd8635,714553bf,6b02288c,720e7a9a,846177bb,381ec2e5,b8e34718) Z8(bfc70616,a8da6801,cf283b57,846928b4,023c7292,48d4f10a,98949a13,731720c9) Z8(e86c3b19,0ae0c9ad,01331577,51057f86,2d122d03,d7bb714f,9dda9810,a7d7e4a3) Z8(b2f7ff77,bcb04996,e2b65d3c,c0ac9dd3,5ea3e8eb,cf10c372,fafce1a4,d8dfb65a) Z8(4093ab9f,d12a8788,31704923,5fbc6ac2,55608d43,42c6a7de,ae9152d7,8967c729) Z8(54b464c9,8d7a3ccc,35a4a700,99dd5e63,c095f4f1,82937ef9,28d4f197,35780668) Z8(284e486c,580488ec,7deb3043,685dbf85,542952c7,1f24e246,ddb11b98,7d3de5b7) Z8(56cce2fd,556f5646,0eade45e,01ee9ddf,8bb04c53,604ff8ef,505f450b,77a8f82f) Z8(9c6db302,54cd100e,c13829bf,e99833a9,15f0f695,a16effb7,1f250a2e,b0555c2b) Z8(44fd2c6f,cc35b22c,bbe0441c,22e7f3eb,c575133c,2528b144,aa033fdc,0d51a93b) Z8(e0473a9b,279e101c,f9a50e0e,e5e5dc9e,cfc0c6e0,08d55816,159759ad,011330f9) Z8(5529a8d9,b16df326,6eb86363,04818720,8daeeb68,0d38f3f0,87c09b04,c95b91af) Z8(78e87cc4,79b2ad0b,d288ff93,96997a4e,7400734a,9d66d779,1ba1f8ee,f54a7b51) Z8(e38dc379,f1adfad7,c02446c4,d287abff,d78dfb56,54eedc77,a313fd01,bff717aa) Z8(f33f80ad,51a632f0,497805a9,e9019868,19486633,4accc5ed,93418c07,f99c402c) Z8(721d44d7,6d1324b3,3767a410,f60df824,d7b3e4cd,ba342453,4b39957f,48e1514a) Z8(aa90b815,5b56157d,edfd7460,5828dca3,02d68ea2,93231e2a,e3f12d86,7b92e9bd) Z8(2e15aea9,9d5fd4cd,7c236ba2,f18515c3,20d80d05,48dfa910,7715aec0,91703da8) Z8(b7719cd4,252b0a18,487d6fa8,792f0b35,8694580f,979d8b84,dd7433e8,02f90672) Z8(8acfd937,4ebf5a18,62161ec9,2cc661a5,1d0b8ae1,0f5d00cc,7ba2d37b,43b84dfa) Z8(d1bfaa37,3a897964,a928cbda,0480de58,60fdfb74,db407de1,8aeef1f8,261fbf43) Z8(4f175bfb,32070075,b88c45fa,8c78566a,f45bfebc,d780d91c,b9f56f5a,1b30402b) Z8(b823d10b,b005863d,a404cad4,8080d124,5da45544,96231d82,9d51a007,151b1c04) Z8(42c65ffc,e3aa22ab,99206756,23a9bf00,336ae318,5631549e,5e19eb01,b3723087) Z8(d0e6a1b1,80ee4d2e,af8ac680,7b8802dc,4c9fee5c,c7d8fc73,45c71b8b,776f2dac) Z8(cb44c322,60255eaa,6a1dcb9e,a3f2143d,ba350248,c8025b53,4e6d0155,d958f0fb) Z8(d898af92,72f7183a,95c7061e,c91f6542,15facdd9,c13e0fc5,317dd93a,1bdf92a4) Z8(8e0c3707,9e2498bd,a78a5002,477a4a65,874ca621,cb544703,38dc6d91,c782806f) Z8(d5f7a7e7,09e1817f,20d37d29,a2cd4b89,9d3b6842,2e18c6ad,030e9b81,d0c90c21) Z8(07ef4bc1,36afff60,49baa82b,fea6940b,25d8f0b7,df870b88,e215f9f8,08450f43) Z8(753eeb56,b0b8043e,a820efd9,04f69f90,cfb065d7,d53862ec,b8c5f9fb,4ae87be1) Z8(edd9c440,91b32c41,24d3e3e2,dbc7f4ef,4353fd91,184084aa,3dff8b49,a95516e0) Z8(8964afa3,7625df05,0389371c,e8089828,e1d9205f,e75c7aa2,3e83dd5a,98dcb36f) Z8(520d48b3,c2b52f7b,27b24f71,f9ffaf4d,54014541,9e963d37,6572d095,e4aa2c35) Z8(5797e494,c34dd16b,47c29223,9775bcd2,2b62dbd1,e4310ebf,6c7e03dd,f76270ac) Z8(4350b749,515abbae,52942da8,703580d6,b1f2e33e,dd4a3e3b,b980c5d0,6af9adcd) Z8(a0262286,0bb25bcd,c28dcca6,32dc9f0c,42d6fa12,0654d793,b5c73408,89bc7fe6) Z8(97280740,c60cb571,1d09bbab,c96012fb,ddaa5beb,10c6a4f4,aaeb970f,623d21a4) Z8(014d588d,9fb09793,8d9b1648,6bcee7db,1c59d361,3eaae9f7,26dc072c,6192d081) Z8(2231339a,f285f63f,dc593213,6198214c,d80bc2c8,1a32062c,96956976,53095cad) Z8(a51c63cc,ac54986d,f32663db,d75a31b8,52655182,b3c7d560,f34e5bb7,7f35ef60) Z8(f20ea1f7,eddcd018,5ad50d5a,701283f3,1d0f8bd6,84812393,19c13064,b95aa971) Z8(140621a0,7a440cca,aab3148a,057d1b80,74d00138,aa7c058b,af011fcd,da01f60e) Z8(59c639e8,cdc0592e,257d00c4,d8710d98,27cbbe4a,0876e36d,36e464dd,2f9403e1) Z8(2e08e4de,9e1f7269,d9209aba,0160eb50,62178979,c4cd4b77,91d01327,d0da47a3) Z8(611a770d,9821651d,5b0e2bdc,fcebab83,c9bbfb3f,ff4cfde7,570ee6df,4973aed2) Z8(94aa288e,7d8918dd,9e773b5a,3e07dcc8,fdd118fb,21d20f63,1eafb197,0cdba2d4) Z8(32fc4ecb,ea68b422,2d9e44d9,42c8fc86,cd40dc4e,7ecfec1e,38b5f023,88bca151) Z8(01461826,7d2ef73e,54d02ebf,725877fc,68c05473,75c97a39,199cceb1,3eaf648b) Z8(d1efca04,38d09f9b,d1fff6b0,cbacb3b0,832abe37,7bfdcfbe,b3a97771,a065422c) Z8(91909947,8b322320,33bc0125,8c7c62c1,18ff3879,7d6236a7,6bfcbef3,99f77ad3) Z8(23654b18,de3c58fb,b257a23a,20bdd2cc,2a2131e6,f449b192,03082dd6,a0b50fd2) Z8(4333a04a,db7cb6de,f8f8220f,67b451a2,af49ecc7,9f10c91a,01f21f28,3a46fe53) Z8(3a0f5164,9503bde5,e5f5fb4b,706d89a6,dba8d9b7,1b2d845c,80d867d8,9537fbf4) Z8(e2c4d089,5a27975f,6739d7ba,13001446,579d503d,32ced8ff,37edf3eb,6fd37131) Z8(9b466c48,5ef5cf3c,808536a7,ec720b66,290adfab,90bc3a04,6c16b12b,cf266666) Z8(f270a207,97e5ff4c,263086f7,9bfa2099,8240d705,6e20a0ff,dd9831e6,36ad0280) Z8(6ea2371b,a3b85a1e,68fd7b13,322c2bf8,6d7d6454,a493fac2,9ebe46ec,dba2f464) Z8(87520ef4,4c8b43af,cb37b3e7,e55ea834,a689f11c,8d51b36c,cca90ec0,adf734b3) Z8(7536e650,5546c15d,0fc72daf,793e8b16,d3f5c6b5,1117ac72,17e7cfb4,7bd95392) Z8(3b9ed924,52eaeb13,ab6bed4f,0a19820a,4147e6a5,31448064,a43b73b0,9acfd1ac) Z8(94b6783d,fe22e50c,70ca3031,dc2f55f8,c3e4a38e,6d82217b,8cc65e80,40c5deff) Z8(7c1f2b65,d01bc922,f6a5b85a,f5e7c780,aae29108,7bf204e1,6cb381c4,508e73c1) Z8(dd3bbb95,a1aa33e2,a330025b,fd7b93f9,041c1d9f,34aace94,e7bc6b9b,1fa3ccc1) Z8(583c2497,2e650722,80a5581e,3f2a7c9c,e501500c,5c4b5b8e,e76bdfa1,95c05088) Z8(13ec0758,bfed2378,069458cc,4637eb10,ab2b3539,4349c047,ef2ee7bd,c630ec6f) Z8(828bdc33,34453bfb,b9343e7f,37904a8c,981e74ec,a86f6b59,d2fde1dd,de9d7253) Z8(93844b59,d29cb3df,1e2f72d4,de28054c,856b5f9b,ce567322,dec08a6a,0d190223) Z8(22d3317e,1dfdfc7d,e86593ea,23fd04d3,5d2417fe,8428f4ba,c12e69dc,7addbc72) Z8(ff5cfa40,1090b562,6bb9363f,231e1f5b,237c8a33,378fc388,2d47a147,7bd52818) Z8(974e6934,9e5a01fc,ad29bc59,874ce2fc,6e04f97d,fd2590d9,f07e4bea,fbbec9bd) Z8(08cea682,4574afee,93b2aa36,4c39d2e6,6ccb9c52,d0c997b0,f2365a46,a463fca3) Z8(9a77d35a,792d7c48,90cd9d57,e64e9d36,24fc8089,e0c61a35,091bca03,ecb57460) Z8(e9b1137a,83a39371,aaa90958,c38caa09,d5d62609,c9c5f4fb,b299c30f,872c2b87) Z8(bab323fc,d82bfa26,fa81df15,ed6adc9a,b896ba82,1aa8b337,b733792b,8ae1cb8b) Z8(7488c870,3424267a,3e6ed740,4476e354,c0a584a5,aa953e2d,dd59eeb9,ba684379) Z8(58168d22,9f6d1d27,380a0504,108f93ad,b8c79819,030b413d,0975e308,b5decd20) Z8(7b02b9ac,d55d00e6,1174ccf5,46908261,1f1b9948,e503800d,313bfa92,59170a91) Z8(cb2ccd72,b85f1ed8,40b70336,caf642d2,dd60180b,0e5fef9d,d53797ca,8c7ddcc9) Z8(9ce77536,a51c8d22,aaf18d53,e84a7365,753bcc1e,7b0ebb07,95b802a8,1a003ebc) Z8(5c7f3a87,386af20e,f96b7bc4,8ef98591,f284e080,267a1916,9878c5dc,9ec122f2) Z8(0042eb1e,5108ba7d,057252a3,e7a7f105,f207691f,f34d8801,90cf8691,d29b651c) Z8(4db2a0ab,ee8327eb,280b550b,a7940453,dd7a724e,ba16c257,2ec707ca,99e7a7c6) Z8(a0d6edd7,3f14a133,70f305f4,5c48aeea,751fde9d,60f36de7,3763fe69,24491e08) Z8(a9daa465,83827655,cfdeaa27,de868ee3,cc4dcc5f,baca8d09,10f61d30,b73b52f4) Z8(d0c8beb3,47784818,2970c6d8,a91ee8bf,1466158d,7b1b3044,60b52a3e,6ac3bf2f) Z8(259616dd,25512c0d,ccdcca59,3c9a8513,85a02504,af5748fa,4ae224ce,d37028e3) Z8(181ee0f8,46aaf820,51c39433,ab926f67,81d5c728,2ad7fece,9b47c83d,f4ac33b7) Z8(4c4783f9,9ba481a1,e6d6830a,a652289e,12acc474,14115aa7,4da61704,87494edc) Z8(c5b7ad77,ec10443b,dce11b0c,c1f589a3,51f59e00,db586065,2408fe1d,77f06b9e) Z8(9c7e0b38,cde05423,e0f67847,f32401bf,4f0838ed,1f518a69,9fb003ae,1d904ae7) Z8(2e18322e,fccdfdfb,2bff2db6,dea485ff,7e43ad7f,0d81b626,efda0f76,ceb39582) Z8(180b91ec,f938d261,d1b15cc2,19165547,89b6af1d,4ba0cfbf,5bd489b2,8d5c8b0d) Z8(3728836e,be14aecd,47ceb86d,4549af3f,c319de52,08e80a14,d1d7920a,245e5bbe) Z8(f4702418,dda9a13d,ca2fa179,74ada683,b97c4918,3ce95a6f,ecc88b13,2466f155) Z8(08ca6e7e,98d10dfa,08c7621b,6a9977b0,ebf7a6b1,3e7845a5,e0dbc28d,1de34ccd) Z8(c78da9c1,123dce18,94c7494b,48be4cda,ed199e0f,a1ac78c6,622a77f2,4a8eb9d6) Z8(9e90f210,31de0bc4,b80c8ec8,2b06caa6,65fda265,69b90d1b,671f7b96,d83211d1) Z8(a24c775e,25502698,72e1d200,e31a1ba8,f899b652,df3c323c,e38e9b3f,77b228fe) Z8(d3fd1156,70fd4139,0e914fc5,d07842d6,9f19520a,509e8ed6,4a395f8e,ccff6504) Z8(69137590,1dbf1578,c54c8b11,382e885b,9f218d96,cd42d4e6,5ec82dd6,1aae09da) Z8(a62b01b7,ab9b1731,d1b7e0ab,f8f42c6b,58d00fe2,5a3b1445,bb0eeec0,24bc8002) Z8(2199aa70,3cfb9675,d9b46106,c7cbc566,382ecbfa,7e2512ca,4b5b2735,81198ecf) Z8(fce74681,3527c33e,ef971965,a9df4a0d,89a9a7b6,0cdd4b6c,65df5edc,2137d0ea) Z8(630c44d8,72358686,fe47daa2,bb3a6f96,6786c864,ef8f3db7,347a5fdc,09cf41e2) Z8(bfd425f5,1ab277bf,de65c3ca,5b8e6ba1,0627a74c,9e8c9b82,d0c7b3ae,a36a5882) Z8(e0b01b48,463c4fc8,93f4c5d7,edb95c21,142990fe,453fb14a,4394cc56,476644c4) Z8(9a23a668,7e6c577a,38bdc4a0,7c4e63b8,b3c16e35,9b39af61,4a652a7e,99ce6097) Z8(290b6935,731f83b8,7df0105a,1933ceaa,6fd94f4e,f3574565,3a14c7ea,7921624c) Z8(756b23db,ef7f966f,1e1023f1,f3b8e410,5a6e9f44,6de00f4a,f6e6f9a0,e7607f9b) Z8(46f26034,23327a8a,ff81b848,64e4038c,a61cb84a,2f9a8c1d,5cdd984e,0c925c8d) Z8(ea81cdea,2626a199,2929bf9d,81488c05,c7c15525,86577831,2b04c310,616f1fdd) Z8(7898f402,a79019a6,0080c7a4,1ebfc564,43a685a5,c9f00aed,da460ba3,e376b819) Z8(2a62760f,d18d56fe,8621cde9,07b84ab6,e012b055,d36078d7,97af6b03,e6a41441) Z8(baf86dd1,020d1c20,6d4e13b5,f1983188,30c754c4,2360ae4a,7d624c00,0e4b980a) Z8(f1dbf23b,d2518d5e,d8e3647b,b49759d1,6e0edf79,cb45a21e,4ce69ad8,74096bfd) Z8(f3fce937,75aa48c8,52188249,87b63c0f,33e9d711,29a8936e,877a941a,cf6ebd5c) Z8(7ccfe177,f06f4429,cf31b1ac,87ee5705,10620d33,3f7934d0,e2d321d0,4b3721d8) Z8(c03b8f49,b46cdf79,228d43d8,368f9f03,da5517c1,013dc2a3,1ce7661e,c857ff26) Z8(751bea46,81faee6d,38ff4daa,435058fd,17338de0,67c10455,d5120103,5d38d99e) Z8(4aa8e3bc,535bb263,ed52efa1,c44397ac,343dba42,dae4d90a,8f46fbce,e8cbd58a) Z8(31a4a929,d20aa71f,c0385d43,b3637ee9,9de04922,2a93dbba,8d365387,d954bdc5) Z8(b25bbb4d,579f7af9,0152e74c,8277cbcd,3f77d833,12da4fb1,9d1323b5,73cc5af3) Z8(68f8f4cb,76f7d7a9,c8b67e6f,139a6bfc,1d622ba2,757dd8b2,5224b055,099cf151) Z8(c87c7243,494f8a38,f369a455,dcd990e3,b2edda84,a73171d9,9a16a0ba,086b05ec) Z8(44e075ec,d44d32fc,27fc66e0,32841bb1,10ed48f8,b6e9edd7,46a3765c,611d977e) Z8(150e31e9,a071f9cf,06aef18e,fac5b78b,c29c79ff,41f99c12,db7e1585,a7a783ba) Z8(9a82b49d,c6f7999a,287eb113,9efba619,c3bd5de0,859d2187,f0e1d62b,6df60879) Z8(304da8fe,7e18e0f0,c76d5c96,5dd800dd,490acc06,d75177e4,675ce1e7,a906b56b) Z8(c65140d0,4c755c6a,90d94e56,fb62f284,f2112889,8936dffe,2ed38659,13e63c6a) Z8(80c5ac2d,0eff7b08,7256a82d,d713198e,deb6bfe5,26ec4b37,2cf1ecd5,7f383386) Z8(c0588a6f,e0e44238,f4ffd6e1,afd85a13,71a8a87e,be91b944,87321d3a,931e6354) Z8(d09096f9,fb477db8,d4b87b53,a8449dd7,ac1acfe0,b86d3076,b9439077,dab131dc) Z8(9057ab2e,b4a4e8f2,f5169920,4d5d5da2,e7236608,888fb623,4745ea64,fabc947f) Z8(35b44a34,6abad3ea,7484f02d,2ebd7ad0,d2cea2d8,6e432762,4022f31f,5cbb0de2) Z8(f9f5bce8,8e3d70c9,3d32baa2,2436b9be,a3672411,14f8c9f1,3bd7aafe,909e2711) Z8(2e920841,d044ecca,cdac3828,cc2501ab,7ceddd59,9020880a,1b11cbbd,6cc7c3d3) Z8(aef92fca,1add679a,b218043f,7192b976,4b86d4ac,d49b34d1,8c1f4c51,5f8abd9f) Z8(a1e5b13b,bc7d5d33,1be064b2,f7f75d90,37445092,58335dc9,3f95dd3f,5f9ecc3e) Z8(5c68d877,9587caa3,01a429f0,a0018fd0,6f8dd138,25e5c324,2e2fd3c3,6a0e9c64) Z8(58d38a15,fa7a7272,e1089709,a86565d6,e0593c37,f21dec9c,486b080e,2506b096) Z8(610cbded,8b493876,8a3083c6,16186ec2,7592e3b3,138e6d25,c55c0e20,c887b711) Z8(77896c91,7e5a7c54,be4939af,375038d3,e2b95c76,ed798f2a,7e692a96,bdfd2e14) Z8(532de006,400a6c6d,0c630b6f,8b109f4a,c2a9b8bb,ce0cf55b,36937885,7ea37951) Z8(f92d351a,67916341,73919042,4cfe26cc,492d3893,1d885956,c741b727,f017e303) Z8(587f79ab,3bdda4cd,d5b16721,696f6f93,5200f1ed,8f4fd2c7,c572da94,23186093) Z8(8d2ce6be,0b70a4e3,01ff60b4,fe061c7e,4ca16c97,1b3c9495,fd11ed48,34e7de5f) Z8(237add52,fae088ff,0460285f,e50ac3a5,d2f3ad70,315708aa,462210e0,45d31a4d) Z8(5e4de7e3,386bb615,27c59ac0,71b37ebe,0ee77bc9,5fb5fe5f,413d9b05,4f36e754) Z8(6e56a720,2e3a24c7,90a9f912,8929c88b,45db0db2,6d86d4b6,7afdeabb,edfce6d1) Z8(b589ccdd,049c9ddc,b12ac0b7,c94829e5,b5a3a4d5,d17d82e4,08a5e627,97930d89) Z8(30fb8873,d6655d63,a9df95ec,cb7a0bdd,1b95a40d,f785fd5e,9abc1803,7d07461b) Z8(3e6e975b,4a9a2aff,b9963359,6f434532,23cd4ace,4598d75a,cba04209,8f0b0a24) Z8(22263ab7,8f3ef602,d61531de,cd5781db,f897f469,30126888,a2bb24ce,e3537ffb) Z8(adddb49e,3c5c438b,dd202e1d,766c0503,27044eae,c144b945,e3170844,cf82f7fc) Z8(038a3476,a59a87a0,b8f22634,f9fe5a38,31c99582,87431857,633d7400,4dd2c4f5) Z8(c92f3349,556cfe3c,12076c46,fae3b105,5597d37e,0f6946a4,a6147a51,a6ab9b58) Z8(85230c4c,a5c39c9c,0c6f9991,7554c807,82c757c3,9f101934,b6ea1cf4,041f9f0a) Z8(be455c12,235947e7,c510a3ba,d5ce92ea,21c24064,adddbcd8,fb85f5e8,8f8b14ef) Z8(c044d454,1488b79f,c6c30e10,3d413e3f,0b3230f9,e120b545,dfc146f6,1a41ac2b) Z8(b2769a93,a337a159,e9208332,3c7587ff,dd1e7c23,fefe0ac0,b33084bf,0c2dd6f4) Z8(9c702421,0c6cf357,d3e34923,b3033531,5268dc2d,3bb6ae06,9581d437,6ac9d3c3) Z8(4835d324,3109b84b,649b8da8,e92fbc1d,ea444a5d,d3816f50,2def51ca,3f3e1c73) Z8(5805bf0c,12fff876,550980c5,0a5f2ad4,6ec61c4e,9a393b31,397378c4,67790811) Z8(46ed0177,a2db9593,d230c2ce,8c2bc0bf,74d81271,729b0ea1,37330114,aa472b52) Z8(54d14eea,7b5ac4a6,090bf753,0d46d356,c308cb80,0f65c5fd,a8ae8ec2,1373158f) Z8(4806011c,872cf023,232ce410,f5b45f85,00c309b3,bfe548c7,ec85c526,d64de4a9) Z8(83b9601a,e725b042,cc4b4204,33411a3b,b97487e6,6dedccd5,d764ecfc,ba013302) Z8(f7e3e5f0,a010ac5e,66993aad,a7c92188,c6c36e8c,34ac7ef2,d64cc2b1,b474db56) Z8(253cbc6a,167c9748,a5c383d1,eb9f9a5a,7910cd20,bf573dac,9674bfc8,8cc3ee79) Z8(9e2d7e93,570275da,450a6703,84c5eebc,2210adfa,3bef6b88,413cab5b,6c8b5573) Z8(46c94f8f,e1c2fcf3,04ab86d2,515bbf12,5196e9df,7a1af850,4b9f6cbb,ff6861c0) Z8(31bea978,ecaf42df,a2258cb6,0f2f2b2c,c5ca8c83,b2a8d5ab,f09edb82,4bd9290b) Z8(abbaed5a,9cf213be,234bf07f,6323274a,7f4b1091,d1b64712,4113a3ac,8819329a) Z8(7123ea0c,f0c15e6f,4a0d13b8,4365205e,86eef405,861f5d00,1634b9eb,550765a5) Z8(33d1c1dd,af0e0aba,5af86606,4b7726de,c9cbe7d6,b4392639,437fd669,36b347a7) Z8(6aa722bf,d0d5b23d,23e7520d,60c146b5,2c00b016,68185efa,95fc7d6b,5bb53c80) Z8(1e00d798,52a62474,ee7268d1,2ad34471,5bb620b4,8f2c9e89,c96970bf,534dc286) Z8(b94ed4a8,b5a08d93,50cc569d,03be6af1,3eefca5a,f16c7fdb,c0e68e0a,a7483394) Z8(4cd35bfa,6b70861d,29ad88a9,fdf5ad3a,7087926f,7f660805,1faf7094,98253b63) Z8(790cba6e,d73951f4,e1e9eeb6,2b250997,72690360,936f66cd,9dbd5b6c,c0c27dac) Z8(76bee1bf,3d99dbee,790d6cc1,8bed161b,f45ec91f,b0439a24,c0a2d8b6,57c5daff) Z8(bd4c7b7f,4849b0b6,02e18333,90319ab8,85af3769,805ca8e8,41d03a42,f576cb4f) Z8(d9566b89,fd97cb66,bf19086d,26c9e817,a824380c,0a07fc3d,9a8da5fb,77c96216) Z8(e94b08d6,cd4946b3,b89f5eac,36521f06,aabdd3e3,f6b275ee,fe231a38,a761d3be) Z8(0a8c83f6,88699b9c,2f6e4cd2,2c4f4d6a,544a6464,a942f701,83c8268d,f2576801) Z8(21fb9ce9,d358ac56,b834aeac,bdfaf51c,b5da4acd,741fcc30,d1072d1b,00fb9026) Z8(08badf33,697abe14,7a068c69,42cd55ec,ace3a6c9,708ccf4d,05b374c4,7d16311d) Z8(fd5d402d,b1004cf6,a8bc4cd2,875ef5a3,0b94c482,cd805bf1,9bf8b125,6d72215b) Z8(7679ad17,e7d589ed,1c58611c,c0054c1c,e45d269a,050d9da6,2942f9dd,3701610b) Z8(7ade70a6,b76a46df,356b0d1a,8d8fe1c2,139920de,5b9b47c1,2986d24b,ca531de8) Z8(5c52f0d5,e70019b6,d59b0845,691ebe91,57e122c8,003229b9,2b35b4a8,ae8c0772) Z8(776119d1,6dd399b2,cb923bcd,052fb98e,2ba05e80,1fe2568f,dbddc609,e937ddd1) Z8(6a475899,84cc47e6,7a63adce,90d1e82b,f352a5d7,90316f92,164caa2f,96b9e7c0) Z8(46bbdce5,fc73d794,843e0993,f2fe5c38,a6ae3b2d,69529381,3de4a7a0,ac731bd3) Z8(e66ac51a,f3657e01,6b7d88bc,5883b5e2,8a6d87f3,32c83827,2e9cc03f,7becb1e7) Z8(73d89140,480e12c6,5effbf80,943ed5a8,c18ddc09,56b3ac87,0f522160,c8e52004) Z8(4886a5a3,81dc5268,4155560a,3adb2b73,7fb426a9,fea8de12,4db626a6,52bc27b8) Z8(07276d82,c9ca533d,29b7b89b,06dc7197,5d879fed,b69758f5,58506420,452f6228) Z8(086e8bc2,70071dc1,b36405ac,e0446e90,0cc7f7a5,2fab8616,71faec92,96d1c338) Z8(cc4f650e,2bed647a,90586864,4694ba03,940a6a53,248ddce4,15a88d86,364db3e4) Z8(5fdcbc07,6343ed4b,95fe4bb2,ce86f7de,c5cc16ff,d978a042,9846ad2a,be969017) Z8(f2133494,7db9f9b7,3fe64299,bde86347,52be925b,6ae1c560,d835fe2f,ce827c3b) Z8(0a170c24,a4fbb323,f6acf6d0,42ce4990,0a13bb83,598c626e,ce20fb22,66de15cb) Z8(5b56edec,1f8f4fc3,76ed5761,5dbb1e69,2ca0accf,4ab7719e,d6b166bc,d1d7e493) Z8(02ba9518,29aaf7ae,6a47d8e1,cd77e530,da1b4709,a7cdf8b8,c6911ad6,71b982ca) Z8(f149733c,433d14be,0f0f8dec,ee7c5e6c,921862ca,91bd9068,b70ca66f,7ca6a0ac) Z8(980cce36,15bd438a,17235e58,a0c02814,267bfeaf,3d052a8e,ba05d912,501598f1) Z8(2510f1fe,75816fe2,a93e16a7,33cb178f,7d796521,acf22f9a,17f6652e,5dd47253) Z8(c5e72196,9b42c377,15e8f44e,b942075b,31c25f64,542a0630,788c6ea5,c8ac3b73) Z8(4405328a,ee74fe80,9c9083f1,118782b1,1be3b315,371ab357,9516f209,ba3902a5) Z8(3da4d693,f2ef6d33,08f3bffa,031ac558,b275ea04,7d1fb15d,e33c72f6,68f5ad6e) Z8(234afc78,dc2c6217,b06cdbe0,ee7798d1,4ac5b150,b942426b,f5153e9f,ca26d532) Z8(4fc16886,0cc1c2b1,f44b0ab6,0ac52de0,e78242da,254802a1,86e8bcdc,b9477099) Z8(0f7a8947,a6f8dcae,cbf31492,7eee200f,ae258a11,75dd7153,6542858d,75f71e7b) Z8(df5500ce,7b759721,5bfe1895,ccb3b591,e39ec991,ae1789f2,9ad124da,8868a14f) Z8(e7a2cb6e,07456f0c,f5be13df,0472edc3,c59370bd,3def6483,5d78bb17,954b0571) Z8(b95ea78d,91bffb26,eb0016f0,3aa81462,69980dbc,95b6b8e9,3815d880,83c117ce) Z8(a053a56a,6439b1f6,7105586b,3985a989,26e6c1df,fa12988f,262a4722,aa0fef89) Z8(fb04db75,f848a2ca,e3176074,1d561252,956d9a6a,dd7d78a0,1a827dcc,eb32f25e) Z8(6c28dc4d,a938e725,c6bf49a8,84e1eece,642ff0f7,01954eeb,352b320a,d83055f6) Z8(47f72d70,7da2a6d3,a11becc8,13d430eb,00e845ae,cde56a32,62e3f081,43200b26) Z8(392d8ce1,346e8b35,cb7d1911,21abde48,e83adccb,9301a4bc,b7764d2a,ed0959f3) Z8(c7ef0eb0,0dd6fb44,9cba8e52,49ac5d9f,50b095da,745f969e,ae8ef3da,02b7c8d9) Z8(9b9532ba,c5b7329c,65849245,c3aaf17a,6b5deaaa,78501306,20cc7c54,20ce4820) Z8(b3ff5cf4,eed3f4c1,1bf1a239,a1967f26,e2fdc943,cd1db626,a27b0d6d,e20a86bf) Z8(d4c9888a,a0a7ced5,b919d049,293c7093,36e4b638,158705d5,d79525b4,cfd73f55) Z8(6722a8cf,ffe57aa1,46a25a88,71d66d16,49b009c6,2dea97dc,63669d88,8e064b3f) Z8(c9be8ada,1f91d799,f865cbeb,778cbdd8,521b46d8,f359b473,4e922221,4f90b322) Z8(918282b1,024873a8,c86b9f32,5ba779fb,1bd16947,895cccc3,9a6f2f4a,8843b388) Z8(8df6dceb,d3b9533b,eaa575a3,75e3a4b7,2ee4aa93,6cfeca82,80677af0,fb6f6218) Z8(69bd8816,a394c8b8,2464905b,244dd334,19cb7c6b,93525da0,1b874f1f,b1afd8e7) Z8(86c0ee7d,d2180f30,e4e39e61,312d2ade,a4225596,682a3b29,ff38a967,a36aea8a) Z8(7a2b3083,6a2e159e,340be36d,aaea6cdc,bf607a64,d3ff39d1,ebdda28c,970f4d17) Z8(fd03dbed,5e183bd7,0782ec37,e0eb2eb4,4f362b62,f1e1f7d5,42344330,01dfb051) Z8(fb7185ce,7bc0d3d9,43f5e1ee,cae6a5ed,cac57779,61b2ed55,8afe5f00,dca425cd) Z8(9c9ea008,ddc17954,0c08df52,0052a097,6cd5a7be,46fedd33,f8bab6c5,285f3e90) Z8(83afe269,702a6cd5,2ea6becb,cab998e2,8049fa03,2a34e63b,2c2cfce9,991c1845) Z8(eba0cc74,5eed6701,20e9909f,1939ff68,098da512,5bb7e081,af26e423,93a6cbef) Z8(c11aac50,791431d0,c6f919fe,680a0ee0,ae63983e,019eb216,df7c02c1,5351e600) Z8(8bc307f9,1ee93044,5c58ea7d,e2810e80,2fb2b4fb,5c8335cc,3133594a,9011aa57) Z8(11597a56,55ac3e16,5849131c,037fa0c2,ffeefece,86b12d36,a8c57c0a,d4912a20) Z8(b656b717,33d597a8,5506c9fc,cc27d89d,300c207d,81391a43,5f93f3be,ea328a0a) Z8(ea95a777,213cbe01,2cd70c4d,8758f8ef,ad300711,5c9b12ea,54550b15,18975b26) Z8(b811f643,287dd141,a9b92e42,e9c01494,25e4841e,6d3d8859,c581aa86,15ba2a2d) Z8(76b5dc2b,153be21a,fc4172c7,aff62580,b9e2ffcb,955eb0a8,031d42a5,e1755585) Z8(5bcb50d5,38305325,5123dcda,d08ccd55,0942f9e4,ed14133e,45ba173c,d80e9b84) Z8(3a828deb,9b49b906,7b6389e9,618c66eb,4f5f391f,c5a1ce3f,e7af2675,dafbeca0) Z8(42640c63,957a94cb,d48a412b,b41c1544,3cb6f318,b61e05bd,d9ce2897,bb72ce86) Z8(cbe41a2b,3b3cc419,c9045029,5872d95c,e99d65b8,14167d88,c0a91535,83946895) Z8(36de1028,37321241,5dfc2732,93802c4c,138ce47c,c2a593a3,dc73c5da,bba63903) Z8(0868fb02,0fb3dc65,51291d5b,befe6a7b,c2869c70,2b4452c9,017ab1d6,176b0585) Z8(60901507,57a454e7,a80b2fff,ef1cac0b,1e418faf,4a341f76,995ea184,b93aaafa) Z8(e10668b0,8632b7bf,176ed32f,4e43a223,1f41b717,ce6506bb,39324a48,35f992f6) Z8(66c67fff,76909e55,48c91f2f,1b5e6948,08c11d5c,8ef713a7,71e3c85b,ccd3e78e) Z8(83a2ead0,1f4a4750,edf859e9,c04aaf63,12b23463,25418c32,7eee1220,1db3a350) Z8(d9aa5ae7,531187a0,b01933a5,1a3f0850,de463ab7,4c8142de,cf3759d0,7b715073) Z8(3ceed410,f545c91d,9f446915,04b26636,5b65afb2,e7e67bdd,495a9559,a3b9cdd5) Z8(36e3a419,c7317837,a2085985,ec7b7153,fb4df77b,d4e9384f,493b030c,4d5949f3) Z8(220f8d18,a6aa093e,6a22e4bb,d35435d9,b1dd76c5,0f47c7fa,baa82641,8fbce82a) Z8(b2446408,4852e87c,1cb50c84,66767c8a,5846e267,6ae1cbfb,f88c9f9a,af4a0fb0) Z8(c41e616c,74c0253a,0e3a4846,019eee75,77101b44,eca53360,2441c349,49c3b3f5) Z8(8b679e5e,5c56b2f2,deaab967,c8cabe90,a6b4e7c3,793853a8,d96a0b0c,22efd10e) Z8(2c1682d8,1a491b8a,82889a61,f993f6ed,653299e4,0b55d51b,ad08cc4f,e2b3d0f3) Z8(0c07d7da,c9ea2cac,e95fde9e,cc5bfc31,fb9167b0,13308fe8,1f89207d,d6d79fcf) Z8(f3f14268,df46cdc4,c76de5cd,9759574a,cf38f038,4e02fcd0,c5e17c5d,b9cd71b7) Z8(2b21fab0,7b4c07a5,c9ab6ff2,2b00982d,7bffff5b,f4e9d7d6,5091aefc,8b400da6) Z8(3f0e4133,f40c46a7,6b064188,1bbe07ca,a544f5d8,147f2aef,0bd42a7c,e3b94afa) Z8(6c1b1839,9d175111,3fdfb317,2ebdb34d,a209e18d,58bbfde5,f8e99546,ae741687) Z8(10fd4e8b,fcc8c784,0492db4c,cfd1b320,fbeb5bf7,a032f49d,30ca007a,8bb375a7) Z8(87d5c5d8,f73d5c96,734b2bd6,d236a9f0,cf4fe740,dd97c6d6,3076dd01,a0ea1598) Z8(ea4cab04,1c062458,012a3381,e8ecd823,d1696aa5,43743cf2,bcfa9f4d,974c869e) Z8(a0bde6a1,98bb0d49,d48e33cb,39081c72,a0dfa989,11ed50a6,f9f6b9df,3bed4762) Z8(d4e10d3e,ad4e61f2,8681532b,abdc4460,06863774,57147646,579f183d,28e275e1) Z8(c482a053,5bea013f,02f3f9ae,a704e316,076e9171,82eb7662,c37dbb25,43e21d5b) Z8(93b1d63a,737b80a8,00cb8e82,44f6d7b5,9b341aec,918e6ebd,a18bacee,8d4d37e8) Z8(1dff9852,7a77724f,3c9782fa,b043f425,492cefe7,f7abed11,1d050349,6d64858f) Z8(e50cede4,16c043c4,5a8680ac,7a09220a,68365a4b,843028fc,48aa1dc3,cad5d464) Z8(2ab5b79e,964d1d3e,4007f590,f31c8568,c9da8b78,4688c362,f4a6ef7c,d3720a30) Z8(3ae21974,c1c3289f,32c80296,607106ee,6fd6cb7d,3e7630b1,85327f0a,dceb64ef) Z8(f1a55f41,59a2a895,09896c2c,a35fa956,93c533ee,f8553aae,dc7416ec,e45ee4b9) Z8(5d29f522,02ff90d5,117833a8,2c140309,48de441b,bce89d8b,02fb2d10,7da4c124) Z8(d58998b4,5386bb89,85197da4,aef2ce29,31f02eb5,8ec46d05,610daef4,8cefbc10) Z8(380839d8,7dd5ec94,72c297f3,dfd25833,968848da,1e5307df,58e0ace1,95bec368) Z8(5922e359,b6d2e1a8,ef8dbee2,fe78988e,91d83558,97ef4614,619dde23,3f9d5eec) Z8(8c3e7a4b,49865a20,b6ad2a7a,3e37a8ed,12958f0e,549369c2,90448344,c8482aac) Z8(b3aba320,da606c1a,0d73d040,9b5f8780,e675eef3,57564bd6,990c8f05,49f32da7) Z8(afbab41e,ce868f4d,7495e02a,58a044ec,3deb0214,57c19884,794aada6,94f5dd8b) Z8(f4933f1d,f9d873cf,2297a79f,8c6e388a,39a29cd4,7ab7d9cd,00f25d49,5de66438) Z8(a34887d3,7f1410d7,41a06013,3d4cdbf7,d0ec6499,25cef2f5,ec61b251,c0a965b1) Z8(0efaa295,c02bdaa0,7264c926,eb0352af,6db68069,8c0d9726,6c8ff222,45928cac) Z8(57313ce3,075231dc,c1fbf763,efb77714,5fdf267e,e909a564,f0222a98,6af3783f) Z8(5a1396f8,56a4a5df,8f8ad35c,5e2eab6f,1656adaf,9c5c1d95,e59fa3db,b7ad2025) Z8(8bd3efb5,bf493276,bf693bcc,7fc22c59,280bfa83,583ce7d6,82d10d5d,87a93f10) Z8(8da862d3,bfdcbdd2,29872e75,50c44a5e,a4cccd03,88224389,ca002665,8c320b7a) Z8(9d3d4361,2e0c456f,7cc32ea6,34889ba6,98450e07,274b5ae0,1a3fb62e,c88f1232) Z8(2f1cbd02,e1de27e7,1e8800d8,9be753c0,7b463997,8a07246c,4566e636,cabbf675) Z8(31662e2c,4e1837b8,07b56f2b,fa84c76e,867b8820,0ba61f51,08e7fa13,be4e7034) Z8(61a14cba,c962f6d2,e1e3b64e,ac970c6e,b19cba06,8c8ae0ec,723d910c,886180d6) Z8(9233cd76,7987a0a6,737592fe,7440aa3a,e91fd354,97f10e9e,af4bea93,b0e6118e) Z8(15c7a0c7,c46b7406,c6aa0c04,5a4f71a2,971cf472,025922c7,eca87963,c31b0a3b) Z8(14078dd4,1622986f,dd6d1651,dc195205,3f7f425c,d438581f,6ac00761,083f5784) Z8(02a29b8b,3aa86498,99527bfc,f8f4f5f9,27ff9b66,fbe83417,67eba34f,59099dd8) Z8(9960317b,20eaf4a0,1d63c098,55bdd7ac,c38f093f,6f8aca92,72b581b1,8a65617a) Z8(1191527e,4285d260,2e853fb0,9606a334,d388bc6e,de5a11e6,b1c83a70,f11a8b79) Z8(f525db1f,61f39162,eeceeafa,c430cdd3,ef221f02,12228034,0b7f6b3b,c2d557ff) Z8(53ee8716,08953a9d,f5d8d739,94d55c8d,a77c0161,2fe7b8a4,e4d70aa1,230ac40a) Z8(f229fef3,a4c0b379,53a26b16,fd6d2337,5fe3baa6,233b1df6,9622d9b3,8e0cf071) Z8(957c7714,11d61770,b6935bc1,3763dc2b,794122cb,e6ddb461,11194f6f,cb84bbd3) Z8(744b25c5,2e509f28,02691bde,cf5ba5bc,24c35670,09d1aa3e,5a9fe595,41cf6d4b) Z8(30ed9d4d,28277b8a,3554e11f,056db1d5,73bb1a92,406a866b,4fa1de95,4ffe68e4) Z8(da1677b5,a365fcb6,0eee3b51,37d0dc71,94c249f6,bfce70f9,768739e9,52e4e4a4) Z8(3c60744b,aeda5671,8ec61c4f,7c6adfd0,12498d88,92155d00,cfcc3078,d9d832e4) Z8(e6ec7f97,b56926fb,ebe983af,33665522,2533cda8,1401b20f,433ed799,e66d9810) Z8(a264e4e0,85c6323b,cb5192a9,e871436d,028ec890,4d1e5449,5a9f00c4,4f521f15) Z8(9b0454e2,0221394b,c5314d2e,0e939efe,504418d5,e82bbc9d,f517f9a0,9d4059b0) Z8(5e0efcad,8e1d75a0,5a1f23d1,4bbeee00,749eff9f,6a307d6f,102addcf,04254dac) Z8(763f4dfa,818b6823,270c6315,d70211bc,c5ee6a08,960010b6,7d15a1ee,f74c2778) Z8(631e6b9e,0fafbe7e,82b22900,3b528bb5,2e29c890,59476f14,d331919a,3523b958) Z8(6e64b08a,c36b48cf,2e79112e,956a44fa,c10d3bed,f79ec810,12fa52ff,8f85ae6e) Z8(1f8ffb56,196e7c30,7b142c79,d8418038,078996a3,fea58906,d91648ff,4321bdeb) Z8(71d46367,f220cdc0,2a2c5ad1,051eccc2,1bd0a390,c897e7f3,88817346,cd6df0de) Z8(9b200c69,f5093969,905706df,5c6b7e66,b68abebd,fdf39988,41762eee,35870047) Z8(b9753813,66aa9d68,33d53736,c37534f5,341ba410,64131587,dfa1f6f9,e7cb73c0) Z8(526f0ff7,386624e0,b650e37d,f3ebbc68,74346f65,0aba4ff2,06609763,dac8a667) Z8(dca05fea,2d8f990d,c296f834,d1639b8d,f8dbf919,887c6bb7,67e3de7f,8aca661c) Z8(c95d7ba0,755916ac,78948a5c,c7874e50,aa150206,18c8f543,dc1b339d,855c0716) Z8(17b29f1d,7e5353ca,954590ee,2a0e4911,0c57261f,f690db32,6dd6a8eb,1c704d7a) Z8(cf52f1d6,7442a742,fab21d62,0d7c3bdd,aaebe31a,e077ca60,f79c5dae,c471dc49) Z8(68aee2a4,be32b6f7,3d10361c,ce4e1ba7,727faa0a,f0d98098,08e07365,2e68338d) Z8(392cfcd7,076acc2d,a9989733,519bdec0,79af81bb,d220ace0,cd4c0f99,af3f42b5) Z8(12768e02,1cf6e589,67484515,9dabd91a,2951cac2,789e20dd,138dae70,11c78b3e) Z8(eff14881,5040d9b3,0b09bc16,ef158fb0,8556f681,07107ff9,c56117a3,49b8c0e7) Z8(efd5333a,0d84b8ac,acc89f29,5a600153,4ddd0a63,1491317f,6044367f,be94f619) Z8(fb872c1d,cf13ae15,d5f188af,316218be,6df60ecf,ef2a985d,eec4625b,ba4c3ee3) Z8(5866ef72,e2822c20,52c13cce,c87f64f0,d9fffaff,18192ff3,11b6ecd0,fae6acac) Z8(b5803e5a,f00fa507,c04d8a5b,d792b681,dcea2df2,9df1dcac,ce8c71fd,9a7f7b66) Z8(28d9921a,c2ba6be2,6f06edc6,5f44e617,336f7008,51611c51,25529c86,fa29df27) Z8(e9b4b842,c0666356,a0a8b1d3,3791a61f,75b023cc,19a29546,1c31683d,94cb6f01) Z8(5afa4099,89566267,c850cd74,4fe4df47,4688892f,2659967a,57dd35fe,e7b6cfb7) Z8(c8080328,5b479107,9c6abd86,8515992a,32404442,9a97dab7,e012a850,9601097f) Z8(ca634d01,e4335cb3,76de156c,a33293c8,4b837ea7,d6d70776,fb9b910f,3d8db05b) Z8(d3f11194,86d8432c,a1feaa0a,f14fc860,97395d86,efaf79d0,aedb75f1,79c676fc) Z8(83aa278f,3e8f22c3,a7bd1227,b1e3534f,a720d542,8d379b22,56ca5dc7,13ee88cd) Z8(31ffab52,39d25067,a278b60c,d3d33b6a,63119530,b44ab647,2adb1191,18237ef8) Z8(34f22b51,090f2ab1,41911288,934cc14f,4ae3f63c,8aebc180,482548e6,8cf24603) Z8(104f1887,fe0caee2,256fb806,3969c5d4,5748537b,cbfaf6b5,5d5b40c4,32008fd6) Z8(27fd9d3a,5ac1e543,489061fd,58d893dc,11b1847a,f8cf2d80,0097e897,69b5ce6f) Z8(96770a6a,0b1b86fc,1b112eeb,12e966a7,572d7df5,c474e8a8,456a2dca,01167807) Z8(494cfc22,9f43b959,be85e2cd,0c0559e2,2acf87fe,a701025e,a041561c,f7832f76) Z8(b9b5fa0b,531cc86d,a863e924,b64fd5f9,6306bcc9,7d1f5f90,cee445e7,0b91942d) Z8(a335916a,fd3f7974,35bb95ca,3df7cf9b,0fe9cdcb,792e5107,9558d0f9,21c1b2fb) Z8(455fb438,404b3bcd,55757560,9cc09b93,261f3c74,800132f4,7b52b23d,c374216e) Z8(0b4d9d63,c8135a19,246663f0,8c5b0866,efed5745,a1bdd3f0,2b0da37e,d9c0d748) Z8(7b9b3231,07a9efd4,ab48427c,21d7a1db,fe6077c5,d9c8c990,67f2bdff,c38ab429) Z8(240d6bcd,b2756011,3476ad24,e92eb428,44378719,becf7645,253fdc5c,c2b44222) Z8(38779f49,20d499c1,769be459,f8119a83,de84b55e,e2d32d02,1b0a9226,3ec31c17) Z8(378abf49,01d56cbb,b9885dc2,5d3b1d5a,65e94d44,e0ce58d0,68cd3907,903f0438) Z8(77f3aede,6cbdc326,a5c6a6f2,886e45ca,a1595410,5fe4f4cb,a3d851da,bf3c6749) Z8(cf89d8b2,1eb7d0d7,552ff617,bbc8c71f,bccb72f2,920e5c68,b15e9c6a,7de0d9ed) Z8(66442932,57eb3acc,23d73566,7616b661,9926ac0c,b04d54ff,c21f101f,e24bd5c4) Z8(c751cba0,5afbcf4a,eddc1cd3,44d6ae12,818cd49d,f3709121,a3035e01,659dbfa3) Z8(adc11a63,d784be58,7235b332,e4fecfb8,412b7173,87b3d59a,d0a4f2df,b7361143) Z8(0dc59cd8,c9cc57a0,8f07a0dc,d2bcd617,57aa07ff,276c0953,134879c8,c543a017) Z8(7a0c3f01,40e1b0a3,10666b04,11388e41,5a8e5f87,d0527e11,8cb487f7,0dbe7b1f) Z8(08652ea7,f824a5b2,f34a36f3,6cc33798,3789e49f,ac6aedee,2ee38e78,d42136fa) Z8(084e9f25,bb942228,db5fd45b,3b67eac8,19327889,378748f6,035b8fa5,d4270257) Z8(937783e9,db9013c5,e968d8be,0ab07fa7,96fd5f73,22271dcd,715d950e,dbdeb0a3) Z8(1d272b72,304f25b5,e5536ea3,d5ce8752,3db315d1,764dc96d,e0100eed,5058c177) Z8(b8fb625a,1a41db4c,f81b9fd6,bebad89d,6bf22cf8,aa40c34a,1f0020b5,68430638) Z8(c4b3a894,f36277a3,f93ebb13,dd6375fe,7a70ec8d,d3a2c6d5,3535a3ca,50d5625e) Z8(002a2178,f787012c,f39a1f9f,5d5d9e38,d8d3df06,2ef31fb5,82043f4f,00275494) Z8(aee63d9a,790149d9,ad703190,8fed2f8a,9549d6ef,caa2b467,8402a9dd,7d122e47) Z8(4c9f4744,de5f442b,e8945760,920af509,6035b8e7,9ae8dbca,b9b4825a,851b9995) Z8(f3d7daef,203e8179,12e3808c,d0049540,8cac4356,50f08770,f00f5e62,e3d8053d) Z8(3d16dfe4,4f4e2b1a,b70fea41,b90ed626,7ef51d38,8e950b49,531081b3,9f59c5d0) Z8(1248b6f9,bb53e43b,a6c5053d,a392424f,9b330e07,b0b438a0,68559ab7,42a68b18) Z8(512f5ba7,35b50e20,6c9361d5,237d4b44,d52a2452,a5e839f9,42cecd23,1deaeb44) Z8(bea98ca7,841f91ee,adf0da30,1482ed18,23721a0f,260ee1bd,93239c75,8fbd791d) Z8(8ef63181,0cdb9482,513aa662,6f501995,67d3f857,c9fb6c72,cf4e62f9,41b1ea6c) Z8(9cd72189,4e3f8335,9d26a616,4ca32fe6,271e8718,3e27d444,fd97d16b,cd2ee356) Z8(141b262a,1d01e205,6eba6da9,1f082717,78395517,76728243,ff7b799f,6f93a478) Z8(c1988cff,2baa86e9,7b1ea9de,daa8bfaa,3ccdd5bd,80368961,5b094c65,b7932432) Z8(4a1934d5,403aae60,488b9de2,1b66d58f,e771e0fb,79f5f12e,041af483,5f76693b) Z8(1af267ad,6f4be88e,436fab32,9241cc9b,a5079d00,977adfee,3503543b,69ef260a) Z8(2cc740be,74a0b795,2359d710,989afd67,15a877e9,c5d5e8a9,2bb94854,e55e4532) Z8(3b26a376,99d71a20,47cdf26b,6b5561b3,13489b0e,b7baa198,70cc7ef9,150cb928) Z8(ae1ac2ef,7fc4ecd7,3a6ca36e,3804abd8,ede01f46,3198f1b0,b2fa9e73,5ed01f9b) Z8(faee366c,1f92383a,32139529,3ab501a0,489caa95,1ffde425,5b48bcfc,00380da1) Z8(e80e62e4,206b500d,7d385b8c,c89baaf2,739dfadf,f4b7a674,345ea91b,75841b16) Z8(3556fbcd,7099f371,3b57d593,6ad6f3eb,6eece405,37c5626e,44b662b7,3a3c724e) Z8(e12efdf9,87062869,e1e03ef2,3fbb6780,2c7f66ab,c62125e2,0e78354c,14529da3) Z8(d37a2ed6,bd62653d,4b577e9b,0a3192e8,ca69a059,874bb077,a0a6208b,f6a64596) Z8(d36db6de,e24e030b,a1fd2daa,4c46dab6,1686decb,1f505ffc,ed03a431,d61b49e4) Z8(c9ceb6b3,ebfea720,a8dbf39e,d913c77c,a23a2f21,e0394296,26f08608,4e28edd9) Z8(b6f27bf7,8b8bbc42,7739c858,1438742a,be1c1053,3ca73462,713b2138,e9943437) Z8(6e7dff4a,1d9303e6,187e8123,346fc1e2,59cf5d39,e3034b92,a5307f8a,3ddeab31) Z8(5557f78f,388ad3dc,af57db99,830b8eec,1ad01b1b,25f94e9e,bb92abcf,d31576ff) Z8(18b5f816,d5167116,73e11266,11e02e74,ca1ea6d9,a5252fbc,19e0a46d,ad8d5697) Z8(c600777a,e7874461,94dabec4,6b1172f9,d0e43110,a2c1f75c,54e02332,a486cac4) Z8(29bc9132,ee165314,ae3d7a61,749dbeb9,ab77eae6,5d13e354,bc8402e0,5dad978b) Z8(9eda5a08,d0d55936,efbd599e,c73497cb,a6f04e50,917ff255,ee205871,394e2047) Z8(6e3e6165,a470420f,27f0ffb1,d8ad8eea,12750660,2423bf0f,5e4615eb,5af53749) Z8(22fce5b7,ad4b8c4b,cd96f94d,cf2c404e,6774f94b,1ae80598,b39749cf,3dea2f5e) Z8(3c347bf8,0a119cde,398916d8,fac3d022,8c83dc3b,a63f25d5,13c49b6c,4cf60a21) Z8(d7cfbbff,38deb3b5,7c5153f5,140f7ed4,96a38ab6,7ff989ba,7506b093,c0ee8513) Z8(c33141ca,68055cb8,f845cdf4,a88c3b02,9d81eb55,cae61097,fa0b13c4,09f23850) Z8(472f2740,ee6f0dfa,76256e8f,d843387d,814f0387,2a164dd4,4de3cc19,6da0f0e3) Z8(1cdde009,d2f6ad35,658d1607,e9faba7a,921ca703,a71d908d,93d21b22,6a7917b0) Z8(907af181,ef4e6354,7b328fe6,21e95923,c15e1c2b,b70471b7,caf3d4f3,9ac69740) Z8(6c98cf56,d71fa87d,2b8c5538,27db6db1,346f83e8,42a8768d,aa840f4b,916cef9c) Z8(042b6024,4284b16e,82a8c1ff,21a3a737,8e2f9fe0,ad6338fc,adca5f79,a1719607) Z8(a4f52e75,b24a4af9,bc298348,89a3cc2c,f8b21e11,b158b4cc,c9061b1e,c85e3fd5) Z8(ef1f77d5,f95e82c6,312ae7f6,80aa94a9,afca6cf7,2e29edf5,92e20898,5db315bd) Z8(08f5f825,6b6cc4af,60a8184d,17fb0c46,daf512f3,3fbab2f4,d98df0f0,72070f4f) Z8(d9c8d86a,50dfd02e,4970758b,7afff5cc,b8cd9d5e,14b364f5,f314b8f1,8bf1e282) Z8(5df87172,67e5c491,83edbf4b,0d796446,627b5b0f,47f404c2,75ce847e,67b8ebf0) Z8(3a36c55c,c758790b,fd4ff1a7,db5a7cb5,19f66386,92c2479c,f9416183,d503ef96) Z8(2ae80e9d,74f7749a,a8032e59,4c22df3b,a56c3dd3,f730b811,a86b7524,4a43169e) Z8(86336353,6f4fcffe,460df641,7ad162ad,e21a7e9d,fe970f12,a5ee43b6,22334114) Z8(323c0d79,737fda5b,46e2b91a,febab074,4c99b23f,e1b326f3,7d683dc5,45fe5d0e) Z8(0b624021,36fc2c4a,b441a4af,f3cf2309,f9afa603,ac695197,dbf9deb6,f588e00a) Z8(ef2308c3,ab7f27ca,592dfd40,0debb9d2,5ecc4c70,77340cc2,d7764116,23c826c7) Z8(7a34ccd5,05120cb3,29520a8a,c656fd3c,e9626d67,f45384c9,7dff5146,a304f3e1) Z8(b4b1c0b3,6f956b7b,312b7069,d74a9232,1ef2be13,33f4634e,daa7ce67,dd533bd2) Z8(fcceedd1,fa2b5251,9c6adb93,664f6f36,dc5093aa,bf66af66,7be3c371,dfa6379b) Z8(af35febb,d38bb7c3,e242e238,5537eda2,5f321064,ed9e71e7,edc8b2a9,f95b6038) Z8(e0356b7d,9bd231ce,d5c51e2d,c589e398,8663a6af,c8506dfd,3f6b0da4,db6befda) Z8(5d78a19c,f200c6e6,60213c5a,56dea8a0,76734fd0,e6ae72f5,fd9ed41c,28e9065b) Z8(0d83015e,ed25d1a9,7cf119b5,6998f95a,e7f9b2ae,9e64064b,86622f04,24016127) Z8(6b722595,43785623,10caa688,6d095a8b,586b9ac8,76ebf0f7,199c27e0,6e88d40d) Z8(0de2d678,9227cb92,d003cbae,a4eedf8f,2ec7a941,675fc1f4,efdef86d,e35e4bbf) Z8(d22c7843,0e0d137f,b4e456f7,d0f87ce1,624cdc3b,fdabb2a1,3b8ce899,38f65c19) Z8(9c7cff3d,bcc89077,de8a054d,6c005b36,61f7cb36,20a6a433,eacc5bc5,8501d100) Z8(d6861dc8,be710da6,503e50cf,0f5d9b53,b715eec0,8a1487d6,73b81d29,d6797a0b) Z8(76d6e904,1b8bc578,ff38592e,5c81ed47,83d75092,769160d6,c2552f69,584430a6) Z8(37b59aeb,18a58364,a0eb870a,dcaff3a3,272c6106,a5ecc4ad,201005e2,3775df4d) Z8(4a026a38,a7fd681f,c7715a91,02575e0b,244972a4,3c5be0ef,a75a7805,5087a1ed) Z8(8afa6dd2,49ab17c9,694b2c47,0535ecd6,3923ec1a,27a3111e,b97fb10d,2a2b65fc) Z8(31ba26db,da0e04eb,ca7541a1,bb97b52c,a0bda983,76f6ab6b,a62b572a,3a42b8af) Z8(8f579afc,e088f148,b0a7fd96,8f5938c3,48934b9d,0234e22f,4ab00753,4bd10982) Z8(380dd1cd,0685317d,b72320ac,454eb31e,19ef87b0,4bdf25d8,6d584a5b,710cad6f) Z8(61ed02e2,5509de27,816833c8,d9212077,0c167d9b,cb54eaf5,1a7a48d3,24883bb0) Z8(a2ecd21e,d52c2e51,3f065d45,9540ee80,95636e93,5a51922e,41b3e231,5e1fa394) Z8(a9f51965,a05c3846,4f9ae951,0f1ebd76,a4f703fe,b637b4a8,824ce169,4b386d27) Z8(3c6789e3,3d655dcb,0ce4a093,8b67bc14,38729b45,abc5915f,7c568252,f4db67cf) Z8(fca97dd4,47efe23c,b71ab552,8130674b,2464c6ac,3387290b,d2308b48,e7478100) Z8(df6caf9c,acffc33e,b414d8f6,d3d8b007,d4b7e265,e7a92a97,c0437c36,3fce9c8e) Z8(c7ffa4ea,7c539d7c,fef96341,d9207c34,781188f5,7c877f23,327dfd3d,8757a134) Z8(5c6976f8,2c25bc66,007e1feb,8356df7d,d595208f,2743a82e,541ccb41,a2b3fe4b) Z8(531d508d,3d2ed6a5,eb53bd58,da570da6,90f1429c,f37d92b1,5e0b41eb,4f0b7e03) Z8(617d97af,528452d9,05ddb62a,b12bf061,2ab8ee12,45a0dcc1,5bddddba,d4aa1124) Z8(e205193c,0c1d6676,4852bb1c,da1a935e,e002f4d1,a7611d4d,18b5d3b3,aabe025a) Z8(227288b3,ee8d44e0,0eabc778,67956366,f2c170a8,835c8748,63bbf42a,37c4bc7b) Z8(99fb7e68,7af0c53e,e305d750,9058ec13,07a12e56,88abacc6,756510c0,82994a9d) Z8(e0ac4c58,d4fbdff5,bc3415b6,d9d0541b,990f1c2c,ffdeb7a1,7ee43f3c,9f54faee) Z8(495555f1,7cf75b36,70807768,f24b212a,91d609f7,ee3e9075,ac48acd3,5aafa526) Z8(d9848f05,51a85e10,d0bbe9be,b674572e,f5f865b7,fe4218c0,f959e921,0fba2735) Z8(d4fb20ec,ddd79e9e,cd3abd5e,f67a1cec,66458baa,2aa3b64d,8f6da594,fa92ac6d) Z8(0678a6df,8e64edbf,70c8bdb2,59480918,e7158502,fb565b1a,c74946f8,dcf87c74) Z8(d0e12a43,0cd65293,65aa53a0,0a8f6b04,0896bd10,903daf58,d6019a51,dc06d3cd) Z8(cf519cff,e0013882,a4b2c100,ae9048cd,ba6ea75d,573aff0e,ed183677,df367020) Z8(b34f7f6c,f417cdbe,530d90d6,38d75d22,82ec4214,326ad758,d754c52b,ca82fc1a) Z8(86452cc3,1b390a6a,4ae6661f,7853a0fe,bf2e5575,70efd24d,201d18de,379e9a89) Z8(33648767,4780cd99,415186e8,489b1457,1eabd875,49749826,15722813,12192a39) Z8(0f9d9e64,90eb856b,aaa2b10a,03742d52,070feb82,15c1c1f8,f8a829c2,97d08a83) Z8(12da5fa8,742a4c11,4244c8ee,8d3c90c6,a262f9cb,eaff7cad,92e39852,28562f48) Z8(63b89ef9,f6160bfb,58ca3259,093067ed,ecfb5b90,93cd20b1,bd3dd108,7c3a75ad) Z8(aac1d981,6e1f8126,f6ffb926,5c8eb573,6883f90f,2d8e4104,f7b04922,59d82c2c) Z8(c360f322,7b4fc8b3,e733a82c,7e4a8e59,94eba6fd,3c1cc349,75757683,bf340692) Z8(819716a6,7bbda089,3c06cafa,2cfd032b,6eb00a44,b3f440e3,ac27d3c6,e62c27ca) Z8(d9931f39,447506d4,8e959868,70693517,73267928,5f7e07e6,8df30887,0aa1f879) Z8(25331363,e02a0b4c,2fabbfbb,836f790c,d9a27574,f0e50107,979ad5ad,b89fc92f) Z8(1a6841a9,9a72bb07,c886dd3a,c6bbf512,f7e2ccb8,9f231998,840288ed,52267e55) Z8(170e5163,05e08a4a,8987792e,42377ef9,c5648a73,f8511a7e,c8dc0383,67487e08) Z8(da599547,14a879a3,87879dc1,7b6c66ee,00fb7697,15b4e05d,765703a3,81f7a129) Z8(663a6220,2240e9da,6b383b81,b390f43e,91d185d2,38a11ccc,5d30bfdb,bd724a3c) Z8(28df6cf1,60e7b069,a1c39dc5,be7728d9,45b383a8,fbe406b1,ad3313b8,aac90247) Z8(7a2336c9,8a5deb31,5b84398c,820acadb,2f3448c1,7b3b1321,90583f3a,b0c98432) Z8(0a30deca,d77d6949,bad2b9ac,210a9eeb,2a0dd401,bd51ea23,756710f7,590c92d5) Z8(b871cf3e,cbfcfafe,f102f537,7a9805dd,6fd217ca,d50c747e,397dd177,1fd2b8f2) Z8(cc4ac825,aa4f8a57,a41647bb,6df9f82e,9360ec3a,8fa17ab5,427bb9d4,223b6b39) Z8(191f2694,5ea03380,b8b2842b,d92b18bb,af7c3349,85652499,36cff368,e70e2f94) Z8(37f76237,cfe5f6aa,5f188e14,ee46cbe8,82f401fa,4604c36a,a557fa04,8467614c) Z8(fd4940c9,02d53d28,38d54b90,8fb15cf2,634a2f0a,1985ab47,46eeb283,9a485cb0) Z8(a202fef9,34fd2ee8,8530ae27,e07ed453,c55a0056,1bb14dbe,2aa12532,404fe805) Z8(346e146e,14102bb2,604a0f47,536c6d41,404e81a1,690ac879,0f74e2b7,f14081c0) Z8(fe0c784a,ad96e4d1,972cbeca,a2cec724,182c3fe8,1950e5bd,2a4ee2b1,a41fa4e0) Z8(a328da9a,f1016aa4,0b16da45,2580f54b,d5fec81a,77aeee38,7e464a08,0247a324) Z8(a0dc7375,fcde85d2,5b173e6c,e46d73ea,fb3be909,cefd0023,a36e4a18,42f55790) Z8(77cfcc5b,bfd20c0e,1744809e,4d81f48c,55829a2b,a3a2ca31,58378e31,0eb767f8) Z8(45f110ed,26446929,a2e47654,db07a5d1,c84e0262,e04246f3,84b06dbe,57020389) Z8(b37440ee,d5bbfe97,11ec6161,0bc64018,9aef84c4,37371b05,409820d8,7980c81b) Z8(59562849,f20f5a45,6bd1301d,ba606972,f973d1f7,aee644d8,23ff069c,68f1f7c4) Z8(67056da2,1b34308a,76483a4f,583c4ed4,13461ee3,9b47c50b,1beaf03f,c7f94138) Z8(e6a7fefe,92e0f63b,cd0cb793,dc699ea9,bf1da702,04a3ac23,37d93a34,ec829f52) Z8(c87a978e,b75a1465,42aa67a4,0b68d509,32af8f87,fb366819,bac621ac,d8f122af) Z8(3bf26782,9cf95acf,7f9bd344,c054d19b,d4b18126,9a847c67,cf67c550,ad75642a) Z8(bfefbdfb,cd92dccf,987fc207,b36afb86,ba1dcc14,3582866a,6575067f,9b42924b) Z8(8524b3ec,0599af72,c44e99ed,f8304f36,6b5bc313,36a01718,395d7dd8,2fe8e2f0) Z8(88462a2d,c9bbfdad,94c823d9,a67c1654,6e706f35,0bc175cc,23ebe41f,82cd4831) Z8(7e12213b,66ad63cb,0e444b9f,8b169390,998301ba,d51a4b16,c09adb02,c75d140b) Z8(3f957e2c,99865934,a1f44cd2,2bd0ec23,82836b54,637f6b39,1a2f82fb,7b00e399) Z8(b817f1be,1f2e5608,ce36828c,1cb98d19,b5cbd131,78fe92de,63c5771c,67f19e30) Z8(f3c65e8e,aefd0336,3a6b5880,3e01363b,8e9ff588,e306d2a8,1c5e0857,895db568) Z8(bedec84e,9c3e0053,18474e05,1212afad,73ceaeda,20167c53,15a1cea2,6ba852fc) Z8(df576899,315e23c7,a9e8f00e,df5d20ab,7ba11092,14b12361,d935aa0c,9c7c27f8) Z8(818c494f,8c87c5f5,6086044a,d279fca2,12c66c97,53899ddc,0038e73b,f9e2dd55) Z8(c2b30d61,1cb23304,40a32246,a7e53f5f,45d7ca20,c99f98fa,ab373836,23cd7056) Z8(3a91ece8,2fe8cdd0,182b9e95,8e5b61a8,6d80e154,b0f75d36,b0ee01f9,137d7394) Z8(2a77e398,5089b706,bc3b12d4,79c4c9c1,7235d17d,5b764b6e,27edb848,f70dd20e) Z8(437e3e63,3bfcd1ed,74375121,7e57779f,de8409f8,47556467,41dd9965,2b349d90) Z8(d3f745e3,a445ef82,f1d378d4,64434ee6,3a836239,44d3ba2a,0fa99072,3e0c00d1) Z8(f379098d,0898e848,5bd31c53,6f2b16ca,2026d022,c371546f,3cb4709a,6a743a17) Z8(16c2d5fb,08972fed,3aa4281f,71ad5ee3,9260af03,47f7a77a,dca305af,1da2c02d) Z8(36f53ef5,3d796a38,e6decc33,9a2eb35e,fcafcbe4,a78ad89b,3a2ca467,df6ac43a) Z8(a9bb21bc,a348cd1d,d98209d9,11a913c9,1598cc9e,9702a1b9,05973c3a,361fb9c5) Z8(d80432c2,4165c7bd,b342e57e,aac11329,273d262c,e6e11661,192daa12,b0953172) Z8(352e528f,e1e70657,14a355e3,7090eddf,2c00f9c7,21a816d3,ee329cdd,88251ef7) Z8(b8e1fc4b,0f1b9410,400a8ad1,76847474,7294ac7e,1a2d1841,62bfbc57,f2c21ca5) Z8(b0639035,5ec44a54,09a95236,714a7c9e,3afe86ef,8a17e2fd,23ff409f,45815384) Z8(c7ba4ae6,b0ffe725,5ea2e235,059c156c,3cc708c9,5f172c93,fcafc902,156c57cd) Z8(7e13bc73,5d75ef6b,a7bd5c1a,f445617a,88caa926,cd960952,bd1f1e2a,52a2d6b3) Z8(55a5dd23,e433f83b,5d0bd8bf,c62f4f5d,946c3cfa,46b86973,26313b0f,7ae8b690) Z8(4d581964,b9ec2f26,37e8dca4,49766248,ff8894a7,876e30d3,32930d0b,1f6cfc43) Z8(2737b38c,c94f0b7b,396003d8,ab01e0fa,7e7da00a,689c0776,a8b99234,3818d033) Z8(edeae20e,ea569480,ba2c0c99,933c5f9f,a0cd9dfc,ebf8e83c,ae57f1d5,78ce29bd) Z8(2e718916,16fbe37a,c8eb5cde,f50e3581,413bf711,a86d5736,2272566c,532f5601) Z8(0cac3d0f,191205cd,dab17120,d69840ba,a4f2a13b,ccd8f380,3347b85e,93d293b6) Z8(588c63e0,1e1d1f30,445f8abf,bf3ac884,825e12ee,3be70d19,6932ca1d,c27b373d) Z8(93a157b3,8ce89d90,124053a0,7ca79de0,32783da5,34925764,7fa19c5d,39401b7f) Z8(7f382971,737585d2,ed9eaa6c,ad0d323b,44eefe22,2f99dc51,995b442b,d99fe7fe) Z8(06994dee,78a85d0f,cd645a0c,9e18dfc1,607f2092,9f7be76a,51a428cf,2411a470) Z8(f975b5fc,b48b8f17,278ffec9,c4bc0581,29e2132f,ed7af2a6,cb918ba2,da95b0d8) Z8(81a28e7a,2779e557,6ec1c814,102172dd,530f3c46,485f6280,31add9e5,19dbdfd6) Z8(52cf6e9c,1bb66f79,e1f590e9,20789a40,c8726c8c,3c61c8e8,cb942bea,21733b0e) Z8(ec687bce,c4ab9131,40b96824,486b9da5,39e8e72a,2a323f3e,eab7a0ea,857cb599) Z8(fd538e3b,3662ff8e,0860731b,c9a0154e,5b9b5985,74901953,a4cef002,277a1967) Z8(d3a6d916,da2024f9,46f7c1f3,3e7ea0df,75eff166,d2181f68,4802b376,2a3a97a2) Z8(b5402b40,84010c3e,40763314,924c8d3f,4cfe0984,2a6695e8,644a1f20,a84d3eaf) Z8(c9425a45,9bc29b0d,4feae866,c548b907,3a1000f3,f9b6bb5b,da3f6c02,0c13f26f) Z8(edf0756f,0914adfe,400aba1e,cdea208c,c85518a5,114bc957,5d4b7b9f,0a69dccf) Z8(1ad0f7d1,81034e21,38e75a60,0c9a4e1d,2732166d,2d8013c1,d777a532,72541d67) Z8(77212d52,30eca897,c8e460a5,6a24c54e,dcdffc74,6186f682,868b003d,840abced) Z8(43c93463,50e65aa1,00c925f4,c437083d,3942e172,8e436769,f49d2928,c2d66be5) Z8(c0b21149,8dcf8652,51e77a9a,006cc427,1a2c8679,c3018d2f,68ef8843,3e37e7ad) Z8(46d725dd,a241bdc6,571c58a2,28ca9e1f,90efc2b1,a21ec147,e2407f89,75756a26) Z8(1c178395,c85e4da9,42834b10,e99607fa,3f3e2571,4bbc19b6,1e578316,95ff2eac) Z8(a42d48e0,f2ae1f2d,0cf40674,1cdef8c2,aab10703,1a50076e,e77607ca,78a569b9) Z8(5e58d6eb,4414a090,1d9e63cc,6eec1dcd,af7ded6f,c69a0dce,230cde53,74037800) Z8(647e03bb,914d6387,3f5c92f0,be1fe916,a1cde46c,5afbd37c,549b2760,6978165b) Z8(fbe7b434,1d17f0a9,a6d39a5a,9a820a1c,9f171a36,70da6e14,3bc62d66,5ca0afe6) Z8(60b97847,715606af,fc8c4249,49f5290d,0a21605c,09eb18b4,fc5b6a86,652c9e0c) Z8(3faed52b,7d5d2b35,26e4e849,67612086,6e1dd4e0,bfa96af8,0e167036,7eaa8222) Z8(9d183300,02048316,e9d480a8,7f23e2d8,38f8377d,b2951c8f,07d4b9d8,fee5c725) Z8(1a778b41,b9503cef,1cd52dd3,40ecc838,64afd17f,d8a05947,8c84dce0,f9621bb8) Z8(02e54ec4,a781cc8e,c7377e54,8ee3f7d4,8efd4a54,f5819f66,51049100,ab457256) Z8(1d4ff1ef,26f79d63,d6422f25,19224b76,1ab9880e,632dcb68,62a7a660,8c20c25e) Z8(2471e8a4,3d1d524e,5adb256f,a7fad713,51aaf23e,ae9174be,539efeda,a0f3118b) Z8(6b787f8f,d8e2c96d,9d7c845e,1d9e129b,0532044f,a97197f6,76383982,401639d3) Z8(845e7f63,db71dcc2,4916f953,3b3da736,dfb21233,9b377014,b48b57e0,5c0a8220) Z8(2e9cf2ad,ab5e8284,7052bb8d,fee04a97,6afb9ae3,4c8df78f,1bf69d3a,f3f595bf) Z8(6c048d10,4856c153,a359e3e3,96982360,e99487a9,0906d719,c66845ed,5834604b) Z8(5450aee8,2aaa1858,9898ea3c,3b4ad1cb,a00e0a64,28ac90f1,682f5ac4,7cbcfc65) Z8(0a493f83,cbd007c1,3a20c286,eb06b537,2db94e01,78f12a45,0c434f6a,cbf54311) Z8(0535fc14,13eea8ac,86f9f9ff,738456ee,44fa0b8c,c1d45e0a,1a4fb556,b84184ed) Z8(9cd46952,7659ea5c,197ec220,ae1f74dd,d71195f7,352f27b4,3ee1f106,25eb97b0) Z8(9a668b3b,53967484,105a4f51,8167948b,9e85f206,54014f7d,a7c342ed,252bf954) Z8(8f6ea3ab,c88382d9,7e4697ce,c60cc582,33a62bec,2c7cfd38,d01bb4ca,f956177f) Z8(663a5817,717fe608,23a6befb,e2604bd9,507a8543,c0edfc38,099ebd1f,71d87f1a) Z8(8ab1eab4,edacc487,3b7a0e16,4cd211e9,603a3e26,938a851a,9668047c,ddcb01d0) Z8(3f478b11,852b74e8,5f979c17,588e63db,f17ed717,c189f86d,0035c1ad,14dc23a5) Z8(498da3ff,eea2c5e7,9bc5eff0,b935f7b3,69eeefbd,b68340fc,b501d34b,767af842) Z8(13d83d53,a34aac73,b21c438a,0631f3fa,10e83743,6ad0a041,100ef1c1,e55df455) Z8(cd8edfd9,ed117627,7a3d77bb,3c451aab,927dc80d,3dad611f,55c62293,548a802b) Z8(fd40c371,685bf20e,5fa02e9e,41d1db9d,d8ce9cd8,994664d3,0430d55e,c24bdfab) Z8(bd57a154,2ced1501,5726ede7,63dd18b9,99adce08,aa63a8ed,7adeb28d,f57487ba) Z8(de7e3454,d7d20d9a,b9f57918,4f50b4b4,59f929f8,2616b827,2852959f,92007bd3) Z8(bcfd1e9b,2d533014,62820f06,73c189c0,d50558ee,acdc1df7,2b9d4abc,bb9e0dc6) Z8(d4570ad0,c963f3e7,9c650a8a,a78a59b9,6be66334,f9083c54,ae15f530,5dfc3ea9) Z8(48263fce,2c450348,17a25bc7,e2f827a4,3095cd36,35bc0552,0b87dcab,aae7583d) Z8(3a963f67,a7b13502,bb784ee8,b9015eba,386f598a,d15f8c07,40f117b1,723f54c2) Z8(37acc48d,dc95cc04,e3f9b42e,84e869b9,6318a339,cb86ba93,f2b500fd,483d09b0) Z8(a39125fd,1e9db006,abad4db1,7d22b88e,a1e61c60,006b2a9d,ac0afce4,32421a3f) Z8(9c43331d,bc009e80,27e89d4f,8197fbd5,772baf18,94f914bf,b904ed83,9381c0a1) Z8(57fd3b3e,dbdeddb4,cfe63350,e74eb6c2,996c7009,f0135247,bc9911fc,2b2d3e24) Z8(8da2a3f7,81e09bca,52063acc,e1c37b1e,2daca98b,3d10150a,5c025c82,11f1403a) Z8(4b9cd773,7c14341d,d07cfa5d,58a6d96e,6c656a74,fc35517f,3dfb491f,f8461e8b) Z8(4bb00e27,7be6823b,9cf0d4cf,98a5c79e,9cecb731,351c050d,e1c063f2,870da919) Z8(5a822112,b8adb3e7,bcea51f6,427c548f,b566cd7f,3f321159,824b16c3,5a41d26f) Z8(47d654bd,1d8878f7,fca6c531,cfd9868d,a70672fa,6467fd61,695eab96,875afc20) Z8(4f3fdec2,eda583a5,3e26e27b,98957ebc,8e42549d,4ec61f7b,057a280f,0bc59bcd) Z8(341f8be9,c2585526,f82eadce,8ca4e2bc,69a0ce6d,1ebcc56b,7ba53da5,95d1e195) Z8(dc226c77,e0be2c30,83235658,2c9841cb,bef0b79f,bf4c04d4,9d85f809,ada71dbf) Z8(be361413,5123b07b,27480dd8,067346f0,162c387f,70a276dd,5f2f833f,9770cbc0) Z8(dc98fe7b,1257f51a,0ed35c93,aed1961a,d21435f0,e18f24ad,e3a1891b,30ffc5a0) Z8(f62ea4f3,78631060,c5e8af27,bc9fcc73,9c05f856,5b2430b6,302772af,5cba64d2) Z8(ad16ea47,491d5214,df52fc9f,95468e9e,af18ff74,c1c86162,b1e26aea,41e9d4c8) Z8(cddcef17,b0550189,eaf7eaa1,47cd8b08,88bbe782,303a3487,9390b4cd,c23180cf) Z8(64b1604b,0132fc92,bbba9e18,dbc11034,1a1469dd,df3be67f,ad06dfaf,9ea20bb6) Z8(5f2de789,c75faed7,dc965921,d5facb80,e1bcb915,cc4fce47,467e02e4,0449a3c6) Z8(99027a9f,4db24449,bb26de5b,736c0a4b,45cb86e8,b71f5af9,764c249d,5fba2962) Z8(825be11c,fa962062,1c8c0cf4,b7ac75c7,44d7228f,3fe0bb44,e36d8a25,b38a5066) Z8(3ef510f2,94a9df98,6d396803,7a20d1f8,e1e6828c,80b7c103,8388c5be,b0131156) Z8(c55b12d2,f244e2cb,25b6d049,6991ddcd,bec838e3,de5a3276,ccfc9f90,ff5bc085) Z8(64fc3f08,2af7e171,54dabf78,3fca648f,77f02480,e6192d8b,53512dc7,8f224b11) Z8(de288fd8,4a6c0d72,07cb577d,8f3a49b1,9a3002e4,88d933cb,a6afc5c3,88b3714e) Z8(ec72ef00,5a503ea8,3c25147a,2dea6aae,d4f0e561,59c78f17,a26d1fd1,909ebe47) Z8(18195bb6,76cfe046,65236b5e,082371d3,3dde6946,f945c6fe,58488395,5006e1d4) Z8(4939742e,973209f4,f0eac926,4de1bb87,f229b080,8dbfdb0e,cb251d54,014e718c) Z8(b4b52238,6654e1d1,b60a1b5f,29df90ab,b352e7b1,85b5d269,58ca98dd,112f56ad) Z8(76f8db93,e86b6318,b510f8ae,e10c6f5a,d6af7452,1cb3d2ec,e1284fd9,96be7ff8) Z8(87dc0b12,77e83b72,94147d82,4fba86ca,ccfcf808,d0beed36,4316521d,b0f2dfbe) Z8(88b0c35a,ed229f83,b54b45a0,7938b958,02315fab,fdfe00fb,4915b891,83565d8a) Z8(cd5107ed,98ec091a,a171a78b,ce05e3aa,a8d5405c,3d726a17,3ea46056,e2fc7ac4) Z8(0467d7b6,3f47f6db,0362363b,c94ee58b,896078ab,2695ea17,efa1ae2a,af19e783) Z8(41d2e363,d1152db0,997fce3a,b92e8c16,8d5cc645,6d5a8c93,6d83e585,b0540923) Z8(a52feecc,195d9f50,4c490c87,d7cbd120,e0e1539e,0cb1f323,aa48c726,8d98e93e) Z8(629e7f9c,90338ede,06af7200,ee638267,14946df8,7ea54a5b,e9f39858,01d648ef) Z8(446da695,ba46e56a,d6e62337,e01b48fa,a0ab7b9d,70bd203d,b5da39c0,fbb02610) Z8(0fdc2831,8a23f915,c17eeacf,b6c66c6f,ad7ae1b7,6de2320f,52055e24,d6b27f3d) Z8(6c78b99f,f157e43a,2b34206e,80ff74dc,269a93c0,ccf3e5d7,7a3f7ef0,0133b279) Z8(8e91bf42,963ee831,edd5b7b4,d02d9d93,3b21003c,120e2a45,f43cf487,a63512a3) Z8(13571a68,c6374440,44b9d321,0d3d9dec,989034f8,bfdfc91f,b2dbbc6d,cd76c0b2) Z8(72de0ba5,a3fa58d0,9e72bb1d,f2c13675,81626e1a,91745eb5,9bfb9616,f0f12e2c) Z8(f7e7e797,4249c36b,a42b8558,b1cbe40e,2b75566f,e43e8c4d,f779d109,2e1b828e) Z8(c2d10c8b,deccd12d,11a5201a,aabbc514,85a15792,57528a77,b4b5a2b6,1bcca4e0) Z8(ee932714,a0c91f9d,05c042b4,581d559f,d9de534e,c49cfb8c,c55a7214,d969033a) Z8(a9392c4e,62b71f04,a353ac8f,2652d083,fbb5c569,119c41c5,caf8ca1d,50fe7518) Z8(21826356,eee9d959,a29ae754,c03039e6,8899cb91,3fe537af,6747d614,3b4379f7) Z8(2360dbf3,faeefc22,e8fd9549,11d5c129,b409b454,f1586a5e,622caddb,3061a6f5) Z8(2102c616,00ff3eea,fa8c2076,264bd3d5,ae9f6920,18bb041d,a2c6d51e,788cbe2d) Z8(318de655,95f6ecf8,63844730,ff2fe4bb,f2fcb247,8b654b13,642de029,f95577a7) Z8(ff146da2,b5ec9b5b,f5ab4274,67059950,3c5cce48,23c866e7,d464ba6d,9fc4b60f) Z8(3c309fd5,7d2350e7,c488dd99,d56c938e,a3f48272,60ab5359,cb1dc14e,96873755) Z8(07b801d0,7581de52,62464483,475cf3c4,2019057d,ecf4ae0a,c1caa68b,d7fafa09) Z8(7e741a33,3db10c1d,b660933b,6bd02b8a,42a0b4ff,2b0c04ad,759df1b3,e08b7bc2) Z8(9df24d34,c06f416b,1b7cfe73,9b3f30a0,11aedb6b,8dad3fab,22fefaaa,dae03aca) Z8(966ab762,fb8d5419,dc5193a8,8c29c8a9,c91fe38f,e477870a,28642cee,7192ed74) Z8(9b38a28a,8bb196ee,eb6aac61,bed30b97,0fb7391f,9b78469b,e4e81fc1,54d27446) Z8(9deda7f5,b213b57c,4c0b52c5,6ee786a8,6f1bab06,0538aec1,56be3b1a,8591c213) Z8(8e31a81b,a852e1b8,a9899296,48c5dcb4,d24b0b3f,5cc6f79a,4b59b55b,9c83b0e5) Z8(6a482f45,609477f9,941f42d0,30d2dfda,989f8903,f29cfc2d,6df451f7,79528456) Z8(7242d0ca,ddf1b444,fcb19c1e,e54bb6df,cd474df6,75cf87a0,4b6817bd,f09167d5) Z8(7bda6303,2250337d,0b1762a9,ced990f2,5bb06ac1,5f58e589,47aee0f3,8f70471b) Z8(2d28ed86,0f5e636e,425c9da7,b6788626,c821e5aa,dafb5152,4b4f1317,46b85475) Z8(2a46b82b,bfc4d94e,a84bd986,6701d3e9,5ea59406,0c86cf5d,b48ea3ad,e103f3e0) Z8(5574292b,4be769d2,ff9cff09,27d03131,ad5776aa,e97f8e57,e49b270b,6cadc168) Z8(c110c296,140ff616,b5c9483f,1d8b9eb2,c5ac635c,cfcbe6c2,f06ec0cf,656dfa4c) Z8(edbb8761,3d3d1c39,5adfc86d,a0f65511,19c327b3,110a4d8a,658248d9,fa5af7e5) Z8(91b05a75,4d3d56ec,11291a4e,7845e62f,2dd465d6,5b075370,36894876,15330055) Z8(38e14c56,4fc09d7e,020803fc,cd5814b5,5b5fd022,6a8aaf20,a81f7623,bb723044) Z8(570bb090,c8e055fe,03d22e89,ad232d4c,0603803f,6669147e,0491cf4d,9ac96796) Z8(8e70fb57,f5474f7a,0372c652,ed6b06c0,8a986e91,9eac9b26,77070578,d9f36ddc) Z8(07a7d396,4e5dd11f,795e38ea,229bccba,95f1c990,de607c9a,f9d03973,542170da) Z8(b406da15,f15181e4,34308b8e,aababa66,cf3c9209,520614a5,6f78a1ba,dc4bd0c9) Z8(c11ca492,beffc79a,53dfbd80,3a6c39ea,f0c1cc22,59e252bb,e3f5236d,fd534c4f) Z8(c656a2d9,583cd0ef,d9f7dba1,fb4fe1f5,20a8969d,91b9292e,21d1c089,9379bee9) Z8(f45e23b6,f7123315,59d542a2,f0ec6c77,bbf2413c,33b0ac14,2ea189b4,885b8b42) Z8(e65dc555,1bf1d476,6620a1d3,b21610c7,357e8376,1d5237b1,1a80064d,060e0829) Z8(cc9922cd,cb01603f,1b323389,61fec952,138d8784,a6f46a71,240ac200,d5668b7a) Z8(beee5c17,97c53a1a,7a965253,56d47515,eee564be,4e0b3095,9378ab5f,b8467c1b) Z8(ed2cc6d5,7801a681,87d30fe7,4b6b46ee,04b092b0,a2933bff,ec937742,ac7a0116) Z8(35689c30,b7723c5d,cd493ff8,3700ab70,b6058125,955aade6,cfb6fb42,eb79c685) Z8(53a4212b,fa3c15b6,7e0bef29,62728386,d3fd081f,5a565035,fd7af5df,debae30c) Z8(4c5636ab,765757af,46981736,26c3cdf8,843aa7b6,fbb47b88,85ac881c,597df775) Z8(6e0e2301,7d850c67,d71a0b6b,9c4c7d01,a7e77db2,d873bd57,9d9cafa3,f52d70c9) Z8(61cdfb62,98c1dbff,8cb3a786,cfeb69af,4ffeabda,64c38ad9,14a84fd7,4e05f853) Z8(afc36a07,8a18776a,a3699c55,2fd4e9f1,28e89134,78fc0479,6dfa8837,dd4fa9e5) Z8(2a26c6ae,ebed9cd8,fd642e3e,f8ea8e77,3eb9436b,bbf35781,6973261d,ce85dabb) Z8(db0ffe6d,92422ff8,38f41a55,0eca36a8,2bbbce91,1a887996,50e6d18d,dd09a8ef) Z8(7fcbfcc4,d2516766,9c6f0b1e,100b05f5,e6643357,98f2be9a,b23a2884,9a1b3aee) Z8(b98a403e,b2a7e949,fbd05284,e8c4b007,bfd90336,11cf9e23,c430dfcb,e217da54) Z8(344c500e,a3210550,c9be789f,316a19d5,a36c2f05,c2724e2a,d4723b63,e342ac0e) Z8(95ffc577,2feb58d1,fd72456b,d98795f3,f7eb8aa0,8fa202cd,c1cdace0,a6512bcb) Z8(ee6c3510,3f18467e,6f667c02,ccf48294,39a98801,6d014eaa,c3801a58,902e4f7b) Z8(6425a843,d77adc5f,b59cc541,babdc104,4594f4a0,5372cd90,69b5e334,8a9f5fcb) Z8(d8b22b9d,7df95802,1bb90cfb,487f3960,73e89601,3cd12f68,25a4113c,91eb158b) Z8(1033875a,37870480,142598e8,2dadfac3,d101a54d,5e5d45da,594894b3,be92d057) Z8(61a8ba27,a0e4ff10,607015bb,2997e256,66cc746a,a7d88e0f,93d9dcde,86b271e4) Z8(2f3173e5,ec52f687,742d7f94,31433249,38e20620,96e15608,aea4d485,6fcca12e) Z8(603ca4b2,3917c9d1,43c21360,c913621f,7d16b296,0f5285d8,036f03f7,c9e70144) Z8(2fcd9aac,801ad177,8169a445,d6cb327d,24b4015a,092b78e6,b023a542,3d42b13a) Z8(71b85e47,a7efea1a,db1f31ad,0ef4111c,f076b4f5,1a299a26,2023390a,649b9e53) Z8(122b5351,831924ab,b4763b66,95795aac,b9710f3f,bff2adcf,4c98d891,a98e3744) Z8(a9cf1bf7,0aedaaa6,2b84f01b,dc1cd48d,b5d49c70,0fbfff1c,b1037813,83ef5071) Z8(0c745021,02d2cf18,b1cd4a62,e0d70865,d5571a9b,fba7fb13,4d57bde4,7bd5323f) Z8(6538f897,6717387e,62e50df8,e1841b31,0272f90a,1b532f27,ffda8362,f7d1438d) Z8(a1f1892d,5b635553,d1e929bb,a8217ce8,2fbd462c,11000ecc,4bca7708,78ad18de) Z8(484f592e,e1024daf,c368c496,7cf938f4,e88c49cc,39a8f8b6,af31c372,c074eea8) Z8(d4afb568,d03a8528,d27b7465,a79f939b,9c960792,51dc4a1e,ad9eb076,d05b2b01) Z8(8e00f590,da599125,8bb7eb9e,6fca0f88,23db1250,1da5ba0a,f31ba770,adf3da4a) Z8(2637fdcb,4d817cd8,25d36ec1,94a49d95,144911e6,4a41d43e,c7a17a8c,d4406ce3) Z8(4c6607b4,a908f4e2,67e9ed7f,a034c6d8,83856782,1b1fd48a,f9872163,75e91fd1) Z8(2b1af688,e6895bfa,c6b5142e,cb6e47fb,518eef77,11a940ae,2e94b1d4,84207108) Z8(62ed29f8,7540e6d4,c8cff5ac,97da875d,3c79dd92,d9e61408,646936b7,7debb96f) Z8(7c07a506,cfb86155,8180e8a3,bbbda89e,fa3063c1,ce5b4df1,763de9f4,00b4093c) Z8(a31ab712,91f8ad74,b6d5ecd3,c3e588e0,0a3e3734,096baf6f,ba78c906,fcf93a42) Z8(97d72d91,088a0a55,aa0f5039,3eb36083,fd6d278a,e8f5f0dd,fdffb5fb,77ccfe70) Z8(2ae559a7,647cbe20,35d1f916,e11235fc,6e6c1117,285db21f,8f0a1bbf,70138071) Z8(73d66e97,ef034598,1337c5f3,13f5b314,a17c8002,d7a4656e,4dc10948,1dc398b0) Z8(b63da69c,fa9457ec,b662d2e4,2f423160,bb07415f,cd060187,d1fe3f8c,1e3c90e0) Z8(5440b34e,1227293a,2c7f128d,9d6043ea,dc292628,3c46a502,6c560a93,a9f886da) Z8(c73d8c43,e5836e3a,2c5ef6ba,29d17e18,c84bf4e3,f72ae9f5,42ee8ead,e989be14) Z8(5309331c,bfdecfcc,6c592403,1a1c54ef,4235e2e8,4ab1c52f,b2c568d8,de1fcf5b) Z8(6028cd4b,03ac1451,9ccfc687,489c479e,23ff6fea,87ea71d6,0a99609d,5f01c27c) Z8(4924c3df,af09f359,d1798462,2369ffa7,77b1760b,e8674dc6,43b83d08,66b6fed8) Z8(7a38bf41,6d751999,1f4bc3b8,f16637ea,63eaf166,a17a3e88,728b6946,09f6c0d0) Z8(9b52b216,9afcc7f0,962897c0,eec881f8,8cea66e4,b6e891d2,d2b6f345,2456f093) Z8(5137257b,fa2b23d2,d5928e54,7a3e0e19,8a65612b,6bfb99f7,ab2c5ab6,85e4d0af) Z8(5f1f9ee1,fd1a8794,b44d30b0,8becdc24,57009891,e568e6fa,1e4789f9,818ba0a5) Z8(066617b3,a3bedc0f,7c6c9df5,dfd011ad,98ae348b,0afbd340,936c4a56,8a6f8120) Z8(27fb4176,d48c6c05,9414a3ae,41f4917d,7d47cfd5,f8da0361,c0bd78ad,5dd57127) Z8(8a9ef961,ac3e364d,e1eae686,ef32db36,afc920ea,a7b95040,af4e640c,ffdc3d19) Z8(ead9401c,e2552bec,7be8235b,d1e09ca9,04f7034a,b036e70a,3abe790f,7819f0e2) Z8(a5782fae,dedec677,05eb6cff,59cdd56d,5c2ca135,ffb121a4,06e5bd27,e86b485b) Z8(2ccb7e23,a12dd97b,f1199982,9eb4ccdd,525375c7,1c6726dc,e155f8be,46e56c9d) Z8(56080695,ae816ebe,99149abd,ae389dbb,7bee9169,6d383962,e5af7fdb,f5711db8) Z8(bbdbd718,93129a63,dc6db1e3,91f345e7,22f72c53,a87a9df2,dfb0fcb1,e54f7a60) Z8(ee82f3ed,f3ee3b73,63b57aa9,6e596d88,ef137123,e4a5cb66,43d78a16,27c4ca85) Z8(3e4d4358,63433d2d,184eafe7,3ebcd3ef,60f903e1,25430744,7b6ec3eb,61de2e59) Z8(0e3105e2,87853efa,4728ff00,c4d97a75,6f010c0a,54d06da7,d0c19406,dcc9d37f) Z8(4767110f,ac72f22e,77774ead,e6f15a6d,095aef62,48945e6d,79632c86,c970d366) Z8(768c3ce0,ff2539b1,f79ef023,0b9413da,b0cf2ad7,a89b3d95,0bb2875a,5727afec) Z8(75440989,16e64272,e9162d48,ac09b365,2ee66510,dcb7c72a,b216cb8f,762d9aec) Z8(7259530f,83533aa0,08689368,00e8e86d,eeaaecb1,0d00f8b8,a582df38,77c5e11c) Z8(9411b922,4fb182ca,afc990ed,c6f0ee66,8b4cc790,1943cc5f,110d991c,ebb2dfad) Z8(6f752895,25ce0e0b,8bf752f5,a57a3fc9,4fc6eedd,0d9c2354,860c1d11,2fbfe907) Z8(77c15548,8a1800f3,39882822,44e386ca,bf0987bb,602049a5,157d2b88,9b11a3f0) Z8(cfc5ee1b,b35141bf,91be484d,8f551c4a,ed07612b,92584c70,a69f2299,01c3f41b) Z8(5acdab56,7b472e1f,7b93f306,a09b169b,cc77c271,98ef926f,422e4759,cb1be915) Z8(1376d45e,cff0fc80,dd425f2f,0929f3ad,03abe71a,7191d105,5215bfcc,5062a7e4) Z8(791c4e95,67442cbd,056e5380,2628a545,42a708ba,9e71ec5e,9a5bb933,e1a3f85f) Z8(d9d47ddd,bdf4ff77,400fae64,e9c056c6,179e2546,d4cb8ea3,477ae50e,b5a49130) Z8(797af702,992dcb34,9c565796,8c87accc,b85d30b7,e87a150b,a37a6f21,9045d361) Z8(06f07e60,b0c306ba,08df25be,25686351,7f97299d,2e141046,97faa978,a58b6c29) Z8(b80a2d6c,f1713abf,c3261afc,931e79c2,484d9b3a,262a1051,a4f0e129,ebf7169f) Z8(6f552a9b,35492e1d,99fcf251,edd3c08c,bbf622f0,bcb9acbf,a14fb1b0,11a69283) Z8(95e247fd,6db45dca,377fedac,39d022c1,296bdf6d,784e28fa,cb33b900,1c829ddd) Z8(f6ad64ce,c625bd30,a7c81f59,c1467b9d,7a4c54ff,e7169e99,2f859e9b,bac693a8) Z8(c328dd95,ec22a15f,952521e6,e4d3d933,1394fee8,033e0fe9,f19ff770,65cef723) Z8(2b9b511b,e9525a7b,d836d2aa,5feda65f,b80e4327,1b77bdc3,3ad2cf1d,bd5e5374) Z8(076e0644,37d3c42b,73c1fcc7,ee7de54e,c94b46cf,ac72d9a8,125e1ca1,db70d06a) Z8(9eef6981,ce260aae,bded63aa,4213d437,bdf7f302,7e8a258a,2c3a852f,19a5d281) Z8(cbfd7b93,4a3ac6f1,fa2ce09b,dd164031,958e49b3,328a0858,1d423a0b,df960ee6) Z8(2f71223b,d1a3f3ea,4ef7ed40,4f1d1158,0003c862,30e38c17,90cefe16,ba78c602) Z8(5f0b79dd,3f2e557f,a980581a,587f07ff,26c2b7bf,185a9759,a09b0715,48f05fd1) Z8(5f2446a8,a2e414b3,24cdd67d,d2f5fa00,f100bca0,4aab98b2,976addd7,8daae11e) Z8(e3a544dc,ccc5b710,eb917f74,cad531a6,483c0438,2abce623,a1a856c3,778e07e3) Z8(aa872f4d,07cf0bd8,b014a636,fa8dca70,9837517f,2d0d7184,0ca860cf,493a5b7a) Z8(20b9f5fb,f0b17bce,70476178,406c4c56,32e6029f,8023345f,9e0f3ff2,8b4d00cf) Z8(e1acb9d4,55e63cdb,27c57f6e,46159818,413ca327,0d45525d,9195a487,7ee6f16a) Z8(b38455e2,af229323,a905030a,763ed744,00d4e1f2,d09896c7,f9d09438,c9dcc6a6) Z8(78e3d613,953891b0,70055d2a,c7cac96b,06c4274c,5545ef4e,38cb9aba,357a92ee) Z8(796a885a,debb772e,7d6a9570,847204e0,603a675c,da4e7170,3e26ac69,ba405d33) Z8(92cd16e3,34faec15,eb9be7d9,45753d7e,a20dce93,c32d8ad0,0e2c1e8d,2f3d80e6) Z8(dfba610b,763c8bf3,6c1d6e2e,0372174b,54efbedb,7fdc684a,e2101862,ca474688) Z8(0e8c6ed9,fb81cd41,95a0cca3,a6bb8177,e9deb217,3e650ad1,084c914a,889acef5) Z8(fbde23f7,935d635e,66f21562,4a0f57cd,7b95144b,4a94272c,d0506a75,64fe41aa) Z8(cc333293,688e8c55,3b6483d5,abefe4d0,90b7ab9d,156328d5,19e2c0be,d7ad5c2f) Z8(62f75217,cfa80be4,d04570da,bcb772b5,e992da56,95a70d07,4e566505,a69f866e) Z8(a5269c45,050aab33,d7e361d6,87c14c2f,d54433d4,9e7116a0,dc2d5ea1,1a542522) Z8(66f8c9bb,c53c45b6,5b6225ab,32552fb8,69f881ae,b85c542d,a4ee61e0,2d5dc702) Z8(cf132337,84ce62ce,4664dc49,2cae07b5,27c33114,2bad602b,c42365e5,16f4b675) Z8(377b939a,9aa53c88,f34a1414,cbc0a619,6e741484,ff4c3987,d6f9be21,6085995d) Z8(9a1ed953,4f801b5e,3e008a3d,249322bc,a38ad1f6,5c73b9af,8c87b7c4,30b3719c) Z8(33845d54,1b275047,a79d10bd,9c649524,70592812,690c9801,c0381ce8,dc9cb39e) Z8(40773637,dfbd208b,5e834522,aa9b747a,5c6a2284,71a51e40,d7168a4d,9732bcea) Z8(9eceef7d,6c7d9378,f1aeac0a,b0746ddc,3dd3fb6e,f23ec644,5628ee6d,21dbceda) Z8(36b0c89f,148c7cb5,2ecfadc7,dd68b519,20bcde90,bd161211,ea198089,ce92fe1c) Z8(b8133cd8,d7b4afd4,1a5a797c,2881e7a4,7d092188,c079f617,d2568d36,f910788e) Z8(49d92407,c895ac04,f6f86016,441f966c,ea25bbb5,1bda6655,35614bfb,fd2cb96f) Z8(8ff4bc9c,fcedbaf2,f14c2cb3,7b95a096,161a4ae6,78ad5842,0183b80e,99a56c90) Z8(724b6ae2,6ce4b9db,cf0bfb24,35140fa8,65e9da8e,1af051d1,6f41ffd1,05588cb9) Z8(2ef27cc0,5a155cf0,d9f1a979,05bb443c,5341738d,a73e91de,27f77a59,3f47cae6) Z8(116d9171,2f6d5c66,240d6c2c,61c9a399,2c091e95,13182a2e,43eabe2f,38f9cefc) Z8(42e05d64,e2277056,14e88f9a,4ab3fa95,c7739240,7c34dcaf,855c739e,0cabb4d3) Z8(62ebf381,51bd9ed3,9a10bd6e,7b75f42c,d2062109,e9617bcc,eb967590,34e119b5) Z8(a558d929,b8e1bb97,c5e8734e,43d20c78,aa17a975,b8332671,641bb653,f0e21ee4) Z8(ac99bc46,471d1d3d,dba61f78,44a099ef,8e73be93,1fce56b3,e63d0ab0,1d9a5f47) Z8(5e6ba13e,85800d4a,43bd7080,e6ad6405,745aab25,1d4cadac,25517d6b,b2539f28) Z8(fc9f6c09,2321114f,3959d0b9,e6e6607e,ec2b8985,e051d233,e5efb715,7d647d92) Z8(e3641b02,3de81bda,2f4902dd,e4bdf9ad,2b49f9ff,b65f8d71,2df65e23,fd0aa30d) Z8(f965fc03,8528d9ed,0fa6370d,aa5626b2,df6ac5dc,3b011248,a546d951,b112196b) Z8(260b89f4,03ef0786,b0b12348,b4eb6cc3,9b77d3a9,899facbb,2369d688,3762dc4e) Z8(1c418a52,fdc2d958,fef1d902,e5db4a5e,096f2649,f6bab61b,a3ac7d95,a7650642) Z8(4e3e7bfe,b5013c38,025187d2,f8edaaf7,c3d508dd,b8ae6f4c,c399abcb,8b9a41e3) Z8(c8ce20f9,3ea85da0,2ed21a61,16eb9831,364d7eee,3d0e4f1a,3580ca1e,f8adac0d) Z8(49e965f2,6fa069e7,52a93a5e,7bdecfb1,3299b4de,b0566aa2,1023b459,19116d8e) Z8(13aa621d,b352198e,a7071d88,2c30b93a,ba3b9428,9bfdb470,d68970b4,68b741e6) Z8(c679e7b4,03b9b399,be381086,ab8b318c,da0d97d3,3f75a798,4bb04cc9,bb9fb5e8) Z8(ad52e737,bf14eb2b,7a0a8341,731b3c4e,db1e859a,40fed235,57656752,e4142c6b) Z8(8e1e2860,7efe471c,93feaf75,db80bf6f,b1538de9,ed9a6880,f850f9b2,2c0153fc) Z8(ffa248dc,8c827fee,58b0e672,4cf97837,798eb238,b692a0b3,edc0d6c8,21c53cfe) Z8(e1b7264f,cf471610,5f5d003e,b0629220,38a5f3c5,5c665e28,1c8dac5c,72277dbc) Z8(7eef04dc,b6955168,ebd4336d,d835c16f,95d14bf9,64145c09,4610f87f,66002690) Z8(2e7df485,0dcfe433,954d4858,c34f97eb,a1611387,47a15967,5a0e4ade,2f30a4c0) Z8(ccae53cc,58073f55,c8c36793,efbfeb82,0bc4ebed,4ade7c73,880266f3,baee76e7) Z8(0c2ca287,5f93bd53,5572fd19,0cc156d6,85a43491,45116f40,bc90311a,8693c37d) Z8(c093c432,5e957293,4746f80a,5f95dbf0,65433a4e,068ab477,baca87b3,92f33fc2) Z8(f4e0e8a3,76da80d9,a6e6c6a9,ce8970aa,91bf0837,623989d3,40ed43e1,15c1e850) Z8(a1171a39,b4bbde9c,60cc7489,007e7d9c,1eda56b4,dfcf2460,0a40a1d7,90724102) Z8(e4618fd5,aa215215,624d407b,b8225c9d,e038672b,ac018e35,039d3e2c,b86f736f) Z8(060ae3b1,2c5bcf3a,b5aa3377,3a90dca7,54f1b8d1,7af09fb6,c9732065,652bb747) Z8(e7e16ecf,caf62f64,7493a521,4280488f,c750bff6,d9e2ec57,acae33a4,0a890cf1) Z8(44a186da,8e986808,5817e290,a1980eff,5c95e9c7,d64f2ee1,40fcf79a,d81b9a3d) Z8(2921f92f,a526dfe6,d95fa4b8,85916152,0236d639,f409129d,8b703963,c516d825) Z8(8e46c5ee,eef8a59b,1e1c2b79,7d5a821f,f2d309c4,b8296629,0f986c65,17a47959) Z8(64efed58,97d79567,e845f856,51623b4c,56fcd505,40fdb1eb,30d2010a,3b48f14d) Z8(f5cd52fb,a54ad888,a200cbeb,50b41664,c63e4671,3e4158e6,3f3c6a98,6eec0125) Z8(0ca79e87,65245f6e,de0dc5cf,be8f4020,71a3e350,d9b78f04,419beab4,00266ec7) Z8(21bdc6a0,0e25e897,697e9293,9036d94f,8a8e8281,ef1c1605,1d21eb26,ace98c2e) Z8(c6a73ac5,153485d7,c5b1cc83,5f00c5a2,1ed599fe,6ceac9cf,2419d0af,adf7a49f) Z8(6e15c9d3,e9b98fa0,59bfe9b8,5d6a33ac,543ecd12,f7d98716,ba9b7aff,bb4d7936) Z8(88a3bfdc,0c333453,82a01bc4,adfcd18f,28671be0,2d43e205,598cbe14,640db20f) Z8(baefc57d,e86d152a,28b0b822,7905d0e8,9905d037,39e4bb3b,0bac4a14,689cc2e0) Z8(d20d3bdc,fedb827e,a0114b62,c2c72952,6be313cf,786ec11b,bb39cf8c,d128d10c) Z8(d500d868,72796ef6,c28397e4,8a31e818,344d3122,1907f7b4,d851959c,42096ded) Z8(f37a41d9,d623633b,a1e672dd,dfff72f3,9bcdf744,9116fc77,51ca3fc9,d75c41ea) Z8(3e8e35f2,98031d1a,254abc72,0e65b2c7,10f025d0,bd64640f,752f55b1,242e9023) Z8(1b13bb21,ebe86252,d6e8744f,7787dedb,c2f53f07,3fb1e045,777cf11f,d02e8b19) Z8(b97dd591,c2c36c61,38bcdf7a,1f256273,3c20376b,a6dc2196,be1a8454,5392cd8a) Z8(23f37b4d,c63b5c29,e5557418,33de32ce,e4241815,2d5edf0f,e9325e6c,b234d140) Z8(fffab36a,4dc8a765,91264e41,10f9624a,31896303,d8a64ac5,14c70836,61ad6c55) Z8(81ee5e90,733c6757,608b33db,d2e2d194,85191cc5,d6d3d470,1c8750c3,17ac5f93) Z8(f905a539,7441cda2,97b5b17d,ef67a51c,1c8d2c8e,20345ec3,480fc388,64de21a8) Z8(48c4d433,14bf6797,56166eb7,3531d0e5,4defa236,8c9b4bfe,442efdb8,d7d88ea6) Z8(52b21696,528b1e2e,2d186a64,dc06756a,5ccf8451,dbb362af,8cce3747,37a24e6a) Z8(6c2ef6b0,14842df2,4ec0f9b8,2a33f3be,12d353d3,bcef539d,6fffe7c4,2112a49d) Z8(8ee32558,63542e08,e1f3d94e,61899086,b0829783,093e1d69,cc605ff5,5947c529) Z8(bb601eb4,b16366b7,d20e52ca,02062e9c,2490da4c,b9ff1ae9,b4a216b0,aae2e5bb) Z8(2a493b17,b1d57457,e06ddef6,90daae5d,155fb454,9e717ff3,95271f99,f778893a) Z8(7ae5d8f4,18ca0e6e,1083822f,7d2012c0,d5d6d8f0,48d649e8,c8abca07,3892fdcc) Z8(3aa5ef04,3c373bb6,0d7cb031,9e093301,1044d707,b7a9f58c,4724f3d0,f1eae917) Z8(643f9d82,8f0bf98a,88ccfe26,0f4dee43,8759907e,2fccc86d,42cc28eb,933e0866) Z8(5065ba8f,2b56477e,947bfb3b,96a911bc,91f1d81a,03b4503f,530fc162,429c2ecd) Z8(c93b2762,d01d3980,6425dfac,8b42076b,8cb914d0,fbf3f6e0,7d3a7780,83d775aa) Z8(aaeb5f46,24a1313e,8a993cee,37a37e79,b5c98bb1,11fb4c25,1c388e5f,09641f78) Z8(8899457c,51b5610c,006d3c78,bd3fe9cd,15ffa51b,4a3828ba,9e016ae4,ecbd7a28) Z8(0350da4a,66ef0687,c1144074,c2aca536,7aa09696,b078a13b,3c21c225,5bdd7f91) Z8(b0b9e0e7,1ee48e7d,5b7e08c0,917c8a41,c695d8d4,63afa2b8,fe72a718,47acf453) Z8(d7ac9057,cb2fc73a,fa5b2c54,373b4c43,e6c95f3d,58fd4506,5eea6f81,b670bea9) Z8(abb500b8,cb1bccfd,7069f622,43c63df5,5ea568a7,0ac41139,97d4b4f2,707d8a45) Z8(76cc415d,c5af1198,844cb095,6f027ceb,3ac4b6e0,2083809d,d57b47a6,a9ac30be) Z8(9088c2c8,81c5d5aa,8b6ad0ca,6017f943,593af066,4784a26d,ea34c41f,5d658178) Z8(3aef813c,47cdac4b,b2580b90,f8c353c8,285089c8,b0ac52bc,3191ac56,0c4e0870) Z8(d8f26dca,cb44eaed,6cf71ade,1a9102ad,3d56711f,b8cf7e96,bf9395df,007785dd) Z8(4f0fa133,265be9a5,3c721c58,8127e70d,8036f2bc,c91c8b5e,b364a074,09c27921) Z8(fa9fbef3,7cd0e4d5,6837e641,f2af9439,14428b6d,a00840ed,d933e219,ca315194) Z8(80dc57ce,22e84ff7,91ec6f88,26a3d922,249cf590,558141b5,d1da09f3,783110fb) Z8(f33f24df,6395f731,2d814f65,9845f9e7,88a1e8f1,da0cd423,20aa833f,a9f9ca61) Z8(c6dbcfba,b845a7e0,065be030,9d6a8839,899b6b14,e81e2dc5,7a732fd8,59959326) Z8(84727387,9a580f07,8617bf55,6a18a118,8b63b0d1,387240cc,c6d78433,0b0b1cb7) Z8(e5f1752c,35237e67,da6ebbfb,deb51086,12223aac,a14f98ed,f447a243,349bbae6) Z8(053c74c3,23c26791,237e89ce,72f9f742,b17a7d4c,98c9eafc,d9c897d4,268764e2) Z8(3b8f57a5,39d732f5,a78a05a5,5463369e,8e689aae,47739cac,c6010098,9e6e8d0b) Z8(58f13f59,d4b41b3a,092c6c64,f0a3f218,be6e6774,bb741d86,a65a9d22,6ea4f224) Z8(764b7e32,418952e4,6e120f1b,e9eddcf6,ad1d6506,8751a5a1,0c9319c1,5ebcf0eb) Z8(d7d2a328,72a31f86,745c0b15,50e0dd97,750d31fd,74dd51cf,6bbf8d3a,1ebb5cd6) Z8(69ba8070,a862c2fd,a48e8dfe,93951e81,b56f7dcb,aef939a8,5613850d,d9f61827) Z8(341ef7d9,4c8a8a58,068ba76e,eb771978,fbac59f0,c0ed8281,ca09768e,56ed7585) Z8(83d0cf75,292bafe9,2832df7c,063c57fe,cec29804,2b0db64c,d32dd8ec,f3e48d0e) Z8(6bd1a582,c69460c4,997976a2,460099d8,9ab1a6e6,a175baa1,3c79a9f4,bdb51a59) Z8(09e6844b,0b74e21b,fee26581,a9515711,66c864eb,9fb1f926,b1b05537,31f6ced1) Z8(1d099880,b8297a30,055c6bcb,7d47ee8f,c93922e9,a0cd222a,c0606acd,f2aac943) Z8(442ebafc,889aa107,fce93189,7b3673c4,877254c0,8e5dc037,769f62f3,091fbb2c) Z8(c1d09294,d23f29a6,e9841586,f2428640,c73607cb,8ef53bc2,225b0741,069127ae) Z8(2f788c47,8aae5807,1203a9ec,1b793e84,94e2e724,f8eaf401,b96c86e9,3dcacb97) Z8(e5f9cb82,860aae79,fe21f1af,027f0223,f41589d1,e039ec5a,5e6e6677,06831b9d) Z8(db3b757b,7057679e,6ed829aa,7c8c383c,55288c4c,05f688fb,e2153642,6f8e019e) Z8(5d260f85,c620cd1a,b064a431,928c6016,3b8383cd,4984ee88,d0bddb9d,25af0332) Z8(d9ab8c9c,f89e2e62,62b6d795,8efe373f,add42122,1ea2e9ba,b6a8efab,6c7dcc55) Z8(dc438025,9b4185be,3881647c,217200f4,761f4754,eee4437c,bcd8ee36,0e0de0aa) Z8(986bed93,a5e3d35c,8fe2ae08,ebe7d2d3,fa0a3fec,699b18f1,fda51671,3e6f4ac4) Z8(bd49d4b4,810eef13,8469a875,7610f801,38b094ef,130799bf,90b4adea,6d74e8df) Z8(5e23e245,1b042486,e3e5ded0,954916b5,d2a3d027,58b9c46b,c00df9e4,bbac988c) Z8(e81ff2f5,65602033,80f00af8,1b02036f,d60d674a,82c2170e,0fa2bdce,f2645f7d) Z8(3fa3c22a,0c7af46e,7cab598a,71c94701,a65e2dfb,05d9b554,2da1d119,f97d4674) Z8(b48ddc27,9c86e488,9f67c22d,c8ccc3df,c256ee80,bffac15d,bae6cab0,98b013a3) Z8(6973b3e8,67ab6b1f,b84652b0,0f9ceb99,75e81ae8,b2d5552d,22b3dac6,013532dd) Z8(24e01427,be5551f9,fff5a123,fc836f31,af385315,9bf9e9f2,72f43017,1f9eaa6f) Z8(806fa86a,819cff7e,fe962aa9,e02824e7,7062e2fd,00a4f49a,52be905d,a049aa31) Z8(967f2743,d685468d,4d77cfd1,6771ee06,e7724a29,9b96e0a6,d663b65b,ff138a12) Z8(4359d077,80d8e55d,022230d0,e6bb0427,1fcfd8d6,c07bf262,bada1359,f29e3480) Z8(c8762f55,7a6a18b7,99000ce6,1acd4a7d,9b2f74ee,3789c5bc,facfe46e,ca638068) Z8(d17919b3,4918b1ec,9ffe10a7,f1a46e96,34d129e0,182609fe,f845e1cd,74462897) Z8(ff9ecc6e,a6b18b1b,2cd6d010,24291371,55e6e609,141f515e,3018eacb,8ea1b526) Z8(f630218e,2f6da052,8e04d3a7,d03556f2,844bf085,acb85b11,f0a53e02,d0d5e59c) Z8(06ac449f,cdb9f0a8,94c7957a,a378fd3d,8d544cae,79945a87,9d02a803,7d9e6b1c) Z8(13977c1c,a245175f,89085d9b,086e9d46,e69d5a0c,ec29d84e,19ec2c62,9bca449a) Z8(48bf61b1,95df6774,edb91f61,5d9c140f,23550f43,34fda29c,25c7276d,963ad5d2) Z8(8bd4c1d9,889f4fda,3e30e0a9,db7a7f02,1722a79a,47511164,63343d1d,80b08cce) Z8(2eb04809,811b1307,1ea35f12,7614121e,5dfc1a02,28771c85,e418ec25,0c1d0e1c) Z8(66e7bf78,cc8ac8f0,ce03c1fe,c471fff6,0372437e,46aa089c,a32668b1,c5706bb2) Z8(dbf6d062,c4015746,fba87a8e,a2cdcb10,fd35946c,a3025ac8,36bb0c67,e741a113) Z8(3ede39db,ab59169c,9b7e1421,1d9e2bd5,9f4ce05d,034c11ab,1eb33550,285c84ea) Z8(42afe364,8fbde714,0437d164,266ccf51,40d899a8,a95fd0ee,0a09f960,3d6c1366) Z8(567de8de,036c9679,72fec915,cf7d7da6,6ad8b210,ed1fec6c,5159626d,afa06bb4) Z8(047d0157,b27d2fd7,02788995,baf1bf4f,36969a6c,949ba3a8,7b7674db,6b83e67c) Z8(4c7532ec,e0e38fde,e2e7eb76,01bdc212,eadead1f,ea694993,44eb271b,c72b3176) Z8(b55b0757,84ba2992,6f0d4902,2a129aa5,e549c413,d78943db,55e68864,a4c8051b) Z8(28fb484b,5fd07fe3,1cee0791,c7e3cb5a,8a433e16,2d5a341f,7b0864af,503416ae) Z8(ac28dc4e,41b348ea,4867f571,81199df4,1bd93bc8,5dd917f0,1d7e2eff,2394dee7) Z8(7cdf7c55,97fbe543,df8cfc98,9b059eae,1155775e,1718de8e,0bcafeeb,f57e9655) Z8(9a9f25f6,d62613d5,2fff2858,59bd8c30,890e5a68,1dcd7e96,3a407b9c,18af433c) Z8(353591f0,a2e49a11,420724fe,892e52e5,42ad9e0c,aafc2061,03dba901,92e156a0) Z8(b7fae92b,845b91d4,e0cfa63e,3b7010d8,2d1729b2,b847deec,56426835,9536ad2d) Z8(7ebc8d61,72d16945,322e885b,a8f29bba,55a3518e,a797b1dd,d0805454,40d0d229) Z8(00f1e47f,ba1439af,0ce391be,5828dd2a,4bf0b73a,eef28aad,12383671,0606b905) Z8(5f3b9553,b5878241,72ad6473,cd4538cc,6bb142c5,5efbd767,221fec8d,4a222b77) Z8(51ab79d8,2857afd2,fb64aa39,47822e76,699e33ee,f46f931c,ccb53267,bf368bc5) Z8(caceea02,9526785e,2a910532,5a98ee8e,0cb44051,257801a1,f764355e,b3839e9d) Z8(94b779c0,5b833a1c,653b83c1,3577441b,d4ce6488,d456ab6a,5412ba6d,e0d740c4) Z8(425324ef,b556acc8,0b5d9925,b688bd3c,face3e50,26338b7e,ce6c4039,4ad42eda) Z8(c6f8e91a,55c0fb16,8f0f056b,a4df39ff,c63cf98d,499e1a49,f64fb205,960a20df) Z8(b1f9cd81,221e82ce,853b435d,085e6382,b106b7bd,c1aa9afc,8acbebf4,06bd4bba) Z8(9bf4a4d9,351dc11c,1d82919f,5bb6b959,3c2776ae,8d6d7c27,d8d0dbf9,63ef2a26) Z8(fc94f734,57767da3,dd2b2213,2b88d46d,f7ba9a51,85ee2b2e,ac1f6ad5,adeab1bf) Z8(9701d6f2,feeb1c62,59c20537,e49a9555,a24db612,72ca9898,904a2ca8,fea97efb) Z8(61744383,5422b5ec,b5a6032a,60b8413e,322fd0f3,58e16a2f,95e09aa8,077d05cc) Z8(a252c846,ea1e89d8,6bbf4064,2a493cd4,cd6b5ddc,1dcb2791,f305e52c,6cf68aa8) Z8(82a5aa1e,3d7a8ac3,d4d04c1d,06ea1c11,30cd1210,aa2d9d94,a8c08a63,4797a28e) Z8(759ab934,c8234314,4caed4f8,662665cf,70c8f888,a98b90e9,06146f1d,3000e784) Z8(cd2f3da8,d0074d5b,a42137e7,96234295,2ae13d13,e54cd16c,e36ba645,f52c8cd2) Z8(b858b4e7,089614e8,92fa21a6,a8640749,d423f1e8,3e8a4b7b,464ff83b,71f74b7c) Z8(4922beb8,30317100,d1175b84,4a34b019,f7a3d15a,06a38e01,58eee977,fc3f13e0) Z8(434e1a0f,e3756d3b,20c3f3ba,26f21bb7,6e210a00,6aadcf39,4ee1d26d,6a1f9eb0) Z8(9cb172b7,88d3c875,c53e5c08,2c8cb9b5,454c4284,b00dfd11,904d0464,439eda07) Z8(fbf07a3c,02bfd1ea,d47898c4,c8a7d5b8,4992f83c,6a2c5842,ac30dcc2,c60d4b3c) Z8(1855fa10,027c8f7f,4413cd25,4f0010d6,44c841f2,52ea70f5,b8ab2445,54343f7d) Z8(21528c07,9ba3fc6d,6dd3fd30,b1621276,2755a87a,71c2154f,c26a3b0a,0b01767e) Z8(f0b7d4eb,be719f12,07744c3f,b5dd45be,e566ad3c,33677009,fa0cd9f1,6913dc64) Z8(c756cec9,49848de7,84b4aa2e,f0e5a54d,629cc6c1,47d47c14,3eec7e6d,904c4f00) Z8(dd143a29,3b0bddd0,30d1d115,cef24a69,8466b26c,b9df93b7,66a4e5ad,c1c5b014) Z8(89ee14d5,c81f55fa,530241ad,cc9065c0,42146687,b303baa1,8118136c,927e5626) Z8(b4e80fa4,39af7c44,8dcdf25f,a2079845,074bdea8,e0849840,060637fd,641f37da) Z8(eb7004fe,46a927e4,2d3acee1,dc7a7c32,b9c84644,dc7686da,fc301d78,82c637bb) Z8(3525ebad,73676441,647fccdf,6811f1a8,c4852498,f348b569,5bf683e0,0174d6c6) Z8(a06efded,e2b0de09,53c35401,7093f8ad,0f76ece8,e8d60378,7a5993ec,9f8c45e0) Z8(8ccb9931,5a531600,c22d1c4a,4070e37a,ddde57fb,a30eb147,8ed86a48,b22b2296) Z8(d5d05093,e7b7ce4e,1357b282,1fa3a4e8,4fc4a44f,9c047c28,8f395a10,ca89ca50) Z8(06353f65,d6a3251b,d23aa5f4,3504de0b,242ad5da,e01e183a,694d99f0,76833885) Z8(bdeaa24a,dfcb9099,6cd36b11,ceeb8d13,ee39cf05,63ec6deb,3d1a2d81,149f5ea3) Z8(6afaa033,22e94dad,1fcb8d63,cebe7a1f,d0f59db3,098ab739,66f15283,44e103ac) Z8(61f6f273,8eac682f,c4805d99,76ea5850,64cd92f6,a2fd6d08,6a228909,bca3ff7c) Z8(6831da14,807c3220,45dac9d3,ec18c96d,c24fd23f,69dabb23,ccd18252,af037819) Z8(c83e1611,e2bed73a,b66e53fa,72557dd1,1a1c7afb,fa9cd9c1,f43f7e9c,6d78fbde) Z8(c3bd937d,b0d6b4bc,cb0a5cba,f4907faf,0ce69df1,860a774b,98040d87,538ea0c1) Z8(418fc6f8,da471fb6,02231b25,cddb4faf,40ee75fd,a00f4b5a,832544ff,aa6d43b7) Z8(d8991020,f48906b7,10bea83d,85dbf00c,d066739b,dc2ca45c,217ddf51,a59ff340) Z8(ef7651d9,f1bf1647,f2d54f6b,0eb4ff03,1e5cd0e1,4e2411c6,268137d1,0ced2476) Z8(c08fae75,4ba7e452,c06dfb35,78e8c9cc,c2058eec,f15f6eec,46ff2c83,a41b6626) Z8(a6ce14e6,cbc758db,66249a5f,cc55053f,34869c86,050d7993,7fde8c49,246d5abf) Z8(e5270234,aaa4bf05,c7bab166,d2519caa,3b140f45,393412d8,98f2d50c,407b3e5d) Z8(3a9b0baf,1b0f16aa,5b48fca1,b582d316,964f86cc,a79a7889,2a28a22b,d497bfb0) Z8(f9b6a3d0,8527c462,a03a45f6,74986758,69060803,9bed7d12,6b2422c8,613cd5f1) Z8(48f1d99d,89bfc90a,c24fdb92,bd80a7f6,2ea8af18,4a9b537e,73be392f,cada6a63) Z8(8a265a5d,5e543099,7119ffc3,abbbf34d,e0e867e0,ef580996,66911152,18ee4fed) Z8(959e7d0f,6260ba6d,95235401,a1dfce22,4a83808b,ca6d32cc,1503cb19,9f304d85) Z8(c369b05e,2549c028,2276a7f4,f2a27bdb,77ae081a,3eb3f97a,69a080e5,81ea7d9b) Z8(c1159f1e,9fac1b60,fd397588,d08ff8ee,74cda7e0,7d9d49bf,749fc5ff,d02b8dd8) Z8(668c14fc,bd8c0a3f,13ba47af,c393876b,5b780ff8,cc5d3b3e,1dcb41fc,a05efbf6) Z8(bbef38ad,cd2f0edd,0cb988d7,c02fd68c,1a0fffc1,09a7a15a,be6327f6,bd2d2e1c) Z8(989be821,7524d28b,81eeeb2b,e27c2e25,5fe06c06,be61d652,8a31f8c5,09f646c3) Z8(e1178a2e,c5e10291,72b6387a,ed68e0fc,9fb59f1d,619005f5,243b4352,8a4bd5d9) Z8(12ed07fa,a1de674f,8ea99387,cc12ad0a,bb44392e,e95524fb,f28c2de3,4825c313) Z8(705d288b,ba82e4e4,cda6fdbd,aa85d7ed,d1cb5ab6,2cc227f5,1849640b,984258a4) Z8(e15f5080,462a13fa,0182da03,b36212e9,3bc842f3,56de2510,61df0c4e,cf9c350e) Z8(1eee0dbd,34a9cd5d,68725494,2c64c059,e7fe2ae4,045b1c8a,760bd67d,3771dad1) Z8(0617b104,94819b05,9785e8fd,5745a3df,42ccfbcb,f459b117,67bb1823,ad044901) Z8(5054bc8d,4f4c4444,82ea31d7,5c2b3662,90aaaafb,38664298,3881c777,829bf0f7) Z8(38de2c5f,dcda4a61,f2b8ebc7,afe2edfe,a1fe5fa9,92656327,4706b8d8,2f41f966) Z8(b88a052b,7c0a5e1d,a80ad130,64d9e4b2,25e90503,0d662823,d12daee9,3002d95a) Z8(2fa652cd,2c2040f8,58ba309f,3405dcf6,7a8e9022,a41f5bc5,3d5c8534,2cc93381) Z8(dbb22c17,bee1744e,44ec1339,ca7fb623,26c59e33,b189e1d3,066b6dd0,47ad09b7) Z8(329820ce,b35b529f,a43b86d2,6613acc2,9160e187,c68e45a9,efa16f22,d2c990b4) Z8(56688c15,21c5e9b8,bf772dbf,1f981a6b,6a521c1c,6aaa9e9d,cca9916a,2c5f5d1e) Z8(a2b6e386,c35325b3,7df870e2,9d1b60eb,bea48e16,d034f527,112128e4,bb0f696f) Z8(7893bb42,2ba849d3,efb1a162,c5ffae81,3a240564,d49258b0,f22848fc,3c8a992a) Z8(999a07ee,d197ebf5,81847652,3030719f,a4f09e60,74c8ee10,58a09213,5c96b4cb) Z8(97a93926,e52250d1,af57830e,cb125696,974fe4ee,125f9145,98fbdfa5,ad26c2f2) Z8(f6a59084,e7aa9459,bf1294ff,9802e59a,e9b05eb1,a0bd9f53,530a19e9,0f52953a) Z8(5731365b,1a667fbf,2e953616,c23b9c5b,d2f8467e,db588768,bf30c004,30ef44eb) Z8(3773a533,73228656,d8030b46,f76e387f,34dbf9bd,3e6c7456,d7512ba1,a2a34833) Z8(b80eb18e,39e6b22f,a3b4835f,92b9b376,8aaa4fe2,80195418,bc970ef6,7dad3cf7) Z8(4bf3202f,b08cee0d,2a1b5349,3b318536,c60e5893,70987778,28356121,8de4f0cd) Z8(45349112,4157f31d,6fc656a7,297097b9,ba98742f,7ec7ee88,b8b8568b,42bfe394) Z8(03a0ee2f,677aea8e,a45fb6e7,449187e2,8ceed919,1cc3ecb8,ba847ef9,a1b50e7e) Z8(7a1c11ca,a67543f5,f87c9b22,79aefaff,38b29de8,dfda0c7b,c9118e32,f425b77f) Z8(923bff0f,bb62f54e,2fac7c2d,c5c65842,0391e3fd,4c3e4eee,56f8a9ab,1de7d666) Z8(f11a2c9b,8e9ad58a,e6609b25,689b9864,b425f197,83a3f9c3,2da146ad,65f755ae) Z8(e453bb2b,57cec152,917375e5,37b6a77c,c1822f97,bf1f14b2,d5b70003,17190c68) Z8(2fca6ce7,f6864a5d,830df26b,bd4538fa,d768adbb,9621deea,4d0784f8,71292a47) Z8(eaf6b323,15b7f882,44a11287,ba2188e0,381fbc19,72096840,b84c6eb9,b0e0df3a) Z8(d45b33c3,336d1be0,bde280c4,5c735f9a,6c2f6b73,9e5bf751,cce3247b,e0aa7b2c) Z8(d70bcaf8,63b349d3,dfb08f60,32848ff6,fd02747f,15bdb641,f0516284,9c39c2ef) Z8(4ab81b22,10f2ecb5,23cb3b98,25a1b531,f8f7f211,2386fdd5,7d71b586,d6a43be9) Z8(ef6e6ef5,fa63bf04,22c95a32,53023cec,70a95dd4,d59a37be,7adbc77b,a1972488) Z8(fadf8d51,bbdc4bcf,3c1a0118,17d9849c,65d98081,1b31742d,5d81f6f8,b0d4a197) Z8(f03e10d7,9f21032e,90c7dc8b,2e6775b9,b1ba7774,3695d7b8,73633046,1400e7e6) Z8(677a9879,061f3558,42374d6b,141690ad,263bbc14,f14a0c85,2c273826,aa369f93) Z8(3edf8771,a6e13c6e,acd7db0c,025b3f4c,f919f470,479383e4,80628501,e39513ef) Z8(13c4693a,7a8f05d8,aa67a26e,768b9a56,b34932d4,f6851cab,403dfa31,c8af55f0) Z8(e87ae715,06d6a912,d57bb8a5,fdf8e5c2,4c749446,856c0035,e893b7ee,70dde994) Z8(85ef8c3b,4ec0ec81,fa96d02d,0552992c,01c13eb9,c46462a0,6038ebcc,14521c3c) Z8(0da26cfe,c33df6fc,c78f6a24,b08d8942,aedcf2da,f849dce0,afddc324,58fa31ba) Z8(80dc506c,f04922f5,9d9c19db,972854b6,7fb81ee3,aff7871e,eb5180a3,f882184d) Z8(5d02a4c4,02fbd99d,984f9700,6ef450ed,76d86676,e05da6cc,f314b3ab,bcf17d7a) Z8(00813c9a,c9f23806,664e32f3,cfc8990e,668c25c7,719c0d9a,d72c3ae6,96aa9971) Z8(21866d3e,9c6709cc,c270559a,fb23296c,daf69535,f6a65b91,e141e0fb,42668c60) Z8(60897aec,2411fc04,cdd83b9b,1b680dbe,3b8bc47a,e0e05e9e,98ef790d,70c23100) Z8(38a3265d,eaeddae9,1fbc8b11,a17194c0,41510b45,d6e16756,48847fa7,04db7731) Z8(c0ac78d1,865f6833,17728891,3726f7c1,02868257,1c764c4c,715a68a9,cc291f30) Z8(da31ffb9,f27b7659,2609811a,0894324f,020456d9,9088539b,ee7ffeda,dc587b5c) Z8(75bbe273,6d94b140,d746626c,f396e9da,92924454,9818042b,24d94723,27f02f10) Z8(73ebfddd,62312aa8,776c1df8,40b1b278,c30f39de,c22925e6,892b504f,a097ebba) Z8(503c7238,72639546,81152d80,d8379b9d,a5a2dc03,3b52f823,2c473452,36d3e5fc) Z8(109a5ac1,a1b9ebba,7ec4294a,f4e6a5ae,f89430e2,2335ef66,2d04773c,4f2132c9) Z8(1646e845,b8ec529a,abfc155f,541123c2,be718b8e,f43776d6,4ff081c1,d825429f) Z8(3a6d2bb0,35c3e30e,acf6c48e,c0235a54,393d57b1,4be84484,f2f15206,bf0da208) Z8(1e551462,058955e9,59479af5,cdbf71f6,a6a76cff,161ccd6c,2a1ed5e6,8479a9f8) Z8(a3cb8109,eb7b06e6,bf512d65,12d37c9e,7c940527,a5d2d20a,c30d9ae1,33adc5ff) Z8(19a14011,9e818c12,8735397b,ccc62f55,d94e566b,5682760a,ec78807c,42025cd0) Z8(39f68651,395c2bb0,ab6b10e5,31c5eb47,d81effcc,2d2c49f7,dddec51c,5f9ee9e5) Z8(6b2a9372,4a0775de,04327ce2,43c990f6,a6484d53,a78a7ceb,44c98aab,e427d8ef) Z8(19761aee,be67251d,44f24725,0c7aac79,ecaf6c3a,f228cbe1,951cceff,7177d2e4) Z8(150a2f4b,43624a4f,d1d6b84c,07079dfc,1c06f1cd,a42a30f2,6e298524,fc08a739) Z8(7ca275bc,a6e45272,62c0ea01,0f1c0fd0,20e34ab2,e64ae14d,c742bcc9,c869ad60) Z8(6d7ebecc,af9387bf,2c42942a,ea1576fe,71e6f17a,9c9c72df,1ed1a0db,7269bad7) Z8(dc1cc271,11f91345,5e0fb236,23ec1a74,3a9f988d,d523ada6,e4b5c74c,a58fd1c1) Z8(2e9fcb77,d64b2fbd,340516e3,39520cf3,a2545bd0,ff657e45,14a944e2,e81c0be5) Z8(61d7deb7,e0c72489,387c24e3,d7fb023c,717bfa1f,70650c9c,691cbc34,14cc2c23) Z8(50b7117c,5585296c,5664cf66,b886a316,f4d29ab3,79bbc199,47f133aa,855c32d8) Z8(8cff4851,07b7785f,12e510b1,77fbd323,d0d55fb3,81f0fc33,d053b461,9a8b608e) Z8(63199baf,dc07ae5e,1397254a,1a38e091,682a9335,82442938,faf6b86c,5f5a4833) Z8(456dbf48,83135c13,7e85a420,750cad2b,b091a93c,6da37ce0,ce6bcd76,2c1e770a) Z8(beade43f,69ccae3a,796184f6,a09992f6,00b277bb,f27f5661,c562ca42,3caea6a9) Z8(16d557de,6dfe6971,a847bdf8,ef1b5d52,fac27958,14a2e2ed,80d629fc,615915e5) Z8(7fd5f9a5,9df4bf48,01b86e44,8f214593,6c6ccf50,18f05c3d,84f5b280,aacf8e6e) Z8(f9fe9aba,138eb9df,6083feac,5a44e2d7,e6944d4f,1a949ea2,b0fcc85f,52c927f1) Z8(e22937f1,eab0b925,820ec370,4a8476dd,2087095b,c2b83f14,cae871eb,a238d3ae) Z8(73975785,e88d65ba,d7d77452,8a3b61e3,f0c9fe3d,37fe354e,ff182afd,d5f20203) Z8(a5332598,79421d64,8dd4b23a,d8c69f86,f591f891,c1a59b84,e6149da4,e7a2d70a) Z8(d62a8347,76cad2ea,733c0f35,8b80ac5a,f123de87,4ad386bc,be621d9b,5f49c264) Z8(21b4a2fb,2fd4f186,615e3408,b2d330e8,2b159a58,483469f1,c198a803,ea6629b8) Z8(c02f6209,3e27ded8,0e116604,69d12e76,08dc55a4,2e4f7b2d,80f8cbd1,3f79728f) Z8(f5fe61b4,bcdaa9c5,fb9d42d1,40b2b299,d77996e9,6a8a768c,1bb14798,107d8375) Z8(da0f7c36,c842a490,f40888f3,529c9807,7c8dee49,7382d4cd,c6063a24,48abbe45) Z8(b8099dd6,90a03bf8,97c15dc4,22f976b2,01aa00a2,fc467b2a,5f3003ec,7a0a0303) Z8(ec29e322,a7e38d91,fed7377b,07f39ec7,332c23bc,758240ac,cd45fde9,1b038b45) Z8(54d735a7,1047c684,a7b59951,f3f3053f,11454856,4ece0ea3,1b112d11,50b38ac7) Z8(5cb82173,741fa18e,29b25b98,558bfc71,48bbf5fa,37195202,914ff712,eb0ecfe7) Z8(db1aba7e,d3b922c5,0a271dc3,70a51a96,ac99acc4,dd561cef,fb6db42e,c65c49b7) Z8(53f04181,ab1f88c3,d625e295,1afd28cf,10fd3082,504b46c9,37c23bd2,1c63228a) Z8(4ccec845,e6c04c0b,b0af5f1e,517b9d3b,cefdaf16,a3b8fd4d,a7e613bb,657577ab) Z8(8e511cfc,fb50acdb,b48f3e68,53c2904f,34303bb5,86d4ffce,97364ac9,f95e5740) Z8(b39e81eb,2f1a84b2,0808a9be,33ac3688,2b24ca55,321aa249,e92aa577,beda85c3) Z8(9e96a708,a9132578,59b83e54,3715d85a,74291f7a,30878391,39fc1d80,892420e1) Z8(27e7e69b,b4cc6118,3697793a,5f306865,c7d9ee97,b9958104,87fd5ed2,1d772ffc) Z8(09cb9d48,8a47f260,ba2ca81a,24a4e88e,66295a74,8132d4ea,5e0310bb,1728a243) Z8(192cedea,0e991793,6ec4ac58,a6875b89,f91c850c,f6f37b95,5bc43b7e,b52a5942) Z8(8c2ac657,61fd0946,f8508e78,787ef7cc,266d26d9,30339e90,1ce0acbe,846b017f) Z8(3fe89f06,9ac368ab,b9f98307,92bad912,a95e27c9,71ce6350,84effed4,59604bb5) Z8(71a74fa0,21a9bea9,b5cfcc6f,46435dca,8b0fe044,03475967,8d5d55ab,0bd0e6cb) Z8(fbf20111,832821f5,42b51b22,54aca0aa,722545df,058a715f,f64a3679,8fb5b8ba) Z8(8f4d6916,9258a9e4,c023d188,2a16b80f,dab19229,d71d0dce,34e1a6cf,856a2b6d) Z8(ec4dfbe3,e550bb9d,02ed94f1,afee3ad8,fe16e64a,865405a8,7b94a8a5,7736cfbe) Z8(fcbe7509,ccb258db,89af3603,3a7b8aaa,93aa9f3d,5811748c,40a6f672,94a56f35) Z8(0a0ea148,4b313ec6,e96dbd92,5e0f28d0,69ad0ff3,ec15caad,e0d81586,546032d2) Z8(37b68616,1c42a436,269db45b,f90fadc1,c6aa7d2d,744ce7ca,3022d936,6a5aedff) Z8(8b54c939,15abe590,7000578c,5f6f7b81,d41cf4d2,3de64f17,04b75fbf,5f4a48ec) Z8(c09d4318,022a2466,5e9f0ca1,a2d4eeb7,13ec71e3,888aa64f,a78344d0,dce4ba3f) Z8(4a3ba731,163e9b02,a0d5f085,69843e1e,0ae2207d,c14ca55e,119c9442,002db15d) Z8(31683b5a,96f571a1,e04736d5,cbeaafd9,5a75aac0,0dd2eff9,41368702,484c9bda) Z8(1c7236fd,aa25135b,3ddb29eb,e1d32ef3,9f73d0db,e15fd187,0c50a3d8,8a3fb6e4) Z8(ce33df4a,d1c57f08,6b17e4d7,b1e0f7c2,51a4e69a,82ec8497,ad5f40a6,f564cdba) Z8(b72996b0,a615ab2a,c76009e9,997f3505,5722601d,e2e8d219,705719cc,b1384e38) Z8(375101f3,82b033c5,107bf2e4,7a11b580,2165d46c,47410c23,bc922f95,af8b5018) Z8(b92a9557,4b73a717,57018778,441f0813,e188808e,025e60da,983fe53b,49098e88) Z8(adb47cb8,75770ac2,cc5be076,052467f2,67b64e3d,391f9301,bb263a81,07ffaceb) Z8(088f88a7,6be69f44,cd3be04c,fa4ef178,fcb1e87d,9b7b6ce2,57220ec0,48d28ac2) Z8(c7216dcb,e431ba12,52e0bf81,0bd29104,adc9d9cc,9455c285,a9a2b447,dd166627) Z8(92613e38,860e6971,22997ebc,1b9b0873,dad5d9cf,78add210,3152a5fd,078ccfa3) Z8(f169ae28,0e0b542e,da502d91,459d9f62,52d33073,d32b8157,8ff115a9,ffb3bc32) Z8(e4594795,a3a963c5,96f5ef57,2f6110ca,28c3971e,052f4626,b9aeb4ae,e4c4ad8a) Z8(5c902d4e,1a43be1e,774ccf98,614d0b71,d84faa6a,d72be32e,d53a8afd,b29885eb) Z8(42f6eb24,9bd4b758,f6bb38b8,8f008b00,e9b1bb03,318a57fc,0a56ec7a,21e07eb4) Z8(2041b1cd,af2091dc,55774607,ee4c92e6,9e715adf,23c30bef,362ce980,a7d584cf) Z8(b20101e4,0e94a6c6,fc3bf63c,0d8b767e,44f53136,9ad3bddf,0d8990aa,15711cf6) Z8(6808d4ca,0e23bf75,932d834b,ccaf96a5,99d7683b,c39b0c6e,cc938122,8b3a4073) Z8(74a0d14e,b1caeeee,a7dddb9c,c12a6161,750e03aa,5ffdc94e,c68f587d,91b12a78) Z8(a6240b12,a46245eb,7e37bdcf,44018366,5dd451b5,c771588b,9944fc80,3a769172) Z8(5c9abe8e,89639829,aba5d5d4,6dd1c3e7,e9e56d5b,03fd1a43,e05c9c97,a21a3ca8) Z8(b45e6a69,9f945ab9,1e795222,1c58b262,6d5997f9,48291494,64da94ab,eb0ab1b3) Z8(b57a6374,ea0a67da,b719eb8a,6cd49209,ccc753a5,94d5b21a,b15c66f1,d23f3bf9) Z8(68013a9c,f1c29456,3ffba60e,1ba92d78,5b1120c4,99daba33,c02dd0b8,00ad48f4) Z8(9135480e,20184add,718c4e48,eb06ce52,c7f04870,cad26baf,d653f325,467f5571) Z8(1e1ec4aa,a3cbb5ce,bd37f51d,dd8fdd31,735458cd,7f5d42ab,cf329319,682096dc) Z8(ac2c3898,33d0d248,01c084ea,97f76292,b9c62d1d,16c27d5f,78b99d7a,2d0958ed) Z8(6380235c,0d51933c,27ca5762,b48a515c,679b9a4d,10160c49,d31896b6,c2a9fd71) Z8(da57ec58,81abbdb2,622667bf,aa8d1aa7,1fa462fb,23a605e5,898fcc20,ce6f375f) Z8(e13f7cfc,684404d1,cd8f867b,78b31917,273c87e8,7992657c,1922ef00,4a20f8a2) Z8(edb045bb,d1154565,eefa4d2b,50eef811,47a6b1b3,b1610403,12dede6d,e9ab8674) Z8(015dff8a,78bf163d,26a89a69,08527f69,eca4db17,7f339845,09cf14a3,964a6dd6) Z8(4c0aee5c,8313d0b5,d08e8146,419a81df,e94065b1,e548497a,2f45024d,ed715d99) Z8(933e83c7,aefbac0f,a82b5ac1,b0a68b6f,61af8f1c,6afb7fc0,1d20fb8c,d400c979) Z8(5938b56c,e5bfe3b9,fdf2cb6e,5d4f3e6a,d0da9483,137c1942,f8cf2582,bba7bb14) Z8(a8253fa6,70ce52b3,f1ab488a,f52c4a8c,a2c2698d,94b7b46e,7dd3492c,dc1fb0ca) Z8(61dc716c,f3a9c9fb,fd6e2ee0,8b42d0c4,0564b7bb,5ae95e34,507360e7,cd5a2e65) Z8(25126dd3,d9ed055a,f29c6971,e81d4c23,cb0d43ee,be7a1185,c01122c4,a2356805) Z8(627900a1,ba71d0dc,4bf6976f,76c14f9e,6f2c981b,2619fb35,9d113e2a,3c4ef84b) Z8(9ddb7e3f,b446ff53,447daf4d,08ceb8fa,7141b438,5c9982d0,11e83c65,0c697c0f) Z8(f676180f,e51335ef,2395d531,bc3f4f20,0a68b767,40b51b48,bddff6d3,e8c690af) Z8(2df0557c,5c2fe528,d408429b,4b8bde06,2fc72aea,2b9380a4,f3a4ff85,8e48a5a9) Z8(ddf9f7ee,e20ec99f,b63cc257,9ffe8fb0,76b92097,64a44f75,24800835,969811c8) Z8(d8ab8137,057be1e0,4583dc90,c1c93e9f,102b37bf,3de3c238,778eb0d1,26fe71e2) Z8(b0317346,353b5083,90702a9b,20d4e067,c656f28a,58b4777c,44f48017,23ad4801) Z8(36624762,f8379e5f,1568760c,05ff0e76,b6ea671a,4d7e5a84,735304ce,76ecfda0) Z8(ba5f4da9,0754e772,5b46c84e,276b7094,b03e1cc2,455c8662,8ae3b9e8,495a0543) Z8(b2c4555a,29af9899,d2e79ef3,b5d7d157,3e350fe8,358290ee,5e801b6a,7f3e3898) Z8(823dca27,e9bc9284,2424c266,9dda246a,5a71c570,ce14db33,51331a1f,b99fe0d9) Z8(dabb82f5,4de0111d,9b2bac42,5e8b03df,01ffb8fc,0e3874f4,497ce216,2bd7b489) Z8(89bb14cd,e7678b74,84a4cfd5,16b4e8ee,62816fa8,376332c5,a0112de2,d075f273) Z8(d1d2ff69,7a6dd146,1437fd30,aba45951,45d2ceac,e28db2db,2eb5753d,e62dd852) Z8(eb760a45,a8743e44,a61b26c3,575f15aa,d9f580fa,ee294020,334858b8,0b9425ee) Z8(3279aa33,24d0b73f,3ff7ad29,2077ab72,4ee3763c,656a661d,661e41b7,d5d7efba) Z8(82f6752d,44da9534,93542145,922ab1eb,0d085e40,60a170d4,2209fe4f,a330ad78) Z8(3729f83a,0f74ccdd,5ec1f0e4,31dcc4dd,4ad6522e,7b777265,a31d9198,50de8a27) Z8(c18ab031,08b8ca8b,10006693,41523f6e,8b89e6fe,02d93560,08c38fd8,139d277a) Z8(7f363938,fc79f6f3,359749a3,1adf144c,11050a33,045f3880,f77940a1,74b6e5b6) Z8(083c6bd6,6158f109,8c1d2459,df1cd684,ad66f9e4,7f2cf4c1,339a14e1,32ad29dd) Z8(91d26e40,5e6c0376,e8a2e874,389bd169,7ca1cf97,a2fdc091,6979145e,3c18181d) Z8(a5eb6b46,595d82dc,0c0e9978,4400360c,767502ec,1c4c308e,2c8a6320,3c6bcb6b) Z8(8c2538f9,2b0b9b90,362dc818,d0e1a022,8b78b85b,1c4c24d1,c169dbcf,b51d60b3) Z8(62ff47d9,1e57dcd0,6db54da6,a09e08da,178e6d83,f6225d36,e0002f4a,15b86238) Z8(22207026,a3937199,c2eae029,ac77c7a8,6019e93c,1558ae57,d9104941,35c96e5a) Z8(5b9c76a2,bd564685,c36eef67,55f408d6,55355f91,6ba7c43e,b72b9863,243cd244) Z8(c332e663,9b714ac6,065c2adb,1e1c7e11,ff39c154,8258b9a9,9d1b5911,97b56922) Z8(79197da4,33fc298b,ecf5ce3e,322f551e,29584a6e,79917f0b,1a94e375,1950c697) Z8(9e9aaaf2,f321eec1,04648d2d,71722053,0ba6fbc1,7b6f043f,039ba2ce,ec3596e5) Z8(fff20f67,5bdef7b6,f007410b,4d9e9d7b,606f7d6b,d4fa23f3,083c5d71,5df2cd54) Z8(96c6bcd7,eef8caf1,c1af672a,f9bbed39,61ea1176,a8a8848c,e2fd042d,7a27eae7) Z8(ce83e52d,0fec39b9,62b9447d,d67e18f3,77d9b714,9fc510f4,8e15ae2c,b3d07d76) Z8(3e94a7e0,f9e86598,0c09cd81,27e78fdb,d968f581,df2dfa26,dac92d7b,af4ed43c) Z8(91c2da46,ebef374f,b355c529,a9171add,1b5f18f1,8eb0850d,4f52bd67,1b42dd5c) Z8(6075889b,3e073f0f,eab19a71,53aa849e,320de8cf,6d4f78b4,af1fa39d,bbfc88c9) Z8(7ffacf0c,104bbab8,3aa19a09,f1347443,8d675e9c,df7bd72b,c2417f70,3e9a8245) Z8(8cc68b69,1b5df9c0,7ec52e2c,be9fcfb4,0487a966,544e2721,d60e6350,d9e702e5) Z8(2810195a,f44772e6,4ba3e319,65886955,65f60a50,931ce8aa,f0e3203b,4aaf57c4) Z8(53d7640f,00c837e5,ebd48b0b,152f72c8,60f23f50,1dc89ab5,c59e6d2b,835325ac) Z8(6c3574a6,21e0a710,71a3bbbf,65df6950,adb32892,96aad8b8,58ed44d8,3d831752) Z8(cb009c94,5239d15f,afe6a040,d66188e4,cc9e94cc,82378f2d,221af444,9a1cba07) Z8(63b114b3,9c14fcfe,bbb15fc8,e267962e,98f7ede8,75467d5a,25dd0683,0a209a9d) Z8(179065e7,b41b22b5,b78d21fe,4aa56940,df23bf01,14095c69,018fc641,18f19c74) Z8(3b4638c3,e7d228c6,db473866,42e60415,bf54e4a8,576fe7c9,bac4766b,b97524a0) Z8(ac61bdd8,86f2fabb,9cbea239,e3b8d8e3,5694718e,45c68177,58624c7a,d8af97ae) Z8(889f8b10,9ba06405,6c91f976,1beecdd6,4c164dc0,dde90fe8,e1ae90d1,6625d102) Z8(3b7e5b67,cab6c4fc,6293935b,2e5791b9,65a59cab,d8a1f609,1ecd04b1,921f8f34) Z8(4869421d,00a81b0d,e83ed8f8,bb1a6827,6cc9e68c,8d02d6e1,92955027,8f6f5a9b) Z8(41cdfa82,c786c25e,7ffdd56a,098b15d3,28d998d8,1da2e26e,101f2a90,aba525e2) Z8(31c6d58f,14b34442,6e5c5823,58d689f2,a933ecdc,24ad7b5e,effcb16c,2a92c843) Z8(55dc3183,956479c9,57a50fee,21f901aa,898d1076,f2c32053,f844133a,d32bda78) Z8(76c79def,f5278fe0,c4e3aef0,c21a2120,1e2fd619,c9f68260,33d2ad27,dd965965) Z8(eb1c20f8,9752c22a,a4dd2654,bee4b389,ebbe216e,45cfa25f,994b0905,6c932ec7) Z8(2eda9a3d,e557b1e4,69dd5710,29a842a2,31276a25,32279e0b,129ada49,c27925c6) Z8(f882e2ac,e5963b3c,0c7bb52f,fc840a26,865e3ac5,9993fcd0,121cf72a,b545c72a) Z8(c9222bee,a376dd9e,a0fe034b,c2fe582c,9755753c,561f4a6c,4f4bd8b6,666a0780) Z8(ad564fea,2b16da9c,75bd3616,cde3d2e7,be440d4f,fae696ca,e4b29215,d7ca1adc) Z8(5860bc10,a1e6f9bd,baf9db0f,b8113a91,7f4bd4cd,2460a9cf,51307642,28cf9aa0) Z8(90882946,166aea6e,a774a6ee,c422d005,e693e87d,12575791,0659ebba,3e645e5e) Z8(4670d859,6fcc2185,44147d35,c452479e,e68f6fdf,63f9b0e1,48d9d5cc,fdab80d0) Z8(6beaf824,1c759f65,9324728d,bd8056ab,e7053715,e16a1d48,6e760d30,434ecbe0) Z8(8f746c5c,225e12c4,d0edfafa,d724cd96,c57e0de1,ae2a6492,833a0cea,88e59eb3) Z8(b712756d,4ac1c0f2,a3bc24ac,f6af9a66,936dfb00,6d541837,2e407e1f,c3534651) Z8(1393e5e7,dfa1539d,0393bdb6,de0006a1,aff34003,6675f9da,c08fdb43,e301c24d) Z8(7a13870e,633602af,8662bf72,c26f9ff0,680b686d,3b7aec87,b6dde0c7,9464eb9a) Z8(462c8733,d25ac32e,91a1284e,2354ee28,731bea6d,483cb9f8,da4eb473,6a7b1cac) Z8(82d13f94,c1fe05ef,2893f33a,bb8486db,5deaf7ad,f070c1a9,4413f45d,902d11e7) Z8(9532a491,aaf89f15,099faa13,bedf794d,b522fcc0,82bb4aba,b53798ce,8e80a982) Z8(a5a668e5,e90a72a8,0004ebcd,8b8b2388,afc7389b,1a98c25d,587fdd9e,80bc42d9) Z8(0270d419,f8c0fc20,33b375d4,4ac13ea0,ad7ebf2f,35f7906e,7672e77b,ee9ca31a) Z8(2e283baf,672839e6,fbc968db,09e877d3,a489c3fd,f4943a65,35d9a1f9,470483b6) Z8(bbc195bf,ba8503a7,6e083bdd,6f932771,f12807da,8e725d40,c523987f,029b2813) Z8(ad6c4971,51602236,1c020f10,81d998d0,97e95701,a1be0d65,03f91cb1,afa52910) Z8(84b53b76,94f6155c,34b4ae18,5d2c49fb,b82fd80f,631b4715,0836dc31,dc098d28) Z8(f8cdfa3c,1dda0686,04bb4b2f,1b4f5728,2d228630,c1db5f2c,10022d67,536ebeaf) Z8(138fcb2b,cdda6bad,5a00cc71,35831b14,d05e8809,4a498ea2,1953bf6a,e1d6c078) Z8(2848362b,d0d85a44,8b72a7be,6303cd97,6f659baf,9054a783,3e8fd85d,a1fdd8d5) Z8(8f19e53b,2b5771bd,25816c1c,8c9f0733,04ce7c47,f6a28d81,08644ac8,b2b7caaf) Z8(69adfa3f,142bd147,94e110d6,5c8402e6,a4979e63,c3ac6bc7,8882553e,20132a72) Z8(01b3bd8f,f8d33c19,74d3b5ea,ce96677c,98992629,7acf99b9,cf839836,27d37e58) Z8(cffb9f85,6c41d914,62caad36,f984d4e3,e7181b99,ca6b25c2,1e887aed,17d4f008) Z8(7d69cf4e,6d020b38,980e5f34,0f318132,0eceddae,5cbff485,10f7a4bb,d8e74524) Z8(a034ab8b,66372b87,b13e1af6,a9272703,40f2bec8,2ff33b8f,464eed37,69cdfb94) Z8(b02d517c,10b5056f,0675aaff,18728cf6,30a39845,0609c0ef,6a51975a,fcc66520) Z8(2ddd24d7,21149bf3,8bf918bc,c7409172,e3bf8191,41581d5f,a5a3cf40,7383c87d) Z8(f489bf36,eee6a84e,89b42956,97fecc91,5e647bd6,548416ea,6e856bb6,0d4ab22b) Z8(eabd03cf,e95a3ca2,6f9ee838,40587d47,ba0880ce,13545583,8b061311,e583a16c) Z8(ea8b6c80,b4a4af9e,6a12ca0c,d7bfd0cb,477219d0,309731b3,fd996df5,469f56d8) Z8(b7989352,f14af0d9,43a6d57b,31a07275,5b1ec477,c51738a3,b9ec3a2d,0ed9afad) Z8(52067ee8,7af5d8c3,4dabc9e8,5de2fc47,58eb4e3e,f2f981e7,ba2264ef,0cda7569) Z8(ae379af3,8f843de6,ff82c489,c02d7dad,37333f59,c1970215,ba9e85e1,737c3a8f) Z8(e02b6307,7d1b7267,17c85bef,cb0b1597,6ae6a5c4,3caebf55,bfb91bc0,fd61893e) Z8(b4a5c93e,477f0e59,e6c4f9c3,0719a761,418570a3,3d9c5b49,ca2a0510,2ea8f417) Z8(e50c3277,5edb832f,25a5af9f,1d9ff844,9d48c097,2c6ffe2f,42f85b3c,38ecd4be) Z8(b584b53b,bc64c7c8,2e3bf4f6,f314fb16,fd6f5022,e9e5957b,6e8e2a43,8621b128) Z8(eafc328f,90f315e3,26cefb4f,205c906e,c6fb0149,c5fc8835,cbf26056,76f7088a) Z8(ce86a30d,df4d01d9,5ef83340,a234ed14,6cd007e4,db9f19c0,b88936b5,b0d8667f) Z8(20d7649f,345f8a4c,42375964,3fa085e7,08c776e0,c6537f67,d0913c0b,72522a71) Z8(9eb8e439,ef6e478c,ad0d7eb9,d3104591,e9b3c850,155ebd2a,4c68bd5a,42dbf996) Z8(978a8194,5590d2b4,59ec0a43,2d537b68,cb0da98f,32a22fd3,9f64c8a8,81b79da9) Z8(0be07223,5942778d,216885f9,c42d7b98,9e1d3a21,f21af731,b03d0f27,40113a3a) Z8(4c4e779e,17f0b8e9,ea2d34f1,8528389e,01226a1b,2369dea3,7bd13de5,1aab9ef5) Z8(b6db7a5f,12adabc4,20c100f6,b23b5479,d20dfc56,a54e2efa,acf4b400,7590ca94) Z8(95c70166,faa5fc85,98f188bb,be0e841b,0b8a43ec,dd14a7cd,bb12c425,6f498dbc) Z8(6f71b9d1,d78ebe45,f3cec11d,cb944558,e06d8ecd,baf7aa8a,45998ab6,b2c0c21c) Z8(60456dae,a94425f1,84f22667,861e8c8c,310b6873,af154022,0498e2d5,ac5f69af) Z8(a6e11801,4d3c874c,1799b81b,f5a2753f,229774ce,916bce87,b1f6d7f7,d827c7cc) Z8(0fb4d504,87c40cfb,8bc0abf6,2ce2e730,41b95f5b,5e9d6cc3,369d1ebd,e62f304d) Z8(34e29a9d,d9aa67b1,5b8e0413,cc357a12,6fcd9db5,78cb9152,0cabe806,e215d180) Z8(9a584347,d07f4124,b7df0fbf,cfafe4a7,233b4ec2,2128595a,6f9359df,8acd2de3) Z8(07c13726,9cafd990,a5cfdbdb,c30af077,3e659f52,ad7f916b,c0639407,a14c8dc4) Z8(d07c1ee8,c51cc17c,f838f626,e230c892,6f36a101,0ef480f6,dbe7d200,9f7511f9) Z8(9e27bdda,4de36e50,cd10874b,7c3513fb,43fc16a3,1fa5bb66,9dc0229a,a8752870) Z8(0eda163a,4350ad27,7d97cbf8,e9054a61,32dd2691,9ab36339,934a8284,a15033c3) Z8(c910fabb,c4a49feb,943b73bd,ded03c09,f791da2d,bf58cc91,d2f6adf1,6edcf906) Z8(d0a53aee,64f5c0cc,179f3a41,47a0a83f,26d0d4d5,ba9aa43e,e9026030,c4f1c5f7) Z8(4113a267,a78a6df4,79d27ed3,4a305463,1e81ae4b,0fa5e9b5,ae2ff41f,5716f76e) Z8(c1339300,1b38deb4,9a163219,cf142472,a405275a,42cf2341,26fc00ec,e7a45556) Z8(dc586052,3e08d81a,da67f64c,1316953b,6c5752e0,a50d01c6,bdacff22,7d33b304) Z8(f4bf5a54,ffb3cd77,6435d18d,e0217ebb,5d13f71a,fe4e4b38,738b8478,fe7b2d0d) Z8(8cd54ff4,38676d0f,48e7b575,05e93340,e38d9461,19abfa01,466c7d1a,0a17c381) Z8(3709b945,2516136d,af95757c,2a5f911b,154ce075,a345a8c2,5dfba3b1,40de02a1) Z8(1483192f,e63d2eaa,b9545425,a44f45f1,d3c3ef87,42509bf0,53c96eb8,b067d886) Z8(b38f3e0e,9b0963ae,4b917df9,aea8ee8a,03a9f5d0,b7691cdc,81acfc27,4f8a5538) Z8(2cef965c,0d14581c,99957582,d616ae87,b3b9db94,c65c9598,aca524a9,9c8c94d6) Z8(0452a048,f785614e,7a4256f2,de07defd,6da2f656,0278f4fd,730280a5,e1cdfa52) Z8(cffb2cad,325948bb,26d70c1d,d43de355,9a775b00,5caa2dba,62f002f3,5a9622a0) Z8(9eef0692,14009f04,48e65abd,4f3755ba,fa949af3,d0f8c346,8b7ac9f1,9019f4f5) Z8(84bd7d37,146c6260,e931e139,97cae39e,c4e8b543,20c61d6e,ebb6bc96,bdaf93a8) Z8(ff28e4d9,05fbc893,8ce5e846,44cd1b3e,105d5836,0b9b2aec,af106256,473e1010) Z8(b66708fd,5fdb92d8,0dc8d6fe,ddcc673b,7643d6c8,6581fdc9,da88105b,da4d15a2) Z8(a7a46eef,284a352f,a4f59891,6168cb15,2c99de69,2c18c870,566043c4,f36b3d16) Z8(d01e098d,4756eb39,90cf3016,87050ae4,f9e09d05,b47fa79f,b10eca95,690de2cf) Z8(37b60998,437be0c0,8d96482e,d4b9f3a8,8f11746d,8567842d,75840827,d8d47e5d) Z8(e75ceb2d,96080452,5ba1cc3f,a28cde8a,3568d779,f242dc61,f45cfb6c,2a02647f) Z8(1acbe823,62da8daa,0dba279d,365836e9,2bd8def6,662846bf,cb89d477,615bb08b) Z8(abbe7553,d9a01605,7d31b512,13a3e19a,44d94ee4,e0469c1b,f8d3dd59,5412a33d) Z8(2d495611,f6a2128b,c0705971,7f80fcce,37b6e778,82e1233c,82032647,1252f5c3) Z8(e255580c,e8d24efe,e4f89aee,2fd21908,fc943425,35faf731,92696aa4,6f7d797c) Z8(6b415169,989675a5,781ea549,c6f1bdc5,2dba2228,7cce1a1e,08c73fa0,f9e1b338) Z8(cfa54d09,54569c2e,acbe97b5,16ca315c,c587a86a,b090e999,c3f2b082,b1ac5fa1) Z8(3fe0e335,19ec389d,3e497bdd,4ed08c11,4b2e09d2,0d4bbb08,60bceb52,10e2abb2) Z8(09878159,885869bc,2937ae37,e5b72e2e,3bdeef8b,4d2f33b4,8959a2c2,125670db) Z8(ad59b4ed,fd99813a,6f254236,bfa3e6c1,930f18b2,fb6a2a98,f35a15b1,f5bfbe95) Z8(f3378b80,35fd05a9,d66f8405,49a220d5,de7146ae,f91a74dc,424fe2fd,687d82be) Z8(ab696d48,7a48ac54,1c90f7e8,46724491,f1a78984,ef948a3c,4276d942,2af28661) Z8(99f414e2,e83df521,18783932,e934078e,2c07f089,af0a1b37,a01b17e3,87ec24dd) Z8(0f50edcb,57831ddd,f5f42367,31447178,5f17bff3,e29546d5,77ed7e32,92eabe89) Z8(cd87896d,73b24753,b89b9c24,4d00e74e,4f00c74b,7eec7007,b88ea2af,0faa8cd3) Z8(e8bc8bd5,bcac60ad,dd95915e,e4c91686,9cb3aa84,a27dc1d4,42d89afc,4a4f251b) Z8(750f5bc0,7c053d55,e9b5eb61,cb33b992,7e416ef6,0c4a3480,e258807e,82e680c1) Z8(914b19df,c8dff8ec,53c01b89,7e58508f,eab1046e,091f1651,1b501a09,075bf74e) Z8(dcdb2d43,cfbfed23,7f0c222c,b14a5792,60de8a25,1e87141d,70d1f0e0,2f0ee0e1) Z8(ac0ea292,d730302e,397c4d8f,81b4f9c5,bf482bd7,5b83e11e,7adb95c7,484bdd94) Z8(a9de16e3,38d9c127,922d9d22,ea03a07f,cb7306bc,19cf31e0,94b3f82f,ca870d45) Z8(229b5ddc,30380b61,75be285a,26c01b90,7f3cb2ae,de1d1167,1fa7e858,a556743c) Z8(8ed8bc1c,1e11a374,2e646929,9dd6f5c6,22cf000b,08cbf907,e5e7973e,62a39ad6) Z8(355d51e3,df5dbe13,4661edc4,aceb0a39,2ac558d2,72ee4b8f,7c3343fd,4e6ad7df) Z8(a02aa01f,3bcbd8be,eb75c113,2a42a009,73c16279,1ec8a187,fbcca458,bdb75556) Z8(ca883405,fb86cd77,2aacaa5a,e051242b,73093588,6e3d9374,7c852f84,a0e1a0a8) Z8(24b83823,9903ea68,466822bf,c7c6db30,eebc0309,78d23a4f,39ad5e4b,20e43a8d) Z8(a94d0de1,744ef929,cbd4f9d2,36dfa120,e6845137,f3b96f32,53f9cfa0,906217ff) Z8(54e49c38,40920db1,ba83c45f,0bd48d9e,d9ba4696,4c092e0e,77a86b6a,54baffef) Z8(693326a3,44badce6,f0dd3580,824c9b2a,34fc86da,dacd36b5,c498f408,2dc4f65c) Z8(b435327e,c4c1a0ec,1c21cf94,d85f8ba3,63d8196e,f1cf3f9b,ba51bc80,ddc72a04) Z8(34f5f9d1,cf2a0a43,0a1fb245,aa74f617,6bb9fddc,9445109c,3716c973,05abfe95) Z8(ed89adea,061d5e8d,57ad2c44,5a9decef,9bd441e3,60751740,b5060f5d,1e15681a) Z8(a059c9f9,457835a0,92cad68e,f84f07f6,6df5bf56,6397cac7,f6601a34,bda850e1) Z8(a9bdec25,4ab05b3d,ba1842e4,f98d1768,4d5c268c,48d0144f,6742ee4f,33d79fc8) Z8(aa2b095d,a4076872,0adcd0a7,db86e59e,ee004b5f,477b988e,29ea8d34,5b6ef3fb) Z8(185ef97f,35aaaf4d,630c486f,110812f4,13f8429a,e772e350,d60ee5b2,bb7e799c) Z8(b035bf38,ba515f92,49cbe723,b8992c13,9f29e360,9bbcbea3,06915971,1deced7c) Z8(48d059d2,3d6bc29b,4a32e9f6,2aaf66d3,66a6b104,23aae730,80afd8af,07c27974) Z8(525330f5,0bff6c82,240c4baa,a9a65e25,f5b74b38,93261398,361241db,25e3a52c) Z8(dd8021dd,cf10862e,03f1d701,80f76ff0,1e7af9fb,9486eaca,87bfa96a,2b761068) Z8(d1fbb33a,9f1a266b,d0cbcf01,f4ed09bf,f753265e,eb3a87c5,7b25f161,678e824c) Z8(6fcabe86,43dd87c6,a4466651,d9f4c24d,5264fd97,934df9e3,7a6023ae,db7afc26) Z8(bb5a8917,8884d576,ca1d58ea,97c20e9f,20588246,1802c32f,44955891,d2a34b70) Z8(ab7db9e6,7da88f32,f072b430,322a172b,fc0c83a9,a01ac0b6,13923e0a,6d19e59a) Z8(58c076e7,f1b85686,d3cdb8d2,52c605d2,ba4e5b62,0459e7f4,3f510e4b,f14966c4) Z8(67c0f1f7,f74fbba4,2addbf6a,c6f9d363,a78178f1,f7884fe9,4cffeec6,b34beda8) Z8(f8152ca3,4fb495e0,5073acc4,4da07cca,42244ac7,2a3dab0b,8caf5bb9,b58fc47e) Z8(d4e05a7c,525dcab8,c39ecf52,7ee62df1,2cc450fc,6b96d199,296d0d5e,15da5f99) Z8(4aeded74,2f114b43,a7447a3c,55423d67,c6ee9cc3,6d11e432,758b95b8,07e7207a) Z8(7aa6c92c,1094dead,b7ae6dfd,315438e4,d9a05df3,fab12361,42769719,c639d7b0) Z8(fb2a694a,73ba67a4,05995d97,3c7a3482,a96e677c,f76e7efd,4525e94a,09162caa) Z8(8aef8eb6,5d41e584,17a98a60,99d20154,87b23bf3,9f6ae612,c25f07d8,942edf43) Z8(f419f690,fb7ccc9e,58b544ff,b9ffa6cb,33c7a4ec,5e05a794,9e1e9e0b,29db1de5) Z8(737ba69c,f7dbc12f,71f49660,a10aa47b,ca44aa8b,6be20256,e607c389,24dd7618) Z8(09cdcef0,1e5c0cfa,00cc0bdf,7a5d0ccc,df5e265e,27e318f7,480672c9,14c0d43f) Z8(46d6485b,e9651f59,0f56b5ea,4bec5c8b,34a0c919,ee64627b,48b7ce61,300c0372) Z8(7cb825e0,7132214c,272fc944,01325ada,9aa885d1,dbad6346,a8a78851,85eda194) Z8(363c028b,651508d2,ea272261,d1d73a2e,904f6bf9,237edceb,595539e6,6de06a97) Z8(27013885,efd83dee,15862e2d,fc140408,f53f7132,5fd44606,0a6b44bc,2676266d) Z8(7e30a926,5622b2e6,d5c47413,8ae3afea,d10e8c9e,c0220924,eaf83cd3,5c19bb65) Z8(8b6735fb,c2d8023e,71d96cc7,a6bddee9,b765f740,72a94311,19276865,dbcf8ece) Z8(21d2b57e,d4fb23db,8d617a05,4c71285d,ef5a375c,fd781091,49513ff9,0f8a46ab) Z8(334a700e,ffad98f9,1dd30c06,291af134,24968172,65c19a22,15917ee9,b177804f) Z8(c6366e60,8948f982,044fe69a,89629cbf,ffb1fd20,cba4e4ce,5af3eca6,b8cca47e) Z8(0724156f,464bbd51,b6ce5232,c91d86e0,1cb5466f,4098c6f5,916f4c79,4e50f2ef) Z8(a4eab401,e4995642,a5e3bbb3,7142e289,0937d41f,9902bc48,69070d26,f9375938) Z8(18006dbe,376701e4,06cc6eb9,15271a0a,01102b39,750648b0,f6502cb4,fa115e8f) Z8(d4e51945,a0d1bd85,27c578c8,c2e061f6,41095b6f,1a11a4d7,4b10b41c,9bd0b931) Z8(a7792989,80bbd59e,905abc00,328bf05a,908638c1,96c1b21d,87622f2a,72919e2a) Z8(726e6729,62755a9f,2e9493d7,ad1eda99,1dde7ebc,adbbe7f6,78b43650,cf9a5762) Z8(10ee9fed,cb0f0e2e,b81de811,9031e2c4,6b1fd8bb,e7baaee8,4c9ac0a1,14c8cd01) Z8(0b796f15,2728dd93,6fe903fa,9704889d,68f8bba6,f5dcb53b,a3a0d75b,5f8935fd) Z8(3227648b,76007e6f,a9762390,58112c51,5048e983,fce91fb1,09f7ea9d,37c5a7d3) Z8(7bc60151,ba6d4fd2,14949515,bae4ff3f,3bf647f2,6ed68340,de3ee596,a6c848ed) Z8(675baf0c,a0cfff42,db361c4e,e445aede,1c477a67,cd9e99b6,287eb31e,42f4342d) Z8(c396313b,49de1bfb,eb07cd45,0d9aa71c,ed748d45,2bf282a6,557b6c99,29067b2b) Z8(b1a879a1,0792cb6d,024c27c8,62450b0c,2c9ad95b,cc610c47,743e5013,8944ca99) Z8(0cf3fdc4,d3d94a80,52620093,ee8f7418,e1487d39,53da2aeb,4fcd50b9,ad31ce7a) Z8(cd11dba2,121b94fc,4198babe,165e569a,84347ac6,5bbf2daf,9d55db6a,eb04c60d) Z8(65617b8f,23ad4834,8b480a94,6f2e5e4c,7772b3e5,56d02df9,70fb084b,e1f105cc) Z8(189228d5,7f243fd8,ed823b6f,c32a6acd,ff5d47f0,888cd649,715b993e,b99d2d20) Z8(c9b9fe61,80e725d1,147e9688,0eba4488,f77638d7,d167994d,c30d2707,edd25224) Z8(2e451dac,f8f63e3e,138c1970,ff4bc9e7,8e9b436b,0b2fa503,6d2b7068,0e30a696) Z8(3bbc1d39,32b7a73c,0c49178b,fc604aba,f936f647,43e9892e,194040f3,2ca4b348) Z8(a76c9708,1a5d6263,30c55c60,d8e15157,86a9777f,9f4f62a3,2f3f61e6,bf895e71) Z8(833f9b60,6a4c5122,a99ba136,fa7b4f4f,9af9d763,774ea8af,f3ab249c,ad7e6fc3) Z8(c7b9423c,06777b37,aa6e2d68,575a34af,6cb4b435,cbd7b74f,252dabd4,8583e3b6) Z8(f8dc7888,4720bb7c,851ed91c,1b4f22fd,37df42e1,dcb59519,99e40152,e9a3a985) Z8(382e98d4,8b585186,4495e0bc,5b9f3ddf,844a7e41,77c697e7,f2c00072,ec4ef5b9) Z8(251c04ef,60dec5d9,317aba73,06d70099,f82eb4ca,648f47db,ce5b0420,4f0477c1) Z8(75759116,8dc761a2,bbe588da,36d40002,a9c5fd5c,1d07aa6c,61fbdfe1,01cd69e1) Z8(bf171234,267e234c,9f485354,096e67c5,93f6c08c,fb8aa06b,e5a1efe9,beeaaa85) Z8(d8c4439e,10162c63,b75090a4,8959ab8e,ecc05889,e2a627be,f1c30e3b,2010944f) Z8(cde24be5,bbbc39ec,a8b66a5d,4bde9075,31a6de38,ab0a0047,ac1f5521,23a8cfbe) Z8(da63d849,c03b20e3,2056a027,9094272f,d1f5452a,8a44e200,3968f1fb,c250dd8c) Z8(cfb092e9,4d2e3752,621a5083,967943b8,c9166e5c,049debdd,bc42645a,bd28c1ca) Z8(e13286f9,68a34c8c,039e1fc5,ea10f141,70c13b02,4e035f29,4c6d3884,38360d8c) Z8(d7c95ab4,55a06cf9,6d7f1602,49041446,c31655ac,807d4a0e,bbda9053,75684de9) Z8(69c049d3,bd3b60e9,b51f3ea1,fe2ddb75,b85160c7,e163280f,d4841926,fa9a927d) Z8(203b7032,469571c4,c2c11011,b56d7809,48685190,4397092a,398ed421,1ca42a0b) Z8(df0fd894,92b2f87f,d6810ff3,c05a3e45,296dbbef,ff9c882f,0759bc5a,53efec0e) Z8(0d6a325a,8437e866,cebdec3b,58cce9d4,10124f53,bafd822c,552ceff4,0f1213af) Z8(6c8d9999,dd265f25,9e2b2982,4bb9fc41,7fe90463,1c78252b,e00b3527,d548bbda) Z8(8b81d54a,3c887a47,af908992,c086d09e,211c4a0f,eb5efba3,8c5af565,a5552cfe) Z8(2b161fab,888b4848,0fa72ede,c979c54e,cecb3e59,85d70e05,f28c47b4,5e1c21b9) Z8(542d3414,9fbe5ecd,5e079884,889df948,f11f755b,1e7833c4,345310f1,48cd0adc) Z8(4d0ec4ae,44008fff,15e6cfaa,910eb993,2b6d0460,aadab932,161b8291,dc7b6e51) Z8(ad03388d,bddc5451,968317bd,de0735f5,5a375fc3,6de81896,e0c0c2af,262604e8) Z8(32462c0e,1e9be548,9c48feab,8049886e,cc62f502,ea7ce1ba,ab3c9b1e,95f7c3b0) Z8(01df36fc,94006423,ebe78c69,958ed2a9,611493b8,41cb1c45,d55f5dbe,61cf98e8) Z8(8cf8f734,773c72a0,5a509320,fa5f5111,e036261c,75e43ec8,ff867e87,3e1a26e6) Z8(9df31413,845df54f,d7b70f13,b51447f9,db5f734d,ac2d7320,fa51842f,537c57fb) Z8(91e63af9,5bae7f8c,993d53d4,8c9a7498,51968628,55947c60,7bd51988,ccc85020) Z8(f6b36da6,41c65d4c,c7366e25,6003359d,d2ed36b6,97594296,550ba77b,d2e15f8a) Z8(d0857af8,01478ea1,5819585a,0b8c5538,c37088e7,dfaf7862,bb06b24d,5e511288) Z8(40f88b7a,71738bb9,997d8eaa,c892ea71,b5fd7ba6,5f6ecd27,9d238df2,8d2d75ae) Z8(8b6f72ba,a032c912,a40c42de,ce246737,667bc6da,d094d6eb,10012cfe,4c448b73) Z8(e9df77d0,e0a7b50c,0b22dc16,4f88d34a,fc2a54a8,b5e5db35,d4acf6c5,b2e01473) Z8(945945a7,43731ffd,22ea5f09,4499c099,77d1d022,a73f3f92,14ae6232,a6e33e9f) Z8(93bb3e11,f1a242d0,da9f1f2b,a5ffd7e1,4eb3260c,2cc9e42a,3485911d,f53e9551) Z8(b4380195,f15b9cf6,d83932bd,9def7d69,9ae75b42,a70b8815,6aa89d87,a35200d1) Z8(661e9b5e,fe8b9a19,fc2970ef,88b73070,b5467b24,97a45dd0,23154d6b,98208564) Z8(9d0fdea0,39fc1345,2fb0ecc4,937e9ebe,7ebcf61c,968b3d85,33447464,8a47fcbf) Z8(7031ff9e,56eeaf2f,3633ddbb,cf764b36,82c3f6b3,9b2ff617,6639b97a,a2b25b0b) Z8(b88b7bca,1276768d,82efa174,ce2a61cf,d1bb8621,84652722,1b9d0860,cc2bc145) Z8(0c58d361,d4b72631,49e5b1cf,804a36aa,e9c2bbfe,1c810ab8,9965d370,05681489) Z8(4ebf9b9e,8c1e0227,b7c00a32,f10f0c8c,c7335625,097de10a,212b15ec,3763dd66) Z8(d7c07019,5dcefef1,13705b04,874b5ee2,03ab412c,5aceb1db,7f1adc9f,944da243) Z8(a5400d1e,1dbeb865,68cdbb61,a27cf32f,9ae0e69c,4dd47cf2,fcac3f5b,c01c9f5a) Z8(066a46bf,138d5a87,295b8947,b63505aa,ad9c7acd,8b472dc0,8b821ab5,b0918a3a) Z8(778729ae,800098aa,52c72cdd,e2f1414a,98013ac9,de471951,b486f0c9,c1a2c4b8) Z8(468433f3,be17ca5c,f8bd3b3a,9e415dd0,7efa1e64,ccbe58ca,498c35c4,3aeab7d6) Z8(fa8c445c,ee0bed67,702b4dcc,dd039c81,5f3efe2e,2910812a,26086f92,716739d2) Z8(00120581,4d26d32b,702d669f,2f1f5874,bb9d4d58,0e2ed156,93ecd048,3bfef344) Z8(677538e9,69067e2e,23824d52,482988a5,be44aa96,9ae01881,20a3328d,bca60947) Z8(a06ed10f,a0542fda,744ea04e,12f55098,a100e9db,12ba2c17,5de54595,65dc1168) Z8(55cb5147,11baa11f,347f7b66,b399ca41,e5ae7aa9,85883bca,4270b97b,9d4584b3) Z8(ae81d895,8656767a,67cc16b6,b78d7691,305940c3,a252b102,07004373,bef79803) Z8(e40060a0,a3bc6755,63cfbda3,658b7045,cfc74367,07e19dd6,265b33a0,c0a13446) Z8(439e7807,edd01bb9,0092824d,1e7a168b,d25500cb,6704a627,26b8bb81,115a44d2) Z8(03e2d33d,fa66d1da,82b2aa21,c8715df6,e03b3a3d,5911c66d,4e44157e,9b682586) Z8(91cf3f89,15160c7b,99ff6278,3bc08322,8d85fbb2,96862baf,3ae77c97,61296af7) Z8(99893f23,28c8a32e,69781781,3bd98d33,3d9780aa,3270a3f3,a5953897,c5e05951) Z8(04b82965,edbb719f,203a293b,daa5347e,8d069a90,7518bf57,6f65242d,b16aa64b) Z8(858fb4e9,a2b618d4,9f266a7b,b5091681,8d0e1f43,0412c78d,69a9e192,8b121fdd) Z8(fa9fbfea,5419cb00,6513f467,d93324f4,6b4405be,07f30169,94b8652d,b5188cd7) Z8(a09de94c,3324391d,2d06238c,94f71ca2,35bfc43d,631dfcd1,a53c731e,8945a316) Z8(99321a65,858dd82a,0d256148,2a00c6b9,ca0b54b8,9ff4df96,4dc4d900,cf7d56d8) Z8(b09c6090,d591a67e,54fbd6ce,decedaa3,be7ddfb3,2e4b0c5e,2db4e4dc,3fb92934) Z8(91bd8729,31c83aa0,48d8487a,843efdbd,4ebf02ea,acfd0ec6,c682aa80,d3be8d8c) Z8(6c7424db,8ff53cd6,f2c0a968,a7457b99,a6e27773,e8fabdfc,4858bb58,568d0b6b) Z8(010637c2,2147646b,27cb06dc,93274a07,1195ec2f,c53ebab8,f9fdf1da,925bbd83) Z8(2e8666ad,f3c17291,3ea5b62a,53f10a42,903f6cf3,a35f09a5,a7fb07c8,b554ce99) Z8(c8e28fd4,2a6a0f69,656c0043,a76e05a5,2bedd1ca,bfe45d71,0953224a,aa96b19b) Z8(202f3871,e7e85874,65526f61,30917e7e,05ec8e50,aaa16998,c62d838c,0ba7d782) Z8(efe8700a,3158ba53,b699418a,0c5b7381,6ba5bfec,edbe0e10,faf985ee,ec3f0d72) Z8(d28c908a,a2bff952,4e8f1373,1af929cc,c9d8510a,0945189b,e2a7a514,9d778cc1) Z8(bfbdb80f,732edac5,fca71999,e86ac4b6,64cf7d59,5984f97b,ae2e3895,eaedf354) Z8(29dad521,0dc97c46,b317c326,41dc0852,9be45d5f,dd83573e,3b104b55,37a0fc6d) Z8(55831bc1,0acfd370,db738bea,d18c20e0,f6b102d0,da47e16a,a079c8d8,2bb41fc0) Z8(4e840101,688292f5,54772134,821ca958,6c436a00,96b5ab73,9e9d116a,9598a615) Z8(70bc7239,c5792e88,801d8d31,eaa3ae10,23636603,b15e037d,bdf5363a,591ce745) Z8(720a040b,93b88f0f,7519c557,55088be2,cf38669e,8a2a9188,f8ed0d2c,fd16ea94) Z8(b0fed025,c671a2e8,975be84e,1f9f13c3,3fb4c1f6,95f0da7b,e3cb19a1,52669e67) Z8(388b2789,ad398128,d6097a8a,20b44b00,6a3d3744,0703f1e2,fc06815a,00a8ef45) Z8(26d07950,f902a73c,634c83f8,45fb9d35,d6d65e6c,cb284d2a,f101fcf6,6f8678f6) Z8(035de03c,2ee2ef8a,2ef6ada1,ad576c77,f5d57c4e,4286700a,1e783014,915298db) Z8(5350b4dd,56680c69,4117f412,9bfa3a21,370f1333,f7bd3e4a,3c7cfcfe,cf4e4776) Z8(3e88fa73,ead0a1d9,80cf17fa,46d33348,20537c5d,29eb43a1,86402160,97eb3280) Z8(65185173,e89d8e6d,097ba7be,caf9bf04,256e7be0,1ac6ce9d,57cbb50b,d20e906b) Z8(f34567da,996f8985,afc39694,5e178392,ea8c8e98,b42a24f7,d9207c3c,278c4203) Z8(bcc509b0,7979d7b9,98903df3,966fe843,be47686f,48885dde,34e2f50c,94e764dc) Z8(62799046,808f5ba7,f54cfab5,76cd573c,b00d72d1,8bc7693f,2215400a,60921620) Z8(804650ff,83d8ccde,c21e262e,3eb9f382,031deada,f29f8cb5,1266dabf,cd75779a) Z8(b025d6b8,ad6535b9,c7460dff,69495b3b,74721dcf,1cc75cdf,a0dee2b5,71a91bba) Z8(da3850f2,e5485810,420d40e3,426e8113,a5d8ecc6,f6128e97,3b151682,10e56d03) Z8(d125f315,7e494f47,42dae8de,cb569ac2,7af1fd1b,aa2f3802,7ba49a47,3d0ae619) Z8(578357c3,ddf6ce8a,476e586f,ee81aeb6,af4c7514,381e5eca,1faebc83,cafd2d5a) Z8(c9fb1ac7,2124e8e0,c1b93461,565a3f56,9b9da690,1652a3b2,0e334f34,ebd13bab) Z8(185c3b85,609ba7ea,1e2c03a9,efdf72dc,0a3a4e1f,221b47fc,ee93c90d,5dcb2828) Z8(8f263ae7,800f49b1,24b68f54,b561095f,689f36c2,b346dde2,65f23582,6c73d698) Z8(0bfdb869,9c41a7ad,e08dd903,7e3f225d,9bf1d7c3,c044844a,a13d30cf,a8896734) Z8(2019ffc0,ae041a80,274cb80b,a67022dc,d5b736ef,7ff16054,53220ebe,60f9e42f) Z8(b3d76a43,a52c0b75,1edb7d9d,b0ea7cb8,38efb3dc,4997787f,263bb8e3,4efe568f) Z8(816c95bf,c938ed77,8fd9941c,76ce6764,28d985eb,9a204a42,5c81b7c1,720634a3) Z8(7dc7d8ff,15e43ff3,9dfe33c4,bee88ad4,21bd89fc,732809f3,1fe9e44d,0fefbf47) Z8(5db17d5f,97aa8786,6378f78c,a8414a92,e00724ef,50f42edb,2eca3790,fdddc733) Z8(b0de9b32,4b5a5f99,157b9801,dd561043,824c9338,95db7fe2,b6921d48,5cf614b8) Z8(06ff74b8,148c0692,cf6717c3,1af65de3,345a6b37,fc930a17,bc457086,dc8f36ce) Z8(16b8c180,dcf82f52,975ac1ef,73d1da2f,c9565067,275e1cb0,2ba9ceaf,27b01824) Z8(41a23b21,071fbd9d,7386560f,5d5647fd,b66ad4a5,c97a49ac,f1250324,29381c69) Z8(2b2dfd47,619375dd,06536830,c8a61536,971bbda7,b7282831,f0cb06e4,025e4f5b) Z8(d765dcb3,69e659a1,8ca62afa,e8a469ca,cb740615,9bb5527a,cb9f4bab,b91f299d) Z8(02212fae,0bf4ee53,96ac9bfe,c6b5c455,d5525c4b,6e997d67,9f023fca,b36f8dd1) Z8(2a2c3cd9,de904a40,eb36f95a,aedeca8a,1b528309,442fa9b5,948c78c8,275bb57d) Z8(2bdd88e0,853eff7c,762ea3f6,ebccb9d4,5a685d2b,d17638d8,ffb3317c,09a67004) Z8(97423234,f0b73b71,0143c41e,2f87ce69,39447a09,c9241a67,aa9c469b,41ecc7c0) Z8(df22572e,5c55d7af,77676ea1,826feff0,2de4c405,3652c90c,f3e404c4,e20fe838) Z8(de57bf57,8a0396bd,7b9ba83f,b4296d9d,64f600e9,59373a5e,dd30beef,65abeb16) Z8(aa501e66,05dcb038,b63cf8a8,79524f5b,69e233c7,911fad67,53a9ceae,908757be) Z8(c585b9ed,bf59291d,caa42e6f,68545f1a,b2771a73,56bed22a,755520ac,3310e41d) Z8(fe5e6850,1440e5ca,bcdab7c7,a0f62f8d,94ee82a8,1339d722,00abe010,9601cd6f) Z8(730086a6,b8ae0ab8,da757ea9,49734009,45d9c9ab,a285ad7c,11a4ff34,718231e9) Z8(29d13f2f,cf2cd257,74364967,826e5292,3462b18e,2977121a,33a2a591,8f5373a7) Z8(f26e5613,5788ce23,d4f72505,fae12a2d,3c058f51,9d035b07,be52f8cf,b8d14d48) Z8(34d692f7,aaa28e03,e8d298ae,e277cc10,9b772c64,ea53d222,94ed8bf4,b5b1fe61) Z8(ac19f4fc,3fc07583,495b697c,c35e6f05,6cf181f1,8f3dba54,78d92c61,ddbe98b9) Z8(6a3444d1,95db871b,bc1f4bab,5df51063,598bd8f5,560d48d0,76f6ffa6,e7bd7096) Z8(915e6a39,39303bef,06ec2a20,6b4826ba,89a75de5,f5d8e318,be83d580,992dfa53) Z8(289ab106,cbc4d2d0,73ff649e,be1f10c1,8617a282,e6a36b30,cf383168,7321a97c) Z8(40951d9b,afd4bb1e,2f9dc889,5ebcfced,20c96f5e,8853bbbf,be858fd0,3de6d6ef) Z8(b7aff58c,a2ad6403,d85b0871,b268140d,e58b6088,ac9d7639,d9225531,d062a9a6) Z8(f38aa569,54dd8046,4f767fc8,f24f4f29,4feece8f,060fe2e3,2fc91629,dfdc345d) Z8(96934cc0,781942c1,e308bde2,29535179,00e54dd8,df52d8d5,73ee2e4a,63d4b8f9) Z8(d123a8a6,85a99cbb,4ac00738,9f4c7fd3,6c77c06c,1422b16e,5e72b0ef,929e9e40) Z8(a471e317,fb52e736,86848536,ca07fe82,f5436bfb,fdf95967,9330f095,0cdaaed6) Z8(78792c33,3085d1b1,a94ab1f7,c6916edd,d7d485d4,b4ceee9b,efe6998d,12ec0a89) Z8(e72a8add,82eb036e,5ed80a21,c0ccc7fe,4966ba33,8c6dbe84,7a522e09,0bc32ef7) Z8(1a021b03,a4e673d0,f674174f,f1598dc0,2c80c820,7404e150,cfdd067d,bac814ff) Z8(984c92a3,caa32b9b,80529b80,00e3b96b,c5ba0cba,00d513f0,0eb88f1a,c92e1dd9) Z8(6e4d25e7,83f2e73f,ac5e2eb2,db819899,9dfe024d,565675fe,f483b033,400ebc26) Z8(acb01b8f,6c56768e,3aa54c66,a8a9ed9d,552cb269,e5a69730,1eb31453,9a43ba11) Z8(278eae12,c4296240,c27656b2,3002b50b,d618cafc,3e729c99,3942c09c,71e7b875) Z8(4a5c58cb,f70f0a7a,e997c6f4,952280c7,d090df6e,b6924768,6f13cf2b,75e812dd) Z8(ccb92fca,f1e4302a,47410993,cd9374e0,7106c445,3cf17277,26c539fd,fee880e4) Z8(8b451eff,b6fe32a8,1b67de2a,67b9e75c,d6ef07a9,d0a98b63,14e3cbf0,b09cd522) Z8(01f69b1c,75ebe744,92e48271,03c36f5e,6975fcbb,b0b0df6a,15ab829c,b412b07a) Z8(04ba2f1b,09304920,7e3cc92f,eb623590,c9bc8958,50704d95,a907024d,0b9c287c) Z8(e23e9bde,d981b276,488063f7,f603e75e,c13ef384,3af0934e,e7bd7ce8,9bb75a4d) Z8(d82b01cb,251b92c6,cfd818b1,0f80a7c0,7b8800f2,bcd506bd,1e059a5c,5cbef7a8) Z8(ebaae95e,2fd3bef3,0c0dbfe1,5d77f30a,eff58423,9fdc1b2d,e82c038c,1abd1a79) Z8(abaa8d61,9cb9d3a3,2ce25d7e,d640ca8c,033090fa,b4faa517,9b9577ac,7e88afa8) Z8(12bcaaee,0ada618b,24d090f5,aa411417,936c1975,9323eabf,2fb65687,cbde8ba3) Z8(cd8884f0,e5265406,79ef126b,ce9bec6a,dc29a2a9,25be2754,d4592442,0f0b86fb) Z8(a6bb76af,7978789d,abf37628,eeb5c231,01acf5cd,80493e69,bb627cb8,2124c721) Z8(e323dc24,04fc20a1,ebb08520,12603f3d,ce1cdefa,222ff0b7,f0d7e4b6,a8b3d1d6) Z8(43e1231b,ea98a3a1,197d0f84,7f4da506,24464bdf,7dac1194,ca6cfbf3,d6fdc95a) Z8(42a2f452,456cf6cb,dc468415,96e58322,9c48dc89,77af2a47,daf6ef85,036ed785) Z8(ee92edbd,8db8b57a,45b44a0b,d3a86cea,903fa6a5,54aeec10,96da36c4,4be63dff) Z8(0a9f8fb6,f5d855f2,11e5f94d,39502958,ac6b15c3,a1eda073,77fa2227,27052c6e) Z8(e008e018,c8665508,722df837,ca05f6a7,8dd1130b,56215316,bc8a795c,f4fc679a) Z8(ee5831f8,3a2bc900,ebf054fb,c10240e1,2eaf30be,b8a0ff8f,39adc3dd,978ecc75) Z8(519c5359,e2696070,72220392,275176c3,e5c7a0ef,cbe13175,9175eacf,a0c966f3) Z8(72ccb96c,b3610a4f,a08d6754,386afe7b,7a60e637,7c958a0a,0fb4468d,c33e9fbc) Z8(054dc3e4,d09f8777,57231dcd,e93a0b21,ea691ef6,8742690f,223cd47b,e21a903c) Z8(959608dc,14efbaad,3b473af4,a15601dd,09731a86,39983c8d,b81bab08,ffdba646) Z8(7254b4f1,e038f804,37118e78,81f1e264,ed5b9785,2f7179f2,a2dd458f,650b99bb) Z8(0f3aeae8,ca94f051,430d11cc,b130fd1b,2901732f,e4f09ac1,d9e82e13,806f3e9e) Z8(84da59e6,902d930b,2b36a1e2,ea5f7b4f,f12562d9,468420fc,2bcab129,a524c405) Z8(ee337e77,a6b77c57,464ef9e1,6f8f207e,6be78925,6cdb5d40,38d28db3,bbcae60b) Z8(6de1599e,e42b3d87,1fb08a99,a4091b30,6ea5a74c,4dc785b2,23eb2c1e,a0707dc2) Z8(dec35338,d666b7b0,bae5cb5b,0b362fc9,26ebca65,22c7eedf,83669603,9fd97bea) Z8(61649f52,1f3080cb,1baf44e6,2f23f67f,0747c947,b0c8788b,877ebe0e,224dc993) Z8(5aa97e23,f202b38a,6814ac26,11d4f268,231c2c2f,52e857cf,5e461b22,5e8360cb) Z8(ee11f0c5,c1cbb950,793c972c,20217edb,f79927d1,f664d0ae,b0668b7b,d1e1ad20) Z8(e6edfac7,4fa94078,bfdedc3f,54758ab8,ee747068,1d0f9c2a,a17761f0,f33daea5) Z8(80a34140,35d84a19,2c1115b1,0961f5be,0573b94a,7435532e,4423d13b,58617603) Z8(87312b0d,54cfd8c4,29cfc2fd,104fa8c5,1c40e5a5,71af55d6,078c1dbe,222689e5) Z8(6c4343fa,47d2d80d,87e0bbd1,9d9232f3,a76df00b,91cfebf6,255c3d23,e565bfd8) Z8(59907fd1,0adb17e1,3833c93d,fcf7cd3a,1ecb9ae4,50f370c5,391c509a,632f5953) Z8(05b60a81,3f853ac0,09301a03,a932f088,99dd12c5,f6737641,262bb572,b97bb62a) Z8(eee23790,671e24fa,4aad5fee,0d92e59c,d11d8f5e,b4a7fbe6,35e308a6,47603b0a) Z8(0dcee4f6,37f98f9d,e31a6f58,c43d08de,d4d044b6,837a1123,0426506e,171261d3) Z8(562962d4,7e22814a,02ba169a,e812bf25,7c649cd2,8b6cabb6,7321750d,2073f4e2) Z8(acfce43a,4ab2a841,bc26ed5d,28f4aa1a,0cd3cfbc,4d4feef0,59ff55fa,f20c2a2a) Z8(56cff010,56aec095,cd26bf67,a5da2ad9,b67243e6,2fe62195,ec210060,84a32cff) Z8(07d6db47,747faa70,f00316c9,a2653d94,1c023d10,031f11d6,c5854b89,dc44a727) Z8(35750226,470044c5,e18d55af,0b6fa655,f01224cf,fc03f8d5,e36e201b,73d44dee) Z8(23ff126e,a60d3be6,2ae801d3,64b2ba82,7b8ae956,e4e576d3,e816b5b7,c4c70a8a) Z8(fef4b3b9,34f03333,f7775447,3ff81970,a95af69b,d3f7838b,880be4d6,37b6bf30) Z8(e4828b58,af2e6a38,09972377,1fbdde09,59529e15,292d2fee,9fbe23e3,ce684ee5) Z8(2426794f,03ba72c6,23964238,dbe6a006,185046bc,f8947ccd,db9db7e2,a423bf69) Z8(d045782c,4b055c37,4bf191a4,e5588559,1d0d0c93,5700c0a8,75b1b9bd,d1eb09f5) Z8(bbddb631,f1701f07,b83f7282,5e145f60,76c9b5fc,0aa98996,afc74d3a,150a4f2b) Z8(958bf3b2,9a6900e3,23124f57,06167ed8,72fcca8f,d9a96e5d,49930ad0,56d7b3c9) Z8(db01655e,e886479a,9253fb6f,701a4b96,07aabc28,f31bbbb3,509ece29,ed00435d) Z8(17d097b9,c880f133,a597392e,0d1f9b28,2b97c779,119e8468,ae78fe5e,78a3e76b) Z8(e9b02dec,530718f3,9b09af39,1af25a91,63743d3e,0da736bc,8a1c8229,f5f2ac92) Z8(f71fbb0d,7c84cd4d,7b770931,14fee532,66ae73c3,3875022a,2e23a5c6,a31b6209) Z8(2ba441f5,fd200a8a,b6ad7a81,69576e3e,e8d133a1,58436112,9423f791,5731da9a) Z8(39129f8b,15c2c5de,1c5038b7,3944ed86,6a6166da,f3edd6f3,904cf330,6048e67c) Z8(83d79386,95d8d529,cca3129f,fc9d655b,3962ef3c,25ba8362,a310b736,476f7bb4) Z8(acfd967c,f2469124,8517a664,d3955b8f,d9ba6196,75727dc4,e0b0c562,511427ad) Z8(6cea0d01,93e86f4a,60aedb58,e23b665a,8c251e95,57e73a30,86fb8978,ab5e44f2) Z8(f8c83742,b0300016,a20a7f2e,edaacfec,44ca4738,3edba997,c8fa2b4c,58de48c6) Z8(26b5c811,92770e98,d4e47091,8c585338,41a1de8b,89c21f63,5873ecb4,2cb87493) Z8(162a205e,8cfea891,e7726d01,945289ab,84a4ed61,9da1847c,5d47bec5,7ca9ed20) Z8(c3bd51c9,219847d9,1bc79d4c,9216e4ad,4bfb14af,9e147b28,a094da06,00c8e2bf) Z8(752d4d97,9f1587e5,bc1fe24a,ca2c8585,013d9e25,88545ca9,4361d713,e31c4bcf) Z8(e887c13c,6269e046,d9c4ccbc,6c3152ae,552b082e,25eb07d1,009bfd63,b0e296a4) Z8(fe25997b,3f27d1a7,4dbe7ff6,5cd3454f,86fe6a66,9d218353,9ed334ef,c8ffc273) Z8(6bae5b17,9000b3d4,b66b47d7,6e8d4bb7,cf08ca7d,04e55267,8f348f28,c97e0fde) Z8(90635f95,79d66031,56008fd8,920c0cf4,e2db0c59,7174b123,24a5201c,0e474423) Z8(031d3202,e174784e,2e817c67,866cc559,ea1a7be9,627f656b,ef9dfc08,8079d53f) Z8(33e2d150,bc4c1215,db416fe3,3edcfdb0,ef1798ac,27d544be,993c81f1,82ea78e3) Z8(bf27686f,e9e68682,104c24cb,5e954190,d78f8a43,351f26b2,0f31ab1a,90995e4e) Z8(abe5f40a,9159eba1,42adba8f,50ce79b2,9bc73a97,a2b559ef,30221d9e,b371c92f) Z8(7654aa32,769613e2,2e9e95e1,e4519420,d74f21ea,fcbc373e,34df73b5,cfc1759c) Z8(6ee5d844,cb7843c0,6d5905c9,5e422322,67e3d4a0,a1652ce6,07973078,85c9144b) Z8(4c5d0b1d,bfa544f0,59f3d60e,87c48698,10b01da4,585246ae,183af30a,7b2691e6) Z8(e161911b,8e9d4ec8,08f22c02,45d3312c,7e1baf6d,249fff26,e4823fa0,885a4c5c) Z8(19c16b8f,9f637cf0,276f720c,e0b9bd3e,0ad39e57,ffe9c0dd,1fec3185,f3854f87) Z8(e8788a0e,56f4c167,ff4f7d40,ab104951,08165517,fed6a1ed,e6143fda,16367289) Z8(0a3b6cb7,1fe80a98,09f22683,04759f52,c2a0e0dd,0c598626,f9e0e3a0,dc169639) Z8(6dd29b32,e45282eb,7c88d0c0,35949d51,7e50d832,c165a911,eca7f605,fe118dfe) Z8(cd03620a,093e1c24,730d232e,81a89672,70a2a15e,2fca8a81,9c8f7b00,09d5d113) Z8(c2a0875a,84f5fe25,b0411d37,5ee5b509,d55ce1b6,c4384c88,ad338e16,aff86144) Z8(e3696e4a,be64dfbd,0998f07d,6c96b6f0,f5ffd3e2,b255b5d8,a620f400,c0bc3330) Z8(a9d43ab1,4e7888a5,9838e725,c6525338,e0e96310,76115644,d73e7291,1406ee81) Z8(f4663370,f6bc702d,7e2f48d3,86e5f67c,22e459f8,0250f623,329ad737,b49bd120) Z8(e16c0aac,00c32017,45fdeb1e,7f25ad41,d4b1f52c,81e0c760,fe2077da,a60f95bc) Z8(0b2e13a9,c576d9e9,a5eed11d,f6f378e5,736a68e2,7414c638,2c6e64fb,25a11bf7) Z8(a185879f,6efaf126,1b077046,77a6a858,57a54301,916b6083,08be7474,8633b54c) Z8(c383d408,99f993d2,46d17523,78cbc8b6,f326c264,439f49f2,b4a20e9e,023c1de9) Z8(09b04cdf,92457948,0610e4e1,5b254b5d,c079faf4,e3cbf0a5,ae6459fc,b1337100) Z8(e475e5dd,a939c623,2ad78545,07281f4e,f43632dc,733f9492,ab9df290,601b4832) Z8(1db1148b,f7e89d58,0af175f7,e7d242ec,4bff0b49,926acdb4,d3056f77,028265c6) Z8(42f93b37,b01f24e0,807a566a,37cf9cc6,939709fc,7d48f09a,b77ad652,9ef3f673) Z8(5f867f97,a5a794e4,fa2ef4cd,85ae6fbf,32c889d2,f0a84319,16085f4e,3f9937f1) Z8(4967da23,707e20ee,dc43f46d,cffcbbc4,af06eea2,ba1eaff4,c48a823d,2f94e4f7) Z8(62cadaad,87905774,c24c666e,ded9ae25,199ad295,e1b00573,31e361f2,859e63a3) Z8(959018be,69cc030d,ee653966,7ce36425,dbdcdff4,d0b64c4f,62c08bb9,1761c664) Z8(9ebd8c0b,ac39c38e,bae48e2a,4131bc58,93d94c8e,7521a60f,562c90e4,cd902068) Z8(14577762,d25c060f,91cb65ff,0ab9b877,c21debf7,d4b9ca64,dacb4a98,36705d2a) Z8(04db5e84,e66d8056,99ff9bb8,612ca330,11ede701,48a34967,490d26be,02555d6b) Z8(f033e201,ee7b4fff,d85bfe2e,cb118b03,19a38dc2,39dbfd91,bf96ec31,70457baa) Z8(d20d6b50,c922064a,631a8349,9b527157,8fc1c11f,4ba875a9,37908938,a5519ecc) Z8(032f043b,e5193221,5cdce7ef,c5e84d84,30791612,560a0112,cf98445b,a8023399) Z8(5fcc8b90,86b45f3c,b70702db,76c36225,027bb532,70424a5c,dab34c9c,ebf591d8) Z8(dcba30db,398c03c6,491f5f7b,c903e40f,ae981c12,7f88858c,2e50482d,984d08f6) Z8(bfd97c74,9913930a,ba2d1937,ce78fe44,06de30f6,225c9f09,0ce13157,21056b5e) Z8(0780aaf5,ab2adbe1,6e0cbacc,0c45a68a,7f752ece,e78efabb,335f1318,93598a5f) Z8(44845118,bb2c9bdb,e2c381db,6ebdf5bf,70c51c45,6695ec8b,66fd5428,a2e40181) Z8(fb349a21,bdcf353a,0845b51d,d42812f0,3ae1faf8,b2a0cabe,bee2723e,bf5d2bf0) Z8(0f09dd0e,c453c244,8d6c2f45,8f1bc235,dfb54671,d27e6707,a86a825c,245d64e2) Z8(9b5979c2,50f1d507,2f03b1a6,526badf7,81a08cc1,af95ab12,f0d50165,202a0c59) Z8(276a764f,232252f9,b2128b50,0d8dfc71,b97f920b,87283535,303bbf29,71a68de0) Z8(bdaa67d1,851454c1,0cb9948e,3a29f486,b87c9ca9,5c774fbe,6d5e65fd,c0e6d51c) Z8(82eefbc0,1346ff43,345f2b56,f820d44b,603fc15f,e4115009,fe6f90a0,964d6462) Z8(dd55cfec,c53df51b,6cd95824,1f707fff,dae750fe,7b691af6,730a6d64,c75cf0dc) Z8(455f0654,d9dd0245,90cae083,d8232e1a,8ecee101,73cab9a5,6f817f0f,55714b8e) Z8(c4731f5e,88332f8e,deb4a7ed,b21ddfe3,168ba3af,48568dc5,1fae0dd0,5e924609) Z8(9f8b4ef8,dedd77f9,fe4e0b48,b0e52504,4589727a,406e9c55,d46d964c,d6a6412e) Z8(029fb0b8,277ed871,6c4f76db,50904192,72215145,3cab3d70,5047d632,17b16be3) Z8(44d4bdbb,1b20cbac,4270b138,a6cc9803,7ca7ce75,b0b78ed5,563a695e,d44b9ee5) Z8(b771f0fa,7dd55d18,0003fcd7,4c243440,4116e216,5d055f7d,6f98726c,a9f0e582) Z8(d832021d,efc02465,9d85e121,0b995c90,d5fefeea,e19127cd,77b40c94,76f13acb) Z8(9a8c6ff6,8a6d4596,ced0ddef,0def8809,9ede288c,b4a5818c,3749e187,b9c03c02) Z8(7879c15b,6cdde013,5ee56208,5fc0ad11,1fed6329,f38703fd,98aeee88,f3386cab) Z8(2f86b562,6f7287ca,090c9933,f3df85f6,ee27d8e7,e44f7055,83921bfd,111fa4c1) Z8(a1283c2a,292b760e,d357064a,be7632d0,3be4f4ee,17cbfc49,ea4ebace,93a032d6) Z8(ede41b2d,56c05811,8f025936,f77aa1c9,5e50c26f,c7d9269f,0e62d47e,d1c2733f) Z8(c00ff2ed,1df127aa,4e48f6af,bcaf1138,f09d33d7,8e8e4926,76a8088c,006d76a9) Z8(0945cff6,b665ea1f,76194796,837f5d54,6a2ce379,1a6ba6f0,f1078af7,b4528089) Z8(29d7a089,5b8682d6,0dd776cd,bc017e6e,668c1211,04a5e750,f5e94b5f,aa555c5f) Z8(8a5202a8,8e7d1264,ab46a41d,5f06ce0e,8b14f7a0,03a81df4,a5c701e3,d385ed33) Z8(8b16a2e5,687ae1a0,bf233c95,6f23be51,8204a564,0fec210c,3c5c3dcd,e71be4e6) Z8(e85edc26,560e48e4,4fa28d73,d2718926,d5cd4c73,000aa48d,18dead09,9e21f621) Z8(c1f3b573,cfc43229,e58befef,76131e32,33b3032c,ee5aec13,b72012e5,70b92b4e) Z8(e000ca7b,5a2819a9,9f4f5fdb,042e3987,f829707a,df92d22c,33653234,9697ec75) Z8(680ef8cb,c501f18b,e8f02c96,0e0216ef,521f3908,f9db80cf,be63b27a,7e61f76e) Z8(1a43b91d,ff0ec8c4,9ab595fb,f0f17963,bf7e5000,a6249d6a,1c1cdccf,110a2bc7) Z8(55034fc0,7cdc6e13,576f2cf2,87430593,552d4939,2289c242,12c806b4,e2dcade3) Z8(2ed7eaaa,1cdaec4e,4b31813f,9ad590b9,382f2b5d,e6e284e5,d8f0f937,9a675671) Z8(c1911583,f145b052,bb1bfd61,1b4d6be3,38d9ef09,c91f9540,230c1dc3,a4b3a09a) Z8(2aacb9e4,0b56e35f,e6fff065,aac15edd,9f72c762,79dd2d63,4a00ebcc,ff5a9ba6) Z8(935f6add,c4c88194,5b4c62ad,8fdd25cb,3d5b7ccc,891cf5e1,659cd5e1,b5ed08cf) Z8(d06abe26,8128c411,a349e897,f9bda387,cfcf6f26,cc4ee9c9,ea94d464,1f01561e) Z8(4a0daaf3,00adf1ab,dc63d648,bfbbb9ef,7b43de85,f4d470fe,03dfb11f,d7d47294) Z8(160d81d6,2d237453,34e79648,97e30ba7,04f49fe9,8b0de8b1,b9d22c91,e50c9d1c) Z8(34fdb35b,5b34f837,1bb60051,67b04b88,16fe251b,0b26fd70,34efe2e4,f1ba9327) Z8(76535724,4ea04b1e,93c90efb,b99896f0,224d0376,bd7a493c,872b8445,bd8f6445) Z8(b38458a8,4e51f561,8887fb00,14474910,6c3dcf72,8d5cf1b4,b2ccc5a7,39915a38) Z8(67ec4e3b,56d23545,f8534525,bab8e493,e661ac9c,1f7fb979,eea01689,34e15d5f) Z8(065f9b44,7f18d767,9c16c362,4b18c328,709e077a,9e78a37b,90a3c285,52f53c6c) Z8(c8f8ec92,f36ddb5b,02ffcbb7,97747ffd,2055801a,fa0cde52,c9fb8a36,79bfc8ba) Z8(1a8692aa,5d994f56,c0dc5c0f,e60a3314,25e4842e,4019e737,dd7478e4,4c1e6c7f) Z8(e10ea6ed,aa9f2e1f,1ac31219,2f8b6c46,9c4d03fa,6180d09d,caef2ad8,67e66dfe) Z8(0e6ed9b9,92dc9603,e99911fe,06be5479,a024ecdc,a1b7b03e,72334516,1d8c775d) Z8(cd6bc9d6,516509dc,79a6a98b,d644b3ff,145b85e3,7e754a13,24037ec8,6e8fceec) Z8(3bf1b9e5,d44192c5,98f15ca4,620339f1,8fba0352,6e7623da,29194141,e124ba4d) Z8(59849e44,28cc7de3,10a5c496,59f1ca03,ca495b24,8461b5c8,f0915073,a6df2721) Z8(06610145,48bcef57,35621eb4,87830fc8,05da0d8b,73ba1458,76759cb4,ac0a8c9a) Z8(9c2c4eda,fec1c59e,b4427e12,b4c2e891,e545d76b,f173caec,c1c698b2,2215b5a7) Z8(96b5b649,0baf051b,bc59142f,c507be6d,b518ae12,5a295490,3270b92e,484e8932) Z8(4c47a480,bff80038,d652c3ea,7d2582e1,35ac3860,5d8680a0,98374510,87d95a82) Z8(bf3ffbbb,6de0bce3,6e1873e4,6b9275f6,7a3a6ceb,3850ab70,4c004c18,ffb2d99a) Z8(14a1cf78,01de6525,b3878380,05892047,bd842e6f,904abfd9,a1167160,d30607ab) Z8(996be2e4,517b0b93,582dc037,3ef93c4e,f1c8133f,4ef58187,073cf460,76194694) Z8(55d0ab03,f4af9b2c,6bbc3a97,61390083,8f10b0b5,cb9f968b,00d9ad26,50b41df0) Z8(74153e41,a7daf1c4,559ff1ab,aa2dee0a,266a9f32,8f474f0b,b7217238,b51920ef) Z8(38cea67a,97fa77e3,ab3e0214,d61ebc1f,154cc1f3,dec2aa66,4885cdcf,59b30967) Z8(c3b0a84f,9ca2d9be,08bf15d6,2c777f14,b19847ad,e2c90c06,c6cc44e5,22e1be80) Z8(e3b3264d,10d1c106,fe6393aa,175b0b9d,daf82315,722db653,09f0bdc3,4302bb24) Z8(b9f08fac,c270e77e,38b66870,17d902e5,7d0f9e7b,ef44894b,28844376,e03dc424) Z8(f6b4cf6f,9f96f8eb,78a5e6c3,dc99cf0f,77948144,f90d2346,0e7d2504,fef25603) Z8(0c6e4fac,28947b48,6fa68497,08063f6c,4d582b45,518c8d1f,87dd8bae,ce83ca6e) Z8(3ded8062,7690e0d3,110d3333,d424cccb,a0691c9f,8491b74b,dbbf961b,bf8ca597) Z8(b528c4e5,87831a89,25c506f4,e03b31c8,deb32601,c267d481,cdd0e613,a3577811) Z8(6e1aa6ce,2b20dcd8,95b4622c,58f8937a,2ad0e689,2a2ef558,315a24c9,797777b7) Z8(5b8f2a5a,1b7c0a29,66bb1810,abe98aae,81958558,5ecf8530,fcb391cc,a0ee86c1) Z8(4681c431,4c4be55e,53faaefb,20ecfc21,a97b03d8,46781eae,93d3a877,2ac45527) Z8(8b83e1fa,d5f74f40,4afba6b4,038a9ed4,bd187ae7,eeea49cb,dc6326e9,b9d8a0eb) Z8(211ae76a,ffb00a55,4f6f4588,8a861c50,b41a7a11,10367d40,a668f918,73fcdfef) Z8(c22ef1db,a961a13c,5a77fb4d,c3c2602c,78aec24f,85728f35,90ae43a6,544a3875) Z8(f0b2d6b7,9920cd10,62d4821e,95763947,33449cae,e5eecf9c,420606c3,1719a471) Z8(e55be920,818b2cc0,9e9a55d6,26b1cb43,396daf48,61379a62,5e401b64,d65d988d) Z8(6f40cee2,a6b5b07f,25c20877,c1145c7a,54380361,634bd886,c4e7ed7f,885517fa) Z8(85e630d5,e4c78afd,d8735255,1b66600f,0e9a4760,c22ae6ea,fa0e9fea,c79c9e84) Z8(7ce167fd,b636c927,d59a9917,56aa061f,b8724096,05892927,b9a769f6,bbf1344d) Z8(cd881354,22041a46,72542533,71a1d60c,8ac117b4,a39d9dd5,28d2ce91,15432387) Z8(48e2a3c5,9203d9a9,6e7f69ab,34db510a,2cd704d8,607733de,29154aa7,f384c842) Z8(ae9ec3d3,a865d115,8b83f017,a0f6be73,4c7598e6,95e39376,ee43d440,7c748bc3) Z8(d96795a4,9294db13,6364afc4,067705f7,b9efc03a,3d2cb687,5abc687e,ed8183f7) Z8(bd2140b4,e7f0e937,f23b4ce7,6432ee53,1f3827c3,161bd5a6,f4a78c87,68e4461b) Z8(1176185a,18a69dfb,32a89105,deaf117b,33746e9d,96d3196c,3816bb85,3d1b228e) Z8(3f59f82a,593f4ba8,4f86b14e,acd08499,7c364293,7c3f8956,6cbfa457,7ff3e620) Z8(28b686d1,a1c0e367,62b67af9,fed3295e,7e2e7391,7100403f,f553150a,bd9864e9) Z8(e3ac48b7,62e7da84,64e0c290,3dd8fa17,183dafbc,1413d3b8,4f5540c1,9fb7cfb2) Z8(00ab5d7b,da5d1341,6999e284,802c1083,0431f795,be287953,1c1f19e9,8e01b147) Z8(b1d262d1,a4e5da07,09e7f615,c21e90a9,8b30b320,595fc4c4,30ed74d9,6efb4050) Z8(1c9dd97f,970efd5e,d406ee38,b67112f3,35b7bc32,d215c40d,82d96baa,96ae1526) Z8(f2eed99a,f40e0024,672311b4,e9a0daa3,9b3c4d61,968ea93b,0174c330,fbb562cd) Z8(b1148b65,254d755c,27d5507b,27ed24a3,043545f9,17435b25,cc2773ec,ae1aa7de) Z8(76f4b4a4,419c67c9,d806f787,88691d37,90b1a165,07288378,64df2765,a19c7c82) Z8(ceff8802,dbf2b465,0b9f3d9c,14c7ec37,91410931,af5fabc5,c957e169,3af3e809) Z8(066241aa,fe847877,7d54dec3,34939e6c,6cd589ec,e8795af0,91f57914,41b01ac5) Z8(856b32c0,21f9b82a,179910ad,2470d945,bfde968c,0e465c1e,bdbd386b,32b3547b) Z8(e0ef5170,2047db49,1d9810ce,0b9c87ad,c2d5869a,906b4cfe,f4f71be7,25d7fbbc) Z8(0b540d0e,b0bb7715,cbf1ee35,8a63e752,30059855,4691d3f5,89973e96,c58dec41) Z8(da2e37b0,a6da947c,86b17659,9a13d0b8,760674ae,d1e3cdfd,97f604dd,5cd8257b) Z8(d396c0b9,a7abb4fc,3b4418e2,9784d5bb,6404fd30,58cbfddc,8c5522e0,58ac744c) Z8(0a38ae5d,06c1e882,3b2529b6,a6d2f12c,cbb990d8,e316ff97,78412080,27207a18) Z8(3ccc7dfe,d2c444b6,a9f6b0fe,be631180,7ef54272,dda820c6,a4222017,813abfad) Z8(1dbe2a60,2de557d4,2f170cd4,383e2330,ce6cb17e,aa74ddf1,08683125,dc2e90b2) Z8(b2093588,8db83717,7c2bb947,71ce5047,fc2f4108,c902ff2c,426fffb0,c0c72099) Z8(c2dba36e,e038791d,27c77d25,eb3b00f0,83d64d20,b205f6bc,bf4b1d62,3b51a9bd) Z8(1ef0d2dd,5e4d6c83,5f583cac,9bf5c702,e599349b,cb8cf949,fdf5cb9f,8aa51438) Z8(ff91b34f,1eeaaa09,7fe4216a,95871991,e7fd29a0,19ee6fe2,73cc7ae4,bc1567cf) Z8(7a2f8479,bab31bc4,56833ef2,ed8c18db,538a8025,5c2389ef,a2f878ea,58e44038) Z8(6d6b393b,b9530eb9,d094b384,c7129d69,7afd85cd,b7fb4e17,69ef68c8,2014fc9e) Z8(5c4c3747,3f4297c1,b5b55c63,074b5a3c,b4ab95fa,da06cb5a,2e4f7a15,605cb03f) Z8(37151d49,d26dffda,1869bee9,d7adc727,1133d57a,23e155b8,7b5b370a,8fafd081) Z8(d7f6161c,f336e231,d1da82aa,f2a435a9,7e8fe030,b2cddd01,f98fdb64,567c6874) Z8(03b76a46,a48b42ae,d469e90e,c6cddcf2,c94222b0,319fc670,a6bb804d,84bf96f4) Z8(335cb072,1f175952,75924165,8f743bd7,13e55433,e9fb97f8,a01b810c,fc4241f7) Z8(8c76603a,77249f43,d55e4b88,5de9d76d,9c9bb98a,0a46ebf2,57eddfdd,2c4bd824) Z8(f463f117,88d1a024,0554a960,8968fab0,fe607124,485583ac,f9f60e64,a296b2bd) Z8(372fd0ea,1326e92f,056d01b8,6cb8aced,ad2af42c,964eeb27,7cde9156,dfc786bc) Z8(96a06692,11786973,252f4312,5533046f,3578d48e,a7c13720,49df291c,31ea7acb) Z8(8a49e666,9ab1f191,4fda32d5,c5400be1,e09a22b6,00ca356a,957c8a15,bf92f6d8) Z8(b2cbf7d9,fbd173f6,d74a7486,94869d04,1e84877d,59ea3bd9,3a8b2ad7,ddb3804f) Z8(bd9c2b69,234fe71a,645ade00,5e45a8fd,26c9fac8,18c1794a,a99bbfc3,9376b166) Z8(eb63b6c2,5ffb2c1b,cc24aa73,d1d81194,dcd4b26e,c26d23cb,f03c8bb8,59d04018) Z8(4805c144,df545e0b,042cdc40,73a249a6,330b517b,918ee488,9cb9fea1,e3735701) Z8(8ebf87a7,f57adeb4,04d718f7,c5a638ad,e8b54a8d,d21d35fe,4162e92f,004cc7f3) Z8(28935de7,d2e8a79d,b79bdca9,36b63082,fe650e08,c3d395a8,55e7ab4f,95b5b57e) Z8(c94f4639,86dd290f,853feb7d,9e6540b9,b5010d28,f3ffd35e,d5fc9b4e,5b310927) Z8(c2251793,8a5216d7,369807d2,426b3191,630f3257,a55369ed,36a6cc03,3ae2b401) Z8(2b193a93,b43e591c,27ce08c7,0d425e24,6b0e2f9e,720df0b0,cdfd7884,d14d88b0) Z8(6c860d1b,41961ffc,b2c12bb5,c049432f,d499e987,e61ea278,82b71866,34446b41) Z8(aef85fa9,a027f8e2,775c8d1c,a8a390ac,e20e81b5,3facca70,5173a83b,e3148b51) Z8(079519f0,8a2f0d7b,c1c2dc18,70dc5f79,f81bfbaa,3b6e619b,73060d21,8b41faab) Z8(ccc989e0,663eebc2,bbf39a54,3bb289c9,8cbfb470,6066092e,415dc5ad,015402e3) Z8(881d1844,3edb1999,9ece38df,dc16eed7,1e024ee0,518151b4,0d3bfb7c,7e005f36) Z8(be2dab47,86efc81d,c6570f6c,d3578319,34eea96a,10931714,d6e39ed0,bbd7bbae) Z8(6052a89f,83e056b5,7dbe41bf,6dad5d38,d56c2d97,f56f57be,e33ce7bc,864b3e68) Z8(0719b540,d36b719f,0e2296f7,e9893ce8,de1d0662,64a7d918,dbd96297,b69a7c3c) Z8(29bf4b2a,a124ba97,9ca86656,739a9532,affa92d3,9db52517,5a791432,9b55f4e2) Z8(4ff6d051,e48ac777,88211b72,050af89a,3e40759c,5646e536,35227403,241990f2) Z8(8af08023,48456078,b0fa317a,179ec78f,6d695618,e494e334,ac93691e,9f2fcb45) Z8(b72ffe39,66c1cf0e,2edf7292,7ca71356,c9af32a1,b2cdfa9f,0d9f4299,0041ce7e) Z8(7b7c9e7d,ddc24efb,bb1b4623,65964d7a,bf093dd6,45ac6efe,92f33c20,d17ed003) Z8(635565b9,c8916308,7e22281e,ee5a274d,3666afb8,dd7ea11c,ce001b3a,6e20ba70) Z8(35778a9a,a79ef85b,ae6a829d,5a07dbe9,279286c3,55100386,c14fd637,f6926b4f) Z8(e0a8c0c5,dcb79263,41c8516d,d55fd5d5,7d58cc50,4721e5dd,3bff7fda,adc7279c) Z8(e0dc5dd9,dd11b946,62025438,0c646763,b793a99a,10d26442,0f761663,77482fd0) Z8(c4e18443,0f6279a7,77a55929,75d3de28,7ca0cf84,31eea43e,6b816bf5,2bb2a923) Z8(6f68fc45,523b14b1,65dc8782,b028daa2,52118787,a93964c9,48c45c39,fdf3a498) Z8(56b69e33,2674de3a,dd6cb4e9,a6166489,5c7e1523,bd306209,db0d9b89,6cdbd5c5) Z8(4e470eef,f631be45,f33519b3,64b622e7,3ec8e703,819072df,d59c7fe6,f55a959b) Z8(45c816a6,a07e8535,a7586999,56c37346,649a0bcf,fb09256d,83e4a95f,a2fe5d1a) Z8(3d7fa055,6bf63e2b,d6ba9546,146f0a56,575edc1b,5bfa306c,31368143,24a52bf4) Z8(f9215cf5,d3088453,ee792582,5bbf1d5b,80de406c,ca0d04a4,7da3edc7,07326636) Z8(db7030ac,f67d8ab0,0e99850e,0b581d00,bfd1023c,575d622e,ba179c08,9ee85149) Z8(4c6e1da2,e1896ad4,a76e2045,68c867a8,2bdee0b4,9a829a29,20c8aa55,0735c756) Z8(49c0d166,e5a18f39,b03321d8,8bc8c613,67e5ab85,c390f217,bf07a8d8,cf36aa5e) Z8(07f8c19f,6b39680b,61651e69,b1ed73cb,4fa8e837,a96f7875,3f469c75,efd3eac3) Z8(4c4cc0f0,b3e779de,5f4e7c13,959061e9,cc8593c4,a4c2696a,a30c657d,831679cc) Z8(a4d69dfe,7196c636,92812689,57917769,92c8112d,a21ddd8e,28a63a77,c47a6edc) Z8(1f90c7c5,0f88ebe1,e0ec86c1,abd312d2,1f0a3497,05a97686,f4f5938c,bf86c52d) Z8(ac882f09,dc5e1e2b,e3c2be1f,f642a458,a32a8614,2a0659e3,a5d201bf,df1e03f1) Z8(2d025790,56ba61a2,1b6a0e73,129f2100,b3771471,4d88ea03,5b02a5bd,0b71f0e0) Z8(6491312b,8a983a00,b76b1116,72da0cd7,9ec9fdd0,364eac08,df80068f,864bc793) Z8(3ae7d0ff,d7209b06,59f666dd,02aaf5ca,6cd21841,6e9d09a7,95317baa,89f3a6a9) Z8(a65efc6c,02678ad1,4f0b77b4,a5849458,0b08247f,764e4864,7a5990b0,4ed3ef88) Z8(b03f5b51,dd2bfcaa,5676a03c,125cbf15,41e84291,f5f85a37,756bfe82,978baf66) Z8(aae9048f,47abe149,1c5e06ac,85b6c0b5,f99cbb95,9a4e2bb8,9869bc88,c061475b) Z8(04602120,08e3a9cb,b340406a,f480395b,a12b481a,de0fe3f5,e417bfcd,40907dcf) Z8(4630c9b0,f89a116c,b09518e0,d5cb84f6,bc44c8b7,9abc761d,c43df93b,dc0736b4) Z8(e6b808da,16ffbd27,57c81144,ec59dffd,d0c0fbdd,51f9d24e,2d37748f,07e7d943) Z8(8653cbba,e1625f47,0745eb80,43075525,4ad5ed82,45147ac1,24425fa9,dc1da2a0) Z8(dd3a3ab0,c91df13c,234a99c8,cf216008,c63db788,d6eeb599,479c3c31,dc6cbe5b) Z8(73f3f7bc,406d5b6d,b32c5b97,991bb7b5,af04635a,c5c4d259,7a8f92a1,f0bf38e9) Z8(80d84b69,6273fad9,a621777c,05aea84c,7d2021b7,c18ffd86,367e657d,661c9a5f) Z8(2f8628c2,34455321,4fd128b9,8b3c1e72,e7afc246,19725c5b,3d8daf05,389a3653) Z8(6dc72801,469f47c4,b1194b4f,52b61fbc,2e186ae6,64d69279,af1a4915,12063b37) Z8(1315515b,f4e35fa7,9911c966,e0b4b0f9,51328da9,895a72b4,3cdbf085,bc0d5211) Z8(cde8fb76,8490e5ec,2d54e4bc,4e80a33e,7f77939c,e1fff33a,617ff84b,af3a3db6) Z8(141fa8fd,634b0391,92ac5663,f90170e1,e00019ae,dfba5fb1,54beed7a,94f416bc) Z8(9acbb1f8,0fab5c6e,e2f189e4,408bfd42,a9514a78,60edf001,739f2d6f,b7688b7e) Z8(25924489,19b9cd53,25187b9a,1b401ba9,f0beafa6,951d4331,59b1acda,0ecbc1b5) Z8(f5df288e,cdac0254,3783f2dc,76f90a07,452a8022,fc165c96,84879d2b,2526b782) Z8(193ec27e,92e19be8,beb2397a,d8999700,2702e919,de4e11d2,b7e99b37,06add8c9) Z8(9e1b8d29,e9824441,7874f244,f4b00a40,aabfdca4,acaf85ea,0d4cc54f,ebe6b8c8) Z8(fe85f485,06bb8a99,234fc00c,dfe549ea,9d20d237,ba5fa9eb,669c4277,99de8b91) Z8(058f6841,397322c0,64c81277,6605a3eb,32a11f8f,db51a05a,adcccc02,eceba96d) Z8(161d6821,7656a0ad,f6b75aa2,31ac2233,c6844e50,c75fda8e,ac84c0b0,63733e16) Z8(ef45ec9e,5cb61b19,a374b3eb,f640e5d2,9c30d95e,81716271,669764f0,5651fa55) Z8(24036f0d,6abafdb3,135b0e9f,0bd30128,665fc593,2ff57351,7299a793,e9f7b9c9) Z8(fc560ee4,6fae75d6,30981539,04147b4a,bd6b63a7,08d5489b,294b324d,c2e855ee) Z8(ee6ea129,ed8142a8,510e597c,9e32e6bd,f70c2e5d,c1bebe67,201d6abf,c5566460) Z8(36fc044a,cd7f7719,bce64d18,aa2e23b0,749adef9,aaecb789,ab5e7f2f,f843bfaa) Z8(60a0f32c,6bdf355d,1f4d65ac,6452913d,dcb03035,64be1d89,f3f81f60,54e1aff3) Z8(1aedadca,ef73cb65,4f8189a4,16a50bc4,7cd24ad1,1818e5aa,9de66898,1b326765) Z8(844e3232,cfe01ebb,8857ed9e,5b6eaa41,ead2caec,af14cbee,ed4c92c6,28d0f7c7) Z8(e5f37fcc,0a962a22,64693ae4,303ecceb,180aee96,d9a80960,a9017ec7,f664cbb8) Z8(aac9523e,a980aebe,e97724de,2c8ab22f,edddf3b3,9ab644de,87f4ace1,b81ef47d) Z8(d7df19c7,3d295919,e750fcb3,089c9f39,02da03d7,9a0f3567,49c21518,7dae2c97) Z8(b8510eec,8513f128,aa892f1a,b648e6f5,6b571617,65bd30dd,2086a5ac,4d1e7b6e) Z8(d5c6db93,92a85ffc,1385ca97,017e074e,7eb6e047,6907ec0c,0a3e663e,98100846) Z8(0fb97e22,502c1ad4,9144fa5e,49974b0e,dc226ee7,c2e83fa6,f49ffd2f,d847e14c) Z8(3744e06a,e1a37d18,add417e5,10890336,685e6626,d972eef1,e1822bad,8117dabb) Z8(6f39b9f0,6927af3c,b730d786,acae12aa,5c8c1f55,15996216,925a4791,16a497aa) Z8(bf72a56c,e3bd2524,10b5ea77,57eefd90,ac4c0ee6,45bc50c2,2be61a30,bdeee682) Z8(faa15561,63963d9a,81ba98f4,a48f3c81,943f9527,c8381cec,351d4d20,cee1996f) Z8(09548d01,a15ebd73,570255fe,dc624df8,18b2d60c,8583c567,1935335e,e2778056) Z8(5493cb8d,73ba4c3e,8dc11bbc,a5d109e1,64fc5978,bae42292,dbf944bb,d5eb595b) Z8(b31e05e4,67be010c,df2a299b,d6092164,eadc678d,3e6cb07b,e7af81cb,f00f9feb) Z8(dd0c4874,e300c536,45f9ef18,be35271e,3d137bf1,711fd392,cc9795c8,36efd196) Z8(55f62826,48699bf2,7da4fe33,10b3bcb2,88393d58,c24bbd03,c4521fb3,55560ebe) Z8(7318c070,97b5344f,9d548d41,eaee5346,19b4a1c5,b2d28b83,f7f3d109,1b870034) Z8(58fee59f,08b4e034,aeeb8204,918f5f1f,a7362fe5,da8afc86,e9fe9b96,cc31375b) Z8(407c042b,af47ab2d,8c4914fc,f1f438e9,7dcb11cf,a75f2558,ea3d4d9b,365a1123) Z8(ec7b772a,82a096c5,8a304665,f7311357,c6152618,0ff764bc,35b3b662,8ff11b74) Z8(0b903466,dc733022,70ce2fa7,25304d64,8c3bb629,4989a980,85ac35bd,345fbc62) Z8(219e46e5,63f9b00d,9ec03089,c911afe8,6f57c4ff,9f766b5d,794bf554,835b7e22) Z8(9cd0fb0e,b2ba2766,7ae30b91,3e216a48,3766a453,11557ed7,ce935969,b305031c) Z8(c79aae79,ec3f7589,2a762541,c17bcf1c,5aa2fa46,a7e01c2f,ae5d4c46,c46258d5) Z8(90847ea1,a3340143,65fe1f10,03a28358,010293eb,426d39f7,be4d6bf2,777f8e72) Z8(83089938,58236984,5a48508b,7dff077e,e7b3e0f3,cb072b3d,df127681,cde8cf48) Z8(2921d02b,224b1b33,388f4127,a6ee06fb,c1d8d051,5fe3cb84,52e3909a,3f8d69d5) Z8(64bbdfb6,73588015,47c46b2e,92a4790f,efa23215,c836e2dd,743c6f1c,4edefd78) Z8(63e516e9,978b5d66,9cd714c4,7e69a349,7694a8cd,d2165d79,c08385f9,378006c7) Z8(9314d667,4d3bc55b,659866c7,a6564e06,e641b6bf,2d6452cc,60ad4bb2,a5d1fb02) Z8(21e63146,836f8500,8e4ec160,a129bfa3,15d12e38,e4bab3e4,2807da8f,b747c1d2) Z8(b10977ee,f445d4da,07d0a9ce,7a0e4054,c01fe63d,3f17e752,67222a71,b1f22ce1) Z8(3783ebb6,ea29f33a,6a5c3f7b,ae6eef50,23c8dfcf,6eb7d446,5b86cf4b,9665e367) Z8(851c26fc,97de8586,a6dbf047,3fd3ee19,2da5b29f,2b1c9021,4fa06252,72d4385f) Z8(c3833763,6ec3e2e1,82c6442e,6856e222,b155fd88,1ee65d10,f24d28b7,5b0a9a74) Z8(20752c27,ac1d351c,669063a1,f4e11304,cb2c91ae,4d868da4,ca2d9940,76bf5e52) Z8(f2015df6,508e33c5,b208080b,820eb267,6f4798b8,a6c225c0,fbe59c25,b40fe2cb) Z8(3f4feffd,8606dcb1,b2adce1b,9f5c29b4,66f8d3e1,ae4d2f82,128e2381,5f82d83b) Z8(b17f432a,4b6cd913,08e10f54,cdff0fc1,ecabf8ad,c152597a,9c0dcc92,91451f52) Z8(7c7d6332,0b41c1ce,48f79f31,0c7f7ba3,9ccffb78,74e20b0e,bfb75a5a,7a6e4c2b) Z8(019634f5,59d19110,08f75794,8b6f497e,9bff242f,97630c2c,cc5171d4,c2c60d16) Z8(2d38fb43,89146eec,6fc36bd1,a788e2ef,776f5141,193ebce2,a2f4c4d9,0c9b3ae4) Z8(358edd9f,adc8b9fd,8c6484ca,ffbac4cf,b52b8282,e2c0a97e,835717cc,d8235068) Z8(fc5b4495,a687d2d6,2c36e856,3826824f,f26a263e,aaff03da,b64fa038,a10d486d) Z8(7a723110,c4585a90,1803be2b,d55d70c2,dd603f4f,c82fae01,05da6977,3314af3b) Z8(55dd534c,41e9db8a,564f7902,6fc6831a,4b332f08,bf771542,01d00b92,e4cd0224) Z8(78b5bd12,ca731fd8,35fc335f,4f715f8f,dbed0580,4c07fbf0,acf4e5e8,3b563438) Z8(f5b5f85b,5e4d1dc0,5498ff9d,8d2eee1d,4ca484c7,f7feb2dd,61f1e2fa,71b39c0d) Z8(1614c069,b0e19649,2031ce0c,89cf97f3,5141c2bb,85f7e594,fd95bbb0,0cc4b06d) Z8(d3aba1a7,61a9d102,f339109f,e556b012,f69487cd,3d8c13c8,677550fc,eb06723f) Z8(d9382254,debcdb33,f6b4480c,cc357526,2c0dd60c,f627b884,2438841c,c74e4ae2) Z8(253c2658,f72b4f71,28f8ea5b,7079217c,b5ab5ad7,ea879675,9e5bee01,9583dd50) Z8(65ed0c1a,5177c5da,7bb4c1d2,def1d47b,1ada435d,502138b3,d8d5820e,6284c7d4) Z8(7f493abe,9941e4b9,d9bdc7d7,c901d779,554006b1,e8881213,66e8ed52,8bf6efcd) Z8(9d2a9f60,72d76f6e,88217196,48de863b,77c04b02,d86faef0,b778e24e,d3a189b0) Z8(78a4b51f,1b78d543,548b05f2,486881cc,4beed6ab,62f38f2b,a4aef7df,46e3c64d) Z8(ab4c890e,bfcd3df4,23178a9f,1565e648,de37e7ea,ceba2b9b,cf1873de,13445283) Z8(0381fb9d,21b762ac,33beeb26,5ffff250,cdb8e3fb,0a9e7be5,d4c8945d,b411e16f) Z8(60357fdc,b1c853d3,43542d98,4757348f,30ab3308,88d82e06,8d8bfc7a,225cba7c) Z8(de44138f,6808dd09,f6daa08a,fe5b67e6,93b92780,6c1f80f3,9a836ae3,a93fad5d) Z8(666bda02,de914233,99f416e5,ccf4608c,43fa2a66,e53af166,d870a4c4,a316d3f4) Z8(f4e7f206,f33d2f06,2d60d930,4b900eac,c7702fcc,e3d60b47,902481f2,789e2902) Z8(da2afc9b,e9bc15ea,a2089bd9,d9ac60a1,3533ea2a,6b49b95c,9c93ede7,70fea71f) Z8(2cfd6563,80bbc0c5,d91130af,207747a0,4f96cebd,f6a52267,a1d56a00,6a0b5fa5) Z8(59185d86,8e2c5d0d,e6c6cc08,941e27ee,8bdcd2a2,2400c277,95ab5592,6dd35b74) Z8(555f1577,aed3e7d7,aac5e8ea,72f511e4,9d1b49e0,84ecca6e,53b6a29e,cfa74a52) Z8(5b2bb4d0,324eed99,7fc163ee,93a31d75,bb29ce85,83322f4a,ab3d7cb4,22975699) Z8(e7fcca82,46fb2174,8c58ff1c,c3ddfc50,d04e94de,40adcde6,fc10b148,f7c994ce) Z8(b4845d37,a1803ad1,ebb25c69,44f3830b,d5fbecb5,b197aa0f,937fde3c,d9680ba2) Z8(c197a308,0ead709f,8b53b2d4,fbd86a58,7b32ea38,dad85ced,f30b1d43,7defd013) Z8(114fe877,769d9137,1fc4f287,179962ff,8669ab70,00b12b98,9d00be52,12136ac6) Z8(a823e91e,9184c39e,13ce2305,bb48291e,0d0f6320,92122d87,5fcc462f,7794b64d) Z8(0d92a896,99785a4b,ddb7ddb6,7a2f3b90,73c89f93,c897136d,869fa241,b0e183e4) Z8(d474f849,59f6d145,6ac0dcae,3d1c400a,49fd8278,fd4f06ae,5e4f8019,f1002590) Z8(ddbd9d20,8009a3fd,354659c6,65f005c7,0b38910e,11769e7f,68b0ef6d,4f064571) Z8(18eab72c,e72b4cb4,1f4f13de,8751179e,5082d9d7,791b514c,62d010a2,a052410a) Z8(5228bdf8,cd28b9f5,e944ec3b,b2b9fda1,702c2408,7a801380,fc7a6a1c,04a14159) Z8(41151f0f,b81dd140,c2358875,1f2ada72,767caceb,71da3180,39c7a57e,6bf4156e) Z8(d6d387fa,966053c3,85c315ee,ec54feda,c2feebb8,432b8bda,5af8a4cf,4f5d5376) Z8(1bdfc5ac,c469bf34,affd4119,052e12e5,733e129f,00e28c6a,24026e65,063b94ad) Z8(80568719,49e45d88,ebe8412d,a36141cf,15b24aee,e3d6c51e,744c8a9a,9199875f) Z8(6a04edb1,261729a8,ce514ea7,44a6cbc3,69ed7cc3,8817d2dc,893f7534,9ffa1400) Z8(d48640da,34857205,ba1592d6,b8c10878,221ab0f0,00cf8ec8,8a12a532,9f34e04e) Z8(a7a47efa,038e8bc7,bc90ba05,d8a5ecb5,63858ecc,b8e1c8cc,c73b93c2,827310d4) Z8(42a26ac9,96e1deb2,98f04e1e,b63ae3f4,8c4d0aca,38532ccd,c763e962,68769ec0) Z8(a102fd37,6bb4590f,2305d566,a513d723,804efb71,5e2bd475,8a0589d7,a186984f) Z8(67dca50b,19da2da6,c5640310,48a6da3f,0649ff60,90094d5e,e280c057,c870e68f) Z8(6d377e19,6051283b,f8e53a58,8731792c,1ad45139,f889655a,2ea96f5c,a98e7eb4) Z8(b138ea2f,385c0ed1,9abfbee7,7149d74b,66912ee2,d125c745,a997c052,a147debf) Z8(0bb9c619,1c77c05b,a5f15700,bbf663f4,04bc7328,3cae6a50,8a689f24,70e88eae) Z8(42994778,8dda9bb5,347b2516,a5a7f18b,13dab2ea,b2f3db55,2992e3d7,ce81f2a4) Z8(102db868,63cca6fa,ca9b13c0,ba43fa97,ea868373,f290bed3,8c027270,0cd96dc4) Z8(4b4fb85b,d5019902,06d67d81,99e239aa,576cc8f3,f251f71d,5386b130,4372c17f) Z8(74a29d01,24763c14,727dc4c1,9497d631,7a5852b6,654928a9,c05837f7,a87220b7) Z8(937e38ea,4e53279d,0b023d43,9d12361b,73f921e7,dce9e47f,6ca154ee,aaa17f59) Z8(a83be356,6abb7dc8,72123154,2fdf117a,792c28f8,0e17175f,70c037b2,660e1b75) Z8(aac7f45a,fea566a8,b39dfc9a,258696e0,7a086b1f,4fc00282,4e44eca1,d4782a41) Z8(b9322c56,6663dc6b,60e9b579,1fc2138c,68da1ed6,6a858888,f5c8bf15,d36ec5e8) Z8(28efa015,3b8a79f0,4f4ba995,da0a9950,535feb30,6c62f313,7a5fe012,777e8010) Z8(338c5a38,2e716ad0,61054419,1d3c343b,2e762b84,723e7ab4,830a98d3,93c38e63) Z8(0f858b11,16a24d08,ecb3390c,64eb4cb0,626a79aa,fc4548ff,9d6aa870,2bac2c0d) Z8(15453ebc,a701355f,d6c342ee,ca2a3bc6,be6ca7ad,0ebc3ae7,fef4dfdb,a67a7ecf) Z8(4da4394b,89d6a0e7,bdbe26f8,a4e3eb9d,0fa2a98c,eaf034e6,7b653b16,994ffa77) Z8(b69532b0,74f40cf4,24ba54bc,ea3bb719,a726a53a,7e711ac3,771dadc4,01e6e881) Z8(a832d771,5c12fbc1,7e4a4bac,79ad0016,b6f9068c,20baed48,e8aef327,8af87313) Z8(4c892785,0cf694ec,8f6e82fa,6c2e0aa6,146c1a56,da84e9c9,7b14283b,029ceef5) Z8(3fc79fc1,c177b3bf,a1361edb,e2e7eb32,125b042a,6dc86660,a2afb901,6c1d5f04) Z8(fbe80f81,2ea9800b,68c30665,be682f2c,8b2f764c,a5499b92,0fd77750,6aa0b8f5) Z8(7fb5a54c,91b964fc,e8d4ce8d,3683d895,7b429b59,2632cd59,bf880628,801bf1cd) Z8(7427b7f8,29ffa438,2c43caed,a928993b,6ad5748e,9a6ad5f9,2971a477,01049254) Z8(2984c95c,2f6031ae,d09f06cd,aa2a6e24,8b16bde4,f8537b03,6b2b4461,c88fb5f4) Z8(20e749be,c19ecb17,b1e9010e,649930dd,c6af2cda,9b18a787,602292f4,ba07524d) Z8(22d169b4,8a6e2e61,b67b36c1,462b85f2,f4f1a289,6de1f549,d3e587af,f47f3044) Z8(b39e19f1,66df1718,626b3e54,d8d49d0e,780d603d,ec59ee7f,cc466a47,826aec93) Z8(90f9a939,ec7c482c,d4f01abc,82bc1a66,ce342d45,a2523247,852e364b,e8d9cacf) Z8(adf2db6d,393e4170,60e0f036,16a45a0b,3e14bd7e,a25787a9,bda649c1,27c39743) Z8(968366fa,853f035d,34d4e94d,f60ff228,f9d05dd7,cbdf5f19,f7648bc3,dea8ad30) Z8(59466820,44282bee,3e839f1d,16d876df,796f400d,71fbec38,1c8ee629,62050b1e) Z8(f4ddfcac,d8a6edd6,a7bcad2a,f2b3abf4,ac3d7779,9d82356f,51581e1a,b08ac97e) Z8(67dddb23,641a3888,ff7a246f,ee1d8d55,85d5298b,98e86851,fccfc4e4,ac4a06bf) Z8(cebb6fa4,c342bd09,24a4fbbc,e57e6ef6,02b4e380,826f9d50,d3d7115d,df88214d) Z8(a08a81f9,48b49953,00863964,9ffb047b,1fc12fd8,1d81722b,1408adae,fde7dc93) Z8(080b605e,3329a4aa,b91c8042,d4dacb65,ac2a8410,374bd953,a221dc10,515f8b28) Z8(6dede440,3a51a899,8cd35976,a446eb01,f80267fe,8d76fa03,e5261cdb,ea5ed3d8) Z8(ed0d9006,53bd35ea,a1b25f55,eb7f07bf,27279ab8,141e8d48,f26e53ce,b269cecf) Z8(2d9e915f,40656769,9cce6ac0,5625f474,04e64543,5820f080,86b5d248,2e5edfb6) Z8(61f65a5f,ac9f5513,79f42a82,6975797d,9f6e957d,ded4c491,7bfbe355,f97e70ad) Z8(6f863f53,8800fc97,51f59c1f,bd28878b,89cc5d7d,dbab0a56,4b1984d2,09f80db1) Z8(1f883dc1,0b3d46e9,872e8984,4ad3a69f,373a68e7,d6b50da1,459d7ac2,095890c1) Z8(442f56a8,1adcfaef,1651fb1a,d45ad971,afaaff4b,12197fc7,1ba57aed,a3524e61) Z8(a4198bf0,7d3db354,44212e48,7159cdb2,a17fc867,31f022eb,5661293d,2a421338) Z8(3cdc6e62,e87e6536,a070a258,2297fad7,0e016e83,af2f6f63,ba7446f1,0bf7f2dd) Z8(b3877a34,97160bad,fa2941ce,f572f914,591f31df,d16b80a6,cda7976f,a07f0d07) Z8(bda873ea,cf3a8080,30ad3848,447e2bf7,fd49196c,d47a2501,70b5c814,9a4d1823) Z8(9e82fe20,361414fe,02066304,0fcce0af,8d6b4902,03094453,46b3182d,61589e9f) Z8(235abc9d,c74c1fa8,a6c3f3a1,d73716dc,e2a08c1c,9ff2144f,e08ae6cf,f3f58f7c) Z8(ae455170,27fdf08c,24558516,c50e5f2b,0717f3c2,1a2b38f6,5ad4fbc6,a3940673) Z8(20e8de09,1b61c760,3b4d1eee,78001b19,2a8be7ed,510f7742,7b8b5803,e7903810) Z8(9fba107e,edfa3fd8,b4be7d15,a3da86c1,dbfd475b,510d1080,63b7d0e5,feb60c00) Z8(f8296782,45c14f7c,c00b840c,e09309da,7de53638,25c2877c,c821276f,157bc44a) Z8(2a71998a,fc3b1847,0523fa57,99421581,0e5b18cf,6ea02556,c060b470,3d3d4a19) Z8(a419183b,925d4a44,4876aee9,f301dfbf,2c3131be,e79b40f6,2da99587,49d3649b) Z8(4f7fc5e9,52627c89,248c7cd3,993aec89,5ce85065,4a1d6e49,10ec31dd,223425fd) Z8(13c4e909,fe0bd666,cd79d96a,8a466cfc,9f2eceb5,b402cded,d8179f34,72568612) Z8(8d04ddd5,522bd50f,e7e30d20,b891c9dc,3b3f49f9,459439a2,2f162131,e0e1e1ee) Z8(ccf5dfb6,21be7d52,35ef4646,78feaedb,fed65311,88baf0b9,6d36bd02,32c38866) Z8(60015701,6099b702,de78aabf,37ef828f,a1fdd738,0ab71ba8,9b2a0d0e,144d9edf) Z8(9722b323,aabdf7fc,a409089c,5fc1e8e9,e75c29b6,81691afa,cef3ee5d,5aa3d1ac) Z8(a0ac04b0,70bb64b5,833ad974,d1ffff36,446df649,017d35d5,100f2292,074b4543) Z8(8a50537d,8fe292af,2f08ec23,50ca5e5d,430a4ece,548d0f97,b95d2fa7,a14842d1) Z8(0b92b930,29ca5049,0fe0156a,e1318900,825aa5b5,f8cfcba9,630aabf8,fcb5445c) Z8(9a0f5d31,1c166668,7304a96e,bb93c230,078c9f55,647bda23,3753e8ff,15eac029) Z8(56fc200b,cadee2ab,192f9045,01d9c811,f46c518c,ef046684,45bb2352,54e58c95) Z8(ecf53a43,dc827246,c1cc65cc,4e8e0570,32832176,4adcdad5,e3e3f9ea,53640b1e) Z8(bdbe5ebf,deee024c,61a4a506,ccce3cf3,7efdc1b2,87642e3c,60b1f57a,c4795e52) Z8(96270959,891c654c,769a88c3,a628bc72,a88bcda5,04b2a8d1,860965c4,80f42da2) Z8(e0b600fa,cdadb41d,779666c6,8cbe391d,9d9b8fa1,7a4d362b,c4b1161b,5fc1c961) Z8(a2be4ccf,eac2b0ec,7e6a5d0f,b8dd4fd6,ba13e23c,31a36bf7,1ba6eb6d,ffbddd7a) Z8(f937a44a,e3463f88,78e73179,0052e7bc,450af890,072ce84a,88311445,9089f9fc) Z8(30a4351d,c55167a1,fa3f8b05,4c3db965,41a834c6,9e3e5c31,ce8d2f34,6e386a9c) Z8(1edfe4e9,269143d2,7be878a3,8db83ef8,237b75cd,cfe22795,6a22392a,f69e73a5) Z8(697f008d,e28ee23b,872b9211,c27ba0fa,b55197f1,10eb8972,ad4232d8,32885c70) Z8(d17f3700,0a90c686,5c1b804e,fbb9e046,74d7e87e,290f5e65,ba0eda6e,7f0a3d59) Z8(7ae4105b,ca86b8ce,f063c526,47baea9a,56c14628,9004afd9,b5cceedc,acc468a0) Z8(e8859e70,ea85f38a,cbc0c2ab,09c952b6,c23e6e90,dc4f858c,d0725a90,f074d7f2) Z8(537de54e,203211a6,0b7b3a9f,4a3913b2,00a065ee,3159bd0d,efdd1af8,d9cee46e) Z8(d0924492,4587ad9e,380e9e6c,18b990ed,f8ffb310,fc189f47,35cbf567,ba71c4b4) Z8(2c36072d,fe431c71,5a84f66a,8a9fc2ad,f7245ffb,44397ed8,caea6bc4,332258b9) Z8(3475bcb5,2e9d7db2,91f2d154,98d33054,48eec31b,cc0f2498,60065a60,fdb7e599) Z8(252505f1,4b9419d2,267726fd,eaaba8b9,92e20407,230a017d,dd6e1094,6d4bb33b) Z8(6d25f3f8,5606638b,94625ffe,cdee81e6,3ed8a673,12c39322,95425aa1,15a06324) Z8(004bc64e,1caabb1e,7f862031,b0405a54,d823f33d,55f54469,22ac404c,73372e85) Z8(21ada446,76c8145a,f93bc046,04f6d1e8,bb9b3017,67bd1edd,9c1c7847,43a1fe4b) Z8(e129d1b3,2faf1bee,2690fdaf,97289b37,f9cb1502,e2d87860,a130278c,60bf06ce) Z8(946ce444,c2e9735e,c4cfe75f,a389b800,3550dc6f,4a7776d4,3fe59cb4,b245e477) Z8(e52b1e88,486135a9,0482f361,40af30ef,7eed607e,a268d3c8,7c4fb7c3,b42c6263) Z8(2890b4e3,6901b449,24bf0b0d,2dc907b5,8b467931,f2f3ee5e,8c168473,5e6e0401) Z8(45298fe4,63055caa,a800a985,bbe6a9cc,7e224591,693de78d,39f4435e,7d8ab12d) Z8(902f1948,589f4e80,50334198,467d34be,91273ee9,3255bd4d,9cd4114d,78592c7b) Z8(d80d90cd,eae86fce,ac80776b,ffa08395,d9177d6a,b2c656e6,93e895df,216aa2fc) Z8(0a71fbe1,d4894e72,ce4e95d4,cf210c4f,2dd10905,4ef42a95,17013ce3,71ae652d) Z8(9740d3e3,3984ca9c,8420cec2,d0846dcc,b9b9609c,f2ea3294,2eb63b2b,e835cd1a) Z8(5e2e6968,71eb5b2a,8359fe73,df5c400e,45c7600f,d26aa746,d95951c8,b60de064) Z8(9b5e950b,6816a569,b38a2548,2007c1b2,0744db44,cfd53cad,bcc8b67e,1dc872b8) Z8(329a75ea,f7eefdb1,8e423a2b,f7a839bb,f0cc5e25,262d0a06,eab9c1e3,91fb17ba) Z8(2624e455,01499524,7ebbf090,d2fde5ed,3772103e,eccee225,4c1aa2b5,bf35e5ae) Z8(9d79764e,eb63b668,00fef95f,b847830e,ab74e469,ca9d69c7,84d74fa0,5fd2f477) Z8(37b35679,292e2232,1f00301e,3f253087,65fb7d99,cd788a57,824124f2,7d394584) Z8(acbdd961,af0c6cd7,c3ec9390,00d9183c,5a5ab4a5,40910d03,4c92e776,55654be4) Z8(5b8ac629,1bd25f3a,f777cd08,6beaa63a,7ff31e60,7bc7190f,bac4b9ae,5b59c410) Z8(e933f4d8,6b10589a,aebbfcb2,2a26dd52,a80bfbee,8d2dfe75,a197e480,ac5f4325) Z8(2f77d094,614b8296,8720e1cf,52d9ba2a,0a28692e,a98f6c92,0a558011,f6970078) Z8(42f8985d,cb5c8e5f,fa25b4b9,76981dc5,09ec1968,99cd7685,c6f4e9fe,5f2b94cb) Z8(fbd45424,7785d99c,f451b5f0,a1a010da,af450832,c4be8de0,01808cf2,a726c840) Z8(dff355fb,d59ccb50,d04f1049,182f84bc,971aa007,2a45b755,09c7031e,08d2e8d4) Z8(302d6db2,33b2a5de,d3206c8c,66d50802,6438ae90,acd087ca,c1ae5a33,52d49063) Z8(6d58c886,5c4b1af8,37d42920,0bcffa4f,c9a38d35,e348f131,86817382,33035112) Z8(384c1f3d,dcdc8ccf,c27be72f,67ae9bc3,c125df63,e735a48d,ae78a68f,a29bbef4) Z8(b7e5c202,a738f7cc,047e1cce,1425e52c,9bbefe03,94fe561b,6858c9cb,2b441c21) Z8(5df5a5ef,abbf9405,59184987,d65f720a,ad9692c8,b51c30c1,4cb8df58,8c9a269d) Z8(c24ba012,7b7a81f4,851e68a5,dad107c7,fecb43b1,7545a94d,3b931cba,1e3ed9dd) Z8(e36059d2,81171dac,5ed41fee,87270128,2c5f774c,b1166acd,e59be72f,1f8e56ee) Z8(cadbeebb,473def00,8dd3c28b,86396afd,dfbd9572,514574eb,db35e58d,54ed0d7c) Z8(aa833546,8c20377f,0c198654,b90edb3e,752496d0,a2184e30,779f5218,68d2b4cc) Z8(970f3e0f,453f1e03,3912c6d7,00a9077e,1a89ab00,ac106d39,1b34860f,e615641a) Z8(9dcd1915,21a90ced,feaf2b07,55288761,4ba22bfe,a85898a6,f8b5ab7d,8a8cbfb3) Z8(73d7de7d,c9139ce1,a4a4568c,1fc94472,1e63c97f,7ff71897,4f108478,87744d44) Z8(96af44bb,24dbac03,3d32d32c,d2c1f8cb,1a52af24,0c12f106,22f691cf,0f75f59c) Z8(6f1fb081,796447b0,ca8df490,f50bbd12,14c1b011,29cf944c,69a12579,062a8b42) Z8(dc87d1bc,a98b61a3,9f106a31,ccabed31,cc169e62,2ef2bca2,a9d955e1,92aa615c) Z8(983071a0,254e41ea,3cfbd511,7a2376a3,c35cc304,97ca8e09,edc279df,ada9b5f8) Z8(212e09c2,4fe1fffa,37329e09,c922bb09,777e2b20,3b9d6f7b,5cdbcd5c,399ac4e2) Z8(28a11449,4b2abc04,dec77c9c,327a4c2f,c4433986,936cf8ff,4368facc,912205a0) Z8(c62b9aa0,6fe36cba,8d95a131,b91c77bf,3cb6e1be,44f40266,3ba8d1ac,f02dfd39) Z8(0f0120e4,d81a0c88,8553f90d,9d50211e,b823d383,b760e65d,e8e54c76,e0f8623e) Z8(c7292b07,b4fbd3e1,e263a4a1,d12c56e5,9ab6dd7d,f851849e,ec783cf1,f39028ea) Z8(0dc08f80,f55471e7,12345ed4,43d6b9a8,e19bb7b7,182fc7b2,ea57304a,ead2cd07) Z8(d0d28eb7,5418a47b,2d7018a8,28f84ca9,2b0d2cb2,7fbc56de,0ede895e,3673c026) Z8(d449e604,b14a1e0f,dd268913,148ce328,eecc2a06,0e0f108d,d19e3225,4f293537) Z8(c3854642,50a343c7,6c09a496,b0f87fb6,52ac41b2,8adbd078,9e62591d,d2dc182f) Z8(d1a8b83a,87584913,eb3e2e45,ed52b0f5,8423513c,cab4d7c5,ef8bb5ff,8416ea57) Z8(a31a83fe,533d09ea,f9151f2a,4411f9d6,185ef6fd,e379d081,3209d8f9,25d15d9d) Z8(361ebd29,d9c91e28,dba363c5,6ac42c5b,68bb1661,ede6d6af,9d3dc123,afd84c1c) Z8(d4073969,c6cde809,3f41b976,2362da44,7484fe9c,8d13743f,ec28d887,e595f56f) Z8(487699c9,fb51e77b,7024402d,552217db,9f87c739,2583dd22,6470a93a,03e76ba5) Z8(a5633400,a6bf3e2b,b2c41e96,4551d9fd,83a5dcdd,61b4b601,9ffda6b8,89a9151c) Z8(120f6c9a,f13d90a2,afa44ff7,4024c741,e82b0360,82cba50e,f191ea87,6bdbe5a6) Z8(827a8825,96612551,5b7e4f96,eebb1293,8516a779,b2480b9f,0ccc6e64,e003fb61) Z8(11c2cf70,4fb61526,0aad15b4,c94c9e22,142631d1,fc2920f1,3977d08c,cc29c284) Z8(f57fc2ef,17ae64f9,7d535ebe,c7d2b38d,4db51d2f,66d855f2,e5cafebf,ceda6897) Z8(596aa5e5,9c811035,d5b88dcd,093a81dd,7aef7c6a,8f59e1a9,1152c8ce,8c1a25db) Z8(89c0e6c8,099bf63e,e6f4ad85,dcbd9c2d,de75cfe0,973cd96c,47fc10f6,b0ccb277) Z8(b58cfede,a8898045,2dbbc8cb,ba4c622b,ef2b5cc6,d78f6230,fbbaaa3d,015469dc) Z8(077faa48,9b970acb,f6887929,5b6a9cd9,f997f12c,0ff06942,6c4835f7,502370b4) Z8(a4813b16,4921e2f1,63ce5c1c,f37d1f3e,8afee107,f394f1a7,cc80db27,fed10d8a) Z8(42eee6f3,5262a2c1,da7add1e,3b773f5c,91245759,0911374a,9248777c,42c9cf54) Z8(f34ef07e,7e40e99c,f665e7a4,49f4473a,b4dbcfa0,66228e0b,9e9172e4,d32a2cfe) Z8(0372f823,a55cb7d1,52163b9f,9784bc15,ad012aca,aee6469f,7dff4543,34b0f2aa) Z8(e6b62ce9,8ccb72b1,d27fd01f,80ccb899,796159b8,5b043ece,bc193b1e,329edb5a) Z8(f383e5f7,dff48934,9991c584,247f2246,07a4040b,bd7f8c04,ed22d4ff,d6486959) Z8(d3b7568d,167d24e9,302131a3,5b42ee46,610d6dbe,a4963165,81bb476e,783b547f) Z8(4ac8eeec,e3527284,de6ba45d,02cdda41,5096861f,270c8f42,33dbe816,5f60a4c1) Z8(a59eac91,c80b6210,e10d359a,a745eac2,dc2e5483,30976893,1114ad60,155f1f88) Z8(ebbf9626,bc1380d4,a7960c02,93fe4334,4a0b7ab1,bca3e797,ee5cd8f4,911e2495) Z8(645cceed,e98a7a43,93f8690c,ba68cfe7,dd7fec63,21c59b02,b870e1c9,b8c4e7ff) Z8(8f7f74e1,577ef3db,27b1fee4,e7bdc4b1,a441575a,0e88c8a4,2406b198,f068db07) Z8(089bcb78,72b98143,e3875039,83a27f97,7315386b,43714d47,98f17b4a,9c0b5877) Z8(3ed55abf,c2a48fbb,d7c12e90,70cc9e36,8a8a24d7,eb006d9b,69209c2a,ea78348e) Z8(d36c2ce5,32fba94b,91aec466,57019f2b,021aa0ae,4c80cddc,d8826194,9fb39eaf) Z8(deae7597,84f068a6,115eb61c,695ab745,5fc75809,2f2d0d03,89188f16,63e25e12) Z8(c6ef5eea,5c51b54e,aa9402f5,5f8fd9f4,62b9569f,6f37db93,4a933d16,4c1cabd4) Z8(f52a2313,ada7860e,05a4a3bc,ee40dad8,cc7f1b9d,1d0fc3f4,0fe4b316,f4b72a65) Z8(4805a40e,815e5ca1,fdecccd5,94ea7ca1,dd26b406,f8553b1e,2ca595ab,00ad6c5d) Z8(ef79bd4e,61962ee7,6310bab8,33e5eb52,5a411cc4,2867c3aa,6f2b9623,45607157) Z8(71d98fea,a8f88bcc,14b2e044,44dfaa9a,a3a50c65,a7dfc2f9,7d507294,e76030bd) Z8(65a7a5d9,2f672e09,9af670e2,8a7fd704,d11aad45,a1a33f47,ef4e1042,82b077fd) Z8(27e385e7,0d1e0f39,7159793e,6e0ff553,1c134a40,d9655f1d,115d9a4d,e2e8bafa) Z8(b4765a54,fb1928e7,55a2e4c8,9ab73f47,04f23425,347115b8,a1b3eb19,ee618e02) Z8(fca6a07f,b0d36ab2,69085f56,d75f9988,c1b2696e,c602f5dd,5b76c47c,513597f8) Z8(7d93875d,bc0a0c71,9c0c8328,3a0163f5,ca042a30,12a37dda,7dd90c25,237db5f7) Z8(d4db5c6d,9680a2f1,878af916,f1e667ab,6bbb9463,20ead69e,829dad3d,b6ebe349) Z8(8cd4a9b9,f66bf830,1e5f55df,7732b2ce,0def00dc,022e50a9,499c9396,c249f347) Z8(818e9e74,7280dc98,b3f1a316,02adbd23,a8f24d54,1ec9016f,60c04893,ce90f461) Z8(e02839e9,6f973e40,6915cefd,a2f59c8a,6fcb5a2a,de0cc00e,e0ef1efa,e8d5cca2) Z8(b3660d7a,e4e0886e,2e83b25d,4e1edfb2,fa4f8c07,b1f19022,74bd0f2d,1325ace4) Z8(4dc4a27f,9307f63b,00f912f6,6f6d706d,e6754124,bd0544b0,b3bed437,ee3a10df) Z8(4381adba,d77f699a,5ee38403,c7dc0ccc,0877983a,8e8f32a7,952a54ec,758d8cc1) Z8(d644dde7,0b928c7f,b6f632e2,23692d91,64f7c493,3154d592,b3760ace,91b53d27) Z8(a9ca3fb6,439b4fcb,5d6e2a8b,09a88b6d,842dcab7,4610b47f,2a1c8c74,25033928) Z8(eb246d71,4e583caf,2eab27ef,44e42d5f,7a682327,51b2474a,302d30e8,ba227812) Z8(59871702,e35c2c61,7850195f,c62f1c79,20a416bf,190b35fb,9c222bd0,12564858) Z8(de179755,b1f3a6de,6e9dd3d6,947dd974,e245cba3,d4cb06b4,455a7ce6,4e21b866) Z8(77596f5f,2cc3914b,6f6dad90,4e551d4e,4bc3f82a,d228bcfc,18af315a,31d86de5) Z8(edc8b061,3bcdac29,59a1f802,8ea4a61c,4693179f,00357787,cca11095,c14823d7) Z8(f41057f0,5e51bc2f,129aab8f,d6186ecc,f54fa91a,326213b1,4d713b3e,bdac8396) Z8(f4298b3d,91e17b05,a7b00ed2,f1f222ef,348164c8,8fb0c1d3,4adfa2b3,e559f20c) Z8(c002b683,9c1c67c1,288290ef,446d3119,999cf3f2,acdaa2f3,b6b78734,ceff2b44) Z8(d84e83eb,1086ebde,577ba0b1,6a1a57ae,bfe2af66,53dcc011,df6bd592,740fa243) Z8(f25ed5bd,78e0c43b,4a05f02e,fcc14a01,e53ac818,923c9416,6b960094,9afdf883) Z8(ddcf31c2,2b2bc78b,4f42591c,53de09f8,e4079dda,21e9f481,bd9824f8,3bbf8022) Z8(06eb10ae,2b550288,720c74ec,83155412,a368c101,badb327b,dbb12b2d,a8b4f746) Z8(4dcb1f3d,116edfce,58e03cd0,a5d97b31,b0b7e538,d2c503d6,a0fb21dd,e3f043b0) Z8(0c21b10a,a99fb1dc,410d2a0a,00de55d2,8c4c158d,bf95dc52,6cefca7e,c5bfc544) Z8(d7dc4746,c6280cd1,9815f155,6f0e955e,770363d8,3658d1c7,05800221,07646e9c) Z8(e25a7a30,14d6acf1,3384fe68,89dc571a,a4ec8a69,9efa5958,dc5a7afc,7492660a) Z8(ff027ff9,66d61a5d,7f2b759e,bfb972e4,87a6e499,280aa457,e706b930,b619d4ec) Z8(458375be,2b5ae464,57573aff,5569dad0,fbb56450,4354320b,ee262d89,c50e16ca) Z8(47c41c74,5ce82396,51d822ba,a1cc5392,4742d2c3,beb2aa08,08bc6714,60234a5e) Z8(b01525c2,13534f10,d189bc14,1dce156b,1333611a,1b1e5481,6d863398,f531ae63) Z8(282d64fa,1df0bd60,acf83117,0238eb08,5f8c9eda,f5a177b7,cb8e0472,e63d3aee) Z8(7aac2e97,5f68fbc4,88a3329d,ca667aad,95b4daca,98fa3442,ab7f451b,a5e940b3) Z8(02feb3b1,c6030a80,93861b12,b1828330,b872a1c1,5162708a,cfb96575,8aa5d126) Z8(838acc46,817edbdd,eb9ed434,03a45348,f34196c0,43f366ae,e2e7e5ce,9b7744db) Z8(b5634f95,f962e5da,01712cc5,c4dc847f,9122f2b2,20daf9e1,581fe125,2a392e17) Z8(ba918552,4c096b6d,80127883,f3bb951d,d7949d18,16d0a422,a21e02c9,4d3a6ea8) Z8(4e88a691,2c8c7e90,747e2301,905e00a9,e0af05f1,ece13dc1,9b3590dd,5ae87fe0) Z8(0c6dc234,7ae10092,db9426fb,e828b048,48ed2c69,10d42061,d947e226,df786115) Z8(91578803,23acbacd,e27358fd,6f27fcca,74eb2784,ac4f9ba9,f4c89c13,249f75b6) Z8(d8127e82,a90c225e,e0570aff,34d1a0d4,284b7de8,299458f3,8d4b1eca,62c9ea50) Z8(4c500623,e46415ed,f9cd7c0b,6089563f,11b99c80,390e458c,4c388e73,2e950f92) Z8(04173472,c73e2d58,6802e5c4,fb3049ff,18a114a2,77e75608,ace26965,f02e2b7d) Z8(d6159234,85a9476b,c6aa7a91,3ded029d,4591db06,30fd9780,54210710,64748add) Z8(1fc4bda8,1a1cda87,4b82afdf,c958eabf,dac1677b,74b61381,0f16409a,a90c8577) Z8(1073eab6,bd37ebfa,80d81997,9177e89c,625b2ecb,54a72659,7929b88e,f171744f) Z8(73aca178,ea82131a,20afecde,01f42622,f27f9600,6ed74010,e0dcab4b,4be44e6c) Z8(cdbe3f20,1b7135d5,1c31c059,9d767d18,0f6e67fa,55aea6a1,dad76e16,c6bd2855) Z8(c4197a43,6621b3ed,8863448f,e3cca24a,d49f8f0c,082ff617,3a10912a,dcb4f3cd) Z8(24806456,62cae4d1,78892a49,ee3dc019,de814369,041f69ab,2e80faf7,e0e842db) Z8(eba137dc,adb093ec,90637f71,172a016b,1f0b4a69,f2040651,17220e64,7b67cc71) Z8(c36405b2,2f3f5160,2a719f9a,218b5198,c76a52d0,c9d9503d,c9e780ce,64d26aff) Z8(598799e1,2af6c81e,b0765d26,31d363b1,2c569cf2,cce37369,0d4bc042,bc714aee) Z8(a944f5a5,d02032ed,ee9d2408,de3717b4,3e6b2c39,0ea7ae92,26911948,321bb972) Z8(9bc04c2b,3be1dfd9,c0c6c045,90867aea,aac7d5b3,0a2e31b5,927d6420,58ee5ac4) Z8(cdd3a1a3,6d25d409,afc4d313,6efb0d52,d28447f8,2bf06b80,9126fb1d,bf5211c0) Z8(763f7dcf,fb510a49,55187d8f,0d9ca41e,05a990f0,01f3e80f,921e0622,ff281864) Z8(d6886516,84cfe4e9,1519687a,82120bc8,6e4bb175,b9dc5207,52b71dad,11b34067) Z8(b85d01e2,48849857,1991ba48,e7fdc522,a7ba1508,423c8397,13df8e03,bca6ca97) Z8(638a0e5b,1f84187b,cc54246d,d3f1e316,49acffac,17f36543,b3824494,6ffe58e8) Z8(e054159b,0d82366b,81091d86,eee46e3b,decf45f9,eacbe2be,a171ea79,04c47015) Z8(ea8a6a21,c2ca6dab,8d9e3d2c,9b3aa5b6,170f2970,dd240403,1a02e414,5e37913c) Z8(3741a61f,539eaa35,a8f236bf,7483c07e,df48c549,eaeafa55,28c26268,066d6e05) Z8(21f637ee,f2e8646c,9e1988a8,c4c43552,760286e4,5a4e021d,291a0969,792d9edb) Z8(89e35fd0,7420a26f,3c87e052,6c7d6b4e,c91c2ccd,733570c0,fa8a11c2,cfbb5d3c) Z8(ee80ed49,4d4d6d55,559151a2,a09b3c0a,57861192,69f5b45b,25470e04,210c9ca8) Z8(0da83c13,22e519fb,8e6b6b85,908a815a,4a9bffd8,de9bca61,f5e77c44,4eaafde1) Z8(c10aaba3,63b3288a,c6d1b459,b7202ac2,f95a37c5,549a525d,3195a948,60781ec9) Z8(49a98401,4ec37817,b6282889,837b3c3f,aa6b8475,82face54,9266bdd8,12ed5756) Z8(91f5be6e,6692af4c,bdb3839c,6213844e,8dccf1af,10bde956,777969db,969aebeb) Z8(d4e65fc5,77012615,06141239,e9574068,6ef42d78,c048751c,4b06cf6c,e2b6e620) Z8(93d9996b,2584a3cd,e7ed1fe4,c921f028,f9927f2d,83dda375,c840b2cb,6eab9fa6) Z8(aa21c65c,243e24c0,7319958e,4129446e,e3c501d4,5598b8c2,16223348,dbe5f40f) Z8(4d21417e,6c6864c6,f2b6a52a,82e2d9a9,f5bd8489,35dda92d,cbc8b330,b02633db) Z8(7c4b0087,dd761818,b578f14d,48457f58,167a69fb,604cc802,faf4ad61,8eb492c8) Z8(b3980e69,c1d30cc0,9c5c57eb,a6c53f4a,93b15700,41083d2b,8362dd01,80812390) Z8(a802d4b3,ab59dd6f,19b34b2d,5f0816d2,21fac244,6a1d9147,59799cb5,d376e23e) Z8(7b7d6aa6,60a30290,996dabc4,b0973b3e,98462f7f,99c55ee2,46501792,3b157524) Z8(eb167257,ecaa9d21,124ed480,a6d279ce,9c8cc900,d3d6545f,33b680d2,d8a44ac3) Z8(40c80840,3270655d,20bd685d,13b27c6f,00240faf,a536e81a,c929f61f,b080e63e) Z8(57e29ba5,48fb66ed,adf10907,c4227486,f8d8dc6e,ad4e8b19,c632116c,1b9bb59d) Z8(b37fbfa5,d36d6aac,92621107,ec4673ca,b2874554,a70c08f3,f0b719d9,8e0ec924) Z8(b5431b88,f89c4da2,a58be887,e748b2f5,afbe8329,c048cb5f,9c74baf1,5193a884) Z8(9231fed8,aa703019,690ac817,ac8038c9,f55ca27c,9a864ab2,b9951a6c,3397b4bb) Z8(5e2b7652,1443e0a6,f5c9e2f8,664876a4,254ee773,7a50ae65,90ed25c4,871771f7) Z8(03581bf6,02cf4380,67df8c6a,61d69624,519348c5,9812638e,1c1c4933,852459d3) Z8(c1dc9c03,870bd45e,22151c0b,662c4319,a503b0e3,a548b27e,15fa63f9,c0de97ae) Z8(498cc5e5,c5a3ca08,2399fd86,78d984a8,f39a69f4,2540f65d,86bf76a5,abe312dc) Z8(bf6d2bf4,fd61e0c4,40d5d651,8844f642,7e665574,57c99b20,fa6724d2,61714ba7) Z8(cac0cb89,fbd409aa,c45383cb,98426a99,44e1fc34,fd9039f3,b77e43de,301ce849) Z8(eb4ac384,a2ceafef,a7f55c09,f0b4267c,3cdaf3d1,db4d86f4,8efb09ef,82425308) Z8(99f52a54,6c7800e9,bd93e541,d661716c,0c75a4e9,a2891880,c4068131,b3c1f3c0) Z8(68a6c170,b3e53de0,c390f4eb,f5e16314,902f70ef,752585f4,690fec29,478e3fc0) Z8(62f350b0,ac35764d,a41d5cc8,2f078216,afe90ebc,cd9872e1,05a0da38,3db395b1) Z8(5e67830c,72b2f769,394b5447,62576bcc,b43ed7b3,316ae1ee,029f7935,bfaadf64) Z8(42c18850,a4c5e037,bddc57f7,1268a3ce,4bfcebf3,5fe8f7c6,5ee44d60,7073799d) Z8(50efd314,68eaef9a,c8ac9a77,83ba748f,352ecdca,ebd7c8f4,b8dea895,f252e857) Z8(b34c021f,deb81f16,477c0566,15d42868,b4bebba7,75b4c708,f63498c8,900ee68d) Z8(b0eb3215,57bbc454,ec89130a,f642e276,f7a227a8,9071658b,65191273,45a56f51) Z8(7c385094,5da84294,54ec305a,83140684,1c181b3a,2d972f2e,606065d2,f4637f3c) Z8(7b98c53b,d2b7ab67,33d5828a,a6041d35,c3ce9db8,bed5fc88,b671fbbc,78e22b13) Z8(283d3cf0,91da0825,b426a39c,e25fff4b,f1f75b02,8b0af774,603c62c1,af5e4891) Z8(0a7426b6,c7efda07,90cba861,70bfe178,a92101d6,93246e8a,8067262c,32682a3b) Z8(0a93e5f8,7373a7ce,e358c61d,a50f8176,632666e8,754c3f3f,dba5bce6,dee14462) Z8(7fbc33a9,42ef3bf5,bd64c87d,71e60d29,844f83c4,d0811ee5,5e1dbe8a,ad8b61b0) Z8(f59bae48,361cd11a,edb05d23,f7a3b022,f48e34dc,c76709a9,ca7b52bd,271958cd) Z8(70c63729,2f37fb49,64e1bd8e,d869694a,91deb019,96d1c10c,a1707a54,d4ad4fbf) Z8(f6f2b750,5357d69b,82e7e2d8,3442e607,bbdf799c,bba6f132,c9b663ef,8ee7741b) Z8(0dae9669,bdbafe26,6d64f8cd,c0699738,d36e21c7,ab5a4229,e031650a,4328c097) Z8(40e12adb,33c9083b,15c637f2,fb1d55b4,78b29e7f,3620d3af,c5551851,6247672d) Z8(31ae45b2,0460a394,2d5bcf1b,df7fb530,29b5331e,8da9d5ea,49108ac7,c768fdc5) Z8(29e96951,79e2ba64,117cc8cf,6c425121,f0f92276,342ad01c,8d48165c,911dc595) Z8(8df98409,d6a52336,3d9993f3,6e5fdf0f,2afe2d24,db1a3a03,967e948d,cb5b7bb4) Z8(6712196d,d8e55925,5700106b,b48933d0,b3f30994,82be857e,448d4bae,2c221575) Z8(99732e16,778b7144,35781de7,ebb4fb4c,0dfda43b,d513705e,2b5cff17,5aad6143) Z8(2ada5451,5326b4df,880bd8b0,aecc7e57,0a33d493,23f7dfda,965cfae8,849d1b37) Z8(3729806a,984d34d3,e3d70392,f583b568,1ec0504f,c07bede5,ccefa5f1,af1c5a79) Z8(07ec437e,f80ac44d,31486a57,16bbd11e,991d6261,53d573eb,26034167,2e7552ca) Z8(84a3c513,4f225e79,a8b8762c,9e192c65,80f50a59,b5183f00,0fe25f80,647bbf81) Z8(bf4ec959,eab58902,e182769c,dc75485e,7f199aed,0ceae762,f85d24e9,fdd1eb1f) Z8(09da53ce,16ed0ef5,fcf05a3c,ffcd6dc9,61a43052,7cdefdc9,0fae5c01,ebc6a72c) Z8(77c6baa8,aa27aaaa,5e1cf611,d616fcbe,b0b75c31,7d137898,e796bd48,96709a86) Z8(6ac7c376,7580eb8f,62692305,dbefd5a5,2f2ccb9b,227e074c,c1e8799f,f1f89319) Z8(7c445fc2,0c0c9503,de22647c,b6a7c562,e4655378,83fd6f63,3ee05215,65eb351e) Z8(b6a0e14d,2c79f4d9,fd70c9c0,731c4035,73d93905,add31e7e,8b9d36cf,5c260fce) Z8(b21b946f,1d954786,b47f0fc6,872dc0ec,d21c1ec1,2dac4024,ca290704,9a0e4720) Z8(3b6ed4e1,f51609a0,826396b0,59768aa0,5d4bb825,b74d9cd0,a3df4518,1b8970a7) Z8(d706a536,91fac86b,bb96fe5b,27de0b49,e3620825,a704a2f7,c05ab78a,25c288d9) Z8(6b1b506f,f7f20f4f,730fab5d,7c7017fd,180944c0,146b6fbd,17d28e37,d89de4be) Z8(91a8303a,5d8d7a59,9a23fcb2,77560230,986c636a,e00ca4b3,485ebe46,ac1c379d) Z8(07655f55,3e942dd3,b61e83e3,ada2a402,a024e51c,bafadf77,74c9ba10,de4eb10d) Z8(5cd05ac7,037100f0,70b26008,bbe6a0df,6952dc9d,8c7bac2a,6248cfdf,c880af9d) Z8(26d83d46,767010a1,643c7761,4373da67,3bc17e18,1df94c39,845bd8ef,8d01737e) Z8(f69075b0,6900a2e7,3d081cae,6a4f35ef,3ff32b3c,ddb489d6,88dc1b54,38695a9f) Z8(caeaa56d,6d871f96,34e9533f,e0bf44e0,2be6404b,74b0a43e,920cbef5,13a0a17d) Z8(cfaa2eea,d3871d7b,11ef480d,71b15235,39e92155,a0ab650b,9e56a634,7889c39f) Z8(c9ec632f,845829f9,e7d84c51,a34c0289,4cf8fa8b,55d6abd8,2b5c6bdd,b5bf38dd) Z8(63bb692d,e50ee670,e7d2582a,c777166e,02c5a991,463cd25d,236bd53f,60e1c3eb) Z8(a15c0a28,7e946d03,5de791c4,9035d106,5ea14e63,ef2ca089,99be94b5,a3c4ab93) Z8(8f9dbedf,41c71a96,2d55fadd,be537710,45221e9a,0a2bc360,0e04ee43,405d3ea3) Z8(b877a52b,b0189e44,d45a6438,4eae6589,8b5d3bff,29fc0c93,01c118a5,83800acf) Z8(35606288,bca125a1,da5bb135,a64c41ec,11ded766,709f9c89,51ac274e,a46ee066) Z8(8474b974,d662143b,4a351392,4c2418f4,667d80a7,4eb52964,04f4db26,68f590eb) Z8(b4ceca28,c7c7848f,e9663497,ffd95ad8,706842a6,84806806,6d96a5f2,686c5d1f) Z8(4c0119e0,10c1ab5e,bee871ce,0522acaf,9766c7d3,83dcc657,fc825b2a,6b593a37) Z8(f850669b,a8547a21,cbf76243,1f762b7e,3cbe5e81,9002dfcf,e15ad706,47baf7bc) Z8(44f26786,be18c6c0,a522253a,ea770e13,70ba5da1,420621a0,d7bc5482,bc98ec4b) Z8(a8682f02,e4175e4b,84a3bd78,1efc97a9,5cc0b1e7,03c0eb8c,643a53c1,dde8cba7) Z8(ec90fe1f,ed13db49,f9150018,86bb4206,e34ec2bf,b87ab0b0,88e70c9a,17924c2d) Z8(8c1c0914,5c216363,2131bc56,4bb37772,c911900a,ed0b86e5,61b6e9ac,503427a6) Z8(c023977f,e36586b6,58e604c4,e519d00e,2c2e9173,b7ab3297,166daf88,3fd2016c) Z8(488e7f31,256e3589,53a709c9,ced0968e,513e88b0,a7736131,04c5abad,d17cc56c) Z8(fbde2ed8,d7741a8d,1d8d15b4,fab3bf12,4d70eced,0fe52688,07954675,54469cc1) Z8(9485d7b2,55011a98,23a73ff3,533f93f0,43479913,9fce50f0,47e1f021,9a0e857a) Z8(ae8df869,5ab2b9b9,9823fddc,9a2f572f,48ba35d0,057479b2,42320587,cba3f3b0) Z8(0facf23d,fa37503f,77482d56,ba32e641,6da46cc1,9c14ba6a,8f86a00e,3f84e5ab) Z8(ded064d5,f0ddd50b,7a241d2a,5085f2de,fb93bb52,c873327e,5dec77f6,f601c313) Z8(b2b60b1d,01c72eab,ec340c47,98646846,e1c35ce8,9e45c238,8d8603bb,f721ae82) Z8(fb0f027a,2d4caecc,5b425923,2c1c12fc,640ffcd1,8c200e56,dbd07c5f,352098b2) Z8(6b936d54,b906f112,df134594,e4c0f392,86809efe,5ac3b0a0,855cbaa5,853a5140) Z8(211898e1,0cc39049,945a1c35,4c7859d8,4e95b15a,469ef0ec,87fee11b,51190117) Z8(f87a0e1e,f9352ba3,980ce5da,dba5dcab,8e49144d,5e303f5d,913168a5,02c6a60b) Z8(f4ea90b4,e3bfe056,851e37f7,3ff3c912,a5713bff,780d5f2f,d6aac49c,9c7e937b) Z8(25ee3844,44668c37,a72e7bab,3172ef7c,635c5b2e,1ef3e92f,675b40c8,68474056) Z8(9f1bc7d9,b1d01204,3bc5dbee,495a0723,7b30e7da,835202b7,9f6e5aaf,09256f67) Z8(3d85d7f4,cdc58d9b,cea0a492,9c3383a0,f58d2dce,cda6e53f,859a09d4,947a7151) Z8(fa1701f5,0d99e0db,46ca02fe,3485022e,ea449c59,78b823a6,8ece1cc1,2c721fb7) Z8(20e0e43e,d836eb66,a7c5b664,4111c4a0,54fb9328,4d744a2e,4c501b58,09fae7d6) Z8(daadb7d6,99aec8fc,8a9aed94,03f5e700,1e6a27c8,61a62f67,51c484e4,3098c23b) Z8(15147b25,d5e60240,2392d788,95274a3f,1f4c926f,a1c098d4,b7f69210,1273d404) Z8(f6dffa60,f395889b,72e64560,b5f46e5d,e2adfcae,5224ffc0,d35c1461,61f8c43c) Z8(aec66f93,dba92d84,8aa34369,b0eeddf1,66079fb8,3535e47f,0dce4be7,1ef182bf) Z8(95628ba7,789c4deb,ab9b555a,923347a6,5d52d629,32b4158c,98ebf57f,1b71eefb) Z8(05360d08,6910ae6c,bf1f09d3,d150787c,db8a8010,d789236c,433d31a6,63f7a06b) Z8(b78b6e03,2526ea61,e17fd6ab,d014ee12,04f5efd3,ff8b824b,173785eb,d92d90a8) Z8(cc9006b2,e27b1e7e,9e04ffa7,d6d12bb7,c501f11a,0ca69669,cf2ec8e5,d38b3a2b) Z8(ea45b79e,7f3567b2,d690c192,036a0319,2f121388,eb303b60,3186aa37,7c3c07e0) Z8(59aac509,06ef44dc,780f9fff,705aec31,83deebdd,8215fe90,5f0fcfbc,fbbee3e6) Z8(7075e7bc,9f293d02,cc7b6616,6c7effe8,23b3a2d4,8b05b489,e0551900,45711c36) Z8(52657d31,2921529b,4061a98d,172ca8b1,a70e38c8,a4ee29c9,1c508f9c,099a637c) Z8(552eea92,23736bd7,70cdd748,483caa27,f83c5cfa,df1cbbd2,03dfc2f5,df416163) Z8(6aa3317d,1b1091e1,b0b74acd,2ff17614,b0107c7e,f1ff3509,c4e44248,8fff3e01) Z8(eb5b9c24,306863e4,c513ed76,80780e60,ba4b021c,99dcbb9e,85481133,756cdaa7) Z8(e199bfec,aa94686d,738df1b1,8982340f,3b9fe348,ae4e89c4,8ab5b380,51424ba5) Z8(27f5fb41,f8400a7e,7dae8d1f,ce15b1cf,ae63263d,37205eed,2a21c0a4,2062faf6) Z8(54c5d794,d56cdbf7,b816a33d,30a39df3,eabeba2e,014fd3ea,027adf75,3598e432) Z8(723a3402,05f40424,34aaee33,f1521d13,465f307b,8ad12e9d,00812d58,86b1d868) Z8(a8df91ff,aa69b71b,1d0f3b9c,040d9f84,4bc4e4bc,9fde3cd1,afca6b96,4fdf8d5b) Z8(9f675987,7be45842,6a221300,2474bce1,b65ac2cc,8c8d6af9,9451352b,41848923) Z8(63c453fb,86f0daa2,810a5fde,5718bbba,de15705a,3a4940d2,00b915c8,69d640fa) Z8(5f219d4f,0c9d09e9,e653eeff,c467857d,05dfc0ca,55d70d7a,bcba47d9,37424277) Z8(ca6f34fa,6660b20d,88eca315,63aa0f44,be7abcec,dec5aced,de2e5c71,69a4a518) Z8(c660cb58,5a987594,8174b843,2c1516bb,82effd12,f607e461,1ca4c82c,724cc197) Z8(3398fe3c,519832ea,9c9d3ada,d3f4187e,339581d2,5d0da467,fe4e7660,784e6f4c) Z8(3c3b86a9,d996675c,804a1e1c,4473f52c,500f9cdf,2173dff5,e521e64c,fde2d994) Z8(b4c1a3d4,2d6fa9f3,598fc138,2ecee9b4,ba9c02e0,7ef144b5,9724c306,b0849f10) Z8(897fee1c,9d6107c1,4b31ccc6,ddde0df9,5a9d16f4,e2171f48,73853e35,f660373e) Z8(1d44396d,e70d716a,7c19dadd,12f7c6f0,6191a4b4,95bc60f0,f943782b,a8845013) Z8(b8e8d5bc,9c3325e3,4491f9ba,4801ea0f,28438d7f,d014610d,262692b6,c7e665f0) Z8(ee35a67b,10b1f430,848dd30a,d98206d7,8897599e,b06d0fa1,ef517827,33f2a7ac) Z8(6ba729e7,149fa756,7b9702ed,87aadadf,0e77345e,935215a0,9f05988e,2043bdc6) Z8(c806e8bb,6f437fa3,6deef38c,74204d73,d9082530,13ede77f,f55c8491,c381b245) Z8(833db8b2,e6d96795,5b0b3de9,4f01f512,27c8a13d,14d1ecd0,3a62aca3,5d187f68) Z8(713f7803,516b84c8,f8a71cb4,cdba8200,fafd0296,63f4b07b,eef717c5,aebedf35) Z8(73ff1fd2,d1aa2ed9,d80632a6,548dfa2e,585392f0,15526d7a,8a7bf48c,bff779df) Z8(93c4f36d,ca4613ec,1bd715a9,2b049478,95cd574b,2d2b4d3c,3ff5bf1d,9fbca906) Z8(fc3eb04c,35b3ad69,7ac041e4,f278382a,a007b67e,2e75b1b7,a97a7c21,926a7756) Z8(a31c5f13,9ab67b19,49b56141,ff9e8eea,a6e07319,eb593a7c,ec98dc4f,048aa839) Z8(c327dd96,76aecc17,5b9995b8,553a14ba,dd0bdc5a,2cb842a1,457514da,861c10c7) Z8(8f27f228,94b928cf,2db0c3ce,a9e3a3db,405095b0,bfc97b11,93804076,ee527e80) Z8(f46f3bf3,a6c1e533,780dd1cd,c80ebfb5,1e931831,d8950f9b,0ac54143,086c6eac) Z8(796f455c,0a747811,9224ee9f,da0c1f19,e44b74e7,b2e402ed,1940f44f,facb5e92) Z8(c23ad237,eccd8820,62f574a7,71d4acf6,d4da1c79,57e3255d,cee58e03,2dae03e7) Z8(d7d96e6a,aa9adf9d,76a0705f,52588469,34f73d10,8f7a0b32,26ee3d0f,6f69054a) Z8(ff96dd80,73765017,2f5db950,15b94207,51992dac,150f4a80,890e364c,2602c1c7) Z8(3ca8aa5e,d34c1874,c88bf95c,695fa64d,7aa65d95,95f0c6ab,5b9814b9,09a57db1) Z8(73cf0b40,c6276eef,70e1cd2a,8dd4e1eb,11d7b9a7,d751647a,194e9e9b,a55fea33) Z8(44d47153,1986a783,4307b677,18a40419,f97fce3b,502bcb8c,13a60c28,a677fda6) Z8(85fb9169,0bb6b95e,60a84616,362bdc6d,76f9feba,5bcc1bca,c3f4bdcd,7fdd0965) Z8(11cc9e18,13736553,94d6894a,320736c3,ede2cd3a,c228cead,192b162d,08cd877c) Z8(90a27140,94c5dbfc,b1c26bda,51203d97,dc4febf2,d04aba14,e0fba55a,e50d16d2) Z8(d8023014,bf41b530,a9be9dd6,419011ec,0c83798a,102396bb,d88ffb36,67726d06) Z8(18641189,d2bc0474,21f43e11,df55308a,a36d8014,8297b890,19c8f022,727e6d92) Z8(e4996f55,234936f1,6ff67e91,d39e5f19,972c19a2,0b42a858,4ec3bae0,a17cf588) Z8(8d8b78b0,c2b5bd43,b856693f,ed06c860,34780844,a30b90de,62a42989,704132aa) Z8(b3ce16ed,27e73a5a,8585a35b,87e3708f,ad121fec,55b20037,b604a263,259f4047) Z8(06ac38f9,b820034a,632061b1,b88be18e,7f2cee33,57229cdb,b5019331,4bd7538a) Z8(bc27a55d,8e8514bb,dc77724a,56715033,4dd5397f,d409fe8e,d8bdef96,ac85cb1a) Z8(cb8fc303,bf77a843,c3b4c4b7,1ae2d720,2faaabfe,3b7067f6,7ef99afe,4f3e8030) Z8(46ccf7e3,aeec0509,cf8baf83,7d2597f2,70d9f2e1,db1353e2,5e6733fd,2fe78312) Z8(93ce65e9,793a8d90,f1298529,f6242b2c,0ba837c8,ebaa3e12,6aa6c644,7e1443f1) Z8(dd517ec9,3e024e29,2bd18962,cad4559f,1e8d3817,09796bd8,23d51871,48cb7d68) Z8(a622d97f,67fe417a,94a50672,950359da,1cb626ad,9e4c8de1,7eff37e9,9c681069) Z8(db1984c4,ad2514bf,7363472e,8bd8c6c0,908b6363,e57dd0c2,08b595da,7d8fc0d0) Z8(a503c2a7,1c142e77,b9b94292,f7775e01,b40b96b3,89fded05,716ae7d5,a742ec57) Z8(523a5778,7a919807,826b0d41,66988720,9d899303,d4fb9ff8,01eb5b13,b28bdd05) Z8(92e97d24,78876130,ea8a0e85,34b23e63,c95831c7,c96bbe3e,088045f9,91f0d6e0) Z8(03a60daa,8cd87055,88a17c85,86e039e5,45244be6,1449c148,6468ca1f,2e1b644f) Z8(5d149c41,ec818db2,baf80acf,31fdf71c,588cd0b2,adbb91b9,af7e142e,731a03f3) Z8(fcf9752f,9fe6bfad,ca1c27ce,29952e4a,02c4a8b0,3c04426c,b8a374ba,ff5fa05e) Z8(0149fefb,85d7f013,783d66c4,eb0ea813,b2ccd02c,06f86b2c,bf50c08b,c369bd15) Z8(9e716dc2,70efa3bc,9044df44,ec3b31d9,93cb1f31,d4415349,eb3cf709,78cc8312) Z8(c7aecd42,95099fd9,12061e8b,92cd2be2,262f7005,60dc688d,2ce2137c,f59855b8) Z8(298f3efe,deca130d,7a98aa3c,db472f13,82b9303a,538c7f25,9658fdfe,2c2f5220) Z8(6e4de714,f49f59df,66c2e39e,08657916,2cc5a683,9bbcc584,5a75578d,34d67990) Z8(11ba4345,bde6477b,7a9029d1,94bf27bb,a3eb85da,dce22e5b,0cb4281d,7a6d9c2d) Z8(533568f3,39dbbb76,540ba85f,c1bf724c,7724b309,d8d52798,fb6fb72b,a3e2add7) Z8(7f096aec,80f85e7a,f44ebbe5,1dc19fd8,01a09689,1baa69ad,022a62db,2efe661a) Z8(c0e41ff2,9b4c8d57,35421eb4,6797c3af,90ee1d41,a1a63c6e,92b2c7f5,91d9d5cb) Z8(9ca89190,20745a2d,9c611a36,6a172900,baf817db,45107e78,d1799204,62e40b12) Z8(d520489e,a5e5d628,54fd3c70,691a0982,c135adc5,3fa0b151,8bd048f1,51c11559) Z8(62928ae8,d4752b16,d51264d0,31f642f1,76a7e23c,9d60ff4f,40109ee0,c8371791) Z8(1c7579b1,1542a2b4,84c80d22,4ec1fd4c,fc7cae0a,edfdfae6,9d73be7f,a93167b0) Z8(fc171937,d4260f03,f2636056,e73a5c26,6cb321a0,c9354bb4,57d0ec6c,006ed3d6) Z8(df2482ac,9b0ae0c8,571881c7,216dcfbe,4588cf3f,23efcc0c,94d4705e,dfcbfd3c) Z8(ea403e95,fc3f998a,e9d1067f,ad1ff45d,bf4d4e27,4659ce60,d43df4c1,f1b21b80) Z8(9b08bee4,eace6107,a6d1fffc,01a9e8b7,5a201bef,e1497a8a,f34b587f,3fe58084) Z8(af4ba266,6a546f4a,8d8098cb,5934b9b9,4e558e9d,3c1dceb5,14c3582b,bb7f03b6) Z8(7fd74ede,e6cfdf40,3ca0f816,aa543092,a912ed97,4769548d,78f9a3db,5e155118) Z8(b8cbceed,90e0e0da,0e37dc0c,d3855d87,3606942c,3a99d6e8,80b24c76,dda7ce6d) Z8(cb5d23df,c0ac44a1,f17f6646,ffeecdc4,561f8afe,9e9dc096,b52bec55,23a614b3) Z8(43b627c9,2c3de016,e8e6249f,48c9c30d,cc9fa87b,069fbe48,ba5534d0,d1dc32d7) Z8(926a20b8,cf284ba9,2c3f5be7,158a89ee,2136024b,6b840208,6267d853,586a0991) Z8(be5f4be6,fece6891,fed50429,c243206f,c5e473d8,ef77bef4,7d02eb51,005d592b) Z8(13832a2f,357b0d8f,fb283fd0,ac94278e,8f8e796d,43102f6b,457743d6,bc9c3cb4) Z8(365ed950,bcfa1576,98252780,5aaaa432,9b183388,1e465085,7333d4ef,8ea98e05) Z8(f21607cf,ab7f6943,11604ec8,9ae507e6,9ada9bd2,27140b1f,d08b9a44,9ce3d80f) Z8(27af3749,86dd4111,eeca85e6,99b2d53d,816d36a2,3d365002,2ca4f818,336d13dd) Z8(38be9f8f,bfdb9dc4,2b48cd71,e32012b7,c10c9763,f7778675,cecd49e5,cf6ef65b) Z8(d57e33d8,bc556fa4,d9990aad,27a72f87,71c1aa63,6f6668e7,001efd2e,2571f432) Z8(5428853e,c808ab0e,62c69e29,f7a1b86e,e664a9d2,ae6a25c9,65b400c2,9ebc2a23) Z8(907c669e,90d6926f,3618e558,539b48f0,c4a66f4d,c8192b8f,4f9d2149,d1836795) Z8(513dbac5,4b12d24a,da51d86f,a895ae37,08716d09,e5f35b2b,5aec8495,771bcc57) Z8(4c504178,efb1cc90,7ca5261f,f8bdfeda,c21ff2a6,b0189781,74fccc4c,acd3961e) Z8(d84f9ab4,c6f64885,cb2be5a2,d1bae8bc,8eded06f,e5c35472,0d6c1f70,0b53fc06) Z8(cf04ce76,e16029c2,5132b261,0cfe1c60,1bb89cec,7f680922,fa9fa4c8,110caa4c) Z8(7277da2b,74e64da4,6b73f8b2,5446317c,198fda21,811d926d,0a60fe36,9efeb500) Z8(c9257616,70ac1565,12e5d97a,e88a9a51,5e44b6a1,c1309165,44e3112f,d3838f8f) Z8(768f4874,62048f3b,a1f14878,bcbc7b75,bf0491d4,e8e94157,f4e5d560,f88e5c66) Z8(e36a663b,1251dd2b,0590b542,eee6b680,4f137f88,76cd03d0,d6410f8f,02908a34) Z8(155f50dc,790970fe,86cf2a5f,27b0fd77,bc6d8a6a,b54b1f83,6033cba4,ae5dde62) Z8(bdbd3079,4011e454,19fb875c,7eb45064,70ada4e7,0a63188b,c22d6c18,b1b937a0) Z8(2168f5ef,bf5cbb53,0b6b7dd1,26224bc9,54cf54c1,d6b20869,a0d92360,0f0987e1) Z8(8fcb3f9c,b1a2a908,4ad365eb,08d8118c,6e2e8f74,a20e432f,a0d4dcd2,27f36409) Z8(04903e84,ceb08e2d,a4db1287,b3abc1ae,79999a16,3ec9401a,f7ee3cae,e1c22dbf) Z8(bb3b9577,f4eb4893,2d6533f4,24eb539f,ba127f76,95cde432,9e3f0139,b1d0a32d) Z8(f640081b,efd21dfd,d4d0ee32,a84e04a3,b4a658b2,ed5b38e8,7824b128,d66c2e3f) Z8(5c52c841,724e35fe,279a6b04,4ea7fc48,de11c3cc,159778dd,eb6b29a9,e8b04dde) Z8(b06707ed,79047ac8,a1ce7aa7,f644202a,6e1841a3,100baf1f,7680d894,cd1285bc) Z8(a3bf296b,0fb37dc4,caa8b1c6,a88dcf5d,7a813b07,e5f8f4e9,6742684d,2f870b9f) Z8(8e87c3d7,94bd5f0f,8e3255b1,ccf16d30,db096081,4ef2fb7a,e2f08c21,8a8e9088) Z8(d152f285,b84da949,d51549fe,7e2e7014,3e73661e,2da23c9c,f52f2356,259b2ad2) Z8(330b0dfb,e0592f3d,fb548cf7,f3d5eb32,f4b52d25,5b3c3e8c,94792ae3,d4220690) Z8(bab4d387,338b2dba,629440ee,74db8e0c,04aaac27,04a96cf6,593a1a3b,95b60d3a) Z8(7a55178f,02b77b81,ddb81a3b,1c22c81d,3a6546fe,d6c205b2,050c83f7,59536185) Z8(4d4cb539,4caeaba4,1e468df1,38d71c7e,08f51395,8fbab561,aee61d64,9b195e95) Z8(d3a63e5d,ad53990a,49890d60,cb0b9d88,3f4d0ff3,eaa125b1,7d150c4e,aa9e439e) Z8(af165b25,e4814878,61a460e8,0e485a0f,170533f0,dcd5bd7a,9562885c,49159d0c) Z8(fb212d41,740709cf,584ed683,31222ca1,dc2a288b,011bd559,84fb4170,25eb87eb) Z8(e8ffcfc3,39dc1310,9e94a387,a3856ddf,4aaf8a6d,51632366,d4d74703,8ec3c314) Z8(98a69854,d0d34ca3,982b1ea1,1304455a,47e84d57,ba521dc0,38ad7d8d,9034d22f) Z8(f02e8511,bab7152c,70f4545d,e1eb3c85,78f26bb7,eaf29e81,35cf16a1,6c0d531c) Z8(a77aa57e,f8995f08,d759a499,c3672dd4,b1f83132,d1684b86,4f38c9c6,1c424469) Z8(bc04f269,0e32d696,295e7a7c,c8affb03,0d62db9d,ea5eaf02,359a488c,3419a4b1) Z8(9531d972,543e01de,1e71f615,56a47dc7,067cb0fe,64d457de,fb5ef4af,b03ce759) Z8(8222f5f5,fd923857,895f5f01,9b6b7aff,b362aa63,86c96dc2,93a52872,0d75abd4) Z8(d07e019b,660122b5,055168d7,cdfd4b9b,1fbd2dff,3137d761,072e8de3,4853d4d5) Z8(1fe68b11,364ea28e,0c7fb0c6,b96e902f,987c6628,86a917b3,a8ddfe23,af511657) Z8(4ea7897a,1b80c0b0,4677e3bb,b94e9d25,c62fc23a,06498f66,1bef0d0a,c1be5d15) Z8(d72f5883,4a2a2e7c,99221220,b8e76036,46dc6902,5adcfee9,5e536473,52e94498) Z8(807e106d,8d2403ff,bdb55ced,0cc07ab4,18af8977,e9c5cb13,1a56d9de,b76524c7) Z8(b553fdbb,d1ee4e9a,e79213ae,5859d08a,2790d5f3,dbdabc33,03928fc7,4fbcd518) Z8(ef3d01b6,66538aa1,b3bb2e04,9634b911,bb955e3c,b62c71a1,a58bceb2,397471cb) Z8(ac71c539,36a08669,9d697d69,fb9e1ae1,42d69189,79ed4eb6,5ec73e8b,4c782669) Z8(03aceada,a024030b,fd2003f5,632338e1,89fd1b08,185ab78d,a8ad5e91,657f86dd) Z8(666233af,38f99c40,2d9c5d3b,c3b81143,50045dc2,69c5abac,0e20ec2f,8ed238da) Z8(97796285,d5290656,81ca0216,f120f29a,7bb2f270,eed60c16,dc069c97,5dfadfca) Z8(909e6390,046d3703,7c3f88d2,6434355e,e98c65ce,e2a0d491,9ac562b0,0394c4f8) Z8(ec32578a,48c6e4fc,847e4f80,e20e37fc,fe3ca691,79220e82,718deaf7,13cc2ff8) Z8(49fbb9f2,29d89909,df976803,c854f753,7cc34a51,fd038866,88d31e10,56147a09) Z8(f3e09a8c,0f9db2ff,fad5fa20,86671e64,a05fb758,4b1f38d4,f52e1e1f,d8287a3e) Z8(1bc10381,ac96aa6f,25d2dc73,fb76ea63,5994f5ce,0c015d9f,04deb5d9,5e4e34a3) Z8(45f091ed,f50c052d,0b13b3f8,86a4cb90,5f942308,809973a1,31542797,bdcc7ac3) Z8(1ec3578a,dfce2d23,b83c79d7,abe3e237,02dd50b0,0b0ed590,8be6fc95,7872a3f3) Z8(f4d83a71,8af51b9f,f3868932,22546063,058e76fe,13af47fd,b87b6a56,cfad172d) Z8(30e2b56c,bc72d096,6f430db5,1e2d0e38,e668367f,6f72a0d0,0e587179,6f5ca671) Z8(d8bbc128,89164e16,1d7e0e2e,b4841308,a27e7f48,d1efe677,b013e62b,2c1b8ca4) Z8(f70bbbfd,f2276861,72af6661,d38b9e2c,0409cbdb,2370aa4b,4e9007f5,ab6b2ea8) Z8(e11d8a93,da967e3b,a4d3f836,f826fa52,1d6d7934,ed7daf71,3ec819fc,734e4a25) Z8(08f1bf0d,209cf241,110bdf66,751d819f,48719dfa,2e2750ed,8b1f3171,c6f5f000) Z8(3fa6f90c,0b372c1e,ca87bcad,a61eb994,dcb4c5be,799e378e,467cf8fb,f6c6de2a) Z8(48a58db6,211ba2b3,a963e3bf,fcb01eba,6d18fe59,7a7a6c08,f6bc6826,975fcc3c) Z8(b2930b1b,81b9a7ce,df976f3f,8ec810d2,3c1bfd5f,16d89bf1,72ae3422,499e4589) Z8(b42bd87a,58877cad,0e435f15,8b72f7c7,1e4bc7d0,59cfb147,77c80805,2e79d2f5) Z8(3b69e7a0,06a18dac,c9fa3f3e,4f5c36b5,2354dd96,f63efb34,cea371ed,aafa8c69) Z8(9bada3d3,e57d79ea,5a2728a5,0d0d35f9,c3b13e37,ea2ced55,8eae983c,6b00bb99) Z8(077d0fe6,c531286d,9d347760,16130d85,1f894ac7,704b4be8,0f70f9fa,fc1b7ace) Z8(85b13e2c,bd01a3c7,e5a2085f,e26dc94e,9b9035b5,1ff54f6a,85b175a3,546be6e3) Z8(7ed530fc,c21d79f0,7d0ebaa9,06e6814b,22fd6844,a5b5fad1,bc720823,e7863db8) Z8(166133da,fd66cca7,9538f204,afd64030,2e6f792e,6952038f,21ed5c09,eceb70df) Z8(6bbdbc46,fdc281d3,aec21b7d,a89dd990,6850d792,f0855f4f,bf225700,b9908133) Z8(8cab078e,25c82cb2,a3e54242,a3442020,5d3e4ccc,512aaa1b,ff96c3d1,a07f5511) Z8(a60c8f60,a66fcb0c,e7ed6c28,aec63c26,5a56e5e9,1af64e07,ac7d985a,8e99f652) Z8(f874e612,45c5bc78,213eeae8,52747fa2,2f880c55,93b20170,2cc422c3,91a4f360) Z8(423db407,19744c84,99cc04da,74dfed5c,e1eb208e,87f92e14,cf7a72a4,62c7e3a5) Z8(9da39372,926823ec,a3b6c298,dc26d367,cd8c8506,f394d632,ee008f7d,7ee297b1) Z8(bacea55d,e3008dd9,d2d15002,7365b007,f36cdf62,0623f633,a518b02e,80edf13d) Z8(c0d04054,c1299ba4,33cf8529,a30be956,37b978e3,bc3ca2fe,d22a3b42,2e9f88a6) Z8(2b86f135,e029bf24,66af3daf,a2a275fa,c7cf70a8,3514eaec,cd05c7f8,3f9c0672) Z8(f3734fd4,6979f902,371c6f3e,debe841c,ceee420f,31a5a4da,e8fe97a5,271be053) Z8(3381b85a,b8b43e2c,731e651a,c0ae127f,8f2b2373,0de2e4e0,d9b248bc,b8f0be30) Z8(7e624c67,02f54979,661500a6,f90bda96,25f8efea,a8de9dc9,783081b0,fcf54956) Z8(becc3c21,a8550fb3,63a221ea,deab5378,68c1b8b6,d0749582,ebf9e078,adae0c09) Z8(9c23baf4,382f6dfe,02e75a78,eecf7513,215ec2b5,4c1f421a,b0baf7cb,55fb49a7) Z8(289dbd18,d903e17b,d179c21e,291b1ce5,863dc547,777a5e20,8a8784ac,56bc89fa) Z8(6c209557,57193472,786c94b4,4a6e936a,f24664a7,caa90793,670e04a8,47d307b8) Z8(6b645c34,87f909d7,d4e64bc0,a4e94c59,a34e1f0f,ce5004aa,a38df28b,64143f93) Z8(6ef030a1,0ff452af,68914137,6876522c,2c4617fb,20e875f5,aef4ab8a,11a67cb2) Z8(aa9278ac,c50fe4d4,20443758,70168c57,80e9ce25,b9fd1208,289471ce,72911cc8) Z8(113cd60c,11108fe2,4a69d7c8,74c1205d,298cf268,d679b73f,b6947d5d,83f4697f) Z8(039ac61d,f6460510,b1b37584,5920d59f,43a2b6ea,ed497657,85364849,66d1aa22) Z8(14d5906f,6a932879,40be5df2,1851668d,bd024ffc,e6e34fec,6e8e6838,b3b742c5) Z8(2ec5d2c1,68eaa2cb,ddc4ef81,9d7925f1,16135b83,91e43c29,bf4fa142,a793eec2) Z8(29ea5468,d566677f,5828b077,ceca0ddc,51202b2a,4f63dfb5,556908f8,ed5130d0) Z8(760207e0,0342d023,a72b0984,5cbe92ad,e1f18a67,5cc2f7e9,b5e73dba,3451da46) Z8(31e063e4,150ab7b8,c2a09fc7,45d7c5b3,32287c60,a8934e23,64a4500e,030170f9) Z8(4b2f4a33,59908789,a6eb7cb7,cd454826,21e4c2e2,80d6d3ef,f153ccbb,7e442b55) Z8(af0fc01c,692316c6,4b753585,6110deb3,3d378a75,0701a571,e91c3ed4,808a0844) Z8(e964a153,d95c8131,4307887e,c929cabb,577d35af,f4db0f92,dceae0c3,4c6f74d0) Z8(1e8cd325,b0cfc177,6dcdce23,9c5286fd,cf5a05b4,1ab2b51c,a56bdcc4,ab2055a3) Z8(55b9aa62,a96d6df3,35c4dfe0,45035b9b,48943110,708cff46,7bac2f0d,3c13819b) Z8(a940bb46,35049bba,292512ea,14581c62,6d12bc69,2a5cd22f,f0d310c2,6a4073a5) Z8(cd2491a4,a2da8d82,6abda74b,bd1cd1f2,60e4b295,5d84c522,755056ee,a084a550) Z8(2c707edd,270b14d8,5e6fb9cb,676dda04,31f1b05a,9e9ebbc2,80e54399,7496e39b) Z8(9e13641f,6f9f6bcb,80809c50,d5558efa,d58b744f,7157d251,b8ee3a68,26810837) Z8(4e4781e0,107697a0,ddeacb86,9cdc1510,9b3c9755,af4a62d4,8671bdbf,f64e7ea1) Z8(ffe61b91,6368df7e,04236558,b2bc23ff,134bd728,82d9ac95,ff4b15d2,7ccb928f) Z8(d7af2ee0,188c47b0,1a6b10bd,326a25c4,e7e2cefd,1d2218b5,af96e547,868e9dd3) Z8(a7981d8b,0cad2d3d,e8969a85,c068c465,e95b24db,860c7667,dd115774,651e6554) Z8(7f3e76ba,1d46bfc4,de159d4a,5c1570aa,438eea33,a044dbfe,9992f161,02c55f1f) Z8(bb1cc07b,4a40bd4c,f36d7cd7,8dccd03d,7e4c46c9,b5a0ac04,1811f075,42192fe4) Z8(fccff15f,6e763ad5,6d323d48,8f7cdd91,aa884eec,4e4884ac,67f22b1c,581ec996) Z8(72950950,8e2bb317,09b3a293,4bf6bb6a,4b7b265e,88c76347,22d692d8,3c457a27) Z8(eb8b4272,ce1ed91a,9e06796e,e7cc91d6,9fd5aece,bbd4b292,2258d583,0ca93f4c) Z8(0e914edb,27ed815f,4d0d1587,fbc1ef54,b76a9713,7860d5e5,a24d5032,4c475830) Z8(f23c4eb9,a0ecd15b,86d95733,c41dd5b9,cac4fdaa,71f7c144,d89905dc,6b97430c) Z8(0334d312,71af76a9,8a64c167,cc4de934,71ffcba1,0d913b20,e7ab8a1e,e8e442ac) Z8(6f6c02b7,8b88cc78,b88ea7bd,f2a4d943,37a17788,9eedcdcc,d36f0b20,996fc4b6) Z8(803c742e,2de864b5,b909f0e5,a8322cf0,6696ee5f,96534107,af826e24,13f35fde) Z8(7f412556,66b977a6,55aaa035,448853b5,3e5e4be7,14bec8dd,4f251ed0,c29dbe5f) Z8(bb01929c,2a7ee272,82c3df59,8ad27f30,b58467c2,68c2ece0,6bce5542,63e58328) Z8(b762225e,be9d39d0,19fcea3a,97bb2627,f0440dcc,d3b4ccc4,6aa9f743,5c2976b2) Z8(32f33dfd,e5761145,2e7bd637,fea6e485,e3257ffa,5b1b302a,4eb292c2,9fd2187f) Z8(262de78d,0cc5a2e3,98aa62ac,de020f6d,a7fe02a6,bc1e0fd5,aff7407f,ed93c304) Z8(0acdd274,2ac46215,56f6a3d0,8ed91f5e,e4c49e83,89d14d60,9a17fde5,78aca16a) Z8(609f5f0a,819b393e,b169ef5f,d2ec168a,c64f63b7,e1ef1d8a,c65a3456,9032f6a4) Z8(fc4a9833,82f16037,b2dfa98c,47575f29,22712667,2985255f,f2090010,b00d04c9) Z8(9f5d7ada,ef9790b2,7e33c831,7dbfed3f,0eb4126b,28205816,a50a19a1,ece273b4) Z8(5dde89a6,a0e3b550,b95eedb9,1d4f7aed,2b9870c6,e8872878,7c74dcdf,b41b3c4c) Z8(aab19563,03e07187,6296eaca,c40debd4,07516c28,38487fb1,35a646f2,2ed28da6) Z8(1cefd4c2,4362dabd,9d985052,17ff3ca8,dfc27876,023b16f7,70197792,3bc3ee92) Z8(2ed0dff2,e8001193,926744fb,4b0d789b,d867f14b,e929b365,c69cca7a,141bcd47) Z8(d314f763,0138e4d2,aafd5c18,41090e5b,1f21e11f,a851ab21,f3d83369,f0fc1813) Z8(711f1536,403ea525,8522e91e,32a6fbd5,661a49fe,a57ddb82,173c2442,cb83581a) Z8(eb1dd975,c9cb3729,163582a6,ad6ec2cc,18b7112a,838acdfa,adf10dcb,729bff1c) Z8(65a5e013,55b3366a,b0774b7d,507d2f9d,dbdd3280,145cb134,af268b7c,3d52bb5b) Z8(d6e2d6a9,f3fd39a1,471c0889,2083184a,d813215e,8f5c75d4,5557f09a,cc0027b9) Z8(d634bf34,bd5033e8,7e74152c,330b46b6,959f92ef,10392058,9c8eaee5,d71b34fd) Z8(25180b41,13cc439b,02eac0d2,04389498,3b844db1,ee05aeed,525c49ad,9a83b4a5) Z8(4a7a82ed,35f9c367,7d699b98,527af673,c98c7d33,eded9085,8fbf6ea9,927a3134) Z8(53a93da3,1b3c98b3,0fe254e4,67f06b13,5f326a60,6a2e1528,b2481c23,95b1e6f9) Z8(94c5ef9c,0c1a0bc2,1659dfc6,1dbd626f,42725be2,00a12040,70b7c3e2,400dadb3) Z8(ec0dd4f0,9290ce11,14abb1ea,96c47756,6da0bdc3,a6ab686b,a464aa7f,5d9a05f4) Z8(92c6d772,d489312d,27f4dd4f,d79fd147,42f0a8cb,95ebde9d,23dffb38,c34249e5) Z8(c1cde5cc,c6b34229,5c3eeace,ce6aa37d,61528277,b5b90971,beab31f3,43e2c3ff) Z8(dd476ca4,d93eac00,631d7fa1,d3b34a98,0757e574,e85c48de,bb506ba2,19f77b56) Z8(91562fa0,78e80505,25f10da9,14847581,5319d8ea,a96683f8,ad293df6,a650d30d) Z8(a1b2ee52,0ed0522b,47412d3b,66e8c85a,f9fce84a,c287fd8c,0abf6c20,b694e95f) Z8(f771857a,31d88024,4b11a1ad,ab008279,f2573600,f75bebb5,90938fe0,a489c639) Z8(0172ee51,abaee167,5f18d121,fa9766f8,957eddbc,6a90eab6,f9c6bed9,8d2217aa) Z8(3c400bc3,254cc35c,c7180cfa,e5173926,0456d1a5,2abc5a44,21d67b05,89d112c1) Z8(437f0a56,e69f9956,349f598a,3c6ff291,80e0485f,cde8a361,148870b3,d62e1dff) Z8(d8d59e13,02ef6125,9accc88e,3b191d81,0f801318,df7c058f,a5ed1330,f03bea81) Z8(60af3351,646eea92,69a9c557,ca366d1e,b3156d2e,0d0bdf43,5f1129e8,992e8bf0) Z8(d3811316,af00a9f2,ce5aff81,d5f94450,665a5176,d36feba4,e53398f3,5cfe2653) Z8(0355a18e,29fdf716,980febbb,b47d2f6c,881731d1,6fb0091e,4cddc19b,6772e1c1) Z8(f1706f20,8acc9737,7e4462d4,67680548,e9e03333,b19c5671,fc74c12f,59c022cf) Z8(33551a87,3342e32c,8a2b6d5f,f6209124,f1294405,d80ae39d,e6a67730,c6bd28f6) Z8(0e4c824c,68eb3a50,10ca2a2b,e74751da,486f4e5f,175870ad,794ac59a,903f61b9) Z8(9f8f7d4d,46325785,97f70854,1c562c01,d8b88960,31e3228a,d1c102fc,15b75bde) Z8(e15aa6b9,36754cb4,89b6c436,e9e16830,17ea4675,c329d5e4,f85c63b3,1254fcbc) Z8(70890c26,58b263ad,d6f566cb,f89f149c,be17b75d,3e8dc137,4cc6dce3,076f2563) Z8(74b3213a,e7bb5d73,38b2a891,e4038c5b,c51a5719,bfa569b2,7bdc3b85,fbf03e79) Z8(f54cf3c0,69050334,021d6995,93a2857b,1eff36fc,1fcdfcf7,7722f66a,93b57b5b) Z8(f2b67a5e,ca40c491,326da01c,dbdd67fb,e81e5c0d,09017aea,eb0d5cc7,264dc8e6) Z8(c5bad264,ab103b03,e09a562c,8c2e72e2,0b527989,232bda45,3a500289,6d02cf93) Z8(a22e4b09,69c3ea4f,44921ec6,d927cda3,ce0168a0,abd97a02,9ae0cba7,0a2d6d9f) Z8(7878e417,154608ef,a882f91f,e4afd563,c9bf5ee3,24600f29,abdfd66e,8e102c14) Z8(6bbf58d5,a8289f8a,8cfc30a1,83192cd7,1f94dbf5,5ea7706a,713d263d,6c07eb72) Z8(022ca6ab,3c0f125c,7254a724,eb374792,884cbbf3,64a0ce0b,8772be90,c1dad18f) Z8(6a0bf04f,cff82cc3,609a6eff,95733b5d,7cd1cac2,a7b7f91f,da513ff8,4f034af1) Z8(6cd5fbcb,a84e534d,e37b2b4a,19ed4317,3cec4c73,95defa7f,060d1dd5,71306254) Z8(12f84189,4e7d273a,14f97c2d,de5f0476,70cf8c65,beecaf9e,cdb32cfa,637f417a) Z8(782073a4,842dfc6b,e4940071,97b801d7,4cd0cd24,2e568a96,1a0009ed,34b4e2e3) Z8(5a0c42f8,e502493d,5a02be5c,f070b44d,0378a8cb,f3d8e568,e0f705ba,256bfaf0) Z8(03a0b691,85a349ed,43e46bf6,19943080,7eaf0b9c,52b3b24a,71a3c30e,9e301f39) Z8(e8308dbc,e06a8446,13318572,a8879bfd,e74b5e84,a603c464,1f34f494,9c37a164) Z8(4fb60cfa,a50d00ec,4fd82967,054e4f83,15073d26,20ca7e8d,983b85cc,03d0fe5d) Z8(b56e7efc,5eed5612,b4d93d97,fcec56f2,91a0cf29,070e7bd3,00dff9b5,70bb57fe) Z8(55d7eff8,9f49a77a,794f830d,25c3b848,b8da4990,ada20745,2654b37f,265144af) Z8(34e42a6b,520be3a3,699823ac,61bf51f6,0c002042,f51f1c7b,80fc8e46,c0606f2a) Z8(8c251b8a,e8e7bd6e,cbc717d8,9cd1d40b,7d34a02a,c50d8279,3dcd3a75,0fec9746) Z8(c670f4b4,5a111373,e2e4d1f0,2cc3b92d,d155f6ea,fea07acf,40f74410,191dc716) Z8(b86b7fcf,6b94ae7e,ada12be6,4087d371,60dd4981,e06131cf,24faadfb,28ff6564) Z8(90bbeb7e,8c4ff063,93b35d17,b4b8b333,73923df1,7ce5db1a,cbff2326,25e28ea2) Z8(af339d7d,64c694d6,cdfd2033,50437d3a,bb06a66e,cb5baf63,746de41a,e9d50d9d) Z8(56bccec6,d65b3724,c9b0725c,bef678d9,3f2fea8b,f65ced49,cfadc3d3,24185c3e) Z8(7e4c7227,4311ca18,ab8bbb64,15e796af,bce74917,0c3d5c40,1b522997,f0f8da6c) Z8(2505ef80,2c59be2e,c106757d,62697df2,d9ad2a88,7f8d3f0a,8f50e293,01dedd69) Z8(58dcd5e6,9905583a,e23c601c,e402c855,84798d30,4e20cd03,7165fb10,b00e5f0d) Z8(fbcdb8ec,13beb580,69023714,00ab9530,eb029851,06477d02,3886e326,bda7b00a) Z8(703d0212,fd2f294b,6eb4c033,034fe823,32cba47f,65db33b5,970fbc2c,a85c021f) Z8(44a60a19,7c65f7d1,fae32eb1,83c850c1,e148eedb,78bf0282,39d4ba97,65a4f209) Z8(c49874ae,cf40dee1,d74b7750,883b63bc,9f8c24f0,578b9ad2,7d2d7f3c,a1c6c473) Z8(00051d6e,a06290b8,7a13c24d,66635be0,fd38a243,93f68283,71ed0018,80dbd25c) Z8(5954c902,c7d23725,1c237aed,e47b48a8,717ef46d,d6b06ff4,edfcab3d,e2f1957d) Z8(ea805669,eaf865a6,449eb433,17689051,b55ef213,104a5e1b,2a63981a,76ce0781) Z8(e460f597,ddb0e877,4f546447,4fadb74d,152f9b7d,e275eb72,99a0aad9,e765a0f4) Z8(a4bc6402,d2f0a67a,92900736,2cbce2dc,b5c0c205,08c8759f,151e842a,995f6f12) Z8(6f45e357,2d8284c2,79432610,dd893a6b,e318b8b0,5c265da0,be268476,e2aa85b2) Z8(88aa9967,4b3b9e6e,e95d1999,fcd1488b,25d48214,10680303,40b82502,300dd44f) Z8(6a3f038b,370d1619,bc7b21d3,ceba467f,70cbdbc4,c40e2ac9,3d12c6ab,b58bdcce) Z8(cec80eac,b6091f45,08aa8e56,8a5af446,94074f87,67071411,91ccc252,7856983f) Z8(91ee232f,0a08da1c,21380264,8d3c13b7,04f80d79,fc2d7770,6abc3830,a5c618ce) Z8(4e17f04d,9a90f9e5,d5a09d9e,2845dd5b,793db83e,3d48de11,c5f1445a,175515d4) Z8(e952acb9,abaa46a1,a8025dd4,1cd5f2b4,990a8fbc,9c248753,d4f99a0c,fdfc7261) Z8(752adc12,59f6fd8d,d9dad171,83f5f3df,dc154029,313dfeb7,01ad827a,78da7c95) Z8(599e5684,a5e48d8a,b00c2406,d769430e,43617e07,80967fd4,cd8ec19c,ce98e393) Z8(90eb334b,a491de35,0a04d4d2,383c64b6,97ebbcb5,e546436a,b92b6775,bbcc4210) Z8(4969f82e,d7c18b24,23634d43,816bf594,8195ce1d,df034c8f,64985f1c,ae7a7f19) Z8(80cd6f72,20810d01,7a5a32fe,10367aed,0a967562,f5ba33f0,31c6bcb2,cbb595d2) Z8(aef00b97,a1b48779,47604497,a322f4eb,3c2b2aa6,9fad3f7e,87b0fcb4,b1f552a3) Z8(9f82d67a,35a89a62,aa3f885e,afbf8b75,06a3a40f,ac0a1885,f4c62bbe,50b20303) Z8(9ed76ca6,e7785707,4df88a7e,8c1fd4fd,98a047a2,fa58d7af,061787c0,07767c23) Z8(4782585a,9c94e1ef,d3711a7b,98419ba1,cddcacce,bc5ecbd1,91310c15,d286551f) Z8(0b85b306,f808b683,c25008b1,968edaac,1b3229de,2ee8647e,c5d99fa9,4c19f5df) Z8(109dda22,8d24d7bf,0f046e0f,15f858cc,789d16d0,4ea3364c,e7ae120d,9f9694e2) Z8(9f171436,7eccfedc,77e3ee42,bbabfde2,d5efb316,66d7badf,0009e97a,c010c3eb) Z8(ff817fef,cfb7649c,e8229b9b,0a5cfa17,cf5de0f5,6d9374b5,bae0d062,b87a136d) Z8(e7c79266,7faf28d4,4df040c9,1c19a8be,1d8ded62,bdbe3cfa,4c43fcd9,fb801209) Z8(467a303a,6b6e6c02,fce26b37,4e06fb54,f5f20871,a8d91b99,c9e0b52e,bfd615ad) Z8(df16dcfb,af69376e,f169b463,c2272022,77aba281,c5d545c7,3c358b45,66f1917b) Z8(4a094803,2dba58f3,d4c92cfa,5c5e4156,c07b938f,963c382d,ce8a58e3,792bbbc1) Z8(78e9a729,d11e4e54,e0009a97,2c6744af,089be8db,091a4ddf,9287ff07,2de8fcf5) Z8(268a0bb1,82950d4e,632a9163,e466990e,59543ad1,61001e4d,79c0b660,84a3bf85) Z8(514b63d3,9a722c43,ae66a2b0,17a1bf74,5716f721,ef330368,6fe6831c,c76d6bc8) Z8(5e5232a6,9cfe00c1,d6f4f218,f659978c,fc8b0fd1,5d77b5e3,8de6be98,4201fb7c) Z8(c99055a0,a1004438,155b4e14,07167eb6,7951d86d,f22cc5bd,cb918e71,941e12aa) Z8(b6c31e5c,1bcbea79,7ee32c7d,bc19ae7c,3cc01232,9d84b3d6,9053d9ca,8db01b02) Z8(a40ee126,83b9a410,0964b460,a9c43a58,3e6abc1c,59fca0c0,f4aec997,2af3d893) Z8(82da3042,90ee85d6,b505e09e,30913d9f,15b8388a,9c5c7fd8,d0801614,ba8bfa2e) Z8(2f701ea6,12c5993d,06f7cd52,ac275fac,07e79d7b,f22dad17,74a3f540,76079166) Z8(6412cbfc,d10687c0,1a680d7d,7865dc53,2205a7e0,ec621f49,7a5c7111,d158404a) Z8(a2868f81,f7abd59d,1b1b075c,f2507ae6,f1096b47,4db01b6c,296c8177,e7b37fd6) Z8(7aa35c2c,be26f41e,6fae7cfb,5eb4a5bc,82801849,15198367,0930f270,e24fc040) Z8(975e9486,6e79df0b,4f7bc079,fdf487a0,b4e9f0ad,a67baea7,566d3a38,3a470c5d) Z8(46aac656,64dd6277,9bb8785f,15b7a6d1,e959f484,f70ade7a,1b7eac5c,d4080399) Z8(a552eebc,d098a593,22ba9f3b,88efc428,29e1127f,c3e17f91,6fc063fa,e5ce7b30) Z8(5a4bf444,88b5a02a,04651c80,3e2d1062,7f4ea501,93af99c5,f3d1bb13,8274f710) Z8(37353400,b442c3ad,b0b137cc,6b0279c5,34b23225,d3a1bd82,1276449f,1c173a8a) Z8(1998df6b,1ebb3dd2,cf53f2d9,9cf37661,3c55cf69,43477b11,dc047597,983ff05f) Z8(6674b4af,250e2717,442b6861,8ceb428b,c7f486c5,8de9704b,5e0a368c,f38eade7) Z8(dba6d38c,5794fe0d,13c3c48f,ba2a1bd6,c529d6dc,fd1b96f3,719bf81b,bc8f888a) Z8(c95f4727,9a7dfcb0,b76ccb37,9888f0f9,103a8165,d23a05f3,48c39bf1,b713b205) Z8(9420ef6a,9234ea85,fb9efcb8,7d498d66,97387cbe,eb11630c,a908169c,ae97a482) Z8(085f0d45,237d7a6d,bf63c439,72abb1ad,461e22d0,2766f3ff,4146a068,f7b17cfd) Z8(c5c1bee3,1be0932f,3fa309c7,bbf1e733,ff83c39e,5e8ee43e,902157cc,dc3cfeda) Z8(4e992dc8,e8ad9902,e65af6fb,b3f5191e,73d16130,ee55b105,09a39b27,c6fa01e3) Z8(da80f4ef,a638cade,9ed9c610,b6976359,f34c7a84,f8f28119,1931cf1a,83e104d1) Z8(9caf1bbd,d3856309,e70dbeb4,299d8886,d2dd641f,d465a5a4,6b568b49,8042107e) Z8(1f5f0156,2b4519a4,84ba0f04,0d40bf30,460f0242,0a116c3c,b9f83468,fda73cdf) Z8(86c2c15b,7821b36b,c4347132,4f449682,f8b702eb,9ccc6d1e,7711e670,e6d199de) Z8(a96e00d9,ca57511b,0d9956a5,90a991cb,6dd308f2,81a81df1,61cb707e,1c6406ca) Z8(04abb049,831a1f5a,50ac1a43,0cd7bd89,6d076f36,2b34c387,ef6a5ebd,add7b980) Z8(283dc9b7,58118ea5,0957884f,cb6e5527,6aa8054a,a9ea62d9,e56797d1,923b6750) Z8(05e5d0cc,4ac9af77,13c5f541,afb40fe5,444560e6,97257c06,b4bb7615,c3a1cfa2) Z8(ecf6537d,b64199c6,14cac452,21be12d9,2fa57336,a6f0cc3a,eae76dce,b1f36c4d) Z8(830d6926,b3a2b31e,219263c8,036405b6,0a591542,a26f428c,ca195ed4,7493f3cc) Z8(aea7580b,d808e62c,97a8768d,e3090288,a68189ea,d4da66f3,db3b78eb,5408ccb1) Z8(7cac9071,e77c4a09,3f93ba3f,4158580c,f6c2ee39,c139eae5,1a042a4d,fef13297) Z8(65140b3c,ccf8a858,03d7306e,289926cf,02509e47,bd48e29f,09a12dfa,1064e38c) Z8(6003e683,fd2a57d7,826daec5,9e3e63c1,85ee8a83,fc20a3be,1dbb58ff,90a8e5c5) Z8(34fa4278,b8a0ef49,4ac1cd00,dd0412e1,262dcd7b,cf7f7ba6,109291ad,8bea4f6e) Z8(1491d8af,8d2fc0f4,01e4f7cf,ab2be0ff,d44a3e6a,9b489d4c,00000000,00000000) }; int _arb_hypgeom_gamma_coeff_shallow(arf_t c, mag_t err, slong i, slong prec) { slong term_limbs; slong exp, pos; mp_size_t xn; mp_ptr xp; int negative; term_limbs = (prec + FLINT_BITS - 1) / FLINT_BITS; #if FLINT_BITS == 32 term_limbs += (term_limbs & 1); #endif exp = arb_hypgeom_gamma_coeffs[i].exp; pos = arb_hypgeom_gamma_coeffs[i].tab_pos; xn = arb_hypgeom_gamma_coeffs[i].nlimbs; negative = arb_hypgeom_gamma_coeffs[i].negative; #if FLINT_BITS == 32 pos *= 2; xn *= 2; #endif if (term_limbs > xn) return 0; xp = (mp_ptr) arb_hypgeom_gamma_tab_limbs + pos; ARF_EXP(c) = exp; ARF_XSIZE(c) = ARF_MAKE_XSIZE(term_limbs, negative); if (term_limbs == 1) { ARF_NOPTR_D(c)[0] = xp[xn - 1]; } else if (term_limbs == 2) { ARF_NOPTR_D(c)[0] = xp[xn - 2]; ARF_NOPTR_D(c)[1] = xp[xn - 1]; } else { ARF_PTR_D(c) = xp + xn - term_limbs; } if (err != NULL) { MAG_EXP(err) = exp - term_limbs * FLINT_BITS + 1; MAG_MAN(err) = MAG_ONE_HALF; } return 1; } arb-2.22.1/arb_hypgeom/gamma_taylor.c000066400000000000000000000437231417376376500175120ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arb_hypgeom.h" #define DEBUG 0 const double arb_hypgeom_rgamma_d_tab[128] = { 1.0, 0.57721566490153286061, -0.65587807152025388108, -0.042002635034095235529, 0.1665386113822914895, -0.042197734555544336748, -0.0096219715278769735621, 0.0072189432466630995424, -0.0011651675918590651121, -0.00021524167411495097282, 0.00012805028238811618615, -0.000020134854780788238656, -1.2504934821426706573e-6, 1.1330272319816958824e-6, -2.0563384169776071035e-7, 6.1160951044814158179e-9, 5.0020076444692229301e-9, -1.1812745704870201446e-9, 1.0434267116911005105e-10, 7.782263439905071254e-12, -3.6968056186422057082e-12, 5.100370287454475979e-13, -2.0583260535665067832e-14, -5.3481225394230179824e-15, 1.2267786282382607902e-15, -1.1812593016974587695e-16, 1.1866922547516003326e-18, 1.4123806553180317816e-18, -2.2987456844353702066e-19, 1.7144063219273374334e-20, 1.3373517304936931149e-22, -2.0542335517666727893e-22, 2.7360300486079998448e-23, -1.7323564459105166391e-24, -2.3606190244992872873e-26, 1.8649829417172944307e-26, -2.2180956242071972044e-27, 1.2977819749479936688e-28, 1.1806974749665284062e-30, -1.1245843492770880903e-30, 1.277085175140866204e-31, -7.3914511696151408235e-33, 1.134750257554215761e-35, 4.6391346410587220299e-35, -5.3473368184391988751e-36, 3.2079959236133526229e-37, -4.4458297365507568821e-39, -1.3111745188819887129e-39, 1.6470333525438138868e-40, -1.0562331785035812186e-41, 2.6784429826430494784e-43, 2.4247154948517826897e-44, -3.736587834535612554e-45, 2.6283329809401954491e-46, -9.2981759953768862996e-48, -2.3279424186994705986e-49, 6.1696208352443874204e-50, -4.9282955867709899305e-51, 2.1835131834145106973e-52, -1.2187221891475165553e-54, -7.1171088416628746319e-55, 6.9205040543286892535e-56, -3.6764384683566763277e-57, 8.563098056275654328e-59, 4.9630454283668443848e-60, -7.1542945770816152182e-61, 4.5517276890885041177e-62, -1.6183993053202944344e-63, -3.8180434243999502464e-66, 5.1850524119058482295e-66, -4.1671368092239208861e-67, 1.9162906929373887193e-68, -3.8089281324683658733e-70, -2.2063861055924121016e-71, 2.7722310960098954165e-72, -1.5987660478100181057e-73, 5.3197307804174034028e-75, -8.0517461416842390432e-78, -1.2484629810263795113e-77, 9.6431887683992238428e-79, -4.2827980483017479213e-80, 9.5087142369030441861e-82, 2.7131392138694383464e-83, -4.0968779415069156659e-84, 2.3742980019740160598e-85, -8.2770890210072789764e-87, 9.072497609426645865e-89, 1.0645558195026985633e-89, -9.285335619603754493e-91, 4.3333135927203670323e-92, -1.1745606334673315984e-93, -2.6908010752365215433e-96, 2.3898952892036810357e-96, -1.5569361182789167325e-97, 6.0488748201074133757e-99, -1.2273370571029378615e-100, -2.540738850916238751e-102, 3.7708800953170816508e-103, -2.0089261677502892352e-104, 6.6158100911447349361e-106, -9.2404702022121568081e-108, -4.82072018655246532e-109, 4.4938898756858357188e-110, -2.0497789059725778416e-111, 5.7862770569866937508e-113, -4.5696744624334387424e-115, -5.8267365553303743945e-116, 4.2025380699297338056e-117, -1.6889318527713702846e-118, 4.1226213324018604871e-120, -8.2451196593745569675e-123, -5.2036993784470216679e-123, 3.1616685922306712047e-124, -1.1432359131094236326e-125, 2.4359648735131490197e-127, 8.8701584767164321698e-130, -3.6328610892429035156e-130, 1.9485148907440212068e-131, -6.450096583602651512e-133, 1.215186561728963791e-134, 1.0637863819629713691e-136, -2.0430980587447135517e-137, 9.9760876002985183681e-139, -3.0707428945789381066e-140, 5.2091832948433107534e-142, 6.7131589510935005823e-144, -9.434301219575868381e-145, 4.2908149482548296582e-146, }; #define GAMMA_MIN_X 1.4616321449683623413 #define GAMMA_MIN_Y 0.88560319441088870028 /* Crude upper bound for psi(x) for x > 0, adequate for perturbation bounds for gamma. */ double d_abs_digamma_ubound(double x) { if (x <= 1.0) { return (1.0 + 1e-14) / x + 0.57721566490153286061 - x + 1e-14; } else if (x <= GAMMA_MIN_X) { return -1.250380137503405359*x + 1.8275958024049382196 + 1e-14; } else if (x <= 8.0) { return (x - GAMMA_MIN_X) * (1.7581621716802087234 + x * (-0.74622516195984912595 + x * (0.17009872711678924164 + x * (-0.018637559864260712285 + x * 0.00077747045691426195132)))) + 1e-12; } else if (x <= 128.0) { return 0.75334126757115431475 + x * (0.21045131598436795981 + x * (-0.0075387469533717503617 + x * (0.00017308475161765275722 + x * (-2.4025446500822043239e-6 + x * (1.9547402969088507111e-8 + x * (-8.5654894222045481692e-11 + x * 1.5584520745423393038e-13)))))) + 1e-12; } else { return (mag_d_log_upper_bound(x) + 1.0 / x) * (1.0 + 1e-14); } } /* Upper or lower bound (depending on direction) for gamma(x), assuming x > 0, no overflow. */ double _arb_hypgeom_d_gamma(double x, int direction) { double s, t, p; int i, r; if (direction == 1) p = 1 + 1e-14; else p = 1 - 1e-14; if (x < 0.5) { s = d_polyval(arb_hypgeom_rgamma_d_tab, 19, x); s = 1.0 / (s * x); } else if (x <= 1.5) { s = 1.0 / d_polyval(arb_hypgeom_rgamma_d_tab, 19, x - 1.0); } else { r = (int) (x + 0.5); s = d_polyval(arb_hypgeom_rgamma_d_tab, 19, x - r); t = 1.0; for (i = 0; i < r - 1; i++) t *= (x - i - 1) * p; s = t / s; } return s * p; } /* Set res = [a, b]; not checking overflow or underflow. */ void arb_set_interval_d_fast(arb_t res, double a, double b, slong prec) { double mid, rad; if (a > b) { flint_printf("arb_set_interval_d_fast: expected a < b\n"); flint_abort(); } mid = a + 0.5 * (b - a); rad = (0.5 * (b - a) + (mid * 1e-15)) * (1 + 1e-15); arf_set_d(arb_midref(res), mid); mag_set_d(arb_radref(res), rad); arb_set_round(res, res, prec); } int _arf_increment_fast(arf_t x, slong prec); /* Try to compute gamma(x) using Taylor series. Returns 1 on success, 0 on failure (x too large or precision too large). */ int arb_hypgeom_gamma_taylor(arb_t res, const arb_t x, int reciprocal, slong prec) { double dx, dxerr, log2u, ds, du; slong i, n, wp, r, tail_bound, rad_exp, mid_exp; arf_t s, u, v; short term_prec[ARB_HYPGEOM_GAMMA_TAB_NUM]; int success; #if DEBUG printf("INPUT: "); arb_printd(x, 200); printf("\n"); printf("INPUT prec: %ld\n", prec); #endif /* We don't want to deal with infinities or huge/tiny exponents here. */ if (!ARB_IS_LAGOM(x)) return 0; /* 2^e bounds for the midpoint and radius. */ mid_exp = arf_is_zero(arb_midref(x)) ? WORD_MIN : ARF_EXP(arb_midref(x)); rad_exp = mag_is_zero(arb_radref(x)) ? WORD_MIN : MAG_EXP(arb_radref(x)); /* Containing zero. */ if (rad_exp >= mid_exp && arb_contains_zero(x)) { if (reciprocal) { arb_t t; arb_init(t); arb_add_ui(t, x, 1, prec + 10); if (!arb_contains_zero(t)) { success = arb_hypgeom_gamma_taylor(t, t, reciprocal, prec + 10); if (success) arb_mul(res, x, t, prec); } else { /* todo: accurate wide interval */ success = 0; } arb_clear(t); return success; } else { arb_indeterminate(res); return 1; } } /* Quick exclusion of too large numbers. */ if (mid_exp > 8 || rad_exp > 8) return 0; /* Adjust precision if the input is not precise. */ if (rad_exp != WORD_MIN) prec = FLINT_MIN(prec, -rad_exp + MAG_BITS); prec = FLINT_MAX(prec, 2); /* Midpoint and radius as doubles. */ dx = arf_get_d(arb_midref(x), ARF_RND_NEAR); dxerr = mag_get_d(arb_radref(x)); /* Too large to be efficient (high precision), or gamma(x) may overflow doubles (wide case). */ if (dx + dxerr > 160.0 || dx - dxerr < -160.0) return 0; /* Very close to 0, reduce to gamma(x) = gamma(x + 1) / x. */ if (mid_exp < -32 || (dx - dxerr >= -0.5 && dx - dxerr < ldexp(1.0, -6))) { arb_t t; arb_init(t); arb_add_ui(t, x, 1, prec + 10); #if DEBUG printf("DIVIDING NEAR 0\n"); #endif success = arb_hypgeom_gamma_taylor(t, t, reciprocal, prec + 10); if (success) { if (reciprocal) arb_mul(res, x, t, prec); else arb_div(res, t, x, prec); } arb_clear(t); return success; } /* Nearest (roughly) integer to x, to use as shift for argument reduction to move to the interval [-0.5,0.5]. It's OK that dx is approximate so that the reduced argument will actually lie in [-0.5-eps,0.5+eps]. */ if (dx >= 0.0) r = (slong) (dx + 0.5); else r = -(slong) (-dx + 0.5); /* Tuning cutoff. */ if (prec >= 40) { if (r < -(40 + (prec - 40) / 4)) return 0; if (r > 70 + (prec - 40) / 8) return 0; } /* For negative numbers, reduce to the positive case. */ /* gamma(x) = (-1)^r * gamma(1+x-r) / (rf(1+r-x,-r)*(x-r)) */ /* 1/gamma(x) = (-1)^r * rgamma(1+x-r) * rf(1+r-x,-r) * (x-r) */ if (dx < 0.0) { arb_t t, u, v; arb_init(t); arb_init(u); arb_init(v); arb_sub_si(t, x, r, prec + 10); /* Pole. */ if (!reciprocal && arb_contains_zero(t)) { arb_indeterminate(res); success = 1; } else { arb_add_si(u, x, 1 - r, prec + 10); success = 1; if (reciprocal && !arb_is_positive(u)) { /* todo: accurate wide interval */ success = 0; } success = arb_hypgeom_gamma_taylor(u, u, reciprocal, prec + 10); if (success) { /* Wide bounds for rising factorial. */ if (prec < 44) { double a, b, c, d; c = (-dx + r + 1 - dxerr) * (1 - 1e-14); d = (-dx + r + 1 + dxerr) * (1 + 1e-14); a = b = 1.0; for (i = 0; i < -r; i++) { a = a * ((c + i) * (1 - 1e-15)); b = b * ((d + i) * (1 + 1e-15)); } arb_set_interval_d_fast(v, a, b, 53); if (reciprocal) { arb_mul(res, u, v, prec + 10); arb_mul(res, res, t, prec); } else { arb_div(res, u, v, prec + 10); arb_div(res, res, t, prec); } } else { arb_neg(v, x); arb_add_si(v, v, 1 + r, prec + 10); arb_hypgeom_rising_ui_rec(v, v, -r, prec + 10); arb_mul(v, v, t, prec + 10); if (reciprocal) arb_mul(res, u, v, prec); else arb_div(res, u, v, prec); } if (r % 2) arb_neg(res, res); } } arb_clear(t); arb_clear(u); arb_clear(v); return success; } /* Wide enclosure. */ if (prec < 40 || rad_exp > -16) { double a, b, c; #if DEBUG printf("WIDE CASE\n"); #endif dxerr += ldexp(1.0, mid_exp - 51); dxerr *= (1 + 1e-15); a = (dx - dxerr) * (1 - 1e-15); b = (dx + dxerr) * (1 + 1e-15); if (a >= GAMMA_MIN_X) { a = _arb_hypgeom_d_gamma(a, -1); b = _arb_hypgeom_d_gamma(b, 1); } else if (b <= GAMMA_MIN_X) { c = _arb_hypgeom_d_gamma(a, 1); a = _arb_hypgeom_d_gamma(b, -1); b = c; } else { a = _arb_hypgeom_d_gamma(a, 1); b = _arb_hypgeom_d_gamma(b, 1); b = FLINT_MAX(a, b); a = GAMMA_MIN_Y * (1 - 1e-15); } if (reciprocal) { c = (1.0 / b) * (1 - 1e-15); b = (1.0 / a) * (1 + 1e-15); a = c; } arb_set_interval_d_fast(res, a, b, prec); return 1; } /* Propagated error. */ if (rad_exp == WORD_MIN) { dxerr = 0.0; rad_exp = WORD_MIN; } else { /* First-order relative error estimate plus safety factor to guarantee an upper bound. */ dxerr = MAG_MAN(arb_radref(x)) * ldexp(1.0, -MAG_BITS); dxerr = dxerr * d_abs_digamma_ubound(dx) * 1.001; } #if DEBUG flint_printf("propagated error = %g x 2^%wd\n", dxerr, rad_exp); #endif wp = prec + 6 + FLINT_BIT_COUNT(FLINT_ABS(r)); if (wp > ARB_HYPGEOM_GAMMA_TAB_PREC) return 0; success = 0; arf_init(s); arf_init(u); arf_init(v); /* u = x - r */ arf_sub_si(u, arb_midref(x), r, wp, ARF_RND_DOWN); /* du = dx - r; */ du = arf_get_d(u, ARF_RND_NEAR); /* bound log2(u) */ if (-0.0001 < du && du < 0.0001) log2u = arf_is_zero(u) ? -wp : ARF_EXP(u); else log2u = mag_d_log_upper_bound(du < 0 ? -du : du) * 1.4426950408889634074 * (1 + 1e-14); term_prec[0] = wp; n = 0; for (i = 1; i < ARB_HYPGEOM_GAMMA_TAB_NUM; i++) { tail_bound = arb_hypgeom_gamma_coeffs[i].exp + i * log2u + 5; if (tail_bound <= -wp) { n = i; break; } term_prec[i] = FLINT_MIN(FLINT_MAX(wp + tail_bound, 2), wp); } if (n == 0) { flint_printf("warning: gamma_taylor: unexpected failure\n"); success = 0; goto cleanup; } #if DEBUG printf("COMPUTATION: wp = %ld, du = %g, log2u = %g, n = %ld\n", wp, du, log2u, n); #endif if (wp <= 512 && n <= 128) { ds = 0.0; for (i = n - 1; i >= 1 && term_prec[i] <= 53; i--) { #if DEBUG flint_printf("add term %wd with precision %wd (doubles)\n", i, term_prec[i]); #endif ds = du * ds + arb_hypgeom_rgamma_d_tab[i]; } arf_set_d(s, ds); } else { i = n - 1; } for ( ; i >= 1; i--) { arf_t c; #if DEBUG flint_printf("add term %wd with precision %wd\n", i, term_prec[i]); #endif if (!_arb_hypgeom_gamma_coeff_shallow(c, NULL, i, term_prec[i])) { flint_printf("arb_hypgeom_gamma_taylor: prec = %wd, du = %g, log2u = %d, term_prec[%wd] = %wd", prec, du, log2u, i, term_prec[i]); flint_abort(); } if (term_prec[i] < wp - 128) { arf_set_round(v, u, term_prec[i], ARF_RND_DOWN); arf_mul(s, s, v, term_prec[i], ARF_RND_DOWN); arf_add(s, s, c, term_prec[i], ARF_RND_DOWN); } else { arf_mul(s, s, u, term_prec[i], ARF_RND_DOWN); arf_add(s, s, c, term_prec[i], ARF_RND_DOWN); } } if (i == 0) { #if DEBUG flint_printf("add term %wd with precision %wd\n", i, term_prec[i]); #endif arf_mul(s, s, u, wp, ARF_RND_DOWN); arf_add_ui(s, s, 1, wp, ARF_RND_DOWN); } if (r == 0 || r == 1) { if (r == 0) arf_mul(s, s, u, wp, ARF_RND_DOWN); if (reciprocal) { arf_set_round(arb_midref(res), s, prec, ARF_RND_DOWN); } else { arf_one(u); arf_div(arb_midref(res), u, s, prec, ARF_RND_DOWN); } arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec - 1); } else if (wp <= 320 || r <= 3) { _arf_increment_fast(u, wp); arf_set(v, u); for (i = 2; i < r; i++) { _arf_increment_fast(u, wp); arf_mul(v, v, u, wp, ARF_RND_DOWN); } if (reciprocal) arf_div(arb_midref(res), s, v, prec, ARF_RND_DOWN); else arf_div(arb_midref(res), v, s, prec, ARF_RND_DOWN); arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec - 1); } else { arb_t t; arb_init(t); _arf_increment_fast(u, wp); arb_set_arf(t, u); arb_hypgeom_rising_ui_rec(t, t, r - 1, wp); if (reciprocal) { arb_set_arf(res, s); arb_div(res, res, t, prec); } else arb_div_arf(res, t, s, prec); arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec - 1); arb_clear(t); } /* Add propagated error. */ if (dxerr != 0) { mag_t err; double dy; dy = arf_get_d(arb_midref(res), ARF_RND_UP); dxerr = dxerr * dy * (1 + 1e-15); MAG_SET_D_2EXP(MAG_MAN(err), MAG_EXP(err), dxerr, rad_exp); mag_add(arb_radref(res), arb_radref(res), err); } success = 1; #if DEBUG printf("OUTPUT: "); arb_printd(res, 200); printf("\n"); #endif cleanup: arf_clear(s); arf_clear(u); arf_clear(v); return success; } arb-2.22.1/arb_hypgeom/gamma_upper_fmpq.c000066400000000000000000000260371417376376500203550ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static void mag_div_fmpq(mag_t res, const mag_t x, const fmpq_t a) { mag_t t; mag_init(t); mag_set_fmpz_lower(t, fmpq_numref(a)); mag_div(res, x, t); mag_set_fmpz(t, fmpq_denref(a)); mag_mul(res, res, t); mag_clear(t); } static void mag_pow_fmpq_fast(mag_t res, const mag_t x, const fmpq_t e) { fmpz_t b; fmpz_init(b); if (mag_cmp_2exp_si(x, 0) >= 0) { fmpz_cdiv_q(b, fmpq_numref(e), fmpq_denref(e)); mag_pow_fmpz(res, x, b); } else { fmpz_fdiv_q(b, fmpq_numref(e), fmpq_denref(e)); mag_pow_fmpz(res, x, b); } fmpz_clear(b); } slong _arb_hypgeom_gamma_upper_fmpq_inf_choose_N_1(mag_t err, const fmpq_t a, const arb_t z, int prefactor, const mag_t abs_tol) { slong N, aa, ab; fmpz_t az1, az2; fmpq_t a1; mag_t t, u; fmpz_init(az1); fmpz_init(az2); fmpq_init(a1); mag_init(t); mag_init(u); fmpz_fdiv_q(az1, fmpq_numref(a), fmpq_denref(a)); fmpz_cdiv_q(az2, fmpq_numref(a), fmpq_denref(a)); if (!fmpz_fits_si(az1) || !fmpz_fits_si(az2)) { mag_inf(err); N = -1; } else { aa = fmpz_get_si(az1); ab = fmpz_get_si(az2); /* prefactor z^(a-1) * exp(-z) */ if (prefactor) { arb_get_mag_lower(t, z); mag_expinv(t, t); fmpq_sub_ui(a1, a, 1); arb_get_mag(u, z); mag_pow_fmpq_fast(u, u, a1); mag_mul(err, t, u); } else { mag_one(err); } if (mag_is_inf(err)) { N = -1; } else { arb_get_mag_lower(t, z); mag_inv(t, t); for (N = 1; ; N++) { mag_mul_ui(u, err, FLINT_MAX(FLINT_ABS(aa - N), FLINT_ABS(ab - N))); mag_mul(u, u, t); if (N >= ab - 1 && mag_cmp(u, abs_tol) < 0) { mag_swap(err, u); break; } /* Stop if terms are increasing, unless a is a positive integer in which case the series will terminate eventually. */ if (mag_cmp(u, err) > 0 && !(aa == ab && aa >= 1)) { mag_inf(err); N = -1; break; } mag_swap(err, u); } } } fmpz_clear(az1); fmpz_clear(az2); mag_clear(t); mag_clear(u); fmpq_clear(a1); return N; } slong _arb_hypgeom_gamma_upper_fmpq_inf_choose_N(mag_t err, const fmpq_t a, const arb_t z, const mag_t abs_tol) { return _arb_hypgeom_gamma_upper_fmpq_inf_choose_N_1(err, a, z, 1, abs_tol); } slong _arb_hypgeom_gamma_upper_fmpq_inf_choose_N_rel(mag_t err, const fmpq_t a, const arb_t z, slong prec) { mag_t tol; slong N; mag_init(tol); mag_set_ui_2exp_si(tol, 1, -prec); N = _arb_hypgeom_gamma_upper_fmpq_inf_choose_N_1(err, a, z, 0, tol); mag_clear(tol); return N; } static void upper_bsplit(arb_t M, arb_t S, arb_t Q, const fmpz_t ap, const fmpz_t aq, const arb_t z, slong na, slong nb, int cont, slong prec) { if (nb - na == 0) { arb_zero(M); arb_zero(S); arb_one(Q); } else if (nb - na == 1) { fmpz_t t; fmpz_init_set(t, ap); fmpz_submul_ui(t, aq, na + 1); fmpz_neg(t, t); arb_set_fmpz(M, t); arb_mul_fmpz(S, z, aq, prec); arb_neg(S, S); arb_set(Q, S); fmpz_clear(t); } else { slong m; arb_t M2, S2, Q2; m = na + (nb - na) / 2; arb_init(M2); arb_init(S2); arb_init(Q2); upper_bsplit(M, S, Q, ap, aq, z, na, m, 1, prec); upper_bsplit(M2, S2, Q2, ap, aq, z, m, nb, cont, prec); /* todo: squaring opt; power table */ arb_mul(S, S, Q2, prec); arb_addmul(S, M, S2, prec); if (cont) arb_mul(M, M, M2, prec); arb_mul(Q, Q, Q2, prec); arb_clear(M2); arb_clear(S2); arb_clear(Q2); } } void _arb_hypgeom_gamma_upper_fmpq_inf_bsplit(arb_t res, const fmpq_t a, const arb_t z, slong N, slong prec) { arb_t M, S, Q; fmpq_t a1; arb_init(M); arb_init(S); arb_init(Q); fmpq_init(a1); N = FLINT_MAX(N, 0); upper_bsplit(M, S, Q, fmpq_numref(a), fmpq_denref(a), z, 0, N, 0, prec); arb_div(S, S, Q, prec); fmpq_sub_ui(a1, a, 1); arb_pow_fmpq(M, z, a1, prec); arb_mul(S, S, M, prec); arb_neg(M, z); arb_exp(M, M, prec); arb_mul(res, S, M, prec); arb_clear(M); arb_clear(S); arb_clear(Q); fmpq_clear(a1); } /* select N and bound error for z**a * exp(-z) / a * sum(z**n / rf(a+1, n)) */ slong _arb_hypgeom_gamma_lower_fmpq_0_choose_N(mag_t err, const fmpq_t a, const arb_t z, const mag_t abs_tol) { slong N, aa, ab, c; fmpz_t az1, az2; mag_t t, u; fmpz_init(az1); fmpz_init(az2); mag_init(t); mag_init(u); fmpz_fdiv_q(az1, fmpq_numref(a), fmpq_denref(a)); fmpz_cdiv_q(az2, fmpq_numref(a), fmpq_denref(a)); if (!fmpz_fits_si(az1) || !fmpz_fits_si(az2)) { mag_inf(err); N = -1; } else { aa = fmpz_get_si(az1); ab = fmpz_get_si(az2); /* prefactor z^a * exp(-z) / a */ arb_get_mag_lower(t, z); mag_expinv(t, t); arb_get_mag(u, z); mag_pow_fmpq_fast(u, u, a); mag_mul(err, t, u); mag_div_fmpq(err, err, a); arb_get_mag(t, z); for (N = 1; ; N++) { c = FLINT_MIN(FLINT_ABS(aa + N), FLINT_ABS(ab + N)); if (c == 0) { fmpq_t q; fmpq_init(q); fmpq_add_ui(q, a, N); mag_div_fmpq(err, err, q); fmpq_clear(q); } else { mag_div_ui(err, err, c); } mag_mul(err, err, t); /* todo: condition can be relaxed */ /* todo: faster check (compare t) */ if ((aa + N) > 0 && mag_cmp(err, abs_tol) < 0) { mag_div_ui(u, t, aa + N); mag_geom_series(u, u, 0); mag_mul(u, err, u); if (mag_cmp(u, abs_tol) < 0) { mag_swap(err, u); break; } } } } fmpz_clear(az1); fmpz_clear(az2); mag_clear(t); mag_clear(u); return N; } /* todo: squaring opt; power table */ static void lower_bsplit(arb_t M, arb_t S, arb_t Q, const fmpz_t ap, const fmpz_t aq, const arb_t z, slong na, slong nb, int cont, slong prec) { if (nb - na == 0) { arb_zero(M); arb_zero(S); arb_one(Q); } else if (nb - na == 1) { fmpz_t t; fmpz_init_set(t, ap); fmpz_addmul_ui(t, aq, na + 1); arb_set_fmpz(S, t); arb_set(Q, S); arb_mul_fmpz(M, z, aq, prec); fmpz_clear(t); } else { slong m; arb_t M2, S2, Q2; m = na + (nb - na) / 2; arb_init(M2); arb_init(S2); arb_init(Q2); lower_bsplit(M, S, Q, ap, aq, z, na, m, 1, prec); lower_bsplit(M2, S2, Q2, ap, aq, z, m, nb, cont, prec); arb_mul(S, S, Q2, prec); arb_addmul(S, M, S2, prec); if (cont) arb_mul(M, M, M2, prec); arb_mul(Q, Q, Q2, prec); arb_clear(M2); arb_clear(S2); arb_clear(Q2); } } void _arb_hypgeom_gamma_lower_fmpq_0_bsplit(arb_t res, const fmpq_t a, const arb_t z, slong N, slong prec) { arb_t M, S, Q; arb_init(M); arb_init(S); arb_init(Q); N = FLINT_MAX(N, 0); lower_bsplit(M, S, Q, fmpq_numref(a), fmpq_denref(a), z, 0, N, 0, prec); arb_div(S, S, Q, prec); arb_pow_fmpq(M, z, a, prec); arb_mul(S, S, M, prec); arb_neg(M, z); arb_exp(M, M, prec); arb_mul(S, S, M, prec); arb_div_fmpz(S, S, fmpq_numref(a), prec); arb_mul_fmpz(res, S, fmpq_denref(a), prec); arb_clear(M); arb_clear(S); arb_clear(Q); } /* bounded by 1/z^n * sum z^k / k! */ slong _arb_hypgeom_gamma_upper_singular_si_choose_N(mag_t err, slong n, const arb_t z, const mag_t abs_tol) { slong k; mag_t t, u, zm; mag_init(t); mag_init(u); mag_init(zm); arb_get_mag(zm, z); arb_get_mag_lower(t, z); mag_inv(t, t); mag_pow_ui(t, t, n); for (k = 1; ; k++) { mag_mul(t, t, zm); mag_div_ui(t, t, k); if (mag_cmp(t, abs_tol) < 0) { mag_div_ui(u, zm, k); mag_geom_series(u, u, 0); mag_mul(u, t, u); if (mag_cmp(u, abs_tol) < 0) { mag_swap(err, t); break; } } } mag_clear(t); mag_clear(u); mag_clear(zm); return k; } static void singular_bsplit(arb_t M, arb_t S, arb_t Q, slong n, const arb_t z, slong na, slong nb, int cont, slong prec) { if (nb - na == 0) { arb_zero(M); arb_zero(S); arb_one(Q); } else if (nb - na == 1) { fmpz_t t; slong k; k = na; if (k == n) arb_neg(M, z); else arb_mul_si(M, z, n - k, prec); arb_set_si(S, (k != n) ? (k + 1) : 0); fmpz_init_set_si(t, k + 1); if (k != n) fmpz_mul_si(t, t, k - n); arb_set_fmpz(Q, t); fmpz_clear(t); } else { slong m; arb_t M2, S2, Q2; m = na + (nb - na) / 2; arb_init(M2); arb_init(S2); arb_init(Q2); singular_bsplit(M, S, Q, n, z, na, m, 1, prec); singular_bsplit(M2, S2, Q2, n, z, m, nb, cont, prec); arb_mul(S, S, Q2, prec); arb_addmul(S, M, S2, prec); if (cont) arb_mul(M, M, M2, prec); arb_mul(Q, Q, Q2, prec); arb_clear(M2); arb_clear(S2); arb_clear(Q2); } } void _arb_hypgeom_gamma_upper_singular_si_bsplit(arb_t res, slong n, const arb_t z, slong N, slong prec) { arb_t M, S, Q; arb_init(M); arb_init(S); arb_init(Q); N = FLINT_MAX(N, 0); singular_bsplit(M, S, Q, n, z, 0, N, 0, prec); /* (-1)**n/fac(n) * (digamma(n+1) - ln(z)) - (S/Q)/z**n */ arb_pow_ui(M, z, n, prec); arb_mul(Q, Q, M, prec); arb_div(S, S, Q, prec); arb_set_ui(M, n + 1); arb_digamma(M, M, prec); arb_log(Q, z, prec); arb_sub(M, M, Q, prec); arb_fac_ui(Q, n, prec); arb_div(M, M, Q, prec); if (n & 1) arb_neg(M, M); arb_sub(res, M, S, prec); arb_clear(M); arb_clear(S); arb_clear(Q); } arb-2.22.1/arb_hypgeom/gamma_upper_fmpq_step_bsplit.c000066400000000000000000000171711417376376500227640ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" #include "arb_hypgeom.h" static void taylor_M(mag_t M, const arb_t a, const arb_t z, const mag_t x, slong Rexp) { arb_t t, u; arb_init(t); arb_init(u); arb_sub_ui(u, a, 1, 53); arb_sgn(t, u); arb_mul_2exp_si(t, t, Rexp); arb_add(t, z, t, 53); arb_pow(t, t, u, 53); arb_one(u); arb_mul_2exp_si(u, u, Rexp); arb_sub(u, u, z, 53); arb_exp(u, u, 53); arb_mul(t, t, u, 53); arb_get_mag(M, t); arb_clear(t); arb_clear(u); } /* choose N such that M * C^N / (1 - C) <= tol */ /* todo: fix */ static slong mag_geom_choose_N(const mag_t M, const mag_t C, const mag_t tol) { mag_t t, u; slong N; if (mag_is_finite(M) && mag_is_zero(C)) return 1; /* N = log(M / ((1 - C) tol)) / log(1/C) */ mag_init(t); mag_init(u); mag_one(t); mag_sub_lower(t, t, C); mag_mul_lower(t, t, tol); mag_div(t, M, t); mag_log(t, t); mag_inv_lower(u, C); mag_log_lower(u, u); mag_div(t, t, u); N = ceil(mag_get_d(t)); N = FLINT_MAX(N, 1); mag_clear(t); mag_clear(u); return N; } static void taylor_bound(mag_t err, const arb_t a, const arb_t z, const mag_t x, slong Rexp, slong N) { mag_t C, M; mag_init(C); mag_init(M); /* C = x / R */ mag_mul_2exp_si(C, x, -Rexp); /* M R C^n / (1 - C) / N */ mag_geom_series(err, C, N); if (!mag_is_inf(err)) { taylor_M(M, a, z, x, Rexp); mag_mul(err, err, M); mag_mul_2exp_si(err, err, Rexp); mag_div_ui(err, err, N); } mag_clear(C); mag_clear(M); } static slong taylor_N(const arb_t a, const arb_t z, const mag_t x, slong Rexp, const mag_t abs_tol) { mag_t C, M; slong N; mag_init(C); mag_init(M); /* C = x / R */ mag_mul_2exp_si(C, x, -Rexp); if (mag_cmp_2exp_si(C, 0) < 0) { taylor_M(M, a, z, x, Rexp); mag_mul_2exp_si(M, M, Rexp); N = mag_geom_choose_N(M, C, abs_tol); } else { N = WORD_MAX; } mag_clear(C); mag_clear(M); return N; } static void arb_hypgeom_gamma_upper_taylor_choose(slong * res_N, mag_t err, const arb_t a, const arb_t z, const mag_t x, const mag_t abs_tol) { slong N, New; mag_t zlow; slong Rexp; mag_init(zlow); arb_get_mag_lower(zlow, z); Rexp = 0; while (mag_cmp_2exp_si(zlow, Rexp + 1) < 0) Rexp--; N = taylor_N(a, z, x, Rexp, abs_tol); while (N > 1 && mag_cmp_2exp_si(x, Rexp - 1) < 0) { New = taylor_N(a, z, x, Rexp - 1, abs_tol); if (New <= N) { Rexp = Rexp - 1; N = New; } else { break; } } if (Rexp == 0) { while (N > 1 && mag_cmp_2exp_si(zlow, Rexp + 1) > 0) { New = taylor_N(a, z, x, Rexp + 1, abs_tol); if (New <= N) { Rexp = Rexp + 1; N = New; } else { break; } } } *res_N = N; taylor_bound(err, a, z, x, Rexp, N); if (mag_cmp(err, abs_tol) > 0) { printf("err = "); mag_printd(err, 10); printf("\n"); printf("abs_tol = "); mag_printd(abs_tol, 10); printf("\n"); printf("a = "); arb_printd(a, 10); printf("\n"); printf("z = "); arb_printd(z, 10); printf("\n"); printf("x = "); mag_printd(x, 10); printf("\n"); flint_abort(); } mag_clear(zlow); } static void gamma_upper_taylor_bsplit(arb_mat_t M, arb_t Q, const fmpz_t ap, const fmpz_t aq, const arb_t z0, const arb_t x, const arb_t x2, slong a, slong b, int cont, slong prec) { if (b - a == 0) { arb_mat_one(M); } else if (b - a == 1) { slong n; fmpz_t t; n = a; fmpz_init(t); /* Q = -z0*(n+1)*(n+2)*aq */ fmpz_mul2_uiui(t, aq, n + 1, n + 2); arb_mul_fmpz(Q, z0, t, prec); arb_neg(Q, Q); /* x Q */ arb_mul(arb_mat_entry(M, 0, 1), Q, x, prec); /* aq n x */ fmpz_mul_ui(t, aq, n); arb_mul_fmpz(arb_mat_entry(M, 1, 0), x, t, prec); /* x*(-ap + aq*(n + z0 + 1))*(n + 1) */ arb_add_ui(arb_mat_entry(M, 1, 1), z0, n + 1, prec); arb_mul_fmpz(arb_mat_entry(M, 1, 1), arb_mat_entry(M, 1, 1), aq, prec); arb_sub_fmpz(arb_mat_entry(M, 1, 1), arb_mat_entry(M, 1, 1), ap, prec); arb_mul_ui(arb_mat_entry(M, 1, 1), arb_mat_entry(M, 1, 1), n + 1, prec); arb_mul(arb_mat_entry(M, 1, 1), arb_mat_entry(M, 1, 1), x, prec); arb_set(arb_mat_entry(M, 2, 0), Q); arb_set(arb_mat_entry(M, 2, 2), Q); fmpz_clear(t); } else { arb_mat_t M1, M2; arb_t Q2; slong m; arb_mat_init(M1, 3, 3); arb_mat_init(M2, 3, 3); arb_init(Q2); m = a + (b - a) / 2; gamma_upper_taylor_bsplit(M1, Q, ap, aq, z0, x, x2, a, m, 1, prec); gamma_upper_taylor_bsplit(M2, Q2, ap, aq, z0, x, x2, m, b, cont, prec); if (cont) { arb_mat_mul(M, M2, M1, prec); } else { arb_mat_transpose(M1, M1); arb_dot(arb_mat_entry(M, 2, 0), NULL, 0, arb_mat_entry(M1, 0, 0), 1, arb_mat_entry(M2, 2, 0), 1, 3, prec); arb_dot(arb_mat_entry(M, 2, 1), NULL, 0, arb_mat_entry(M1, 1, 0), 1, arb_mat_entry(M2, 2, 0), 1, 3, prec); arb_dot(arb_mat_entry(M, 2, 2), NULL, 0, arb_mat_entry(M1, 2, 0), 1, arb_mat_entry(M2, 2, 0), 1, 3, prec); } arb_mul(Q, Q2, Q, prec); arb_mat_clear(M1); arb_mat_clear(M2); arb_clear(Q2); } } /* Given Gz0 = Gamma(a, z0) and expmz0 = exp(-z0), compute Gz1 = Gamma(a, z1) */ void _arb_gamma_upper_fmpq_step_bsplit(arb_t Gz1, const fmpq_t a, const arb_t z0, const arb_t z1, const arb_t Gz0, const arb_t expmz0, const mag_t abs_tol, slong prec) { arb_t x, Q, a_real; arb_mat_t M; mag_t xmag, err; slong N; fmpq_t a1; if (arb_is_zero(z0)) { mag_init(err); arb_init(x); N = _arb_hypgeom_gamma_lower_fmpq_0_choose_N(err, a, z1, abs_tol); _arb_hypgeom_gamma_lower_fmpq_0_bsplit(Gz1, a, z1, N, prec); arb_add_error_mag(Gz1, err); arb_sub(Gz1, Gz0, Gz1, prec); arb_clear(x); mag_clear(err); return; } mag_init(xmag); mag_init(err); arb_init(x); arb_init(Q); arb_init(a_real); fmpq_init(a1); arb_mat_init(M, 3, 3); arb_sub(x, z1, z0, prec); arb_get_mag(xmag, x); arb_set_fmpq(a_real, a, 53); arb_hypgeom_gamma_upper_taylor_choose(&N, err, a_real, z0, xmag, abs_tol); gamma_upper_taylor_bsplit(M, Q, fmpq_numref(a), fmpq_denref(a), z0, x, NULL, 0, N, 0, prec); arb_mul(arb_mat_entry(M, 2, 0), arb_mat_entry(M, 2, 0), Gz0, prec); fmpq_sub_ui(a1, a, 1); arb_pow_fmpq(arb_mat_entry(M, 0, 0), z0, a1, prec); arb_mul(arb_mat_entry(M, 0, 0), arb_mat_entry(M, 0, 0), expmz0, prec); arb_submul(arb_mat_entry(M, 2, 0), arb_mat_entry(M, 2, 1), arb_mat_entry(M, 0, 0), prec); arb_div(Gz1, arb_mat_entry(M, 2, 0), Q, prec); arb_add_error_mag(Gz1, err); mag_clear(xmag); mag_clear(err); arb_clear(x); arb_clear(Q); arb_clear(a_real); fmpq_clear(a1); arb_mat_clear(M); } arb-2.22.1/arb_hypgeom/gamma_upper_integration.c000066400000000000000000000022071417376376500217260ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_gamma_upper_integration(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec) { arb_t t, u; arb_init(t); arb_init(u); arb_one(t); arb_add_ui(u, s, 1, prec); arb_hypgeom_u_integration(u, t, u, z, prec); if (arb_is_finite(u)) { if (regularized != 2) { arb_pow(t, z, s, prec); arb_mul(u, u, t, prec); if (regularized == 1) { arb_rgamma(t, s, prec); arb_mul(u, u, t, prec); } } arb_neg(t, z); arb_exp(t, t, prec); arb_mul(res, t, u, prec); } else { arb_indeterminate(res); } arb_clear(t); arb_clear(u); } arb-2.22.1/arb_hypgeom/gamma_upper_series.c000066400000000000000000000051231417376376500206750ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "arb_hypgeom.h" void _arb_hypgeom_gamma_upper_series(arb_ptr g, const arb_t s, arb_srcptr h, slong hlen, int regularized, slong n, slong prec) { arb_t c; arb_init(c); arb_hypgeom_gamma_upper(c, s, h, regularized, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _arb_vec_zero(g + 1, n - 1); } else { arb_ptr t, u, v; arb_ptr w = NULL; t = _arb_vec_init(n); u = _arb_vec_init(n); v = _arb_vec_init(n); if (regularized == 2) { w = _arb_vec_init(n); arb_neg(t, s); _arb_poly_pow_arb_series(w, h, hlen, t, n, prec); } /* Gamma(s, h(x)) = -integral(h'(x) h(x)^(s-1) exp(-h(x)) */ arb_sub_ui(u, s, 1, prec); _arb_poly_pow_arb_series(t, h, hlen, u, n, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(v, t, n, u, hlen - 1, n, prec); _arb_vec_neg(t, h, hlen); _arb_poly_exp_series(t, t, hlen, n, prec); _arb_poly_mullow(g, v, n, t, n, n, prec); _arb_poly_integral(g, g, n, prec); _arb_vec_neg(g, g, n); if (regularized == 1) { arb_rgamma(t, s, prec); _arb_vec_scalar_mul(g, g, n, t, prec); } else if (regularized == 2) { _arb_vec_set(u, g, n); _arb_poly_mullow(g, u, n, w, n, n, prec); _arb_vec_clear(w, n); } _arb_vec_clear(t, n); _arb_vec_clear(u, n); _arb_vec_clear(v, n); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_gamma_upper_series(arb_poly_t g, const arb_t s, const arb_poly_t h, int regularized, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, n); if (hlen == 0) { arb_t t; arb_init(t); _arb_hypgeom_gamma_upper_series(g->coeffs, s, t, 1, regularized, n, prec); arb_clear(t); } else { _arb_hypgeom_gamma_upper_series( g->coeffs, s, h->coeffs, hlen, regularized, n, prec); } _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/gamma_upper_sum_rs.c000066400000000000000000000062741417376376500207230ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static slong asymp_prec(slong k, double logdz, slong prec) { double gain; if (prec <= 128) return prec; if (k <= 5) return prec; gain = (k * logdz - (k * (log(k) - 1.0))) * 1.4426950408889634 - 4; gain = FLINT_MAX(gain, 0); prec = prec - gain; prec = FLINT_MAX(prec, 32); return prec; } void _arb_hypgeom_gamma_upper_sum_rs_1(arb_t res, ulong p, ulong q, const arb_t z, slong N, slong prec) { slong m, i, j, k, jlen, jbot, jtop, wp; double dz, logdz; mp_limb_t c, chi, clo; arb_t s, t; arb_ptr zpow; mp_ptr cs; m = n_sqrt(N); m = FLINT_MAX(m, 2); k = N - 1; j = k % m; jlen = 0; jbot = j; if (arf_cmpabs_2exp_si(arb_midref(z), prec) >= 0) { logdz = ARF_EXP(arb_midref(z)) * log(2); } else if (arf_cmpabs_2exp_si(arb_midref(z), -32) >= 0) { dz = arf_get_d(arb_midref(z), ARF_RND_UP); dz = fabs(dz); logdz = log(dz); } else if (arf_cmpabs_2exp_si(arb_midref(z), -prec) <= 0) { logdz = -prec * log(2); } else { logdz = ARF_EXP(arb_midref(z)) * log(2); } arb_init(s); arb_init(t); zpow = _arb_vec_init(m + 1); cs = flint_malloc(sizeof(mp_limb_t) * (m + 1)); arb_mul_ui(zpow + m, z, q, prec); arb_inv(zpow + m, zpow + m, prec); _arb_vec_set_powers(zpow, zpow + m, m + 1, prec); while (k >= 0) { /* Find run of coefficients whose product fits in a limb */ jlen = 1; jtop = jbot = k; if (jtop > 0) { c = p + q * (jtop - 1); while (jlen <= j) { if (jbot >= 2) { umul_ppmm(chi, clo, c, p + q * (jbot - 2)); if (chi != 0) break; c = clo; } jbot--; jlen++; } } if (jbot != jtop - jlen + 1) abort(); /* Factors between jbot and jtop inclusive */ if (jbot == 0) cs[0] = 1; else cs[0] = p + q * (jbot - 1); for (i = 1; i < jlen; i++) cs[i] = cs[i - 1] * (p + q * (jbot + i - 1)); wp = asymp_prec(k - jlen, logdz, prec); /* todo: special case jlen == 1 */ arb_add(t, s, zpow + j, wp); arb_swap(zpow + j, t); arb_dot_ui(s, NULL, 0, zpow + j - jlen + 1, 1, cs, 1, jlen, wp); arb_swap(zpow + j, t); k -= jlen; j -= (jlen - 1); if (j == 0 && k >= 1) { arb_mul(s, s, zpow + m, wp); j = m - 1; } else { j--; } } arb_swap(res, s); _arb_vec_clear(zpow, m + 1); arb_clear(s); arb_clear(t); flint_free(cs); } arb-2.22.1/arb_hypgeom/legendre_p.c000066400000000000000000000023751417376376500171400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void arb_hypgeom_legendre_p(arb_t res, const arb_t n, const arb_t m, const arb_t z, int type, slong prec) { if (arb_is_zero(m) && arb_is_int(n) && arf_sgn(arb_midref(n)) >= 0 && arf_cmpabs_2exp_si(arb_midref(n), FLINT_BITS - 1) < 0) { arb_hypgeom_legendre_p_ui(res, NULL, arf_get_si(arb_midref(n), ARF_RND_DOWN), z, prec); } else { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), n); arb_set(acb_realref(u), m); arb_set(acb_realref(v), z); acb_hypgeom_legendre_p(t, t, u, v, type, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } } arb-2.22.1/arb_hypgeom/legendre_p_ui.c000066400000000000000000000323721417376376500176350ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" /* todo: improve for small k */ static double log2_bin_uiui_fast(ulong n, ulong k) { static const float htab[] = {0.2007, 0.3374, 0.4490, 0.5437, 0.6254, 0.6963, 0.7580, 0.8114, 0.8572, 0.8961, 0.9285, 0.9545, 0.9746, 0.9888, 0.9973, 1.0}; if (k == 0 || k >= n) return 0; if (k > n / 2) k = n - k; k = (32.0 * k) / n; return n * htab[FLINT_MIN(k, 15)]; } /* x is unused but part of the API */ void arb_hypgeom_legendre_p_ui_deriv_bound(mag_t dp, mag_t dp2, ulong n, const arb_t x, const arb_t x2sub1) { mag_t c, t, u; mag_init(c); mag_init(t); mag_init(u); arb_get_mag_lower(t, x2sub1); mag_rsqrt(t, t); /* t >= 1/(1-x^2)^(1/2) */ mag_mul_ui(u, t, n); /* u >= n/(1-x^2)^(1/2) */ mag_set_ui_2exp_si(c, 409, -8); /* c >= 2^(3/2)/sqrt(pi) */ mag_sqrt(dp, u); mag_mul(dp, dp, t); mag_mul(dp, dp, c); /* dp >= c*sqrt(n)/(1-x^2)^(3/4) */ mag_mul(dp2, dp, u); mag_mul_2exp_si(dp2, dp2, 1); /* dp2 >= 2*c*n^(3/2)/(1-x^2)^(5/4) */ mag_set_ui(t, n); mag_add_ui(t, t, 1); mag_mul(t, t, t); /* t >= (n+1)^2 */ mag_mul_2exp_si(u, t, -1); /* u >= (n+1)^2/2 */ mag_min(dp, dp, u); /* |P'(x)| <= dp */ mag_mul(t, t, t); mag_mul_2exp_si(u, t, -3); mag_min(dp2, dp2, u); /* |P''(x)| <= dp2 */ mag_clear(c); mag_clear(t); mag_clear(u); } void arb_hypgeom_legendre_p_ui(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong prec) { arb_t xsub1, x2sub1; double xx, xxsub1, cancellation_zero, cancellation_one; double cost_zero, cost_one, cost_asymp; double log2x, log2u, tolerance, asymp_error; double yy, log2nsy, log2k, size; slong wp; slong d, k, K_zero, K_one, K_asymp; int basecase_ok; if (!arb_is_finite(x) || n > UWORD_MAX / 4) { if (res != NULL) arb_indeterminate(res); if (res_prime != NULL) arb_indeterminate(res_prime); return; } if (arf_sgn(arb_midref(x)) < 0) { arb_t t; arb_init(t); arb_neg(t, x); arb_hypgeom_legendre_p_ui(res, res_prime, n, t, prec); if (n % 2 == 1 && res != NULL) arb_neg(res, res); if (n % 2 == 0 && res_prime != NULL) arb_neg(res_prime, res_prime); arb_clear(t); return; } if (arb_is_one(x) && n < UWORD_MAX) { if (res != NULL) arb_set(res, x); if (res_prime != NULL) { arb_set_ui(res_prime, n); arb_mul_ui(res_prime, res_prime, n + 1, prec); arb_mul_2exp_si(res_prime, res_prime, -1); } return; } if (n == 0) { if (res != NULL) arb_one(res); if (res_prime != NULL) arb_zero(res_prime); return; } if (n == 1) { if (res != NULL) arb_set_round(res, x, prec); if (res_prime != NULL) arb_one(res_prime); return; } xx = arf_get_d(arb_midref(x), ARF_RND_UP); /* Use basecase recurrence? */ /* The following tests are not very elegant, and not completely accurate either, but they are fast in the common case. */ if (res_prime != NULL) { basecase_ok = ((xx < 0.999999 && n < 10 && prec < 2000) || (xx < 0.999999 && n < 50 && prec < 1000) || (xx < 0.9999 && n < 100 && prec < 1000) || (xx < 0.999 && n < 350 && prec < 1000) || (xx < 0.9 && n < 400 && prec < 1000)) && ((xx > 0.00001 && n < 10 && prec < 2000) || (xx > 0.00001 && n < 60 && prec < 1000) || (xx > 0.01 && n < 200 && prec < 1000) || (xx > 0.1 && n < 400 && prec < 1000)); /* the recurrence also performs better when n ~= prec */ if (!basecase_ok) basecase_ok = (xx > 0.1 && xx < 0.99 && n < 800 && prec > 0.4 * n && prec < 1.5 * n); } else if (prec < 500) { basecase_ok = ((xx < 0.999999 && n < 20) || (xx < 0.999 && n < 60) || (xx < 0.9 && n < 100)) && ((xx > 0.00001 && n < 20) || (xx > 0.01 && n < 60) || (xx > 0.1 && n < 100)); if (!basecase_ok) basecase_ok = (xx > 0.1 && xx < 0.99 && n < 300 && prec > 0.4 * n && prec < 1.5 * n); } else { basecase_ok = 0; } if (basecase_ok) { mag_t t; mag_init(t); arb_get_mag(t, x); if (mag_cmp_2exp_si(t, 0) >= 0) basecase_ok = 0; mag_clear(t); } if (basecase_ok) { arb_hypgeom_legendre_p_ui_rec(res, res_prime, n, x, prec); return; } arb_init(xsub1); arb_init(x2sub1); arb_sub_ui(xsub1, x, 1, prec + 10); arb_mul(x2sub1, x, x, 2 * prec); arb_sub_ui(x2sub1, x2sub1, 1, prec + 10); arb_neg(x2sub1, x2sub1); /* use series at 1 unless |x| < 1-eps */ if (!arb_is_negative(xsub1) || arf_cmp_d(arb_midref(xsub1), ldexp(1.0, -2 * FLINT_BIT_COUNT(n))) > 0) { if (arf_cmp_d(arb_midref(xsub1), 2.0) >= 0) { if (n < 10000.0 * prec && n < UWORD_MAX / 4) K_one = n + 1; else K_one = 1; } else /* check for early convergence */ { xxsub1 = arf_get_d(arb_midref(xsub1), ARF_RND_UP); log2u = log(fabs(xxsub1) * 0.5) * 1.44269504088896; if (log2u < -30) log2u = arf_abs_bound_lt_2exp_si(arb_midref(xsub1)) - 1.0; K_one = n + 1; K_one = FLINT_MIN(K_one, 100000.0 * prec); K_one = FLINT_MIN(K_one, UWORD_MAX * 0.25); size = 0.0; if (n * (2.0 + log2u) < -prec) { for (k = 1; k < K_one; k = FLINT_MAX(k+1, k*1.05)) { size = log2_bin_uiui_fast(n, k) + log2_bin_uiui_fast(n + k, k) + k * log2u; if (size < -prec) { K_one = k; break; } } } } arb_hypgeom_legendre_p_ui_one(res, res_prime, n, x, K_one, prec); } else /* guaranteed to have |x| < 1 */ { cost_zero = 1e100; cost_one = 1e100; cost_asymp = 1e100; xx = FLINT_MAX(xx, 1e-50); xxsub1 = arf_get_d(arb_midref(xsub1), ARF_RND_UP); /* Estimate cancellation for series expansion at 0. */ /* |P_n(xi)| ~= (x+sqrt(1+x^2))^n. */ cancellation_zero = n * log(xx + sqrt(1.0 + xx * xx)) * 1.44269504088896; cancellation_zero = FLINT_MIN(cancellation_zero, 1.272 * n); cancellation_zero = FLINT_MAX(cancellation_zero, 0.0); /* Estimate cancellation for series expansion at 1. */ /* For x >= 1, P_n(x) ~= I_0(n*sqrt(2(x-1))) ~= exp(n*sqrt(2(x-1))) */ if (xxsub1 >= 0.0) { cancellation_one = 0.0; } else { cancellation_one = n * sqrt(2.0*fabs(xxsub1)) * 1.44269504088896; cancellation_one = FLINT_MIN(cancellation_one, 2.0 * n); cancellation_one = FLINT_MAX(cancellation_one, 0.0); } d = n / 2; K_zero = d + 1; K_one = n + 1; K_asymp = 1; asymp_error = 0.0; wp = 1.01 * prec + FLINT_BIT_COUNT(n); tolerance = -wp; /* adjust for relative tolerance near 0 */ if (n % 2) { tolerance += arf_abs_bound_lt_2exp_si(arb_midref(x)); } if (n > 10) { /* look for early truncation of series at 1 */ log2u = log(fabs(xxsub1) * 0.5) * 1.44269504088896; if (log2u < -30) log2u = arf_abs_bound_lt_2exp_si(arb_midref(xsub1)) - 1.0; log2x = log(fabs(xx)) * 1.44269504088896; if (log2x < -30) log2x = arf_abs_bound_lt_2exp_si(arb_midref(x)); if (n * (2.0 + log2u) < tolerance) { for (k = 1; k < K_one; k = FLINT_MAX(k+1, k*1.05)) { size = log2_bin_uiui_fast(n, k) + log2_bin_uiui_fast(n + k, k) + k * log2u; if (size < tolerance) { K_one = k; break; } } } /* look for early truncation of series at 0 */ if (n * (1.0 + log2x) < tolerance) { for (k = 1; k < K_zero; k = FLINT_MAX(k+1, k*1.05)) { size = log2_bin_uiui_fast(n, d - k) + log2_bin_uiui_fast(n+1+2*k, n) - n + 2.0 * k * log2x; if (size < tolerance) { K_zero = k; break; } } } /* look for possible convergence of asymptotic series */ /* requires information about y = sqrt(1-x^2) */ yy = arf_get_d(arb_midref(x2sub1), ARF_RND_DOWN); yy = sqrt(FLINT_MAX(0.0, yy)); log2nsy = log(2.0 * n * yy) * 1.44269504088896; cost_zero = (prec + cancellation_zero) * K_zero; cost_one = (prec + cancellation_one) * K_one; for (k = 1; k < n && prec * k < FLINT_MIN(cost_zero, cost_one); k = FLINT_MAX(k + 1, k * 1.05)) { /* todo: better account for prefactor in the asymptotic series? */ log2k = log(k) * 1.44269504088896; size = 3.0 + k * (log2k - 1.43); /* estimate K! */ size -= k * log2nsy; /* 1/(2n sin(theta))^K */ if (size < asymp_error) { asymp_error = size; K_asymp = k; } if (size < tolerance) { break; } } } cost_zero = (prec + cancellation_zero) * K_zero; cost_one = (prec + cancellation_one) * K_one; cost_asymp = (prec + 0.0) * K_asymp * 2.0; #if 0 printf("zero: K = %ld, cost = %g, cancel %g\n", K_zero, cost_zero, cancellation_zero); printf("one: K = %ld, cost = %g, cancel %g\n", K_one, cost_one, cancellation_one); printf("asymp: K = %ld, cost = %g, error = %f (tol = %f)\n", K_asymp, cost_asymp, asymp_error, tolerance); #endif if (asymp_error < tolerance && cost_asymp < FLINT_MIN(cost_zero, cost_one)) { arb_hypgeom_legendre_p_ui_asymp(res, res_prime, n, x, K_asymp, wp); } else if (FLINT_MIN(cost_zero, cost_one) < (1e6 * prec) * prec && n < UWORD_MAX / 4) { mag_t err1, err2, xrad; arb_t xmid; mag_init(err1); mag_init(err2); mag_init(xrad); arb_init(xmid); arf_set(arb_midref(xmid), arb_midref(x)); mag_zero(arb_radref(xmid)); mag_set(xrad, arb_radref(x)); arb_hypgeom_legendre_p_ui_deriv_bound(err1, err2, n, x, x2sub1); if (cost_zero < cost_one) arb_hypgeom_legendre_p_ui_zero(res, res_prime, n, xmid, K_zero, wp + cancellation_zero); else arb_hypgeom_legendre_p_ui_one(res, res_prime, n, xmid, K_one, wp + cancellation_one); if (res != NULL) { mag_mul(err1, err1, xrad); arb_add_error_mag(res, err1); arb_set_round(res, res, prec); } if (res_prime != NULL) { mag_mul(err2, err2, xrad); arb_add_error_mag(res_prime, err2); arb_set_round(res_prime, res_prime, prec); } mag_clear(err1); mag_clear(err2); mag_clear(xrad); arb_clear(xmid); } else if (asymp_error < -2.0) { /* todo -- clamp to [-1,1]? */ arb_hypgeom_legendre_p_ui_asymp(res, res_prime, n, x, K_asymp, wp); } else { if (res != NULL) { arf_zero(arb_midref(res)); mag_one(arb_radref(res)); } if (res_prime != NULL) { arf_zero(arb_midref(res_prime)); mag_set_ui(arb_radref(res_prime), n); mag_add_ui(arb_radref(res_prime), arb_radref(res_prime), 1); mag_mul_ui(arb_radref(res_prime), arb_radref(res_prime), n); mag_mul_2exp_si(arb_radref(res_prime), arb_radref(res_prime), -1); } } } arb_clear(xsub1); arb_clear(x2sub1); } arb-2.22.1/arb_hypgeom/legendre_p_ui_asymp.c000066400000000000000000000177541417376376500210550ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #define UNROLL 4 static void asymp_series(acb_t res, ulong n, acb_srcptr xpow, slong m, slong K, slong prec) { slong j, k, khi, klo, u, r; fmpz * c; acb_t s; acb_init(s); c = _fmpz_vec_init(UNROLL + 1); k = K - 1; while (k >= 1) { u = FLINT_MIN(UNROLL, k); khi = k; klo = k - u + 1; for (j = klo; j <= khi; j++) { ulong aa = (2 * j - 1); ulong bb = (2 * j - 1); if (j == klo) fmpz_ui_mul_ui(c + khi - j, aa, bb); else fmpz_mul2_uiui(c + khi - j, c + khi - j + 1, aa, bb); } for (j = khi; j >= klo; j--) { ulong aa = (j); ulong bb = (2 * j + 2 * n + 1); if (n < UWORD_MAX / 8) { if (j == khi) { fmpz_ui_mul_ui(c + u, aa, bb); } else { fmpz_mul(c + khi - j, c + khi - j, c + u); fmpz_mul2_uiui(c + u, c + u, aa, bb); } } else { fmpz_t t; fmpz_init(t); fmpz_set_ui(t, n); fmpz_add_ui(t, t, j); fmpz_mul_2exp(t, t, 1); fmpz_add_ui(t, t, 1); if (j == khi) { fmpz_mul_ui(c + u, t, aa); } else { fmpz_mul(c + khi - j, c + khi - j, c + u); fmpz_mul_ui(t, t, aa); fmpz_mul(c + u, c + u, t); } fmpz_clear(t); } } while (k >= klo) { r = k % m; if (k == khi) { acb_add(s, s, xpow + r, prec); acb_mul_fmpz(s, s, c + khi - k, prec); } else if (r == 0) { acb_add_fmpz(s, s, c + khi - k, prec); } else { acb_addmul_fmpz(s, xpow + r, c + khi - k, prec); } if (r == 0 && k != 0) acb_mul(s, s, xpow + m, prec); k--; } acb_div_fmpz(s, s, c + u, prec); } acb_add_ui(res, s, 1, prec); acb_clear(s); _fmpz_vec_clear(c, UNROLL + 1); } /* error: 0.50795 / (y^K sqrt(ny)) * [K! n! / (2^K (n+K)!)] */ /* [K! / (2n)^K] */ static void _arb_hypgeom_legendre_p_ui_asymp_error(mag_t res, ulong n, const mag_t y, slong K) { mag_t t, u; mag_init(t); mag_init(u); /* t = K! / (y^K sqrt(ny)) */ mag_mul_ui_lower(t, y, n); mag_sqrt_lower(t, t); mag_pow_ui_lower(u, y, K); mag_mul_lower(t, t, u); mag_fac_ui(u, K); mag_div(t, u, t); if (K < n / 16) { /* (2n)^K */ mag_set_ui_lower(u, n); mag_mul_2exp_si(u, u, 1); mag_pow_ui_lower(u, u, K); mag_div(t, t, u); } else { /* n! */ mag_fac_ui(u, n); mag_mul(t, t, u); /* (n+K)! */ mag_rfac_ui(u, n + K); mag_mul(t, t, u); /* 2^K */ mag_mul_2exp_si(t, t, -K); } mag_mul_ui(t, t, 131); mag_mul_2exp_si(t, t, -8); mag_set(res, t); mag_clear(t); mag_clear(u); } int arb_abs_le_ui(const arb_t x, ulong n) { arf_struct u[3]; arf_t t; int res; if (!arb_is_finite(x) || arf_cmpabs_ui(arb_midref(x), n) > 0) return 0; if (arb_is_exact(x)) return 1; if (arf_sgn(arb_midref(x)) >= 0) arf_init_set_shallow(u + 0, arb_midref(x)); else arf_init_neg_shallow(u + 0, arb_midref(x)); arf_init_set_mag_shallow(u + 1, arb_radref(x)); arf_init(u + 2); /* no need to free */ arf_set_ui(u + 2, n); arf_neg(u + 2, u + 2); arf_init(t); arf_sum(t, u, 3, MAG_BITS, ARF_RND_DOWN); res = (arf_sgn(t) < 0); arf_clear(t); return res; } void _arb_hypgeom_legendre_p_ui_asymp(arb_t res, ulong n, const arb_t x, const arb_t y, acb_srcptr w4pow, const arb_t binom, slong m, slong K, slong prec) { arb_t t, u; acb_t s, z; fmpz_t e; mag_t err; arb_init(t); arb_init(u); acb_init(s); acb_init(z); mag_init(err); fmpz_init(e); /* u = n + 1/2 */ arb_set_d(u, 0.5); arb_add_ui(u, u, n, prec); arb_get_mag_lower(err, y); _arb_hypgeom_legendre_p_ui_asymp_error(err, n, err, K); /* z = (x + yi)^(n+0.5) * (1-i) */ if (n < 256 || prec > 2000) { arb_set(acb_realref(z), x); arb_set(acb_imagref(z), y); acb_pow_arb(z, z, u, prec); } else { arb_atan2(t, y, x, prec); arb_mul(t, t, u, prec); arb_sin_cos(acb_imagref(z), acb_realref(z), t, prec); } arb_one(acb_realref(s)); arb_set_si(acb_imagref(s), -1); acb_mul(z, z, s, prec); /* main series */ asymp_series(s, n, w4pow, m, K, prec); /* we will use Re(z * s) */ acb_mul(z, z, s, prec); /* prefactor: t = 4^n / (pi * sqrt(y) * (n+0.5) binomial(2n,n)) */ arb_mul(t, binom, u, prec); arb_sqrt(u, y, prec); arb_mul(t, t, u, prec); arb_const_pi(u, prec); arb_mul(t, t, u, prec); arb_div(res, acb_realref(z), t, prec); fmpz_set_ui(e, n); arb_mul_2exp_fmpz(res, res, e); arb_mul_2exp_fmpz(res, res, e); arb_add_error_mag(res, err); arb_clear(t); arb_clear(u); acb_clear(s); acb_clear(z); mag_clear(err); fmpz_clear(e); } void arb_hypgeom_legendre_p_ui_asymp(arb_t res, arb_t res2, ulong n, const arb_t x, slong K, slong prec) { arb_t y, binom; acb_t w; acb_ptr w4pow; slong m; if (n == 0) { if (res != NULL) arb_one(res); if (res2 != NULL) arb_zero(res2); return; } if (!arb_abs_le_ui(x, 1)) { if (res != NULL) arb_indeterminate(res); if (res2 != NULL) arb_indeterminate(res2); return; } K = FLINT_MAX(K, 1); if (res2 != NULL) m = n_sqrt(2 * K); else m = n_sqrt(K); arb_init(y); arb_init(binom); acb_init(w); w4pow = _acb_vec_init(m + 1); /* y = sqrt(1-x^2) */ arb_one(y); arb_submul(y, x, x, 2 * prec); arb_sqrt(y, y, prec); /* w = 1 - (x/y)i */ arb_one(acb_realref(w)); arb_div(acb_imagref(w), x, y, prec); arb_neg(acb_imagref(w), acb_imagref(w)); acb_mul_2exp_si(w, w, -2); _acb_vec_set_powers(w4pow, w, m + 1, prec); /* binomial(2n,n) */ arb_hypgeom_central_bin_ui(binom, n, prec); if (res2 == NULL) { _arb_hypgeom_legendre_p_ui_asymp(res, n, x, y, w4pow, binom, m, K, prec); } else { arb_t t, u, v; arb_init(t); arb_init(u); arb_init(v); _arb_hypgeom_legendre_p_ui_asymp(t, n, x, y, w4pow, binom, m, K, prec); /* recurrence for central binomial */ arb_mul_ui(binom, binom, n, prec); arb_set_ui(u, n); arb_mul_2exp_si(u, u, 2); arb_sub_ui(u, u, 2, prec); arb_div(binom, binom, u, prec); _arb_hypgeom_legendre_p_ui_asymp(u, n - 1, x, y, w4pow, binom, m, K, prec); /* P' = n (P[n-1] - x P) / (1 - x^2) */ arb_submul(u, t, x, prec); arb_mul(v, x, x, 2 * prec); arb_neg(v, v); arb_add_ui(v, v, 1, prec); arb_div(u, u, v, prec); arb_mul_ui(res2, u, n, prec); if (res != NULL) arb_set(res, t); arb_clear(t); arb_clear(u); arb_clear(v); } arb_clear(y); arb_clear(binom); acb_clear(w); _acb_vec_clear(w4pow, m + 1); } arb-2.22.1/arb_hypgeom/legendre_p_ui_one.c000066400000000000000000000104561417376376500204750ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #define UNROLL 4 static void sum_rs_inner(arb_t s, arb_srcptr xpow, slong m, ulong n, slong K, ulong prime, slong prec) { slong j, k, khi, klo, u, r; fmpz * c; arb_zero(s); c = _fmpz_vec_init(UNROLL + 1); k = K - 1; while (k >= 1) { u = FLINT_MIN(UNROLL, k); khi = k; klo = k - u + 1; for (j = klo; j <= khi; j++) { ulong aa = (n - j + 1 - prime); ulong bb = (n + j + prime); if (j == klo) fmpz_ui_mul_ui(c + khi - j, aa, bb); else fmpz_mul2_uiui(c + khi - j, c + khi - j + 1, aa, bb); } for (j = khi; j >= klo; j--) { ulong aa = (j); ulong bb = (j + prime); if (j == khi) { fmpz_ui_mul_ui(c + u, aa, bb); } else { fmpz_mul(c + khi - j, c + khi - j, c + u); fmpz_mul2_uiui(c + u, c + u, aa, bb); } } while (k >= klo) { r = k % m; if (k == khi) { arb_add(s, s, xpow + r, prec); arb_mul_fmpz(s, s, c + khi - k, prec); } else if (r == 0) arb_add_fmpz(s, s, c + khi - k, prec); else arb_addmul_fmpz(s, xpow + r, c + khi - k, prec); if (r == 0 && k != 0) arb_mul(s, s, xpow + m, prec); k--; } arb_div_fmpz(s, s, c + u, prec); } _fmpz_vec_clear(c, UNROLL + 1); } void arb_hypgeom_legendre_p_ui_one(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong K, slong prec) { arb_t s, v; arb_ptr xpow; slong m; mag_t u, a, t, err; if (n == 0) { if (res != NULL) arb_one(res); if (res_prime != NULL) arb_zero(res_prime); return; } /* overflow protection */ if (n > UWORD_MAX / 4) { if (res != NULL) arb_indeterminate(res); if (res_prime != NULL) arb_indeterminate(res_prime); } arb_init(v); arb_init(s); mag_init(u); mag_init(a); mag_init(t); mag_init(err); K = FLINT_MIN(K, n + 1); if (res != NULL && res_prime != NULL) m = n_sqrt(2 * K); else m = n_sqrt(K); xpow = _arb_vec_init(m + 1); arb_sub_ui(v, x, 1, prec); arb_mul_2exp_si(v, v, -1); _arb_vec_set_powers(xpow, v, m + 1, prec); /* truncating */ if (K < n + 1) { arb_get_mag(u, v); mag_mul_ui(t, u, n - K); mag_mul_ui(t, t, n + K + 1); mag_div_ui(t, t, K + 1); mag_div_ui(t, t, K + 1); mag_geom_series(t, t, 0); mag_pow_ui(u, u, K); mag_mul(u, u, t); } if (res != NULL) { sum_rs_inner(s, xpow, m, n, K, 0, prec); arb_add_ui(res, s, 1, prec); if (K < n + 1) { mag_set(err, u); mag_bin_uiui(t, n, K); mag_mul(err, err, t); mag_bin_uiui(t, n + K, K); mag_mul(err, err, t); arb_add_error_mag(res, err); } } if (res_prime != NULL) { K = FLINT_MIN(K, n); sum_rs_inner(s, xpow, m, n, K, 1, prec); arb_add_ui(res_prime, s, 1, prec); arb_mul_ui(res_prime, res_prime, n, prec); arb_mul_ui(res_prime, res_prime, n + 1, prec); arb_mul_2exp_si(res_prime, res_prime, -1); /* truncating */ if (K < n) { mag_set(err, u); mag_bin_uiui(t, n, K + 1); mag_mul(err, err, t); mag_bin_uiui(t, n + K + 1, K + 1); mag_mul(err, err, t); mag_mul_ui(err, err, n); arb_add_error_mag(res_prime, err); } } _arb_vec_clear(xpow, m + 1); arb_clear(s); arb_clear(v); mag_clear(u); mag_clear(a); mag_clear(t); mag_clear(err); } arb-2.22.1/arb_hypgeom/legendre_p_ui_rec.c000066400000000000000000000073011417376376500204600ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_legendre_p_ui_rec(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong prec) { slong wp; ulong k, den; mp_limb_t denlo, denhi; mpz_t p0, p1, xx, tt; fmpz_t fxx; int error; arb_t t, u, x2sub1; mag_t err1, err2, xrad; if (n > (UWORD(1) << (FLINT_BITS / 2 - 1))) { if (res != NULL) arb_indeterminate(res); if (res_prime != NULL) arb_indeterminate(res); return; } if (n == 0) { if (res != NULL) arb_one(res); if (res_prime != NULL) arb_zero(res_prime); return; } mag_init(xrad); arb_get_mag(xrad, x); /* error analysis assumes |x| < 1 */ if (mag_cmp_2exp_si(xrad, 0) >= 0) { arb_hypgeom_legendre_p_ui_one(res, res_prime, n, x, n + 1, prec); mag_clear(xrad); return; } mpz_init(p0); mpz_init(p1); mpz_init(xx); mpz_init(tt); fmpz_init(fxx); arb_init(t); arb_init(u); arb_init(x2sub1); mag_init(err1); mag_init(err2); wp = -arf_abs_bound_lt_2exp_si(arb_midref(x)); wp = FLINT_MAX(wp, 0); wp = FLINT_MIN(wp, prec); wp += prec + 2 * FLINT_BIT_COUNT(n + 2); /* (n+2)^2 >= 0.75(n+1)(n+2)+1 */ arb_mul(x2sub1, x, x, ARF_PREC_EXACT); arb_neg(x2sub1, x2sub1); arb_add_ui(x2sub1, x2sub1, 1, wp); error = arf_get_fmpz_fixed_si(fxx, arb_midref(x), -wp); fmpz_get_mpz(xx, fxx); mag_set(xrad, arb_radref(x)); if (error) mag_add_ui_2exp_si(xrad, xrad, 1, -wp); mpz_set_ui(p0, 1); mpz_mul_2exp(p0, p0, wp); mpz_set(p1, xx); den = 1; for (k = 1; k < n; k++) { mpz_mul(tt, p1, xx); mpz_tdiv_q_2exp(tt, tt, wp); flint_mpz_mul_ui(p0, p0, k*k); mpz_neg(p0, p0); flint_mpz_addmul_ui(p0, tt, 2 * k + 1); mpz_swap(p0, p1); umul_ppmm(denhi, denlo, den, k + 1); if (denhi != 0) { flint_mpz_tdiv_q_ui(p0, p0, den); flint_mpz_tdiv_q_ui(p1, p1, den); den = k + 1; } else { den = denlo; } } flint_mpz_tdiv_q_ui(p0, p0, den/n); flint_mpz_tdiv_q_ui(p1, p1, den); if (!mag_is_zero(xrad)) { arb_hypgeom_legendre_p_ui_deriv_bound(err1, err2, n, x, x2sub1); mag_mul(err1, err1, xrad); mag_mul(err2, err2, xrad); } arf_set_mpz(arb_midref(t), p1); arf_mul_2exp_si(arb_midref(t), arb_midref(t), -wp); mag_set_ui_2exp_si(arb_radref(t), (n + 1) * (n + 2), -wp); mag_add(arb_radref(t), arb_radref(t), err1); if (res_prime != NULL) { /* P' = n (P[n-1] - x P) / (1 - x^2) */ arf_set_mpz(arb_midref(u), p0); arf_mul_2exp_si(arb_midref(u), arb_midref(u), -wp); mag_set_ui_2exp_si(arb_radref(u), n * (n + 1), -wp); arb_submul(u, t, x, wp); arb_div(res_prime, u, x2sub1, wp); arb_mul_ui(res_prime, res_prime, n, prec); mag_add(arb_radref(res_prime), arb_radref(res_prime), err2); } if (res != NULL) /* done last since x may be aliased with res */ { arb_set_round(res, t, prec); } mpz_clear(p0); mpz_clear(p1); mpz_clear(xx); mpz_clear(tt); fmpz_clear(fxx); arb_clear(t); arb_clear(u); arb_clear(x2sub1); mag_clear(err1); mag_clear(err2); mag_clear(xrad); } arb-2.22.1/arb_hypgeom/legendre_p_ui_root.c000066400000000000000000000131351417376376500206740ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" /* Compute initial isolating interval, following K. Petras. */ void arb_hypgeom_legendre_p_ui_root_initial(arb_t res, ulong n, ulong k, slong prec) { arb_t phi, psi, s, c, t, u; mag_t err, errc, errd; slong i, tol; arb_init(phi); arb_init(psi); arb_init(s); arb_init(c); arb_init(t); arb_init(u); mag_init(err); mag_init(errc); mag_init(errd); /* Petras numbering starts from 1 */ k++; if (k > n / 2) flint_abort(); tol = -prec; /* We need slightly higher precision since the Newton iteration *arithmetic* error bounds are not self-correcting. */ prec = prec * 1.2 + 10; /* t = 4n+2 */ arb_set_ui(t, n); arb_mul_2exp_si(t, t, 2); arb_add_ui(t, t, 2, prec); /* u = (4k-1) pi */ arb_set_ui(u, k); arb_mul_2exp_si(u, u, 2); arb_sub_ui(u, u, 1, prec); arb_const_pi(phi, prec); arb_mul(u, u, phi, prec); /* phi = ((4k-1)/(4n+2)) pi */ arb_div(phi, u, t, prec); /* errc = phi^2 */ arb_get_mag_lower(errc, phi); mag_mul(errc, errc, errc); /* errd = 22*y^4 * (1 + 2*y^2), y = 1/u */ /* err = y^2 */ arb_get_mag_lower(err, u); mag_one(errd); mag_div(err, errd, err); mag_mul(err, err, err); /* errd = 1+2y^2 */ mag_mul_2exp_si(errd, err, 1); mag_add_ui(errd, errd, 1); /* err = y^4 */ mag_mul(err, err, err); /* errd *= 22y^4 */ mag_mul(errd, errd, err); mag_mul_ui(errd, errd, 22); /* s, c = sin(phi), cos(phi) */ arb_sin_cos(s, c, phi, prec); /* psi = phi + 2 cos(phi) / (t^2 sin(phi)) (1 - 11/[t^2 sin(phi)^2]) */ arb_mul(psi, t, s, prec); arb_mul(psi, psi, psi, prec); arb_ui_div(psi, 11, psi, prec); arb_sub_ui(psi, psi, 1, prec); arb_neg(psi, psi); /* (destroying t) */ arb_mul(t, t, t, prec); arb_mul(t, t, s, prec); arb_div(t, c, t, prec); arb_mul_2exp_si(t, t, 1); arb_mul(psi, psi, t, prec); arb_add(psi, psi, phi, prec); arb_cos(res, psi, prec); mag_mul(err, errc, errd); for (i = 0; i < FLINT_BITS; i++) { if (mag_cmp_2exp_si(err, tol) < 0) break; arb_hypgeom_legendre_p_ui(t, u, n, res, prec); arb_div(t, t, u, prec); arb_sub(res, res, t, prec); mag_mul(errd, errd, errd); mag_mul(err, errc, errd); } arb_add_error_mag(res, err); arb_clear(phi); arb_clear(psi); arb_clear(s); arb_clear(c); arb_clear(t); arb_clear(u); mag_clear(err); mag_clear(errc); mag_clear(errd); } void arb_hypgeom_legendre_p_ui_root(arb_t res, arb_t weight, ulong n, ulong k, slong prec) { slong padding, initial_prec, step, wp; slong steps[FLINT_BITS]; arb_t t, u, v, v0; mag_t err, err2, pb, p2b; int sign; if (k >= n) { flint_printf("require n > 0 and a root index 0 <= k < n\n"); flint_abort(); } sign = 1; if (n % 2 == 1 && k == n / 2) { sign = 0; } else if (k >= n / 2) { k = n - k - 1; sign = -1; } arb_init(t); arb_init(u); arb_init(v); arb_init(v0); mag_init(err); mag_init(err2); mag_init(pb); mag_init(p2b); padding = 8 + 2 * FLINT_BIT_COUNT(n); initial_prec = 40 + padding; if (sign == 0) { arb_zero(res); } else if (initial_prec > prec / 2) { arb_hypgeom_legendre_p_ui_root_initial(res, n, k, prec + padding); } else { step = 0; steps[step] = prec + padding; while (step < FLINT_BITS - 1 && (steps[step] / 2) > initial_prec) { steps[step + 1] = (steps[step] / 2); step++; } wp = steps[step] + padding; arb_hypgeom_legendre_p_ui_root_initial(res, n, k, wp); step--; arb_mul(t, res, res, wp); arb_sub_ui(t, t, 1, wp); arb_hypgeom_legendre_p_ui_deriv_bound(pb, p2b, n, res, t); arb_set(v0, res); for ( ; step >= 0; step--) { wp = steps[step] + padding; /* Interval Newton update: mid(x) - f(mid(x)) / f'(x) */ /* We compute f'(mid(x)) and use the bound on f'' to get f'(x) */ arb_set(v, res); mag_mul(err, p2b, arb_radref(v)); mag_zero(arb_radref(v)); arb_hypgeom_legendre_p_ui(t, u, n, v, wp); arb_add_error_mag(u, err); arb_div(t, t, u, wp); arb_sub(v, v, t, wp); if (mag_cmp(arb_radref(v), arb_radref(res)) >= 0) { /* flint_printf("unexpected Newton iteration failure...\n"); */ break; } arb_set(res, v); } } if (weight != NULL) { wp = FLINT_MAX(prec, 40) + padding; arb_hypgeom_legendre_p_ui(NULL, t, n, res, wp); arb_mul(t, t, t, wp); arb_mul(u, res, res, wp); arb_sub_ui(u, u, 1, wp); arb_neg(u, u); arb_mul(t, t, u, wp); arb_ui_div(weight, 2, t, prec); } if (sign == -1) arb_neg(res, res); arb_set_round(res, res, prec); arb_clear(t); arb_clear(u); arb_clear(v); arb_clear(v0); mag_clear(err); mag_clear(err2); mag_clear(pb); mag_clear(p2b); } arb-2.22.1/arb_hypgeom/legendre_p_ui_zero.c000066400000000000000000000123661417376376500206750ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #define UNROLL 4 static void sum_rs_inner(arb_t s, arb_srcptr xpow, slong m, ulong n, slong K, slong prec) { slong j, k, khi, klo, u, r; ulong d; slong sigma; fmpz * c; sigma = n % 2 ? 1 : -1; d = n / 2; arb_zero(s); c = _fmpz_vec_init(UNROLL + 1); k = K - 1; while (k >= 1) { u = FLINT_MIN(UNROLL, k); khi = k; klo = k - u + 1; for (j = klo; j <= khi; j++) { ulong aa = (d - j + 1); ulong bb = (2 * d + 2 * j + sigma); if (j == klo) fmpz_ui_mul_ui(c + khi - j, aa, bb); else fmpz_mul2_uiui(c + khi - j, c + khi - j + 1, aa, bb); } for (j = khi; j >= klo; j--) { ulong aa = (j); ulong bb = (2 * j + sigma); if (j == khi) { fmpz_ui_mul_ui(c + u, aa, bb); } else { fmpz_mul(c + khi - j, c + khi - j, c + u); fmpz_mul2_uiui(c + u, c + u, aa, bb); } } while (k >= klo) { r = k % m; if (k == khi) { arb_add(s, s, xpow + r, prec); arb_mul_fmpz(s, s, c + khi - k, prec); } else if (r == 0) arb_add_fmpz(s, s, c + khi - k, prec); else arb_addmul_fmpz(s, xpow + r, c + khi - k, prec); if (r == 0 && k != 0) arb_mul(s, s, xpow + m, prec); k--; } arb_div_fmpz(s, s, c + u, prec); } _fmpz_vec_clear(c, UNROLL + 1); } static void _arb_hypgeom_legendre_p_ui_zero(arb_t res, ulong n, const arb_t x, arb_srcptr xpow, slong m, slong K, slong prec) { arb_t s; slong d, prec2; mag_t u, a, t, err; d = n / 2; arb_init(s); mag_init(u); mag_init(a); mag_init(t); mag_init(err); K = FLINT_MIN(K, d + 1); sum_rs_inner(s, xpow, m, n, K, prec); prec2 = arb_rel_accuracy_bits(s); if (prec2 > prec) prec2 = prec; else prec2 = FLINT_MAX(0, prec2) + 20; arb_add_ui(s, s, 1, prec2); if (n % 2 == 1) arb_mul(s, s, x, prec2); arb_swap(res, s); if (d % 2 == 1) arb_neg(res, res); if (n % 2 == 0) { arb_hypgeom_central_bin_ui(s, d, prec2); arb_mul(res, res, s, prec2); arb_mul_2exp_si(res, res, -n); } else { arb_hypgeom_central_bin_ui(s, d + 1, prec2); arb_mul(res, res, s, prec2); arb_mul_ui(res, res, d + 1, prec2); arb_mul_2exp_si(res, res, -n); } if (K < d + 1) { mag_bin_uiui(err, n, d - K); mag_bin_uiui(t, n + 2 * K + (n % 2), n); mag_mul(err, err, t); arb_get_mag(t, x); mag_pow_ui(t, t, 2 * K + (n % 2)); mag_mul(err, err, t); mag_mul_2exp_si(err, err, -n); arb_get_mag(t, x); mag_mul(t, t, t); mag_mul_ui(t, t, d - K + 1); mag_mul_ui(t, t, 2 * d + 2 * K + (n % 2 ? 1 : -1)); mag_div_ui(t, t, K); mag_div_ui(t, t, 2 * K + (n % 2 ? 1 : -1)); mag_geom_series(t, t, 0); mag_mul(err, err, t); arb_add_error_mag(res, err); } arb_clear(s); mag_clear(u); mag_clear(a); mag_clear(t); mag_clear(err); } void arb_hypgeom_legendre_p_ui_zero(arb_t res, arb_t res2, ulong n, const arb_t x, slong K, slong prec) { arb_ptr xpow; arb_t t, u, v; slong m; if (n == 0) { if (res != NULL) arb_one(res); if (res2 != NULL) arb_zero(res2); return; } /* overflow protection */ if (n > UWORD_MAX / 4) { if (res != NULL) arb_indeterminate(res); if (res2 != NULL) arb_indeterminate(res2); } if (res == NULL) { arb_init(v); arb_hypgeom_legendre_p_ui_zero(v, res2, n, x, K, prec); arb_clear(v); return; } arb_init(t); arb_init(u); arb_init(v); K = FLINT_MIN(K, n / 2 + 1); if (res2 != NULL) m = n_sqrt(2 * K); else m = n_sqrt(K); xpow = _arb_vec_init(m + 1); arb_mul(v, x, x, prec); arb_neg(v, v); _arb_vec_set_powers(xpow, v, m + 1, prec); /* todo: recycle prefactor */ if (res2 == NULL) { _arb_hypgeom_legendre_p_ui_zero(t, n, x, xpow, m, K, prec); arb_set(res, t); } else { _arb_hypgeom_legendre_p_ui_zero(t, n, x, xpow, m, K, prec); _arb_hypgeom_legendre_p_ui_zero(u, n - 1, x, xpow, m, K, prec); /* P' = n (P[n-1] - x P) / (1 - x^2) */ arb_submul(u, t, x, prec); arb_add_ui(v, v, 1, prec); arb_div(u, u, v, prec); arb_mul_ui(res2, u, n, prec); arb_set(res, t); } _arb_vec_clear(xpow, m + 1); arb_clear(t); arb_clear(u); arb_clear(v); } arb-2.22.1/arb_hypgeom/lgamma.c000066400000000000000000000036561417376376500162750ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec); int arb_hypgeom_gamma_exact(arb_t res, const arb_t x, int reciprocal, slong prec); void arb_hypgeom_gamma_stirling_inner(arb_t s, const arb_t z, slong N, slong prec); void arb_hypgeom_lgamma_stirling(arb_t y, const arb_t x, slong prec) { int reflect; slong r, n, wp; arb_t t, u; double acc; /* todo: for large x (if exact or accurate enough), increase precision */ acc = arb_rel_accuracy_bits(x); acc = FLINT_MAX(acc, 0); wp = FLINT_MIN(prec, acc + 20); wp = FLINT_MAX(wp, 2); wp = wp + FLINT_BIT_COUNT(wp); arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 0, 0, wp); arb_init(t); arb_init(u); /* log(gamma(x)) = log(gamma(x+r)) - log(rf(x,r)) */ arb_init(t); arb_init(u); arb_add_ui(t, x, r, wp); arb_hypgeom_gamma_stirling_inner(u, t, n, wp); arb_hypgeom_rising_ui_rec(t, x, r, wp); arb_log(t, t, wp); arb_sub(y, u, t, prec); arb_clear(t); arb_clear(u); } void arb_hypgeom_lgamma(arb_t res, const arb_t x, slong prec) { if (!arb_is_positive(x) || !arb_is_finite(x)) { arb_indeterminate(res); return; } if (arb_hypgeom_gamma_exact(res, x, 0, prec)) { arb_log(res, res, prec); return; } if (arb_hypgeom_gamma_taylor(res, x, 0, prec)) { arb_log(res, res, prec); return; } arb_hypgeom_lgamma_stirling(res, x, prec); } arb-2.22.1/arb_hypgeom/li_series.c000066400000000000000000000035201417376376500170030ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_li_series(arb_ptr g, arb_srcptr h, slong hlen, int offset, slong len, slong prec) { arb_t c; if (!arb_is_positive(h) || arb_contains_si(h, 1)) { _arb_vec_indeterminate(g, len); return; } arb_init(c); arb_hypgeom_li(c, h, offset, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_log(g, h, prec); arb_div(g + 1, h + 1, g, prec); } else { arb_ptr t, u; t = _arb_vec_init(len); u = _arb_vec_init(hlen); /* li(h(x)) = integral(h'(x) / log(h(x))) */ _arb_poly_log_series(t, h, hlen, len - 1, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_div_series(g, u, hlen - 1, t, len - 1, len - 1, prec); _arb_poly_integral(g, g, len, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, hlen); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_li_series(arb_poly_t g, const arb_poly_t h, int offset, slong len, slong prec) { slong hlen = h->length; if (len == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_inv_series(g, h, len, prec); return; } arb_poly_fit_length(g, len); _arb_hypgeom_li_series(g->coeffs, h->coeffs, hlen, offset, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/rising_ui.c000066400000000000000000000024361417376376500170220ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_rising_ui(arb_t y, const arb_t x, ulong n, slong prec) { if (n < FLINT_MAX(prec, 100)) { arb_hypgeom_rising_ui_rec(y, x, n, prec); } else { arb_t t; arb_init(t); arb_add_ui(t, x, n, prec); arb_gamma(t, t, prec); arb_rgamma(y, x, prec); arb_mul(y, y, t, prec); arb_clear(t); } } void arb_hypgeom_rising(arb_t y, const arb_t x, const arb_t n, slong prec) { if (arb_is_int(n) && arf_sgn(arb_midref(n)) >= 0 && arf_cmpabs_ui(arb_midref(n), FLINT_MAX(prec, 100)) < 0) { arb_hypgeom_rising_ui_rec(y, x, arf_get_si(arb_midref(n), ARF_RND_DOWN), prec); } else { arb_t t; arb_init(t); arb_add(t, x, n, prec); arb_gamma(t, t, prec); arb_rgamma(y, x, prec); arb_mul(y, y, t, prec); arb_clear(t); } } arb-2.22.1/arb_hypgeom/rising_ui_bs.c000066400000000000000000000026431417376376500175060ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static void bsplit(arb_t y, const arb_t x, ulong a, ulong b, slong prec) { if (b - a <= 16) { if (a == 0) { arb_hypgeom_rising_ui_forward(y, x, b, prec); } else { arb_add_ui(y, x, a, prec); arb_hypgeom_rising_ui_forward(y, y, b - a, prec); } } else { arb_t t, u; ulong m = a + (b - a) / 2; arb_init(t); arb_init(u); bsplit(t, x, a, m, prec); bsplit(u, x, m, b, prec); arb_mul(y, t, u, prec); arb_clear(t); arb_clear(u); } } void arb_hypgeom_rising_ui_bs(arb_t res, const arb_t x, ulong n, slong prec) { if (n <= 1) { if (n == 0) arb_one(res); else arb_set_round(res, x, prec); return; } { arb_t t; slong wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); arb_init(t); bsplit(t, x, 0, n, wp); arb_set_round(res, t, prec); arb_clear(t); } } arb-2.22.1/arb_hypgeom/rising_ui_forward.c000066400000000000000000000033151417376376500205430ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int _arf_increment_fast(arf_t x, slong prec) { if (arf_sgn(x) > 0) { mp_limb_t hi, v, cy; mp_ptr xptr; mp_size_t xn; slong xexp; xexp = ARF_EXP(x); if (xexp >= 1 && xexp <= FLINT_BITS - 1) { ARF_GET_MPN_READONLY(xptr, xn, x); hi = xptr[xn - 1]; v = hi + (UWORD(1) << (FLINT_BITS - xexp)); cy = v < hi; if (cy == 0) { xptr[xn - 1] = v; return 0; } } } return arf_add_ui(x, x, 1, prec, ARF_RND_DOWN); } void _arb_increment_fast(arb_t x, slong prec) { if (_arf_increment_fast(arb_midref(x), prec)) arf_mag_add_ulp(arb_radref(x), arb_radref(x), arb_midref(x), prec); } void arb_hypgeom_rising_ui_forward(arb_t res, const arb_t x, ulong n, slong prec) { arb_t t; ulong k; slong wp; if (n <= 1) { if (n == 0) arb_one(res); else arb_set_round(res, x, prec); return; } wp = prec + FLINT_BIT_COUNT(n); arb_init(t); arb_add_ui(t, x, 1, wp); arb_mul(res, x, t, (n == 2) ? prec : wp); for (k = 2; k < n; k++) { _arb_increment_fast(t, wp); arb_mul(res, res, t, k == (n - 1) ? prec : wp); } arb_clear(t); } arb-2.22.1/arb_hypgeom/rising_ui_jet.c000066400000000000000000000025151417376376500176620ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_rising_ui_jet(arb_ptr res, const arb_t x, ulong n, slong len, slong prec) { if (len == 1) { arb_hypgeom_rising_ui_rec(res, x, n, prec); } else if (n <= 7) { arb_hypgeom_rising_ui_jet_powsum(res, x, n, len, prec); } else if (len == 2) { if (n <= 30 || arb_bits(x) >= prec / 128) arb_hypgeom_rising_ui_jet_rs(res, x, n, 0, len, prec); else arb_hypgeom_rising_ui_jet_bs(res, x, n, len, prec); } else { if (n <= 20 || (n <= 200 && prec > 400 * n && arb_bits(x) >= prec / 4)) { arb_hypgeom_rising_ui_jet_powsum(res, x, n, len, prec); } else if (len >= 64 || (arb_bits(x) + 1 < prec / 1024 && n >= 32)) { arb_hypgeom_rising_ui_jet_bs(res, x, n, len, prec); } else { arb_hypgeom_rising_ui_jet_rs(res, x, n, 0, len, prec); } } } arb-2.22.1/arb_hypgeom/rising_ui_jet_bs.c000066400000000000000000000035611417376376500203500ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static void bsplit(arb_ptr res, const arb_t x, ulong a, ulong b, slong trunc, slong prec) { trunc = FLINT_MIN(trunc, b - a + 1); if (b - a <= 12) { if (a == 0) { arb_hypgeom_rising_ui_jet_powsum(res, x, b - a, FLINT_MIN(trunc, b - a + 1), prec); } else { arb_t t; arb_init(t); arb_add_ui(t, x, a, prec); arb_hypgeom_rising_ui_jet_powsum(res, t, b - a, FLINT_MIN(trunc, b - a + 1), prec); arb_clear(t); } } else { arb_ptr L, R; slong len1, len2; slong m = a + (b - a) / 2; len1 = poly_pow_length(2, m - a, trunc); len2 = poly_pow_length(2, b - m, trunc); L = _arb_vec_init(len1 + len2); R = L + len1; bsplit(L, x, a, m, trunc, prec); bsplit(R, x, m, b, trunc, prec); _arb_poly_mullow(res, L, len1, R, len2, FLINT_MIN(trunc, len1 + len2 - 1), prec); _arb_vec_clear(L, len1 + len2); } } void arb_hypgeom_rising_ui_jet_bs(arb_ptr res, const arb_t x, ulong n, slong len, slong prec) { if (len == 0) return; if (len > n + 1) { _arb_vec_zero(res + n + 1, len - n - 1); len = n + 1; } if (len == n + 1) { arb_one(res + n); len = n; } if (n <= 1) { if (n == 1) arb_set_round(res, x, prec); return; } bsplit(res, x, 0, n, len, prec); } arb-2.22.1/arb_hypgeom/rising_ui_jet_powsum.c000066400000000000000000000100231417376376500212650ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_rising_ui_jet_powsum(arb_ptr res, const arb_t x, ulong n, slong len, slong prec) { slong i, j, k, wp; arb_ptr xpow; TMP_INIT; if (len == 0) return; if (len > n + 1) { _arb_vec_zero(res + n + 1, len - n - 1); len = n + 1; } if (len == n + 1) { arb_one(res + n); len = n; } if (n <= 1) { if (n == 1) arb_set_round(res, x, prec); return; } if (len == 1) { arb_hypgeom_rising_ui_rs(res, x, n, 0, prec); return; } if (n == 2) { arb_mul_2exp_si(res + 1, x, 1); arb_add_ui(res + 1, res + 1, 1, prec); arb_mul(res, x, x, prec + 4); arb_add(res, res, x, prec); return; } if (n <= 12 || (FLINT_BITS == 64 && n <= 20)) { mp_ptr c; TMP_START; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); c = TMP_ALLOC(sizeof(mp_limb_t) * (n + 1) * len); _nmod_vec_zero(c, (n + 1) * len); c[0] = 0; c[1] = 1; c[(n + 1) + 0] = 1; for (i = 2; i <= n; i++) { for (j = FLINT_MIN(len - 1, i); j >= 0; j--) { slong ln, pos; ln = i + 1 - j; pos = (n + 1) * j; if (i == j) { c[pos] = 1; } else { c[pos + ln - 1] = c[pos + ln - 2]; for (k = ln - 2; k >= 1; k--) c[pos + k] = c[pos + k] * (i - 1) + c[pos + k - 1]; c[pos + 0] *= (i - 1); if (j != 0) for (k = ln - 1; k >= 0; k--) c[pos + k] += c[pos - (n + 1) + k]; } } } xpow = _arb_vec_init(n + 1); _arb_vec_set_powers(xpow, x, n + 1, wp); arb_dot_ui(res, NULL, 0, xpow + 1, 1, c + 1, 1, n, prec); for (i = 1; i < len; i++) arb_dot_ui(res + i, NULL, 0, xpow, 1, c + (n + 1) * i, 1, n + 1 - i, prec); _arb_vec_clear(xpow, n + 1); TMP_END; } else { fmpz * c; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); c = _fmpz_vec_init((n + 1) * len); fmpz_one(c + 1); fmpz_one(c + (n + 1) + 0); for (i = 2; i <= n; i++) { for (j = FLINT_MIN(len - 1, i); j >= 0; j--) { slong ln, pos; ln = i + 1 - j; pos = (n + 1) * j; if (i == j) { fmpz_one(c + pos); } else { fmpz_set(c + pos + ln - 1, c + pos + ln - 2); for (k = ln - 2; k >= 1; k--) { fmpz_mul_ui(c + pos + k, c + pos + k, i - 1); fmpz_add(c + pos + k, c + pos + k, c + pos + k - 1); } fmpz_mul_ui(c + pos + 0, c + pos + 0, i - 1); if (j != 0) for (k = ln - 1; k >= 0; k--) fmpz_add(c + pos + k, c + pos + k, c + pos - (n + 1) + k); } } } xpow = _arb_vec_init(n + 1); _arb_vec_set_powers(xpow, x, n + 1, wp); arb_dot_fmpz(res, NULL, 0, xpow + 1, 1, c + 1, 1, n, prec); for (i = 1; i < len; i++) arb_dot_fmpz(res + i, NULL, 0, xpow, 1, c + (n + 1) * i, 1, n + 1 - i, prec); _arb_vec_clear(xpow, n + 1); _fmpz_vec_clear(c, (n + 1) * len); } } arb-2.22.1/arb_hypgeom/rising_ui_jet_rs.c000066400000000000000000000102411417376376500203610ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_rising_ui_jet_rs(arb_ptr res, const arb_t x, ulong n, ulong m, slong len, slong prec) { slong i, j, k, l, m0, xmlen, tlen, ulen, climbs, climbs_max, wp; arb_ptr tmp, xpow; arb_ptr t, u; mp_ptr c; TMP_INIT; if (len == 0) return; if (len > n + 1) { _arb_vec_zero(res + n + 1, len - n - 1); len = n + 1; } if (len == n + 1) { arb_one(res + n); len = n; } if (n <= 1) { if (n == 1) arb_set_round(res, x, prec); return; } if (len == 1) { arb_hypgeom_rising_ui_rs(res, x, n, m, prec); return; } TMP_START; if (m == 0) { if (n <= 7) m = n; else if (n <= 12) m = (n + 1) / 2; else if (n <= 32) m = (n + 2) / 3; else { m0 = n_sqrt(n); m = 8 + 0.5 * pow(prec, 0.4); m = FLINT_MIN(m, m0); m = FLINT_MIN(m, 64); } } wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); climbs_max = FLINT_BIT_COUNT(n - 1) * m; c = TMP_ALLOC(sizeof(mp_limb_t) * climbs_max * m); /* length of (x+t)^m */ xmlen = FLINT_MIN(len, m + 1); tmp = _arb_vec_init(2 * len + (m + 1) * xmlen); t = tmp; u = tmp + len; xpow = tmp + 2 * len; _arb_vec_set_powers(xpow, x, m + 1, wp); tlen = 1; /* First derivatives */ for (i = 1; i <= m; i++) arb_mul_ui(xpow + (m + 1) + i, xpow + i - 1, i, wp); /* Higher derivatives if we need them */ if (len >= 3) { fmpz * f = _fmpz_vec_init(len); fmpz_one(f + 0); fmpz_one(f + 1); for (i = 2; i <= m; i++) { for (j = FLINT_MIN(xmlen - 1, i + 1); j >= 1; j--) fmpz_add(f + j, f + j, f + j - 1); for (j = 2; j < FLINT_MIN(xmlen, i + 1); j++) arb_mul_fmpz(xpow + (m + 1) * j + i, xpow + i - j, f + j, wp); } _fmpz_vec_clear(f, len); } for (k = 0; k < n; k += m) { l = FLINT_MIN(m, n - k); climbs = FLINT_BIT_COUNT(k + l - 1) * l; climbs = (climbs + FLINT_BITS - 1) / FLINT_BITS; ulen = FLINT_MIN(len, l + 1); if (l == 1) { arb_add_ui(u, x, k, wp); arb_one(u + 1); } else { if (climbs == 1) { _arb_hypgeom_rising_coeffs_1(c, k, l); for (j = 0; j < ulen; j++) arb_dot_ui(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, c + j, 1, l - j, wp); } else if (climbs == 2) { _arb_hypgeom_rising_coeffs_2(c, k, l); for (j = 0; j < ulen; j++) arb_dot_uiui(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, c + 2 * j, 1, l - j, wp); } else { fmpz * f = (fmpz *) c; for (i = 0; i < l; i++) fmpz_init(f + i); _arb_hypgeom_rising_coeffs_fmpz(f, k, l); for (j = 0; j < ulen; j++) arb_dot_fmpz(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, f + j, 1, l - j, wp); for (i = 0; i < l; i++) fmpz_clear(f + i); } } if (k == 0) { tlen = ulen; _arb_vec_swap(t, u, ulen); } else { _arb_poly_mullow(res, t, tlen, u, ulen, FLINT_MIN(len, tlen + ulen - 1), wp); tlen = FLINT_MIN(len, tlen + ulen - 1); _arb_vec_swap(t, res, tlen); } } _arb_vec_set_round(res, t, len, prec); _arb_vec_clear(tmp, 2 * len + (m + 1) * xmlen); TMP_END; } arb-2.22.1/arb_hypgeom/rising_ui_rec.c000066400000000000000000000021331417376376500176450ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_rising_ui_rec(arb_t res, const arb_t x, ulong n, slong prec) { if (n <= 1) { if (n == 0) arb_one(res); else arb_set_round(res, x, prec); return; } if (n == 2 && prec <= 1024) { if (res != x) arb_set(res, x); arb_addmul(res, x, x, prec); return; } if ((prec < 512 && n <= 20) || (n <= FLINT_MIN(80, 6000 / prec))) { arb_hypgeom_rising_ui_forward(res, x, n, prec); } else { if (n >= 20 && arb_bits(x) < prec / 8) arb_hypgeom_rising_ui_bs(res, x, n, prec); else arb_hypgeom_rising_ui_rs(res, x, n, 0, prec); } } arb-2.22.1/arb_hypgeom/rising_ui_rs.c000066400000000000000000000102051417376376500175170ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_rising_coeffs_1(ulong * c, ulong k, slong l) { slong i, j; ulong d; if (l < 2) flint_abort(); c[0] = k * (k + 1); c[1] = 2 * k + 1; for (i = 2; i < l; i++) { d = k + i; c[i] = c[i - 1] + d; for (j = i - 1; j >= 1; j--) c[j] = c[j] * d + c[j - 1]; c[0] = c[0] * d; } } void _arb_hypgeom_rising_coeffs_2(ulong * c, ulong k, slong l) { slong i, j; ulong d; mp_limb_t hi, lo; if (l < 2) flint_abort(); umul_ppmm(c[1], c[0], k, k + 1); c[2] = 2 * k + 1; c[3] = 0; for (i = 2; i < l; i++) { d = k + i; add_ssaaaa(c[2 * i + 1], c[2 * i], c[2 * i - 1], c[2 * i - 2], 0, d); for (j = i - 1; j >= 1; j--) { umul_ppmm(hi, lo, c[2 * j], d); hi += c[2 * j + 1] * d; add_ssaaaa(c[2 * j + 1], c[2 * j], hi, lo, c[2 * j - 1], c[2 * j - 2]); } umul_ppmm(hi, lo, c[0], d); c[0] = lo; c[1] = c[1] * d + hi; } } void _arb_hypgeom_rising_coeffs_fmpz(fmpz * c, ulong k, slong l) { slong i, j; ulong d; if (l < 2) flint_abort(); fmpz_set_ui(c + 0, k); fmpz_mul_ui(c + 0, c + 0, k + 1); fmpz_set_ui(c + 1, 2 * k + 1); for (i = 2; i < l; i++) { d = k + i; fmpz_add_ui(c + i, c + i - 1, d); for (j = i - 1; j >= 1; j--) { fmpz_mul_ui(c + j, c + j, d); fmpz_add(c + j, c + j, c + j - 1); } fmpz_mul_ui(c + 0, c + 0, d); } } void arb_hypgeom_rising_ui_rs(arb_t res, const arb_t x, ulong n, ulong m, slong prec) { slong i, k, l, m0, climbs, climbs_max, wp; arb_ptr xpow; arb_t t, u; mp_ptr c; TMP_INIT; if (n <= 1) { if (n == 0) arb_one(res); else arb_set_round(res, x, prec); return; } TMP_START; if (m == 0) { if (n <= 6) m = 1 + (prec >= 1024); else if (n <= 16) m = 4; else if (n <= 50) m = 6; else { m0 = n_sqrt(n); m = 8 + 0.2 * pow(FLINT_MAX(0, prec - 4096), 0.4); m = FLINT_MIN(m, m0); m = FLINT_MIN(m, 60); } } wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); climbs_max = FLINT_BIT_COUNT(n - 1) * m; c = TMP_ALLOC(sizeof(mp_limb_t) * climbs_max * m); xpow = _arb_vec_init(m + 1); _arb_vec_set_powers(xpow, x, m + 1, wp); arb_init(t); arb_init(u); for (k = 0; k < n; k += m) { l = FLINT_MIN(m, n - k); climbs = FLINT_BIT_COUNT(k + l - 1) * l; climbs = (climbs + FLINT_BITS - 1) / FLINT_BITS; /* assumes l >= 2 */ if (l == 1) { arb_add_ui(u, x, k, wp); } else { if (climbs == 1) { _arb_hypgeom_rising_coeffs_1(c, k, l); arb_dot_ui(u, xpow + l, 0, xpow, 1, c, 1, l, wp); } else if (climbs == 2) { _arb_hypgeom_rising_coeffs_2(c, k, l); arb_dot_uiui(u, xpow + l, 0, xpow, 1, c, 1, l, wp); } else { fmpz * f = (fmpz *) c; for (i = 0; i < l; i++) fmpz_init(f + i); _arb_hypgeom_rising_coeffs_fmpz(f, k, l); arb_dot_fmpz(u, xpow + l, 0, xpow, 1, f, 1, l, wp); for (i = 0; i < l; i++) fmpz_clear(f + i); } } if (k == 0) arb_swap(t, u); else arb_mul(t, t, u, wp); } arb_set_round(res, t, prec); arb_clear(t); arb_clear(u); _arb_vec_clear(xpow, m + 1); TMP_END; } arb-2.22.1/arb_hypgeom/shi_series.c000066400000000000000000000026101417376376500171610ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" /* todo: use a sinch function? */ void _arb_hypgeom_shi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_hypgeom_shi(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else { acb_ptr t; slong i; t = _acb_vec_init(len); for (i = 0; i < hlen; i++) arb_set(acb_realref(t + i), h + i); _acb_hypgeom_shi_series(t, t, hlen, len, prec); for (i = 0; i < len; i++) arb_swap(g + i, acb_realref(t + i)); _acb_vec_clear(t, len); } } void arb_hypgeom_shi_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, len); _arb_hypgeom_shi_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/si.c000066400000000000000000000132441417376376500154440ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arb_hypgeom.h" #define LOG2 0.69314718055994531 #define INV_LOG2 1.4426950408889634074 #define EXP1 2.7182818284590452 double arf_get_d_log2_abs_approx_clamped(const arf_t x); /* todo: minima and maxima at multiples of pi */ void arb_hypgeom_si_wide(arb_t res, const arb_t z, slong prec) { mag_set_ui_2exp_si(arb_radref(res), 1988502269, -30); arf_zero(arb_midref(res)); } void _arb_hypgeom_si_asymp(arb_t res, const arb_t z, slong N, slong prec) { arb_t s, c, sz, cz, u; fmpq a[1]; slong wp; mag_t err, t; int negative; negative = arf_sgn(arb_midref(z)) < 0; if (negative) { arb_neg(res, z); _arb_hypgeom_si_asymp(res, res, N, prec); arb_neg(res, res); return; } N = FLINT_MAX(N, 1); arb_init(s); arb_init(c); arb_init(sz); arb_init(cz); arb_init(u); mag_init(err); mag_init(t); /* Error is bounded by first omitted term, N! / z^N */ arb_get_mag_lower(err, z); /* Do something better on wide intervals */ if (mag_cmp_2exp_si(err, 1) < 0) { arb_hypgeom_si_wide(res, z, prec); } else { mag_inv(err, err); mag_pow_ui(err, err, N); mag_fac_ui(t, N); mag_mul(err, err, t); wp = prec * 1.001 + 5; arb_set(u, z); *fmpq_numref(&a[0]) = 1; *fmpq_denref(&a[0]) = 1; arb_hypgeom_sum_fmpq_imag_arb(c, s, a, 1, NULL, 0, u, 1, N, wp); arb_add_error_mag(c, err); arb_add_error_mag(s, err); arb_sin_cos(sz, cz, z, wp); arb_mul(s, s, sz, wp); arb_addmul(s, c, cz, wp); arb_div(s, s, z, wp); arb_const_pi(u, wp); arb_mul_2exp_si(u, u, -1); arb_sub(res, u, s, prec); } arb_clear(s); arb_clear(c); arb_clear(sz); arb_clear(cz); arb_clear(u); mag_clear(err); mag_clear(t); } void _arb_hypgeom_si_1f2(arb_t res, const arb_t z, slong N, slong wp, slong prec) { mag_t err, t; arb_t s, u; fmpq a[1]; fmpq b[3]; N = FLINT_MAX(N, 1); mag_init(err); mag_init(t); arb_init(s); arb_init(u); arb_sqr(u, z, wp); arb_mul_2exp_si(u, u, -2); arb_neg(u, u); *fmpq_numref(&a[0]) = 1; *fmpq_denref(&a[0]) = 2; *fmpq_numref(&b[0]) = 3; *fmpq_denref(&b[0]) = 2; *fmpq_numref(&b[1]) = 3; *fmpq_denref(&b[1]) = 2; *fmpq_numref(&b[2]) = 1; *fmpq_denref(&b[2]) = 1; /* Terms are bounded by u^N / (4 (N!)^2) */ arb_get_mag(err, u); /* u^N */ mag_set(t, err); mag_pow_ui(t, t, N); /* geometric factor for u/N^2 */ mag_div_ui(err, err, N); mag_div_ui(err, err, N); mag_geom_series(err, err, 0); mag_mul(t, t, err); /* 1/(N!)^2 */ mag_rfac_ui(err, N); mag_mul(err, err, err); mag_mul(err, err, t); /* 1/4 */ mag_mul_2exp_si(err, err, -2); arb_hypgeom_sum_fmpq_arb(s, a, 1, b, 3, u, 0, N, wp); arb_add_error_mag(s, err); arb_mul(res, s, z, prec); mag_clear(err); mag_clear(t); arb_clear(u); arb_clear(s); } void arb_hypgeom_si(arb_t res, const arb_t z, slong prec) { slong wp, N, acc; double dz, du; if (!arb_is_finite(z)) { arb_indeterminate(res); return; } if (arb_is_zero(z)) { arb_zero(res); return; } if (ARF_IS_LAGOM(arb_midref(z))) { acc = arb_rel_accuracy_bits(z); acc = FLINT_MAX(acc, 0); acc = FLINT_MIN(acc, prec); acc += FLINT_MAX(0, ARF_EXP(arb_midref(z))); prec = FLINT_MIN(prec, acc + 32); } dz = fabs(arf_get_d(arb_midref(z), ARF_RND_DOWN)); dz = FLINT_MIN(dz, 1e300); if (dz > 2.0) { double log2_err, err_prev, log2dz; log2dz = arf_get_d_log2_abs_approx_clamped(arb_midref(z)); err_prev = 0.0; for (N = 1; N < 2 * prec; N++) { log2_err = ((N + 1.0) * (log(N + 1.0) - 1.0)) * INV_LOG2 - N * log2dz; if (log2_err > err_prev) break; if (log2_err < -prec - 2) { _arb_hypgeom_si_asymp(res, z, N, prec); return; } err_prev = log2_err; } } if (arf_cmpabs_2exp_si(arb_midref(z), -30) < 0) { N = -arf_abs_bound_lt_2exp_si(arb_midref(z)); wp = prec * 1.001 + 10; N = (prec + N - 1) / N; } else { du = 0.25 * dz * dz; wp = prec * 1.001 + 10; if (du > 1.0) wp += dz * 1.4426950408889634; N = (prec + 5) * LOG2 / (2 * d_lambertw((prec + 5) * LOG2 / (2 * EXP1 * sqrt(du)))) + 1; } if (arb_is_exact(z)) { _arb_hypgeom_si_1f2(res, z, N, wp, prec); } else { mag_t err; arb_t zmid; mag_init(err); arb_init(zmid); arb_get_mid_arb(zmid, z); /* |si'(z)| = |sinc(z)| <= min(1, 1/z) */ arb_get_mag_lower(err, z); mag_inv(err, err); if (mag_cmp_2exp_si(err, 0) > 0) mag_one(err); mag_mul(err, err, arb_radref(z)); /* |si(a) - si(b)| < 4 */ if (mag_cmp_2exp_si(err, 2) > 0) mag_set_ui(err, 4); _arb_hypgeom_si_1f2(res, zmid, N, wp, prec); arb_add_error_mag(res, err); arb_clear(zmid); mag_clear(err); } } arb-2.22.1/arb_hypgeom/si_series.c000066400000000000000000000031511417376376500170120ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void _arb_hypgeom_si_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { arb_t c; arb_init(c); arb_hypgeom_si(c, h, prec); hlen = FLINT_MIN(hlen, len); if (hlen == 1) { _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_sinc(g, h, prec); arb_mul(g + 1, g, h + 1, prec); } else { arb_ptr t, u; t = _arb_vec_init(len - 1); u = _arb_vec_init(hlen - 1); /* Si(h(x)) = integral(h'(x) sinc(h(x))) */ _arb_poly_sinc_series(t, h, hlen, len - 1, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(g, t, len - 1, u, hlen - 1, len - 1, prec); _arb_poly_integral(g, g, len, prec); _arb_vec_clear(t, len - 1); _arb_vec_clear(u, hlen - 1); } arb_swap(g, c); arb_clear(c); } void arb_hypgeom_si_series(arb_poly_t g, const arb_poly_t h, slong len, slong prec) { slong hlen = h->length; if (hlen == 0 || len == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, len); _arb_hypgeom_si_series(g->coeffs, h->coeffs, hlen, len, prec); _arb_poly_set_length(g, len); _arb_poly_normalise(g); } arb-2.22.1/arb_hypgeom/sum_fmpq_arb.c000066400000000000000000000016731417376376500175070ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_sum_fmpq_arb(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { if (N <= 2 || (prec <= 1024 && N <= 8) || (prec <= 4096 && N <= 4)) arb_hypgeom_sum_fmpq_arb_forward(res, a, alen, b, blen, z, reciprocal, N, prec); else if (prec >= 8192 && arb_bits(z) <= 0.001 * prec) arb_hypgeom_sum_fmpq_arb_bs(res, a, alen, b, blen, z, reciprocal, N, prec); else arb_hypgeom_sum_fmpq_arb_rs(res, a, alen, b, blen, z, reciprocal, N, prec); } arb-2.22.1/arb_hypgeom/sum_fmpq_arb_bs.c000066400000000000000000000074721417376376500201760ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static void factor(arb_t A, const fmpq * a, slong alen, const fmpq * b, slong blen, const fmpz_t bden, const arb_t z, slong k, slong prec) { slong i; fmpz_t t, u; fmpz_init(t); fmpz_init(u); if (alen == 0) { if (z == NULL) arb_set_fmpz(A, bden); else if (fmpz_is_one(bden)) arb_set(A, z); else arb_mul_fmpz(A, z, bden, prec); } else { /* product of a_i + k = p/q + k = (p + k*q)/q */ fmpz_mul_ui(t, fmpq_denref(a + 0), k); fmpz_add(t, t, fmpq_numref(a + 0)); for (i = 1; i < alen; i++) { fmpz_mul_ui(u, fmpq_denref(a + i), k); fmpz_add(u, u, fmpq_numref(a + i)); fmpz_mul(t, t, u); } if (!fmpz_is_one(bden)) fmpz_mul(t, t, bden); if (z == NULL) arb_set_fmpz(A, t); else arb_mul_fmpz(A, z, t, prec); } fmpz_clear(t); fmpz_clear(u); } static void bsplit(arb_t A1, arb_t B1, arb_t C1, const fmpq * a, slong alen, const fmpz_t aden, const fmpq * b, slong blen, const fmpz_t bden, const arb_t z, int reciprocal, slong aa, slong bb, slong prec) { if (bb - aa == 1) { factor(A1, a, alen, b, blen, bden, reciprocal ? NULL : z, aa, prec); factor(C1, b, blen, a, alen, aden, reciprocal ? z : NULL, aa, prec); /* arb_set(B1, C1); but we skip this */ } else { slong m; arb_t A2, B2, C2; arb_init(A2); arb_init(B2); arb_init(C2); m = aa + (bb - aa) / 2; bsplit(A1, B1, C1, a, alen, aden, b, blen, bden, z, reciprocal, aa, m, prec); bsplit(A2, B2, C2, a, alen, aden, b, blen, bden, z, reciprocal, m, bb, prec); if (bb - m == 1) /* B2 = C2 */ { if (m - aa == 1) arb_add(B2, A1, C1, prec); else arb_add(B2, A1, B1, prec); arb_mul(B1, B2, C2, prec); } else { if (m - aa == 1) arb_mul(B1, C1, C2, prec); else arb_mul(B1, B1, C2, prec); arb_addmul(B1, A1, B2, prec); } arb_mul(A1, A1, A2, prec); arb_mul(C1, C1, C2, prec); arb_clear(A2); arb_clear(B2); arb_clear(C2); } } void arb_hypgeom_sum_fmpq_arb_bs(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { arb_t u, v, w; fmpz_t aden, bden; slong i; if (N <= 3) { arb_hypgeom_sum_fmpq_arb_forward(res, a, alen, b, blen, z, reciprocal, N, prec); return; } arb_init(u); arb_init(v); arb_init(w); fmpz_init(aden); fmpz_init(bden); fmpz_one(aden); fmpz_one(bden); for (i = 0; i < alen; i++) fmpz_mul(aden, aden, fmpq_denref(a + i)); for (i = 0; i < blen; i++) fmpz_mul(bden, bden, fmpq_denref(b + i)); /* we compute to N-1 instead of N to avoid dividing by 0 in the denominator when computing a hypergeometric polynomial that terminates right before a pole */ bsplit(u, v, w, a, alen, aden, b, blen, bden, z, reciprocal, 0, N - 1, prec); arb_add(res, u, v, prec); /* s = s + t */ arb_div(res, res, w, prec); arb_clear(u); arb_clear(v); arb_clear(w); fmpz_clear(aden); fmpz_clear(bden); } arb-2.22.1/arb_hypgeom/sum_fmpq_arb_forward.c000066400000000000000000000115311417376376500212250ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_sum_fmpq_arb_forward(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { arb_t t, u, sden; slong i, k, num_max_bits, den_max_bits, bits1, bits2, Nbits, den_prec; if (N <= 1) { if (N == 1) arb_one(res); else arb_zero(res); return; } arb_init(t); arb_init(u); arb_init(sden); Nbits = FLINT_BIT_COUNT(N); num_max_bits = 0; for (i = 0; i < alen; i++) { bits1 = fmpz_bits(fmpq_numref(a + i)); bits2 = fmpz_bits(fmpq_denref(a + i)) + Nbits; num_max_bits += FLINT_MAX(bits1, bits2) + 1; } den_max_bits = 0; for (i = 0; i < blen; i++) { bits1 = fmpz_bits(fmpq_numref(b + i)); bits2 = fmpz_bits(fmpq_denref(b + i)) + Nbits; den_max_bits += FLINT_MAX(bits1, bits2) + 1; } den_prec = FLINT_MAX(128, prec + 2 * Nbits); if (num_max_bits <= FLINT_BITS - 1 && den_max_bits <= FLINT_BITS - 1) { slong num, den; den = 1; num = 1; for (i = 0; i < alen; i++) den *= *fmpq_denref(a + i); for (i = 0; i < blen; i++) num *= *fmpq_denref(b + i); if (reciprocal) { arb_mul_si(u, z, den, prec); arb_set_si(t, num); arb_div(u, t, u, prec); } else { arb_mul_si(u, z, num, prec); arb_div_si(u, u, den, prec); } arb_one(res); arb_one(t); arb_one(sden); for (k = 1; k < N && !arb_is_zero(t); k++) { arb_mul(t, t, u, prec); if (alen != 0) { num = *fmpq_denref(a + 0) * (k - 1) + *fmpq_numref(a + 0); for (i = 1; i < alen; i++) num *= (*fmpq_denref(a + i) * (k - 1) + *fmpq_numref(a + i)); arb_mul_si(t, t, num, prec); } if (blen != 0) { den = *fmpq_denref(b + 0) * (k - 1) + *fmpq_numref(b + 0); for (i = 1; i < blen; i++) den *= (*fmpq_denref(b + i) * (k - 1) + *fmpq_numref(b + i)); arb_fma_si(res, res, den, t, prec); arb_mul_si(sden, sden, den, den_prec); } else { arb_add(res, res, t, prec); } } arb_div(res, res, sden, prec); } else { fmpz_t num, den, c; fmpz_init(num); fmpz_init(den); fmpz_init(c); fmpz_one(den); fmpz_one(num); for (i = 0; i < alen; i++) fmpz_mul(den, den, fmpq_denref(a + i)); for (i = 0; i < blen; i++) fmpz_mul(num, num, fmpq_denref(b + i)); if (reciprocal) { arb_mul_fmpz(u, z, den, prec); arb_set_fmpz(t, num); arb_div(u, t, u, prec); } else { arb_mul_fmpz(u, z, num, prec); arb_div_fmpz(u, u, den, prec); } arb_one(res); arb_one(t); arb_one(sden); for (k = 1; k < N && !arb_is_zero(t); k++) { arb_mul(t, t, u, prec); if (alen != 0) { fmpz_mul_ui(num, fmpq_denref(a + 0), k - 1); fmpz_add(num, num, fmpq_numref(a + 0)); for (i = 1; i < alen; i++) { fmpz_mul_ui(c, fmpq_denref(a + i), k - 1); fmpz_add(c, c, fmpq_numref(a + i)); fmpz_mul(num, num, c); } arb_mul_fmpz(t, t, num, prec); } if (blen != 0) { fmpz_mul_ui(den, fmpq_denref(b + 0), k - 1); fmpz_add(den, den, fmpq_numref(b + 0)); for (i = 1; i < blen; i++) { fmpz_mul_ui(c, fmpq_denref(b + i), k - 1); fmpz_add(c, c, fmpq_numref(b + i)); fmpz_mul(den, den, c); } arb_fma_fmpz(res, res, den, t, prec); arb_mul_fmpz(sden, sden, den, den_prec); } else { arb_add(res, res, t, prec); } } arb_div(res, res, sden, prec); fmpz_clear(num); fmpz_clear(den); fmpz_clear(c); } arb_clear(t); arb_clear(u); arb_clear(sden); } arb-2.22.1/arb_hypgeom/sum_fmpq_arb_rs.c000066400000000000000000000216431417376376500202120ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static double d_log2_fac(double n) { return (n * (log(n) - 1.0)) * 1.4426950408889634; } static slong tail_precision(slong k, double min_k, slong alen, slong blen, double log2z, double log2max, slong prec) { double term_magnitude; slong new_prec; if (prec <= 128 || k <= 5 || k <= min_k) return prec; term_magnitude = k * log2z; if (alen != blen) term_magnitude += (alen - blen) * d_log2_fac(k); new_prec = prec - (log2max - term_magnitude) + 10; new_prec = FLINT_MIN(new_prec, prec); new_prec = FLINT_MAX(new_prec, 32); /* printf("term %ld, max %f, log2x %f, magn %f new_prec %ld\n", k, log2z, log2max, term_magnitude, new_prec); */ return new_prec; } /* Return approximation of log2(|x|), approximately clamped between COEFF_MIN and COEFF_MAX. */ double arf_get_d_log2_abs_approx_clamped(const arf_t x) { if (arf_is_zero(x)) { return COEFF_MIN; } else if (!arf_is_finite(x)) { return COEFF_MAX; } else if (COEFF_IS_MPZ(ARF_EXP(x))) { if (fmpz_sgn(ARF_EXPREF(x)) < 0) return COEFF_MIN; else return COEFF_MAX; } else { mp_srcptr tp; mp_size_t tn; double v; slong e = ARF_EXP(x); ARF_GET_MPN_READONLY(tp, tn, x); if (tn == 1) v = (double)(tp[0]); else v = (double)(tp[tn - 1]) + (double)(tp[tn - 2]) * ldexp(1.0, -FLINT_BITS); v *= ldexp(1.0, -FLINT_BITS); return 1.4426950408889634074 * mag_d_log_upper_bound(v) + (double) e; } } void arb_hypgeom_sum_fmpq_arb_rs(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { slong m, i, j, k, l, jlen, jbot, jtop, wp; double log2z, log2max, adaptive_min_k; int want_adaptive_precision; arb_t s, t; arb_ptr zpow; fmpz_t c, den; fmpz * cs; slong Nbits, acbits, bcbits, numbits, denbits; if (N <= 1) { if (N == 1) arb_one(res); else arb_zero(res); return; } m = n_sqrt(N); m = FLINT_MAX(m, 2); k = N - 1; j = k % m; jlen = 0; jbot = j; fmpz_init(c); fmpz_init(den); arb_init(s); arb_init(t); zpow = _arb_vec_init(m + 1); cs = _fmpz_vec_init(m + 1); fmpz_one(c); fmpz_one(den); for (i = 0; i < alen; i++) fmpz_mul(den, den, fmpq_denref(a + i)); for (i = 0; i < blen; i++) fmpz_mul(c, c, fmpq_denref(b + i)); if (reciprocal) { arb_mul_fmpz(zpow + m, z, den, prec); arb_set_fmpz(t, c); arb_div(zpow + m, t, zpow + m, prec); } else { arb_mul_fmpz(zpow + m, z, c, prec); arb_div_fmpz(zpow + m, zpow + m, den, prec); } want_adaptive_precision = N > 5; Nbits = FLINT_BIT_COUNT(N); acbits = 0; for (i = 0; i < alen; i++) { numbits = fmpz_bits(fmpq_numref(a + i)); denbits = fmpz_bits(fmpq_denref(a + i)); want_adaptive_precision = want_adaptive_precision && (FLINT_ABS(numbits - denbits) < 2); acbits += FLINT_MAX(denbits + Nbits, numbits) + 1; } bcbits = 0; for (i = 0; i < blen; i++) { numbits = fmpz_bits(fmpq_numref(b + i)); denbits = fmpz_bits(fmpq_denref(b + i)); want_adaptive_precision = want_adaptive_precision && (FLINT_ABS(numbits - denbits) < 2); bcbits += FLINT_MAX(denbits + Nbits, numbits) + 1; } log2max = 0.0; log2z = 0.0; adaptive_min_k = 0.0; if (want_adaptive_precision) { log2z = arf_get_d_log2_abs_approx_clamped(arb_midref(z)); if (reciprocal) log2z = -log2z; /* Terms are increasing, so don't change the precision. */ if (alen >= blen && log2z >= 0.0) { want_adaptive_precision = 0; } else { if (alen >= blen) { log2max = 0.0; } else { slong r = blen - alen; /* r = 1 -> exp(z) */ /* r = 2 -> exp(2*z^(1/2)) */ /* r = 3 -> exp(3*z^(1/3)) */ /* ... */ log2max = r * exp(log2z * 0.693147180559945 / r) * 1.44269504088896; /* fixme */ if (r == 1) adaptive_min_k = exp(log2z * log(2)); else adaptive_min_k = exp(0.5 * log2z * log(2)); } } } _arb_vec_set_powers(zpow, zpow + m, m + 1, prec); while (k >= 0) { jlen = 1; jtop = jbot = k; if (jtop > 0) { while (jlen <= j && jlen <= 8 && jbot >= 2) { jbot--; jlen++; } } if (jbot != jtop - jlen + 1) abort(); /* Factors between jbot and jtop inclusive */ if (jbot == 0 || alen == 0) { fmpz_one(cs + 0); } else { if (acbits <= FLINT_BITS - 1) { slong ac; ac = 1; for (l = 0; l < alen; l++) ac *= *fmpq_denref(a + l) * (jbot - 1) + *fmpq_numref(a + l); fmpz_set_si(cs + 0, ac); } else { fmpz_mul_ui(cs + 0, fmpq_denref(a + 0), jbot - 1); fmpz_add(cs + 0, cs + 0, fmpq_numref(a + 0)); for (l = 1; l < alen; l++) { fmpz_mul_ui(c, fmpq_denref(a + l), jbot - 1); fmpz_add(c, c, fmpq_numref(a + l)); fmpz_mul(cs + 0, cs + 0, c); } } } for (i = 1; i < jlen; i++) { if (alen == 0) { fmpz_set(cs + i, cs + i - 1); } else { if (acbits <= FLINT_BITS - 1) { slong ac; ac = 1; for (l = 0; l < alen; l++) ac *= *fmpq_denref(a + l) * (jbot + i - 1) + *fmpq_numref(a + l); fmpz_mul_si(cs + i, cs + i - 1, ac); } else { fmpz_mul_ui(cs + i, fmpq_denref(a + 0), jbot + i - 1); fmpz_add(cs + i, cs + i, fmpq_numref(a + 0)); for (l = 1; l < alen; l++) { fmpz_mul_ui(c, fmpq_denref(a + l), jbot + i - 1); fmpz_add(c, c, fmpq_numref(a + l)); fmpz_mul(cs + i, cs + i, c); } fmpz_mul(cs + i, cs + i, cs + i - 1); } } } if (blen != 0) { fmpz_one(den); for (i = jlen - 1; i >= 0; i--) { if (i != jlen - 1) fmpz_mul(cs + i, cs + i, den); if (i != 0 || jbot != 0) { if (bcbits <= FLINT_BITS - 1) { slong bc; bc = 1; for (l = 0; l < blen; l++) bc *= *fmpq_denref(b + l) * (jbot + i - 1) + *fmpq_numref(b + l); fmpz_mul_si(den, den, bc); } else { for (l = 0; l < blen; l++) { fmpz_mul_ui(c, fmpq_denref(b + l), jbot + i - 1); fmpz_add(c, c, fmpq_numref(b + l)); fmpz_mul(den, den, c); } } } } } if (want_adaptive_precision) wp = tail_precision(k - jlen, adaptive_min_k, alen, blen, log2z, log2max, prec); else wp = prec; arb_add(t, s, zpow + j, wp); arb_swap(zpow + j, t); arb_dot_fmpz(s, NULL, 0, zpow + j - jlen + 1, 1, cs, 1, jlen, wp); arb_swap(zpow + j, t); if (blen != 0) arb_div_fmpz(s, s, den, wp); k -= jlen; j -= (jlen - 1); if (j == 0 && k >= 1) { arb_mul(s, s, zpow + m, wp); j = m - 1; } else { j--; } } arb_swap(res, s); _arb_vec_clear(zpow, m + 1); _fmpz_vec_clear(cs, m + 1); arb_clear(s); arb_clear(t); fmpz_clear(c); fmpz_clear(den); } arb-2.22.1/arb_hypgeom/sum_fmpq_imag_arb.c000066400000000000000000000017301417376376500204760ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_sum_fmpq_imag_arb(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { if (N <= 10 || (prec <= 1024 && N <= 16)) arb_hypgeom_sum_fmpq_imag_arb_forward(res1, res2, a, alen, b, blen, z, reciprocal, N, prec); else if (prec >= 8192 && arb_bits(z) <= 0.001 * prec) arb_hypgeom_sum_fmpq_imag_arb_bs(res1, res2, a, alen, b, blen, z, reciprocal, N, prec); else arb_hypgeom_sum_fmpq_imag_arb_rs(res1, res2, a, alen, b, blen, z, reciprocal, N, prec); } arb-2.22.1/arb_hypgeom/sum_fmpq_imag_arb_bs.c000066400000000000000000000102671417376376500211670ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static void factor(arb_t A, const fmpq * a, slong alen, const fmpq * b, slong blen, const fmpz_t bden, const arb_t z, slong k, slong prec) { slong i; fmpz_t t, u; fmpz_init(t); fmpz_init(u); if (alen == 0) { if (z == NULL) arb_set_fmpz(A, bden); else if (fmpz_is_one(bden)) arb_set(A, z); else arb_mul_fmpz(A, z, bden, prec); } else { /* product of a_i + k = p/q + k = (p + k*q)/q */ fmpz_mul_ui(t, fmpq_denref(a + 0), k); fmpz_add(t, t, fmpq_numref(a + 0)); for (i = 1; i < alen; i++) { fmpz_mul_ui(u, fmpq_denref(a + i), k); fmpz_add(u, u, fmpq_numref(a + i)); fmpz_mul(t, t, u); } if (!fmpz_is_one(bden)) fmpz_mul(t, t, bden); if (z == NULL) arb_set_fmpz(A, t); else arb_mul_fmpz(A, z, t, prec); } fmpz_clear(t); fmpz_clear(u); } static void bsplit(acb_t A1, acb_t B1, acb_t C1, const fmpq * a, slong alen, const fmpz_t aden, const fmpq * b, slong blen, const fmpz_t bden, const arb_t z, int reciprocal, slong aa, slong bb, slong prec) { if (bb - aa == 1) { factor(acb_realref(A1), a, alen, b, blen, bden, reciprocal ? NULL : z, aa, prec); factor(acb_realref(C1), b, blen, a, alen, aden, reciprocal ? z : NULL, aa, prec); arb_zero(acb_imagref(A1)); arb_zero(acb_imagref(C1)); if (reciprocal) acb_div_onei(C1, C1); else acb_mul_onei(A1, A1); /* arb_set(B1, C1); but we skip this */ } else { slong m; acb_t A2, B2, C2; acb_init(A2); acb_init(B2); acb_init(C2); m = aa + (bb - aa) / 2; bsplit(A1, B1, C1, a, alen, aden, b, blen, bden, z, reciprocal, aa, m, prec); bsplit(A2, B2, C2, a, alen, aden, b, blen, bden, z, reciprocal, m, bb, prec); if (bb - m == 1) /* B2 = C2 */ { if (m - aa == 1) acb_add(B2, A1, C1, prec); else acb_add(B2, A1, B1, prec); acb_mul(B1, B2, C2, prec); } else { if (m - aa == 1) acb_mul(B1, C1, C2, prec); else acb_mul(B1, B1, C2, prec); acb_addmul(B1, A1, B2, prec); } acb_mul(A1, A1, A2, prec); acb_mul(C1, C1, C2, prec); acb_clear(A2); acb_clear(B2); acb_clear(C2); } } void arb_hypgeom_sum_fmpq_imag_arb_bs(arb_t res_real, arb_t res_imag, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { acb_t u, v, w; fmpz_t aden, bden; slong i; if (N <= 3) { arb_hypgeom_sum_fmpq_imag_arb_forward(res_real, res_imag, a, alen, b, blen, z, reciprocal, N, prec); return; } acb_init(u); acb_init(v); acb_init(w); fmpz_init(aden); fmpz_init(bden); fmpz_one(aden); fmpz_one(bden); for (i = 0; i < alen; i++) fmpz_mul(aden, aden, fmpq_denref(a + i)); for (i = 0; i < blen; i++) fmpz_mul(bden, bden, fmpq_denref(b + i)); /* we compute to N-1 instead of N to avoid dividing by 0 in the denominator when computing a hypergeometric polynomial that terminates right before a pole */ bsplit(u, v, w, a, alen, aden, b, blen, bden, z, reciprocal, 0, N - 1, prec); acb_add(u, u, v, prec); /* s = s + t */ acb_div(u, u, w, prec); if (!acb_is_finite(u)) acb_indeterminate(u); arb_swap(res_real, acb_realref(u)); arb_swap(res_imag, acb_imagref(u)); acb_clear(u); acb_clear(v); acb_clear(w); fmpz_clear(aden); fmpz_clear(bden); } arb-2.22.1/arb_hypgeom/sum_fmpq_imag_arb_forward.c000066400000000000000000000164551417376376500222340ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void arb_hypgeom_sum_fmpq_imag_arb_forward(arb_t s_real, arb_t s_imag, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { arb_t t, u, sden; slong i, k, num_max_bits, den_max_bits, bits1, bits2, Nbits, den_prec;; if (N <= 1) { if (N == 1) arb_one(s_real); else arb_zero(s_real); arb_zero(s_imag); return; } arb_init(t); arb_init(u); arb_init(sden); Nbits = FLINT_BIT_COUNT(N); num_max_bits = 0; for (i = 0; i < alen; i++) { bits1 = fmpz_bits(fmpq_numref(a + i)); bits2 = fmpz_bits(fmpq_denref(a + i)) + Nbits; num_max_bits += FLINT_MAX(bits1, bits2) + 1; } den_max_bits = 0; for (i = 0; i < blen; i++) { bits1 = fmpz_bits(fmpq_numref(b + i)); bits2 = fmpz_bits(fmpq_denref(b + i)) + Nbits; den_max_bits += FLINT_MAX(bits1, bits2) + 1; } den_prec = FLINT_MAX(128, prec + 2 * Nbits); if (num_max_bits <= FLINT_BITS - 1 && den_max_bits <= FLINT_BITS - 1) { slong num, den; den = 1; num = 1; for (i = 0; i < alen; i++) den *= *fmpq_denref(a + i); for (i = 0; i < blen; i++) num *= *fmpq_denref(b + i); if (reciprocal) { arb_mul_si(u, z, den, prec); arb_set_si(t, num); arb_div(u, t, u, prec); } else { arb_mul_si(u, z, num, prec); arb_div_si(u, u, den, prec); } arb_one(s_real); arb_zero(s_imag); arb_one(t); arb_one(sden); for (k = 1; k < N && !arb_is_zero(t); k++) { arb_mul(t, t, u, prec); if (alen != 0) { num = *fmpq_denref(a + 0) * (k - 1) + *fmpq_numref(a + 0); for (i = 1; i < alen; i++) num *= (*fmpq_denref(a + i) * (k - 1) + *fmpq_numref(a + i)); arb_mul_si(t, t, num, prec); } if (blen != 0) { den = *fmpq_denref(b + 0) * (k - 1) + *fmpq_numref(b + 0); for (i = 1; i < blen; i++) den *= (*fmpq_denref(b + i) * (k - 1) + *fmpq_numref(b + i)); if (k % 4 == 0) { arb_fma_si(s_real, s_real, den, t, prec); arb_mul_si(s_imag, s_imag, den, prec); } else if (k % 4 == 1) { arb_fma_si(s_imag, s_imag, den, t, prec); arb_mul_si(s_real, s_real, den, prec); } else if (k % 4 == 2) { arb_neg(t, t); arb_fma_si(s_real, s_real, den, t, prec); arb_neg(t, t); arb_mul_si(s_imag, s_imag, den, prec); } else { arb_neg(t, t); arb_fma_si(s_imag, s_imag, den, t, prec); arb_neg(t, t); arb_mul_si(s_real, s_real, den, prec); } arb_mul_si(sden, sden, den, den_prec); } else { if (k % 4 == 0) arb_add(s_real, s_real, t, prec); else if (k % 4 == 1) arb_add(s_imag, s_imag, t, prec); else if (k % 4 == 2) arb_sub(s_real, s_real, t, prec); else arb_sub(s_imag, s_imag, t, prec); } } arb_div(s_real, s_real, sden, prec); arb_div(s_imag, s_imag, sden, prec); } else { fmpz_t num, den, c; fmpz_init(num); fmpz_init(den); fmpz_init(c); fmpz_one(den); fmpz_one(num); for (i = 0; i < alen; i++) fmpz_mul(den, den, fmpq_denref(a + i)); for (i = 0; i < blen; i++) fmpz_mul(num, num, fmpq_denref(b + i)); if (reciprocal) { arb_mul_fmpz(u, z, den, prec); arb_set_fmpz(t, num); arb_div(u, t, u, prec); } else { arb_mul_fmpz(u, z, num, prec); arb_div_fmpz(u, u, den, prec); } arb_one(s_real); arb_zero(s_imag); arb_one(t); arb_one(sden); for (k = 1; k < N && !arb_is_zero(t); k++) { arb_mul(t, t, u, prec); if (alen != 0) { fmpz_mul_ui(num, fmpq_denref(a + 0), k - 1); fmpz_add(num, num, fmpq_numref(a + 0)); for (i = 1; i < alen; i++) { fmpz_mul_ui(c, fmpq_denref(a + i), k - 1); fmpz_add(c, c, fmpq_numref(a + i)); fmpz_mul(num, num, c); } arb_mul_fmpz(t, t, num, prec); } if (blen != 0) { fmpz_mul_ui(den, fmpq_denref(b + 0), k - 1); fmpz_add(den, den, fmpq_numref(b + 0)); for (i = 1; i < blen; i++) { fmpz_mul_ui(c, fmpq_denref(b + i), k - 1); fmpz_add(c, c, fmpq_numref(b + i)); fmpz_mul(den, den, c); } if (k % 4 == 0) { arb_fma_fmpz(s_real, s_real, den, t, prec); arb_mul_fmpz(s_imag, s_imag, den, prec); } else if (k % 4 == 1) { arb_fma_fmpz(s_imag, s_imag, den, t, prec); arb_mul_fmpz(s_real, s_real, den, prec); } else if (k % 4 == 2) { arb_neg(t, t); arb_fma_fmpz(s_real, s_real, den, t, prec); arb_neg(t, t); arb_mul_fmpz(s_imag, s_imag, den, prec); } else { arb_neg(t, t); arb_fma_fmpz(s_imag, s_imag, den, t, prec); arb_neg(t, t); arb_mul_fmpz(s_real, s_real, den, prec); } arb_mul_fmpz(sden, sden, den, den_prec); } else { if (k % 4 == 0) arb_add(s_real, s_real, t, prec); else if (k % 4 == 1) arb_add(s_imag, s_imag, t, prec); else if (k % 4 == 2) arb_sub(s_real, s_real, t, prec); else arb_sub(s_imag, s_imag, t, prec); } } arb_div(s_real, s_real, sden, prec); arb_div(s_imag, s_imag, sden, prec); fmpz_clear(num); fmpz_clear(den); fmpz_clear(c); } arb_clear(t); arb_clear(u); arb_clear(sden); } arb-2.22.1/arb_hypgeom/sum_fmpq_imag_arb_rs.c000066400000000000000000000237331417376376500212110ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" static double d_log2_fac(double n) { return (n * (log(n) - 1.0)) * 1.4426950408889634; } static slong tail_precision(slong k, double min_k, slong alen, slong blen, double log2z, double log2max, slong prec) { double term_magnitude; slong new_prec; if (prec <= 128 || k <= 5 || k <= min_k) return prec; term_magnitude = k * log2z; if (alen != blen) term_magnitude += (alen - blen) * d_log2_fac(k); new_prec = prec - (log2max - term_magnitude) + 10; new_prec = FLINT_MIN(new_prec, prec); new_prec = FLINT_MAX(new_prec, 32); /* printf("term %ld, max %f, log2x %f, magn %f new_prec %ld\n", k, log2z, log2max, term_magnitude, new_prec); */ return new_prec; } /* Return approximation of log2(|x|), clambed between COEFF_MIN and COEFF_MAX. */ double arf_get_d_log2_abs_approx_clamped(const arf_t x); void arb_hypgeom_sum_fmpq_imag_arb_rs(arb_t res_real, arb_t res_imag, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) { slong m, i, j, k, l, jlen, jbot, jtop, wp; double log2z, log2max, adaptive_min_k; int want_adaptive_precision; arb_t s_real, s_imag, t_real, t_imag; arb_ptr zpow; fmpz_t c, den; fmpz * cs; slong Nbits, acbits, bcbits, numbits, denbits; m = n_sqrt(N); m = FLINT_MAX(m, 2); k = N - 1; j = k % m; jlen = 0; jbot = j; fmpz_init(c); fmpz_init(den); arb_init(s_real); arb_init(s_imag); arb_init(t_real); arb_init(t_imag); zpow = _arb_vec_init(m + 1); cs = _fmpz_vec_init(m + 1); fmpz_one(c); fmpz_one(den); for (i = 0; i < alen; i++) fmpz_mul(den, den, fmpq_denref(a + i)); for (i = 0; i < blen; i++) fmpz_mul(c, c, fmpq_denref(b + i)); if (reciprocal) { arb_mul_fmpz(zpow + m, z, den, prec); arb_set_fmpz(t_real, c); arb_div(zpow + m, t_real, zpow + m, prec); } else { arb_mul_fmpz(zpow + m, z, c, prec); arb_div_fmpz(zpow + m, zpow + m, den, prec); } want_adaptive_precision = N > 5; Nbits = FLINT_BIT_COUNT(N); acbits = 0; for (i = 0; i < alen; i++) { numbits = fmpz_bits(fmpq_numref(a + i)); denbits = fmpz_bits(fmpq_denref(a + i)); want_adaptive_precision = want_adaptive_precision && (FLINT_ABS(numbits - denbits) < 2); acbits += FLINT_MAX(denbits + Nbits, numbits) + 1; } bcbits = 0; for (i = 0; i < blen; i++) { numbits = fmpz_bits(fmpq_numref(b + i)); denbits = fmpz_bits(fmpq_denref(b + i)); want_adaptive_precision = want_adaptive_precision && (FLINT_ABS(numbits - denbits) < 2); bcbits += FLINT_MAX(denbits + Nbits, numbits) + 1; } log2max = 0.0; log2z = 0.0; adaptive_min_k = 0.0; if (want_adaptive_precision) { log2z = arf_get_d_log2_abs_approx_clamped(arb_midref(z)); if (reciprocal) log2z = -log2z; /* Terms are increasing, so don't change the precision. */ if (alen >= blen && log2z >= 0.0) { want_adaptive_precision = 0; } else { if (alen >= blen) { log2max = 0.0; adaptive_min_k = N; } else { slong r = blen - alen; /* r = 1 -> exp(z) */ /* r = 2 -> exp(2*z^(1/2)) */ /* r = 3 -> exp(3*z^(1/3)) */ /* ... */ log2max = r * exp(log2z * 0.693147180559945 / r) * 1.44269504088896; /* fixme */ if (r == 1) adaptive_min_k = exp(log2z * log(2)); else adaptive_min_k = exp(0.5 * log2z * log(2)); } } } _arb_vec_set_powers(zpow, zpow + m, m + 1, prec); while (k >= 0) { jlen = 1; jtop = jbot = k; if (jtop > 0) { while (jlen <= j && jlen <= 12 && jbot >= 2) { jbot--; jlen++; } } if (jbot != jtop - jlen + 1) abort(); /* Factors between jbot and jtop inclusive */ if (jbot == 0 || alen == 0) { fmpz_one(cs + 0); } else { if (acbits <= FLINT_BITS - 1) { slong ac; ac = 1; for (l = 0; l < alen; l++) ac *= *fmpq_denref(a + l) * (jbot - 1) + *fmpq_numref(a + l); fmpz_set_si(cs + 0, ac); } else { fmpz_mul_ui(cs + 0, fmpq_denref(a + 0), jbot - 1); fmpz_add(cs + 0, cs + 0, fmpq_numref(a + 0)); for (l = 1; l < alen; l++) { fmpz_mul_ui(c, fmpq_denref(a + l), jbot - 1); fmpz_add(c, c, fmpq_numref(a + l)); fmpz_mul(cs + 0, cs + 0, c); } } } for (i = 1; i < jlen; i++) { if (alen == 0) { fmpz_set(cs + i, cs + i - 1); } else { if (acbits <= FLINT_BITS - 1) { slong ac; ac = 1; for (l = 0; l < alen; l++) ac *= *fmpq_denref(a + l) * (jbot + i - 1) + *fmpq_numref(a + l); fmpz_mul_si(cs + i, cs + i - 1, ac); } else { fmpz_mul_ui(cs + i, fmpq_denref(a + 0), jbot + i - 1); fmpz_add(cs + i, cs + i, fmpq_numref(a + 0)); for (l = 1; l < alen; l++) { fmpz_mul_ui(c, fmpq_denref(a + l), jbot + i - 1); fmpz_add(c, c, fmpq_numref(a + l)); fmpz_mul(cs + i, cs + i, c); } fmpz_mul(cs + i, cs + i, cs + i - 1); } } } if (blen != 0) { fmpz_one(den); for (i = jlen - 1; i >= 0; i--) { if (i != jlen - 1) fmpz_mul(cs + i, cs + i, den); if (i != 0 || jbot != 0) { if (bcbits <= FLINT_BITS - 1) { slong bc; bc = 1; for (l = 0; l < blen; l++) bc *= *fmpq_denref(b + l) * (jbot + i - 1) + *fmpq_numref(b + l); fmpz_mul_si(den, den, bc); } else { for (l = 0; l < blen; l++) { fmpz_mul_ui(c, fmpq_denref(b + l), jbot + i - 1); fmpz_add(c, c, fmpq_numref(b + l)); fmpz_mul(den, den, c); } } } } } if (want_adaptive_precision) wp = tail_precision(k - jlen, adaptive_min_k, alen, blen, log2z, log2max, prec); else wp = prec; /* s = 0 for i in range(jlen): s += cs[i] * zpow[j - jlen + 1 + i] * i^(j - jlen + 1 + i) s += cs[jlen - 1] * (s_real, s_imag) (s_real, s_imag) = s / den */ l = j - jlen + 1; for (i = (2 - l) & 3; i < jlen; i += 4) fmpz_neg(cs + i, cs + i); for (i = (3 - l) & 3; i < jlen; i += 4) fmpz_neg(cs + i, cs + i); if (l % 2 == 0) { arb_dot_fmpz(t_real, NULL, 0, zpow + j - jlen + 1, 2, cs, 2, (jlen + 1) / 2, wp); arb_dot_fmpz(t_imag, NULL, 0, zpow + j - jlen + 1 + 1, 2, cs + 1, 2, jlen / 2, wp); } else { arb_dot_fmpz(t_imag, NULL, 0, zpow + j - jlen + 1, 2, cs, 2, (jlen + 1) / 2, wp); arb_dot_fmpz(t_real, NULL, 0, zpow + j - jlen + 1 + 1, 2, cs + 1, 2, jlen / 2, wp); } if ((jlen - 1 + l) % 4 >= 2) { arb_submul_fmpz(t_real, s_real, cs + jlen - 1, wp); arb_submul_fmpz(t_imag, s_imag, cs + jlen - 1, wp); } else { arb_addmul_fmpz(t_real, s_real, cs + jlen - 1, wp); arb_addmul_fmpz(t_imag, s_imag, cs + jlen - 1, wp); } arb_swap(s_real, t_real); arb_swap(s_imag, t_imag); if (blen != 0) { arb_div_fmpz(s_real, s_real, den, wp); arb_div_fmpz(s_imag, s_imag, den, wp); } k -= jlen; j -= (jlen - 1); if (j == 0 && k >= 1) { arb_mul(s_real, s_real, zpow + m, wp); arb_mul(s_imag, s_imag, zpow + m, wp); if (m % 4 == 1) { arb_swap(s_real, s_imag); arb_neg(s_real, s_real); } else if (m % 4 == 2) { arb_neg(s_real, s_real); arb_neg(s_imag, s_imag); } else if (m % 4 == 3) { arb_swap(s_real, s_imag); arb_neg(s_imag, s_imag); } j = m - 1; } else { j--; } } arb_swap(res_real, s_real); arb_swap(res_imag, s_imag); _arb_vec_clear(zpow, m + 1); _fmpz_vec_clear(cs, m + 1); arb_clear(s_real); arb_clear(s_imag); arb_clear(t_real); arb_clear(t_imag); fmpz_clear(c); fmpz_clear(den); } arb-2.22.1/arb_hypgeom/test/000077500000000000000000000000001417376376500156405ustar00rootroot00000000000000arb-2.22.1/arb_hypgeom/test/t-1f1_integration.c000066400000000000000000000101751417376376500212430ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("1f1_integration...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_t a, b, z, r1, r2; slong prec1, prec2; int regularized; prec1 = 2 + n_randint(state, 80); prec2 = 2 + n_randint(state, 150); arb_init(a); arb_init(b); arb_init(z); arb_init(r1); arb_init(r2); regularized = n_randint(state, 2); arb_randtest_precise(a, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(b, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest(r1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_randtest(r2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_add_ui(a, a, n_randint(state, 100), prec1 + 100); arb_add_ui(b, b, n_randint(state, 200), prec1 + 100); arb_add_ui(z, z, n_randint(state, 100), prec1 + 100); arb_hypgeom_1f1_integration(r1, a, b, z, regularized, prec1); if (arb_is_finite(r1)) { if (n_randint(state, 2)) arb_hypgeom_1f1(r2, a, b, z, regularized, prec2); else arb_hypgeom_1f1_integration(r2, a, b, z, regularized, prec2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); arb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } if (iter == 0) { prec1 = 333; arb_set_str(a, "1.2e7", prec1); arb_set_str(b, "1.3e8", prec1); arb_set_str(z, "1.4e8", prec1); arb_hypgeom_1f1_integration(r1, a, b, z, 0, prec1); arb_set_str(r2, "4.490048760185759949474587200300668633822146852907335040923195547203089703047764681072928822e+11143817 +/- 4.55e+11143726", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (1)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } arb_set_str(a, "1.2e14", prec1); arb_set_str(b, "1.3e15", prec1); arb_set_str(z, "1.4e14", prec1); arb_hypgeom_1f1_integration(r1, a, b, z, 0, prec1); arb_set_str(r2, "7.52012593871057092343210829853229360099866571986384089587141298507823992233368715541e+5903762458197 +/- 5.51e+5903762458113", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(b); arb_clear(z); arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-2f1_integration.c000066400000000000000000000107661417376376500212520ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("2f1_integration...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c, z, r1, r2; slong prec1, prec2; int regularized; prec1 = 2 + n_randint(state, 80); prec2 = 2 + n_randint(state, 150); arb_init(a); arb_init(b); arb_init(c); arb_init(z); arb_init(r1); arb_init(r2); regularized = n_randint(state, 2); arb_randtest_precise(a, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(b, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(c, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest(r1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_randtest(r2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_add_ui(a, a, n_randint(state, 100), prec1 + 100); arb_add_ui(b, b, n_randint(state, 200), prec1 + 100); arb_add_ui(c, c, n_randint(state, 300), prec1 + 100); arb_add_ui(z, z, n_randint(state, 100), prec1 + 100); arb_hypgeom_2f1_integration(r1, a, b, c, z, regularized, prec1); if (arb_is_finite(r1)) { if (n_randint(state, 2)) arb_hypgeom_2f1(r2, a, b, c, z, regularized, prec2); else arb_hypgeom_2f1_integration(r2, a, b, c, z, regularized, prec2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); arb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } if (iter == 0) { prec1 = 333; arb_set_str(b, "2651.1", prec1); arb_set_str(a, "50131.3", prec1); arb_set_str(c, "72923.5", prec1); arb_set_str(z, "-123.5", prec1); arb_hypgeom_2f1_integration(r1, a, b, c, z, 0, prec1); arb_set_str(r2, "2.334513854528911419992516597096504294432862073292366983166036504547076680083826439493425898608e-5118 +/- 2.73e-5212", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (1)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } arb_set_str(b, "1.1e10", prec1); arb_set_str(a, "1.2e11", prec1); arb_set_str(c, "1.3e12", prec1); arb_set_str(z, "0.7", prec1); arb_hypgeom_2f1_integration(r1, a, b, c, z, 0, prec1); arb_set_str(r2, "5.86281189034275194553834976777402286036616612793483753071706787203236651175920694151330e+320059600 +/- 1.96e+320059513", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(z); arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-airy_zero.c000066400000000000000000000140431417376376500202520ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("airy_zero...."); fflush(stdout); flint_randinit(state); /* interlacing test */ { arb_t a, ap, b, bp, ap1; fmpz_t n; arb_init(a); arb_init(ap); arb_init(b); arb_init(bp); arb_init(ap1); fmpz_init(n); for (fmpz_one(n); fmpz_cmp_ui(n, 200) <= 0; fmpz_add_ui(n, n, 1)) { arb_hypgeom_airy_zero(a, ap, b, bp, n, 53); fmpz_add_ui(n, n, 1); arb_hypgeom_airy_zero(NULL, ap1, NULL, NULL, n, 53); fmpz_sub_ui(n, n, 1); if (!arb_gt(ap, b) || !arb_gt(b, bp) || !arb_gt(bp, a) || !arb_gt(a, ap1)) { flint_printf("FAIL: interlacing\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 100, 0); flint_printf("\n\n"); flint_printf("ap = "); arb_printn(ap, 100, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 100, 0); flint_printf("\n\n"); flint_printf("bp = "); arb_printn(bp, 100, 0); flint_printf("\n\n"); flint_printf("ap1 = "); arb_printn(ap1, 100, 0); flint_printf("\n\n"); flint_abort(); } } for (fmpz_set_ui(n, 1000000); fmpz_cmp_ui(n, 1000000 + 200) <= 0; fmpz_add_ui(n, n, 1)) { arb_hypgeom_airy_zero(a, ap, b, bp, n, 53); fmpz_add_ui(n, n, 1); arb_hypgeom_airy_zero(NULL, ap1, NULL, NULL, n, 53); fmpz_sub_ui(n, n, 1); if (!arb_gt(ap, b) || !arb_gt(b, bp) || !arb_gt(bp, a) || !arb_gt(a, ap1)) { flint_printf("FAIL: interlacing\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 100, 0); flint_printf("\n\n"); flint_printf("ap = "); arb_printn(ap, 100, 0); flint_printf("\n\n"); flint_printf("b = "); arb_printn(b, 100, 0); flint_printf("\n\n"); flint_printf("bp = "); arb_printn(bp, 100, 0); flint_printf("\n\n"); flint_printf("ap1 = "); arb_printn(ap1, 100, 0); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(ap); arb_clear(b); arb_clear(bp); arb_clear(ap1); fmpz_clear(n); } /* self-consistency and accuracy test */ for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_t x1, x2, v1, v2; fmpz_t n; slong prec1, prec2; int which; arb_init(x1); arb_init(x2); arb_init(v1); arb_init(v2); fmpz_init(n); fmpz_randtest(n, state, 200); fmpz_abs(n, n); fmpz_add_ui(n, n, 1); prec1 = 2 + n_randtest(state) % 1000; prec2 = 2 + n_randtest(state) % 1000; which = n_randint(state, 4); if (which == 0) { arb_hypgeom_airy_zero(x1, NULL, NULL, NULL, n, prec1); arb_hypgeom_airy_zero(x2, NULL, NULL, NULL, n, prec2); arb_hypgeom_airy(v1, NULL, NULL, NULL, x1, prec1 + 30); arb_hypgeom_airy(v2, NULL, NULL, NULL, x2, prec2 + 30); } else if (which == 1) { arb_hypgeom_airy_zero(NULL, x1, NULL, NULL, n, prec1); arb_hypgeom_airy_zero(NULL, x2, NULL, NULL, n, prec2); arb_hypgeom_airy(NULL, v1, NULL, NULL, x1, prec1 + 30); arb_hypgeom_airy(NULL, v2, NULL, NULL, x2, prec2 + 30); } else if (which == 2) { arb_hypgeom_airy_zero(NULL, NULL, x1, NULL, n, prec1); arb_hypgeom_airy_zero(NULL, NULL, x2, NULL, n, prec2); arb_hypgeom_airy(NULL, NULL, v1, NULL, x1, prec1 + 30); arb_hypgeom_airy(NULL, NULL, v2, NULL, x2, prec2 + 30); } else { arb_hypgeom_airy_zero(NULL, NULL, NULL, x1, n, prec1); arb_hypgeom_airy_zero(NULL, NULL, NULL, x2, n, prec2); arb_hypgeom_airy(NULL, NULL, NULL, v1, x1, prec1 + 30); arb_hypgeom_airy(NULL, NULL, NULL, v2, x2, prec2 + 30); } if (!arb_overlaps(x1, x2) || !arb_contains_zero(v1) || !arb_contains_zero(v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("which = %d, n = ", which); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_printf("v1 = "); arb_printn(v1, 100, 0); flint_printf("\n\n"); flint_printf("v2 = "); arb_printn(v2, 100, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(x1) < prec1 - 3 || arb_rel_accuracy_bits(x2) < prec2 - 3) { flint_printf("FAIL: accuracy\n\n"); flint_printf("which = %d, n = ", which); fmpz_print(n); flint_printf(" prec1 = %wd prec2 = %wd\n\n", prec1, prec2); flint_printf("acc(x1) = %wd, acc(x2) = %wd\n\n", arb_rel_accuracy_bits(x1), arb_rel_accuracy_bits(x2)); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x1); arb_clear(x2); arb_clear(v1); arb_clear(v2); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-bessel_i_integration.c000066400000000000000000000047221417376376500224420ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_i_integration...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_t a, z, r1, r2; slong prec1, prec2; int scaled; prec1 = 2 + n_randint(state, 80); prec2 = 2 + n_randint(state, 150); arb_init(a); arb_init(z); arb_init(r1); arb_init(r2); scaled = n_randint(state, 2); arb_randtest_precise(a, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest(r1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_randtest(r2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_add_ui(a, a, n_randint(state, 100), prec1 + 100); arb_add_ui(z, z, n_randint(state, 100), prec1 + 100); arb_hypgeom_bessel_i_integration(r1, a, z, scaled, prec1); if (arb_is_finite(r1)) { if (n_randint(state, 2)) arb_hypgeom_bessel_i_integration(r2, a, z, scaled, prec2); else { if (scaled) arb_hypgeom_bessel_i_scaled(r2, a, z, prec2); else arb_hypgeom_bessel_i(r2, a, z, prec2); } if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); arb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(z); arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-bessel_j.c000066400000000000000000000045121417376376500200350ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_j...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, y, nu; slong prec; arb_init(x); arb_init(y); arb_init(nu); prec = 2 + n_randint(state, 200); arb_randtest(nu, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_pos_inf(x); arb_hypgeom_bessel_j(y, nu, x, prec); if (arb_is_finite(nu) && !arb_is_zero(y)) { flint_printf("FAIL: positive infinity\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("nu = "); arb_printd(nu, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } arb_neg_inf(x); arb_hypgeom_bessel_j(y, nu, x, prec); if (arb_is_finite(nu) && !arb_is_zero(y)) { flint_printf("FAIL: negative infinity\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("nu = "); arb_printd(nu, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } arb_indeterminate(x); arb_hypgeom_bessel_j(y, nu, x, prec); if (!arf_is_nan(arb_midref(y))) { flint_printf("FAIL: indeterminate\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("nu = "); arb_printd(nu, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(nu); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-bessel_k_integration.c000066400000000000000000000047221417376376500224440ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_k_integration...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_t a, z, r1, r2; slong prec1, prec2; int scaled; prec1 = 2 + n_randint(state, 80); prec2 = 2 + n_randint(state, 150); arb_init(a); arb_init(z); arb_init(r1); arb_init(r2); scaled = n_randint(state, 2); arb_randtest_precise(a, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest(r1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_randtest(r2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_add_ui(a, a, n_randint(state, 100), prec1 + 100); arb_add_ui(z, z, n_randint(state, 100), prec1 + 100); arb_hypgeom_bessel_k_integration(r1, a, z, scaled, prec1); if (arb_is_finite(r1)) { if (n_randint(state, 2)) arb_hypgeom_bessel_k_integration(r2, a, z, scaled, prec2); else { if (scaled) arb_hypgeom_bessel_k_scaled(r2, a, z, prec2); else arb_hypgeom_bessel_k(r2, a, z, prec2); } if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); arb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(z); arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-bessel_y.c000066400000000000000000000045121417376376500200540ustar00rootroot00000000000000/* Copyright (C) 2020 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("bessel_y...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t x, y, nu; slong prec; arb_init(x); arb_init(y); arb_init(nu); prec = 2 + n_randint(state, 200); arb_randtest(nu, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_pos_inf(x); arb_hypgeom_bessel_y(y, nu, x, prec); if (arb_is_finite(nu) && !arb_is_zero(y)) { flint_printf("FAIL: positive infinity\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("nu = "); arb_printd(nu, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } arb_neg_inf(x); arb_hypgeom_bessel_y(y, nu, x, prec); if (arb_is_finite(nu) && !arb_is_zero(y)) { flint_printf("FAIL: negative infinity\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("nu = "); arb_printd(nu, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } arb_indeterminate(x); arb_hypgeom_bessel_y(y, nu, x, prec); if (!arf_is_nan(arb_midref(y))) { flint_printf("FAIL: indeterminate\n\n"); flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n"); flint_printf("nu = "); arb_printd(nu, 50); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(nu); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-central_bin_ui.c000066400000000000000000000041531417376376500212250ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("central_bin_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t b1, b2, t; ulong n; slong prec1, prec2, acc1; n = n_randtest(state); prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(b1); arb_init(b2); arb_init(t); arb_hypgeom_central_bin_ui(b1, n, prec1); arb_set_ui(t, n); arb_add_ui(t, t, n, prec2); arb_add_ui(t, t, 1, prec2); arb_gamma(t, t, prec2); arb_set_ui(b2, n); arb_add_ui(b2, b2, 1, prec2); arb_rgamma(b2, b2, prec2); arb_mul(b2, b2, b2, prec2); arb_mul(b2, b2, t, prec2); if (!arb_overlaps(b1, b2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("b1 = "); arb_printn(b1, 50, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, 50, 0); flint_printf("\n\n"); flint_abort(); } acc1 = arb_rel_accuracy_bits(b1); if (acc1 < prec1 - 2) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec1 = %wd, acc1 = %wd\n", prec1, acc1); flint_printf("b1 = "); arb_printn(b1, prec1 / 3.33, 0); flint_printf("\n\n"); flint_printf("b2 = "); arb_printn(b2, prec2 / 3.33, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(b1); arb_clear(b2); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-ci.c000066400000000000000000000050561417376376500166460ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("ci...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, s, t; slong prec1, prec2; arb_init(x); arb_init(s); arb_init(t); if (n_randint(state, 10) == 0) { prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); } else { prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); } arb_randtest(x, state, 2 + n_randint(state, prec1), 2 + n_randint(state, 100)); arb_randtest(s, state, 2 + n_randint(state, prec1), 2 + n_randint(state, 100)); arb_randtest(t, state, 2 + n_randint(state, prec1), 2 + n_randint(state, 100)); switch (n_randint(state, 3)) { case 0: arb_hypgeom_ci(s, x, prec1); break; case 1: _arb_hypgeom_ci_2f3(s, x, n_randint(state, prec1), prec1, prec1); break; default: _arb_hypgeom_ci_asymp(s, x, n_randint(state, prec1 / 2), prec1); break; } switch (n_randint(state, 3)) { case 0: arb_hypgeom_ci(t, x, prec2); break; case 1: _arb_hypgeom_ci_2f3(t, x, n_randint(state, prec2), prec2, prec2); break; default: _arb_hypgeom_ci_asymp(t, x, n_randint(state, prec2 / 2), prec2); break; } if (!arb_overlaps(s, t)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 100, 0); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(s); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-coulomb_series.c000066400000000000000000000112251417376376500212600ustar00rootroot00000000000000/* Copyright (C) 2019 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("coulomb_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_poly_t F, G, F2, G2, z, w, t, u; arb_t c, l, eta, z0; slong n1, n2, prec1, prec2; unsigned int mask; arb_poly_init(F); arb_poly_init(G); arb_poly_init(F2); arb_poly_init(G2); arb_poly_init(z); arb_poly_init(w); arb_poly_init(t); arb_poly_init(u); arb_init(c); arb_init(l); arb_init(eta); arb_init(z0); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); n1 = n_randint(state, 8); n2 = n_randint(state, 8); arb_poly_randtest(F, state, 10, prec1, 10); arb_poly_randtest(G, state, 10, prec1, 10); arb_randtest(l, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); arb_randtest(eta, state, 1 + n_randint(state, 200), 1 + n_randint(state, 10)); arb_poly_randtest(z, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); arb_hypgeom_coulomb_series(F, G, l, eta, z, n1, prec1); /* F' G - F G' = 1 */ arb_poly_derivative(t, F, prec1); arb_poly_set(u, G); arb_poly_mullow(w, t, u, FLINT_MAX(n1 - 1, 0), prec1); arb_poly_derivative(u, u, prec1); arb_poly_mullow(t, F, u, FLINT_MAX(n1 - 1, 0), prec1); arb_poly_sub(w, w, t, prec1); arb_poly_derivative(t, z, prec1); arb_poly_truncate(t, FLINT_MAX(n1 - 1, 0)); /* hack: work around mullow(nan, 0) = 0 */ arb_poly_get_coeff_arb(z0, z, 0); if (!arb_contains_zero(z0) && !arb_poly_overlaps(w, t)) { flint_printf("FAIL: wronskian, n1 = %wd\n\n", n1); flint_printf("l = "); arb_printd(l, 30); flint_printf("\n\n"); flint_printf("eta = "); arb_printd(eta, 30); flint_printf("\n\n"); flint_printf("z = "); arb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("F = "); arb_poly_printd(F, 30); flint_printf("\n\n"); flint_printf("G = "); arb_poly_printd(G, 30); flint_printf("\n\n"); flint_printf("w = "); arb_poly_printd(w, 30); flint_printf("\n\n"); flint_printf("t = "); arb_poly_printd(t, 30); flint_printf("\n\n"); flint_abort(); } mask = n_randlimb(state); arb_poly_set(G2, z); /* for aliasing */ if (n_randint(state, 2)) { arb_poly_randtest(u, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); arb_poly_add(G2, G2, u, prec2); arb_poly_sub(G2, G2, u, prec2); } arb_hypgeom_coulomb_series((mask & 1) ? F2 : NULL, (mask & 2) ? G2 : NULL, l, eta, G2, n2, prec2); arb_poly_truncate(F, FLINT_MIN(n1, n2)); arb_poly_truncate(G, FLINT_MIN(n1, n2)); arb_poly_truncate(F2, FLINT_MIN(n1, n2)); arb_poly_truncate(G2, FLINT_MIN(n1, n2)); if (((mask & 1) && (!arb_poly_overlaps(F, F2))) || ((mask & 2) && (!arb_poly_overlaps(G, G2)))) { flint_printf("FAIL: consistency (mask)\n\n"); flint_printf("mask = %u\n\n", mask); flint_printf("len1 = %wd, len2 = %wd\n\n", n1, n2); flint_printf("l = "); arb_printd(l, 30); flint_printf("\n\n"); flint_printf("eta = "); arb_printd(eta, 30); flint_printf("\n\n"); flint_printf("z = "); arb_poly_printd(z, 30); flint_printf("\n\n"); flint_printf("F = "); arb_poly_printd(F, 30); flint_printf("\n\n"); flint_printf("F2 = "); arb_poly_printd(F2, 30); flint_printf("\n\n"); flint_printf("G = "); arb_poly_printd(G, 30); flint_printf("\n\n"); flint_printf("G2 = "); arb_poly_printd(G2, 30); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(F); arb_poly_clear(G); arb_poly_clear(F2); arb_poly_clear(G2); arb_poly_clear(z); arb_poly_clear(w); arb_poly_clear(t); arb_poly_clear(u); arb_clear(c); arb_clear(l); arb_clear(eta); arb_clear(z0); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-erf.c000066400000000000000000000147251417376376500170320ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("erf...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); switch (n_randint(state, 2)) { case 0: if (!arb_hypgeom_erf_bb(b, a, 0, prec1)) arb_hypgeom_erf(b, a, prec1); break; default: arb_hypgeom_erf(b, a, prec1); break; } switch (n_randint(state, 2)) { case 0: if (!arb_hypgeom_erf_bb(c, a, 0, prec2)) arb_hypgeom_erf(c, a, prec2); break; default: arb_hypgeom_erf(c, a, prec2); break; } if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 30); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); switch (n_randint(state, 2)) { case 0: if (!arb_hypgeom_erf_bb(b, a, 1, prec1)) arb_hypgeom_erfc(b, a, prec1); break; default: arb_hypgeom_erfc(b, a, prec1); break; } switch (n_randint(state, 2)) { case 0: if (!arb_hypgeom_erf_bb(c, a, 1, prec2)) arb_hypgeom_erfc(c, a, prec2); break; default: arb_hypgeom_erfc(c, a, prec2); break; } if (!arb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 30); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); } #if 0 for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1; prec1 = 2 + n_randint(state, 5000); arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_hypgeom_erfc(b, a, prec1 + 100); arb_set_round(b, b, prec1); arb_div_ui(b, b, 3, prec1); arb_mul_ui(b, b, 3, prec1); if (n_randint(state, 2)) { if (!arb_hypgeom_erf_bb(c, a, 1, prec1)) arb_hypgeom_erfc(c, a, prec1); } else arb_hypgeom_erfc(c, a, prec1); if (arb_is_finite(b) && (arb_rel_accuracy_bits(c) < arb_rel_accuracy_bits(b) - 4.0)) { flint_printf("ACCURACY (erfc)\n\n"); flint_printf("prec = %wd\n\n", prec1); flint_printf("a = "); arb_printd(a, 200); flint_printf("\n"); flint_printf("b = "); arb_printd(b, 200); flint_printf("\n"); flint_printf("c = "); arb_printd(c, 200); flint_printf("\n\n"); } arb_clear(a); arb_clear(b); arb_clear(c); } #endif #if 0 for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t a, b, c; slong prec1; prec1 = 2 + n_randint(state, 5000); arb_init(a); arb_init(b); arb_init(c); arb_randtest_special(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_randtest_special(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arb_hypgeom_erf(b, a, prec1 + 100); arb_set_round(b, b, prec1); arb_div_ui(b, b, 3, prec1); arb_mul_ui(b, b, 3, prec1); if (n_randint(state, 2)) { if (!arb_hypgeom_erf_bb(c, a, 0, prec1)) arb_hypgeom_erf(c, a, prec1); } else arb_hypgeom_erf(c, a, prec1); if (arb_is_finite(b) && (arb_rel_accuracy_bits(c) < arb_rel_accuracy_bits(b) - 4.0)) { flint_printf("ACCURACY (erf)\n\n"); flint_printf("prec = %wd\n\n", prec1); flint_printf("a = "); arb_printd(a, 200); flint_printf("\n"); flint_printf("b = "); arb_printd(b, 200); flint_printf("\n"); flint_printf("c = "); arb_printd(c, 200); flint_printf("\n\n"); } arb_clear(a); arb_clear(b); arb_clear(c); } #endif flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-erfinv.c000066400000000000000000000121561417376376500175430ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("erfinv...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z, w; slong prec, prec2; arb_init(x); arb_init(y); arb_init(z); arb_init(w); prec = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); arb_init(x); arb_init(y); arb_randtest(x, state, prec, 10 + n_randint(state, 300)); arb_randtest(y, state, prec, 100); arb_hypgeom_erfcinv(y, x, prec); arb_hypgeom_erfc(z, y, prec + 10); if (!arb_overlaps(x, z)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_abort(); } if (arb_is_exact(x) && arf_sgn(arb_midref(x)) > 0 && arf_cmp_2exp_si(arb_midref(x), 1) < 0 && arb_rel_accuracy_bits(y) < prec - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("iter = %wd, prec = %wd\n", iter, prec); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_set(z, x); mag_zero(arb_radref(z)); if (n_randint(state, 2)) { arf_set_mag(arb_midref(w), arb_radref(x)); if (n_randint(state, 2)) arb_neg(w, w); arb_add(z, z, w, prec); } arb_hypgeom_erfcinv(z, z, prec2); if (!arb_overlaps(y, z)) { flint_printf("FAIL: overlap 2\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); arb_clear(w); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, z, w; slong prec, prec2; arb_init(x); arb_init(y); arb_init(z); arb_init(w); prec = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); arb_init(x); arb_init(y); arb_randtest(x, state, prec, 100); arb_randtest(y, state, prec, 100); arb_hypgeom_erfinv(y, x, prec); arb_hypgeom_erf(z, y, prec + 10); if (!arb_overlaps(x, z)) { flint_printf("FAIL: overlap\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_abort(); } if (arb_is_exact(x) && arf_cmpabs_2exp_si(arb_midref(x), 0) < 0 && arb_rel_accuracy_bits(y) < prec - 2) { flint_printf("FAIL: accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_set(z, x); mag_zero(arb_radref(z)); if (n_randint(state, 2)) { arf_set_mag(arb_midref(w), arb_radref(x)); if (n_randint(state, 2)) arb_neg(w, w); arb_add(z, z, w, prec); } arb_hypgeom_erfinv(z, z, prec2); if (!arb_overlaps(y, z)) { flint_printf("FAIL: overlap 2\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(y); arb_clear(z); arb_clear(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_fmpq.c000066400000000000000000000075321417376376500203610ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t r, s; fmpq_t q; slong accuracy, prec, pp, qq; prec = 2 + n_randint(state, 1 << n_randint(state, 12)); prec += 20; arb_init(r); arb_init(s); fmpq_init(q); pp = -100 + n_randint(state, 10000); qq = 1 + n_randint(state, 20); fmpq_set_si(q, pp, qq); arb_hypgeom_gamma_fmpq(r, q, prec); arb_set_fmpq(s, q, prec); arb_hypgeom_gamma(s, s, prec); if (!arb_overlaps(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); arb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_abort(); } if (!(fmpz_is_one(fmpq_denref(q)) && fmpz_sgn(fmpq_numref(q)) <= 0) && FLINT_ABS(pp / qq) < 10) { accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 6) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_abort(); } } arb_clear(r); arb_clear(s); fmpq_clear(q); } for (iter = 0; iter < 50 * arb_test_multiplier(); iter++) { arb_t r, s; fmpq_t q; slong accuracy, prec; prec = 2 + n_randint(state, 25000); arb_init(r); arb_init(s); fmpq_init(q); fmpz_randtest(fmpq_numref(q), state, 3 + n_randlimb(state) % 30); fmpz_randtest_not_zero(fmpq_denref(q), state, 3 + n_randlimb(state) % 30); fmpq_canonicalise(q); arb_hypgeom_gamma_fmpq(r, q, prec); arb_set_fmpq(s, q, prec); arb_hypgeom_gamma(s, s, prec); if (!arb_overlaps(r, s)) { flint_printf("FAIL: containment\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, prec / 3.33); flint_printf("\n\n"); flint_printf("s = "); arb_printd(s, prec / 3.33); flint_printf("\n\n"); flint_abort(); } if (!(fmpz_is_one(fmpq_denref(q)) && fmpz_sgn(fmpq_numref(q)) <= 0) && fabs(fmpq_get_d(q)) < 10.0) { accuracy = arb_rel_accuracy_bits(r); if (accuracy < prec - 6) { flint_printf("FAIL: poor accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("q = "); fmpq_print(q); flint_printf("\n\n"); flint_printf("r = "); arb_printn(r, prec / 3.33, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, prec / 3.33, 0); flint_printf("\n\n"); flint_abort(); } } arb_clear(r); arb_clear(s); fmpq_clear(q); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_lower_sum_rs.c000066400000000000000000000042551417376376500221350ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_lower_sum_rs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_t a; ulong p, q; arb_t z, r1, r2, s, t, u; slong k, N, prec; p = n_randint(state, 1000); q = 1 + n_randint(state, 1000); N = n_randint(state, 100); prec = 2 + n_randint(state, 500); fmpq_init(a); fmpq_set_si(a, p, q); arb_init(z); arb_init(r1); arb_init(r2); arb_init(s); arb_init(t); arb_init(u); arb_randtest(z, state, prec, 10); _arb_hypgeom_gamma_lower_sum_rs_1(r1, p, q, z, N, prec); arb_zero(s); arb_one(t); arb_set_fmpq(u, a, prec); for (k = 0; k < N; k++) { arb_add(s, s, t, prec); arb_mul(t, t, z, prec); arb_div(t, t, u, prec); arb_add_ui(u, u, 1, prec); } arb_set(r2, s); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("N = %wd\n\n", N); flint_printf("a = "); fmpq_print(a); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 100, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 100, 0); flint_printf("\n\n"); flint_abort(); } fmpq_clear(a); arb_clear(z); arb_clear(r1); arb_clear(r2); arb_clear(s); arb_clear(t); arb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_stirling_sum.c000066400000000000000000000032101417376376500221220ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_stirling_sum...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t z, s1, s2; slong prec, N, K; prec = 2 + n_randint(state, 800); N = n_randint(state, 200); K = n_randint(state, 20); arb_init(z); arb_init(s1); arb_init(s2); arb_randtest(z, state, prec, 10 + n_randint(state, 200)); arb_hypgeom_gamma_stirling_sum_horner(s1, z, N, prec); arb_hypgeom_gamma_stirling_sum_improved(s2, z, N, K, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("N = %wd, K = %wd, prec = %wd\n\n", N, K, prec); flint_printf("z = "); arb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(z); arb_clear(s1); arb_clear(s2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_taylor.c000066400000000000000000000131341417376376500207230ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_taylor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arb_t x, s1, s2, a, b; slong prec, ebits, prec2; int success, success2, alias, reciprocal; if (n_randint(state, 10) == 0) prec = 2 + n_randint(state, 4000); else prec = 2 + n_randint(state, 300); if (n_randint(state, 10) == 0) ebits = 100; else ebits = 10; prec2 = prec + 1 + n_randint(state, 30); arb_init(x); arb_init(s1); arb_init(s2); arb_init(a); arb_init(b); arb_randtest(x, state, prec, ebits); arb_randtest(s1, state, prec, 10); arb_randtest(s2, state, prec, 10); alias = n_randint(state, 2); reciprocal = n_randint(state, 2); if (alias) { success = arb_hypgeom_gamma_taylor(s1, x, reciprocal, prec); } else { arb_set(s1, x); success = arb_hypgeom_gamma_taylor(s1, s1, reciprocal, prec); } if (success) { /* printf("%ld\n", iter); */ /* Compare with Stirling series algorithm. */ arb_hypgeom_gamma_stirling(s2, x, reciprocal, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); arb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_abort(); } /* Compare with different level of precision. */ success2 = arb_hypgeom_gamma_taylor(s2, x, reciprocal, prec2); if (success2 && !arb_overlaps(s1, s2)) { flint_printf("FAIL (2)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); arb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_abort(); } arf_set_mag(arb_midref(a), arb_radref(x)); arf_set_mag(arb_midref(b), arb_radref(x)); arb_sub_arf(a, a, arb_midref(x), prec + 30); arb_neg(a, a); arb_add_arf(b, b, arb_midref(x), prec + 30); success2 = arb_hypgeom_gamma_taylor(s2, a, reciprocal, prec2); if (success2 && !arb_overlaps(s1, s2)) { flint_printf("FAIL (3)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); arb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_abort(); } success2 = arb_hypgeom_gamma_taylor(s2, b, reciprocal, prec2); if (success2 && !arb_overlaps(s1, s2)) { flint_printf("FAIL (4)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); arb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_abort(); } arb_add(a, a, b, prec + 30); arb_mul_2exp_si(a, a, -1); success2 = arb_hypgeom_gamma_taylor(s2, b, reciprocal, prec2); if (success2 && !arb_overlaps(s1, s2)) { flint_printf("FAIL (5)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("x = "); arb_printn(x, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); arb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_abort(); } } arb_clear(x); arb_clear(s1); arb_clear(s2); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_taylor_tab.c000066400000000000000000000051451417376376500215540ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" ARB_DLL extern arb_hypgeom_gamma_coeff_t arb_hypgeom_gamma_coeffs[ARB_HYPGEOM_GAMMA_TAB_NUM]; int main() { flint_rand_t state; flint_printf("gamma_taylor_tab...."); fflush(stdout); flint_randinit(state); { slong n, prec, maxprec; arb_t c; arf_t d; arb_ptr v, f; v = _arb_vec_init(ARB_HYPGEOM_GAMMA_TAB_NUM); f = _arb_vec_init(2); arb_one(f); arb_one(f + 1); arf_init(d); _arb_poly_rgamma_series(v, f, 2, ARB_HYPGEOM_GAMMA_TAB_NUM, ARB_HYPGEOM_GAMMA_TAB_PREC + 2 * ARB_HYPGEOM_GAMMA_TAB_NUM); for (n = 1; n < ARB_HYPGEOM_GAMMA_TAB_NUM; n++) { maxprec = arb_hypgeom_gamma_coeffs[n].nlimbs; maxprec *= 64; for (prec = 2; prec <= ARB_HYPGEOM_GAMMA_TAB_PREC; prec += (prec < maxprec - 64 ? n_randint(state, 64) : 1)) { if (_arb_hypgeom_gamma_coeff_shallow(arb_midref(c), arb_radref(c), n, prec)) { if (!arb_contains(c, v + n)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd, n = %wd\n\n", prec, n); flint_printf("c = "); arb_printn(c, 1000, 0); flint_printf("\n\n"); flint_printf("v = "); arb_printn(v + n, 1000, 0); flint_printf("\n\n"); flint_abort(); } } } _arb_hypgeom_gamma_coeff_shallow(arb_midref(c), arb_radref(c), n, maxprec); arf_set_round(d, arb_midref(v + n), maxprec, ARF_RND_DOWN); if (!arf_equal(arb_midref(c), d)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd, n = %wd\n\n", prec, n); flint_printf("c = "); arb_printn(c, 1000, 0); flint_printf("\n\n"); flint_printf("d = "); arf_printd(d, 1000); flint_printf("\n\n"); flint_abort(); } } _arb_vec_clear(v, ARB_HYPGEOM_GAMMA_TAB_NUM); _arb_vec_clear(f, 2); arf_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_upper_fmpq.c000066400000000000000000000136701417376376500215740ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_upper_fmpq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_t a; arb_t z, r1, r2; mag_t tol1, tol2, err1, err2; slong N1, N2, prec1, prec2; mag_init(tol1); mag_init(tol2); mag_init(err1); mag_init(err2); fmpq_init(a); arb_init(z); arb_init(r1); arb_init(r2); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); do { fmpq_randtest(a, state, 5); } while (fmpz_is_one(fmpq_denref(a)) && fmpz_sgn(fmpq_numref(a)) <= 0); arb_set_ui(z, 1 + n_randint(state, 100)); arb_div_ui(z, z, 1 + n_randint(state, 100), 200); mag_set_ui_2exp_si(tol1, 1, -(slong) n_randint(state, 100)); mag_set_ui_2exp_si(tol2, 1, -(slong) n_randint(state, 100)); N1 = _arb_hypgeom_gamma_upper_fmpq_inf_choose_N(err1, a, z, tol1); N2 = _arb_hypgeom_gamma_upper_fmpq_inf_choose_N(err2, a, z, tol2); _arb_hypgeom_gamma_upper_fmpq_inf_bsplit(r1, a, z, N1, prec1); arb_add_error_mag(r1, err1); _arb_hypgeom_gamma_upper_fmpq_inf_bsplit(r2, a, z, N2, prec2); arb_add_error_mag(r2, err2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); fmpq_print(a); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 100, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 100, 0); flint_printf("\n\n"); flint_abort(); } fmpq_clear(a); arb_clear(z); arb_clear(r1); arb_clear(r2); mag_clear(tol1); mag_clear(tol2); mag_clear(err1); mag_clear(err2); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_t a; arb_t z, r1, r2; mag_t tol1, tol2, err1, err2; slong N1, N2, prec1, prec2; mag_init(tol1); mag_init(tol2); mag_init(err1); mag_init(err2); fmpq_init(a); arb_init(z); arb_init(r1); arb_init(r2); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); do { fmpq_randtest(a, state, 5); } while (fmpz_is_one(fmpq_denref(a)) && fmpz_sgn(fmpq_numref(a)) <= 0); arb_set_ui(z, 1 + n_randint(state, 100)); arb_div_ui(z, z, 1 + n_randint(state, 100), 200); mag_set_ui_2exp_si(tol1, 1, -(slong) n_randint(state, 100)); mag_set_ui_2exp_si(tol2, 1, -(slong) n_randint(state, 100)); N1 = _arb_hypgeom_gamma_lower_fmpq_0_choose_N(err1, a, z, tol1); N2 = _arb_hypgeom_gamma_lower_fmpq_0_choose_N(err2, a, z, tol2); _arb_hypgeom_gamma_lower_fmpq_0_bsplit(r1, a, z, N1, prec1); arb_add_error_mag(r1, err1); _arb_hypgeom_gamma_lower_fmpq_0_bsplit(r2, a, z, N2, prec2); arb_add_error_mag(r2, err2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); fmpq_print(a); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 100, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 100, 0); flint_printf("\n\n"); flint_abort(); } fmpq_clear(a); arb_clear(z); arb_clear(r1); arb_clear(r2); mag_clear(tol1); mag_clear(tol2); mag_clear(err1); mag_clear(err2); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong na; arb_t z, r1, r2; mag_t tol1, tol2, err1, err2; slong N1, N2, prec1, prec2; mag_init(tol1); mag_init(tol2); mag_init(err1); mag_init(err2); arb_init(z); arb_init(r1); arb_init(r2); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); na = n_randint(state, 50); arb_set_ui(z, 1 + n_randint(state, 100)); arb_div_ui(z, z, 1 + n_randint(state, 100), 200); mag_set_ui_2exp_si(tol1, 1, -(slong) n_randint(state, 100)); mag_set_ui_2exp_si(tol2, 1, -(slong) n_randint(state, 100)); N1 = _arb_hypgeom_gamma_upper_singular_si_choose_N(err1, na, z, tol1); N2 = _arb_hypgeom_gamma_upper_singular_si_choose_N(err2, na, z, tol2); _arb_hypgeom_gamma_upper_singular_si_bsplit(r1, na, z, N1, prec1); arb_add_error_mag(r1, err1); _arb_hypgeom_gamma_upper_singular_si_bsplit(r2, na, z, N2, prec2); arb_add_error_mag(r2, err2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("na = %wd", na); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 100, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(z); arb_clear(r1); arb_clear(r2); mag_clear(tol1); mag_clear(tol2); mag_clear(err1); mag_clear(err2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_upper_integration.c000066400000000000000000000074451417376376500231570ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_upper_integration...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_t a, z, r1, r2; slong prec1, prec2; int regularized; prec1 = 2 + n_randint(state, 80); prec2 = 2 + n_randint(state, 150); arb_init(a); arb_init(z); arb_init(r1); arb_init(r2); regularized = n_randint(state, 3); arb_randtest_precise(a, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest(r1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_randtest(r2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_add_ui(a, a, n_randint(state, 100), prec1 + 100); arb_add_ui(z, z, n_randint(state, 100), prec1 + 100); arb_hypgeom_gamma_upper_integration(r1, a, z, regularized, prec1); if (arb_is_finite(r1)) { if (n_randint(state, 2)) arb_hypgeom_gamma_upper_integration(r2, a, z, regularized, prec2); else arb_hypgeom_gamma_upper(r2, a, z, regularized, prec2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); arb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } if (iter == 0) { prec1 = 333; arb_set_str(a, "5.25", prec1); arb_set_str(z, "1.125", prec1); arb_hypgeom_gamma_upper_integration(r1, a, z, 0, prec1); arb_set_str(r2, "35.072486673952527119466762267780775062420879980812938235868074922070540736636294202721367124421387 +/- 5.01e-97", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (1)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } arb_set_str(a, "-23515.25", prec1); arb_set_str(z, "5118.125", prec1); arb_hypgeom_gamma_upper_integration(r1, a, z, 0, prec1); arb_set_str(r2, "1.2585189324946269645868452847608400602717904014578585865177198314407671242201776909963228597279e-89448 +/- 8.86e-89543", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (1)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(z); arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-gamma_upper_sum_rs.c000066400000000000000000000042551417376376500221400ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_upper_sum_rs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_t a; ulong p, q; arb_t z, r1, r2, s, t, u; slong k, N, prec; p = n_randint(state, 1000); q = 1 + n_randint(state, 1000); N = n_randint(state, 100); prec = 2 + n_randint(state, 500); fmpq_init(a); fmpq_set_si(a, p, q); arb_init(z); arb_init(r1); arb_init(r2); arb_init(s); arb_init(t); arb_init(u); arb_randtest(z, state, prec, 10); _arb_hypgeom_gamma_upper_sum_rs_1(r1, p, q, z, N, prec); arb_zero(s); arb_one(t); arb_set_fmpq(u, a, prec); for (k = 0; k < N; k++) { arb_add(s, s, t, prec); arb_div(t, t, z, prec); arb_mul(t, t, u, prec); arb_add_ui(u, u, 1, prec); } arb_set(r2, s); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("N = %wd\n\n", N); flint_printf("a = "); fmpq_print(a); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 100, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 100, 0); flint_printf("\n\n"); flint_abort(); } fmpq_clear(a); arb_clear(z); arb_clear(r1); arb_clear(r2); arb_clear(s); arb_clear(t); arb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-legendre_p_ui.c000066400000000000000000000070171417376376500210530ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_t x, r1, r2, r3, r4, s, t; ulong n; slong prec1, prec2, prec3; arb_init(x); arb_init(r1); arb_init(r2); arb_init(r3); arb_init(r4); arb_init(s); arb_init(t); n = n_randtest(state) % 1000; prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 500); prec3 = 2 + n_randint(state, 500); arb_randtest(x, state, 2 + n_randint(state, 1000), 3); arb_mul_2exp_si(x, x, -n_randint(state, 15)); if (n_randint(state, 2)) mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_add_ui(x, x, 1, prec1); arb_hypgeom_legendre_p_ui(r1, r2, n, x, prec1); if (n_randint(state, 2)) { arb_hypgeom_legendre_p_ui(r3, NULL, n, x, prec2); arb_hypgeom_legendre_p_ui(NULL, r4, n, x, prec2); } else { arb_hypgeom_legendre_p_ui(r3, r4, n, x, prec2); } if (!arb_overlaps(r1, r3) || !arb_overlaps(r2, r4)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r3 = "); arb_printn(r3, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("r4 = "); arb_printn(r4, 50, 0); flint_printf("\n\n"); flint_abort(); } if (n != 0) { arb_hypgeom_legendre_p_ui(r3, NULL, n - 1, x, prec3); /* check (x^2-1)/n P'_n(x) = x P_n(x) - P_{n-1}(x) */ arb_mul(s, x, x, prec1); arb_sub_ui(s, s, 1, prec1); arb_mul(s, s, r2, prec1); arb_div_ui(s, s, n, prec1); arb_mul(t, x, r1, prec1); arb_sub(t, t, r3, prec1); if (!arb_overlaps(s, t)) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("r3 = "); arb_printn(r3, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } } arb_clear(x); arb_clear(r1); arb_clear(r2); arb_clear(r3); arb_clear(r4); arb_clear(s); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-legendre_p_ui_asymp.c000066400000000000000000000071171417376376500222650ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p_ui_asymp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_t x, r1, r1p, r2, r2p, r3, s; ulong n; slong prec1, prec2, K, K2, K3; arb_init(x); arb_init(r1); arb_init(r1p); arb_init(r2); arb_init(r2p); arb_init(r3); arb_init(s); n = n_randtest(state) % 500; K = n_randint(state, 50); K2 = n_randint(state, 500); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 500); arb_randtest(x, state, 2 + n_randint(state, 1000), 0); arb_mul_2exp_si(x, x, -n_randint(state, 8)); if (n_randint(state, 2)) mag_zero(arb_radref(x)); arb_hypgeom_legendre_p_ui_asymp(r1, r1p, n, x, K, prec1); arb_hypgeom_legendre_p_ui_one(r2, r2p, n, x, K2, prec2); if (!arb_overlaps(r1, r2) || !arb_overlaps(r1p, r2p)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu, K = %wd\n\n", n, K); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("r1p = "); arb_printn(r1p, 50, 0); flint_printf("\n\n"); flint_printf("r2p = "); arb_printn(r2p, 50, 0); flint_printf("\n\n"); flint_abort(); } n = n_randtest(state); if (n == UWORD_MAX) n--; if (n == 0) n++; K = n_randint(state, 50); K2 = n_randint(state, 50); K3 = n_randint(state, 50); /* test (2n+1) x P_n(x) - n P_(n-1)(x) = (n+1) P_(n+1)(x) */ arb_hypgeom_legendre_p_ui_asymp(r1, NULL, n, x, K, prec2); arb_mul(r1, r1, x, prec2); arb_set_ui(r2, n); arb_add_ui(r2, r2, n, prec2); arb_add_ui(r2, r2, 1, prec2); arb_mul(r1, r1, r2, prec2); arb_hypgeom_legendre_p_ui_asymp(r2, NULL, n - 1, x, K2, prec2); arb_mul_ui(r2, r2, n, prec2); arb_hypgeom_legendre_p_ui_asymp(r3, NULL, n + 1, x, K3, prec2); arb_mul_ui(r3, r3, n + 1, prec2); arb_sub(s, r1, r2, prec2); if (!arb_overlaps(s, r3)) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("n = %wu, K = %wd, K2 = %wd, K3 = %wd\n\n", n, K, K2, K3); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r3 = "); arb_printn(r3, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(r1); arb_clear(r1p); arb_clear(r2); arb_clear(r2p); arb_clear(r3); arb_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-legendre_p_ui_deriv_bound.c000066400000000000000000000054041417376376500234310ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p_ui_deriv_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, x2sub1, y, z; mag_t m1, m2, exact; ulong n; slong prec; arb_init(x); arb_init(x2sub1); arb_init(y); arb_init(z); mag_init(m1); mag_init(m2); mag_init(exact); n = n_randtest(state) % 10000; prec = 64; arb_randtest(x, state, 2 * prec, 0); mag_zero(arb_radref(x)); while (arf_cmpabs_2exp_si(arb_midref(x), 0) >= 0) arb_mul_2exp_si(x, x, -1); arb_mul_2exp_si(x, x, -n_randint(state, 10)); arb_mul(x2sub1, x, x, 2 * prec); arb_sub_ui(x2sub1, x2sub1, 1, 2 * prec); arb_neg(x2sub1, x2sub1); arb_hypgeom_legendre_p_ui_deriv_bound(m1, m2, n, x, x2sub1); arb_hypgeom_legendre_p_ui(y, z, n, x, prec); arb_get_mag_lower(exact, z); if (mag_cmp(m1, exact) < 0) { flint_printf("FAIL: first derivative\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 50, 0); flint_printf("\n\n"); flint_printf("m1 = "); mag_printd(m1, 15); flint_printf("\n\n"); flint_abort(); } arb_mul(z, z, x, prec); arb_mul_2exp_si(z, z, 1); arb_mul_ui(y, y, n, prec); arb_mul_ui(y, y, n + 1, prec); arb_sub(z, z, y, prec); arb_div(z, z, x2sub1, prec); arb_get_mag_lower(exact, z); if (mag_cmp(m2, exact) < 0) { flint_printf("FAIL: second derivative\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 50, 0); flint_printf("\n\n"); flint_printf("m2 = "); mag_printd(m2, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(x2sub1); arb_clear(y); arb_clear(z); mag_clear(m1); mag_clear(m2); mag_clear(exact); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-legendre_p_ui_one.c000066400000000000000000000065131417376376500217140ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p_ui_one...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_t x, r1, r2, r3, s, t; ulong n; slong prec1, prec2, prec3, K, K2; arb_init(x); arb_init(r1); arb_init(r2); arb_init(r3); arb_init(s); arb_init(t); n = n_randtest(state) % 500; K = n_randint(state, 300); K2 = n_randint(state, 300); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 500); prec3 = 2 + n_randint(state, 500); arb_randtest(x, state, 2 + n_randint(state, 1000), 1); arb_mul_2exp_si(x, x, -n_randint(state, 15)); if (n_randint(state, 2)) mag_zero(arb_radref(x)); if (n_randint(state, 2)) arb_add_ui(x, x, 1, prec1); arb_set_ui(r1, n); arb_set_ui(r2, 0); /* todo: replace with a different implementation later */ arb_hypgeom_legendre_p(r2, r1, r2, x, 0, prec1); arb_hypgeom_legendre_p_ui_one(r1, r3, n, x, K, prec2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu, K = %wd\n\n", n, K); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_abort(); } if (n != 0) { arb_hypgeom_legendre_p_ui_one(r2, NULL, n - 1, x, K2, prec3); /* check (x^2-1)/n P'_n(x) = x P_n(x) - P_{n-1}(x) */ arb_mul(s, x, x, prec1); arb_sub_ui(s, s, 1, prec1); arb_mul(s, s, r3, prec1); arb_div_ui(s, s, n, prec1); arb_mul(t, x, r1, prec1); arb_sub(t, t, r2, prec1); if (!arb_overlaps(s, t)) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("n = %wu, K = %wd, K2 = %wd\n\n", n, K, K2); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("r3 = "); arb_printn(r3, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } } arb_clear(x); arb_clear(r1); arb_clear(r2); arb_clear(r3); arb_clear(s); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-legendre_p_ui_rec.c000066400000000000000000000040331417376376500216770ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p_ui_rec...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_t x, r1, r2, r3, r4; ulong n; slong prec1, prec2; arb_init(x); arb_init(r1); arb_init(r2); arb_init(r3); arb_init(r4); n = n_randtest(state) % 500; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); arb_randtest(x, state, 2 + n_randint(state, 1000), 1); arb_mul_2exp_si(x, x, -n_randint(state, 15)); if (n_randint(state, 2)) mag_zero(arb_radref(x)); arb_hypgeom_legendre_p_ui_rec(r1, r3, n, x, prec1); arb_hypgeom_legendre_p_ui_zero(r2, r4, n, x, n + 1, prec2); if (!arb_overlaps(r1, r2) || !arb_overlaps(r3, r4)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("r3 = "); arb_printn(r3, 50, 0); flint_printf("\n\n"); flint_printf("r4 = "); arb_printn(r4, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(r1); arb_clear(r2); arb_clear(r3); arb_clear(r4); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-legendre_p_ui_root.c000066400000000000000000000123211417376376500221100ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "flint/arith.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p_ui_root...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { ulong n, k; slong prec; arb_ptr roots, weights; arb_poly_t pol; arb_t s; fmpq_poly_t pol2; n = 1 + n_randint(state, 100); prec = 20 + n_randint(state, 500); roots = _arb_vec_init(n); weights = _arb_vec_init(n); arb_poly_init(pol); fmpq_poly_init(pol2); arb_init(s); for (k = 0; k < n; k++) { if (k > n / 2 && n_randint(state, 2)) { arb_neg(roots + k, roots + n - k - 1); arb_set(weights + k, weights + n - k - 1); } else { arb_hypgeom_legendre_p_ui_root(roots + k, weights + k, n, k, prec); } } arb_poly_product_roots(pol, roots, n, prec); /* fmpq_poly_legendre_p(pol2, n); */ arith_legendre_polynomial(pol2, n); arb_set_fmpz(s, pol2->coeffs + n); arb_div_fmpz(s, s, pol2->den, prec); arb_poly_scalar_mul(pol, pol, s, prec); if (!arb_poly_contains_fmpq_poly(pol, pol2)) { flint_printf("FAIL: polynomial containment\n\n"); flint_printf("n = %wu, prec = %wd\n\n", n, prec); flint_printf("pol = "); arb_poly_printd(pol, 30); flint_printf("\n\n"); flint_printf("pol2 = "); fmpq_poly_print(pol2); flint_printf("\n\n"); flint_abort(); } arb_zero(s); for (k = 0; k < n; k++) { arb_add(s, s, weights + k, prec); } if (!arb_contains_si(s, 2)) { flint_printf("FAIL: sum of weights\n\n"); flint_printf("n = %wu, prec = %wd\n\n", n, prec); flint_printf("s = "); arb_printn(s, 30, 0); flint_printf("\n\n"); flint_abort(); } _arb_vec_clear(roots, n); _arb_vec_clear(weights, n); arb_poly_clear(pol); fmpq_poly_clear(pol2); arb_clear(s); } for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { arb_t x1, x2, w1, w2; ulong n, k; slong prec1, prec2; arb_init(x1); arb_init(x2); arb_init(w1); arb_init(w2); n = 1 + n_randtest(state) % 100000; if (n_randint(state, 2) || n == 1) k = n_randtest(state) % n; else k = n / 2 - (n_randtest(state) % (n / 2)); prec1 = 2 + n_randtest(state) % 2000; prec2 = 2 + n_randtest(state) % 2000; arb_hypgeom_legendre_p_ui_root(x1, w1, n, k, prec1); if (n_randint(state, 10) == 0) arb_hypgeom_legendre_p_ui_root(x1, NULL, n, k, prec1); arb_hypgeom_legendre_p_ui_root(x2, w2, n, k, prec2); if (!arb_overlaps(x1, x2) || !arb_overlaps(w1, w2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu, k = %wu, prec1 = %wd, prec2 = %wd\n\n", n, k, prec1, prec2); flint_printf("x1 = "); arb_printn(x1, 100, 0); flint_printf("\n\n"); flint_printf("x2 = "); arb_printn(x2, 100, 0); flint_printf("\n\n"); flint_printf("w1 = "); arb_printn(w1, 100, 0); flint_printf("\n\n"); flint_printf("w2 = "); arb_printn(w2, 100, 0); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(x1) < prec1 - 3 || arb_rel_accuracy_bits(w1) < prec1 - 3) { flint_printf("FAIL: accuracy\n\n"); flint_printf("n = %wu, k = %wu, prec1 = %wd\n\n", n, k, prec1); flint_printf("acc(x1) = %wd, acc(w1) = %wd\n\n", arb_rel_accuracy_bits(x1), arb_rel_accuracy_bits(w1)); flint_printf("x1 = "); arb_printn(x1, prec1, ARB_STR_CONDENSE * 30); flint_printf("\n\n"); flint_printf("w1 = "); arb_printn(w1, prec1, ARB_STR_CONDENSE * 30); flint_printf("\n\n"); flint_abort(); } if (arb_rel_accuracy_bits(x2) < prec2 - 3 || arb_rel_accuracy_bits(w2) < prec2 - 3) { flint_printf("FAIL: accuracy 2\n\n"); flint_printf("n = %wu, k = %wu, prec2 = %wd\n\n", n, k, prec2); flint_printf("acc(x2) = %wd, acc(w2) = %wd\n\n", arb_rel_accuracy_bits(x2), arb_rel_accuracy_bits(w2)); flint_printf("x2 = "); arb_printn(x2, prec2, ARB_STR_CONDENSE * 30); flint_printf("\n\n"); flint_printf("w2 = "); arb_printn(w2, prec2, ARB_STR_CONDENSE * 30); flint_printf("\n\n"); flint_abort(); } arb_clear(x1); arb_clear(x2); arb_clear(w1); arb_clear(w2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-legendre_p_ui_zero.c000066400000000000000000000064051417376376500221120ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("legendre_p_ui_zero...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_t x, r1, r2, r3, s, t; ulong n; slong prec1, prec2, prec3, K, K2; arb_init(x); arb_init(r1); arb_init(r2); arb_init(r3); arb_init(s); arb_init(t); n = n_randtest(state) % 500; K = n_randint(state, 300); K2 = n_randint(state, 300); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 500); prec3 = 2 + n_randint(state, 500); arb_randtest(x, state, 2 + n_randint(state, 1000), 1); arb_mul_2exp_si(x, x, -n_randint(state, 15)); if (n_randint(state, 2)) mag_zero(arb_radref(x)); arb_set_ui(r1, n); arb_set_ui(r2, 0); /* todo: replace with a different implementation later */ arb_hypgeom_legendre_p(r2, r1, r2, x, 0, prec1); arb_hypgeom_legendre_p_ui_zero(r1, r3, n, x, K, prec2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu, K = %wd\n\n", n, K); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_abort(); } if (n != 0) { arb_hypgeom_legendre_p_ui_zero(r2, NULL, n - 1, x, K2, prec3); /* check (x^2-1)/n P'_n(x) = x P_n(x) - P_{n-1}(x) */ arb_mul(s, x, x, prec1); arb_sub_ui(s, s, 1, prec1); arb_mul(s, s, r3, prec1); arb_div_ui(s, s, n, prec1); arb_mul(t, x, r1, prec1); arb_sub(t, t, r2, prec1); if (!arb_overlaps(s, t)) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("n = %wu, K = %wd, K2 = %wd\n\n", n, K, K2); flint_printf("x = "); arb_printn(x, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 50, 0); flint_printf("\n\n"); flint_printf("r3 = "); arb_printn(r3, 50, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } } arb_clear(x); arb_clear(r1); arb_clear(r2); arb_clear(r3); arb_clear(s); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-lgamma.c000066400000000000000000000063001417376376500175020ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("lgamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t z, s1, s2, a, b; slong prec, ebits, prec2; prec = 2 + n_randint(state, 200); if (n_randint(state, 10) == 0) prec = 2 + n_randint(state, 1000); if (n_randint(state, 10) == 0) ebits = 100; else ebits = 10; ebits = 2; prec2 = 2 + n_randint(state, 200); arb_init(z); arb_init(s1); arb_init(s2); arb_init(a); arb_init(b); arb_randtest(z, state, prec, ebits); arb_randtest(s1, state, prec, 10); arb_randtest(s2, state, prec, 10); if (n_randint(state, 2)) { arb_hypgeom_lgamma(s1, z, prec); } else { arb_set(s1, z); arb_hypgeom_lgamma(s1, s1, prec); } arb_add_ui(s2, z, 1, prec2); arb_hypgeom_lgamma(s2, s2, prec2); arb_log(a, z, prec2); arb_sub(s2, s2, a, prec2); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("z = "); arb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); arb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); arb_printd(s1, 1000); flint_printf("\n\n"); flint_abort(); } arb_set(a, z); mag_zero(arb_radref(a)); if (n_randint(state, 2)) { arf_set_mag(arb_midref(b), arb_radref(z)); if (n_randint(state, 2)) arb_neg(b, b); arb_add(a, a, b, prec); } arb_hypgeom_lgamma(s2, a, prec); if (!arb_overlaps(s1, s2)) { flint_printf("FAIL (2)\n\n"); flint_printf("prec = %wd\n\n", prec); flint_printf("z = "); arb_printn(z, 1000, 0); flint_printf("\n\n"); flint_printf("a = "); arb_printn(a, 1000, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 1000, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 1000, 0); flint_printf("\n\n"); arb_sub(s1, s1, s2, prec2); flint_printf("s1 - s2 = "); arb_printd(s1, 1000); flint_printf("\n\n"); flint_abort(); } arb_clear(z); arb_clear(s1); arb_clear(s2); arb_clear(a); arb_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-rising_ui.c000066400000000000000000000063571417376376500202500ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void rising_algorithm(arb_t res, const arb_t x, ulong n, ulong m, slong prec, int alg, int alias) { if (alias) { arb_set(res, x); rising_algorithm(res, res, n, m, prec, alg, 0); return; } if (alg == 0) arb_hypgeom_rising_ui_rs(res, x, n, m, prec); else if (alg == 1) arb_hypgeom_rising_ui_forward(res, x, n, prec); else if (alg == 2) arb_hypgeom_rising_ui_bs(res, x, n, prec); else if (alg == 3) arb_hypgeom_rising_ui_rec(res, x, n, prec); else arb_hypgeom_rising_ui(res, x, n, prec); } int main() { slong iter; flint_rand_t state; flint_printf("rising_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, xk, y, ya, yb, yayb; ulong k, n, m1, m2, m3; slong prec; int alg1, alg2, alg3, alias1, alias2, alias3; prec = 2 + n_randint(state, 200); k = n_randint(state, 10); n = n_randint(state, 50); m1 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n + k, 1)); m2 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(k, 1)); m3 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n, 1)); alg1 = n_randint(state, 5); alg2 = n_randint(state, 5); alg3 = n_randint(state, 5); alias1 = n_randint(state, 2); alias2 = n_randint(state, 2); alias3 = n_randint(state, 2); if (n_randint(state, 100) == 0) n += 100; arb_init(x); arb_init(xk); arb_init(y); arb_init(ya); arb_init(yb); arb_init(yayb); arb_randtest(x, state, prec, 10 + n_randint(state, 200)); arb_add_ui(xk, x, k, prec); rising_algorithm(y, x, n + k, m1, prec, alg1, alias1); rising_algorithm(ya, x, k, m2, prec, alg2, alias2); rising_algorithm(yb, xk, n, m3, prec, alg3, alias3); arb_mul(yayb, ya, yb, prec); if (!arb_overlaps(y, yayb)) { flint_printf("FAIL\n\n"); flint_printf("k = %wu, n = %wu, m1 = %wu, m2 = %wu, m3 = %wu\n\n", k, n, m1, m2, m3); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); arb_printn(y, 100, 0); flint_printf("\n\n"); flint_printf("ya = "); arb_printn(ya, 100, 0); flint_printf("\n\n"); flint_printf("yb = "); arb_printn(yb, 100, 0); flint_printf("\n\n"); flint_printf("yayb = "); arb_printn(yayb, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(xk); arb_clear(y); arb_clear(ya); arb_clear(yb); arb_clear(yayb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-rising_ui_jet.c000066400000000000000000000061261417376376500211040ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void rising_algorithm(arb_ptr res, const arb_t x, ulong n, ulong m, slong len, slong prec, int alg) { if (alg == 0) arb_hypgeom_rising_ui_jet_powsum(res, x, n, len, prec); else if (alg == 1) arb_hypgeom_rising_ui_jet_rs(res, x, n, m, len, prec); else if (alg == 2) arb_hypgeom_rising_ui_jet_bs(res, x, n, len, prec); else arb_hypgeom_rising_ui_jet(res, x, n, len, prec); } int main() { slong iter; flint_rand_t state; flint_printf("rising_ui_jet...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, xk; arb_ptr y, ya, yb, yayb; ulong k, n, m1, m2, m3, len; slong prec; int alg1, alg2, alg3; prec = 2 + n_randint(state, 200); len = 1 + n_randint(state, 6); k = n_randint(state, 10); n = n_randint(state, 50); m1 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n + k, 1)); m2 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(k, 1)); m3 = n_randint(state, 2) ? 0 : 1 + n_randint(state, FLINT_MAX(n, 1)); alg1 = n_randint(state, 4); alg2 = n_randint(state, 4); alg3 = n_randint(state, 4); arb_init(x); arb_init(xk); y = _arb_vec_init(len); ya = _arb_vec_init(len); yb = _arb_vec_init(len); yayb = _arb_vec_init(len); arb_randtest(x, state, prec, 10); arb_add_ui(xk, x, k, prec); rising_algorithm(y, x, n + k, m1, len, prec, alg1); rising_algorithm(ya, x, k, m2, len, prec, alg2); rising_algorithm(yb, xk, n, m3, len, prec, alg3); _arb_poly_mullow(yayb, ya, len, yb, len, len, prec); if (!_arb_poly_overlaps(y, len, yayb, len)) { flint_printf("FAIL\n\n"); flint_printf("len = %wd, k = %wu, n = %wu, m1 = %wu, m2 = %wu, m3 = %wu\n\n", len, k, n, m1, m2, m3); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("y = "); _arb_vec_printn(y, len, 100, 0); flint_printf("\n\n"); flint_printf("ya = "); _arb_vec_printn(ya, len, 100, 0); flint_printf("\n\n"); flint_printf("yb = "); _arb_vec_printn(yb, len, 100, 0); flint_printf("\n\n"); flint_printf("yayb = "); _arb_vec_printn(yayb, len, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(xk); _arb_vec_clear(y, len); _arb_vec_clear(ya, len); _arb_vec_clear(yb, len); _arb_vec_clear(yayb, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-si.c000066400000000000000000000050561417376376500166660ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, s, t; slong prec1, prec2; arb_init(x); arb_init(s); arb_init(t); if (n_randint(state, 10) == 0) { prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); } else { prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); } arb_randtest(x, state, 2 + n_randint(state, prec1), 2 + n_randint(state, 100)); arb_randtest(s, state, 2 + n_randint(state, prec1), 2 + n_randint(state, 100)); arb_randtest(t, state, 2 + n_randint(state, prec1), 2 + n_randint(state, 100)); switch (n_randint(state, 3)) { case 0: arb_hypgeom_si(s, x, prec1); break; case 1: _arb_hypgeom_si_1f2(s, x, n_randint(state, prec1), prec1, prec1); break; default: _arb_hypgeom_si_asymp(s, x, n_randint(state, prec1 / 2), prec1); break; } switch (n_randint(state, 3)) { case 0: arb_hypgeom_si(t, x, prec2); break; case 1: _arb_hypgeom_si_1f2(t, x, n_randint(state, prec2), prec2, prec2); break; default: _arb_hypgeom_si_asymp(t, x, n_randint(state, prec2 / 2), prec2); break; } if (!arb_overlaps(s, t)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_printn(x, 100, 0); flint_printf("\n\n"); flint_printf("s = "); arb_printn(s, 100, 0); flint_printf("\n\n"); flint_printf("t = "); arb_printn(t, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(x); arb_clear(s); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-sum_fmpq_arb.c000066400000000000000000000055121417376376500207230ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/fmpq_vec.h" #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("sum_fmpq_arb...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t s1, s2, s3, z; fmpq *a, *b; slong alen, blen, N, prec; int reciprocal; alen = n_randint(state, 5); blen = n_randint(state, 5); N = n_randint(state, 100); arb_init(s1); arb_init(s2); arb_init(s3); arb_init(z); a = _fmpq_vec_init(alen); b = _fmpq_vec_init(blen); prec = 2 + n_randint(state, 500); reciprocal = n_randint(state, 2); if (n_randint(state, 10) == 0) arb_randtest_special(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); else arb_randtest(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(s1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(s2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); _fmpq_vec_randtest(a, state, alen, 1 + n_randint(state, 100)); _fmpq_vec_randtest(b, state, blen, 1 + n_randint(state, 100)); arb_hypgeom_sum_fmpq_arb_forward(s1, a, alen, b, blen, z, reciprocal, N, prec); arb_hypgeom_sum_fmpq_arb_rs(s2, a, alen, b, blen, z, reciprocal, N, prec); arb_hypgeom_sum_fmpq_arb_bs(s3, a, alen, b, blen, z, reciprocal, N, prec); if (!arb_overlaps(s1, s2) || !arb_overlaps(s1, s3)) { flint_printf("FAIL: overlap\n\n"); flint_printf("N = %wd\n\n", N); flint_printf("a = "); _fmpq_vec_print(a, alen); flint_printf("\n\n"); flint_printf("b = "); _fmpq_vec_print(b, blen); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, 0); flint_printf("\n\n"); flint_printf("s3 = "); arb_printn(s3, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(s3); arb_clear(z); _fmpq_vec_clear(a, alen); _fmpq_vec_clear(b, blen); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-sum_fmpq_imag_arb.c000066400000000000000000000067541417376376500217310ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/fmpq_vec.h" #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("sum_fmpq_imag_arb...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t s1, s2, s3, r1, r2, r3, z; fmpq *a, *b; slong alen, blen, N, prec; int reciprocal; alen = n_randint(state, 5); blen = n_randint(state, 5); N = n_randint(state, 100); arb_init(s1); arb_init(s2); arb_init(s3); arb_init(r1); arb_init(r2); arb_init(r3); arb_init(z); a = _fmpq_vec_init(alen); b = _fmpq_vec_init(blen); prec = 2 + n_randint(state, 500); reciprocal = n_randint(state, 2); if (n_randint(state, 10) == 0) arb_randtest_special(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); else arb_randtest(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(r1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(r2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(s1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arb_randtest_special(s2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); _fmpq_vec_randtest(a, state, alen, 1 + n_randint(state, 100)); _fmpq_vec_randtest(b, state, blen, 1 + n_randint(state, 100)); arb_hypgeom_sum_fmpq_imag_arb_forward(r1, s1, a, alen, b, blen, z, reciprocal, N, prec); arb_hypgeom_sum_fmpq_imag_arb_rs(r2, s2, a, alen, b, blen, z, reciprocal, N, prec); arb_hypgeom_sum_fmpq_imag_arb_bs(r3, s3, a, alen, b, blen, z, reciprocal, N, prec); if (!arb_overlaps(r1, r2) || !arb_overlaps(s1, s2) || !arb_overlaps(r1, r3) || !arb_overlaps(s1, s3)) { flint_printf("FAIL: overlap\n\n"); flint_printf("N = %wd\n\n", N); flint_printf("a = "); _fmpq_vec_print(a, alen); flint_printf("\n\n"); flint_printf("b = "); _fmpq_vec_print(b, blen); flint_printf("\n\n"); flint_printf("z = "); arb_printn(z, 100, 0); flint_printf("\n\n"); flint_printf("r1 = "); arb_printn(r1, 100, 0); flint_printf("\n\n"); flint_printf("s1 = "); arb_printn(s1, 100, 0); flint_printf("\n\n"); flint_printf("r2 = "); arb_printn(r2, 100, 0); flint_printf("\n\n"); flint_printf("s2 = "); arb_printn(s2, 100, 0); flint_printf("\n\n"); flint_printf("r3 = "); arb_printn(r3, 100, 0); flint_printf("\n\n"); flint_printf("s3 = "); arb_printn(s3, 100, 0); flint_printf("\n\n"); flint_abort(); } arb_clear(s1); arb_clear(s2); arb_clear(s3); arb_clear(r1); arb_clear(r2); arb_clear(r3); arb_clear(z); _fmpq_vec_clear(a, alen); _fmpq_vec_clear(b, blen); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-u_integration.c000066400000000000000000000100361417376376500211140ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" int main() { slong iter; flint_rand_t state; flint_printf("u_integration...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { arb_t a, b, z, r1, r2; slong prec1, prec2; prec1 = 2 + n_randint(state, 80); prec2 = 2 + n_randint(state, 150); arb_init(a); arb_init(b); arb_init(z); arb_init(r1); arb_init(r2); arb_randtest_precise(a, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(b, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest_precise(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 8)); arb_randtest(r1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); arb_randtest(r2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 5)); if (n_randint(state, 2)) arb_add_ui(a, a, n_randint(state, 100), prec1 + 100); arb_add_ui(b, b, n_randint(state, 200), prec1 + 100); arb_add_ui(z, z, n_randint(state, 100), prec1 + 100); arb_hypgeom_u_integration(r1, a, b, z, prec1); if (arb_is_finite(r1)) { if (n_randint(state, 2)) arb_hypgeom_u(r2, a, b, z, prec2); else arb_hypgeom_u_integration(r2, a, b, z, prec2); if (!arb_overlaps(r1, r2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); arb_printd(b, 30); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 30); flint_printf("\n\n"); flint_printf("r1 = "); arb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 30); flint_printf("\n\n"); flint_abort(); } } if (iter == 0) { prec1 = 333; arb_set_str(a, "1.2e7", prec1); arb_set_str(b, "1.3e8", prec1); arb_set_str(z, "1.4e8", prec1); arb_hypgeom_u_integration(r1, a, b, z, prec1); arb_set_str(r2, "7.423720668435352497136323553980928479792327057967344627374385949694801879462740896706198120e-90723524 +/- 6.47e-90723615", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (1)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } arb_set_str(a, "1.0", prec1); arb_set_str(b, "1351.25", prec1); arb_set_str(z, "5118.125", prec1); arb_hypgeom_u_integration(r1, a, b, z, prec1); arb_set_str(r2, "0.0002653059837025369361090415756761601958818507141969057844945316037867908521084665825645386229229474 +/- 5.74e-101", prec1); if (!arb_overlaps(r1, r2) || arb_rel_accuracy_bits(r1) < arb_rel_accuracy_bits(r2) - 10) { flint_printf("FAIL: overlap (2)\n\n"); flint_printf("r1 = "); arb_printd(r1, 100); flint_printf("\n\n"); flint_printf("r2 = "); arb_printd(r2, 100); flint_printf("\n\n"); flint_abort(); } } arb_clear(a); arb_clear(b); arb_clear(z); arb_clear(r1); arb_clear(r2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/test/t-wrappers.c000066400000000000000000000220711417376376500201120ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" void TEST(const arb_t x1, const arb_t x2, const char * s) { if (!arb_overlaps(x1, x2)) { flint_printf("FAIL: %s\n", s); arb_printn(x1, 30, 0); printf("\n\n"); arb_printn(x2, 30, 0); printf("\n\n"); flint_abort(); } } int main() { flint_rand_t state; flint_printf("wrappers...."); fflush(stdout); flint_randinit(state); { arb_t a, b, c, d, z, r, u, v; slong prec; prec = 53; arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(z); arb_init(r); arb_init(u); arb_init(v); arb_set_d(a, 0.5); arb_set_d(b, 0.25); arb_set_d(c, 0.125); arb_set_d(z, 0.75); arb_hypgeom_pfq(r, a, 1, b, 1, z, 0, prec); arb_set_str(v, "[3.40725820729608 +/- 6.88e-15]", prec); TEST(r, v, "pfq"); arb_hypgeom_pfq(r, a, 1, b, 1, z, 1, prec); arb_set_str(v, "[0.93977518087904 +/- 3.26e-15]", prec); TEST(r, v, "pfq regularized"); arb_hypgeom_0f1(r, a, z, 0, prec); arb_set_str(v, "[2.91457744017593 +/- 4.17e-15]", prec); TEST(r, v, "0f1"); arb_hypgeom_0f1(r, a, z, 1, prec); arb_set_str(v, "[1.64437423219054 +/- 3.77e-15]", prec); TEST(r, v, "0f1 regularized"); arb_hypgeom_1f1(r, a, b, z, 0, prec); arb_set_str(v, "[3.40725820729608 +/- 6.88e-15]", prec); TEST(r, v, "1f1"); arb_hypgeom_1f1(r, a, b, z, 1, prec); arb_set_str(v, "[0.93977518087904 +/- 3.26e-15]", prec); TEST(r, v, "1f1 regularized"); arb_hypgeom_u(r, a, b, z, prec); arb_set_str(v, "[0.7761320390950 +/- 3.89e-14]", prec); TEST(r, v, "u"); arb_hypgeom_2f1(r, a, b, c, z, 0, prec); arb_set_str(v, "[3.2569394189980 +/- 8.18e-14]", prec); TEST(r, v, "2f1"); arb_hypgeom_2f1(r, a, b, c, z, 1, prec); arb_set_str(v, "[0.4323021855542 +/- 1.67e-14]", prec); TEST(r, v, "2f1 regularized"); arb_hypgeom_erf(r, z, prec); arb_set_str(v, "[0.711155633653515 +/- 2.35e-16]", prec); TEST(r, v, "erf"); arb_hypgeom_erfc(r, z, prec); arb_set_str(v, "[0.288844366346485 +/- 2.34e-16]", prec); TEST(r, v, "erfc"); arb_hypgeom_erfi(r, z, prec); arb_set_str(v, "[1.03575728441196 +/- 3.17e-15]", prec); TEST(r, v, "erfi"); arb_hypgeom_fresnel(r, NULL, z, 0, prec); arb_set_str(v, "[0.137478632382610 +/- 1.79e-16]", prec); TEST(r, v, "fresnel_s"); arb_hypgeom_fresnel(r, NULL, z, 1, prec); arb_set_str(v, "[0.208877111233384 +/- 4.63e-16]", prec); TEST(r, v, "fresnel_s normalized"); arb_hypgeom_fresnel(NULL, r, z, 0, prec); arb_set_str(v, "[0.726614618304550 +/- 2.11e-16]", prec); TEST(r, v, "fresnel_c"); arb_hypgeom_fresnel(NULL, r, z, 1, prec); arb_set_str(v, "[0.693525990787136 +/- 2.76e-16]", prec); TEST(r, v, "fresnel_c normalized"); arb_hypgeom_gamma_lower(r, a, z, 0, prec); arb_set_str(v, "[1.38132404568612 +/- 3.66e-15]", prec); TEST(r, v, "gamma_lower"); arb_hypgeom_gamma_lower(r, a, z, 1, prec); arb_set_str(v, "[0.77932863808015 +/- 4.17e-15]", prec); TEST(r, v, "gamma_lower 1"); arb_hypgeom_gamma_lower(r, a, z, 2, prec); arb_set_str(v, "[0.89989119796552 +/- 2.76e-15]", prec); TEST(r, v, "gamma_lower 2"); arb_hypgeom_gamma_upper(r, a, z, 0, prec); arb_set_str(v, "[0.39112980521940 +/- 4.21e-15]", prec); TEST(r, v, "gamma_upper"); arb_hypgeom_gamma_upper(r, a, z, 1, prec); arb_set_str(v, "[0.22067136191985 +/- 4.08e-15]", prec); TEST(r, v, "gamma_upper 1"); arb_hypgeom_beta_lower(r, a, b, z, 0, prec); arb_set_str(v, "[2.3363313667086 +/- 3.14e-14]", prec); TEST(r, v, "beta_lower"); arb_hypgeom_beta_lower(r, a, b, z, 1, prec); arb_set_str(v, "[0.44551489018313 +/- 6.22e-15]", prec); TEST(r, v, "beta_lower 1"); arb_hypgeom_expint(r, a, z, prec); arb_set_str(v, "[0.45163779666301 +/- 3.10e-15]", prec); TEST(r, v, "expint"); arb_hypgeom_ei(r, z, prec); arb_set_str(v, "[1.20733281600122 +/- 2.72e-15]", prec); TEST(r, v, "ei"); arb_hypgeom_si(r, z, prec); arb_set_str(v, "[0.72695424715009 +/- 3.99e-15]", prec); TEST(r, v, "si"); arb_hypgeom_ci(r, z, prec); arb_set_str(v, "[0.152163600980330 +/- 5.49e-16]", prec); TEST(r, v, "ci"); arb_hypgeom_shi(r, z, prec); arb_set_str(v, "[0.77383681445623 +/- 5.97e-15]", prec); TEST(r, v, "shi"); arb_hypgeom_chi(r, z, prec); arb_set_str(v, "[0.433496001544996 +/- 7.91e-16]", prec); TEST(r, v, "chi"); arb_hypgeom_li(r, z, 0, prec); arb_set_str(v, "[-0.93693001101265 +/- 5.67e-15]", prec); TEST(r, v, "li"); arb_hypgeom_li(r, z, 1, prec); arb_set_str(v, "[-1.98209379113014 +/- 3.56e-15]", prec); TEST(r, v, "li offset"); arb_hypgeom_bessel_j(r, a, z, prec); arb_set_str(v, "[0.62800587637589 +/- 4.06e-15]", prec); TEST(r, v, "bessel_j"); arb_hypgeom_bessel_y(r, a, z, prec); arb_set_str(v, "[-0.67411792914454 +/- 5.27e-15]", prec); TEST(r, v, "bessel_y"); arb_hypgeom_bessel_jy(r, u, a, z, prec); arb_set_str(v, "[0.62800587637589 +/- 4.06e-15]", prec); TEST(r, v, "bessel_jy"); arb_set_str(v, "[-0.67411792914454 +/- 5.27e-15]", prec); TEST(u, v, "bessel_jy"); arb_hypgeom_bessel_i(r, a, z, prec); arb_set_str(v, "[0.75761498638991 +/- 4.63e-15]", prec); TEST(r, v, "bessel_i"); arb_hypgeom_bessel_i_scaled(r, a, z, prec); arb_set_str(v, "[0.357871979425934 +/- 8.04e-16]", prec); TEST(r, v, "bessel_i"); arb_hypgeom_bessel_k(r, a, z, prec); arb_set_str(v, "[0.68361006034952 +/- 7.89e-15]", prec); TEST(r, v, "bessel_k"); arb_hypgeom_bessel_k_scaled(r, a, z, prec); arb_set_str(v, "[1.4472025091165 +/- 4.23e-14]", prec); TEST(r, v, "bessel_k"); arb_hypgeom_airy(r, NULL, NULL, NULL, z, prec); arb_set_str(v, "[0.179336305478645 +/- 2.36e-16]", prec); TEST(r, v, "airy ai"); arb_hypgeom_airy(NULL, r, NULL, NULL, z, prec); arb_set_str(v, "[-0.193175208104376 +/- 4.67e-16]", prec); TEST(r, v, "airy ai'"); arb_hypgeom_airy(NULL, NULL, r, NULL, z, prec); arb_set_str(v, "[1.00693090863322 +/- 3.90e-15]", prec); TEST(r, v, "airy bi"); arb_hypgeom_airy(NULL, NULL, NULL, r, z, prec); arb_set_str(v, "[0.690299702736886 +/- 2.34e-16]", prec); TEST(r, v, "airy bi'"); arb_hypgeom_coulomb(r, NULL, a, b, z, prec); arb_set_str(v, "[0.281871468006603 +/- 4.68e-16]", prec); TEST(r, v, "coulomb f"); arb_hypgeom_coulomb(NULL, r, a, b, z, prec); arb_set_str(v, "[1.38897454984644 +/- 2.23e-15]", prec); TEST(r, v, "coulomb g"); arb_hypgeom_chebyshev_t(r, a, z, prec); arb_set_str(v, "[0.935414346693485 +/- 7.02e-16]", prec); TEST(r, v, "chebyshev_t"); arb_hypgeom_chebyshev_u(r, a, z, prec); arb_set_str(v, "[1.33630620956212 +/- 3.41e-15]", prec); TEST(r, v, "chebyshev_u"); arb_hypgeom_jacobi_p(r, a, b, c, z, prec); arb_set_str(v, "[1.03224258095454 +/- 6.54e-15]", prec); TEST(r, v, "jacobi_p"); arb_hypgeom_gegenbauer_c(r, a, b, z, prec); arb_set_str(v, "[0.58153237382485 +/- 3.74e-15]", prec); TEST(r, v, "gegenbauer_c"); arb_hypgeom_laguerre_l(r, a, b, z, prec); arb_set_str(v, "[0.76858987769621 +/- 3.19e-15]", prec); TEST(r, v, "laguerre_l"); arb_hypgeom_hermite_h(r, a, z, prec); arb_set_str(v, "[1.31600493243946 +/- 6.52e-15]", prec); TEST(r, v, "hermite_h"); arb_hypgeom_legendre_p(r, a, b, z, 0, prec); arb_set_str(v, "[0.90435295129350 +/- 5.79e-15]", prec); TEST(r, v, "legendre_q"); arb_hypgeom_legendre_q(r, a, b, z, 0, prec); arb_set_str(v, "[-0.3763617490859 +/- 3.83e-14]", prec); TEST(r, v, "legendre_q"); arb_hypgeom_dilog(r, a, prec); arb_set_str(v, "[0.582240526465012 +/- 6.18e-16]", prec); TEST(r, v, "dilog"); arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(z); arb_clear(r); arb_clear(u); arb_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_hypgeom/u_integration.c000066400000000000000000000275471417376376500177130ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_calc.h" #include "double_interval.h" /* Integrand (see comments for 1f1_integration): exp(f(t)) where f(z) = -z*t + a1*log(t) + ba1*log(1+t) g(u,v) = -z*u + 0.5*[a1*log(u^2+v^2) + ba1*log((1+u)^2+v^2)] d/du g(u,v) = -z + u*a1/(u^2+v^2) + (1+u)*ba1/(v^2+(1+u)^2) d/dv g(u,v) = v*a1/(u^2+v^2) + v*ba1/(v^2+(1+u)^2) */ static di_t di_integrand_edge(di_t u, di_t v, di_t a1, di_t ba1, di_t z) { di_t X, Y, Z; X = di_neg(di_fast_mul(z, u)); if (a1.a == 0.0 && a1.b == 0.0) Y = di_interval(0.0, 0.0); else Y = di_fast_mul(a1, di_fast_log_nonnegative(di_fast_add(di_fast_sqr(u), di_fast_sqr(v)))); Z = di_fast_mul(ba1, di_fast_log_nonnegative(di_fast_add(di_fast_sqr(di_fast_add_d(u, 1.0)), di_fast_sqr(v)))); return di_fast_add(X, di_fast_mul_d(di_fast_add(Y, Z), 0.5)); } /* which == 0 - d/du g(u,v) = -z + u*(a-1)/(u^2+v^2) + (u+1)*(b-a-1)/(v^2+(1+u)^2) which == 1 - d/dv g(u,v) = v*(a-1)/(u^2+v^2) + v*(b-a-1)/(v^2+(1+u)^2) */ static di_t di_integrand_edge_diff(di_t u, di_t v, di_t a1, di_t ba1, di_t z, int which) { di_t Y, Z; if (a1.a == 0.0 && a1.b == 0.0) Y = di_interval(0.0, 0.0); else Y = di_fast_div(a1, di_fast_add(di_fast_sqr(u), di_fast_sqr(v))); Z = di_fast_div(ba1, di_fast_add(di_fast_sqr(di_fast_add_d(u, 1.0)), di_fast_sqr(v))); if (which == 0) return di_fast_add(di_neg(z), di_fast_add(di_fast_mul(u, Y), di_fast_mul(di_fast_add_d(u, 1.0), Z))); else return di_fast_mul(v, di_fast_add(Y, Z)); } static di_t di_subinterval(di_t x, slong i, slong N) { di_t res; double step; step = (x.b - x.a) / N; res.a = x.a + step * i; res.b = (i == N - 1) ? x.b : x.a + step * (i + 1); return res; } static void integrand_wide_bound5(acb_t res, const acb_t t, const arb_t a1, const arb_t ba1, const arb_t z, slong prec) { slong i, N; di_t du, dv, da1, dba1, dz, dg, dgprime; double radius, bound; double start, end; int which; arb_t abound; N = 8; bound = -D_INF; da1 = arb_get_di(a1); dba1 = arb_get_di(ba1); dz = arb_get_di(z); /* left edge: left(u) + [0, right(v)] */ /* right edge: right(u) + [0, right(v)] */ for (which = 0; which < 2; which++) { du = arb_get_di(acb_realref(t)); if (which == 0) du.b = du.a; else du.a = du.b; dv = arb_get_di(acb_imagref(t)); start = 0.0; end = dv.b; for (i = 0; i < N; i++) { dv = di_subinterval(di_interval(start, end), i, N); radius = di_fast_ubound_radius(dv); /* g(u,mid(v)) + g'(u,v) * [0, radius] */ #if 1 dg = di_integrand_edge(du, di_fast_mid(dv), da1, dba1, dz); dgprime = di_integrand_edge_diff(du, dv, da1, dba1, dz, 1); dg = di_fast_add(dg, di_fast_mul(dgprime, di_interval(0.0, radius))); #else dg = di_integrand_edge(du, dv, da1, dba1, dz); #endif bound = FLINT_MAX(bound, dg.b); } } du = arb_get_di(acb_realref(t)); start = du.a; end = du.b; dv = arb_get_di(acb_imagref(t)); dv.a = dv.b; /* top edge: [left(u), right(u)] + right(v) */ for (i = 0; i < N; i++) { du = di_subinterval(di_interval(start, end), i, N); radius = di_fast_ubound_radius(du); /* g(mid(u),v) + g'(u,v) * [0, radius] */ #if 1 dg = di_integrand_edge(di_fast_mid(du), dv, da1, dba1, dz); dgprime = di_integrand_edge_diff(du, dv, da1, dba1, dz, 0); dg = di_fast_add(dg, di_fast_mul(dgprime, di_interval(0.0, radius))); #else dg = di_integrand_edge(du, dv, da1, dba1, dz); #endif bound = FLINT_MAX(bound, dg.b); } arb_init(abound); arb_set_d(abound, bound); arb_exp(abound, abound, prec); acb_zero(res); arb_add_error(acb_realref(res), abound); arb_add_error(acb_imagref(res), abound); arb_clear(abound); } /* todo: fix acb_pow(_arb) */ static void acb_my_pow_arb(acb_t res, const acb_t a, const arb_t b, slong prec) { if (acb_contains_zero(a) && arb_is_positive(b)) { /* |a^b| <= |a|^b */ arb_t t, u; arb_init(t); arb_init(u); acb_abs(t, a, prec); arb_get_abs_ubound_arf(arb_midref(t), t, prec); mag_zero(arb_radref(t)); if (arf_cmpabs_2exp_si(arb_midref(t), 0) < 0) arb_get_abs_lbound_arf(arb_midref(u), b, prec); else arb_get_abs_ubound_arf(arb_midref(u), b, prec); arb_pow(t, t, u, prec); acb_zero(res); acb_add_error_arb(res, t); arb_clear(t); arb_clear(u); } else { acb_pow_arb(res, a, b, prec); } } static int integrand(acb_ptr out, const acb_t t, void * param, slong order, slong prec) { arb_srcptr a1, ba1, z; acb_t s, u, v; a1 = ((arb_srcptr) param) + 0; ba1 = ((arb_srcptr) param) + 1; z = ((arb_srcptr) param) + 2; acb_init(s); acb_init(u); acb_init(v); acb_add_ui(v, t, 1, prec); if (order == 1) { if (!(arb_is_positive(acb_realref(t)) || arb_is_zero(a1)) || !arb_is_positive(acb_realref(v))) acb_indeterminate(out); else integrand_wide_bound5(out, t, a1, ba1, z, prec); } else { if (acb_contains_zero(t) || acb_contains_zero(v)) { /* exp(-z t) */ acb_mul_arb(s, t, z, prec); acb_neg(s, s); acb_exp(s, s, prec); /* t^(a-1) */ acb_my_pow_arb(u, t, a1, prec); /* (1+t)^(b-a-1) */ acb_pow_arb(v, v, ba1, prec); acb_mul(out, s, u, prec); acb_mul(out, out, v, prec); } else { acb_mul_arb(s, t, z, prec); acb_neg(s, s); /* t^(a-1) */ if (arb_is_zero(a1)) { acb_zero(u); } else { acb_log(u, t, prec); acb_mul_arb(u, u, a1, prec); } /* (1+t)^(b-a-1) */ acb_log(v, v, prec); acb_mul_arb(v, v, ba1, prec); acb_add(out, s, u, prec); acb_add(out, out, v, prec); acb_exp(out, out, prec); } } acb_clear(s); acb_clear(u); acb_clear(v); return 0; } /* estimate integral by magnitude at peak */ static void estimate_magnitude(mag_t res, const arb_t ra, const arb_t rb, const arb_t rz) { double a, b, z, t1, t2, u, m; fmpz_t e; a = arf_get_d(arb_midref(ra), ARF_RND_NEAR); b = arf_get_d(arb_midref(rb), ARF_RND_NEAR); z = arf_get_d(arb_midref(rz), ARF_RND_NEAR); u = 4 - 4*b + b*b + 4*a*z - 2*b*z + z*z; if (u >= 0.0) { t1 = (-2 + b - z + sqrt(u)) / (2 * z); t2 = (-2 + b - z - sqrt(u)) / (2 * z); } else { t1 = 1e-8; t2 = 1e-8; } /* todo: better estimate when peak is at 0 */ t1 = FLINT_MAX(t1, 1e-8); t2 = FLINT_MAX(t2, 1e-8); m = -1e300; if (t1 > 0.0) { t1 = -z * t1 + (a - 1) * log(t1) + (b - a - 1) * log(1 + t1); m = FLINT_MAX(m, t1); } if (t2 > 0.0) { t2 = -z * t2 + (a - 1) * log(t2) + (b - a - 1) * log(1 + t2); m = FLINT_MAX(m, t2); } m /= log(2); if (fabs(m) < 1e300) { fmpz_init(e); fmpz_set_d(e, m); mag_set_d_2exp_fmpz(res, 1.0, e); fmpz_clear(e); } else { mag_zero(res); } } static void bound_tail(mag_t bound, const arb_t a1, const arb_t ba1, const arb_t z, const arb_t N, slong prec) { arb_t s, u, v, C; arb_init(s); arb_init(u); arb_init(v); arb_init(C); /* Assume N >= 1 and t >= 0. -z*(N+t) + (a-1)*log(N+t) + (b-a-1)*log(1+N+t) <= [-z*N + (a-1)*log(N) + (b-a-1)*log(1+N)] + [-z*t + [max(0, a-1) + max(0, b-a-1)]*log(1+t/N)] <= [-z*N + (a-1)*log(N) + (b-a-1)*log(1+N)] + [-z*t + [max(0, a-1) + max(0, b-a-1)]*(t/N)] Let C = max(0, a-1) + max(0, b-a-1). Then the remainder integral is bounded by integrand(N) * N / (N*z - C), assuming that N*z > C. */ arb_max(u, u, a1, prec); arb_max(v, v, ba1, prec); arb_add(C, u, v, prec); /* s = N*z - C */ arb_mul(s, N, z, prec); arb_sub(s, s, C, prec); if (arb_is_positive(s)) { arb_div(C, N, s, prec); /* exp(-z*N) */ arb_mul(s, N, z, prec); arb_neg(s, s); /* N^(a-1) */ arb_log(u, N, prec); arb_mul(u, u, a1, prec); /* (1+N)^(b-a-1) */ arb_add_ui(v, N, 1, prec); arb_log(v, v, prec); arb_mul(v, v, ba1, prec); arb_add(s, s, u, prec); arb_add(s, s, v, prec); arb_exp(s, s, prec); arb_mul(s, s, C, prec); arb_get_mag(bound, s); } else { mag_inf(bound); } arb_clear(s); arb_clear(u); arb_clear(v); arb_clear(C); } int _arb_hypgeom_u_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, slong prec) { acb_calc_integrate_opt_t opt; arb_struct param[3]; arb_t t, a1, ba1; acb_t zero, N, I; mag_t abs_tol, tail_bound; slong i; fmpz_t n; int ok; arb_init(t); arb_init(a1); arb_init(ba1); arb_sub_ui(a1, a, 1, prec); arb_sub(ba1, b, a, prec); arb_sub_ui(ba1, ba1, 1, prec); ok = arb_is_finite(z) && arb_is_positive(z); ok = ok && arb_is_nonnegative(a1); ok = ok && arb_is_finite(b); if (!ok) { arb_indeterminate(res); } else { mag_init(abs_tol); mag_init(tail_bound); acb_init(zero); acb_init(zero); acb_init(N); acb_init(I); fmpz_init(n); param[0] = *a1; param[1] = *ba1; param[2] = *z; acb_calc_integrate_opt_init(opt); /* opt->verbose = 2; */ /* opt->eval_limit = WORD_MAX; */ estimate_magnitude(abs_tol, a, b, z); mag_mul_2exp_si(abs_tol, abs_tol, -prec); for (i = 1; i < FLINT_BITS; i++) { fmpz_one(n); fmpz_mul_2exp(n, n, i); acb_one(N); arb_mul_2exp_fmpz(acb_realref(N), acb_realref(N), n); bound_tail(tail_bound, a1, ba1, z, acb_realref(N), 64); if (mag_cmp(tail_bound, abs_tol) < 0) break; } acb_calc_integrate(I, integrand, param, zero, N, prec, abs_tol, opt, prec); arb_add_error_mag(acb_realref(I), tail_bound); arb_rgamma(t, a, prec); arb_mul(acb_realref(I), acb_realref(I), t, prec); arb_set(res, acb_realref(I)); mag_clear(abs_tol); mag_clear(tail_bound); acb_clear(zero); acb_clear(N); acb_clear(I); fmpz_clear(n); } arb_clear(t); arb_clear(a1); arb_clear(ba1); return ok; } void arb_hypgeom_u_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, slong prec) { arb_t res2; arb_init(res2); if (!_arb_hypgeom_u_integration(res2, a, b, z, prec)) { arb_t c, d; arb_init(c); arb_init(d); arb_sub(c, a, b, prec); arb_add_ui(c, c, 1, prec); arb_sub_ui(d, b, 2, prec); arb_neg(d, d); if (_arb_hypgeom_u_integration(res2, c, d, z, prec)) { arb_sub_ui(c, b, 1, prec); arb_neg(c, c); arb_pow(c, z, c, prec); arb_mul(res2, res2, c, prec); } arb_clear(c); arb_clear(d); } arb_swap(res, res2); arb_clear(res2); } arb-2.22.1/arb_hypgeom/wrappers.c000066400000000000000000000330351417376376500166740ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_hypgeom.h" #include "acb_hypgeom.h" void arb_hypgeom_erfi(arb_t res, const arb_t z, slong prec) { if (!arb_is_finite(z)) { arb_indeterminate(res); } else { acb_t t; acb_init(t); arb_set(acb_realref(t), z); acb_hypgeom_erfi(t, t, prec); arb_swap(res, acb_realref(t)); acb_clear(t); } } void arb_hypgeom_fresnel(arb_t res1, arb_t res2, const arb_t z, int normalized, slong prec) { if (!arb_is_finite(z)) { if (res1 != NULL) arb_indeterminate(res1); if (res2 != NULL) arb_indeterminate(res2); } else { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), z); acb_hypgeom_fresnel(res1 ? t : NULL, res2 ? u : NULL, t, normalized, prec); if (res1 != NULL) arb_swap(res1, acb_realref(t)); if (res2 != NULL) arb_swap(res2, acb_realref(u)); acb_clear(t); acb_clear(u); } } void arb_hypgeom_ei(arb_t res, const arb_t z, slong prec) { if (!arb_is_finite(z)) { arb_indeterminate(res); } else { acb_t t; acb_init(t); arb_set(acb_realref(t), z); acb_hypgeom_ei(t, t, prec); arb_swap(res, acb_realref(t)); acb_clear(t); } } void arb_hypgeom_shi(arb_t res, const arb_t z, slong prec) { if (!arb_is_finite(z)) { arb_indeterminate(res); } else { acb_t t; acb_init(t); arb_set(acb_realref(t), z); acb_hypgeom_shi(t, t, prec); arb_swap(res, acb_realref(t)); acb_clear(t); } } void arb_hypgeom_chi(arb_t res, const arb_t z, slong prec) { if (!arb_is_finite(z) || !arb_is_positive(z)) { arb_indeterminate(res); } else { acb_t t; acb_init(t); arb_set(acb_realref(t), z); acb_hypgeom_chi(t, t, prec); arb_swap(res, acb_realref(t)); acb_clear(t); } } void arb_hypgeom_li(arb_t res, const arb_t z, int offset, slong prec) { if (!arb_is_finite(z) || !arb_is_nonnegative(z)) { arb_indeterminate(res); } else { acb_t t; acb_init(t); arb_set(acb_realref(t), z); acb_hypgeom_li(t, t, offset, prec); arb_swap(res, acb_realref(t)); acb_clear(t); } } void arb_hypgeom_0f1(arb_t res, const arb_t a, const arb_t z, int regularized, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), a); arb_set(acb_realref(u), z); acb_hypgeom_0f1(t, t, u, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_m(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), a); arb_set(acb_realref(u), b); arb_set(acb_realref(v), z); acb_hypgeom_m(t, t, u, v, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } void arb_hypgeom_1f1(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) { arb_hypgeom_m(res, a, b, z, regularized, prec); } void arb_hypgeom_u(arb_t res, const arb_t a, const arb_t b, const arb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), a); arb_set(acb_realref(u), b); arb_set(acb_realref(v), z); acb_hypgeom_u(t, t, u, v, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } void arb_hypgeom_2f1(arb_t res, const arb_t a, const arb_t b, const arb_t c, const arb_t z, int regularized, slong prec) { acb_t t, u, v, w; acb_init(t); acb_init(u); acb_init(v); acb_init(w); arb_set(acb_realref(t), a); arb_set(acb_realref(u), b); arb_set(acb_realref(v), c); arb_set(acb_realref(w), z); acb_hypgeom_2f1(t, t, u, v, w, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(w); } void arb_hypgeom_pfq(arb_t res, arb_srcptr a, slong p, arb_srcptr b, slong q, const arb_t z, int regularized, slong prec) { acb_ptr t; slong i; t = _acb_vec_init(p + q + 1); for (i = 0; i < p; i++) arb_set(acb_realref(t + i), a + i); for (i = 0; i < q; i++) arb_set(acb_realref(t + p + i), b + i); arb_set(acb_realref(t + p + q), z); acb_hypgeom_pfq(t, t, p, t + p, q, t + p + q, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); _acb_vec_clear(t, p + q + 1); } void arb_hypgeom_bessel_j(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_bessel_j(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_bessel_y(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_bessel_y(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_bessel_jy(arb_t res1, arb_t res2, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_bessel_jy(t, u, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res1, acb_realref(t)); else arb_indeterminate(res1); if (acb_is_finite(u) && acb_is_real(u)) arb_swap(res2, acb_realref(u)); else arb_indeterminate(res2); acb_clear(t); acb_clear(u); } void arb_hypgeom_bessel_i(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_bessel_i(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_bessel_i_scaled(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_bessel_i_scaled(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_bessel_k(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_bessel_k(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_bessel_k_scaled(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_bessel_k_scaled(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_expint(arb_t res, const arb_t s, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), s); arb_set(acb_realref(u), z); acb_hypgeom_expint(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_gamma_lower(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), s); arb_set(acb_realref(u), z); acb_hypgeom_gamma_lower(t, t, u, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_gamma_upper(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), s); arb_set(acb_realref(u), z); acb_hypgeom_gamma_upper(t, t, u, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_beta_lower(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), a); arb_set(acb_realref(u), b); arb_set(acb_realref(v), z); acb_hypgeom_beta_lower(t, t, u, v, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } void arb_hypgeom_chebyshev_t(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_chebyshev_t(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_chebyshev_u(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_chebyshev_u(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_jacobi_p(arb_t res, const arb_t n, const arb_t a, const arb_t b, const arb_t z, slong prec) { acb_t t, u, v, w; acb_init(t); acb_init(u); acb_init(v); acb_init(w); arb_set(acb_realref(t), n); arb_set(acb_realref(u), a); arb_set(acb_realref(v), b); arb_set(acb_realref(w), z); acb_hypgeom_jacobi_p(t, t, u, v, w, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(w); } void arb_hypgeom_gegenbauer_c(arb_t res, const arb_t n, const arb_t m, const arb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), n); arb_set(acb_realref(u), m); arb_set(acb_realref(v), z); acb_hypgeom_gegenbauer_c(t, t, u, v, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } void arb_hypgeom_laguerre_l(arb_t res, const arb_t n, const arb_t m, const arb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), n); arb_set(acb_realref(u), m); arb_set(acb_realref(v), z); acb_hypgeom_laguerre_l(t, t, u, v, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } void arb_hypgeom_hermite_h(arb_t res, const arb_t nu, const arb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); arb_set(acb_realref(t), nu); arb_set(acb_realref(u), z); acb_hypgeom_hermite_h(t, t, u, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); } void arb_hypgeom_legendre_q(arb_t res, const arb_t n, const arb_t m, const arb_t z, int type, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), n); arb_set(acb_realref(u), m); arb_set(acb_realref(v), z); acb_hypgeom_legendre_q(t, t, u, v, type, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); } void arb_hypgeom_dilog(arb_t res, const arb_t z, slong prec) { acb_t t; acb_init(t); arb_set(acb_realref(t), z); acb_hypgeom_dilog(t, t, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); } arb-2.22.1/arb_mat.h000066400000000000000000000324071417376376500141510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARB_MAT_H #define ARB_MAT_H #ifdef ARB_MAT_INLINES_C #define ARB_MAT_INLINE #else #define ARB_MAT_INLINE static __inline__ #endif #include #include "flint/fmpz_mat.h" #include "flint/fmpq_mat.h" #include "flint/perm.h" #include "arb.h" #include "arb_poly.h" #ifdef __cplusplus extern "C" { #endif typedef struct { arb_ptr entries; slong r; slong c; arb_ptr * rows; } arb_mat_struct; typedef arb_mat_struct arb_mat_t[1]; #define arb_mat_entry(mat,i,j) ((mat)->rows[i] + (j)) #define arb_mat_nrows(mat) ((mat)->r) #define arb_mat_ncols(mat) ((mat)->c) ARB_MAT_INLINE arb_ptr arb_mat_entry_ptr(arb_mat_t mat, slong i, slong j) { return arb_mat_entry(mat, i, j); } /* Memory management */ void arb_mat_init(arb_mat_t mat, slong r, slong c); void arb_mat_clear(arb_mat_t mat); ARB_MAT_INLINE void arb_mat_swap(arb_mat_t mat1, arb_mat_t mat2) { arb_mat_struct t = *mat1; *mat1 = *mat2; *mat2 = t; } ARB_MAT_INLINE void arb_mat_swap_entrywise(arb_mat_t mat1, arb_mat_t mat2) { slong i, j; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) arb_swap(arb_mat_entry(mat2, i, j), arb_mat_entry(mat1, i, j)); } /* Window matrices */ void arb_mat_window_init(arb_mat_t window, const arb_mat_t mat, slong r1, slong c1, slong r2, slong c2); ARB_MAT_INLINE void arb_mat_window_clear(arb_mat_t window) { flint_free(window->rows); } /* Conversions */ void arb_mat_set(arb_mat_t dest, const arb_mat_t src); void arb_mat_set_fmpz_mat(arb_mat_t dest, const fmpz_mat_t src); void arb_mat_set_round_fmpz_mat(arb_mat_t dest, const fmpz_mat_t src, slong prec); void arb_mat_set_fmpq_mat(arb_mat_t dest, const fmpq_mat_t src, slong prec); /* Random generation */ void arb_mat_randtest(arb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits); /* I/O */ void arb_mat_fprintd(FILE * file, const arb_mat_t mat, slong digits); ARB_MAT_INLINE void arb_mat_printd(const arb_mat_t mat, slong digits) { arb_mat_fprintd(stdout, mat, digits); } /* Comparisons */ int arb_mat_eq(const arb_mat_t mat1, const arb_mat_t mat2); int arb_mat_ne(const arb_mat_t mat1, const arb_mat_t mat2); int arb_mat_equal(const arb_mat_t mat1, const arb_mat_t mat2); int arb_mat_overlaps(const arb_mat_t mat1, const arb_mat_t mat2); int arb_mat_contains(const arb_mat_t mat1, const arb_mat_t mat2); int arb_mat_contains_fmpq_mat(const arb_mat_t mat1, const fmpq_mat_t mat2); int arb_mat_contains_fmpz_mat(const arb_mat_t mat1, const fmpz_mat_t mat2); ARB_MAT_INLINE int arb_mat_is_empty(const arb_mat_t mat) { return (mat->r == 0) || (mat->c == 0); } ARB_MAT_INLINE int arb_mat_is_square(const arb_mat_t mat) { return (mat->r == mat->c); } int arb_mat_is_exact(const arb_mat_t A); int arb_mat_is_zero(const arb_mat_t mat); int arb_mat_is_finite(const arb_mat_t mat); int arb_mat_is_triu(const arb_mat_t mat); int arb_mat_is_tril(const arb_mat_t mat); ARB_MAT_INLINE int arb_mat_is_diag(const arb_mat_t mat) { return arb_mat_is_tril(mat) && arb_mat_is_triu(mat); } /* Radius and interval operations */ ARB_MAT_INLINE void arb_mat_get_mid(arb_mat_t B, const arb_mat_t A) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_get_mid_arb(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j)); } ARB_MAT_INLINE void arb_mat_add_error_mag(arb_mat_t mat, const mag_t err) { slong i, j; for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) arb_add_error_mag(arb_mat_entry(mat, i, j), err); } /* Special matrices */ void arb_mat_zero(arb_mat_t mat); void arb_mat_one(arb_mat_t mat); void arb_mat_ones(arb_mat_t mat); void arb_mat_indeterminate(arb_mat_t mat); void arb_mat_hilbert(arb_mat_t mat, slong prec); void arb_mat_pascal(arb_mat_t mat, int triangular, slong prec); void arb_mat_stirling(arb_mat_t mat, int kind, slong prec); void arb_mat_dct(arb_mat_t mat, int type, slong prec); void arb_mat_transpose(arb_mat_t mat1, const arb_mat_t mat2); /* Norms */ void arb_mat_bound_inf_norm(mag_t b, const arb_mat_t A); void arb_mat_frobenius_norm(arb_t res, const arb_mat_t A, slong prec); void arb_mat_bound_frobenius_norm(mag_t b, const arb_mat_t A); /* Arithmetic */ void arb_mat_neg(arb_mat_t dest, const arb_mat_t src); void arb_mat_add(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec); void arb_mat_sub(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec); void arb_mat_mul(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec); void arb_mat_mul_classical(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec); void arb_mat_mul_threaded(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec); void _arb_mat_addmul_rad_mag_fast(arb_mat_t C, mag_srcptr A, mag_srcptr B, slong ar, slong ac, slong bc); void arb_mat_mul_block(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec); void arb_mat_mul_entrywise(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec); void arb_mat_sqr_classical(arb_mat_t B, const arb_mat_t A, slong prec); void arb_mat_sqr(arb_mat_t B, const arb_mat_t A, slong prec); void arb_mat_pow_ui(arb_mat_t B, const arb_mat_t A, ulong exp, slong prec); /* Scalar arithmetic */ ARB_MAT_INLINE void arb_mat_scalar_mul_2exp_si(arb_mat_t B, const arb_mat_t A, slong c) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_mul_2exp_si(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c); } ARB_MAT_INLINE void arb_mat_scalar_addmul_si(arb_mat_t B, const arb_mat_t A, slong c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_addmul_si(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_mul_si(arb_mat_t B, const arb_mat_t A, slong c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_mul_si(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_div_si(arb_mat_t B, const arb_mat_t A, slong c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_div_si(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_addmul_fmpz(arb_mat_t B, const arb_mat_t A, const fmpz_t c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_addmul_fmpz(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_mul_fmpz(arb_mat_t B, const arb_mat_t A, const fmpz_t c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_mul_fmpz(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_div_fmpz(arb_mat_t B, const arb_mat_t A, const fmpz_t c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_div_fmpz(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_addmul_arb(arb_mat_t B, const arb_mat_t A, const arb_t c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_addmul(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_mul_arb(arb_mat_t B, const arb_mat_t A, const arb_t c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_mul(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } ARB_MAT_INLINE void arb_mat_scalar_div_arb(arb_mat_t B, const arb_mat_t A, const arb_t c, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_div(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), c, prec); } /* Solving */ ARB_MAT_INLINE void arb_mat_swap_rows(arb_mat_t mat, slong * perm, slong r, slong s) { if (r != s) { arb_ptr u; slong t; if (perm != NULL) { t = perm[s]; perm[s] = perm[r]; perm[r] = t; } u = mat->rows[s]; mat->rows[s] = mat->rows[r]; mat->rows[r] = u; } } slong arb_mat_find_pivot_partial(const arb_mat_t mat, slong start_row, slong end_row, slong c); void arb_mat_solve_tril_classical(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec); void arb_mat_solve_tril_recursive(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec); void arb_mat_solve_tril(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec); void arb_mat_solve_triu_classical(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec); void arb_mat_solve_triu_recursive(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec); void arb_mat_solve_triu(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec); int arb_mat_lu_classical(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec); int arb_mat_lu_recursive(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec); int arb_mat_lu(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec); void arb_mat_solve_lu_precomp(arb_mat_t X, const slong * perm, const arb_mat_t A, const arb_mat_t B, slong prec); int arb_mat_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec); int arb_mat_solve_lu(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec); int arb_mat_solve_precond(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec); int arb_mat_solve_preapprox(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, const arb_mat_t R, const arb_mat_t T, slong prec); void arb_mat_approx_mul(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec); void arb_mat_approx_solve_triu(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec); void arb_mat_approx_solve_tril(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec); int arb_mat_approx_lu(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec); void arb_mat_approx_solve_lu_precomp(arb_mat_t X, const slong * perm, const arb_mat_t A, const arb_mat_t B, slong prec); int arb_mat_approx_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec); int arb_mat_approx_inv(arb_mat_t X, const arb_mat_t A, slong prec); int arb_mat_inv(arb_mat_t X, const arb_mat_t A, slong prec); void arb_mat_det_lu(arb_t det, const arb_mat_t A, slong prec); void arb_mat_det_precond(arb_t det, const arb_mat_t A, slong prec); void arb_mat_det(arb_t det, const arb_mat_t A, slong prec); int _arb_mat_cholesky_banachiewicz(arb_mat_t A, slong prec); int arb_mat_cho(arb_mat_t L, const arb_mat_t A, slong prec); void arb_mat_solve_cho_precomp(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, slong prec); void arb_mat_inv_cho_precomp(arb_mat_t X, const arb_mat_t L, slong prec); int arb_mat_spd_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec); int arb_mat_spd_inv(arb_mat_t X, const arb_mat_t A, slong prec); int _arb_mat_ldl_inplace(arb_mat_t A, slong prec); int _arb_mat_ldl_golub_and_van_loan(arb_mat_t A, slong prec); int arb_mat_ldl(arb_mat_t L, const arb_mat_t A, slong prec); void arb_mat_solve_ldl_precomp(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, slong prec); void arb_mat_inv_ldl_precomp(arb_mat_t X, const arb_mat_t L, slong prec); /* Special functions */ void arb_mat_exp_taylor_sum(arb_mat_t S, const arb_mat_t A, slong N, slong prec); void arb_mat_exp(arb_mat_t B, const arb_mat_t A, slong prec); void _arb_mat_charpoly(arb_ptr poly, const arb_mat_t mat, slong prec); void arb_mat_charpoly(arb_poly_t poly, const arb_mat_t mat, slong prec); void _arb_mat_companion(arb_mat_t mat, arb_srcptr poly, slong prec); void arb_mat_companion(arb_mat_t mat, const arb_poly_t poly, slong prec); void arb_mat_trace(arb_t trace, const arb_mat_t mat, slong prec); void _arb_mat_diag_prod(arb_t res, const arb_mat_t A, slong a, slong b, slong prec); void arb_mat_diag_prod(arb_t res, const arb_mat_t A, slong prec); /* Sparsity structure */ void arb_mat_entrywise_is_zero(fmpz_mat_t dest, const arb_mat_t src); void arb_mat_entrywise_not_is_zero(fmpz_mat_t dest, const arb_mat_t src); slong arb_mat_count_is_zero(const arb_mat_t mat); ARB_MAT_INLINE slong arb_mat_count_not_is_zero(const arb_mat_t mat) { slong size; size = arb_mat_nrows(mat) * arb_mat_ncols(mat); return size - arb_mat_count_is_zero(mat); } ARB_MAT_INLINE slong arb_mat_allocated_bytes(const arb_mat_t x) { return _arb_vec_allocated_bytes(x->entries, x->r * x->c) + x->r * sizeof(arb_ptr); } #ifdef __cplusplus } #endif #endif arb-2.22.1/arb_mat/000077500000000000000000000000001417376376500137725ustar00rootroot00000000000000arb-2.22.1/arb_mat/add.c000066400000000000000000000013621417376376500146700ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_add(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) arb_add(arb_mat_entry(res, i, j), arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j), prec); } arb-2.22.1/arb_mat/addmul_rad_mag_fast.c000066400000000000000000000207741417376376500201050ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" /* Block size for better cache locality. */ #define BLOCK_SIZE 32 /* Don't convert to doubles when smaller than this block size. */ #define MIN_D_BLOCK_SIZE 5 /* With doubles, we can have an exponent range of about 1024, minus some slack for accumulated sums. */ #define DOUBLE_MAX_OFFSET 900 static __inline__ double dot8(const double * A, const double * B) { return ((A[0] * B[0] + A[1] * B[1]) + (A[2] * B[2] + A[3] * B[3])) + ((A[4] * B[4] + A[5] * B[5]) + (A[6] * B[6] + A[7] * B[7])); } /* Upper bound of matrix product, assuming nonnegative entries and no overflow/underflow. B is pre-transposed. Straightforward blocked implementation; could use BLAS, but this matrix product is rarely going to be the bottleneck. */ static void _d_mat_addmul(double * C, const double * A, const double * B, slong ar, slong ac, slong bc) { slong ii, jj, kk, i, j, k; double t, eps; eps = ldexp(1.0, -52); for (ii = 0; ii < ar; ii += BLOCK_SIZE) { for (jj = 0; jj < bc; jj += BLOCK_SIZE) { for (kk = 0; kk < ac; kk += BLOCK_SIZE) { for (i = ii; i < FLINT_MIN(ii + BLOCK_SIZE, ar); i++) { for (j = jj; j < FLINT_MIN(jj + BLOCK_SIZE, bc); j++) { if (BLOCK_SIZE == 32 && kk + BLOCK_SIZE <= ac) { double t0, t1, t2, t3; t0 = dot8(A + i * ac + kk + 0, B + j * ac + kk + 0); t1 = dot8(A + i * ac + kk + 8, B + j * ac + kk + 8); t2 = dot8(A + i * ac + kk + 16, B + j * ac + kk + 16); t3 = dot8(A + i * ac + kk + 24, B + j * ac + kk + 24); t = (t0 + t1) + (t2 + t3); } else { t = 0.0; for (k = kk; k < FLINT_MIN(kk + BLOCK_SIZE, ac); k++) t += A[i * ac + k] * B[j * ac + k]; } C[i * bc + j] += t; } } } } } /* Compensate for possible rounding errors */ for (i = 0; i < ar; i++) for (j = 0; j < bc; j++) C[i * bc + j] *= (1.0 + 2.01 * (ac + 1) * eps); } /* We use WORD_MIN to represent zero here. */ static __inline__ slong _mag_get_exp(const mag_t x) { if (mag_is_special(x)) return WORD_MIN; else return MAG_EXP(x); } static double mag_get_d_fixed_si(const mag_t x, slong e) { return ldexp(MAG_MAN(x), MAG_EXP(x) - e - MAG_BITS); } void _arb_mat_addmul_rad_mag_fast(arb_mat_t C, mag_srcptr A, mag_srcptr B, slong ar, slong ac, slong bc) { slong i, j, k, M, N, P, top, n, block_start, block_end; slong *A_min, *A_max, *B_min, *B_max, max_offset; double *CC, *AA, *BB; M = ar; N = ac; P = bc; /* todo: could use TMP_ALLOC */ A_min = flint_malloc(sizeof(slong) * M); A_max = flint_malloc(sizeof(slong) * M); B_min = flint_malloc(sizeof(slong) * P); B_max = flint_malloc(sizeof(slong) * P); AA = flint_malloc(ar * ac * sizeof(double)); BB = flint_malloc(ac * bc * sizeof(double)); CC = flint_malloc(ar * bc * sizeof(double)); max_offset = DOUBLE_MAX_OFFSET; block_start = 0; while (block_start < N) { block_end = block_start + 1; /* index is exclusive block_end */ /* begin with this column of A and row of B */ for (i = 0; i < M; i++) A_max[i] = A_min[i] = _mag_get_exp(A + i * N + block_start); for (i = 0; i < P; i++) B_max[i] = B_min[i] = _mag_get_exp(B + i * N + block_start); while (block_end < N) { /* check if we can extend with column [block_end] of A */ for (i = 0; i < M; i++) { top = _mag_get_exp(A + i * N + block_end); /* zeros are irrelevant */ if (top == WORD_MIN || A_max[i] == WORD_MIN) continue; /* jump will be too big */ if (top > A_min[i] + max_offset || top < A_max[i] - max_offset) goto mblocks_built; } /* check if we can extend with row [block_end] of B */ for (i = 0; i < P; i++) { top = _mag_get_exp(B + i * N + block_end); if (top == WORD_MIN || B_max[i] == WORD_MIN) continue; if (top > B_min[i] + max_offset || top < B_max[i] - max_offset) goto mblocks_built; } /* second pass to update the extreme values */ for (i = 0; i < M; i++) { top = _mag_get_exp(A + i * N + block_end); if (A_max[i] == WORD_MIN) { A_max[i] = top; A_min[i] = top; } else if (top != WORD_MIN) { if (top < A_min[i]) A_min[i] = top; if (top > A_max[i]) A_max[i] = top; } } for (i = 0; i < P; i++) { top = _mag_get_exp(B + i * N + block_end); if (B_max[i] == WORD_MIN) { B_max[i] = top; B_min[i] = top; } else if (top != WORD_MIN) { if (top < B_min[i]) B_min[i] = top; if (top > B_max[i]) B_max[i] = top; } } block_end++; } mblocks_built: n = block_end - block_start; if (n <= MIN_D_BLOCK_SIZE) { /* increment so we don't just do steps of 1 in degenerate cases */ block_end = FLINT_MIN(block_start + MIN_D_BLOCK_SIZE, N); n = block_end - block_start; for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { for (k = 0; k < n; k++) { mag_fast_addmul(arb_radref(arb_mat_entry(C, i, j)), A + i * ac + block_start + k, B + j * ac + block_start + k); } } } } else { for (i = 0; i < ar; i++) { if (A_min[i] == WORD_MIN) /* only zeros in this row */ continue; A_min[i] = (A_min[i] + A_max[i]) / 2; for (j = 0; j < n; j++) AA[i * n + j] = mag_get_d_fixed_si(A + i * ac + block_start + j, A_min[i]); } /* Note: B and BB are both transposed in memory */ for (i = 0; i < bc; i++) { if (B_min[i] == WORD_MIN) /* only zeros in this column */ continue; B_min[i] = (B_min[i] + B_max[i]) / 2; for (j = 0; j < n; j++) BB[i * n + j] = mag_get_d_fixed_si(B + i * ac + block_start + j, B_min[i]); } for (i = 0; i < ar * bc; i++) CC[i] = 0.0; _d_mat_addmul(CC, AA, BB, ar, n, bc); for (i = 0; i < ar; i++) { if (A_min[i] == WORD_MIN) continue; for (j = 0; j < bc; j++) { if (B_min[j] == WORD_MIN) continue; if (CC[i * bc + j] != 0.0) { mag_t t; MAG_SET_D_2EXP(MAG_MAN(t), MAG_EXP(t), CC[i * bc + j], A_min[i] + B_min[j]); mag_add(arb_radref(arb_mat_entry(C, i, j)), arb_radref(arb_mat_entry(C, i, j)), t); } } } } block_start = block_end; } flint_free(A_max); flint_free(A_min); flint_free(B_max); flint_free(B_min); flint_free(AA); flint_free(BB); flint_free(CC); } arb-2.22.1/arb_mat/approx_inv.c000066400000000000000000000014171417376376500163260ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_approx_inv(arb_mat_t X, const arb_mat_t A, slong prec) { if (X == A) { int r; arb_mat_t T; arb_mat_init(T, arb_mat_nrows(A), arb_mat_ncols(A)); r = arb_mat_approx_inv(T, A, prec); arb_mat_swap(T, X); arb_mat_clear(T); return r; } arb_mat_one(X); return arb_mat_approx_solve(X, A, X, prec); } arb-2.22.1/arb_mat/approx_lu.c000066400000000000000000000105621417376376500161530ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _apply_permutation(slong * AP, arb_mat_t A, slong * P, slong n, slong offset) { if (n != 0) { arb_ptr * Atmp; slong * APtmp; slong i; Atmp = flint_malloc(sizeof(arb_ptr) * n); APtmp = flint_malloc(sizeof(slong) * n); for (i = 0; i < n; i++) Atmp[i] = A->rows[P[i] + offset]; for (i = 0; i < n; i++) A->rows[i + offset] = Atmp[i]; for (i = 0; i < n; i++) APtmp[i] = AP[P[i] + offset]; for (i = 0; i < n; i++) AP[i + offset] = APtmp[i]; flint_free(Atmp); flint_free(APtmp); } } void _arb_vec_approx_scalar_addmul(arb_ptr res, arb_srcptr vec, slong len, const arb_t c, slong prec) { slong i; for (i = 0; i < len; i++) arf_addmul(arb_midref(res + i), arb_midref(vec + i), arb_midref(c), prec, ARF_RND_DOWN); } int arb_mat_approx_lu_classical(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec) { arf_t d; arb_t e; arb_ptr * a; slong i, j, m, n, r, row, col; int result; if (arb_mat_is_empty(A)) return 1; m = arb_mat_nrows(A); n = arb_mat_ncols(A); arb_mat_get_mid(LU, A); a = LU->rows; row = col = 0; for (i = 0; i < m; i++) P[i] = i; arf_init(d); arb_init(e); result = 1; while (row < m && col < n) { r = arb_mat_find_pivot_partial(LU, row, m, col); if (r == -1) { result = 0; break; } else if (r != row) arb_mat_swap_rows(LU, P, row, r); arf_ui_div(d, 1, arb_midref(a[row] + col), prec, ARB_RND); for (j = row + 1; j < m; j++) { arf_mul(arb_midref(e), arb_midref(a[j] + col), d, prec, ARB_RND); arb_neg(e, e); _arb_vec_approx_scalar_addmul(a[j] + col, a[row] + col, n - col, e, prec); arf_zero(arb_midref(a[j] + col)); arb_neg(a[j] + row, e); } row++; col++; } arf_clear(d); arb_clear(e); return result; } int arb_mat_approx_lu_recursive(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec) { slong i, m, n, r1, r2, n1; arb_mat_t A0, A1, A00, A01, A10, A11; slong * P1; m = A->r; n = A->c; if (m <= 1 || n <= 1) { return arb_mat_approx_lu_classical(P, LU, A, prec); } arb_mat_get_mid(LU, A); n1 = n / 2; for (i = 0; i < m; i++) P[i] = i; P1 = flint_malloc(sizeof(slong) * m); arb_mat_window_init(A0, LU, 0, 0, m, n1); arb_mat_window_init(A1, LU, 0, n1, m, n); r1 = arb_mat_approx_lu(P1, A0, A0, prec); if (!r1) { flint_free(P1); arb_mat_window_clear(A0); arb_mat_window_clear(A1); return 0; } /* r1 = rank of A0 */ r1 = FLINT_MIN(m, n1); _apply_permutation(P, LU, P1, m, 0); arb_mat_window_init(A00, LU, 0, 0, r1, r1); arb_mat_window_init(A10, LU, r1, 0, m, r1); arb_mat_window_init(A01, LU, 0, n1, r1, n); arb_mat_window_init(A11, LU, r1, n1, m, n); arb_mat_approx_solve_tril(A01, A00, A01, 1, prec); { /* arb_mat_approx_submul(A11, A11, A10, A01, prec); */ arb_mat_t T; arb_mat_init(T, A10->r, A01->c); arb_mat_approx_mul(T, A10, A01, prec); arb_mat_sub(A11, A11, T, prec); arb_mat_get_mid(A11, A11); arb_mat_clear(T); } r2 = arb_mat_approx_lu(P1, A11, A11, prec); if (!r2) r1 = r2 = 0; else _apply_permutation(P, LU, P1, m - r1, r1); flint_free(P1); arb_mat_window_clear(A00); arb_mat_window_clear(A01); arb_mat_window_clear(A10); arb_mat_window_clear(A11); arb_mat_window_clear(A0); arb_mat_window_clear(A1); return r1 && r2; } int arb_mat_approx_lu(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec) { if (arb_mat_nrows(A) < 8 || arb_mat_ncols(A) < 8) return arb_mat_approx_lu_classical(P, LU, A, prec); else return arb_mat_approx_lu_recursive(P, LU, A, prec); } arb-2.22.1/arb_mat/approx_mul.c000066400000000000000000000071501417376376500163270ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_approx_mul_classical(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { slong ar, br, bc, i, j, k; ar = arb_mat_nrows(A); br = arb_mat_nrows(B); bc = arb_mat_ncols(B); if (br == 0) { arb_mat_zero(C); return; } if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, ar, bc); arb_mat_approx_mul_classical(T, A, B, prec); arb_mat_swap_entrywise(T, C); arb_mat_clear(T); return; } if (br <= 2) { for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { arf_mul(arb_midref(arb_mat_entry(C, i, j)), arb_midref(arb_mat_entry(A, i, 0)), arb_midref(arb_mat_entry(B, 0, j)), prec, ARB_RND); for (k = 1; k < br; k++) { arf_addmul(arb_midref(arb_mat_entry(C, i, j)), arb_midref(arb_mat_entry(A, i, k)), arb_midref(arb_mat_entry(B, k, j)), prec, ARB_RND); } } } } else { arb_ptr tmp; TMP_INIT; TMP_START; tmp = TMP_ALLOC(sizeof(arb_struct) * br * bc); for (i = 0; i < br; i++) for (j = 0; j < bc; j++) tmp[j * br + i] = *arb_mat_entry(B, i, j); for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { arb_approx_dot(arb_mat_entry(C, i, j), NULL, 0, A->rows[i], 1, tmp + j * br, 1, br, prec); } } TMP_END; } } void arb_mat_approx_mul(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { slong cutoff; /* todo: detect small-integer matrices */ if (prec <= 2 * FLINT_BITS) cutoff = 120; else if (prec <= 16 * FLINT_BITS) cutoff = 60; else cutoff = 40; if (arb_mat_nrows(A) <= cutoff || arb_mat_ncols(A) <= cutoff || arb_mat_ncols(B) <= cutoff) { arb_mat_approx_mul_classical(C, A, B, prec); } else { if (arb_mat_is_exact(A) && arb_mat_is_exact(B)) { arb_mat_mul(C, A, B, prec); } else { arb_mat_t AM, BM; if (arb_mat_is_exact(A)) { arb_mat_init(BM, arb_mat_nrows(B), arb_mat_ncols(B)); arb_mat_get_mid(BM, B); arb_mat_mul(C, A, BM, prec); arb_mat_clear(BM); } else if (arb_mat_is_exact(B)) { arb_mat_init(AM, arb_mat_nrows(A), arb_mat_ncols(A)); arb_mat_get_mid(AM, A); arb_mat_mul(C, AM, B, prec); arb_mat_clear(AM); } else { arb_mat_init(BM, arb_mat_nrows(B), arb_mat_ncols(B)); arb_mat_get_mid(BM, B); arb_mat_init(AM, arb_mat_nrows(A), arb_mat_ncols(A)); arb_mat_get_mid(AM, A); arb_mat_mul(C, AM, BM, prec); arb_mat_clear(AM); arb_mat_clear(BM); } } arb_mat_get_mid(C, C); } } arb-2.22.1/arb_mat/approx_solve.c000066400000000000000000000015761417376376500166700ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_approx_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { int result; slong n, m, *perm; arb_mat_t LU; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; perm = _perm_init(n); arb_mat_init(LU, n, n); result = arb_mat_approx_lu(perm, LU, A, prec); if (result) arb_mat_approx_solve_lu_precomp(X, perm, LU, B, prec); arb_mat_clear(LU); _perm_clear(perm); return result; } arb-2.22.1/arb_mat/approx_solve_lu_precomp.c000066400000000000000000000024551417376376500211120ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_approx_solve_lu_precomp(arb_mat_t X, const slong * perm, const arb_mat_t A, const arb_mat_t B, slong prec) { slong i, c, n, m; n = arb_mat_nrows(X); m = arb_mat_ncols(X); if (X == B) { arb_ptr tmp = flint_malloc(sizeof(arb_struct) * n); for (c = 0; c < m; c++) { for (i = 0; i < n; i++) tmp[i] = B->rows[perm[i]][c]; for (i = 0; i < n; i++) X->rows[i][c] = tmp[i]; } flint_free(tmp); } else { for (c = 0; c < m; c++) { for (i = 0; i < n; i++) { arb_set(arb_mat_entry(X, i, c), arb_mat_entry(B, perm[i], c)); } } } arb_mat_get_mid(X, X); arb_mat_approx_solve_tril(X, A, X, 1, prec); arb_mat_approx_solve_triu(X, A, X, 0, prec); } arb-2.22.1/arb_mat/approx_solve_tril.c000066400000000000000000000056251417376376500177210ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void arb_approx_div(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); } void arb_mat_approx_solve_tril_classical(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) { slong i, j, n, m; arb_ptr tmp; arb_t s; n = L->r; m = B->c; arb_init(s); tmp = flint_malloc(sizeof(arb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *arb_mat_entry(X, j, i); for (j = 0; j < n; j++) { arb_approx_dot(s, arb_mat_entry(B, j, i), 1, L->rows[j], 1, tmp, 1, j, prec); if (!unit) arb_approx_div(tmp + j, s, arb_mat_entry(L, j, j), prec); else arb_swap(tmp + j, s); } for (j = 0; j < n; j++) *arb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); arb_clear(s); } void arb_mat_approx_solve_tril_recursive(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) { arb_mat_t LA, LC, LD, XX, XY, BX, BY, T; slong r, n, m; n = L->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A 0]^ [X] == [A^ 0 ] [X] == [A^ X] [C D] [Y] == [-D^ C A^ D^] [Y] == [D^ (Y - C A^ X)] */ arb_mat_window_init(LA, L, 0, 0, r, r); arb_mat_window_init(LC, L, r, 0, n, r); arb_mat_window_init(LD, L, r, r, n, n); arb_mat_window_init(BX, B, 0, 0, r, m); arb_mat_window_init(BY, B, r, 0, n, m); arb_mat_window_init(XX, X, 0, 0, r, m); arb_mat_window_init(XY, X, r, 0, n, m); arb_mat_approx_solve_tril(XX, LA, BX, unit, prec); /* arb_mat_submul(XY, BY, LC, XX); */ arb_mat_init(T, LC->r, BX->c); arb_mat_approx_mul(T, LC, XX, prec); arb_mat_sub(XY, BY, T, prec); arb_mat_get_mid(XY, XY); arb_mat_clear(T); arb_mat_approx_solve_tril(XY, LD, XY, unit, prec); arb_mat_window_clear(LA); arb_mat_window_clear(LC); arb_mat_window_clear(LD); arb_mat_window_clear(BX); arb_mat_window_clear(BY); arb_mat_window_clear(XX); arb_mat_window_clear(XY); } void arb_mat_approx_solve_tril(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) arb_mat_approx_solve_tril_classical(X, L, B, unit, prec); else arb_mat_approx_solve_tril_recursive(X, L, B, unit, prec); } arb-2.22.1/arb_mat/approx_solve_triu.c000066400000000000000000000055331417376376500177300ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void arb_approx_div(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND); } void arb_mat_approx_solve_triu_classical(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) { slong i, j, n, m; arb_ptr tmp; arb_t s; n = U->r; m = B->c; arb_init(s); tmp = flint_malloc(sizeof(arb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *arb_mat_entry(X, j, i); for (j = n - 1; j >= 0; j--) { arb_approx_dot(s, arb_mat_entry(B, j, i), 1, U->rows[j] + j + 1, 1, tmp + j + 1, 1, n - j - 1, prec); if (!unit) arb_approx_div(tmp + j, s, arb_mat_entry(U, j, j), prec); else arb_swap(tmp + j, s); } for (j = 0; j < n; j++) *arb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); arb_clear(s); } void arb_mat_approx_solve_triu_recursive(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) { arb_mat_t UA, UB, UD, XX, XY, BX, BY, T; slong r, n, m; n = U->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A B]^ [X] == [A^ (X - B D^ Y)] [0 D] [Y] == [ D^ Y ] */ arb_mat_window_init(UA, U, 0, 0, r, r); arb_mat_window_init(UB, U, 0, r, r, n); arb_mat_window_init(UD, U, r, r, n, n); arb_mat_window_init(BX, B, 0, 0, r, m); arb_mat_window_init(BY, B, r, 0, n, m); arb_mat_window_init(XX, X, 0, 0, r, m); arb_mat_window_init(XY, X, r, 0, n, m); arb_mat_approx_solve_triu(XY, UD, BY, unit, prec); arb_mat_init(T, UB->r, XY->c); arb_mat_approx_mul(T, UB, XY, prec); arb_mat_sub(XX, BX, T, prec); arb_mat_get_mid(XX, XX); arb_mat_clear(T); arb_mat_approx_solve_triu(XX, UA, XX, unit, prec); arb_mat_window_clear(UA); arb_mat_window_clear(UB); arb_mat_window_clear(UD); arb_mat_window_clear(BX); arb_mat_window_clear(BY); arb_mat_window_clear(XX); arb_mat_window_clear(XY); } void arb_mat_approx_solve_triu(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) arb_mat_approx_solve_triu_classical(X, U, B, unit, prec); else arb_mat_approx_solve_triu_recursive(X, U, B, unit, prec); } arb-2.22.1/arb_mat/bound_frobenius_norm.c000066400000000000000000000015171417376376500203600ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_bound_frobenius_norm(mag_t b, const arb_mat_t A) { slong i, j, r, c; mag_t t; r = arb_mat_nrows(A); c = arb_mat_ncols(A); mag_zero(b); if (r == 0 || c == 0) return; mag_init(t); for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { arb_get_mag(t, arb_mat_entry(A, i, j)); mag_addmul(b, t, t); } } mag_sqrt(b, b); mag_clear(t); } arb-2.22.1/arb_mat/bound_inf_norm.c000066400000000000000000000016201417376376500171330ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_bound_inf_norm(mag_t b, const arb_mat_t A) { slong i, j, r, c; mag_t s, t; r = arb_mat_nrows(A); c = arb_mat_ncols(A); mag_zero(b); if (r == 0 || c == 0) return; mag_init(s); mag_init(t); for (i = 0; i < r; i++) { mag_zero(s); for (j = 0; j < c; j++) { arb_get_mag(t, arb_mat_entry(A, i, j)); mag_add(s, s, t); } mag_max(b, b, s); } mag_clear(s); mag_clear(t); } arb-2.22.1/arb_mat/charpoly.c000066400000000000000000000043731417376376500157660ustar00rootroot00000000000000/* Copyright (C) 2012 Sebastian Pancratz This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _arb_mat_charpoly(arb_ptr cp, const arb_mat_t mat, slong prec) { const slong n = mat->r; if (n == 0) { arb_one(cp); } else if (n == 1) { arb_neg(cp + 0, arb_mat_entry(mat, 0, 0)); arb_one(cp + 1); } else { slong i, k, t; arb_ptr a, A, s; a = _arb_vec_init(n * n); A = a + (n - 1) * n; _arb_vec_zero(cp, n + 1); arb_neg(cp + 0, arb_mat_entry(mat, 0, 0)); for (t = 1; t < n; t++) { for (i = 0; i <= t; i++) { arb_set(a + 0 * n + i, arb_mat_entry(mat, i, t)); } arb_set(A + 0, arb_mat_entry(mat, t, t)); for (k = 1; k < t; k++) { for (i = 0; i <= t; i++) { s = a + k * n + i; arb_dot(s, NULL, 0, mat->rows[i], 1, a + (k - 1) * n, 1, t + 1, prec); } arb_set(A + k, a + k * n + t); } arb_dot(A + t, NULL, 0, mat->rows[t], 1, a + (t - 1) * n, 1, t + 1, prec); for (k = 0; k <= t; k++) { arb_dot(cp + k, cp + k, 1, A, 1, cp + k - 1, -1, k, prec); arb_sub(cp + k, cp + k, A + k, prec); } } /* Shift all coefficients up by one */ for (i = n; i > 0; i--) arb_swap(cp + i, cp + (i - 1)); arb_one(cp + 0); _arb_poly_reverse(cp, cp, n + 1, n + 1); _arb_vec_clear(a, n * n); } } void arb_mat_charpoly(arb_poly_t cp, const arb_mat_t mat, slong prec) { if (mat->r != mat->c) { flint_printf("Exception (arb_mat_charpoly). Non-square matrix.\n"); flint_abort(); } arb_poly_fit_length(cp, mat->r + 1); _arb_poly_set_length(cp, mat->r + 1); _arb_mat_charpoly(cp->coeffs, mat, prec); } arb-2.22.1/arb_mat/cho.c000066400000000000000000000045471417376376500147210ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int _arb_mat_cholesky_banachiewicz(arb_mat_t A, slong prec) { slong n, i, j, k; n = arb_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { for (k = 0; k < j; k++) { arb_submul(arb_mat_entry(A, i, j), arb_mat_entry(A, i, k), arb_mat_entry(A, j, k), prec); } arb_div(arb_mat_entry(A, i, j), arb_mat_entry(A, i, j), arb_mat_entry(A, j, j), prec); } for (k = 0; k < i; k++) { arb_submul(arb_mat_entry(A, i, i), arb_mat_entry(A, i, k), arb_mat_entry(A, i, k), prec); } if (!arb_is_positive(arb_mat_entry(A, i, i))) return 0; arb_sqrt(arb_mat_entry(A, i, i), arb_mat_entry(A, i, i), prec); } return 1; } int arb_mat_cho(arb_mat_t L, const arb_mat_t A, slong prec) { slong n; if (!arb_mat_is_square(A)) { flint_printf("arb_mat_cho: a square matrix is required\n"); flint_abort(); } if (arb_mat_nrows(L) != arb_mat_nrows(A) || arb_mat_ncols(L) != arb_mat_ncols(A)) { flint_printf("arb_mat_cho: incompatible dimensions\n"); flint_abort(); } if (arb_mat_is_empty(A)) return 1; n = arb_mat_nrows(A); if (n == 1) { if (arb_is_positive(arb_mat_entry(A, 0, 0))) { arb_sqrt(arb_mat_entry(L, 0, 0), arb_mat_entry(A, 0, 0), prec); return 1; } else { return 0; } } arb_mat_set(L, A); if (!_arb_mat_cholesky_banachiewicz(L, prec)) return 0; /* set the strictly upper triangular region of L to zero */ { slong i, j; for (i = 0; i < n; i++) for (j = i+1; j < n; j++) arb_zero(arb_mat_entry(L, i, j)); } return 1; } arb-2.22.1/arb_mat/clear.c000066400000000000000000000010701417376376500152220ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_clear(arb_mat_t mat) { if (mat->entries != NULL) { _arb_vec_clear(mat->entries, mat->r * mat->c); flint_free(mat->rows); } } arb-2.22.1/arb_mat/companion.c000066400000000000000000000022521417376376500161220ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _arb_mat_companion(arb_mat_t A, arb_srcptr poly, slong prec) { slong i, j, n; arb_t c; n = arb_mat_nrows(A); if (n == 0) return; for (i = 0; i < n - 1; i++) for (j = 0; j < n; j++) arb_set_ui(arb_mat_entry(A, i, j), (i + 1) == j); arb_init(c); arb_inv(c, poly + n, prec); arb_neg(c, c); for (j = 0; j < n; j++) arb_mul(arb_mat_entry(A, n - 1, j), poly + j, c, prec); arb_clear(c); } void arb_mat_companion(arb_mat_t A, const arb_poly_t poly, slong prec) { slong n = arb_mat_nrows(A); if (n != arb_poly_degree(poly) || n != arb_mat_ncols(A)) { flint_printf("arb_mat_companion: incompatible dimensions!\n"); flint_abort(); } _arb_mat_companion(A, poly->coeffs, prec); } arb-2.22.1/arb_mat/contains.c000066400000000000000000000015071417376376500157570ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_contains(const arb_mat_t mat1, const arb_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 0; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (!arb_contains(arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/contains_fmpq_mat.c000066400000000000000000000015471417376376500176470ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_contains_fmpq_mat(const arb_mat_t mat1, const fmpq_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 0; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (!arb_contains_fmpq(arb_mat_entry(mat1, i, j), fmpq_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/contains_fmpz_mat.c000066400000000000000000000015471417376376500176600ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_contains_fmpz_mat(const arb_mat_t mat1, const fmpz_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 0; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (!arb_contains_fmpz(arb_mat_entry(mat1, i, j), fmpz_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/count_is_zero.c000066400000000000000000000013411417376376500170170ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" slong arb_mat_count_is_zero(const arb_mat_t mat) { slong nz; slong i, j; nz = 0; for (i = 0; i < arb_mat_nrows(mat); i++) { for (j = 0; j < arb_mat_ncols(mat); j++) { if (arb_is_zero(arb_mat_entry(mat, i, j))) { nz++; } } } return nz; } arb-2.22.1/arb_mat/dct.c000066400000000000000000000024631417376376500147150ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" #include "acb_dirichlet.h" void arb_mat_dct(arb_mat_t res, int kind, slong prec) { acb_dirichlet_roots_t roots; acb_t t; arb_t v; slong n, r, c, i, j; r = arb_mat_nrows(res); c = arb_mat_ncols(res); n = FLINT_MIN(r, c); if (n == 0) return; acb_dirichlet_roots_init(roots, 4 * n, (r - 1) * c, prec); acb_init(t); arb_init(v); arb_set_ui(v, n); arb_rsqrt(v, v, prec); if (r > 0) { for (j = 0; j < c; j++) arb_set(arb_mat_entry(res, 0, j), v); } arb_set_ui(v, n); arb_mul_2exp_si(v, v, -1); arb_rsqrt(v, v, prec); for (i = 1; i < r; i++) { for (j = 0; j < c; j++) { acb_dirichlet_root(t, roots, i * (2 * j + 1), prec); arb_mul(arb_mat_entry(res, i, j), acb_realref(t), v, prec); } } acb_dirichlet_roots_clear(roots); acb_clear(t); arb_clear(v); } arb-2.22.1/arb_mat/det.c000066400000000000000000000044001417376376500147100ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _arb_mat_det_cofactor_2x2(arb_t t, const arb_mat_t A, slong prec) { arb_mul (t, arb_mat_entry(A, 0, 0), arb_mat_entry(A, 1, 1), prec); arb_submul(t, arb_mat_entry(A, 0, 1), arb_mat_entry(A, 1, 0), prec); } static void _arb_mat_det_cofactor_3x3(arb_t t, const arb_mat_t A, slong prec) { arb_t a; arb_init(a); arb_mul (a, arb_mat_entry(A, 1, 0), arb_mat_entry(A, 2, 1), prec); arb_submul(a, arb_mat_entry(A, 1, 1), arb_mat_entry(A, 2, 0), prec); arb_mul (t, a, arb_mat_entry(A, 0, 2), prec); arb_mul (a, arb_mat_entry(A, 1, 2), arb_mat_entry(A, 2, 0), prec); arb_submul(a, arb_mat_entry(A, 1, 0), arb_mat_entry(A, 2, 2), prec); arb_addmul(t, a, arb_mat_entry(A, 0, 1), prec); arb_mul (a, arb_mat_entry(A, 1, 1), arb_mat_entry(A, 2, 2), prec); arb_submul(a, arb_mat_entry(A, 1, 2), arb_mat_entry(A, 2, 1), prec); arb_addmul(t, a, arb_mat_entry(A, 0, 0), prec); arb_clear(a); } void arb_mat_det(arb_t det, const arb_mat_t A, slong prec) { slong n; if (!arb_mat_is_square(A)) { flint_printf("arb_mat_det: a square matrix is required!\n"); flint_abort(); } n = arb_mat_nrows(A); if (n == 0) { arb_one(det); } else if (n == 1) { arb_set_round(det, arb_mat_entry(A, 0, 0), prec); } else if (n == 2) { _arb_mat_det_cofactor_2x2(det, A, prec); } else if (!arb_mat_is_finite(A)) { arb_indeterminate(det); } else if (arb_mat_is_tril(A) || arb_mat_is_triu(A)) { arb_mat_diag_prod(det, A, prec); } else if (n == 3) { _arb_mat_det_cofactor_3x3(det, A, prec); /* note: 4x4 performs worse than LU */ } else { if (n <= 10 || prec > 10.0 * n) arb_mat_det_lu(det, A, prec); else arb_mat_det_precond(det, A, prec); } } arb-2.22.1/arb_mat/det_lu.c000066400000000000000000000054661417376376500154250ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" slong arb_mat_gauss_partial(arb_mat_t A, slong prec) { arb_t e; arb_ptr * a; slong j, m, n, r, rank, row, col, sign; m = A->r; n = A->c; a = A->rows; rank = row = col = 0; sign = 1; arb_init(e); while (row < m && col < n) { r = arb_mat_find_pivot_partial(A, row, m, col); if (r == -1) { break; } else if (r != row) { arb_mat_swap_rows(A, NULL, row, r); sign *= -1; } rank++; for (j = row + 1; j < m; j++) { arb_div(e, a[j] + col, a[row] + col, prec); arb_neg(e, e); _arb_vec_scalar_addmul(a[j] + col + 1, a[row] + col + 1, n - col - 1, e, prec); } row++; col++; } arb_clear(e); return rank * sign; } void arb_vec_get_arf_2norm_squared_bound(arf_t s, arb_srcptr vec, slong len, slong prec) { slong i; arf_t t; arf_init(t); arf_zero(s); for (i = 0; i < len; i++) { arb_get_abs_ubound_arf(t, vec + i, prec); arf_addmul(s, t, t, prec, ARF_RND_UP); } arf_clear(t); } void arb_mat_det_lu_inplace(arb_t det, arb_mat_t A, slong prec) { slong i, n, sign, rank; n = arb_mat_nrows(A); rank = arb_mat_gauss_partial(A, prec); sign = (rank < 0) ? -1 : 1; rank = FLINT_ABS(rank); arb_set_si(det, sign); for (i = 0; i < rank; i++) arb_mul(det, det, arb_mat_entry(A, i, i), prec); /* bound unreduced part using Hadamard's inequality */ if (rank < n) { arf_t t; arf_t d; arb_t b; arf_init(t); arf_init(d); arb_init(b); arf_one(d); for (i = rank; i < n; i++) { arb_vec_get_arf_2norm_squared_bound(t, A->rows[i] + rank, n - rank, MAG_BITS); arf_mul(d, d, t, MAG_BITS, ARF_RND_UP); } arf_sqrt(d, d, MAG_BITS, ARF_RND_UP); arb_add_error_arf(b, d); arb_mul(det, det, b, prec); arf_clear(d); arf_clear(t); arb_clear(b); } } void arb_mat_det_lu(arb_t det, const arb_mat_t A, slong prec) { slong n; n = arb_mat_nrows(A); if (n == 0) { arb_one(det); } else { arb_mat_t T; arb_mat_init(T, arb_mat_nrows(A), arb_mat_ncols(A)); arb_mat_set(T, A); arb_mat_det_lu_inplace(det, T, prec); arb_mat_clear(T); } } arb-2.22.1/arb_mat/det_precond.c000066400000000000000000000061501417376376500164260ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _apply_permutation(arb_mat_t A, slong * P, slong n) { arb_ptr * Atmp; slong i; Atmp = flint_malloc(sizeof(arb_ptr) * n); for (i = 0; i < n; i++) Atmp[i] = A->rows[P[i]]; for (i = 0; i < n; i++) A->rows[i] = Atmp[i]; flint_free(Atmp); } /* Enclosure of det(I + eps) using Gershgorin circles. Can be improved. */ void arb_mat_det_one_gershgorin(arb_t det, const arb_mat_t A) { slong n, i, j; arb_t t; mag_t r, e, f; n = arb_mat_nrows(A); arb_init(t); mag_init(r); mag_init(e); mag_init(f); for (i = 0; i < n; i++) { mag_zero(e); for (j = 0; j < n; j++) { if (i == j) { arb_sub_ui(t, arb_mat_entry(A, i, j), 1, MAG_BITS); arb_get_mag(f, t); } else { arb_get_mag(f, arb_mat_entry(A, i, j)); } mag_add(e, e, f); } mag_max(r, r, e); } /* (1 + eps)^n - 1 <= expm1(n*eps) */ mag_mul_ui(r, r, n); mag_expm1(r, r); arf_one(arb_midref(det)); mag_set(arb_radref(det), r); arb_clear(t); mag_clear(r); mag_clear(e); mag_clear(f); } void arb_mat_det_precond(arb_t det, const arb_mat_t A, slong prec) { arb_mat_t LU, Linv, Uinv; arb_t detU; slong n; slong *P; n = arb_mat_nrows(A); if (n == 0) { arb_one(det); return; } P = _perm_init(n); arb_mat_init(LU, n, n); if (!arb_mat_approx_lu(P, LU, A, prec)) { /* Fallback. */ arb_mat_det_lu(det, A, prec); } else { arb_mat_init(Linv, n, n); arb_mat_init(Uinv, n, n); arb_init(detU); arb_mat_one(Linv); arb_mat_approx_solve_tril(Linv, LU, Linv, 1, prec); arb_mat_one(Uinv); arb_mat_approx_solve_triu(Uinv, LU, Uinv, 0, prec); arb_mat_diag_prod(detU, Uinv, prec); arb_mat_mul(LU, A, Uinv, prec); _apply_permutation(LU, P, n); arb_mat_mul(Uinv, Linv, LU, prec); arb_mat_det_one_gershgorin(det, Uinv); if (_perm_parity(P, n)) arb_neg(det, det); arb_div(det, det, detU, prec); if (arb_contains_zero(det)) { /* Run the interval LU algorithm. This can give a much better bound if the Gaussian elimination manages to work through several rows, and it is not that expensive. */ arb_mat_det_lu(detU, A, prec); if (mag_cmp(arb_radref(detU), arb_radref(det)) < 0) arb_set(det, detU); } arb_mat_clear(Linv); arb_mat_clear(Uinv); arb_clear(detU); } _perm_clear(P); arb_mat_clear(LU); } arb-2.22.1/arb_mat/diag_prod.c000066400000000000000000000024571417376376500160760ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _arb_mat_diag_prod(arb_t res, const arb_mat_t A, slong a, slong b, slong prec) { if (b - a == 0) { arb_one(res); } else if (b - a == 1) { arb_set_round(res, arb_mat_entry(A, a, a), prec); } else { slong i; arb_mul(res, arb_mat_entry(A, a, a), arb_mat_entry(A, a + 1, a + 1), prec); for (i = a + 2; i < b; i++) arb_mul(res, res, arb_mat_entry(A, i, i), prec); /* no advantage? */ /* arb_t t; arb_init(t); _arb_mat_diag_prod(t, A, a, a + (b - a) / 2, prec); _arb_mat_diag_prod(res, A, a + (b - a) / 2, b, prec); arb_mul(res, res, t, prec); arb_clear(t); */ } } void arb_mat_diag_prod(arb_t res, const arb_mat_t A, slong prec) { slong m, n; m = arb_mat_nrows(A); n = arb_mat_nrows(A); _arb_mat_diag_prod(res, A, 0, FLINT_MIN(m, n), prec); } arb-2.22.1/arb_mat/entrywise_is_zero.c000066400000000000000000000014061417376376500177220ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _arb_mat_entrywise_is_zero(fmpz_mat_t dest, const arb_mat_t src) { slong i, j; fmpz_mat_zero(dest); for (i = 0; i < arb_mat_nrows(src); i++) { for (j = 0; j < arb_mat_ncols(src); j++) { if (arb_is_zero(arb_mat_entry(src, i, j))) { fmpz_one(fmpz_mat_entry(dest, i, j)); } } } } arb-2.22.1/arb_mat/entrywise_not_is_zero.c000066400000000000000000000014121417376376500205770ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_entrywise_not_is_zero(fmpz_mat_t dest, const arb_mat_t src) { slong i, j; fmpz_mat_zero(dest); for (i = 0; i < arb_mat_nrows(src); i++) { for (j = 0; j < arb_mat_ncols(src); j++) { if (!arb_is_zero(arb_mat_entry(src, i, j))) { fmpz_one(fmpz_mat_entry(dest, i, j)); } } } } arb-2.22.1/arb_mat/eq.c000066400000000000000000000015071417376376500145460ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_eq(const arb_mat_t mat1, const arb_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 0; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (!arb_eq(arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/equal.c000066400000000000000000000015211417376376500152440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_equal(const arb_mat_t mat1, const arb_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 0; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (!arb_equal(arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/exp.c000066400000000000000000000114161417376376500147350ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arb_mat.h" #include "bool_mat.h" #define LOG2_OVER_E 0.25499459743395350926 slong _arb_mat_exp_choose_N(const mag_t norm, slong prec) { if (mag_is_special(norm) || mag_cmp_2exp_si(norm, 30) > 0) { return 1; } else if (mag_cmp_2exp_si(norm, -prec) < 0) { return 2; } else if (mag_cmp_2exp_si(norm, -300) < 0) { slong N = -MAG_EXP(norm); return (prec + N - 1) / N; } else { double c, t; c = mag_get_d(norm); t = d_lambertw(prec * LOG2_OVER_E / c); t = c * exp(t + 1.0); return FLINT_MIN((slong) (t + 1.0), 2 * prec); } } static void _arb_mat_exp_diagonal(arb_mat_t B, const arb_mat_t A, slong prec) { slong n, i; n = arb_mat_nrows(A); if (B != A) { arb_mat_zero(B); } for (i = 0; i < n; i++) { arb_exp(arb_mat_entry(B, i, i), arb_mat_entry(A, i, i), prec); } } void arb_mat_exp(arb_mat_t B, const arb_mat_t A, slong prec) { slong i, j, dim, nz; bool_mat_t S; slong nildegree; if (!arb_mat_is_square(A)) { flint_printf("arb_mat_exp: a square matrix is required!\n"); flint_abort(); } if (arb_mat_is_empty(A)) return; dim = arb_mat_nrows(A); if (dim == 1) { arb_exp(arb_mat_entry(B, 0, 0), arb_mat_entry(A, 0, 0), prec); return; } nz = arb_mat_count_is_zero(A); if (nz == dim * dim) { arb_mat_one(B); return; } bool_mat_init(S, dim, dim); if (nz == 0) { nildegree = -1; bool_mat_complement(S, S); } else { for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) bool_mat_set_entry(S, i, j, !arb_is_zero(arb_mat_entry(A, i, j))); if (bool_mat_is_diagonal(S)) { _arb_mat_exp_diagonal(B, A, prec); bool_mat_clear(S); return; } else { nildegree = bool_mat_nilpotency_degree(S); } } /* evaluate using scaling and squaring of truncated taylor series */ { slong wp, N, q, r; mag_t norm, err; arb_mat_t T; wp = prec + 3 * FLINT_BIT_COUNT(prec); mag_init(norm); mag_init(err); arb_mat_init(T, dim, dim); arb_mat_bound_inf_norm(norm, A); q = pow(wp, 0.25); /* wanted magnitude */ if (mag_cmp_2exp_si(norm, 2 * wp) > 0) /* too big */ r = 2 * wp; else if (mag_cmp_2exp_si(norm, -q) < 0) /* tiny, no need to reduce */ r = 0; else r = FLINT_MAX(0, q + MAG_EXP(norm)); /* reduce to magnitude 2^(-r) */ arb_mat_scalar_mul_2exp_si(T, A, -r); mag_mul_2exp_si(norm, norm, -r); N = _arb_mat_exp_choose_N(norm, wp); if (N < 1) flint_abort(); /* assert */ /* if positive, nildegree is an upper bound on nilpotency degree */ if (nildegree > 0) N = FLINT_MIN(N, nildegree); mag_exp_tail(err, norm, N); arb_mat_exp_taylor_sum(B, T, N, wp); /* add truncation error to entries for which it is not ruled out */ if (nz == 0) { for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) arb_add_error_mag(arb_mat_entry(B, i, j), err); } else if (nildegree < 0 || N < nildegree) { slong w; fmpz_mat_t W; fmpz_mat_init(W, dim, dim); w = bool_mat_all_pairs_longest_walk(W, S); if (w + 1 != nildegree) flint_abort(); /* assert */ for (i = 0; i < dim; i++) { for (j = 0; j < dim; j++) { slong d = fmpz_get_si(fmpz_mat_entry(W, i, j)) + 1; if (d < 0 || N < d) { arb_add_error_mag(arb_mat_entry(B, i, j), err); } } } fmpz_mat_clear(W); } for (i = 0; i < r; i++) { arb_mat_sqr(T, B, wp); arb_mat_swap(T, B); } for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) arb_set_round(arb_mat_entry(B, i, j), arb_mat_entry(B, i, j), prec); mag_clear(norm); mag_clear(err); arb_mat_clear(T); } bool_mat_clear(S); } arb-2.22.1/arb_mat/exp_taylor_sum.c000066400000000000000000000053541417376376500172170ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_exp_taylor_sum(arb_mat_t S, const arb_mat_t A, slong N, slong prec) { if (A == S) { arb_mat_t t; arb_mat_init(t, arb_mat_nrows(A), arb_mat_nrows(A)); arb_mat_set(t, A); arb_mat_exp_taylor_sum(S, t, N, prec); arb_mat_clear(t); } else if (N <= 0) { arb_mat_zero(S); } else if (N == 1) { arb_mat_one(S); } else if (N == 2) { arb_mat_one(S); arb_mat_add(S, S, A, prec); } else if (N == 3) { arb_mat_t T; arb_mat_init(T, arb_mat_nrows(A), arb_mat_nrows(A)); arb_mat_sqr(T, A, prec); arb_mat_scalar_mul_2exp_si(T, T, -1); arb_mat_add(S, A, T, prec); arb_mat_one(T); arb_mat_add(S, S, T, prec); arb_mat_clear(T); } else { slong i, lo, hi, m, w, dim; arb_mat_struct * pows; arb_mat_t T, U; fmpz_t c, f; dim = arb_mat_nrows(A); m = n_sqrt(N); w = (N + m - 1) / m; fmpz_init(c); fmpz_init(f); pows = flint_malloc(sizeof(arb_mat_t) * (m + 1)); arb_mat_init(T, dim, dim); arb_mat_init(U, dim, dim); for (i = 0; i <= m; i++) { arb_mat_init(pows + i, dim, dim); if (i == 0) arb_mat_one(pows + i); else if (i == 1) arb_mat_set(pows + i, A); else arb_mat_mul(pows + i, pows + i - 1, A, prec); } arb_mat_zero(S); fmpz_one(f); for (i = w - 1; i >= 0; i--) { lo = i * m; hi = FLINT_MIN(N - 1, lo + m - 1); arb_mat_zero(T); fmpz_one(c); while (hi >= lo) { arb_mat_scalar_addmul_fmpz(T, pows + hi - lo, c, prec); if (hi != 0) fmpz_mul_ui(c, c, hi); hi--; } arb_mat_mul(U, pows + m, S, prec); arb_mat_scalar_mul_fmpz(S, T, f, prec); arb_mat_add(S, S, U, prec); fmpz_mul(f, f, c); } arb_mat_scalar_div_fmpz(S, S, f, prec); fmpz_clear(c); fmpz_clear(f); for (i = 0; i <= m; i++) arb_mat_clear(pows + i); flint_free(pows); arb_mat_clear(T); arb_mat_clear(U); } } arb-2.22.1/arb_mat/find_pivot_partial.c000066400000000000000000000021071417376376500200130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" slong arb_mat_find_pivot_partial(const arb_mat_t mat, slong start_row, slong end_row, slong c) { slong best_row, i; best_row = -1; for (i = start_row; i < end_row; i++) { if (!arb_contains_zero(arb_mat_entry(mat, i, c))) { if (best_row == -1) { best_row = i; } /* todo: should take the radius into account */ else if (arf_cmpabs(arb_midref(arb_mat_entry(mat, i, c)), arb_midref(arb_mat_entry(mat, best_row, c))) > 0) { best_row = i; } } } return best_row; } arb-2.22.1/arb_mat/fprintd.c000066400000000000000000000015561417376376500156130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_fprintd(FILE * file, const arb_mat_t mat, slong digits) { slong i, j; for (i = 0; i < arb_mat_nrows(mat); i++) { flint_fprintf(file, "["); for (j = 0; j < arb_mat_ncols(mat); j++) { arb_fprintd(file, arb_mat_entry(mat, i, j), digits); if (j < arb_mat_ncols(mat) - 1) flint_fprintf(file, ", "); } flint_fprintf(file, "]\n"); } } arb-2.22.1/arb_mat/frobenius_norm.c000066400000000000000000000014731417376376500171720ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_frobenius_norm(arb_t res, const arb_mat_t A, slong prec) { slong i, j, r, c; r = arb_mat_nrows(A); c = arb_mat_ncols(A); arb_zero(res); if (r == 0 || c == 0) return; for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { arb_srcptr x = arb_mat_entry(A, i, j); arb_addmul(res, x, x, prec); } } arb_sqrtpos(res, res, prec); } arb-2.22.1/arb_mat/hilbert.c000066400000000000000000000014171417376376500155720ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_hilbert(arb_mat_t mat, slong prec) { slong R, C, i, j; R = arb_mat_nrows(mat); C = arb_mat_ncols(mat); for (i = 0; i < R; i++) { for (j = 0; j < C; j++) { arb_one(arb_mat_entry(mat, i, j)); arb_div_ui(arb_mat_entry(mat, i, j), arb_mat_entry(mat, i, j), i + j + 1, prec); } } } arb-2.22.1/arb_mat/indeterminate.c000066400000000000000000000011401417376376500167620ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_indeterminate(arb_mat_t A) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) arb_indeterminate(arb_mat_entry(A, i, j)); } arb-2.22.1/arb_mat/init.c000066400000000000000000000014121417376376500150770ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_init(arb_mat_t mat, slong r, slong c) { if (r != 0 && c != 0) { slong i; mat->entries = _arb_vec_init(r * c); mat->rows = (arb_ptr *) flint_malloc(r * sizeof(arb_ptr)); for (i = 0; i < r; i++) mat->rows[i] = mat->entries + i * c; } else mat->entries = NULL; mat->r = r; mat->c = c; } arb-2.22.1/arb_mat/inlines.c000066400000000000000000000006541417376376500156040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ARB_MAT_INLINES_C #include "arb_mat.h" arb-2.22.1/arb_mat/inv.c000066400000000000000000000013721417376376500147350ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_inv(arb_mat_t X, const arb_mat_t A, slong prec) { if (X == A) { int r; arb_mat_t T; arb_mat_init(T, arb_mat_nrows(A), arb_mat_ncols(A)); r = arb_mat_inv(T, A, prec); arb_mat_swap(T, X); arb_mat_clear(T); return r; } arb_mat_one(X); return arb_mat_solve(X, A, X, prec); } arb-2.22.1/arb_mat/inv_cho_precomp.c000066400000000000000000000044711417376376500173160ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _arb_sqr(arb_t dest, const arb_t src, slong prec) { arb_mul(dest, src, src, prec); } void arb_mat_inv_cho_precomp(arb_mat_t X, const arb_mat_t L, slong prec) { slong n; if (arb_mat_nrows(X) != arb_mat_nrows(L) || arb_mat_ncols(X) != arb_mat_ncols(L)) { flint_printf("arb_mat_inv_cho_precomp: incompatible dimensions\n"); flint_abort(); } if (arb_mat_is_empty(L)) return; n = arb_mat_nrows(L); if (n == 1) { arb_inv(arb_mat_entry(X, 0, 0), arb_mat_entry(L, 0, 0), prec); _arb_sqr(arb_mat_entry(X, 0, 0), arb_mat_entry(X, 0, 0), prec); return; } if (X == L) { flint_printf("arb_mat_inv_cho_precomp: unsupported aliasing\n"); flint_abort(); } /* invert a 2x2 or larger matrix given its L * L^T decomposition */ { slong i, j, k; arb_struct *s; arb_mat_zero(X); s = _arb_vec_init(n); for (i = 0; i < n; i++) { arb_inv(s + i, arb_mat_entry(L, i, i), prec); } for (j = n-1; j >= 0; j--) { for (i = j; i >= 0; i--) { if (i == j) { arb_set(arb_mat_entry(X, i, j), s + i); } else { arb_zero(arb_mat_entry(X, i, j)); } for (k = i + 1; k < n; k++) { arb_submul(arb_mat_entry(X, i, j), arb_mat_entry(L, k, i), arb_mat_entry(X, k, j), prec); } arb_div(arb_mat_entry(X, i, j), arb_mat_entry(X, i, j), arb_mat_entry(L, i, i), prec); arb_set(arb_mat_entry(X, j, i), arb_mat_entry(X, i, j)); } } _arb_vec_clear(s, n); } } arb-2.22.1/arb_mat/inv_ldl_precomp.c000066400000000000000000000037721417376376500173230ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_inv_ldl_precomp(arb_mat_t X, const arb_mat_t L, slong prec) { slong n; if (arb_mat_nrows(X) != arb_mat_nrows(L) || arb_mat_ncols(X) != arb_mat_ncols(L)) { flint_printf("arb_mat_inv_ldl_precomp: incompatible dimensions\n"); flint_abort(); } if (arb_mat_is_empty(L)) return; n = arb_mat_nrows(L); if (n == 1) { arb_inv(arb_mat_entry(X, 0, 0), arb_mat_entry(L, 0, 0), prec); return; } if (X == L) { flint_printf("arb_mat_inv_ldl_precomp: unsupported aliasing\n"); flint_abort(); } /* invert a 2x2 or larger matrix given its L * D * L^T decomposition */ { slong i, j, k; arb_struct *s; s = _arb_vec_init(n); for (i = 0; i < n; i++) { arb_inv(s + i, arb_mat_entry(L, i, i), prec); } arb_mat_zero(X); for (j = n-1; j >= 0; j--) { for (i = j; i >= 0; i--) { if (i == j) { arb_set(arb_mat_entry(X, i, j), s + i); } else { arb_zero(arb_mat_entry(X, i, j)); } for (k = i + 1; k < n; k++) { arb_submul(arb_mat_entry(X, i, j), arb_mat_entry(L, k, i), arb_mat_entry(X, k, j), prec); } arb_set(arb_mat_entry(X, j, i), arb_mat_entry(X, i, j)); } } _arb_vec_clear(s, n); } } arb-2.22.1/arb_mat/is_exact.c000066400000000000000000000012241417376376500157340ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_is_exact(const arb_mat_t A) { slong i, j; for (i = 0; i < arb_mat_nrows(A); i++) for (j = 0; j < arb_mat_ncols(A); j++) if (!mag_is_zero(arb_radref(arb_mat_entry(A, i, j)))) return 0; return 1; } arb-2.22.1/arb_mat/is_finite.c000066400000000000000000000012501417376376500161050ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_is_finite(const arb_mat_t A) { slong i, j, n, m; n = arb_mat_nrows(A); m = arb_mat_ncols(A); for (i = 0; i < n; i++) for (j = 0; j < m; j++) if (!arb_is_finite(arb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/is_tril.c000066400000000000000000000012501417376376500156010ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_is_tril(const arb_mat_t A) { slong i, j, n, m; n = arb_mat_nrows(A); m = arb_mat_ncols(A); for (i = 0; i < n; i++) for (j = i + 1; j < m; j++) if (!arb_is_zero(arb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/is_triu.c000066400000000000000000000012621417376376500156150ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_is_triu(const arb_mat_t A) { slong i, j, n, m; n = arb_mat_nrows(A); m = arb_mat_ncols(A); for (i = 1; i < n; i++) for (j = 0; j < FLINT_MIN(i, m); j++) if (!arb_is_zero(arb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/is_zero.c000066400000000000000000000012441417376376500156110ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_is_zero(const arb_mat_t A) { slong i, j, n, m; n = arb_mat_nrows(A); m = arb_mat_ncols(A); for (i = 0; i < n; i++) for (j = 0; j < m; j++) if (!arb_is_zero(arb_mat_entry(A, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/ldl.c000066400000000000000000000067401417376376500147200ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _arb_sqr(arb_t dest, const arb_t src, slong prec) { arb_mul(dest, src, src, prec); } int _arb_mat_ldl_inplace(arb_mat_t A, slong prec) { slong n, i, j, k; arb_t tmp; int result; n = arb_mat_nrows(A); arb_init(tmp); result = 1; for (i = 0; i < n && result; i++) { for (j = 0; j < i; j++) { for (k = 0; k < j; k++) { arb_mul(tmp, arb_mat_entry(A, i, k), arb_mat_entry(A, j, k), prec); arb_submul(arb_mat_entry(A, i, j), arb_mat_entry(A, k, k), tmp, prec); } arb_div(arb_mat_entry(A, i, j), arb_mat_entry(A, i, j), arb_mat_entry(A, j, j), prec); } for (k = 0; k < i; k++) { _arb_sqr(tmp, arb_mat_entry(A, i, k), prec); arb_submul(arb_mat_entry(A, i, i), arb_mat_entry(A, k, k), tmp, prec); } if (!arb_is_positive(arb_mat_entry(A, i, i))) result = 0; } arb_clear(tmp); return result; } int _arb_mat_ldl_golub_and_van_loan(arb_mat_t A, slong prec) { slong n, i, j, k; arb_struct *v; int result; n = arb_mat_nrows(A); v = _arb_vec_init(n); result = 1; for (j = 0; j < n; j++) { for (i = 0; i < j; i++) { arb_mul(v + i, arb_mat_entry(A, j, i), arb_mat_entry(A, i, i), prec); } arb_set(v + j, arb_mat_entry(A, j, j)); for (i = 0; i < j; i++) { arb_submul(v + j, arb_mat_entry(A, j, i), v + i, prec); } if (!arb_is_positive(v + j)) { result = 0; break; } arb_set(arb_mat_entry(A, j, j), v + j); for (i = j + 1; i < n; i++) { for (k = 0; k < j; k++) { arb_submul(arb_mat_entry(A, i, j), arb_mat_entry(A, i, k), v + k, prec); } arb_div(arb_mat_entry(A, i, j), arb_mat_entry(A, i, j), v + j, prec); } } _arb_vec_clear(v, n); return result; } int arb_mat_ldl(arb_mat_t L, const arb_mat_t A, slong prec) { slong n; int result; if (!arb_mat_is_square(A)) { flint_printf("arb_mat_ldl: a square matrix is required\n"); flint_abort(); } if (arb_mat_nrows(L) != arb_mat_nrows(A) || arb_mat_ncols(L) != arb_mat_ncols(A)) { flint_printf("arb_mat_ldl: incompatible dimensions\n"); flint_abort(); } if (arb_mat_is_empty(A)) return 1; n = arb_mat_nrows(A); arb_mat_set(L, A); if (n == 1) return arb_is_positive(arb_mat_entry(L, 0, 0)); result = _arb_mat_ldl_golub_and_van_loan(L, prec); /* set the strictly upper triangular region of L to zero */ { slong i, j; for (i = 0; i < n; i++) for (j = i+1; j < n; j++) arb_zero(arb_mat_entry(L, i, j)); } return result; } arb-2.22.1/arb_mat/lu.c000066400000000000000000000012071417376376500145560ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_lu(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec) { if (arb_mat_nrows(A) < 8 || arb_mat_ncols(A) < 8) return arb_mat_lu_classical(P, LU, A, prec); else return arb_mat_lu_recursive(P, LU, A, prec); } arb-2.22.1/arb_mat/lu_classical.c000066400000000000000000000027521417376376500166020ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_lu_classical(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec) { arb_t d, e; arb_ptr * a; slong i, j, m, n, r, row, col; int result; if (arb_mat_is_empty(A)) return 1; m = arb_mat_nrows(A); n = arb_mat_ncols(A); arb_mat_set(LU, A); a = LU->rows; row = col = 0; for (i = 0; i < m; i++) P[i] = i; arb_init(d); arb_init(e); result = 1; while (row < m && col < n) { r = arb_mat_find_pivot_partial(LU, row, m, col); if (r == -1) { result = 0; break; } else if (r != row) arb_mat_swap_rows(LU, P, row, r); arb_set(d, a[row] + col); for (j = row + 1; j < m; j++) { arb_div(e, a[j] + col, d, prec); arb_neg(e, e); _arb_vec_scalar_addmul(a[j] + col, a[row] + col, n - col, e, prec); arb_zero(a[j] + col); arb_neg(a[j] + row, e); } row++; col++; } arb_clear(d); arb_clear(e); return result; } arb-2.22.1/arb_mat/lu_recursive.c000066400000000000000000000051371417376376500166530ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _apply_permutation(slong * AP, arb_mat_t A, slong * P, slong n, slong offset) { if (n != 0) { arb_ptr * Atmp; slong * APtmp; slong i; Atmp = flint_malloc(sizeof(arb_ptr) * n); APtmp = flint_malloc(sizeof(slong) * n); for (i = 0; i < n; i++) Atmp[i] = A->rows[P[i] + offset]; for (i = 0; i < n; i++) A->rows[i + offset] = Atmp[i]; for (i = 0; i < n; i++) APtmp[i] = AP[P[i] + offset]; for (i = 0; i < n; i++) AP[i + offset] = APtmp[i]; flint_free(Atmp); flint_free(APtmp); } } int arb_mat_lu_recursive(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec) { slong i, m, n, r1, r2, n1; arb_mat_t A0, A1, A00, A01, A10, A11; slong * P1; m = A->r; n = A->c; if (m <= 1 || n <= 1) { return arb_mat_lu_classical(P, LU, A, prec); } if (LU != A) arb_mat_set(LU, A); n1 = n / 2; for (i = 0; i < m; i++) P[i] = i; P1 = flint_malloc(sizeof(slong) * m); arb_mat_window_init(A0, LU, 0, 0, m, n1); arb_mat_window_init(A1, LU, 0, n1, m, n); r1 = arb_mat_lu(P1, A0, A0, prec); if (!r1) { flint_free(P1); arb_mat_window_clear(A0); arb_mat_window_clear(A1); return 0; } /* r1 = rank of A0 */ r1 = FLINT_MIN(m, n1); _apply_permutation(P, LU, P1, m, 0); arb_mat_window_init(A00, LU, 0, 0, r1, r1); arb_mat_window_init(A10, LU, r1, 0, m, r1); arb_mat_window_init(A01, LU, 0, n1, r1, n); arb_mat_window_init(A11, LU, r1, n1, m, n); arb_mat_solve_tril(A01, A00, A01, 1, prec); { /* arb_mat_submul(A11, A11, A10, A01, prec); */ arb_mat_t T; arb_mat_init(T, A10->r, A01->c); arb_mat_mul(T, A10, A01, prec); arb_mat_sub(A11, A11, T, prec); arb_mat_clear(T); } r2 = arb_mat_lu(P1, A11, A11, prec); if (!r2) r1 = r2 = 0; else _apply_permutation(P, LU, P1, m - r1, r1); flint_free(P1); arb_mat_window_clear(A00); arb_mat_window_clear(A01); arb_mat_window_clear(A10); arb_mat_window_clear(A11); arb_mat_window_clear(A0); arb_mat_window_clear(A1); return r1 && r2; } arb-2.22.1/arb_mat/mul.c000066400000000000000000000023141417376376500147330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_mul(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { slong cutoff; /* todo: detect small-integer matrices */ if (prec <= 2 * FLINT_BITS) cutoff = 60; else if (prec <= 8 * FLINT_BITS) cutoff = 50; else cutoff = 40; if (arb_mat_nrows(A) <= cutoff || arb_mat_ncols(A) <= cutoff || arb_mat_ncols(B) <= cutoff) { if (flint_get_num_threads() > 1 && ((double) arb_mat_nrows(A) * (double) arb_mat_nrows(B) * (double) arb_mat_ncols(B) * (double) prec > 100000)) { arb_mat_mul_threaded(C, A, B, prec); } else { arb_mat_mul_classical(C, A, B, prec); } } else { arb_mat_mul_block(C, A, B, prec); } } arb-2.22.1/arb_mat/mul_block.c000066400000000000000000000400521417376376500161060ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_is_lagom(const arb_mat_t A) { slong i, j, M, N; M = arb_mat_nrows(A); N = arb_mat_ncols(A); for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (!ARB_IS_LAGOM(arb_mat_entry(A, i, j))) return 0; } } return 1; } /* allow changing this from the test code */ ARB_DLL slong arb_mat_mul_block_min_block_size = 0; void arb_mat_mid_addmul_block_fallback(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong block_start, slong block_end, slong prec) { slong M, P, n; slong i, j; arb_ptr tmpA, tmpB; M = arb_mat_nrows(A); P = arb_mat_ncols(B); n = block_end - block_start; tmpA = flint_malloc(sizeof(arb_struct) * (M * n + P * n)); tmpB = tmpA + M * n; for (i = 0; i < M; i++) { for (j = 0; j < n; j++) { *arb_midref(tmpA + i * n + j) = *arb_midref(arb_mat_entry(A, i, block_start + j)); mag_init(arb_radref(tmpA + i * n + j)); } } for (i = 0; i < P; i++) { for (j = 0; j < n; j++) { *arb_midref(tmpB + i * n + j) = *arb_midref(arb_mat_entry(B, block_start + j, i)); mag_init(arb_radref(tmpB + i * n + j)); } } for (i = 0; i < M; i++) { for (j = 0; j < P; j++) { arb_dot(arb_mat_entry(C, i, j), (block_start == 0) ? NULL : arb_mat_entry(C, i, j), 0, tmpA + i * n, 1, tmpB + j * n, 1, n, prec); } } flint_free(tmpA); } void arb_mat_mid_addmul_block_prescaled(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong block_start, slong block_end, const slong * A_min, /* A per-row bottom exponent */ const slong * B_min, /* B per-row bottom exponent */ slong prec) { slong M, P, n; slong i, j; slong M0, M1, P0, P1, Mstep, Pstep; int inexact; /* flint_printf("block mul from %wd to %wd\n", block_start, block_end); */ M = arb_mat_nrows(A); P = arb_mat_ncols(B); n = block_end - block_start; /* Create sub-blocks to keep matrices nearly square. Necessary? */ #if 1 Mstep = (M < 2 * n) ? M : n; Pstep = (P < 2 * n) ? P : n; #else Mstep = M; Pstep = P; #endif for (M0 = 0; M0 < M; M0 += Mstep) { for (P0 = 0; P0 < P; P0 += Pstep) { fmpz_mat_t AA, BB, CC; arb_t t; fmpz_t e; M1 = FLINT_MIN(M0 + Mstep, M); P1 = FLINT_MIN(P0 + Pstep, P); fmpz_mat_init(AA, M1 - M0, n); fmpz_mat_init(BB, n, P1 - P0); fmpz_mat_init(CC, M1 - M0, P1 - P0); /* Convert to fixed-point matrices. */ for (i = M0; i < M1; i++) { if (A_min[i] == WORD_MIN) /* only zeros in this row */ continue; for (j = 0; j < n; j++) { inexact = arf_get_fmpz_fixed_si(fmpz_mat_entry(AA, i - M0, j), arb_midref(arb_mat_entry(A, i, block_start + j)), A_min[i]); if (inexact) { flint_printf("matrix multiplication: bad exponent!\n"); flint_abort(); } } } for (i = P0; i < P1; i++) { if (B_min[i] == WORD_MIN) /* only zeros in this column */ continue; for (j = 0; j < n; j++) { inexact = arf_get_fmpz_fixed_si(fmpz_mat_entry(BB, j, i - P0), arb_midref(arb_mat_entry(B, block_start + j, i)), B_min[i]); if (inexact) { flint_printf("matrix multiplication: bad exponent!\n"); flint_abort(); } } } /* The main multiplication */ fmpz_mat_mul(CC, AA, BB); /* flint_printf("bits %wd %wd %wd\n", fmpz_mat_max_bits(CC), fmpz_mat_max_bits(AA), fmpz_mat_max_bits(BB)); */ fmpz_mat_clear(AA); fmpz_mat_clear(BB); arb_init(t); /* Add to the result matrix */ for (i = M0; i < M1; i++) { for (j = P0; j < P1; j++) { *e = A_min[i] + B_min[j]; /* The first time we write this Cij */ if (block_start == 0) { arb_set_round_fmpz_2exp(arb_mat_entry(C, i, j), fmpz_mat_entry(CC, i - M0, j - P0), e, prec); } else { arb_set_round_fmpz_2exp(t, fmpz_mat_entry(CC, i - M0, j - P0), e, prec); arb_add(arb_mat_entry(C, i, j), arb_mat_entry(C, i, j), t, prec); } } } arb_clear(t); fmpz_mat_clear(CC); } } } /* todo: squaring optimizations */ void arb_mat_mul_block(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { slong M, N, P; slong *A_min, *A_max, *B_min, *B_max; short *A_bits, *B_bits; slong *A_bot, *B_bot; slong block_start, block_end, i, j, bot, top, max_height; slong b, A_max_bits, B_max_bits; slong min_block_size; arb_srcptr t; int A_exact, B_exact; double A_density, B_density; M = arb_mat_nrows(A); N = arb_mat_ncols(A); P = arb_mat_ncols(B); if (N != arb_mat_nrows(B) || M != arb_mat_nrows(C) || P != arb_mat_ncols(C)) { flint_printf("arb_mat_mul_block: incompatible dimensions\n"); flint_abort(); } if (M == 0 || N == 0 || P == 0 || arb_mat_is_zero(A) || arb_mat_is_zero(B)) { arb_mat_zero(C); return; } if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, M, P); arb_mat_mul_block(T, A, B, prec); arb_mat_swap_entrywise(T, C); arb_mat_clear(T); return; } /* We assume everywhere below that exponents cannot overflow/underflow the small fmpz value range. */ if (!arb_mat_is_lagom(A) || !arb_mat_is_lagom(B)) { arb_mat_mul_classical(C, A, B, prec); return; } /* bottom exponents of A */ A_bot = flint_malloc(sizeof(slong) * M * N); /* minimum bottom exponent in current row */ A_min = flint_malloc(sizeof(slong) * M); /* maximum top exponent in current row */ A_max = flint_malloc(sizeof(slong) * M); B_bot = flint_malloc(sizeof(slong) * N * P); B_min = flint_malloc(sizeof(slong) * P); B_max = flint_malloc(sizeof(slong) * P); /* save space using shorts to store the bit sizes temporarily; the block algorithm will not be used at extremely high precision */ A_bits = flint_malloc(sizeof(short) * M * N); B_bits = flint_malloc(sizeof(short) * N * P); A_exact = B_exact = 1; A_max_bits = B_max_bits = 0; A_density = B_density = 0; /* Build table of bottom exponents (WORD_MIN signifies a zero), and also collect some statistics. */ for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { t = arb_mat_entry(A, i, j); if (arf_is_zero(arb_midref(t))) { A_bot[i * N + j] = WORD_MIN; A_bits[i * N + j] = 0; } else { b = arf_bits(arb_midref(t)); A_bot[i * N + j] = ARF_EXP(arb_midref(t)) - b; A_bits[i * N + j] = b; A_max_bits = FLINT_MAX(A_max_bits, b); A_density++; } A_exact = A_exact && mag_is_zero(arb_radref(t)); } } for (i = 0; i < N; i++) { for (j = 0; j < P; j++) { t = arb_mat_entry(B, i, j); if (arf_is_zero(arb_midref(t))) { B_bot[i * P + j] = WORD_MIN; B_bits[i * P + j] = 0; } else { b = arf_bits(arb_midref(t)); B_bot[i * P + j] = ARF_EXP(arb_midref(t)) - b; B_bits[i * P + j] = b; B_max_bits = FLINT_MAX(B_max_bits, b); B_density++; } B_exact = B_exact && mag_is_zero(arb_radref(t)); } } A_density = A_density / (M * N); B_density = B_density / (N * P); /* Don't shift too far when creating integer block matrices. */ max_height = 1.25 * FLINT_MIN(prec, FLINT_MAX(A_max_bits, B_max_bits)) + 192; /* Avoid block algorithm for extremely high-precision matrices? */ /* Warning: these cutoffs are completely bogus... */ if (A_max_bits > 8000 || B_max_bits > 8000 || (A_density < 0.1 && B_density < 0.1 && max_height > 1024)) { flint_free(A_bot); flint_free(A_max); flint_free(A_min); flint_free(B_bot); flint_free(B_max); flint_free(B_min); flint_free(A_bits); flint_free(B_bits); arb_mat_mul_classical(C, A, B, prec); return; } if (arb_mat_mul_block_min_block_size != 0) min_block_size = arb_mat_mul_block_min_block_size; else min_block_size = 30; block_start = 0; while (block_start < N) { /* Find a run of columns of A and rows of B such that the bottom exponents differ by at most max_height. */ block_end = block_start + 1; /* index is exclusive block_end */ /* begin with this column of A and row of B */ for (i = 0; i < M; i++) { A_max[i] = A_min[i] = A_bot[i * N + block_start]; A_max[i] += (slong) A_bits[i * N + block_start]; } for (i = 0; i < P; i++) { B_max[i] = B_min[i] = B_bot[block_start * P + i]; B_max[i] += (slong) B_bits[block_start * P + i]; } while (block_end < N) { double size; /* End block if memory would be excessive. */ /* Necessary? */ /* Should also do initial check above, if C alone is too large. */ size = (block_end - block_start) * M * (double) A_max_bits; size += (block_end - block_start) * P * (double) B_max_bits; size += (M * P) * (double) (A_max_bits + B_max_bits); size /= 8.0; if (size > 2e9) goto blocks_built; /* check if we can extend with column [block_end] of A */ for (i = 0; i < M; i++) { bot = A_bot[i * N + block_end]; /* zeros are irrelevant */ if (bot == WORD_MIN || A_max[i] == WORD_MIN) continue; top = bot + (slong) A_bits[i * N + block_end]; /* jump will be too big */ if (top > A_min[i] + max_height || bot < A_max[i] - max_height) goto blocks_built; } /* check if we can extend with row [block_end] of B */ for (i = 0; i < P; i++) { bot = B_bot[block_end * P + i]; if (bot == WORD_MIN || B_max[i] == WORD_MIN) continue; top = bot + (slong) B_bits[block_end * P + i]; if (top > B_min[i] + max_height || bot < B_max[i] - max_height) goto blocks_built; } /* second pass to update the extreme values */ for (i = 0; i < M; i++) { bot = A_bot[i * N + block_end]; top = bot + (slong) A_bits[i * N + block_end]; if (A_max[i] == WORD_MIN) { A_max[i] = top; A_min[i] = bot; } else if (bot != WORD_MIN) { if (bot < A_min[i]) A_min[i] = bot; if (top > A_max[i]) A_max[i] = top; } } for (i = 0; i < P; i++) { bot = B_bot[block_end * P + i]; top = bot + (slong) B_bits[block_end * P + i]; if (B_max[i] == WORD_MIN) { B_max[i] = top; B_min[i] = bot; } else if (bot != WORD_MIN) { if (bot < B_min[i]) B_min[i] = bot; if (top > B_max[i]) B_max[i] = top; } } block_end++; } blocks_built: if (block_end - block_start < min_block_size) { block_end = FLINT_MIN(N, block_start + min_block_size); arb_mat_mid_addmul_block_fallback(C, A, B, block_start, block_end, prec); } else { arb_mat_mid_addmul_block_prescaled(C, A, B, block_start, block_end, A_min, B_min, prec); } block_start = block_end; } flint_free(A_bot); flint_free(A_max); flint_free(A_min); flint_free(B_bot); flint_free(B_max); flint_free(B_min); flint_free(A_bits); flint_free(B_bits); /* Radius multiplications */ if (!A_exact || !B_exact) { mag_ptr AA, BB; /* Shallow (since exponents are small!) mag_struct matrices represented by linear arrays; B is transposed to improve locality. */ AA = flint_malloc(M * N * sizeof(mag_struct)); BB = flint_malloc(P * N * sizeof(mag_struct)); if (!A_exact && !B_exact) { /* (A+ar)(B+br) = AB + (A+ar)br + ar B = AB + A br + ar (B + br) */ /* A + ar */ for (i = 0; i < M; i++) for (j = 0; j < N; j++) { mag_fast_init_set_arf(AA + i * N + j, arb_midref(arb_mat_entry(A, i, j))); mag_add(AA + i * N + j, AA + i * N + j, arb_radref(arb_mat_entry(A, i, j))); } /* br */ for (i = 0; i < N; i++) for (j = 0; j < P; j++) BB[j * N + i] = *arb_radref(arb_mat_entry(B, i, j)); _arb_mat_addmul_rad_mag_fast(C, AA, BB, M, N, P); /* ar */ for (i = 0; i < M; i++) for (j = 0; j < N; j++) AA[i * N + j] = *arb_radref(arb_mat_entry(A, i, j)); /* B */ for (i = 0; i < N; i++) for (j = 0; j < P; j++) mag_fast_init_set_arf(BB + j * N + i, arb_midref(arb_mat_entry(B, i, j))); _arb_mat_addmul_rad_mag_fast(C, AA, BB, M, N, P); } else if (A_exact) { /* A(B+br) = AB + A br */ for (i = 0; i < M; i++) for (j = 0; j < N; j++) mag_fast_init_set_arf(AA + i * N + j, arb_midref(arb_mat_entry(A, i, j))); for (i = 0; i < N; i++) for (j = 0; j < P; j++) BB[j * N + i] = *arb_radref(arb_mat_entry(B, i, j)); _arb_mat_addmul_rad_mag_fast(C, AA, BB, M, N, P); } else { /* (A+ar)B = AB + ar B */ for (i = 0; i < M; i++) for (j = 0; j < N; j++) AA[i * N + j] = *arb_radref(arb_mat_entry(A, i, j)); for (i = 0; i < N; i++) for (j = 0; j < P; j++) mag_fast_init_set_arf(BB + j * N + i, arb_midref(arb_mat_entry(B, i, j))); _arb_mat_addmul_rad_mag_fast(C, AA, BB, M, N, P); } flint_free(AA); flint_free(BB); } } arb-2.22.1/arb_mat/mul_classical.c000066400000000000000000000045361417376376500167610ustar00rootroot00000000000000/* Copyright (C) 2012, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_mul_classical(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { slong ar, ac, br, bc, i, j, k; if (A == B && (arb_mat_nrows(A) <= 2 || (prec >= 1024 && arb_mat_nrows(A) < 8))) { arb_mat_sqr_classical(C, A, prec); return; } ar = arb_mat_nrows(A); ac = arb_mat_ncols(A); br = arb_mat_nrows(B); bc = arb_mat_ncols(B); if (ac != br || ar != arb_mat_nrows(C) || bc != arb_mat_ncols(C)) { flint_printf("arb_mat_mul: incompatible dimensions\n"); flint_abort(); } if (br == 0) { arb_mat_zero(C); return; } if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, ar, bc); arb_mat_mul_classical(T, A, B, prec); arb_mat_swap_entrywise(T, C); arb_mat_clear(T); return; } if (br <= 2) { for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { /* todo: efficient fmma code */ arb_mul(arb_mat_entry(C, i, j), arb_mat_entry(A, i, 0), arb_mat_entry(B, 0, j), prec); for (k = 1; k < br; k++) { arb_addmul(arb_mat_entry(C, i, j), arb_mat_entry(A, i, k), arb_mat_entry(B, k, j), prec); } } } } else { arb_ptr tmp; TMP_INIT; TMP_START; tmp = TMP_ALLOC(sizeof(arb_struct) * br * bc); for (i = 0; i < br; i++) for (j = 0; j < bc; j++) tmp[j * br + i] = *arb_mat_entry(B, i, j); for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { arb_dot(arb_mat_entry(C, i, j), NULL, 0, A->rows[i], 1, tmp + j * br, 1, br, prec); } } TMP_END; } } arb-2.22.1/arb_mat/mul_entrywise.c000066400000000000000000000017141417376376500170470ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_mul_entrywise(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { slong i, j; if (arb_mat_nrows(A) != arb_mat_nrows(B) || arb_mat_ncols(A) != arb_mat_ncols(B)) { flint_printf("arb_mat_mul_entrywise: incompatible dimensions\n"); flint_abort(); } for (i = 0; i < arb_mat_nrows(A); i++) { for (j = 0; j < arb_mat_ncols(A); j++) { arb_mul(arb_mat_entry(C, i, j), arb_mat_entry(A, i, j), arb_mat_entry(B, i, j), prec); } } } arb-2.22.1/arb_mat/mul_threaded.c000066400000000000000000000057451417376376500166060ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" #include "pthread.h" typedef struct { arb_ptr * C; const arb_ptr * A; const arb_ptr * B; slong ar0; slong ar1; slong bc0; slong bc1; slong br; slong prec; } arb_mat_mul_arg_t; void * _arb_mat_mul_thread(void * arg_ptr) { arb_mat_mul_arg_t arg = *((arb_mat_mul_arg_t *) arg_ptr); slong i, j, br, bc; arb_ptr tmp; TMP_INIT; br = arg.br; bc = arg.bc1 - arg.bc0; TMP_START; tmp = TMP_ALLOC(sizeof(arb_struct) * br * bc); for (i = 0; i < br; i++) for (j = 0; j < bc; j++) tmp[j * br + i] = arg.B[i][arg.bc0 + j]; for (i = arg.ar0; i < arg.ar1; i++) { for (j = arg.bc0; j < arg.bc1; j++) { arb_dot(arg.C[i] + j, NULL, 0, arg.A[i], 1, tmp + (j - arg.bc0) * br, 1, br, arg.prec); } } TMP_END; flint_cleanup(); return NULL; } void arb_mat_mul_threaded(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) { slong ar, ac, br, bc, i, num_threads; pthread_t * threads; arb_mat_mul_arg_t * args; ar = arb_mat_nrows(A); ac = arb_mat_ncols(A); br = arb_mat_nrows(B); bc = arb_mat_ncols(B); if (ac != br || ar != arb_mat_nrows(C) || bc != arb_mat_ncols(C)) { flint_printf("arb_mat_mul_threaded: incompatible dimensions\n"); flint_abort(); } if (br == 0) { arb_mat_zero(C); return; } if (A == C || B == C) { arb_mat_t T; arb_mat_init(T, ar, bc); arb_mat_mul_threaded(T, A, B, prec); arb_mat_swap_entrywise(T, C); arb_mat_clear(T); return; } num_threads = flint_get_num_threads(); threads = flint_malloc(sizeof(pthread_t) * num_threads); args = flint_malloc(sizeof(arb_mat_mul_arg_t) * num_threads); for (i = 0; i < num_threads; i++) { args[i].C = C->rows; args[i].A = A->rows; args[i].B = B->rows; if (ar >= bc) { args[i].ar0 = (ar * i) / num_threads; args[i].ar1 = (ar * (i + 1)) / num_threads; args[i].bc0 = 0; args[i].bc1 = bc; } else { args[i].ar0 = 0; args[i].ar1 = ar; args[i].bc0 = (bc * i) / num_threads; args[i].bc1 = (bc * (i + 1)) / num_threads; } args[i].br = br; args[i].prec = prec; pthread_create(&threads[i], NULL, _arb_mat_mul_thread, &args[i]); } for (i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); } flint_free(threads); flint_free(args); } arb-2.22.1/arb_mat/ne.c000066400000000000000000000015061417376376500145420ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_ne(const arb_mat_t mat1, const arb_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 1; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (arb_ne(arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j))) return 1; return 0; } arb-2.22.1/arb_mat/neg.c000066400000000000000000000012251417376376500147070ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_neg(arb_mat_t dest, const arb_mat_t src) { slong i, j; for (i = 0; i < arb_mat_nrows(src); i++) for (j = 0; j < arb_mat_ncols(src); j++) arb_neg(arb_mat_entry(dest, i, j), arb_mat_entry(src, i, j)); } arb-2.22.1/arb_mat/one.c000066400000000000000000000012651417376376500147230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_one(arb_mat_t mat) { slong i, j; for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) if (i == j) arb_one(arb_mat_entry(mat, i, j)); else arb_zero(arb_mat_entry(mat, i, j)); } arb-2.22.1/arb_mat/ones.c000066400000000000000000000011631417376376500151030ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_ones(arb_mat_t mat) { slong R, C, i, j; R = arb_mat_nrows(mat); C = arb_mat_ncols(mat); for (i = 0; i < R; i++) for (j = 0; j < C; j++) arb_one(arb_mat_entry(mat, i, j)); } arb-2.22.1/arb_mat/overlaps.c000066400000000000000000000015071417376376500157740ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_overlaps(const arb_mat_t mat1, const arb_mat_t mat2) { slong i, j; if ((arb_mat_nrows(mat1) != arb_mat_nrows(mat2)) || (arb_mat_ncols(mat1) != arb_mat_ncols(mat2))) return 0; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) if (!arb_overlaps(arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j))) return 0; return 1; } arb-2.22.1/arb_mat/pascal.c000066400000000000000000000041371417376376500154060ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_pascal(arb_mat_t mat, int triangular, slong prec) { slong R, C, i, j; R = arb_mat_nrows(mat); C = arb_mat_ncols(mat); if (R == 0 || C == 0) return; if (triangular == 1) { for (i = 1; i < R; i++) for (j = 0; j < i && j < C; j++) arb_zero(arb_mat_entry(mat, i, j)); for (j = 0; j < C; j++) arb_one(arb_mat_entry(mat, 0, j)); for (i = 1; i < R && i < C; i++) arb_one(arb_mat_entry(mat, i, i)); for (i = 1; i < R; i++) for (j = i + 1; j < C; j++) arb_add(arb_mat_entry(mat, i, j), arb_mat_entry(mat, i, j - 1), arb_mat_entry(mat, i - 1, j - 1), prec); } else if (triangular == -1) { for (i = 0; i < R; i++) for (j = i + 1; j < C; j++) arb_zero(arb_mat_entry(mat, i, j)); for (i = 0; i < R; i++) arb_one(arb_mat_entry(mat, i, 0)); for (i = 1; i < R && i < C; i++) arb_one(arb_mat_entry(mat, i, i)); for (i = 2; i < R; i++) for (j = 1; j < i && j < C; j++) arb_add(arb_mat_entry(mat, i, j), arb_mat_entry(mat, i - 1, j - 1), arb_mat_entry(mat, i - 1, j), prec); } else { for (j = 0; j < C; j++) arb_one(arb_mat_entry(mat, 0, j)); for (i = 1; i < R; i++) arb_one(arb_mat_entry(mat, i, 0)); for (i = 1; i < R; i++) for (j = 1; j < C; j++) arb_add(arb_mat_entry(mat, i, j), arb_mat_entry(mat, i, j - 1), arb_mat_entry(mat, i - 1, j), prec); } } arb-2.22.1/arb_mat/pow_ui.c000066400000000000000000000026331417376376500154440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_pow_ui(arb_mat_t B, const arb_mat_t A, ulong exp, slong prec) { slong d = arb_mat_nrows(A); if (exp <= 2 || d <= 1) { if (exp == 0 || d == 0) { arb_mat_one(B); } else if (d == 1) { arb_pow_ui(arb_mat_entry(B, 0, 0), arb_mat_entry(A, 0, 0), exp, prec); } else if (exp == 1) { arb_mat_set(B, A); } else if (exp == 2) { arb_mat_sqr(B, A, prec); } } else { arb_mat_t T, U; slong i; arb_mat_init(T, d, d); arb_mat_set(T, A); arb_mat_init(U, d, d); for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--) { arb_mat_sqr(U, T, prec); if (exp & (WORD(1) << i)) arb_mat_mul(T, U, A, prec); else arb_mat_swap(T, U); } arb_mat_swap(B, T); arb_mat_clear(T); arb_mat_clear(U); } } arb-2.22.1/arb_mat/randtest.c000066400000000000000000000023201417376376500157570ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_randtest(arb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits) { slong i, j, density; density = n_randint(state, 100); if (n_randint(state, 2)) for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) if (n_randint(state, 100) < density) arb_randtest(arb_mat_entry(mat, i, j), state, prec, mag_bits); else arb_zero(arb_mat_entry(mat, i, j)); else for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) if (n_randint(state, 100) < density) arb_randtest_precise(arb_mat_entry(mat, i, j), state, prec, mag_bits); else arb_zero(arb_mat_entry(mat, i, j)); } arb-2.22.1/arb_mat/set.c000066400000000000000000000013411417376376500147300ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_set(arb_mat_t dest, const arb_mat_t src) { slong i, j; if (dest != src && arb_mat_ncols(src) != 0) { for (i = 0; i < arb_mat_nrows(src); i++) for (j = 0; j < arb_mat_ncols(src); j++) arb_set(arb_mat_entry(dest, i, j), arb_mat_entry(src, i, j)); } } arb-2.22.1/arb_mat/set_fmpq_mat.c000066400000000000000000000013671417376376500166240ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_set_fmpq_mat(arb_mat_t dest, const fmpq_mat_t src, slong prec) { slong i, j; if (arb_mat_ncols(dest) != 0) { for (i = 0; i < arb_mat_nrows(dest); i++) for (j = 0; j < arb_mat_ncols(dest); j++) arb_set_fmpq(arb_mat_entry(dest, i, j), fmpq_mat_entry(src, i, j), prec); } } arb-2.22.1/arb_mat/set_fmpz_mat.c000066400000000000000000000013451417376376500166310ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_set_fmpz_mat(arb_mat_t dest, const fmpz_mat_t src) { slong i, j; if (arb_mat_ncols(dest) != 0) { for (i = 0; i < arb_mat_nrows(dest); i++) for (j = 0; j < arb_mat_ncols(dest); j++) arb_set_fmpz(arb_mat_entry(dest, i, j), fmpz_mat_entry(src, i, j)); } } arb-2.22.1/arb_mat/set_round_fmpz_mat.c000066400000000000000000000013771417376376500200450ustar00rootroot00000000000000/* Copyright (C) 2012 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_set_round_fmpz_mat(arb_mat_t dest, const fmpz_mat_t src, slong prec) { slong i, j; if (arb_mat_ncols(dest) != 0) { for (i = 0; i < arb_mat_nrows(dest); i++) for (j = 0; j < arb_mat_ncols(dest); j++) arb_set_round_fmpz(arb_mat_entry(dest, i, j), fmpz_mat_entry(src, i, j), prec); } } arb-2.22.1/arb_mat/solve.c000066400000000000000000000012311417376376500152630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { slong n = arb_mat_nrows(A); if (n <= 4 || prec > 10.0 * n) return arb_mat_solve_lu(X, A, B, prec); else return arb_mat_solve_precond(X, A, B, prec); } arb-2.22.1/arb_mat/solve_cho_precomp.c000066400000000000000000000026131417376376500176460ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_solve_cho_precomp(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, slong prec) { slong i, j, c, n, m; n = arb_mat_nrows(X); m = arb_mat_ncols(X); arb_mat_set(X, B); for (c = 0; c < m; c++) { /* solve Ly = b */ for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(L, i, j), arb_mat_entry(X, j, c), prec); } arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c), arb_mat_entry(L, i, i), prec); } /* solve Ux = y */ for (i = n - 1; i >= 0; i--) { for (j = i + 1; j < n; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(L, j, i), arb_mat_entry(X, j, c), prec); } arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c), arb_mat_entry(L, i, i), prec); } } } arb-2.22.1/arb_mat/solve_ldl_precomp.c000066400000000000000000000026001417376376500176440ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_solve_ldl_precomp(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, slong prec) { slong i, j, c, n, m; n = arb_mat_nrows(X); m = arb_mat_ncols(X); arb_mat_set(X, B); for (c = 0; c < m; c++) { /* solve Lz = b */ for (i = 1; i < n; i++) { for (j = 0; j < i; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(L, i, j), arb_mat_entry(X, j, c), prec); } } /* solve Dy = z */ for (i = 0; i < n; i++) { arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c), arb_mat_entry(L, i, i), prec); } /* solve Ux = y */ for (i = n - 1; i >= 0; i--) { for (j = i + 1; j < n; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(L, j, i), arb_mat_entry(X, j, c), prec); } } } } arb-2.22.1/arb_mat/solve_lu.c000066400000000000000000000015651417376376500157750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_solve_lu(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { int result; slong n, m, *perm; arb_mat_t LU; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; perm = _perm_init(n); arb_mat_init(LU, n, n); result = arb_mat_lu(perm, LU, A, prec); if (result) arb_mat_solve_lu_precomp(X, perm, LU, B, prec); arb_mat_clear(LU); _perm_clear(perm); return result; } arb-2.22.1/arb_mat/solve_lu_precomp.c000066400000000000000000000040211417376376500175100ustar00rootroot00000000000000/* Copyright (C) 2012,2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_solve_lu_precomp(arb_mat_t X, const slong * perm, const arb_mat_t A, const arb_mat_t B, slong prec) { slong i, j, c, n, m; n = arb_mat_nrows(X); m = arb_mat_ncols(X); if (X == B) { arb_ptr tmp = flint_malloc(sizeof(arb_struct) * n); for (c = 0; c < m; c++) { for (i = 0; i < n; i++) tmp[i] = B->rows[perm[i]][c]; for (i = 0; i < n; i++) X->rows[i][c] = tmp[i]; } flint_free(tmp); } else { for (c = 0; c < m; c++) { for (i = 0; i < n; i++) { arb_set(arb_mat_entry(X, i, c), arb_mat_entry(B, perm[i], c)); } } } /* solve_tril and solve_triu have some overhead */ if (n >= 4) { arb_mat_solve_tril(X, A, X, 1, prec); arb_mat_solve_triu(X, A, X, 0, prec); return; } for (c = 0; c < m; c++) { /* solve Ly = b */ for (i = 1; i < n; i++) { for (j = 0; j < i; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(A, i, j), arb_mat_entry(X, j, c), prec); } } /* solve Ux = y */ for (i = n - 1; i >= 0; i--) { for (j = i + 1; j < n; j++) { arb_submul(arb_mat_entry(X, i, c), arb_mat_entry(A, i, j), arb_mat_entry(X, j, c), prec); } arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c), arb_mat_entry(A, i, i), prec); } } } arb-2.22.1/arb_mat/solve_preapprox.c000066400000000000000000000045531417376376500173750ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" /* * Helper function to compute a lower bound of 1 - inf_norm(I - A*B). * Returns zero when this lower bound is zero. */ int _mag_err_complement(mag_t m, const arb_mat_t A, const arb_mat_t B, slong prec) { slong n; arb_mat_t I, E; mag_t err; n = arb_mat_nrows(A); arb_mat_init(I, n, n); arb_mat_one(I); arb_mat_init(E, n, n); arb_mat_mul(E, A, B, prec); arb_mat_sub(E, I, E, prec); mag_init(err); arb_mat_bound_inf_norm(err, E); mag_one(m); mag_sub_lower(m, m, err); mag_clear(err); arb_mat_clear(I); arb_mat_clear(E); return !mag_is_zero(m); } int arb_mat_solve_preapprox(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, const arb_mat_t R, const arb_mat_t T, slong prec) { int result; slong m, n; mag_t d; result = 0; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; /* Use Theorem 10.2 of Rump in Acta Numerica 2010 */ mag_init(d); if (_mag_err_complement(d, R, A, prec)) { arb_mat_t C; arb_mat_init(C, n, m); arb_mat_mul(C, A, T, prec); arb_mat_sub(C, C, B, prec); arb_mat_mul(C, R, C, prec); /* Each column gets its own error bound. */ arb_mat_set(X, T); { slong i, j; mag_t e, err; mag_init(e); mag_init(err); for (j = 0; j < m; j++) { mag_zero(err); for (i = 0; i < n; i++) { arb_get_mag(e, arb_mat_entry(C, i, j)); mag_max(err, err, e); } mag_div(err, err, d); for (i = 0; i < n; i++) { arb_add_error_mag(arb_mat_entry(X, i, j), err); } } mag_clear(e); mag_clear(err); } arb_mat_clear(C); result = 1; } mag_clear(d); return result; } arb-2.22.1/arb_mat/solve_precond.c000066400000000000000000000060621417376376500170040ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int _arb_mat_solve_c(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { int result; slong m, n; arb_mat_t I, R; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; arb_mat_init(I, n, n); arb_mat_init(R, n, n); arb_mat_one(I); result = arb_mat_approx_solve(R, A, I, prec); if (result) { arb_mat_t RA, RB; arb_mat_init(RA, n, n); arb_mat_init(RB, n, m); arb_mat_mul(RA, R, A, prec); arb_mat_mul(RB, R, B, prec); result = arb_mat_solve_lu(X, RA, RB, prec); arb_mat_clear(RA); arb_mat_clear(RB); } arb_mat_clear(I); arb_mat_clear(R); return result; } int _arb_mat_solve_d(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { int result; slong m, n; arb_mat_t I, R; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; arb_mat_init(I, n, n); arb_mat_init(R, n, n); arb_mat_one(I); result = arb_mat_approx_solve(R, A, I, prec); if (result) { arb_mat_t RA, RB, E; mag_t d; arb_mat_init(RA, n, n); arb_mat_init(RB, n, m); arb_mat_init(E, n, n); mag_init(d); arb_mat_mul(RA, R, A, prec); arb_mat_mul(RB, R, B, prec); arb_mat_sub(E, I, RA, prec); arb_mat_bound_inf_norm(d, E); if (mag_cmp_2exp_si(d, 0) < 0) { slong i, j; mag_t e, err; mag_init(e); mag_init(err); mag_geom_series(d, d, 1); arb_mat_set(X, RB); for (j = 0; j < m; j++) { mag_zero(err); for (i = 0; i < n; i++) { arb_get_mag(e, arb_mat_entry(RB, i, j)); mag_max(err, err, e); } mag_mul(err, err, d); for (i = 0; i < n; i++) { arb_add_error_mag(arb_mat_entry(X, i, j), err); } } mag_clear(e); mag_clear(err); } else { result = arb_mat_solve_lu(X, RA, RB, prec); } arb_mat_clear(RA); arb_mat_clear(RB); arb_mat_clear(E); mag_clear(d); } arb_mat_clear(I); arb_mat_clear(R); return result; } int arb_mat_solve_precond(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { slong n = arb_mat_nrows(A); slong m = arb_mat_ncols(B); if (m < 0.1 * n + 1) return _arb_mat_solve_c(X, A, B, prec); else return _arb_mat_solve_d(X, A, B, prec); } arb-2.22.1/arb_mat/solve_tril.c000066400000000000000000000052271417376376500163260ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_solve_tril_classical(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) { slong i, j, n, m; arb_ptr tmp; arb_t s; n = L->r; m = B->c; arb_init(s); tmp = flint_malloc(sizeof(arb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *arb_mat_entry(X, j, i); for (j = 0; j < n; j++) { arb_dot(s, arb_mat_entry(B, j, i), 1, L->rows[j], 1, tmp, 1, j, prec); if (!unit) arb_div(tmp + j, s, arb_mat_entry(L, j, j), prec); else arb_swap(tmp + j, s); } for (j = 0; j < n; j++) *arb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); arb_clear(s); } void arb_mat_solve_tril_recursive(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) { arb_mat_t LA, LC, LD, XX, XY, BX, BY, T; slong r, n, m; n = L->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A 0]^ [X] == [A^ 0 ] [X] == [A^ X] [C D] [Y] == [-D^ C A^ D^] [Y] == [D^ (Y - C A^ X)] */ arb_mat_window_init(LA, L, 0, 0, r, r); arb_mat_window_init(LC, L, r, 0, n, r); arb_mat_window_init(LD, L, r, r, n, n); arb_mat_window_init(BX, B, 0, 0, r, m); arb_mat_window_init(BY, B, r, 0, n, m); arb_mat_window_init(XX, X, 0, 0, r, m); arb_mat_window_init(XY, X, r, 0, n, m); arb_mat_solve_tril(XX, LA, BX, unit, prec); /* arb_mat_submul(XY, BY, LC, XX); */ arb_mat_init(T, LC->r, BX->c); arb_mat_mul(T, LC, XX, prec); arb_mat_sub(XY, BY, T, prec); arb_mat_clear(T); arb_mat_solve_tril(XY, LD, XY, unit, prec); arb_mat_window_clear(LA); arb_mat_window_clear(LC); arb_mat_window_clear(LD); arb_mat_window_clear(BX); arb_mat_window_clear(BY); arb_mat_window_clear(XX); arb_mat_window_clear(XY); } void arb_mat_solve_tril(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) arb_mat_solve_tril_classical(X, L, B, unit, prec); else arb_mat_solve_tril_recursive(X, L, B, unit, prec); } arb-2.22.1/arb_mat/solve_triu.c000066400000000000000000000052071417376376500163350ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_solve_triu_classical(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) { slong i, j, n, m; arb_ptr tmp; arb_t s; n = U->r; m = B->c; arb_init(s); tmp = flint_malloc(sizeof(arb_struct) * n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) tmp[j] = *arb_mat_entry(X, j, i); for (j = n - 1; j >= 0; j--) { arb_dot(s, arb_mat_entry(B, j, i), 1, U->rows[j] + j + 1, 1, tmp + j + 1, 1, n - j - 1, prec); if (!unit) arb_div(tmp + j, s, arb_mat_entry(U, j, j), prec); else arb_swap(tmp + j, s); } for (j = 0; j < n; j++) *arb_mat_entry(X, j, i) = tmp[j]; } flint_free(tmp); arb_clear(s); } void arb_mat_solve_triu_recursive(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) { arb_mat_t UA, UB, UD, XX, XY, BX, BY, T; slong r, n, m; n = U->r; m = B->c; r = n / 2; if (n == 0 || m == 0) return; /* Denoting inv(M) by M^, we have: [A B]^ [X] == [A^ (X - B D^ Y)] [0 D] [Y] == [ D^ Y ] */ arb_mat_window_init(UA, U, 0, 0, r, r); arb_mat_window_init(UB, U, 0, r, r, n); arb_mat_window_init(UD, U, r, r, n, n); arb_mat_window_init(BX, B, 0, 0, r, m); arb_mat_window_init(BY, B, r, 0, n, m); arb_mat_window_init(XX, X, 0, 0, r, m); arb_mat_window_init(XY, X, r, 0, n, m); arb_mat_solve_triu(XY, UD, BY, unit, prec); /* arb_mat_submul(XX, BX, UB, XY); */ arb_mat_init(T, UB->r, XY->c); arb_mat_mul(T, UB, XY, prec); arb_mat_sub(XX, BX, T, prec); arb_mat_clear(T); arb_mat_solve_triu(XX, UA, XX, unit, prec); arb_mat_window_clear(UA); arb_mat_window_clear(UB); arb_mat_window_clear(UD); arb_mat_window_clear(BX); arb_mat_window_clear(BY); arb_mat_window_clear(XX); arb_mat_window_clear(XY); } void arb_mat_solve_triu(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) { if (B->r < 40 || B->c < 40) arb_mat_solve_triu_classical(X, U, B, unit, prec); else arb_mat_solve_triu_recursive(X, U, B, unit, prec); } arb-2.22.1/arb_mat/spd_inv.c000066400000000000000000000026351417376376500156060ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_spd_inv(arb_mat_t X, const arb_mat_t A, slong prec) { slong n; arb_mat_t L; int result; if (!arb_mat_is_square(A)) { flint_printf("arb_mat_spd_inv: a square matrix is required\n"); flint_abort(); } if (arb_mat_nrows(X) != arb_mat_nrows(A) || arb_mat_ncols(X) != arb_mat_ncols(A)) { flint_printf("arb_mat_spd_inv: incompatible dimensions\n"); flint_abort(); } if (arb_mat_is_empty(A)) return 1; n = arb_mat_nrows(A); if (n == 1) { if (arb_is_positive(arb_mat_entry(A, 0, 0))) { arb_inv(arb_mat_entry(X, 0, 0), arb_mat_entry(A, 0, 0), prec); return 1; } else { return 0; } } arb_mat_init(L, n, n); arb_mat_set(L, A); if (_arb_mat_cholesky_banachiewicz(L, prec)) { arb_mat_inv_cho_precomp(X, L, prec); result = 1; } else { result = 0; } arb_mat_clear(L); return result; } arb-2.22.1/arb_mat/spd_solve.c000066400000000000000000000014511417376376500161350ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int arb_mat_spd_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { int result; slong n, m; arb_mat_t L; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; arb_mat_init(L, n, n); result = arb_mat_cho(L, A, prec); if (result) arb_mat_solve_cho_precomp(X, L, B, prec); arb_mat_clear(L); return result; } arb-2.22.1/arb_mat/sqr.c000066400000000000000000000007561417376376500147530ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_sqr(arb_mat_t B, const arb_mat_t A, slong prec) { arb_mat_mul(B, A, A, prec); } arb-2.22.1/arb_mat/sqr_classical.c000066400000000000000000000052031417376376500167610ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_sqr_classical(arb_mat_t B, const arb_mat_t A, slong prec) { slong n, i, j, k; arb_t p, s; n = arb_mat_nrows(A); if (arb_mat_ncols(A) != n || arb_mat_nrows(B) != n || arb_mat_ncols(B) != n) { flint_printf("arb_mat_sqr: incompatible dimensions\n"); flint_abort(); } if (n == 0) return; if (n == 1) { arb_mul(arb_mat_entry(B, 0, 0), arb_mat_entry(A, 0, 0), arb_mat_entry(A, 0, 0), prec); return; } if (A == B) { arb_mat_t T; arb_mat_init(T, n, n); arb_mat_sqr_classical(T, A, prec); arb_mat_swap(T, B); arb_mat_clear(T); return; } arb_init(p); arb_init(s); /* contribution of diagonal of A to diagonal of B */ for (i = 0; i < n; i++) { arb_mul(arb_mat_entry(B, i, i), arb_mat_entry(A, i, i), arb_mat_entry(A, i, i), prec); } for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { /* contribution of off-diagonal of A to diagonal of B */ arb_mul(p, arb_mat_entry(A, i, j), arb_mat_entry(A, j, i), prec); arb_add(arb_mat_entry(B, i, i), arb_mat_entry(B, i, i), p, prec); arb_add(arb_mat_entry(B, j, j), arb_mat_entry(B, j, j), p, prec); /* contribution of diagonal of A to off-diagonal of B */ arb_add(s, arb_mat_entry(A, i, i), arb_mat_entry(A, j, j), prec); arb_mul(arb_mat_entry(B, i, j), arb_mat_entry(A, i, j), s, prec); arb_mul(arb_mat_entry(B, j, i), arb_mat_entry(A, j, i), s, prec); } } /* contribution of off-diagonal of A to off-diagonal of B */ if (n > 2) { for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { for (k = 0; k < n; k++) { if (i != j && j != k && k != i) { arb_addmul(arb_mat_entry(B, i, j), arb_mat_entry(A, i, k), arb_mat_entry(A, k, j), prec); } } } } } arb_clear(p); arb_clear(s); } arb-2.22.1/arb_mat/stirling.c000066400000000000000000000052651417376376500160010ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _stirling_number_1u_vec_next(arb_ptr row, arb_srcptr prev, slong n, slong klen, slong prec) { slong k; if (klen > n) arb_one(row + n); if (n != 0 && klen != 0) arb_zero(row); for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--) { arb_mul_ui(row + k, prev + k, n - 1, prec); arb_add(row + k, prev + k - 1, row + k, prec); } for (k = n + 1; k < klen; k++) arb_zero(row + k); } static void _stirling_number_1_vec_next(arb_ptr row, arb_srcptr prev, slong n, slong klen, slong prec) { slong k; if (klen > n) arb_one(row + n); if (n != 0 && klen != 0) arb_zero(row); for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--) { arb_mul_ui(row + k, prev + k, n - 1, prec); arb_sub(row + k, prev + k - 1, row + k, prec); } for (k = n + 1; k < klen; k++) arb_zero(row + k); } static void _stirling_number_2_vec_next(arb_ptr row, arb_srcptr prev, slong n, slong klen, slong prec) { slong k; if (klen > n) arb_one(row + n); if (n != 0 && klen != 0) arb_zero(row); for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--) { arb_mul_ui(row + k, prev + k, k, prec); arb_add(row + k, prev + k - 1, row + k, prec); } for (k = n + 1; k < klen; k++) arb_zero(row + k); } static void _stirling_matrix_1u(arb_mat_t mat, slong prec) { slong n; if (arb_mat_is_empty(mat)) return; for (n = 0; n < mat->r; n++) _stirling_number_1u_vec_next(mat->rows[n], mat->rows[n - (n != 0)], n, mat->c, prec); } static void _stirling_matrix_1(arb_mat_t mat, slong prec) { slong n; if (arb_mat_is_empty(mat)) return; for (n = 0; n < mat->r; n++) _stirling_number_1_vec_next(mat->rows[n], mat->rows[n - (n != 0)], n, mat->c, prec); } static void _stirling_matrix_2(arb_mat_t mat, slong prec) { slong n; if (arb_mat_is_empty(mat)) return; for (n = 0; n < mat->r; n++) _stirling_number_2_vec_next(mat->rows[n], mat->rows[n - (n != 0)], n, mat->c, prec); } void arb_mat_stirling(arb_mat_t mat, int kind, slong prec) { if (kind == 0) _stirling_matrix_1u(mat, prec); else if (kind == 1) _stirling_matrix_1(mat, prec); else _stirling_matrix_2(mat, prec); } arb-2.22.1/arb_mat/sub.c000066400000000000000000000013621417376376500147310ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_sub(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec) { slong i, j; for (i = 0; i < arb_mat_nrows(mat1); i++) for (j = 0; j < arb_mat_ncols(mat1); j++) arb_sub(arb_mat_entry(res, i, j), arb_mat_entry(mat1, i, j), arb_mat_entry(mat2, i, j), prec); } arb-2.22.1/arb_mat/test/000077500000000000000000000000001417376376500147515ustar00rootroot00000000000000arb-2.22.1/arb_mat/test/t-addmul_rad_mag_fast.c000066400000000000000000000073661417376376500213270ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" #define BLOCK_SIZE 32 static void fallback(arb_mat_t C, mag_srcptr A, mag_srcptr B, slong ar, slong ac, slong bc) { slong i, j, k, ii, jj, kk; for (ii = 0; ii < ar; ii += BLOCK_SIZE) { for (jj = 0; jj < bc; jj += BLOCK_SIZE) { for (kk = 0; kk < ac; kk += BLOCK_SIZE) { for (i = ii; i < FLINT_MIN(ii + BLOCK_SIZE, ar); i++) { for (j = jj; j < FLINT_MIN(jj + BLOCK_SIZE, bc); j++) { for (k = kk; k < FLINT_MIN(kk + BLOCK_SIZE, ac); k++) { mag_fast_addmul(arb_radref(arb_mat_entry(C, i, j)), A + i * ac + k, B + j * ac + k); } } } } } } } int main() { slong iter; flint_rand_t state; flint_printf("addmul_rad_mag_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_mat_t C, D; slong m, n, p, density, i, j, off; mag_ptr A, B; mag_t lo, hi; m = n_randint(state, 40); n = n_randint(state, 40); p = n_randint(state, 40); A = _mag_vec_init(m * n); B = _mag_vec_init(p * n); arb_mat_init(C, m, p); arb_mat_init(D, m, p); mag_init(lo); mag_init(hi); density = 1 + n_randint(state, 100); off = n_randint(state, 10000); for (i = 0; i < m * n; i++) { if (n_randint(state, 100) < density) { mag_randtest(A + i, state, 8 + n_randint(state, 10)); mag_mul_2exp_si(A + i, A + i, off); } } off = n_randint(state, 10000); for (i = 0; i < p * n; i++) { if (n_randint(state, 100) < density) { mag_randtest(B + i, state, 8 + n_randint(state, 10)); mag_mul_2exp_si(B + i, B + i, off); } } fallback(C, A, B, m, n, p); _arb_mat_addmul_rad_mag_fast(D, A, B, m, n, p); for (i = 0; i < m; i++) { for (j = 0; j < p; j++) { mag_set_d(lo, 0.9999); mag_set_d(hi, 1.0001); mag_mul(lo, lo, arb_radref(arb_mat_entry(C, i, j))); mag_mul(hi, hi, arb_radref(arb_mat_entry(C, i, j))); if (mag_cmp(arb_radref(arb_mat_entry(D, i, j)), lo) < 0 || mag_cmp(arb_radref(arb_mat_entry(D, i, j)), hi) > 0) { flint_printf("FAIL\n"); flint_printf("m = %wd, n = %wd, p = %wd\n", m, n, p); flint_printf("i = %wd, j = %wd\n", i, j); mag_printd(arb_radref(arb_mat_entry(C, i, j)), 10); flint_printf("\n"); mag_printd(arb_radref(arb_mat_entry(D, i, j)), 10); flint_printf("\n"); flint_abort(); } } } _mag_vec_clear(A, m * n); _mag_vec_clear(B, p * n); arb_mat_clear(C); arb_mat_clear(D); mag_clear(lo); mag_clear(hi); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-charpoly.c000066400000000000000000000037641417376376500172110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main(void) { slong iter; flint_rand_t state; flint_printf("charpoly...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_mat_t A, B, C, D; arb_poly_t f, g; slong m, n; m = n_randint(state, 8); n = m; arb_mat_init(A, m, n); arb_mat_init(B, m, n); arb_mat_init(C, m, m); arb_mat_init(D, n, n); arb_poly_init(f); arb_poly_init(g); arb_mat_randtest(A, state, 1 + n_randint(state, 1000), 10); arb_mat_randtest(B, state, 1 + n_randint(state, 1000), 10); arb_mat_mul(C, A, B, 2 + n_randint(state, 1000)); arb_mat_mul(D, B, A, 2 + n_randint(state, 1000)); arb_mat_charpoly(f, C, 2 + n_randint(state, 1000)); arb_mat_charpoly(g, D, 2 + n_randint(state, 1000)); if (!arb_poly_overlaps(f, g)) { flint_printf("FAIL: charpoly(AB) != charpoly(BA).\n"); flint_printf("Matrix A:\n"), arb_mat_printd(A, 15), flint_printf("\n"); flint_printf("Matrix B:\n"), arb_mat_printd(B, 15), flint_printf("\n"); flint_printf("cp(AB) = "), arb_poly_printd(f, 15), flint_printf("\n"); flint_printf("cp(BA) = "), arb_poly_printd(g, 15), flint_printf("\n"); flint_abort(); } arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(C); arb_mat_clear(D); arb_poly_clear(f); arb_poly_clear(g); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/arb_mat/test/t-cho.c000066400000000000000000000136321417376376500161340ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } int fmpq_mat_is_invertible(const fmpq_mat_t A) { int r; fmpq_t t; fmpq_init(t); fmpq_mat_det(t, A); r = !fmpq_is_zero(t); fmpq_clear(t); return r; } int main() { slong iter; flint_rand_t state; flint_printf("cho...."); fflush(stdout); flint_randinit(state); /* check special matrices */ { slong n; for (n = 1; n < 10; n++) { slong lprec; arb_mat_t L, A; arb_mat_init(L, n, n); arb_mat_init(A, n, n); for (lprec = 2; lprec < 10; lprec++) { int result; slong prec; prec = 1 << lprec; /* zero */ arb_mat_zero(A); result = arb_mat_cho(L, A, prec); if (result) { flint_printf("FAIL (zero):\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } /* negative identity */ arb_mat_one(A); arb_mat_neg(A, A); result = arb_mat_cho(L, A, prec); if (result) { flint_printf("FAIL (negative identity):\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } /* identity */ arb_mat_one(A); result = arb_mat_cho(L, A, prec); if (!result || !arb_mat_equal(L, A)) { flint_printf("FAIL (identity):\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } } arb_mat_clear(L); arb_mat_clear(A); } } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; arb_mat_t A, L, U, T; slong n, qbits, prec; int q_invertible, r_invertible; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 202); fmpq_mat_init(Q, n, n); arb_mat_init(A, n, n); arb_mat_init(L, n, n); arb_mat_init(U, n, n); arb_mat_init(T, n, n); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); q_invertible = fmpq_mat_is_invertible(Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_cho(L, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_cho(L, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } arb_mat_transpose(U, L); arb_mat_mul(T, L, U, prec); if (!arb_mat_contains_fmpq_mat(T, Q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); flint_printf("U = \n"); arb_mat_printd(U, 15); flint_printf("\n\n"); flint_printf("L*U = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); arb_mat_clear(A); arb_mat_clear(L); arb_mat_clear(U); arb_mat_clear(T); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-companion.c000066400000000000000000000033241417376376500173430ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main(void) { slong iter; flint_rand_t state; flint_printf("companion...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_mat_t A; arb_poly_t f, g; slong n, prec; arb_poly_init(f); arb_poly_init(g); do { arb_poly_randtest(f, state, 1 + n_randint(state, 8), 1 + n_randint(state, 1000), 10); } while (arb_poly_degree(f) < 0); n = arb_poly_degree(f); prec = 2 + n_randint(state, 200); arb_mat_init(A, n, n); arb_mat_randtest(A, state, 1 + n_randint(state, 1000), 10); arb_mat_companion(A, f, prec); arb_mat_charpoly(g, A, prec); arb_poly_scalar_mul(g, g, arb_poly_get_coeff_ptr(f, n), prec); if (!arb_poly_contains(g, f)) { flint_printf("FAIL\n"); flint_printf("A:\n"), arb_mat_printd(A, 15), flint_printf("\n"); flint_printf("f:\n"), arb_poly_printd(f, 15), flint_printf("\n"); flint_printf("g:\n"), arb_poly_printd(g, 15), flint_printf("\n"); flint_abort(); } arb_mat_clear(A); arb_poly_clear(f); arb_poly_clear(g); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/arb_mat/test/t-dct.c000066400000000000000000000032551417376376500161350ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("dct...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_mat_t A, Ainv, AT; slong n, prec; n = n_randint(state, 10); prec = 53 + n_randint(state, 30); arb_mat_init(A, n, n); arb_mat_init(Ainv, n, n); arb_mat_init(AT, n, n); arb_mat_randtest(A, state, 100, 10); arb_mat_dct(A, 0, prec); if (!arb_mat_inv(Ainv, A, prec)) { flint_printf("FAIL: small DCT matrix (n = %wd) not invertible\n", n); flint_abort(); } arb_mat_transpose(AT, A); if (!arb_mat_overlaps(AT, Ainv)) { flint_printf("FAIL: overlap (n = %wd)\n", n); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_printf("AT = \n"); arb_mat_printd(AT, 15); flint_printf("\n\n"); flint_abort(); } arb_mat_clear(A); arb_mat_clear(Ainv); arb_mat_clear(AT); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-det.c000066400000000000000000000075511417376376500161420ustar00rootroot00000000000000/* Copyright (C) 2012, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("det...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; fmpq_t Qdet; arb_mat_t A; arb_t Adet; slong n, qbits, prec; n = n_randint(state, 12); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_init(Qdet); arb_mat_init(A, n, n); arb_init(Adet); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_det(Qdet, Q); arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_det(Adet, A, prec); if (!arb_contains_fmpq(Adet, Qdet)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qdet = \n"); fmpq_print(Qdet); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Adet = \n"); arb_printd(Adet, 15); flint_printf("\n\n"); flint_printf("Adet = \n"); arb_print(Adet); flint_printf("\n\n"); flint_abort(); } fmpq_mat_clear(Q); fmpq_clear(Qdet); arb_mat_clear(A); arb_clear(Adet); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_mat_t A, B, AB; arb_t detA, detB, detAB, t; slong n, prec1, prec2, prec3; n = n_randint(state, 12); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); prec3 = 2 + n_randint(state, 200); arb_mat_init(A, n, n); arb_mat_init(B, n, n); arb_mat_init(AB, n, n); arb_init(detA); arb_init(detB); arb_init(detAB); arb_init(t); arb_mat_randtest(A, state, 2 + n_randint(state, 200), 2 + n_randint(state, 100)); arb_mat_randtest(B, state, 2 + n_randint(state, 200), 2 + n_randint(state, 100)); arb_mat_mul(AB, A, B, prec3); arb_mat_det(detA, A, prec1); arb_mat_det(detB, B, prec2); arb_mat_det(detAB, AB, prec3); arb_mul(t, detA, detB, 1000); if (!arb_overlaps(t, detAB)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("n = %wd, prec1 = %wd, prec2 = %wd, prec3 = %wd\n", n, prec1, prec2, prec3); flint_printf("\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("detA = \n"); arb_printn(detA, 50, 0); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("detB = \n"); arb_printn(detB, 50, 0); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(AB, 15); flint_printf("\n\n"); flint_printf("detAB = \n"); arb_printn(detAB, 50, 0); flint_printf("\n\n"); flint_printf("detA*detB = \n"); arb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(AB); arb_clear(detA); arb_clear(detB); arb_clear(detAB); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-det_precond.c000066400000000000000000000077311417376376500176540ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("det_precond...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_mat_t A, B, AB; arb_t detA, detB, detAB, detAb, detBb, detABb, t; slong n, prec1, prec2, prec3; n = n_randint(state, 12); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); prec3 = 2 + n_randint(state, 200); arb_mat_init(A, n, n); arb_mat_init(B, n, n); arb_mat_init(AB, n, n); arb_init(detA); arb_init(detB); arb_init(detAB); arb_init(t); arb_init(detAb); arb_init(detBb); arb_init(detABb); arb_mat_randtest(A, state, 2 + n_randint(state, 200), 2 + n_randint(state, 20)); arb_mat_randtest(B, state, 2 + n_randint(state, 200), 2 + n_randint(state, 20)); arb_mat_mul(AB, A, B, prec3); arb_mat_det_precond(detA, A, prec1); arb_mat_det_precond(detB, B, prec2); arb_mat_det_precond(detAB, AB, prec3); arb_mul(t, detA, detB, 1000); if (!arb_overlaps(t, detAB)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("n = %wd, prec1 = %wd, prec2 = %wd, prec3 = %wd\n", n, prec1, prec2, prec3); flint_printf("\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("detA = \n"); arb_printn(detA, 50, 0); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("detB = \n"); arb_printn(detB, 50, 0); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(AB, 15); flint_printf("\n\n"); flint_printf("detAB = \n"); arb_printn(detAB, 50, 0); flint_printf("\n\n"); flint_printf("detA*detB = \n"); arb_printn(t, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_mat_det_lu(detAb, A, prec1); arb_mat_det_lu(detBb, B, prec2); arb_mat_det_lu(detABb, AB, prec3); if (!arb_overlaps(detA, detAb) || !arb_overlaps(detB, detBb) || !arb_overlaps(detAB, detABb)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("n = %wd, prec1 = %wd, prec2 = %wd, prec3 = %wd\n", n, prec1, prec2, prec3); flint_printf("\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("detA = \n"); arb_printn(detA, 50, 0); flint_printf("\n\n"); flint_printf("detAb = \n"); arb_printn(detAb, 50, 0); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("detB = \n"); arb_printn(detB, 50, 0); flint_printf("\n\n"); flint_printf("detBb = \n"); arb_printn(detBb, 50, 0); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(AB, 15); flint_printf("\n\n"); flint_printf("detAB = \n"); arb_printn(detAB, 50, 0); flint_printf("\n\n"); flint_printf("detABb = \n"); arb_printn(detABb, 50, 0); flint_printf("\n\n"); flint_abort(); } arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(AB); arb_clear(detA); arb_clear(detB); arb_clear(detAB); arb_clear(t); arb_clear(detAb); arb_clear(detBb); arb_clear(detABb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-exp.c000066400000000000000000000057351417376376500161640ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_for_exp(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong i, j; slong d, l, u; d = n_randint(state, 5); l = n_randint(state, 5); u = n_randint(state, 5); fmpq_mat_zero(mat); for (i = 0; i < fmpq_mat_nrows(mat); i++) { for (j = 0; j < fmpq_mat_ncols(mat); j++) { if ((i == j && d) || (i < j && u) || (i > j && l)) { fmpq_randtest(fmpq_mat_entry(mat, i, j), state, bits); } } } } int main() { slong iter; flint_rand_t state; flint_printf("exp...."); fflush(stdout); flint_randinit(state); /* check exp(A)*exp(c*A) = exp((1+c)*A) */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_mat_t A, E, F, EF, G; fmpq_mat_t Q; arb_t c, d; slong n, qbits, prec; n = n_randint(state, 5); qbits = 2 + n_randint(state, 300); prec = 2 + n_randint(state, 300); arb_init(c); arb_init(d); fmpq_mat_init(Q, n, n); arb_mat_init(A, n, n); arb_mat_init(E, n, n); arb_mat_init(F, n, n); arb_mat_init(EF, n, n); arb_mat_init(G, n, n); _fmpq_mat_randtest_for_exp(Q, state, qbits); arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_exp(E, A, prec); arb_randtest(c, state, prec, 10); arb_mat_scalar_mul_arb(F, A, c, prec); arb_mat_exp(F, F, prec); arb_add_ui(d, c, 1, prec); arb_mat_scalar_mul_arb(G, A, d, prec); arb_mat_exp(G, G, prec); arb_mat_mul(EF, E, F, prec); if (!arb_mat_overlaps(EF, G)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("c = \n"); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("E = \n"); arb_mat_printd(E, 15); flint_printf("\n\n"); flint_printf("F = \n"); arb_mat_printd(F, 15); flint_printf("\n\n"); flint_printf("E*F = \n"); arb_mat_printd(EF, 15); flint_printf("\n\n"); flint_printf("G = \n"); arb_mat_printd(G, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(c); arb_clear(d); fmpq_mat_clear(Q); arb_mat_clear(A); arb_mat_clear(E); arb_mat_clear(F); arb_mat_clear(EF); arb_mat_clear(G); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-exp_taylor_sum.c000066400000000000000000000044531417376376500204360ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_sum_taylor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { arb_mat_t A, S1, S2, S3; fmpz_t f; slong n, N, prec1, prec2; n = n_randint(state, 5); N = n_randint(state, 40); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); arb_mat_init(A, n, n); arb_mat_init(S1, n, n); arb_mat_init(S2, n, n); arb_mat_init(S3, n, n); fmpz_init(f); arb_mat_randtest(A, state, prec1, 10); arb_mat_randtest(S1, state, prec1, 10); arb_mat_randtest(S2, state, prec1, 10); arb_mat_exp_taylor_sum(S1, A, N, prec1); arb_mat_exp_taylor_sum(S2, A, N + 1, prec2); arb_mat_pow_ui(S3, A, N, prec2); fmpz_fac_ui(f, N); arb_mat_scalar_div_fmpz(S3, S3, f, prec2); arb_mat_add(S3, S3, S1, prec2); if (!arb_mat_overlaps(S2, S3)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, N = %wd\n", n, N); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("S1 = \n"); arb_mat_printd(S1, 15); flint_printf("\n\n"); flint_printf("S2 = \n"); arb_mat_printd(S2, 15); flint_printf("\n\n"); flint_printf("S3 = \n"); arb_mat_printd(S3, 15); flint_printf("\n\n"); flint_abort(); } arb_mat_exp_taylor_sum(A, A, N, prec1); if (!arb_mat_overlaps(A, S1)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_mat_clear(A); arb_mat_clear(S1); arb_mat_clear(S2); arb_mat_clear(S3); fmpz_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-frobenius_norm.c000066400000000000000000000141071417376376500204100ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" static void _fmpq_mat_sum_of_squares(fmpq_t res, const fmpq_mat_t Q) { slong i, j; fmpq_zero(res); for (i = 0; i < fmpq_mat_nrows(Q); i++) { for (j = 0; j < fmpq_mat_ncols(Q); j++) { fmpq_addmul(res, fmpq_mat_entry(Q, i, j), fmpq_mat_entry(Q, i, j)); } } } int main() { slong iter; flint_rand_t state; flint_printf("frobenius_norm...."); fflush(stdout); flint_randinit(state); /* compare to the exact rational norm */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; fmpq_t q; arb_mat_t A; slong n, qbits, prec; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_init(q); arb_mat_init(A, n, n); fmpq_mat_randtest(Q, state, qbits); _fmpq_mat_sum_of_squares(q, Q); arb_mat_set_fmpq_mat(A, Q, prec); /* check that the arb interval contains the exact value */ { arb_t a; arb_init(a); arb_mat_frobenius_norm(a, A, prec); arb_mul(a, a, a, prec); if (!arb_contains_fmpq(a, q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("frobenius_norm(Q)^2 = \n"); fmpq_print(q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A)^2 = \n"); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A)^2 = \n"); arb_print(a); flint_printf("\n\n"); flint_abort(); } arb_clear(a); } /* check that the upper bound is not less than the exact value */ { mag_t b; fmpq_t y; mag_init(b); fmpq_init(y); arb_mat_bound_frobenius_norm(b, A); mag_mul(b, b, b); mag_get_fmpq(y, b); if (fmpq_cmp(q, y) > 0) { flint_printf("FAIL (bound, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("frobenius_norm(Q)^2 = \n"); fmpq_print(q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A)^2 = \n"); mag_printd(b, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A)^2 = \n"); mag_print(b); flint_printf("\n\n"); flint_abort(); } mag_clear(b); fmpq_clear(y); } fmpq_mat_clear(Q); fmpq_clear(q); arb_mat_clear(A); } /* check trace(A^T A) = frobenius_norm(A)^2 */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, prec; arb_mat_t A, AT, ATA; arb_t t; prec = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); arb_mat_init(A, m, n); arb_mat_init(AT, n, m); arb_mat_init(ATA, n, n); arb_init(t); arb_mat_randtest(A, state, 2 + n_randint(state, 100), 10); arb_mat_transpose(AT, A); arb_mat_mul(ATA, AT, A, prec); arb_mat_trace(t, ATA, prec); arb_sqrt(t, t, prec); /* check the norm bound */ { mag_t low, frobenius; mag_init(low); arb_get_mag_lower(low, t); mag_init(frobenius); arb_mat_bound_frobenius_norm(frobenius, A); if (mag_cmp(low, frobenius) > 0) { flint_printf("FAIL (bound)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("lower(sqrt(trace(A^T A))) = \n"); mag_printd(low, 15); flint_printf("\n\n"); flint_printf("bound_frobenius_norm(A) = \n"); mag_printd(frobenius, 15); flint_printf("\n\n"); flint_abort(); } mag_clear(low); mag_clear(frobenius); } /* check the norm interval */ { arb_t frobenius; arb_init(frobenius); arb_mat_frobenius_norm(frobenius, A, prec); if (!arb_overlaps(t, frobenius)) { flint_printf("FAIL (overlap)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("sqrt(trace(A^T A)) = \n"); arb_printd(t, 15); flint_printf("\n\n"); flint_printf("frobenius_norm(A) = \n"); arb_printd(frobenius, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(frobenius); } arb_mat_clear(A); arb_mat_clear(AT); arb_mat_clear(ATA); arb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-inv.c000066400000000000000000000074441417376376500161630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("inv...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, Qinv; arb_mat_t A, Ainv; slong n, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(Qinv, n, n); arb_mat_init(A, n, n); arb_mat_init(Ainv, n, n); fmpq_mat_randtest(Q, state, qbits); q_invertible = fmpq_mat_inv(Qinv, Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_inv(Ainv, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_inv(Ainv, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(Ainv, Qinv)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qinv = \n"); fmpq_mat_print(Qinv); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = arb_mat_inv(A, A, prec); if (!arb_mat_equal(A, Ainv) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(Qinv); arb_mat_clear(A); arb_mat_clear(Ainv); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-inv_cho_precomp.c000066400000000000000000000111771417376376500205370ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } static int _spd_inv(arb_mat_t X, const arb_mat_t A, slong prec) { slong n; arb_mat_t L; int result; n = arb_mat_nrows(A); arb_mat_init(L, n, n); arb_mat_set(L, A); if (_arb_mat_cholesky_banachiewicz(L, prec)) { arb_mat_inv_cho_precomp(X, L, prec); result = 1; } else { result = 0; } arb_mat_clear(L); return result; } int main() { slong iter; flint_rand_t state; flint_printf("inv_cho_precomp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, Qinv; arb_mat_t A, Ainv; slong n, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(Qinv, n, n); arb_mat_init(A, n, n); arb_mat_init(Ainv, n, n); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); q_invertible = fmpq_mat_inv(Qinv, Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = _spd_inv(Ainv, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = _spd_inv(Ainv, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(Ainv, Qinv)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qinv = \n"); fmpq_mat_print(Qinv); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = _spd_inv(A, A, prec); if (!arb_mat_equal(A, Ainv) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(Qinv); arb_mat_clear(A); arb_mat_clear(Ainv); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-inv_ldl_precomp.c000066400000000000000000000111651417376376500205360ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } static int _spd_inv(arb_mat_t X, const arb_mat_t A, slong prec) { slong n; arb_mat_t L; int result; n = arb_mat_nrows(A); arb_mat_init(L, n, n); arb_mat_set(L, A); if (_arb_mat_ldl_inplace(L, prec)) { arb_mat_inv_ldl_precomp(X, L, prec); result = 1; } else { result = 0; } arb_mat_clear(L); return result; } int main() { slong iter; flint_rand_t state; flint_printf("inv_ldl_precomp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, Qinv; arb_mat_t A, Ainv; slong n, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(Qinv, n, n); arb_mat_init(A, n, n); arb_mat_init(Ainv, n, n); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); q_invertible = fmpq_mat_inv(Qinv, Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = _spd_inv(Ainv, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = _spd_inv(Ainv, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(Ainv, Qinv)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qinv = \n"); fmpq_mat_print(Qinv); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = _spd_inv(A, A, prec); if (!arb_mat_equal(A, Ainv) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(Qinv); arb_mat_clear(A); arb_mat_clear(Ainv); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-ldl.c000066400000000000000000000146231417376376500161370ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } int fmpq_mat_is_invertible(const fmpq_mat_t A) { int r; fmpq_t t; fmpq_init(t); fmpq_mat_det(t, A); r = !fmpq_is_zero(t); fmpq_clear(t); return r; } int main() { slong iter; flint_rand_t state; flint_printf("ldl...."); fflush(stdout); flint_randinit(state); /* check special matrices */ { slong n; for (n = 1; n < 10; n++) { slong lprec; arb_mat_t L, A; arb_mat_init(L, n, n); arb_mat_init(A, n, n); for (lprec = 2; lprec < 10; lprec++) { int result; slong prec; prec = 1 << lprec; /* zero */ arb_mat_zero(A); result = arb_mat_ldl(L, A, prec); if (result) { flint_printf("FAIL (zero):\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } /* negative identity */ arb_mat_one(A); arb_mat_neg(A, A); result = arb_mat_ldl(L, A, prec); if (result) { flint_printf("FAIL (negative identity):\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } /* identity */ arb_mat_one(A); result = arb_mat_ldl(L, A, prec); if (!result || !arb_mat_equal(L, A)) { flint_printf("FAIL (identity):\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } } arb_mat_clear(L); arb_mat_clear(A); } } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; arb_mat_t A, L, D, U, T; slong n, qbits, prec; int q_invertible, r_invertible; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 202); fmpq_mat_init(Q, n, n); arb_mat_init(A, n, n); arb_mat_init(L, n, n); arb_mat_init(D, n, n); arb_mat_init(U, n, n); arb_mat_init(T, n, n); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); q_invertible = fmpq_mat_is_invertible(Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_ldl(L, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_ldl(L, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } /* multiply out the decomposition */ { slong i; arb_mat_zero(D); arb_mat_transpose(U, L); for (i = 0; i < n; i++) { arb_set(arb_mat_entry(D, i, i), arb_mat_entry(L, i, i)); arb_one(arb_mat_entry(L, i, i)); arb_one(arb_mat_entry(U, i, i)); } arb_mat_mul(T, L, D, prec); arb_mat_mul(T, T, U, prec); } if (!arb_mat_contains_fmpq_mat(T, Q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); flint_printf("U = \n"); arb_mat_printd(U, 15); flint_printf("\n\n"); flint_printf("L*U = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); arb_mat_clear(A); arb_mat_clear(L); arb_mat_clear(D); arb_mat_clear(U); arb_mat_clear(T); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-lu.c000066400000000000000000000103611417376376500157770ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int fmpq_mat_is_invertible(const fmpq_mat_t A) { int r; fmpq_t t; fmpq_init(t); fmpq_mat_det(t, A); r = !fmpq_is_zero(t); fmpq_clear(t); return r; } int main() { slong iter; flint_rand_t state; flint_printf("lu...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; arb_mat_t A, LU, P, L, U, T; slong i, j, n, qbits, prec, *perm; int q_invertible, r_invertible; n = n_randint(state, 10); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 202); fmpq_mat_init(Q, n, n); arb_mat_init(A, n, n); arb_mat_init(LU, n, n); arb_mat_init(P, n, n); arb_mat_init(L, n, n); arb_mat_init(U, n, n); arb_mat_init(T, n, n); perm = _perm_init(n); fmpq_mat_randtest(Q, state, qbits); q_invertible = fmpq_mat_is_invertible(Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_lu(perm, LU, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); arb_mat_printd(LU, 15); flint_printf("\n\n"); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_lu(perm, LU, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_abort(); } prec *= 2; } } arb_mat_one(L); for (i = 0; i < n; i++) for (j = 0; j < i; j++) arb_set(arb_mat_entry(L, i, j), arb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) for (j = i; j < n; j++) arb_set(arb_mat_entry(U, i, j), arb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) arb_one(arb_mat_entry(P, perm[i], i)); arb_mat_mul(T, P, L, prec); arb_mat_mul(T, T, U, prec); if (!arb_mat_contains_fmpq_mat(T, Q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); arb_mat_printd(LU, 15); flint_printf("\n\n"); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); flint_printf("U = \n"); arb_mat_printd(U, 15); flint_printf("\n\n"); flint_printf("P*L*U = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); arb_mat_clear(A); arb_mat_clear(LU); arb_mat_clear(P); arb_mat_clear(L); arb_mat_clear(U); arb_mat_clear(T); _perm_clear(perm); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-lu_recursive.c000066400000000000000000000122101417376376500200610ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int fmpq_mat_is_invertible(const fmpq_mat_t A) { int r; fmpq_t t; fmpq_init(t); fmpq_mat_det(t, A); r = !fmpq_is_zero(t); fmpq_clear(t); return r; } int main() { slong iter; flint_rand_t state; flint_printf("lu_recursive...."); fflush(stdout); flint_randinit(state); /* Dummy test with rectangular matrices. Rectangular matrices are not actually supported (the output may be bogus), but the algorithm should at least not crash. */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, prec; slong *perm; arb_mat_t A, LU; n = n_randint(state, 20); m = n_randint(state, 20); prec = 2 + n_randint(state, 200); arb_mat_init(A, n, m); arb_mat_init(LU, n, m); perm = _perm_init(n); arb_mat_randtest(A, state, prec, 10); if (n_randint(state, 2)) { arb_mat_lu_recursive(perm, LU, A, prec); } else { arb_mat_set(LU, A); arb_mat_lu_recursive(perm, LU, LU, prec); } arb_mat_clear(A); arb_mat_clear(LU); _perm_clear(perm); } for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; arb_mat_t A, LU, P, L, U, T; slong i, j, n, qbits, prec, *perm; int q_invertible, r_invertible; n = n_randint(state, 20); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 202); fmpq_mat_init(Q, n, n); arb_mat_init(A, n, n); arb_mat_init(LU, n, n); arb_mat_init(P, n, n); arb_mat_init(L, n, n); arb_mat_init(U, n, n); arb_mat_init(T, n, n); perm = _perm_init(n); fmpq_mat_randtest(Q, state, qbits); q_invertible = fmpq_mat_is_invertible(Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_lu_recursive(perm, LU, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); arb_mat_printd(LU, 15); flint_printf("\n\n"); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_lu_recursive(perm, LU, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_abort(); } prec *= 2; } } arb_mat_one(L); for (i = 0; i < n; i++) for (j = 0; j < i; j++) arb_set(arb_mat_entry(L, i, j), arb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) for (j = i; j < n; j++) arb_set(arb_mat_entry(U, i, j), arb_mat_entry(LU, i, j)); for (i = 0; i < n; i++) arb_one(arb_mat_entry(P, perm[i], i)); arb_mat_mul(T, P, L, prec); arb_mat_mul(T, T, U, prec); if (!arb_mat_contains_fmpq_mat(T, Q)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("LU = \n"); arb_mat_printd(LU, 15); flint_printf("\n\n"); flint_printf("L = \n"); arb_mat_printd(L, 15); flint_printf("\n\n"); flint_printf("U = \n"); arb_mat_printd(U, 15); flint_printf("\n\n"); flint_printf("P*L*U = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); arb_mat_clear(A); arb_mat_clear(LU); arb_mat_clear(P); arb_mat_clear(L); arb_mat_clear(U); arb_mat_clear(T); _perm_clear(perm); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-mul.c000066400000000000000000000063061417376376500161600ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, k, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; arb_mat_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); k = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, n, k); fmpq_mat_init(C, m, k); arb_mat_init(a, m, n); arb_mat_init(b, n, k); arb_mat_init(c, m, k); arb_mat_init(d, m, k); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); fmpq_mat_mul(C, A, B); arb_mat_set_fmpq_mat(a, A, rbits1); arb_mat_set_fmpq_mat(b, B, rbits2); arb_mat_mul(c, a, b, rbits3); if (!arb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd, k = %wd, bits3 = %wd\n", m, n, k, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (arb_mat_nrows(a) == arb_mat_nrows(c) && arb_mat_ncols(a) == arb_mat_ncols(c)) { arb_mat_set(d, a); arb_mat_mul(d, d, b, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (arb_mat_nrows(b) == arb_mat_nrows(c) && arb_mat_ncols(b) == arb_mat_ncols(c)) { arb_mat_set(d, b); arb_mat_mul(d, a, d, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(c); arb_mat_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-mul_block.c000066400000000000000000000113131417376376500173240ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" ARB_DLL extern slong arb_mat_mul_block_min_block_size; int main() { slong iter; flint_rand_t state; flint_printf("mul_block...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { slong m, n, k, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; arb_mat_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); arb_mat_mul_block_min_block_size = n_randint(state, 10); m = n_randint(state, 10); n = n_randint(state, 10); k = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, n, k); fmpq_mat_init(C, m, k); arb_mat_init(a, m, n); arb_mat_init(b, n, k); arb_mat_init(c, m, k); arb_mat_init(d, m, k); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); fmpq_mat_mul(C, A, B); arb_mat_set_fmpq_mat(a, A, rbits1); arb_mat_set_fmpq_mat(b, B, rbits2); arb_mat_mul_block(c, a, b, rbits3); if (!arb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd, k = %wd, bits3 = %wd\n", m, n, k, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (arb_mat_nrows(a) == arb_mat_nrows(c) && arb_mat_ncols(a) == arb_mat_ncols(c)) { arb_mat_set(d, a); arb_mat_mul_block(d, d, b, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (arb_mat_nrows(b) == arb_mat_nrows(c) && arb_mat_ncols(b) == arb_mat_ncols(c)) { arb_mat_set(d, b); arb_mat_mul_block(d, a, d, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(c); arb_mat_clear(d); } for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_mat_t A, B, C, D; slong m, n, p, bits1, bits2, exp1, exp2, prec1, prec2; m = n_randint(state, 40); n = n_randint(state, 40); p = n_randint(state, 40); arb_mat_mul_block_min_block_size = n_randint(state, 10); if (n_randint(state, 4) == 0) { exp1 = 4 + n_randint(state, FLINT_BITS); exp2 = 4 + n_randint(state, FLINT_BITS); } else { exp1 = exp2 = 20; } bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); prec1 = 2 + n_randint(state, 200); prec2 = 2 + n_randint(state, 200); arb_mat_init(A, m, n); arb_mat_init(B, n, p); arb_mat_init(C, m, p); arb_mat_init(D, m, p); arb_mat_randtest(A, state, bits1, exp1); arb_mat_randtest(B, state, bits2, exp2); arb_mat_randtest(C, state, bits2, exp2); arb_mat_mul_block(C, A, B, prec1); arb_mat_mul_classical(D, A, B, prec2); if (!arb_mat_overlaps(C, D)) { flint_printf("FAIL\n"); flint_printf("m = %wd, n = %wd, p = %wd\n", m, n, p); flint_abort(); } arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(C); arb_mat_clear(D); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-mul_entrywise.c000066400000000000000000000071311417376376500202660ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_mul_entrywise(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B) { slong i, j; for (i = 0; i < fmpq_mat_nrows(A); i++) { for (j = 0; j < fmpq_mat_ncols(A); j++) { fmpq_mul(fmpq_mat_entry(C, i, j), fmpq_mat_entry(A, i, j), fmpq_mat_entry(B, i, j)); } } } int main() { slong iter; flint_rand_t state; flint_printf("mul_entrywise...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; arb_mat_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, m, n); fmpq_mat_init(C, m, n); arb_mat_init(a, m, n); arb_mat_init(b, m, n); arb_mat_init(c, m, n); arb_mat_init(d, m, n); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); _fmpq_mat_mul_entrywise(C, A, B); arb_mat_set_fmpq_mat(a, A, rbits1); arb_mat_set_fmpq_mat(b, B, rbits2); arb_mat_mul_entrywise(c, a, b, rbits3); if (!arb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd, bits3 = %wd\n", m, n, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (arb_mat_nrows(a) == arb_mat_nrows(c) && arb_mat_ncols(a) == arb_mat_ncols(c)) { arb_mat_set(d, a); arb_mat_mul_entrywise(d, d, b, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (arb_mat_nrows(b) == arb_mat_nrows(c) && arb_mat_ncols(b) == arb_mat_ncols(c)) { arb_mat_set(d, b); arb_mat_mul_entrywise(d, a, d, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(c); arb_mat_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-mul_threaded.c000066400000000000000000000065321417376376500200210ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_threaded...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, k, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_mat_t A, B, C; arb_mat_t a, b, c, d; flint_set_num_threads(1 + n_randint(state, 5)); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); k = n_randint(state, 10); fmpq_mat_init(A, m, n); fmpq_mat_init(B, n, k); fmpq_mat_init(C, m, k); arb_mat_init(a, m, n); arb_mat_init(b, n, k); arb_mat_init(c, m, k); arb_mat_init(d, m, k); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_randtest(B, state, qbits2); fmpq_mat_mul(C, A, B); arb_mat_set_fmpq_mat(a, A, rbits1); arb_mat_set_fmpq_mat(b, B, rbits2); arb_mat_mul_threaded(c, a, b, rbits3); if (!arb_mat_contains_fmpq_mat(c, C)) { flint_printf("FAIL\n\n"); flint_printf("threads = %d, m = %wd, n = %wd, k = %wd, bits3 = %wd\n", flint_get_num_threads(), m, n, k, rbits3); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_mat_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing with a */ if (arb_mat_nrows(a) == arb_mat_nrows(c) && arb_mat_ncols(a) == arb_mat_ncols(c)) { arb_mat_set(d, a); arb_mat_mul_threaded(d, d, b, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } /* test aliasing with b */ if (arb_mat_nrows(b) == arb_mat_nrows(c) && arb_mat_ncols(b) == arb_mat_ncols(c)) { arb_mat_set(d, b); arb_mat_mul_threaded(d, a, d, rbits3); if (!arb_mat_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpq_mat_clear(A); fmpq_mat_clear(B); fmpq_mat_clear(C); arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(c); arb_mat_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-pascal.c000066400000000000000000000042661417376376500166310ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("pascal...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_mat_t A; fmpz_t t; slong n, m, i, j, prec; n = n_randint(state, 10); m = n_randint(state, 10); prec = 2 + n_randint(state, 200); fmpz_init(t); arb_mat_init(A, n, m); arb_mat_randtest(A, state, 100, 10); arb_mat_pascal(A, 0, prec); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { fmpz_bin_uiui(t, i + j, i); if (!arb_contains_fmpz(arb_mat_entry(A, i, j), t)) { flint_printf("FAIL: containment (0)\n"); flint_abort(); } } } arb_mat_pascal(A, 1, prec); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { fmpz_bin_uiui(t, j, i); if (!arb_contains_fmpz(arb_mat_entry(A, i, j), t)) { flint_printf("FAIL: containment (1)\n"); flint_abort(); } } } arb_mat_pascal(A, -1, prec); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { fmpz_bin_uiui(t, i, j); if (!arb_contains_fmpz(arb_mat_entry(A, i, j), t)) { flint_printf("FAIL: containment (-1)\n"); flint_abort(); } } } arb_mat_clear(A); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve.c000066400000000000000000000110321417376376500165030ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; arb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); m = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); arb_mat_init(A, n, n); arb_mat_init(X, n, m); arb_mat_init(B, n, m); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_solve(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_set_fmpq_mat(B, QB, prec); r_invertible = arb_mat_solve(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = arb_mat_solve(B, A, B, prec); if (!arb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve_cho_precomp.c000066400000000000000000000126401417376376500210670ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } int _spd_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { slong n, m; int result; arb_mat_t L; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; n = arb_mat_nrows(A); arb_mat_init(L, n, n); result = arb_mat_cho(L, A, prec); if (result) { arb_mat_solve_cho_precomp(X, L, B, prec); } arb_mat_clear(L); return result; } int main() { slong iter; flint_rand_t state; flint_printf("solve_cho_precomp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; arb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); m = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); arb_mat_init(A, n, n); arb_mat_init(X, n, m); arb_mat_init(B, n, m); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = _spd_solve(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_set_fmpq_mat(B, QB, prec); r_invertible = _spd_solve(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = _spd_solve(B, A, B, prec); if (!arb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve_ldl_precomp.c000066400000000000000000000126401417376376500210710ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } int _spd_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) { slong n, m; int result; arb_mat_t L; n = arb_mat_nrows(A); m = arb_mat_ncols(X); if (n == 0 || m == 0) return 1; n = arb_mat_nrows(A); arb_mat_init(L, n, n); result = arb_mat_ldl(L, A, prec); if (result) { arb_mat_solve_ldl_precomp(X, L, B, prec); } arb_mat_clear(L); return result; } int main() { slong iter; flint_rand_t state; flint_printf("solve_ldl_precomp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; arb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); m = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); arb_mat_init(A, n, n); arb_mat_init(X, n, m); arb_mat_init(B, n, m); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = _spd_solve(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_set_fmpq_mat(B, QB, prec); r_invertible = _spd_solve(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = _spd_solve(B, A, B, prec); if (!arb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve_lu.c000066400000000000000000000113261417376376500172110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_lu...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; arb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; if (n_randint(state, 50) == 0) { n = n_randint(state, 20); m = n_randint(state, 20); } else { n = n_randint(state, 8); m = n_randint(state, 8); } qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); arb_mat_init(A, n, n); arb_mat_init(X, n, m); arb_mat_init(B, n, m); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_solve_lu(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_set_fmpq_mat(B, QB, prec); r_invertible = arb_mat_solve_lu(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = arb_mat_solve_lu(B, A, B, prec); if (!arb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve_preapprox.c000066400000000000000000000205071417376376500206120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mul_si_frac(fmpq_t res, const fmpq_t x, slong p, slong q) { fmpq_t r; fmpq_init(r); fmpq_set_si(r, p, q); fmpq_mul(res, x, r); fmpq_clear(r); } void _fmpq_max(fmpq_t p, const fmpq_t q, const fmpq_t r) { if (fmpq_cmp(q, r) < 0) fmpq_set(p, r); else fmpq_set(p, q); } void _fmpq_mat_scalar_mul_fmpq(fmpq_mat_t res, const fmpq_mat_t mat, const fmpq_t x) { slong i, j; for (i = 0; i < mat->r; i++) for (j = 0; j < mat->c; j++) fmpq_mul(fmpq_mat_entry(res, i, j), fmpq_mat_entry(mat, i, j), x); } void _fmpq_mat_inf_norm(fmpq_t res, const fmpq_mat_t mat) { fmpq_t s, q; slong i, j; fmpq_init(s); fmpq_init(q); fmpq_zero(res); for (i = 0; i < mat->r; i++) { fmpq_zero(s); for (j = 0; j < mat->c; j++) { fmpq_abs(q, fmpq_mat_entry(mat, i, j)); fmpq_add(s, s, q); } _fmpq_max(res, res, s); } fmpq_clear(s); fmpq_clear(q); } int main() { slong iter; flint_rand_t state; flint_printf("solve_preapprox...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpq_mat_t QA, QB, QR, QT, QE, QX; arb_mat_t A, B, R, T, X; slong n, m, qbits, prec; int q_invertible, r_approximable, r_approximable2; n = n_randint(state, 8); m = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(QA, n, n); fmpq_mat_init(QB, n, m); fmpq_mat_init(QR, n, n); fmpq_mat_init(QT, n, m); fmpq_mat_init(QE, n, n); fmpq_mat_init(QX, n, m); arb_mat_init(A, n, n); arb_mat_init(B, n, m); arb_mat_init(R, n, n); arb_mat_init(T, n, m); arb_mat_init(X, n, m); /* Sample a square matrix QE with inf-norm less than 1. */ { fmpq_t m; fmpq_init(m); fmpq_mat_randtest(QE, state, qbits); _fmpq_mat_inf_norm(m, QE); if (!fmpq_is_zero(m)) { slong p, q; q = 64; p = n_randint(state, q); fmpq_inv(m, m); _fmpq_mul_si_frac(m, m, p, q); _fmpq_mat_scalar_mul_fmpq(QE, QE, m); } fmpq_clear(m); } /* Sample an unrestricted square matrix QR. */ fmpq_mat_randtest(QR, state, qbits); /* Construct QA := inv(QR)(I - QE), so that I - QR*QA = QE */ fmpq_mat_one(QA); fmpq_mat_sub(QA, QA, QE); q_invertible = fmpq_mat_solve_fraction_free(QA, QR, QA); /* Sample unrestricted matrices QB and QT. */ fmpq_mat_randtest(QB, state, qbits); fmpq_mat_randtest(QT, state, qbits); arb_mat_set_fmpq_mat(A, QA, prec); arb_mat_set_fmpq_mat(B, QB, prec); arb_mat_set_fmpq_mat(R, QR, prec); arb_mat_set_fmpq_mat(T, QT, prec); if (q_invertible) { /* Construct QX := inv(QA)QB */ fmpq_mat_solve_fraction_free(QX, QA, QB); r_approximable = arb_mat_solve_preapprox(X, A, B, R, T, prec); if (r_approximable) { if (!arb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("QA = \n"); fmpq_mat_print(QA); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QR = \n"); fmpq_mat_print(QR); flint_printf("\n\n"); flint_printf("QT = \n"); fmpq_mat_print(QT); flint_printf("\n\n"); flint_printf("QE = \n"); fmpq_mat_print(QE); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("R = \n"); arb_mat_printd(R, 15); flint_printf("\n\n"); flint_printf("T = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } /* test aliasing */ if (n_randint(state, 2)) { r_approximable2 = arb_mat_solve_preapprox(T, A, B, R, T, prec); if ((r_approximable != r_approximable2) || (r_approximable && !arb_mat_equal(X, T))) { flint_printf("FAIL (aliasing (X, T))\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("T = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } else { r_approximable2 = arb_mat_solve_preapprox(B, A, B, R, T, prec); if ((r_approximable != r_approximable2) || (r_approximable && !arb_mat_equal(X, B))) { flint_printf("FAIL (aliasing (X, B))\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("T = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } } /* test a simplified case where A = R = I */ { arb_mat_one(A); arb_mat_one(R); fmpq_mat_randtest(QB, state, qbits); fmpq_mat_randtest(QT, state, qbits); arb_mat_set_fmpq_mat(B, QB, prec); arb_mat_set_fmpq_mat(T, QT, prec); arb_mat_zero(X); r_approximable = arb_mat_solve_preapprox(X, A, B, R, T, prec); if (!r_approximable || !arb_mat_contains(X, B)) { flint_printf("FAIL (special values A = R = I))\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("T = \n"); arb_mat_printd(T, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); } } /* test a simplified case where A = R = I and T = B */ { arb_mat_one(A); arb_mat_one(R); fmpq_mat_randtest(QB, state, qbits); arb_mat_set_fmpq_mat(B, QB, prec); arb_mat_set(T, B); arb_mat_zero(X); r_approximable = arb_mat_solve_preapprox(X, A, B, R, T, prec); if (!r_approximable || !arb_mat_contains(X, B)) { flint_printf("FAIL (special values A = R = I, T = B))\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); } } fmpq_mat_clear(QA); fmpq_mat_clear(QB); fmpq_mat_clear(QR); fmpq_mat_clear(QT); fmpq_mat_clear(QE); fmpq_mat_clear(QX); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(R); arb_mat_clear(T); arb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve_precond.c000066400000000000000000000110601417376376500202160ustar00rootroot00000000000000/* Copyright (C) 2018 arbguest This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_precond...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; arb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); m = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); arb_mat_init(A, n, n); arb_mat_init(X, n, m); arb_mat_init(B, n, m); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_solve_precond(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_set_fmpq_mat(B, QB, prec); r_invertible = arb_mat_solve_precond(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = arb_mat_solve_precond(B, A, B, prec); if (!arb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve_tril.c000066400000000000000000000061361417376376500175460ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_tril...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_mat_t A, X, B, Y; slong rows, cols, prec, i, j; int unit; prec = 2 + n_randint(state, 200); if (n_randint(state, 10) == 0) { rows = n_randint(state, 60); cols = n_randint(state, 60); } else { rows = n_randint(state, 10); cols = n_randint(state, 10); } unit = n_randint(state, 2); arb_mat_init(A, rows, rows); arb_mat_init(B, rows, cols); arb_mat_init(X, rows, cols); arb_mat_init(Y, rows, cols); arb_mat_randtest(A, state, prec, 10); arb_mat_randtest(X, state, prec, 10); arb_mat_randtest(Y, state, prec, 10); for (i = 0; i < rows; i++) { if (unit) arb_one(arb_mat_entry(A, i, i)); else arb_set_ui(arb_mat_entry(A, i, i), 1 + n_randint(state, 100)); for (j = i + 1; j < rows; j++) arb_zero(arb_mat_entry(A, i, j)); } arb_mat_mul(B, A, X, prec); if (unit) /* check that diagonal entries are ignored */ { for (i = 0; i < rows; i++) arb_set_ui(arb_mat_entry(A, i, i), 1 + n_randint(state, 100)); } /* Check Y = A^(-1) * (A * X) = X */ arb_mat_solve_tril(Y, A, B, unit, prec); if (!arb_mat_overlaps(Y, X)) { flint_printf("FAIL\n"); flint_printf("A = \n"); arb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); arb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } /* Check aliasing */ arb_mat_solve_tril(B, A, B, unit, prec); if (!arb_mat_equal(B, Y)) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); arb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); arb_mat_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-solve_triu.c000066400000000000000000000061271417376376500175570ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("solve_triu...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { arb_mat_t A, X, B, Y; slong rows, cols, prec, i, j; int unit; prec = 2 + n_randint(state, 200); if (n_randint(state, 10) == 0) { rows = n_randint(state, 60); cols = n_randint(state, 60); } else { rows = n_randint(state, 10); cols = n_randint(state, 10); } unit = n_randint(state, 2); arb_mat_init(A, rows, rows); arb_mat_init(B, rows, cols); arb_mat_init(X, rows, cols); arb_mat_init(Y, rows, cols); arb_mat_randtest(A, state, prec, 10); arb_mat_randtest(X, state, prec, 10); arb_mat_randtest(Y, state, prec, 10); for (i = 0; i < rows; i++) { if (unit) arb_one(arb_mat_entry(A, i, i)); else arb_set_ui(arb_mat_entry(A, i, i), 1 + n_randint(state, 100)); for (j = 0; j < i; j++) arb_zero(arb_mat_entry(A, i, j)); } arb_mat_mul(B, A, X, prec); if (unit) /* check that diagonal entries are ignored */ { for (i = 0; i < rows; i++) arb_set_ui(arb_mat_entry(A, i, i), 1 + n_randint(state, 100)); } /* Check Y = A^(-1) * (A * X) = X */ arb_mat_solve_triu(Y, A, B, unit, prec); if (!arb_mat_overlaps(Y, X)) { flint_printf("FAIL\n"); flint_printf("A = \n"); arb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); arb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } /* Check aliasing */ arb_mat_solve_triu(B, A, B, unit, prec); if (!arb_mat_equal(B, Y)) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 10); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 10); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 10); flint_printf("\n\n"); flint_printf("Y = \n"); arb_mat_printd(Y, 10); flint_printf("\n\n"); flint_abort(); } arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); arb_mat_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-spd_inv.c000066400000000000000000000103721417376376500170230ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } int main() { slong iter; flint_rand_t state; flint_printf("spd_inv...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, Qinv; arb_mat_t A, Ainv; slong n, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(Qinv, n, n); arb_mat_init(A, n, n); arb_mat_init(Ainv, n, n); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); q_invertible = fmpq_mat_inv(Qinv, Q); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_spd_inv(Ainv, A, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_spd_inv(Ainv, A, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(Ainv, Qinv)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qinv = \n"); fmpq_mat_print(Qinv); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = arb_mat_spd_inv(A, A, prec); if (!arb_mat_equal(A, Ainv) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Ainv = \n"); arb_mat_printd(Ainv, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(Qinv); arb_mat_clear(A); arb_mat_clear(Ainv); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-spd_solve.c000066400000000000000000000117601417376376500173610ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void _fmpq_mat_randtest_positive_semidefinite(fmpq_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { slong n; fmpq_mat_t R, RT; if (!fmpq_mat_is_square(mat)) flint_abort(); /* assert */ n = fmpq_mat_nrows(mat); fmpq_mat_init(R, n, n); fmpq_mat_init(RT, n, n); fmpq_mat_randtest(R, state, bits); fmpq_mat_transpose(RT, R); fmpq_mat_mul(mat, R, RT); fmpq_mat_clear(R); fmpq_mat_clear(RT); } int main() { slong iter; flint_rand_t state; flint_printf("spd_solve...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q, QX, QB; arb_mat_t A, X, B; slong n, m, qbits, prec; int q_invertible, r_invertible, r_invertible2; n = n_randint(state, 8); m = n_randint(state, 8); qbits = 1 + n_randint(state, 30); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_mat_init(QX, n, m); fmpq_mat_init(QB, n, m); arb_mat_init(A, n, n); arb_mat_init(X, n, m); arb_mat_init(B, n, m); _fmpq_mat_randtest_positive_semidefinite(Q, state, qbits); fmpq_mat_randtest(QB, state, qbits); q_invertible = fmpq_mat_solve_fraction_free(QX, Q, QB); if (!q_invertible) { arb_mat_set_fmpq_mat(A, Q, prec); r_invertible = arb_mat_spd_solve(X, A, B, prec); if (r_invertible) { flint_printf("FAIL: matrix is singular over Q but not over R\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } } else { /* now this must converge */ while (1) { arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_set_fmpq_mat(B, QB, prec); r_invertible = arb_mat_spd_solve(X, A, B, prec); if (r_invertible) { break; } else { if (prec > 10000) { flint_printf("FAIL: failed to converge at 10000 bits\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_abort(); } prec *= 2; } } if (!arb_mat_contains_fmpq_mat(X, QX)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("QB = \n"); fmpq_mat_print(QB); flint_printf("\n\n"); flint_printf("QX = \n"); fmpq_mat_print(QX); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ r_invertible2 = arb_mat_spd_solve(B, A, B, prec); if (!arb_mat_equal(X, B) || r_invertible != r_invertible2) { flint_printf("FAIL (aliasing)\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("B = \n"); arb_mat_printd(B, 15); flint_printf("\n\n"); flint_printf("X = \n"); arb_mat_printd(X, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_mat_clear(Q); fmpq_mat_clear(QB); fmpq_mat_clear(QX); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(X); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-sqr.c000066400000000000000000000041451417376376500161670ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("sqr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong n, qbits1, rbits1, rbits2; fmpq_mat_t A, B; arb_mat_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = n_randint(state, 10); fmpq_mat_init(A, n, n); fmpq_mat_init(B, n, n); arb_mat_init(a, n, n); arb_mat_init(b, n, n); arb_mat_init(c, n, n); fmpq_mat_randtest(A, state, qbits1); fmpq_mat_mul(B, A, A); arb_mat_set_fmpq_mat(a, A, rbits1); arb_mat_sqr(b, a, rbits2); if (!arb_mat_contains_fmpq_mat(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_mat_printd(b, 15); flint_printf("\n\n"); flint_abort(); } /* test aliasing */ arb_mat_set(c, a); arb_mat_sqr(c, c, rbits2); if (!arb_mat_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_mat_clear(A); fmpq_mat_clear(B); arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-stirling.c000066400000000000000000000033271417376376500172160ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" #include "flint/arith.h" int main() { slong iter; flint_rand_t state; flint_printf("stirling...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100 * arb_test_multiplier(); iter++) { arb_mat_t A; fmpz_mat_t B; slong n, m, prec; n = n_randint(state, 10); m = n_randint(state, 10); prec = 2 + n_randint(state, 200); arb_mat_init(A, n, m); fmpz_mat_init(B, n, m); arb_mat_randtest(A, state, 100, 10); arb_mat_stirling(A, 0, prec); arith_stirling_matrix_1u(B); if (!arb_mat_contains_fmpz_mat(A, B)) { flint_printf("FAIL: containment (0)\n"); flint_abort(); } arb_mat_stirling(A, 1, prec); arith_stirling_matrix_1(B); if (!arb_mat_contains_fmpz_mat(A, B)) { flint_printf("FAIL: containment (1)\n"); flint_abort(); } arb_mat_stirling(A, 2, prec); arith_stirling_matrix_2(B); if (!arb_mat_contains_fmpz_mat(A, B)) { flint_printf("FAIL: containment (2)\n"); flint_abort(); } arb_mat_clear(A); fmpz_mat_clear(B); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-trace.c000066400000000000000000000072651417376376500164660ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("trace...."); fflush(stdout); flint_randinit(state); /* check that the arb trace contains the fmpq trace */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpq_mat_t Q; fmpq_t Qtrace; arb_mat_t A; arb_t Atrace; slong n, qbits, prec; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); fmpq_mat_init(Q, n, n); fmpq_init(Qtrace); arb_mat_init(A, n, n); arb_init(Atrace); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_trace(Qtrace, Q); arb_mat_set_fmpq_mat(A, Q, prec); arb_mat_trace(Atrace, A, prec); if (!arb_contains_fmpq(Atrace, Qtrace)) { flint_printf("FAIL (containment, iter = %wd)\n", iter); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("\n"); flint_printf("Q = \n"); fmpq_mat_print(Q); flint_printf("\n\n"); flint_printf("Qtrace = \n"); fmpq_print(Qtrace); flint_printf("\n\n"); flint_printf("A = \n"); arb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("Atrace = \n"); arb_printd(Atrace, 15); flint_printf("\n\n"); flint_printf("Atrace = \n"); arb_print(Atrace); flint_printf("\n\n"); flint_abort(); } fmpq_mat_clear(Q); fmpq_clear(Qtrace); arb_mat_clear(A); arb_clear(Atrace); } /* check trace(A*B) = trace(B*A) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, prec; arb_mat_t a, b, ab, ba; arb_t trab, trba; prec = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); arb_mat_init(a, m, n); arb_mat_init(b, n, m); arb_mat_init(ab, m, m); arb_mat_init(ba, n, n); arb_init(trab); arb_init(trba); arb_mat_randtest(a, state, 2 + n_randint(state, 100), 10); arb_mat_randtest(b, state, 2 + n_randint(state, 100), 10); arb_mat_mul(ab, a, b, prec); arb_mat_mul(ba, b, a, prec); arb_mat_trace(trab, ab, prec); arb_mat_trace(trba, ba, prec); if (!arb_overlaps(trab, trba)) { flint_printf("FAIL (overlap, iter = %wd)\n", iter); flint_printf("m = %wd, n = %wd, prec = %wd\n", m, n, prec); flint_printf("\n"); flint_printf("a = \n"); arb_mat_printd(a, 15); flint_printf("\n\n"); flint_printf("b = \n"); arb_mat_printd(b, 15); flint_printf("\n\n"); flint_printf("ab = \n"); arb_mat_printd(ab, 15); flint_printf("\n\n"); flint_printf("ba = \n"); arb_mat_printd(ba, 15); flint_printf("\n\n"); flint_printf("trace(ab) = \n"); arb_printd(trab, 15); flint_printf("\n\n"); flint_printf("trace(ba) = \n"); arb_printd(trba, 15); flint_printf("\n\n"); flint_abort(); } arb_clear(trab); arb_clear(trba); arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(ab); arb_mat_clear(ba); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/test/t-transpose.c000066400000000000000000000033261417376376500174000ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("transpose...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n; arb_mat_t a, b, c; m = n_randint(state, 10); n = n_randint(state, 10); arb_mat_init(a, m, n); arb_mat_init(b, n, m); arb_mat_init(c, m, n); arb_mat_randtest(a, state, 2 + n_randint(state, 100), 10); arb_mat_randtest(b, state, 2 + n_randint(state, 100), 10); arb_mat_randtest(c, state, 2 + n_randint(state, 100), 10); arb_mat_transpose(b, a); arb_mat_transpose(c, b); if (!arb_mat_equal(c, a)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd\n", m, n); flint_abort(); } if (arb_mat_nrows(a) == arb_mat_ncols(a)) { arb_mat_transpose(c, a); arb_mat_transpose(a, a); if (!arb_mat_equal(a, c)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } } arb_mat_clear(a); arb_mat_clear(b); arb_mat_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_mat/trace.c000066400000000000000000000015461417376376500152420ustar00rootroot00000000000000/* Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_trace(arb_t trace, const arb_mat_t mat, slong prec) { slong i; if (!arb_mat_is_square(mat)) { flint_printf("arb_mat_trace: a square matrix is required!\n"); flint_abort(); } if (arb_mat_is_empty(mat)) { arb_zero(trace); return; } arb_set(trace, arb_mat_entry(mat, 0, 0)); for (i = 1; i < arb_mat_nrows(mat); i++) { arb_add(trace, trace, arb_mat_entry(mat, i, i), prec); } } arb-2.22.1/arb_mat/transpose.c000066400000000000000000000023371417376376500161610ustar00rootroot00000000000000/* Copyright (C) 2015 Tommy Hofmann This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_transpose(arb_mat_t B, const arb_mat_t A) { slong i, j; if (arb_mat_nrows(B) != arb_mat_ncols(A) || arb_mat_ncols(B) != arb_mat_nrows(A)) { flint_printf("Exception (arb_mat_transpose). Incompatible dimensions.\n"); flint_abort(); } if (arb_mat_is_empty(A)) return; if (A == B) /* In-place, guaranteed to be square */ { for (i = 0; i < arb_mat_nrows(A) - 1; i++) { for (j = i + 1; j < arb_mat_ncols(A); j++) { arb_swap(arb_mat_entry(A, i, j), arb_mat_entry(A, j, i)); } } } else /* Not aliased; general case */ { for (i = 0; i < arb_mat_nrows(B); i++) for (j = 0; j < arb_mat_ncols(B); j++) arb_set(arb_mat_entry(B, i, j), arb_mat_entry(A, j, i)); } } arb-2.22.1/arb_mat/window_init.c000066400000000000000000000013631417376376500164730ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_window_init(arb_mat_t window, const arb_mat_t mat, slong r1, slong c1, slong r2, slong c2) { slong i; window->entries = NULL; window->rows = flint_malloc((r2 - r1) * sizeof(arb_ptr)); for (i = 0; i < r2 - r1; i++) window->rows[i] = mat->rows[r1 + i] + c1; window->r = r2 - r1; window->c = c2 - c1; } arb-2.22.1/arb_mat/zero.c000066400000000000000000000011261417376376500151150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_mat.h" void arb_mat_zero(arb_mat_t mat) { slong i, j; for (i = 0; i < arb_mat_nrows(mat); i++) for (j = 0; j < arb_mat_ncols(mat); j++) arb_zero(arb_mat_entry(mat, i, j)); } arb-2.22.1/arb_poly.h000066400000000000000000000702701417376376500143530ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARB_POLY_H #define ARB_POLY_H #ifdef ARB_POLY_INLINES_C #define ARB_POLY_INLINE #else #define ARB_POLY_INLINE static __inline__ #endif #include #include "flint/fmpz_poly.h" #include "flint/fmpq_poly.h" #include "arb.h" #include "acb.h" #ifdef __cplusplus extern "C" { #endif typedef struct { arb_ptr coeffs; slong length; slong alloc; } arb_poly_struct; typedef arb_poly_struct arb_poly_t[1]; /* Memory management */ void arb_poly_init(arb_poly_t poly); void arb_poly_init2(arb_poly_t poly, slong len); void arb_poly_clear(arb_poly_t poly); void arb_poly_fit_length(arb_poly_t poly, slong len); void _arb_poly_set_length(arb_poly_t poly, slong len); void _arb_poly_normalise(arb_poly_t poly); ARB_POLY_INLINE void arb_poly_swap(arb_poly_t poly1, arb_poly_t poly2) { arb_poly_struct t = *poly1; *poly1 = *poly2; *poly2 = t; } void arb_poly_set(arb_poly_t poly, const arb_poly_t src); void arb_poly_set_round(arb_poly_t poly, const arb_poly_t src, slong prec); void arb_poly_set_trunc(arb_poly_t res, const arb_poly_t poly, slong n); void arb_poly_set_trunc_round(arb_poly_t res, const arb_poly_t poly, slong n, slong prec); /* Basic manipulation */ ARB_POLY_INLINE slong arb_poly_length(const arb_poly_t poly) { return poly->length; } ARB_POLY_INLINE slong arb_poly_degree(const arb_poly_t poly) { return poly->length - 1; } slong arb_poly_valuation(const arb_poly_t poly); ARB_POLY_INLINE int arb_poly_is_zero(const arb_poly_t z) { return arb_poly_length(z) == 0; } ARB_POLY_INLINE int arb_poly_is_one(const arb_poly_t z) { return (arb_poly_length(z) == 1) && arb_is_one(z->coeffs); } ARB_POLY_INLINE int arb_poly_is_x(const arb_poly_t z) { return (arb_poly_length(z) == 2) && arb_is_zero(z->coeffs) && arb_is_one(z->coeffs + 1); } ARB_POLY_INLINE void arb_poly_zero(arb_poly_t poly) { poly->length = 0; } ARB_POLY_INLINE void arb_poly_one(arb_poly_t poly) { arb_poly_fit_length(poly, 1); arb_one(poly->coeffs); _arb_poly_set_length(poly, 1); } void arb_poly_set_coeff_si(arb_poly_t poly, slong n, slong x); void arb_poly_set_coeff_arb(arb_poly_t poly, slong n, const arb_t x); void arb_poly_get_coeff_arb(arb_t x, const arb_poly_t poly, slong n); #define arb_poly_get_coeff_ptr(poly, n) \ ((n) < (poly)->length ? (poly)->coeffs + (n) : NULL) void _arb_poly_reverse(arb_ptr res, arb_srcptr poly, slong len, slong n); void _arb_poly_shift_right(arb_ptr res, arb_srcptr poly, slong len, slong n); void arb_poly_shift_right(arb_poly_t res, const arb_poly_t poly, slong n); void _arb_poly_shift_left(arb_ptr res, arb_srcptr poly, slong len, slong n); void arb_poly_shift_left(arb_poly_t res, const arb_poly_t poly, slong n); ARB_POLY_INLINE void arb_poly_truncate(arb_poly_t poly, slong newlen) { if (poly->length > newlen) { slong i; for (i = newlen; i < poly->length; i++) arb_zero(poly->coeffs + i); poly->length = newlen; _arb_poly_normalise(poly); } } /* Conversions */ void arb_poly_set_fmpz_poly(arb_poly_t poly, const fmpz_poly_t src, slong prec); void arb_poly_set_fmpq_poly(arb_poly_t poly, const fmpq_poly_t src, slong prec); ARB_POLY_INLINE void arb_poly_set_arb(arb_poly_t poly, const arb_t c) { arb_poly_fit_length(poly, 1); arb_set(poly->coeffs, c); _arb_poly_set_length(poly, !arb_is_zero(poly->coeffs)); } void arb_poly_set_si(arb_poly_t poly, slong c); int arb_poly_get_unique_fmpz_poly(fmpz_poly_t res, const arb_poly_t src); /* Comparisons */ int arb_poly_contains(const arb_poly_t poly1, const arb_poly_t poly2); int arb_poly_contains_fmpz_poly(const arb_poly_t poly1, const fmpz_poly_t poly2); int arb_poly_contains_fmpq_poly(const arb_poly_t poly1, const fmpq_poly_t poly2); int arb_poly_equal(const arb_poly_t A, const arb_poly_t B); int _arb_poly_overlaps(arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2); int arb_poly_overlaps(const arb_poly_t poly1, const arb_poly_t poly2); /* Bounds */ void _arb_poly_majorant(arb_ptr res, arb_srcptr vec, slong len, slong prec); void arb_poly_majorant(arb_poly_t res, const arb_poly_t poly, slong prec); /* IO */ void arb_poly_fprintd(FILE * file, const arb_poly_t poly, slong digits); ARB_POLY_INLINE void arb_poly_printd(const arb_poly_t poly, slong digits) { arb_poly_fprintd(stdout, poly, digits); } /* Random generation */ void arb_poly_randtest(arb_poly_t poly, flint_rand_t state, slong len, slong prec, slong mag_bits); /* Arithmetic */ void _arb_poly_add(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec); void arb_poly_add(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec); void arb_poly_add_si(arb_poly_t res, const arb_poly_t poly, slong c, slong prec); void _arb_poly_sub(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec); void arb_poly_sub(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec); void arb_poly_add_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong len, slong prec); void arb_poly_sub_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong len, slong prec); ARB_POLY_INLINE void arb_poly_neg(arb_poly_t res, const arb_poly_t poly) { arb_poly_fit_length(res, poly->length); _arb_vec_neg(res->coeffs, poly->coeffs, poly->length); _arb_poly_set_length(res, poly->length); } ARB_POLY_INLINE void arb_poly_scalar_mul_2exp_si(arb_poly_t res, const arb_poly_t poly, slong c) { arb_poly_fit_length(res, poly->length); _arb_vec_scalar_mul_2exp_si(res->coeffs, poly->coeffs, poly->length, c); _arb_poly_set_length(res, poly->length); } ARB_POLY_INLINE void arb_poly_scalar_mul(arb_poly_t res, const arb_poly_t poly, const arb_t c, slong prec) { arb_poly_fit_length(res, poly->length); _arb_vec_scalar_mul(res->coeffs, poly->coeffs, poly->length, c, prec); _arb_poly_set_length(res, poly->length); _arb_poly_normalise(res); } ARB_POLY_INLINE void arb_poly_scalar_div(arb_poly_t res, const arb_poly_t poly, const arb_t c, slong prec) { arb_poly_fit_length(res, poly->length); _arb_vec_scalar_div(res->coeffs, poly->coeffs, poly->length, c, prec); _arb_poly_set_length(res, poly->length); _arb_poly_normalise(res); } void _arb_poly_mullow_ztrunc(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec); void arb_poly_mullow_ztrunc(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec); void _arb_poly_mullow_classical(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec); void arb_poly_mullow_classical(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec); void _arb_poly_mullow_block(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong n, slong prec); void arb_poly_mullow_block(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong len, slong prec); void _arb_poly_mullow(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong n, slong prec); void arb_poly_mullow(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong len, slong prec); void _arb_poly_mul(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec); void arb_poly_mul(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec); ARB_POLY_INLINE void _arb_poly_mul_monic(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) { if (len1 + len2 - 2 > 0) _arb_poly_mullow(res, poly1, len1, poly2, len2, len1 + len2 - 2, prec); arb_one(res + len1 + len2 - 2); } void _arb_poly_inv_series(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong len, slong prec); void arb_poly_inv_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec); void _arb_poly_div_series(arb_ptr Q, arb_srcptr A, slong Alen, arb_srcptr B, slong Blen, slong n, slong prec); void arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, slong n, slong prec); void _arb_poly_div(arb_ptr Q, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec); void _arb_poly_divrem(arb_ptr Q, arb_ptr R, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec); void _arb_poly_rem(arb_ptr R, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec); int arb_poly_divrem(arb_poly_t Q, arb_poly_t R, const arb_poly_t A, const arb_poly_t B, slong prec); void _arb_poly_div_root(arb_ptr Q, arb_t R, arb_srcptr A, slong len, const arb_t c, slong prec); /* Product trees */ void _arb_poly_product_roots(arb_ptr poly, arb_srcptr xs, slong n, slong prec); void arb_poly_product_roots(arb_poly_t poly, arb_srcptr xs, slong n, slong prec); void _arb_poly_product_roots_complex(arb_ptr poly, arb_srcptr r, slong rn, acb_srcptr c, slong cn, slong prec); void arb_poly_product_roots_complex(arb_poly_t poly, arb_srcptr r, slong rn, acb_srcptr c, slong cn, slong prec); arb_ptr * _arb_poly_tree_alloc(slong len); void _arb_poly_tree_free(arb_ptr * tree, slong len); void _arb_poly_tree_build(arb_ptr * tree, arb_srcptr roots, slong len, slong prec); /* Composition */ void _arb_poly_taylor_shift_horner(arb_ptr poly, const arb_t c, slong n, slong prec); void arb_poly_taylor_shift_horner(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec); void _arb_poly_taylor_shift_divconquer(arb_ptr poly, const arb_t c, slong n, slong prec); void arb_poly_taylor_shift_divconquer(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec); void _arb_poly_taylor_shift_convolution(arb_ptr poly, const arb_t c, slong n, slong prec); void arb_poly_taylor_shift_convolution(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec); void _arb_poly_taylor_shift(arb_ptr poly, const arb_t c, slong n, slong prec); void arb_poly_taylor_shift(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec); void _arb_poly_compose(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec); void arb_poly_compose(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec); void _arb_poly_compose_horner(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec); void arb_poly_compose_horner(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec); void _arb_poly_compose_divconquer(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec); void arb_poly_compose_divconquer(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec); void _arb_poly_compose_series_horner(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec); void arb_poly_compose_series_horner(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec); void _arb_poly_compose_series(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec); void arb_poly_compose_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec); /* Reversion */ void _arb_poly_revert_series_lagrange(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec); void arb_poly_revert_series_lagrange(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec); void _arb_poly_revert_series_newton(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec); void arb_poly_revert_series_newton(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec); void _arb_poly_revert_series_lagrange_fast(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec); void arb_poly_revert_series_lagrange_fast(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec); void _arb_poly_revert_series(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec); void arb_poly_revert_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec); /* Evaluation and interpolation */ void _arb_poly_evaluate_horner(arb_t res, arb_srcptr f, slong len, const arb_t a, slong prec); void arb_poly_evaluate_horner(arb_t res, const arb_poly_t f, const arb_t a, slong prec); void _arb_poly_evaluate_rectangular(arb_t y, arb_srcptr poly, slong len, const arb_t x, slong prec); void arb_poly_evaluate_rectangular(arb_t res, const arb_poly_t f, const arb_t a, slong prec); void _arb_poly_evaluate(arb_t res, arb_srcptr f, slong len, const arb_t a, slong prec); void arb_poly_evaluate(arb_t res, const arb_poly_t f, const arb_t a, slong prec); void _arb_poly_evaluate2_horner(arb_t y, arb_t z, arb_srcptr f, slong len, const arb_t x, slong prec); void arb_poly_evaluate2_horner(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, slong prec); void _arb_poly_evaluate2_rectangular(arb_t y, arb_t z, arb_srcptr f, slong len, const arb_t x, slong prec); void arb_poly_evaluate2_rectangular(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, slong prec); void _arb_poly_evaluate2(arb_t y, arb_t z, arb_srcptr f, slong len, const arb_t x, slong prec); void arb_poly_evaluate2(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, slong prec); void _arb_poly_evaluate_vec_iter(arb_ptr ys, arb_srcptr poly, slong plen, arb_srcptr xs, slong n, slong prec); void arb_poly_evaluate_vec_iter(arb_ptr ys, const arb_poly_t poly, arb_srcptr xs, slong n, slong prec); void _arb_poly_evaluate_vec_fast_precomp(arb_ptr vs, arb_srcptr poly, slong plen, arb_ptr * tree, slong len, slong prec); void _arb_poly_evaluate_vec_fast(arb_ptr ys, arb_srcptr poly, slong plen, arb_srcptr xs, slong n, slong prec); void arb_poly_evaluate_vec_fast(arb_ptr ys, const arb_poly_t poly, arb_srcptr xs, slong n, slong prec); void _arb_poly_interpolate_newton(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec); void arb_poly_interpolate_newton(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec); void _arb_poly_interpolate_barycentric(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec); void arb_poly_interpolate_barycentric(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec); void _arb_poly_interpolation_weights(arb_ptr w, arb_ptr * tree, slong len, slong prec); void _arb_poly_interpolate_fast_precomp(arb_ptr poly, arb_srcptr ys, arb_ptr * tree, arb_srcptr weights, slong len, slong prec); void _arb_poly_interpolate_fast(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong len, slong prec); void arb_poly_interpolate_fast(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec); /* Derivative and integral */ void _arb_poly_derivative(arb_ptr res, arb_srcptr poly, slong len, slong prec); void arb_poly_derivative(arb_poly_t res, const arb_poly_t poly, slong prec); void _arb_poly_integral(arb_ptr res, arb_srcptr poly, slong len, slong prec); void arb_poly_integral(arb_poly_t res, const arb_poly_t poly, slong prec); /* Transforms */ void arb_poly_borel_transform(arb_poly_t res, const arb_poly_t poly, slong prec); void _arb_poly_borel_transform(arb_ptr res, arb_srcptr poly, slong len, slong prec); void arb_poly_inv_borel_transform(arb_poly_t res, const arb_poly_t poly, slong prec); void _arb_poly_inv_borel_transform(arb_ptr res, arb_srcptr poly, slong len, slong prec); void _arb_poly_binomial_transform_basecase(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec); void arb_poly_binomial_transform_basecase(arb_poly_t b, const arb_poly_t a, slong len, slong prec); void _arb_poly_binomial_transform_convolution(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec); void arb_poly_binomial_transform_convolution(arb_poly_t b, const arb_poly_t a, slong len, slong prec); void _arb_poly_binomial_transform(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec); void arb_poly_binomial_transform(arb_poly_t b, const arb_poly_t a, slong len, slong prec); void _arb_poly_graeffe_transform(arb_ptr b, arb_srcptr a, slong len, slong prec); void arb_poly_graeffe_transform(arb_poly_t b, const arb_poly_t a, slong prec); /* Special functions */ void _arb_poly_pow_ui_trunc_binexp(arb_ptr res, arb_srcptr f, slong flen, ulong exp, slong len, slong prec); void arb_poly_pow_ui_trunc_binexp(arb_poly_t res, const arb_poly_t poly, ulong exp, slong len, slong prec); void _arb_poly_pow_ui(arb_ptr res, arb_srcptr f, slong flen, ulong exp, slong prec); void arb_poly_pow_ui(arb_poly_t res, const arb_poly_t poly, ulong exp, slong prec); void _arb_poly_pow_series(arb_ptr h, arb_srcptr f, slong flen, arb_srcptr g, slong glen, slong len, slong prec); void arb_poly_pow_series(arb_poly_t h, const arb_poly_t f, const arb_poly_t g, slong len, slong prec); void _arb_poly_pow_arb_series(arb_ptr h, arb_srcptr f, slong flen, const arb_t g, slong len, slong prec); void arb_poly_pow_arb_series(arb_poly_t h, const arb_poly_t f, const arb_t g, slong len, slong prec); void _arb_poly_binomial_pow_arb_series(arb_ptr h, arb_srcptr f, slong flen, const arb_t g, slong len, slong prec); void _arb_poly_rsqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_rsqrt_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_sqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_sqrt_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_log_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec); void arb_poly_log_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_log1p_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec); void arb_poly_log1p_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_atan_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec); void arb_poly_atan_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_asin_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec); void arb_poly_asin_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_acos_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec); void arb_poly_acos_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_exp_series_basecase(arb_ptr f, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_exp_series_basecase(arb_poly_t f, const arb_poly_t h, slong n, slong prec); void _arb_poly_exp_series(arb_ptr f, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_exp_series(arb_poly_t f, const arb_poly_t h, slong n, slong prec); void _arb_poly_sinh_cosh_series_basecase(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sinh_cosh_series_basecase(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec); void _arb_poly_sinh_cosh_series_exponential(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sinh_cosh_series_exponential(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec); void _arb_poly_sinh_cosh_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sinh_cosh_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec); void _arb_poly_sinh_series(arb_ptr s, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sinh_series(arb_poly_t s, const arb_poly_t h, slong n, slong prec); void _arb_poly_cosh_series(arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_cosh_series(arb_poly_t c, const arb_poly_t h, slong n, slong prec); void _arb_poly_sin_cos_series_basecase(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec, int times_pi); void arb_poly_sin_cos_series_basecase(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec, int times_pi); void _arb_poly_sin_cos_series_tangent(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong len, slong prec, int times_pi); void arb_poly_sin_cos_series_tangent(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec, int times_pi); void _arb_poly_sin_cos_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_sin_cos_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec); void _arb_poly_sin_cos_pi_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_sin_cos_pi_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec); void _arb_poly_sin_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sin_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_cos_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_cos_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_sin_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sin_pi_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_cos_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_cos_pi_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_cot_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_cot_pi_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_tan_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_tan_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_sinc_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sinc_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_sinc_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec); void arb_poly_sinc_pi_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec); void _arb_poly_compose_series_brent_kung(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec); void arb_poly_compose_series_brent_kung(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec); void _arb_poly_evaluate_acb_horner(acb_t res, arb_srcptr f, slong len, const acb_t x, slong prec); void arb_poly_evaluate_acb_horner(acb_t res, const arb_poly_t f, const acb_t a, slong prec); void _arb_poly_evaluate_acb_rectangular(acb_t y, arb_srcptr poly, slong len, const acb_t x, slong prec); void arb_poly_evaluate_acb_rectangular(acb_t res, const arb_poly_t f, const acb_t a, slong prec); void _arb_poly_evaluate_acb(acb_t res, arb_srcptr f, slong len, const acb_t x, slong prec); void arb_poly_evaluate_acb(acb_t res, const arb_poly_t f, const acb_t a, slong prec); void _arb_poly_evaluate2_acb_horner(acb_t y, acb_t z, arb_srcptr f, slong len, const acb_t x, slong prec); void arb_poly_evaluate2_acb_horner(acb_t y, acb_t z, const arb_poly_t f, const acb_t x, slong prec); void _arb_poly_evaluate2_acb_rectangular(acb_t y, acb_t z, arb_srcptr f, slong len, const acb_t x, slong prec); void arb_poly_evaluate2_acb_rectangular(acb_t y, acb_t z, const arb_poly_t f, const acb_t x, slong prec); void _arb_poly_evaluate2_acb(acb_t y, acb_t z, arb_srcptr f, slong len, const acb_t x, slong prec); void arb_poly_evaluate2_acb(acb_t y, acb_t z, const arb_poly_t f, const acb_t x, slong prec); void _arb_poly_lambertw_series(arb_ptr res, arb_srcptr z, slong zlen, int flags, slong len, slong prec); void arb_poly_lambertw_series(arb_poly_t res, const arb_poly_t z, int flags, slong len, slong prec); void _arb_poly_gamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_gamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_rgamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_rgamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_lgamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_lgamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_digamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_digamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec); void _arb_poly_rising_ui_series(arb_ptr res, arb_srcptr f, slong flen, ulong r, slong trunc, slong prec); void arb_poly_rising_ui_series(arb_poly_t res, const arb_poly_t f, ulong r, slong trunc, slong prec); void _arb_poly_zeta_series(arb_ptr res, arb_srcptr h, slong hlen, const arb_t a, int deflate, slong len, slong prec); void arb_poly_zeta_series(arb_poly_t res, const arb_poly_t f, const arb_t a, int deflate, slong n, slong prec); void _arb_poly_riemann_siegel_theta_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_riemann_siegel_theta_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec); void _arb_poly_riemann_siegel_z_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec); void arb_poly_riemann_siegel_z_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec); slong _arb_poly_swinnerton_dyer_ui_prec(ulong n); void _arb_poly_swinnerton_dyer_ui(arb_ptr T, ulong n, slong trunc, slong prec); void arb_poly_swinnerton_dyer_ui(arb_poly_t poly, ulong n, slong prec); /* Root-finding */ void _arb_poly_newton_convergence_factor(arf_t convergence_factor, arb_srcptr poly, slong len, const arb_t convergence_interval, slong prec); int _arb_poly_newton_step(arb_t xnew, arb_srcptr poly, slong len, const arb_t x, const arb_t convergence_interval, const arf_t convergence_factor, slong prec); void _arb_poly_newton_refine_root(arb_t r, arb_srcptr poly, slong len, const arb_t start, const arb_t convergence_interval, const arf_t convergence_factor, slong eval_extra_prec, slong prec); void _arb_poly_root_bound_fujiwara(mag_t bound, arb_srcptr poly, slong len); void arb_poly_root_bound_fujiwara(mag_t bound, arb_poly_t poly); ARB_POLY_INLINE slong arb_poly_allocated_bytes(const arb_poly_t x) { return _arb_vec_allocated_bytes(x->coeffs, x->alloc); } /* Macros */ /* counts zero bits in the binary representation of e */ ARB_POLY_INLINE int n_zerobits(mp_limb_t e) { int zeros = 0; while (e > 1) { zeros += !(e & 1); e >>= 1; } return zeros; } /* Computes the length of the result when raising a polynomial of length *len* to the power *exp* and truncating to length *trunc*, without overflow. Assumes poly_len >= 1. */ ARB_POLY_INLINE slong poly_pow_length(slong poly_len, ulong exp, slong trunc) { mp_limb_t hi, lo; umul_ppmm(hi, lo, poly_len - 1, exp); add_ssaaaa(hi, lo, hi, lo, 0, 1); if (hi != 0 || lo > (mp_limb_t) WORD_MAX) return trunc; return FLINT_MIN((slong) lo, trunc); } #ifndef NEWTON_INIT #define NEWTON_INIT(from, to) \ { \ slong __steps[FLINT_BITS], __i, __from, __to; \ __steps[__i = 0] = __to = (to); \ __from = (from); \ while (__to > __from) \ __steps[++__i] = (__to = (__to + 1) / 2); \ #define NEWTON_BASECASE(bc_to) { slong bc_to = __to; #define NEWTON_END_BASECASE } #define NEWTON_LOOP(step_from, step_to) \ { \ for (__i--; __i >= 0; __i--) \ { \ slong step_from = __steps[__i+1]; \ slong step_to = __steps[__i]; \ #define NEWTON_END_LOOP }} #define NEWTON_END } #endif #ifdef __cplusplus } #endif #endif arb-2.22.1/arb_poly/000077500000000000000000000000001417376376500141745ustar00rootroot00000000000000arb-2.22.1/arb_poly/acos_series.c000066400000000000000000000035741417376376500166500ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_acos_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { arb_t c; arb_init(c); arb_acos(c, h, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _arb_vec_zero(g + 1, n - 1); } else { arb_ptr t, u; slong ulen; t = _arb_vec_init(n); u = _arb_vec_init(n); /* acos(h(x)) = integral(-h'(x)/sqrt(1-h(x)^2)) */ ulen = FLINT_MIN(n, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); arb_sub_ui(u, u, 1, prec); _arb_vec_neg(u, u, ulen); _arb_poly_rsqrt_series(t, u, ulen, n, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(g, t, n, u, hlen - 1, n, prec); _arb_poly_integral(g, g, n, prec); _arb_vec_neg(g, g, n); _arb_vec_clear(t, n); _arb_vec_clear(u, n); } arb_swap(g, c); arb_clear(c); } void arb_poly_acos_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0) { if (n == 0) arb_poly_zero(g); else { arb_poly_fit_length(g, 1); arb_const_pi(g->coeffs, prec); arb_mul_2exp_si(g->coeffs, g->coeffs, -1); _arb_poly_set_length(g, 1); } return; } arb_poly_fit_length(g, n); _arb_poly_acos_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/add.c000066400000000000000000000022601417376376500150700ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_add(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) { slong i, min = FLINT_MIN(len1, len2); for (i = 0; i < min; i++) arb_add(res + i, poly1 + i, poly2 + i, prec); for (i = min; i < len1; i++) arb_set_round(res + i, poly1 + i, prec); for (i = min; i < len2; i++) arb_set_round(res + i, poly2 + i, prec); } void arb_poly_add(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { slong max = FLINT_MAX(poly1->length, poly2->length); arb_poly_fit_length(res, max); _arb_poly_add(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); _arb_poly_set_length(res, max); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/add_series.c000066400000000000000000000015731417376376500164500ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_add_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong len, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; len1 = FLINT_MIN(len1, len); len2 = FLINT_MIN(len2, len); len = FLINT_MAX(len1, len2); arb_poly_fit_length(res, len); _arb_poly_add(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/add_si.c000066400000000000000000000015301417376376500155620ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_add_si(arb_poly_t res, const arb_poly_t x, slong y, slong prec) { slong len = x->length; if (len == 0) { arb_poly_set_si(res, y); } else { arb_poly_fit_length(res, len); arb_add_si(res->coeffs, x->coeffs, y, prec); if (res != x) _arb_vec_set(res->coeffs + 1, x->coeffs + 1, len - 1); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } } arb-2.22.1/arb_poly/asin_series.c000066400000000000000000000031741417376376500166510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_asin_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { arb_t c; arb_init(c); arb_asin(c, h, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _arb_vec_zero(g + 1, n - 1); } else { arb_ptr t, u; slong ulen; t = _arb_vec_init(n); u = _arb_vec_init(n); /* asin(h(x)) = integral(h'(x)/sqrt(1-h(x)^2)) */ ulen = FLINT_MIN(n, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); arb_sub_ui(u, u, 1, prec); _arb_vec_neg(u, u, ulen); _arb_poly_rsqrt_series(t, u, ulen, n, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(g, t, n, u, hlen - 1, n, prec); _arb_poly_integral(g, g, n, prec); _arb_vec_clear(t, n); _arb_vec_clear(u, n); } arb_swap(g, c); arb_clear(c); } void arb_poly_asin_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, n); _arb_poly_asin_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/atan_series.c000066400000000000000000000030521417376376500166350ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_atan_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { arb_t c; arb_init(c); arb_atan(c, h, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _arb_vec_zero(g + 1, n - 1); } else { arb_ptr t, u; slong ulen; t = _arb_vec_init(n); u = _arb_vec_init(n); /* atan(h(x)) = integral(h'(x)/(1+h(x)^2)) */ ulen = FLINT_MIN(n, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); arb_add_ui(u, u, 1, prec); _arb_poly_derivative(t, h, hlen, prec); _arb_poly_div_series(g, t, hlen - 1, u, ulen, n, prec); _arb_poly_integral(g, g, n, prec); _arb_vec_clear(t, n); _arb_vec_clear(u, n); } arb_swap(g, c); arb_clear(c); } void arb_poly_atan_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { arb_poly_zero(g); return; } arb_poly_fit_length(g, n); _arb_poly_atan_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/binomial_transform.c000066400000000000000000000024161417376376500202300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_binomial_transform(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec) { if (alen < 10 || len < 10) _arb_poly_binomial_transform_basecase(b, a, alen, len, prec); else _arb_poly_binomial_transform_convolution(b, a, alen, len, prec); } void arb_poly_binomial_transform(arb_poly_t b, const arb_poly_t a, slong len, slong prec) { if (len == 0 || a->length == 0) { arb_poly_zero(b); return; } if (b == a) { arb_poly_t c; arb_poly_init2(c, len); _arb_poly_binomial_transform(c->coeffs, a->coeffs, a->length, len, prec); arb_poly_swap(b, c); arb_poly_clear(c); } else { arb_poly_fit_length(b, len); _arb_poly_binomial_transform(b->coeffs, a->coeffs, a->length, len, prec); } _arb_poly_set_length(b, len); _arb_poly_normalise(b); } arb-2.22.1/arb_poly/binomial_transform_basecase.c000066400000000000000000000031351417376376500220550ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_binomial_transform_basecase(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec) { slong n, k; fmpz_t t; fmpz_init(t); for (n = 0; n < len; n++) { arb_zero(b + n); for (k = 0; k < FLINT_MIN(n + 1, alen); k++) { if (k == 0) { fmpz_one(t); } else { fmpz_mul_si(t, t, -(n - k + 1)); fmpz_divexact_ui(t, t, k); } arb_addmul_fmpz(b + n, a + k, t, prec); } } fmpz_clear(t); } void arb_poly_binomial_transform_basecase(arb_poly_t b, const arb_poly_t a, slong len, slong prec) { if (len == 0 || a->length == 0) { arb_poly_zero(b); return; } if (b == a) { arb_poly_t c; arb_poly_init2(c, len); _arb_poly_binomial_transform_basecase(c->coeffs, a->coeffs, a->length, len, prec); arb_poly_swap(b, c); arb_poly_clear(c); } else { arb_poly_fit_length(b, len); _arb_poly_binomial_transform_basecase(b->coeffs, a->coeffs, a->length, len, prec); } _arb_poly_set_length(b, len); _arb_poly_normalise(b); } arb-2.22.1/arb_poly/binomial_transform_convolution.c000066400000000000000000000032121417376376500226620ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb_poly.h" void _arb_poly_binomial_transform_convolution(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec) { slong i; arb_ptr c, d; alen = FLINT_MIN(alen, len); c = _arb_vec_init(alen); d = _arb_vec_init(len); _arb_poly_borel_transform(c, a, alen, prec); for (i = 1; i < alen; i += 2) arb_neg(c + i, c + i); arb_one(d); for (i = 1; i < len; i++) arb_div_ui(d + i, d + i - 1, i, prec); _arb_poly_mullow(b, d, len, c, alen, len, prec); _arb_poly_inv_borel_transform(b, b, len, prec); _arb_vec_clear(c, alen); _arb_vec_clear(d, len); } void arb_poly_binomial_transform_convolution(arb_poly_t b, const arb_poly_t a, slong len, slong prec) { if (len == 0 || a->length == 0) { arb_poly_zero(b); return; } if (b == a) { arb_poly_t c; arb_poly_init2(c, len); _arb_poly_binomial_transform_convolution(c->coeffs, a->coeffs, a->length, len, prec); arb_poly_swap(b, c); arb_poly_clear(c); } else { arb_poly_fit_length(b, len); _arb_poly_binomial_transform_convolution(b->coeffs, a->coeffs, a->length, len, prec); } _arb_poly_set_length(b, len); _arb_poly_normalise(b); } arb-2.22.1/arb_poly/borel_transform.c000066400000000000000000000017521417376376500175430ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_borel_transform(arb_ptr res, arb_srcptr poly, slong len, slong prec) { slong i; arb_t t; arb_init(t); arb_one(t); for (i = 0; i < len; i++) { if (i > 1) arb_mul_ui(t, t, i, prec); arb_div(res + i, poly + i, t, prec); } arb_clear(t); } void arb_poly_borel_transform(arb_poly_t res, const arb_poly_t poly, slong prec) { arb_poly_fit_length(res, poly->length); _arb_poly_borel_transform(res->coeffs, poly->coeffs, poly->length, prec); _arb_poly_set_length(res, poly->length); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/clear.c000066400000000000000000000010641417376376500154270ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_clear(arb_poly_t poly) { slong i; for (i = 0; i < poly->alloc; i++) arb_clear(poly->coeffs + i); flint_free(poly->coeffs); } arb-2.22.1/arb_poly/compose.c000066400000000000000000000064221417376376500160110ustar00rootroot00000000000000/* Copyright (C) 2010 William Hart Copyright (C) 2012 Sebastian Pancratz Copyright (C) 2012, 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* compose by poly2 = a*x^n + c, no aliasing; n >= 1 */ void _arb_poly_compose_axnc(arb_ptr res, arb_srcptr poly1, slong len1, const arb_t c, const arb_t a, slong n, slong prec) { slong i; _arb_vec_set_round(res, poly1, len1, prec); /* shift by c (c = 0 case will be fast) */ _arb_poly_taylor_shift(res, c, len1, prec); /* multiply by powers of a */ if (!arb_is_one(a)) { if (arb_equal_si(a, -1)) { for (i = 1; i < len1; i += 2) arb_neg(res + i, res + i); } else if (len1 == 2) { arb_mul(res + 1, res + 1, a, prec); } else { arb_t t; arb_init(t); arb_set(t, a); for (i = 1; i < len1; i++) { arb_mul(res + i, res + i, t, prec); if (i + 1 < len1) arb_mul(t, t, a, prec); } arb_clear(t); } } /* stretch */ for (i = len1 - 1; i >= 1 && n > 1; i--) { arb_swap(res + i * n, res + i); _arb_vec_zero(res + (i - 1) * n + 1, n - 1); } } void _arb_poly_compose(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) { if (len1 == 1) { arb_set_round(res, poly1, prec); } else if (len2 == 1) { _arb_poly_evaluate(res, poly1, len1, poly2, prec); } else if (_arb_vec_is_zero(poly2 + 1, len2 - 2)) { _arb_poly_compose_axnc(res, poly1, len1, poly2, poly2 + len2 - 1, len2 - 1, prec); } else if (len1 <= 7) { _arb_poly_compose_horner(res, poly1, len1, poly2, len2, prec); } else { _arb_poly_compose_divconquer(res, poly1, len1, poly2, len2, prec); } } void arb_poly_compose(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { const slong len1 = poly1->length; const slong len2 = poly2->length; if (len1 == 0) { arb_poly_zero(res); } else if (len1 == 1 || len2 == 0) { arb_poly_set_arb(res, poly1->coeffs); } else { const slong lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { arb_poly_fit_length(res, lenr); _arb_poly_compose(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); arb_poly_swap(res, t); arb_poly_clear(t); } _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } } arb-2.22.1/arb_poly/compose_divconquer.c000066400000000000000000000116001417376376500202420ustar00rootroot00000000000000/* Copyright (C) 2010 William Hart Copyright (C) 2012 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_compose_divconquer(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) { slong i, j, k, n; slong *hlen, alloc, powlen; arb_ptr v, pow, temp; arb_ptr * h; if (len1 == 1) { arb_set(res, poly1); return; } if (len2 == 1) { _arb_poly_evaluate(res, poly1, len1, poly2, prec); return; } if (len1 == 2) { _arb_poly_compose_horner(res, poly1, len1, poly2, len2, prec); return; } /* Initialisation */ hlen = (slong *) flint_malloc(((len1 + 1) / 2) * sizeof(slong)); for (k = 1; (2 << k) < len1; k++) ; hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1; for (i = k - 1; i > 0; i--) { slong hi = (len1 + (1 << i) - 1) / (1 << i); for (n = (hi + 1) / 2; n < hi; n++) hlen[n] = ((1 << i) - 1) * (len2 - 1) + 1; } powlen = (1 << k) * (len2 - 1) + 1; alloc = 0; for (i = 0; i < (len1 + 1) / 2; i++) alloc += hlen[i]; v = _arb_vec_init(alloc + 2 * powlen); h = (arb_ptr *) flint_malloc(((len1 + 1) / 2) * sizeof(arb_ptr)); h[0] = v; for (i = 0; i < (len1 - 1) / 2; i++) { h[i + 1] = h[i] + hlen[i]; hlen[i] = 0; } hlen[(len1 - 1) / 2] = 0; pow = v + alloc; temp = pow + powlen; /* Let's start the actual work */ for (i = 0, j = 0; i < len1 / 2; i++, j += 2) { if (!arb_is_zero(poly1 + j + 1)) { _arb_vec_scalar_mul(h[i], poly2, len2, poly1 + j + 1, prec); arb_add(h[i], h[i], poly1 + j, prec); hlen[i] = len2; } else if (!arb_is_zero(poly1 + j)) { arb_set(h[i], poly1 + j); hlen[i] = 1; } } if ((len1 & WORD(1))) { if (!arb_is_zero(poly1 + j)) { arb_set(h[i], poly1 + j); hlen[i] = 1; } } _arb_poly_mul(pow, poly2, len2, poly2, len2, prec); powlen = 2 * len2 - 1; for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) { if (hlen[1] > 0) { slong templen = powlen + hlen[1] - 1; _arb_poly_mul(temp, pow, powlen, h[1], hlen[1], prec); _arb_poly_add(h[0], temp, templen, h[0], hlen[0], prec); hlen[0] = FLINT_MAX(hlen[0], templen); } for (i = 1; i < n / 2; i++) { if (hlen[2*i + 1] > 0) { _arb_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1], prec); hlen[i] = hlen[2*i + 1] + powlen - 1; } else hlen[i] = 0; _arb_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i], prec); hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]); } if ((n & WORD(1))) { _arb_vec_set(h[i], h[2*i], hlen[2*i]); hlen[i] = hlen[2*i]; } _arb_poly_mul(temp, pow, powlen, pow, powlen, prec); powlen += powlen - 1; { arb_ptr t = pow; pow = temp; temp = t; } } _arb_poly_mul(res, pow, powlen, h[1], hlen[1], prec); _arb_vec_add(res, res, h[0], hlen[0], prec); _arb_vec_clear(v, alloc + 2 * powlen); flint_free(h); flint_free(hlen); } void arb_poly_compose_divconquer(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { const slong len1 = poly1->length; const slong len2 = poly2->length; if (len1 == 0) { arb_poly_zero(res); } else if (len1 == 1 || len2 == 0) { arb_poly_set_arb(res, poly1->coeffs); } else { const slong lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { arb_poly_fit_length(res, lenr); _arb_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); arb_poly_swap(res, t); arb_poly_clear(t); } _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } } arb-2.22.1/arb_poly/compose_horner.c000066400000000000000000000055401417376376500173660ustar00rootroot00000000000000/* Copyright (C) 2010 William Hart Copyright (C) 2012 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_compose_horner(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) { if (len1 == 1) { arb_set(res, poly1); } else if (len2 == 1) { _arb_poly_evaluate(res, poly1, len1, poly2, prec); } else if (len1 == 2) { _arb_vec_scalar_mul(res, poly2, len2, poly1 + 1, prec); arb_add(res, res, poly1, prec); } else { const slong alloc = (len1 - 1) * (len2 - 1) + 1; slong i = len1 - 1, lenr = len2; arb_ptr t, t1, t2; t = _arb_vec_init(alloc); if (len1 % 2 == 0) { t1 = res; t2 = t; } else { t1 = t; t2 = res; } /* Perform the first two steps as one, "res = a(m) * poly2 + a(m-1)". */ { _arb_vec_scalar_mul(t1, poly2, len2, poly1 + i, prec); i--; arb_add(t1 + 0, t1 + 0, poly1 + i, prec); } while (i--) { _arb_poly_mul(t2, t1, lenr, poly2, len2, prec); lenr += len2 - 1; { void *t_ = t1; t1 = t2; t2 = t_; } arb_add(t1 + 0, t1 + 0, poly1 + i, prec); } _arb_vec_clear(t, alloc); } } void arb_poly_compose_horner(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { const slong len1 = poly1->length; const slong len2 = poly2->length; if (len1 == 0) { arb_poly_zero(res); } else if (len1 == 1 || len2 == 0) { arb_poly_set_arb(res, poly1->coeffs); } else { const slong lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { arb_poly_fit_length(res, lenr); _arb_poly_compose_horner(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose_horner(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); arb_poly_swap(res, t); arb_poly_clear(t); } _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } } arb-2.22.1/arb_poly/compose_series.c000066400000000000000000000056241417376376500173660ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_compose_series(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) { if (len2 == 1) { arb_set_round(res, poly1, prec); _arb_vec_zero(res + 1, n - 1); } else if (_arb_vec_is_zero(poly2 + 1, len2 - 2)) /* poly2 is a monomial */ { slong i, j; arb_t t; arb_init(t); arb_set(t, poly2 + len2 - 1); arb_set_round(res, poly1, prec); for (i = 1, j = len2 - 1; i < len1 && j < n; i++, j += len2 - 1) { arb_mul(res + j, poly1 + i, t, prec); if (i + 1 < len1 && j + len2 - 1 < n) arb_mul(t, t, poly2 + len2 - 1, prec); } if (len2 != 2) for (i = 1; i < n; i++) if (i % (len2 - 1) != 0) arb_zero(res + i); arb_clear(t); } else if (len1 < 6 || n < 6) { _arb_poly_compose_series_horner(res, poly1, len1, poly2, len2, n, prec); } else { _arb_poly_compose_series_brent_kung(res, poly1, len1, poly2, len2, n, prec); } } void arb_poly_compose_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong len1 = poly1->length; slong len2 = poly2->length; slong lenr; if (len2 != 0 && !arb_is_zero(poly2->coeffs)) { flint_printf("exception: compose_series: inner " "polynomial must have zero constant term\n"); flint_abort(); } if (len1 == 0 || n == 0) { arb_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { arb_poly_set_arb(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { arb_poly_fit_length(res, lenr); _arb_poly_compose_series(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose_series(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(t, lenr); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } } arb-2.22.1/arb_poly/compose_series_brent_kung.c000066400000000000000000000062251417376376500216020ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "arb_mat.h" void _arb_poly_compose_series_brent_kung(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) { arb_mat_t A, B, C; arb_ptr t, h; slong i, m; if (n == 1) { arb_set(res, poly1); return; } m = n_sqrt(n) + 1; arb_mat_init(A, m, n); arb_mat_init(B, m, m); arb_mat_init(C, m, n); h = _arb_vec_init(n); t = _arb_vec_init(n); /* Set rows of B to the segments of poly1 */ for (i = 0; i < len1 / m; i++) _arb_vec_set(B->rows[i], poly1 + i*m, m); _arb_vec_set(B->rows[i], poly1 + i*m, len1 % m); /* Set rows of A to powers of poly2 */ arb_set_ui(A->rows[0] + 0, UWORD(1)); _arb_vec_set(A->rows[1], poly2, len2); for (i = 2; i < m; i++) _arb_poly_mullow(A->rows[i], A->rows[(i + 1) / 2], n, A->rows[i / 2], n, n, prec); arb_mat_mul(C, B, A, prec); /* Evaluate block composition using the Horner scheme */ _arb_vec_set(res, C->rows[m - 1], n); _arb_poly_mullow(h, A->rows[m - 1], n, poly2, len2, n, prec); for (i = m - 2; i >= 0; i--) { _arb_poly_mullow(t, res, n, h, n, n, prec); _arb_poly_add(res, t, n, C->rows[i], n, prec); } _arb_vec_clear(h, n); _arb_vec_clear(t, n); arb_mat_clear(A); arb_mat_clear(B); arb_mat_clear(C); } void arb_poly_compose_series_brent_kung(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong len1 = poly1->length; slong len2 = poly2->length; slong lenr; if (len2 != 0 && !arb_is_zero(poly2->coeffs)) { flint_printf("exception: compose_series: inner " "polynomial must have zero constant term\n"); flint_abort(); } if (len1 == 0 || n == 0) { arb_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { arb_poly_set_arb(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { arb_poly_fit_length(res, lenr); _arb_poly_compose_series_brent_kung(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose_series_brent_kung(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(t, lenr); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } } arb-2.22.1/arb_poly/compose_series_horner.c000066400000000000000000000054011417376376500207340ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_compose_series_horner(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) { if (n == 1) { arb_set(res, poly1); } else { slong i = len1 - 1; slong lenr; arb_ptr t = _arb_vec_init(n); lenr = len2; _arb_vec_scalar_mul(res, poly2, len2, poly1 + i, prec); i--; arb_add(res, res, poly1 + i, prec); while (i > 0) { i--; if (lenr + len2 - 1 < n) { _arb_poly_mul(t, res, lenr, poly2, len2, prec); lenr = lenr + len2 - 1; } else { _arb_poly_mullow(t, res, lenr, poly2, len2, n, prec); lenr = n; } _arb_poly_add(res, t, lenr, poly1 + i, 1, prec); } _arb_vec_zero(res + lenr, n - lenr); _arb_vec_clear(t, n); } } void arb_poly_compose_series_horner(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong len1 = poly1->length; slong len2 = poly2->length; slong lenr; if (len2 != 0 && !arb_is_zero(poly2->coeffs)) { flint_printf("exception: compose_series: inner " "polynomial must have zero constant term\n"); flint_abort(); } if (len1 == 0 || n == 0) { arb_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { arb_poly_set_arb(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { arb_poly_fit_length(res, lenr); _arb_poly_compose_series_horner(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose_series_horner(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(t, lenr); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } } arb-2.22.1/arb_poly/contains.c000066400000000000000000000014751417376376500161650ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int arb_poly_contains(const arb_poly_t poly1, const arb_poly_t poly2) { slong i; if (poly2->length > poly1->length) return 0; for (i = 0; i < poly2->length; i++) { if (!arb_contains(poly1->coeffs + i, poly2->coeffs + i)) return 0; } for (i = poly2->length; i < poly1->length; i++) if (!arb_contains_zero(poly1->coeffs + i)) return 0; return 1; } arb-2.22.1/arb_poly/contains_fmpq_poly.c000066400000000000000000000017201417376376500202440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int arb_poly_contains_fmpq_poly(const arb_poly_t poly1, const fmpq_poly_t poly2) { slong i; fmpq_t t; if (poly2->length > poly1->length) return 0; fmpq_init(t); for (i = 0; i < poly2->length; i++) { fmpq_poly_get_coeff_fmpq(t, poly2, i); if (!arb_contains_fmpq(poly1->coeffs + i, t)) { fmpq_clear(t); return 0; } } fmpq_clear(t); for (i = poly2->length; i < poly1->length; i++) if (!arb_contains_zero(poly1->coeffs + i)) return 0; return 1; } arb-2.22.1/arb_poly/contains_fmpz_poly.c000066400000000000000000000015021417376376500202530ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int arb_poly_contains_fmpz_poly(const arb_poly_t poly1, const fmpz_poly_t poly2) { slong i; if (poly2->length > poly1->length) return 0; for (i = 0; i < poly2->length; i++) if (!arb_contains_fmpz(poly1->coeffs + i, poly2->coeffs + i)) return 0; for (i = poly2->length; i < poly1->length; i++) if (!arb_contains_zero(poly1->coeffs + i)) return 0; return 1; } arb-2.22.1/arb_poly/cos_pi_series.c000066400000000000000000000027641417376376500171770ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_cos_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_cos_pi(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_sin_cos_pi(t, g, h, prec); arb_neg(t, t); arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ arb_const_pi(t, prec); arb_mul(g + 1, g + 1, t, prec); arb_clear(t); } else { arb_ptr t = _arb_vec_init(n); _arb_poly_sin_cos_pi_series(t, g, h, hlen, n, prec); _arb_vec_clear(t, n); } } void arb_poly_cos_pi_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_one(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_cos_pi_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/cos_series.c000066400000000000000000000026331417376376500165020ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_cos_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_cos(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_sin_cos(t, g, h, prec); arb_neg(t, t); arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t = _arb_vec_init(n); _arb_poly_sin_cos_series(t, g, h, hlen, n, prec); _arb_vec_clear(t, n); } } void arb_poly_cos_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_one(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_cos_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/cosh_series.c000066400000000000000000000026141417376376500166510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_cosh_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_cosh(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_sinh_cosh(t, g, h, prec); arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t = _arb_vec_init(n); _arb_poly_sinh_cosh_series(t, g, h, hlen, n, prec); _arb_vec_clear(t, n); } } void arb_poly_cosh_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_one(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_cosh_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/cot_pi_series.c000066400000000000000000000024231417376376500171700ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_cot_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_cot_pi(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u; t = _arb_vec_init(len); u = _arb_vec_init(len); _arb_poly_sin_cos_pi_series(t, u, h, hlen, len, prec); _arb_poly_div_series(g, u, len, t, len, len, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, len); } } void arb_poly_cot_pi_series(arb_poly_t res, const arb_poly_t f, slong len, slong prec) { arb_poly_fit_length(res, len); if (f->length == 0 || len == 0) _arb_vec_indeterminate(res->coeffs, len); else _arb_poly_cot_pi_series(res->coeffs, f->coeffs, f->length, len, prec); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/derivative.c000066400000000000000000000016371417376376500165110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_derivative(arb_ptr res, arb_srcptr poly, slong len, slong prec) { slong i; for (i = 1; i < len; i++) arb_mul_ui(res + i - 1, poly + i, i, prec); } void arb_poly_derivative(arb_poly_t res, const arb_poly_t poly, slong prec) { slong len = poly->length; if (len < 2) { arb_poly_zero(res); } else { arb_poly_fit_length(res, len - 1); _arb_poly_derivative(res->coeffs, poly->coeffs, len, prec); _arb_poly_set_length(res, len - 1); } } arb-2.22.1/arb_poly/digamma_series.c000066400000000000000000000114741417376376500173200ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec); void _arb_poly_gamma_stirling_eval2(arb_ptr res, const arb_t z, slong n, slong num, int diff, slong prec); void _arb_poly_digamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong i, r, n, rflen, wp; arb_t zr; arb_ptr t, u, v; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_digamma(res, h, prec); if (arb_is_finite(res)) _arb_vec_zero(res + 1, len - 1); else _arb_vec_indeterminate(res + 1, len - 1); return; } wp = prec + FLINT_BIT_COUNT(prec); t = _arb_vec_init(len + 1); u = _arb_vec_init(len + 1); v = _arb_vec_init(len + 1); arb_init(zr); /* use zeta values at small integers */ if (arb_is_int(h) && (arf_cmpabs_ui(arb_midref(h), prec / 2) < 0)) { r = arf_get_si(arb_midref(h), ARF_RND_DOWN); if (r <= 0) { _arb_vec_indeterminate(res, len); goto cleanup; } else if (r == 1) { arb_const_euler(u, prec); arb_zeta_ui_vec(u + 1, 2, len - 1, prec); for (i = 0; i < len; i += 2) arb_neg(u + i, u + i); } else { arb_one(v); arb_one(v + 1); rflen = FLINT_MIN(len + 1, r); _arb_poly_rising_ui_series(u, v, 2, r - 1, rflen, wp); _arb_poly_derivative(v, u, rflen, wp); _arb_poly_div_series(t, v, rflen - 1, u, rflen, len, wp); arb_const_euler(u, prec); arb_zeta_ui_vec(u + 1, 2, len - 1, prec); for (i = 0; i < len; i += 2) arb_neg(u + i, u + i); _arb_vec_add(u, u, t, len, wp); } } else { /* use Stirling series */ arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 1, wp); /* psi(x) = psi((1-x)+r) - h(1-x,r) - pi*cot(pi*x) */ if (reflect) { if (r != 0) /* otherwise t = 0 */ { arb_sub_ui(v, h, 1, wp); arb_neg(v, v); arb_one(v + 1); rflen = FLINT_MIN(len + 1, r + 1); _arb_poly_rising_ui_series(u, v, 2, r, rflen, wp); _arb_poly_derivative(v, u, rflen, wp); _arb_poly_div_series(t, v, rflen - 1, u, rflen, len, wp); for (i = 1; i < len; i += 2) arb_neg(t + i, t + i); } arb_sub_ui(zr, h, r + 1, wp); arb_neg(zr, zr); _arb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); for (i = 1; i < len; i += 2) arb_neg(u + i, u + i); _arb_vec_sub(u, u, t, len, wp); arb_set(t, h); arb_one(t + 1); _arb_poly_cot_pi_series(t, t, 2, len, wp); arb_const_pi(v, wp); _arb_vec_scalar_mul(t, t, len, v, wp); _arb_vec_sub(u, u, t, len, wp); } else { if (r == 0) { arb_add_ui(zr, h, r, wp); _arb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); } else { arb_set(v, h); arb_one(v + 1); rflen = FLINT_MIN(len + 1, r + 1); _arb_poly_rising_ui_series(u, v, 2, r, rflen, wp); _arb_poly_derivative(v, u, rflen, wp); _arb_poly_div_series(t, v, rflen - 1, u, rflen, len, wp); arb_add_ui(zr, h, r, wp); _arb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); _arb_vec_sub(u, u, t, len, wp); } } } /* compose with nonconstant part */ arb_zero(t); _arb_vec_set(t + 1, h + 1, hlen - 1); _arb_poly_compose_series(res, u, len, t, hlen, len, prec); cleanup: arb_clear(zr); _arb_vec_clear(t, len + 1); _arb_vec_clear(u, len + 1); _arb_vec_clear(v, len + 1); } void arb_poly_digamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { arb_poly_fit_length(res, n); if (f->length == 0 || n == 0) _arb_vec_indeterminate(res->coeffs, n); else _arb_poly_digamma_series(res->coeffs, f->coeffs, f->length, n, prec); _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/div_root.c000066400000000000000000000021321417376376500161630ustar00rootroot00000000000000/* Copyright (C) 2011 William Hart Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_div_root(arb_ptr Q, arb_t R, arb_srcptr A, slong len, const arb_t c, slong prec) { arb_t r, t; slong i; if (len < 2) { arb_zero(R); return; } arb_init(r); arb_init(t); arb_set(t, A + len - 2); arb_set(Q + len - 2, A + len - 1); arb_set(r, Q + len - 2); /* TODO: avoid the extra assignments (but still support aliasing) */ for (i = len - 2; i > 0; i--) { arb_mul(r, r, c, prec); arb_add(r, r, t, prec); arb_set(t, A + i - 1); arb_set(Q + i - 1, r); } arb_mul(r, r, c, prec); arb_add(R, r, t, prec); arb_clear(r); arb_clear(t); } arb-2.22.1/arb_poly/div_series.c000066400000000000000000000053361417376376500165030ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_div_series(arb_ptr Q, arb_srcptr A, slong Alen, arb_srcptr B, slong Blen, slong n, slong prec) { Alen = FLINT_MIN(Alen, n); Blen = FLINT_MIN(Blen, n); if (Blen == 1) { _arb_vec_scalar_div(Q, A, Alen, B, prec); _arb_vec_zero(Q + Alen, n - Alen); } else if (n == 2) { if (Alen == 1) { arb_div(Q, A, B, prec); arb_div(Q + 1, Q, B, prec); arb_mul(Q + 1, Q + 1, B + 1, prec); arb_neg(Q + 1, Q + 1); } else { arb_div(Q, A, B, prec); arb_mul(Q + 1, Q, B + 1, prec); arb_sub(Q + 1, A + 1, Q + 1, prec); arb_div(Q + 1, Q + 1, B, prec); } } else if (Blen == 2 || n <= 10) { /* The basecase algorithm is faster for much larger Blen and n than this, but unfortunately has worse numerical stability. */ slong i; arb_t q; arb_init(q); arb_inv(q, B, prec); arb_div(Q, A, B, prec); for (i = 1; i < n; i++) { arb_dot(Q + i, (i < Alen) ? A + i : NULL, 1, B + 1, 1, Q + i - 1, -1, FLINT_MIN(i, Blen - 1), prec); if (!arb_is_one(q)) arb_mul(Q + i, Q + i, q, prec); } arb_clear(q); } else { arb_ptr Binv; Binv = _arb_vec_init(n); _arb_poly_inv_series(Binv, B, Blen, n, prec); _arb_poly_mullow(Q, Binv, n, A, Alen, n, prec); _arb_vec_clear(Binv, n); } } void arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, slong n, slong prec) { if (n == 0) { arb_poly_zero(Q); return; } if (B->length == 0) { arb_poly_fit_length(Q, n); _arb_vec_indeterminate(Q->coeffs, n); _arb_poly_set_length(Q, n); return; } if (A->length == 0) { arb_poly_zero(Q); return; } if (Q == A || Q == B) { arb_poly_t t; arb_poly_init(t); arb_poly_div_series(t, A, B, n, prec); arb_poly_swap(Q, t); arb_poly_clear(t); return; } arb_poly_fit_length(Q, n); _arb_poly_div_series(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, n, prec); _arb_poly_set_length(Q, n); _arb_poly_normalise(Q); } arb-2.22.1/arb_poly/divrem.c000066400000000000000000000056661417376376500156430ustar00rootroot00000000000000/* Copyright (C) 2011 William Hart Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* TODO: tighten this code */ void _arb_poly_div(arb_ptr Q, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) { slong lenQ, lenB2; arb_ptr Arev, Brev; lenQ = lenA - lenB + 1; Arev = _arb_vec_init(2 * lenQ); Brev = Arev + lenQ; _arb_poly_reverse(Arev, A + (lenA - lenQ), lenQ, lenQ); if (lenB >= lenQ) { _arb_poly_reverse(Brev, B + (lenB - lenQ), lenQ, lenQ); lenB2 = lenQ; } else { _arb_poly_reverse(Brev, B, lenB, lenB); lenB2 = lenB; } _arb_poly_div_series(Q, Arev, lenQ, Brev, lenB2, lenQ, prec); _arb_poly_reverse(Q, Q, lenQ, lenQ); _arb_vec_clear(Arev, 2 * lenQ); } void _arb_poly_divrem(arb_ptr Q, arb_ptr R, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) { const slong lenQ = lenA - lenB + 1; _arb_poly_div(Q, A, lenA, B, lenB, prec); if (lenB > 1) { if (lenQ >= lenB - 1) _arb_poly_mullow(R, Q, lenQ, B, lenB - 1, lenB - 1, prec); else _arb_poly_mullow(R, B, lenB - 1, Q, lenQ, lenB - 1, prec); _arb_vec_sub(R, A, R, lenB - 1, prec); } } void _arb_poly_rem(arb_ptr R, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) { const slong lenQ = lenA - lenB + 1; arb_ptr Q = _arb_vec_init(lenQ); _arb_poly_divrem(Q, R, A, lenA, B, lenB, prec); _arb_vec_clear(Q, lenQ); } int arb_poly_divrem(arb_poly_t Q, arb_poly_t R, const arb_poly_t A, const arb_poly_t B, slong prec) { const slong lenA = A->length, lenB = B->length; if (lenB == 0 || arb_contains_zero(B->coeffs + lenB - 1)) { return 0; } if (lenA < lenB) { arb_poly_set(R, A); arb_poly_zero(Q); return 1; } if (Q == A || Q == B) { arb_poly_t T; arb_poly_init(T); arb_poly_divrem(T, R, A, B, prec); arb_poly_swap(Q, T); arb_poly_clear(T); return 1; } if (R == A || R == B) { arb_poly_t U; arb_poly_init(U); arb_poly_divrem(Q, U, A, B, prec); arb_poly_swap(R, U); arb_poly_clear(U); return 1; } arb_poly_fit_length(Q, lenA - lenB + 1); arb_poly_fit_length(R, lenB - 1); _arb_poly_divrem(Q->coeffs, R->coeffs, A->coeffs, lenA, B->coeffs, lenB, prec); _arb_poly_set_length(Q, lenA - lenB + 1); _arb_poly_set_length(R, lenB - 1); _arb_poly_normalise(R); return 1; } arb-2.22.1/arb_poly/equal.c000066400000000000000000000012221417376376500154440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int arb_poly_equal(const arb_poly_t A, const arb_poly_t B) { slong i; if (A->length != B->length) return 0; for (i = 0; i < A->length; i++) if (!arb_equal(A->coeffs + i, B->coeffs + i)) return 0; return 1; } arb-2.22.1/arb_poly/evaluate.c000066400000000000000000000017321417376376500161510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate(arb_t res, arb_srcptr f, slong len, const arb_t x, slong prec) { if ((prec >= 1024) && (len >= 5 + 20000 / prec)) { slong fbits; fbits = _arb_vec_bits(f, len); if (fbits <= prec / 2) { _arb_poly_evaluate_rectangular(res, f, len, x, prec); return; } } _arb_poly_evaluate_horner(res, f, len, x, prec); } void arb_poly_evaluate(arb_t res, const arb_poly_t f, const arb_t a, slong prec) { _arb_poly_evaluate(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate2.c000066400000000000000000000017251417376376500162350ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate2(arb_t y, arb_t z, arb_srcptr f, slong len, const arb_t x, slong prec) { if ((prec >= 1024) && (len >= 5 + 20000 / prec)) { slong fbits; fbits = _arb_vec_bits(f, len); if (fbits <= prec / 2) { _arb_poly_evaluate2_rectangular(y, z, f, len, x, prec); return; } } _arb_poly_evaluate2_horner(y, z, f, len, x, prec); } void arb_poly_evaluate2(arb_t r, arb_t s, const arb_poly_t f, const arb_t a, slong prec) { _arb_poly_evaluate2(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate2_acb.c000066400000000000000000000013371417376376500170410ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate2_acb(acb_t y, acb_t z, arb_srcptr f, slong len, const acb_t x, slong prec) { _arb_poly_evaluate2_acb_rectangular(y, z, f, len, x, prec); } void arb_poly_evaluate2_acb(acb_t r, acb_t s, const arb_poly_t f, const acb_t a, slong prec) { _arb_poly_evaluate2_acb(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate2_acb_horner.c000066400000000000000000000032471417376376500204200ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate2_acb_horner(acb_t y, acb_t z, arb_srcptr poly, slong len, const acb_t x, slong prec) { if (len == 0) { acb_zero(y); acb_zero(z); } else if (len == 1) { acb_set_round_arb(y, poly + 0, prec); acb_zero(z); } else if (acb_is_zero(x)) { acb_set_round_arb(y, poly + 0, prec); acb_set_round_arb(z, poly + 1, prec); } else if (len == 2) { acb_mul_arb(y, x, poly + 1, prec); acb_add_arb(y, y, poly + 0, prec); acb_set_round_arb(z, poly + 1, prec); } else { acb_t t, u, v; slong i; acb_init(t); acb_init(u); acb_init(v); acb_set_round_arb(u, poly + len - 1, prec); acb_zero(v); for (i = len - 2; i >= 0; i--) { acb_mul(t, v, x, prec); acb_add(v, u, t, prec); acb_mul(t, u, x, prec); acb_add_arb(u, t, poly + i, prec); } acb_swap(y, u); acb_swap(z, v); acb_clear(t); acb_clear(u); acb_clear(v); } } void arb_poly_evaluate2_acb_horner(acb_t r, acb_t s, const arb_poly_t f, const acb_t a, slong prec) { _arb_poly_evaluate2_acb_horner(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate2_acb_rectangular.c000066400000000000000000000051611417376376500214270ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate2_acb_rectangular(acb_t y, acb_t z, arb_srcptr poly, slong len, const acb_t x, slong prec) { slong i, j, m, r; acb_ptr xs; acb_t s, t; arb_t c; if (len < 3) { if (len == 0) { acb_zero(y); acb_zero(z); } else if (len == 1) { acb_set_round_arb(y, poly + 0, prec); acb_zero(z); } else if (len == 2) { acb_mul_arb(y, x, poly + 1, prec); acb_add_arb(y, y, poly + 0, prec); acb_set_round_arb(z, poly + 1, prec); } return; } m = n_sqrt(len) + 1; m *= 1; r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); arb_init(c); _acb_vec_set_powers(xs, x, m + 1, prec); acb_set_arb(y, poly + (r - 1) * m); for (j = 1; (r - 1) * m + j < len; j++) acb_addmul_arb(y, xs + j, poly + (r - 1) * m + j, prec); for (i = r - 2; i >= 0; i--) { acb_set_arb(s, poly + i * m); for (j = 1; j < m; j++) acb_addmul_arb(s, xs + j, poly + i * m + j, prec); acb_mul(y, y, xs + m, prec); acb_add(y, y, s, prec); } len -= 1; r = (len + m - 1) / m; arb_mul_ui(acb_realref(z), poly + (r - 1) * m + 1, (r - 1) * m + 1, ARF_PREC_EXACT); arb_zero(acb_imagref(z)); for (j = 1; (r - 1) * m + j < len; j++) { arb_mul_ui(c, poly + (r - 1) * m + j + 1, (r - 1) * m + j + 1, ARF_PREC_EXACT); acb_addmul_arb(z, xs + j, c, prec); } for (i = r - 2; i >= 0; i--) { arb_mul_ui(acb_realref(s), poly + i * m + 1, i * m + 1, ARF_PREC_EXACT); arb_zero(acb_imagref(s)); for (j = 1; j < m; j++) { arb_mul_ui(c, poly + i * m + j + 1, i * m + j + 1, ARF_PREC_EXACT); acb_addmul_arb(s, xs + j, c, prec); } acb_mul(z, z, xs + m, prec); acb_add(z, z, s, prec); } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); arb_clear(c); } void arb_poly_evaluate2_acb_rectangular(acb_t r, acb_t s, const arb_poly_t f, const acb_t a, slong prec) { _arb_poly_evaluate2_acb_rectangular(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate2_horner.c000066400000000000000000000031771417376376500176150ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate2_horner(arb_t y, arb_t z, arb_srcptr poly, slong len, const arb_t x, slong prec) { if (len == 0) { arb_zero(y); arb_zero(z); } else if (len == 1) { arb_set_round(y, poly + 0, prec); arb_zero(z); } else if (arb_is_zero(x)) { arb_set_round(y, poly + 0, prec); arb_set_round(z, poly + 1, prec); } else if (len == 2) { arb_mul(y, x, poly + 1, prec); arb_add(y, y, poly + 0, prec); arb_set_round(z, poly + 1, prec); } else { arb_t t, u, v; slong i; arb_init(t); arb_init(u); arb_init(v); arb_set_round(u, poly + len - 1, prec); arb_zero(v); for (i = len - 2; i >= 0; i--) { arb_mul(t, v, x, prec); arb_add(v, u, t, prec); arb_mul(t, u, x, prec); arb_add(u, t, poly + i, prec); } arb_swap(y, u); arb_swap(z, v); arb_clear(t); arb_clear(u); arb_clear(v); } } void arb_poly_evaluate2_horner(arb_t r, arb_t s, const arb_poly_t f, const arb_t a, slong prec) { _arb_poly_evaluate2_horner(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate2_rectangular.c000066400000000000000000000047041417376376500206240ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate2_rectangular(arb_t y, arb_t z, arb_srcptr poly, slong len, const arb_t x, slong prec) { slong i, j, m, r; arb_ptr xs; arb_t s, t, c; if (len < 3) { if (len == 0) { arb_zero(y); arb_zero(z); } else if (len == 1) { arb_set_round(y, poly + 0, prec); arb_zero(z); } else if (len == 2) { arb_mul(y, x, poly + 1, prec); arb_add(y, y, poly + 0, prec); arb_set_round(z, poly + 1, prec); } return; } m = n_sqrt(len) + 1; m *= 1; r = (len + m - 1) / m; xs = _arb_vec_init(m + 1); arb_init(s); arb_init(t); arb_init(c); _arb_vec_set_powers(xs, x, m + 1, prec); arb_dot(y, poly + (r - 1) * m, 0, xs + 1, 1, poly + (r - 1) * m + 1, 1, len - (r - 1) * m - 1, prec); for (i = r - 2; i >= 0; i--) { arb_dot(s, poly + i * m, 0, xs + 1, 1, poly + i * m + 1, 1, m - 1, prec); arb_mul(y, y, xs + m, prec); arb_add(y, y, s, prec); } /* todo: rewrite using arb_dot */ len -= 1; r = (len + m - 1) / m; arb_mul_ui(z, poly + (r - 1) * m + 1, (r - 1) * m + 1, ARF_PREC_EXACT); for (j = 1; (r - 1) * m + j < len; j++) { arb_mul_ui(c, poly + (r - 1) * m + j + 1, (r - 1) * m + j + 1, ARF_PREC_EXACT); arb_addmul(z, xs + j, c, prec); } for (i = r - 2; i >= 0; i--) { arb_mul_ui(s, poly + i * m + 1, i * m + 1, ARF_PREC_EXACT); for (j = 1; j < m; j++) { arb_mul_ui(c, poly + i * m + j + 1, i * m + j + 1, ARF_PREC_EXACT); arb_addmul(s, xs + j, c, prec); } arb_mul(z, z, xs + m, prec); arb_add(z, z, s, prec); } _arb_vec_clear(xs, m + 1); arb_clear(s); arb_clear(t); arb_clear(c); } void arb_poly_evaluate2_rectangular(arb_t r, arb_t s, const arb_poly_t f, const arb_t a, slong prec) { _arb_poly_evaluate2_rectangular(r, s, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate_acb.c000066400000000000000000000013461417376376500167570ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate_acb(acb_t res, arb_srcptr f, slong len, const acb_t x, slong prec) { _arb_poly_evaluate_acb_rectangular(res, f, len, x, prec); } void arb_poly_evaluate_acb(acb_t res, const arb_poly_t f, const acb_t a, slong prec) { _arb_poly_evaluate_acb(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate_acb_horner.c000066400000000000000000000025071417376376500203340ustar00rootroot00000000000000/* Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate_acb_horner(acb_t y, arb_srcptr f, slong len, const acb_t x, slong prec) { if (len == 0) { acb_zero(y); } else if (len == 1 || acb_is_zero(x)) { acb_set_round_arb(y, f, prec); } else if (len == 2) { acb_mul_arb(y, x, f + 1, prec); acb_add_arb(y, y, f + 0, prec); } else { slong i = len - 1; acb_t t, u; acb_init(t); acb_init(u); acb_set_arb(u, f + i); for (i = len - 2; i >= 0; i--) { acb_mul(t, u, x, prec); acb_add_arb(u, t, f + i, prec); } acb_swap(y, u); acb_clear(t); acb_clear(u); } } void arb_poly_evaluate_acb_horner(acb_t res, const arb_poly_t f, const acb_t a, slong prec) { _arb_poly_evaluate_acb_horner(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate_acb_rectangular.c000066400000000000000000000033511417376376500213440ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate_acb_rectangular(acb_t y, arb_srcptr poly, slong len, const acb_t x, slong prec) { slong i, j, m, r; acb_ptr xs; acb_t s, t, c; if (len < 3) { if (len == 0) { acb_zero(y); } else if (len == 1) { acb_set_round_arb(y, poly + 0, prec); } else if (len == 2) { acb_mul_arb(y, x, poly + 1, prec); acb_add_arb(y, y, poly + 0, prec); } return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); acb_init(c); _acb_vec_set_powers(xs, x, m + 1, prec); acb_set_arb(y, poly + (r - 1) * m); for (j = 1; (r - 1) * m + j < len; j++) acb_addmul_arb(y, xs + j, poly + (r - 1) * m + j, prec); for (i = r - 2; i >= 0; i--) { acb_set_arb(s, poly + i * m); for (j = 1; j < m; j++) acb_addmul_arb(s, xs + j, poly + i * m + j, prec); acb_mul(y, y, xs + m, prec); acb_add(y, y, s, prec); } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); acb_clear(c); } void arb_poly_evaluate_acb_rectangular(acb_t res, const arb_poly_t f, const acb_t a, slong prec) { _arb_poly_evaluate_acb_rectangular(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate_horner.c000066400000000000000000000024471417376376500175320ustar00rootroot00000000000000/* Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate_horner(arb_t y, arb_srcptr f, slong len, const arb_t x, slong prec) { if (len == 0) { arb_zero(y); } else if (len == 1 || arb_is_zero(x)) { arb_set_round(y, f, prec); } else if (len == 2) { arb_mul(y, x, f + 1, prec); arb_add(y, y, f + 0, prec); } else { slong i = len - 1; arb_t t, u; arb_init(t); arb_init(u); arb_set(u, f + i); for (i = len - 2; i >= 0; i--) { arb_mul(t, u, x, prec); arb_add(u, f + i, t, prec); } arb_swap(y, u); arb_clear(t); arb_clear(u); } } void arb_poly_evaluate_horner(arb_t res, const arb_poly_t f, const arb_t a, slong prec) { _arb_poly_evaluate_horner(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate_rectangular.c000066400000000000000000000032031417376376500205330ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate_rectangular(arb_t y, arb_srcptr poly, slong len, const arb_t x, slong prec) { slong i, m, r; arb_ptr xs; arb_t s, t, c; if (len < 3) { if (len == 0) { arb_zero(y); } else if (len == 1) { arb_set_round(y, poly + 0, prec); } else if (len == 2) { arb_mul(y, x, poly + 1, prec); arb_add(y, y, poly + 0, prec); } return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _arb_vec_init(m + 1); arb_init(s); arb_init(t); arb_init(c); _arb_vec_set_powers(xs, x, m + 1, prec); arb_dot(y, poly + (r - 1) * m, 0, xs + 1, 1, poly + (r - 1) * m + 1, 1, len - (r - 1) * m - 1, prec); for (i = r - 2; i >= 0; i--) { arb_dot(s, poly + i * m, 0, xs + 1, 1, poly + i * m + 1, 1, m - 1, prec); arb_mul(y, y, xs + m, prec); arb_add(y, y, s, prec); } _arb_vec_clear(xs, m + 1); arb_clear(s); arb_clear(t); arb_clear(c); } void arb_poly_evaluate_rectangular(arb_t res, const arb_poly_t f, const arb_t a, slong prec) { _arb_poly_evaluate_rectangular(res, f->coeffs, f->length, a, prec); } arb-2.22.1/arb_poly/evaluate_vec_fast.c000066400000000000000000000067131417376376500200270ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* This gives some speedup for small lengths. */ static __inline__ void _arb_poly_rem_2(arb_ptr r, arb_srcptr a, slong al, arb_srcptr b, slong bl, slong prec) { if (al == 2) { arb_mul(r + 0, a + 1, b + 0, prec); arb_sub(r + 0, a + 0, r + 0, prec); } else { _arb_poly_rem(r, a, al, b, bl, prec); } } void _arb_poly_evaluate_vec_fast_precomp(arb_ptr vs, arb_srcptr poly, slong plen, arb_ptr * tree, slong len, slong prec) { slong height, i, j, pow, left; slong tree_height; slong tlen; arb_ptr t, u, swap, pa, pb, pc; /* avoid worrying about some degenerate cases */ if (len < 2 || plen < 2) { if (len == 1) { arb_t tmp; arb_init(tmp); arb_neg(tmp, tree[0] + 0); _arb_poly_evaluate(vs + 0, poly, plen, tmp, prec); arb_clear(tmp); } else if (len != 0 && plen == 0) { _arb_vec_zero(vs, len); } else if (len != 0 && plen == 1) { for (i = 0; i < len; i++) arb_set(vs + i, poly + 0); } return; } t = _arb_vec_init(len); u = _arb_vec_init(len); left = len; /* Initial reduction. We allow the polynomial to be larger or smaller than the number of points. */ height = FLINT_BIT_COUNT(plen - 1) - 1; tree_height = FLINT_CLOG2(len); while (height >= tree_height) height--; pow = WORD(1) << height; for (i = j = 0; i < len; i += pow, j += (pow + 1)) { tlen = ((i + pow) <= len) ? pow : len % pow; _arb_poly_rem(t + i, poly, plen, tree[height] + j, tlen + 1, prec); } for (i = height - 1; i >= 0; i--) { pow = WORD(1) << i; left = len; pa = tree[i]; pb = t; pc = u; while (left >= 2 * pow) { _arb_poly_rem_2(pc, pb, 2 * pow, pa, pow + 1, prec); _arb_poly_rem_2(pc + pow, pb, 2 * pow, pa + pow + 1, pow + 1, prec); pa += 2 * pow + 2; pb += 2 * pow; pc += 2 * pow; left -= 2 * pow; } if (left > pow) { _arb_poly_rem(pc, pb, left, pa, pow + 1, prec); _arb_poly_rem(pc + pow, pb, left, pa + pow + 1, left - pow + 1, prec); } else if (left > 0) _arb_vec_set(pc, pb, left); swap = t; t = u; u = swap; } _arb_vec_set(vs, t, len); _arb_vec_clear(t, len); _arb_vec_clear(u, len); } void _arb_poly_evaluate_vec_fast(arb_ptr ys, arb_srcptr poly, slong plen, arb_srcptr xs, slong n, slong prec) { arb_ptr * tree; tree = _arb_poly_tree_alloc(n); _arb_poly_tree_build(tree, xs, n, prec); _arb_poly_evaluate_vec_fast_precomp(ys, poly, plen, tree, n, prec); _arb_poly_tree_free(tree, n); } void arb_poly_evaluate_vec_fast(arb_ptr ys, const arb_poly_t poly, arb_srcptr xs, slong n, slong prec) { _arb_poly_evaluate_vec_fast(ys, poly->coeffs, poly->length, xs, n, prec); } arb-2.22.1/arb_poly/evaluate_vec_iter.c000066400000000000000000000015331417376376500200300ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_evaluate_vec_iter(arb_ptr ys, arb_srcptr poly, slong plen, arb_srcptr xs, slong n, slong prec) { slong i; for (i = 0; i < n; i++) _arb_poly_evaluate(ys + i, poly, plen, xs + i, prec); } void arb_poly_evaluate_vec_iter(arb_ptr ys, const arb_poly_t poly, arb_srcptr xs, slong n, slong prec) { _arb_poly_evaluate_vec_iter(ys, poly->coeffs, poly->length, xs, n, prec); } arb-2.22.1/arb_poly/exp_series.c000066400000000000000000000116711417376376500165140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* allow changing this from the test code */ ARB_DLL slong arb_poly_newton_exp_cutoff = 0; /* with inverse=1 simultaneously computes g = exp(-x) to length n with inverse=0 uses g as scratch space, computing g = exp(-x) only to length (n+1)/2 */ static void _arb_poly_exp_series_newton(arb_ptr f, arb_ptr g, arb_srcptr h, slong len, slong prec, int inverse, slong cutoff) { slong alloc; arb_ptr T, U, hprime; alloc = 3 * len; T = _arb_vec_init(alloc); U = T + len; hprime = U + len; _arb_poly_derivative(hprime, h, len, prec); arb_zero(hprime + len - 1); NEWTON_INIT(cutoff, len) /* f := exp(h) + O(x^m), g := exp(-h) + O(x^m2) */ NEWTON_BASECASE(n) _arb_poly_exp_series_basecase(f, h, n, n, prec); _arb_poly_inv_series(g, f, (n + 1) / 2, (n + 1) / 2, prec); NEWTON_END_BASECASE /* extend from length m to length n */ NEWTON_LOOP(m, n) slong m2 = (m + 1) / 2; slong l = m - 1; /* shifted for derivative */ /* g := exp(-h) + O(x^m) */ _arb_poly_mullow(T, f, m, g, m2, m, prec); _arb_poly_mullow(g + m2, g, m2, T + m2, m - m2, m - m2, prec); _arb_vec_neg(g + m2, g + m2, m - m2); /* U := h' + g (f' - f h') + O(x^(n-1)) Note: should replace h' by h' mod x^(m-1) */ _arb_vec_zero(f + m, n - m); _arb_poly_mullow(T, f, n, hprime, n, n, prec); /* should be mulmid */ _arb_poly_derivative(U, f, n, prec); arb_zero(U + n - 1); /* should skip low terms */ _arb_vec_sub(U + l, U + l, T + l, n - l, prec); _arb_poly_mullow(T + l, g, n - m, U + l, n - m, n - m, prec); _arb_vec_add(U + l, hprime + l, T + l, n - m, prec); /* f := f + f * (h - int U) + O(x^n) = exp(h) + O(x^n) */ _arb_poly_integral(U, U, n, prec); /* should skip low terms */ _arb_vec_sub(U + m, h + m, U + m, n - m, prec); _arb_poly_mullow(f + m, f, n - m, U + m, n - m, n - m, prec); /* g := exp(-h) + O(x^n) */ /* not needed if we only want exp(x) */ if (n == len && inverse) { _arb_poly_mullow(T, f, n, g, m, n, prec); _arb_poly_mullow(g + m, g, m, T + m, n - m, n - m, prec); _arb_vec_neg(g + m, g + m, n - m); } NEWTON_END_LOOP NEWTON_END _arb_vec_clear(T, alloc); } void _arb_poly_exp_series(arb_ptr f, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_exp(f, h, prec); _arb_vec_zero(f + 1, n - 1); } else if (n == 2) { arb_exp(f, h, prec); arb_mul(f + 1, f, h + 1, prec); /* safe since hlen >= 2 */ } else if (_arb_vec_is_zero(h + 1, hlen - 2)) /* h = a + bx^d */ { slong i, j, d = hlen - 1; arb_t t; arb_init(t); arb_set(t, h + d); arb_exp(f, h, prec); for (i = 1, j = d; j < n; j += d, i++) { arb_mul(f + j, f + j - d, t, prec); arb_div_ui(f + j, f + j, i, prec); _arb_vec_zero(f + j - d + 1, hlen - 2); } _arb_vec_zero(f + j - d + 1, n - (j - d + 1)); arb_clear(t); } else { slong cutoff; if (arb_poly_newton_exp_cutoff != 0) cutoff = arb_poly_newton_exp_cutoff; else if (prec <= 256) cutoff = 750; else cutoff = 1e5 / pow(log(prec), 3); if (hlen <= cutoff) { _arb_poly_exp_series_basecase(f, h, hlen, n, prec); } else { arb_ptr g, t; arb_t u; int fix; g = _arb_vec_init((n + 1) / 2); fix = (hlen < n || h == f || !arb_is_zero(h)); if (fix) { t = _arb_vec_init(n); _arb_vec_set(t + 1, h + 1, hlen - 1); } else t = (arb_ptr) h; arb_init(u); arb_exp(u, h, prec); _arb_poly_exp_series_newton(f, g, t, n, prec, 0, cutoff); if (!arb_is_one(u)) _arb_vec_scalar_mul(f, f, n, u, prec); _arb_vec_clear(g, (n + 1) / 2); if (fix) _arb_vec_clear(t, n); arb_clear(u); } } } void arb_poly_exp_series(arb_poly_t f, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(f); return; } if (hlen == 0) { arb_poly_one(f); return; } if (hlen == 1) n = 1; arb_poly_fit_length(f, n); _arb_poly_exp_series(f->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(f, n); _arb_poly_normalise(f); } arb-2.22.1/arb_poly/exp_series_basecase.c000066400000000000000000000044351417376376500203420ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" static void _arb_poly_exp_series_basecase_rec(arb_ptr f, arb_ptr a, arb_srcptr h, slong hlen, slong n, slong prec) { slong k; arb_t s; arb_init(s); arb_exp(f, h, prec); for (k = 1; k < hlen; k++) arb_mul_ui(a + k, h + k, k, prec); for (k = 1; k < n; k++) { arb_dot(s, NULL, 0, a + 1, 1, f + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); arb_div_ui(f + k, s, k, prec); } arb_clear(s); } void _arb_poly_exp_series_basecase(arb_ptr f, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(n, hlen); if (n < 20 || hlen < 0.9 * n || prec <= 2 * FLINT_BITS || n < 1000.0 / log(prec + 10) - 70) { arb_ptr t = _arb_vec_init(hlen); _arb_poly_exp_series_basecase_rec(f, t, h, hlen, n, prec); _arb_vec_clear(t, hlen); } else { slong m, v; arb_ptr t, u; m = (n + 2) / 3; v = m * 2; t = _arb_vec_init(n); u = _arb_vec_init(n - m); _arb_poly_mullow(t, h + m, hlen - m, h + m, hlen - m, n - v, prec); _arb_vec_scalar_mul_2exp_si(t, t, n - v, -1); _arb_vec_set(u, h + m, v - m); _arb_poly_add(u + v - m, t, n - v, h + v, hlen - v, prec); _arb_poly_exp_series_basecase_rec(f, t, h, m, n, prec); _arb_poly_mullow(t, f, n, u, n - m, n - m, prec); _arb_poly_add(f + m, f + m, n - m, t, n - m, prec); _arb_vec_clear(t, n); _arb_vec_clear(u, n - m); } } void arb_poly_exp_series_basecase(arb_poly_t f, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(f); return; } if (hlen == 0) { arb_poly_one(f); return; } arb_poly_fit_length(f, n); _arb_poly_exp_series_basecase(f->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(f, n); _arb_poly_normalise(f); } arb-2.22.1/arb_poly/fit_length.c000066400000000000000000000014231417376376500164630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_fit_length(arb_poly_t poly, slong len) { slong i; if (len > poly->alloc) { if (len < 2 * poly->alloc) len = 2 * poly->alloc; poly->coeffs = flint_realloc(poly->coeffs, len * sizeof(arb_struct)); for (i = poly->alloc; i < len; i++) arb_init(poly->coeffs + i); poly->alloc = len; } } arb-2.22.1/arb_poly/fprintd.c000066400000000000000000000015141417376376500160070ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_fprintd(FILE * file, const arb_poly_t poly, slong digits) { slong i; flint_fprintf(file, "["); for (i = 0; i < poly->length; i++) { flint_fprintf(file, "("); arb_fprintd(file, poly->coeffs + i, digits); flint_fprintf(file, ")"); if (i + 1 < poly->length) flint_fprintf(file, ", "); } flint_fprintf(file, "]"); } arb-2.22.1/arb_poly/gamma_series.c000066400000000000000000000240701417376376500167770ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_gamma_stirling_bound(mag_ptr err, const arb_t x, slong k0, slong knum, slong n); void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec); void arb_gamma_stirling_coeff(arb_t b, ulong k, int digamma, slong prec); void _arb_poly_lgamma_series_at_one(arb_ptr u, slong len, slong prec) { slong i; if (len > 0) arb_zero(u); if (len > 1) arb_const_euler(u + 1, prec); if (len > 2) arb_zeta_ui_vec(u + 2, 2, len - 2, prec); for (i = 2; i < len; i++) arb_div_ui(u + i, u + i, i, prec); for (i = 1; i < len; i += 2) arb_neg(u + i, u + i); } static void bsplit(arb_ptr Q, arb_ptr T, const arb_t z, slong a, slong b, slong num, slong prec) { if (b - a == 1) { arb_gamma_stirling_coeff(T, a, 0, prec); if (a == 1) { /* (z + t) */ arb_set(Q, z); if (num > 1) arb_one(Q + 1); if (num > 2) arb_zero(Q + 2); } else { /* (z + t)^2 */ arb_mul(Q, z, z, prec); /* TODO: precompute */ if (num > 1) arb_mul_2exp_si(Q + 1, z, 1); if (num > 2) arb_one(Q + 2); } } else { slong m, n1, n2, q1len, q2len, t1len, t2len, qlen, tlen, alloc; arb_ptr Q1, T1, Q2, T2; m = a + (b - a) / 2; n1 = m - a; n2 = b - m; q1len = FLINT_MIN(2 * n1 + 1, num); t1len = FLINT_MIN(2 * n1 - 1, num); q2len = FLINT_MIN(2 * n2 + 1, num); t2len = FLINT_MIN(2 * n2 - 1, num); qlen = FLINT_MIN(q1len + q2len - 1, num); tlen = FLINT_MIN(t1len + q2len - 1, num); alloc = q1len + q2len + t1len + t2len; Q1 = _arb_vec_init(alloc); Q2 = Q1 + q1len; T1 = Q2 + q2len; T2 = T1 + t1len; bsplit(Q1, T1, z, a, m, num, prec); bsplit(Q2, T2, z, m, b, num, prec); _arb_poly_mullow(Q, Q2, q2len, Q1, q1len, qlen, prec); _arb_poly_mullow(T, Q2, q2len, T1, t1len, tlen, prec); _arb_poly_add(T, T, tlen, T2, t2len, prec); _arb_vec_clear(Q1, alloc); } } void _arb_poly_mullow_cpx(arb_ptr res, arb_srcptr src, slong len, const arb_t c, slong trunc, slong prec) { slong i; if (len < trunc) arb_set(res + len, src + len - 1); for (i = len - 1; i > 0; i--) { arb_mul(res + i, src + i, c, prec); arb_add(res + i, res + i, src + i - 1, prec); } arb_mul(res, src, c, prec); } void _arb_poly_log_cpx_series(arb_ptr res, const arb_t c, slong num, slong prec) { slong i; for (i = 0; i < num; i++) { if (i == 0) arb_log(res + i, c, prec); else if (i == 1) arb_inv(res + i, c, prec); else arb_mul(res + i, res + i - 1, res + 1, prec); } for (i = 2; i < num; i++) { arb_div_ui(res + i, res + i, i, prec); if (i % 2 == 0) arb_neg(res + i, res + i); } } void _arb_poly_gamma_stirling_eval2(arb_ptr res, const arb_t z, slong n, slong num, int diff, slong prec) { slong k, tlen, qlen; arb_ptr T, Q; mag_ptr err; arb_t c; T = _arb_vec_init(num); Q = _arb_vec_init(num); err = _mag_vec_init(num); arb_init(c); arb_gamma_stirling_bound(err, z, 0, num, n); if (n <= 1) { _arb_vec_zero(res, num); } else { qlen = FLINT_MIN(2 * (n - 1) + 1, num); tlen = FLINT_MIN(2 * (n - 1) - 1, num); bsplit(Q, T, z, 1, n, num, prec); _arb_poly_div_series(res, T, tlen, Q, qlen, num, prec); } if (diff) { _arb_vec_add_error_mag_vec(res, err, num); _arb_poly_derivative(res, res, num, prec); if (num > 1) { /* add log(z+x) - 1/(2(z+x)) */ arb_inv(c, z, prec); _arb_vec_set_powers(T, c, num, prec); for (k = 1; k < num - 1; k++) { arb_mul_2exp_si(T, z, 1); arb_div_ui(T, T, k, prec); arb_add_ui(T, T, 1, prec); arb_mul_2exp_si(T, T, -1); if (k % 2 == 0) arb_submul(res + k, T, T + k + 1, prec); else arb_addmul(res + k, T, T + k + 1, prec); } arb_mul_2exp_si(c, c, -1); arb_sub(res, res, c, prec); arb_log(c, z, prec); arb_add(res, res, c, prec); } } else { /* ((z-1/2) + t) * log(z+t) */ _arb_poly_log_cpx_series(T, z, num, prec); arb_one(c); arb_mul_2exp_si(c, c, -1); arb_sub(c, z, c, prec); _arb_poly_mullow_cpx(T, T, num, c, num, prec); /* constant term */ arb_const_log_sqrt2pi(c, prec); arb_add(T, T, c, prec); /* subtract (z+t) */ arb_sub(T, T, z, prec); if (num > 1) arb_sub_ui(T + 1, T + 1, 1, prec); _arb_vec_add(res, res, T, num, prec); _arb_vec_add_error_mag_vec(res, err, num); } _arb_vec_clear(T, num); _arb_vec_clear(Q, num); _mag_vec_clear(err, num); arb_clear(c); } void _arb_poly_gamma_stirling_eval(arb_ptr res, const arb_t z, slong n, slong num, slong prec) { _arb_poly_gamma_stirling_eval2(res, z, n, num, 0, prec); } void _arb_poly_gamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong i, rflen, r, n, wp; arb_ptr t, u, v; arb_struct f[2]; if (hlen == 1) { arb_gamma(res, h, prec); if (arb_is_finite(res)) _arb_vec_zero(res + 1, len - 1); else _arb_vec_indeterminate(res + 1, len - 1); return; } hlen = FLINT_MIN(hlen, len); wp = prec + FLINT_BIT_COUNT(prec); t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(len); arb_init(f); arb_init(f + 1); /* use zeta values at small integers */ if (arb_is_int(h) && (arf_cmpabs_ui(arb_midref(h), prec / 2) < 0)) { r = arf_get_si(arb_midref(h), ARF_RND_DOWN); if (r <= 0) { _arb_vec_indeterminate(v, len); } else if (r == 1) { _arb_poly_lgamma_series_at_one(u, len, wp); _arb_poly_exp_series(v, u, len, len, wp); } else { _arb_poly_lgamma_series_at_one(u, len, wp); _arb_poly_exp_series(t, u, len, len, wp); arb_one(f); arb_one(f + 1); rflen = FLINT_MIN(len, r); _arb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), r - 1, rflen, wp); _arb_poly_mullow(v, t, len, u, rflen, len, wp); } } else { /* otherwise use Stirling series */ arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 0, wp); /* gamma(h) = (rf(1-h, r) * pi) / (gamma(1-h+r) sin(pi h)), h = h0 + t*/ if (reflect) { /* u = 1/gamma(r+1-h) */ arb_sub_ui(f, h, r + 1, wp); arb_neg(f, f); _arb_poly_gamma_stirling_eval(t, f, n, len, wp); _arb_vec_neg(t, t, len); _arb_poly_exp_series(u, t, len, len, wp); for (i = 1; i < len; i += 2) arb_neg(u + i, u + i); /* v = 1/sin(pi x) */ arb_set(f, h); arb_one(f + 1); _arb_poly_sin_pi_series(t, f, 2, len, wp); _arb_poly_inv_series(v, t, len, len, wp); _arb_poly_mullow(t, u, len, v, len, len, wp); /* rf(1-h,r) * pi */ if (r == 0) { rflen = 1; arb_const_pi(u, wp); } else { arb_sub_ui(f, h, 1, wp); arb_neg(f, f); arb_set_si(f + 1, -1); rflen = FLINT_MIN(len, r + 1); _arb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), r, rflen, wp); arb_const_pi(v, wp); _arb_vec_scalar_mul(u, u, rflen, v, wp); } /* multiply by rising factorial */ _arb_poly_mullow(v, t, len, u, rflen, len, wp); } else { /* gamma(h) = gamma(h+r) / rf(h,r) */ if (r == 0) { arb_add_ui(f, h, r, wp); _arb_poly_gamma_stirling_eval(t, f, n, len, wp); _arb_poly_exp_series(v, t, len, len, wp); } else { /* TODO: div_series may be better (once it has a good basecase), if the rising factorial is short */ arb_set(f, h); arb_one(f + 1); rflen = FLINT_MIN(len, r + 1); _arb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), r, rflen, wp); _arb_poly_inv_series(t, u, rflen, len, wp); arb_add_ui(f, h, r, wp); _arb_poly_gamma_stirling_eval(v, f, n, len, wp); _arb_poly_exp_series(u, v, len, len, wp); _arb_poly_mullow(v, u, len, t, len, len, wp); } } } /* compose with nonconstant part */ arb_zero(t); _arb_vec_set(t + 1, h + 1, hlen - 1); _arb_poly_compose_series(res, v, len, t, hlen, len, prec); arb_clear(f); arb_clear(f + 1); _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, len); } void arb_poly_gamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { arb_poly_fit_length(res, n); if (f->length == 0 || n == 0) _arb_vec_indeterminate(res->coeffs, n); else _arb_poly_gamma_series(res->coeffs, f->coeffs, f->length, n, prec); _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/get_coeff_arb.c000066400000000000000000000010731417376376500171060ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_get_coeff_arb(arb_t x, const arb_poly_t poly, slong n) { if (n < poly->length) arb_set(x, poly->coeffs + n); else arb_zero(x); } arb-2.22.1/arb_poly/get_unique_fmpz_poly.c000066400000000000000000000013221417376376500206020ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int arb_poly_get_unique_fmpz_poly(fmpz_poly_t res, const arb_poly_t src) { int success; fmpz_poly_fit_length(res, src->length); success = _arb_vec_get_unique_fmpz_vec(res->coeffs, src->coeffs, src->length); _fmpz_poly_set_length(res, src->length); _fmpz_poly_normalise(res); return success; } arb-2.22.1/arb_poly/graeffe_transform.c000066400000000000000000000027421417376376500200370ustar00rootroot00000000000000/* Copyright (C) 2021 Matthias Gessinger This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_graeffe_transform(arb_ptr b, arb_srcptr a, slong len, slong prec) { slong lo, le, ls, deg, i; arb_ptr pe, po; if (len <= 1) { if (len) arb_sqr(b, a, prec); return; } deg = len - 1; lo = len / 2; ls = 2 * lo - 1; le = deg / 2 + 1; po = _arb_vec_init(lo); pe = _arb_vec_init(FLINT_MAX(le, ls)); for (i = deg; i >= 0; i--) { if (i % 2 == 0) arb_set(pe + i / 2, a + i); else arb_set(po + i / 2, a + i); } _arb_poly_mul(b, pe, le, pe, le, prec); _arb_poly_mul(pe, po, lo, po, lo, prec); _arb_poly_sub(b + 1, b + 1, ls, pe, ls, prec); if (len % 2 == 0) { _arb_vec_neg(b, b, deg); arb_set(b + deg, pe + (deg - 1)); } _arb_vec_clear(pe, FLINT_MAX(le, ls)); _arb_vec_clear(po, lo); } void arb_poly_graeffe_transform(arb_poly_t b, const arb_poly_t a, slong prec) { arb_poly_fit_length(b, a->length); _arb_poly_graeffe_transform(b->coeffs, a->coeffs, a->length, prec); _arb_poly_set_length(b, a->length); } arb-2.22.1/arb_poly/init.c000066400000000000000000000011611417376376500153020ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_init(arb_poly_t poly) { poly->coeffs = NULL; poly->length = 0; poly->alloc = 0; } void arb_poly_init2(arb_poly_t poly, slong len) { arb_poly_init(poly); arb_poly_fit_length(poly, len); } arb-2.22.1/arb_poly/inlines.c000066400000000000000000000006561417376376500160100ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ARB_POLY_INLINES_C #include "arb_poly.h" arb-2.22.1/arb_poly/integral.c000066400000000000000000000015771417376376500161570ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_integral(arb_ptr res, arb_srcptr poly, slong len, slong prec) { slong k = len - 1; for (k = len - 1; k > 0; k--) arb_div_ui(res + k, poly + k - 1, k, prec); arb_zero(res); } void arb_poly_integral(arb_poly_t res, const arb_poly_t poly, slong prec) { arb_poly_fit_length(res, poly->length + 1); _arb_poly_integral(res->coeffs, poly->coeffs, poly->length + 1, prec); _arb_poly_set_length(res, poly->length + 1); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/interpolate_barycentric.c000066400000000000000000000034131417376376500212540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_interpolate_barycentric(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) { arb_ptr P, Q, w; arb_t t; slong i, j; if (n == 1) { arb_set(poly, ys); return; } P = _arb_vec_init(n + 1); Q = _arb_vec_init(n); w = _arb_vec_init(n); arb_init(t); _arb_poly_product_roots(P, xs, n, prec); for (i = 0; i < n; i++) { arb_one(w + i); for (j = 0; j < n; j++) { if (i != j) { arb_sub(t, xs + i, xs + j, prec); arb_mul(w + i, w + i, t, prec); } } arb_inv(w + i, w + i, prec); } _arb_vec_zero(poly, n); for (i = 0; i < n; i++) { _arb_poly_div_root(Q, t, P, n + 1, xs + i, prec); arb_mul(t, w + i, ys + i, prec); _arb_vec_scalar_addmul(poly, Q, n, t, prec); } _arb_vec_clear(P, n + 1); _arb_vec_clear(Q, n); _arb_vec_clear(w, n); arb_clear(t); } void arb_poly_interpolate_barycentric(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) { if (n == 0) { arb_poly_zero(poly); } else { arb_poly_fit_length(poly, n); _arb_poly_set_length(poly, n); _arb_poly_interpolate_barycentric(poly->coeffs, xs, ys, n, prec); _arb_poly_normalise(poly); } } arb-2.22.1/arb_poly/interpolate_fast.c000066400000000000000000000057461417376376500177170ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_interpolation_weights(arb_ptr w, arb_ptr * tree, slong len, slong prec) { arb_ptr tmp; slong i, n, height; if (len == 0) return; if (len == 1) { arb_one(w); return; } tmp = _arb_vec_init(len + 1); height = FLINT_CLOG2(len); n = WORD(1) << (height - 1); _arb_poly_mul_monic(tmp, tree[height-1], n + 1, tree[height-1] + (n + 1), (len - n + 1), prec); _arb_poly_derivative(tmp, tmp, len + 1, prec); _arb_poly_evaluate_vec_fast_precomp(w, tmp, len, tree, len, prec); for (i = 0; i < len; i++) arb_inv(w + i, w + i, prec); _arb_vec_clear(tmp, len + 1); } void _arb_poly_interpolate_fast_precomp(arb_ptr poly, arb_srcptr ys, arb_ptr * tree, arb_srcptr weights, slong len, slong prec) { arb_ptr t, u, pa, pb; slong i, pow, left; if (len == 0) return; t = _arb_vec_init(len); u = _arb_vec_init(len); for (i = 0; i < len; i++) arb_mul(poly + i, weights + i, ys + i, prec); for (i = 0; i < FLINT_CLOG2(len); i++) { pow = (WORD(1) << i); pa = tree[i]; pb = poly; left = len; while (left >= 2 * pow) { _arb_poly_mul(t, pa, pow + 1, pb + pow, pow, prec); _arb_poly_mul(u, pa + pow + 1, pow + 1, pb, pow, prec); _arb_vec_add(pb, t, u, 2 * pow, prec); left -= 2 * pow; pa += 2 * pow + 2; pb += 2 * pow; } if (left > pow) { _arb_poly_mul(t, pa, pow + 1, pb + pow, left - pow, prec); _arb_poly_mul(u, pb, pow, pa + pow + 1, left - pow + 1, prec); _arb_vec_add(pb, t, u, left, prec); } } _arb_vec_clear(t, len); _arb_vec_clear(u, len); } void _arb_poly_interpolate_fast(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong len, slong prec) { arb_ptr * tree; arb_ptr w; tree = _arb_poly_tree_alloc(len); _arb_poly_tree_build(tree, xs, len, prec); w = _arb_vec_init(len); _arb_poly_interpolation_weights(w, tree, len, prec); _arb_poly_interpolate_fast_precomp(poly, ys, tree, w, len, prec); _arb_vec_clear(w, len); _arb_poly_tree_free(tree, len); } void arb_poly_interpolate_fast(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) { if (n == 0) { arb_poly_zero(poly); } else { arb_poly_fit_length(poly, n); _arb_poly_set_length(poly, n); _arb_poly_interpolate_fast(poly->coeffs, xs, ys, n, prec); _arb_poly_normalise(poly); } } arb-2.22.1/arb_poly/interpolate_newton.c000066400000000000000000000043161417376376500202640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" static void _interpolate_newton(arb_ptr ys, arb_srcptr xs, slong n, slong prec) { arb_t p, q, t; slong i, j; arb_init(p); arb_init(q); arb_init(t); for (i = 1; i < n; i++) { arb_set(t, ys + i - 1); for (j = i; j < n; j++) { arb_sub(p, ys + j, t, prec); arb_sub(q, xs + j, xs + j - i, prec); arb_set(t, ys + j); arb_div(ys + j, p, q, prec); } } arb_clear(p); arb_clear(q); arb_clear(t); } static void _newton_to_monomial(arb_ptr ys, arb_srcptr xs, slong n, slong prec) { arb_t t, u; slong i, j; arb_init(t); arb_init(u); for (i = n - 2; i >= 0; i--) { arb_set(t, ys + i); arb_set(ys + i, ys + i + 1); for (j = i + 1; j < n - 1; j++) { arb_mul(u, ys + j, xs + i, prec); arb_sub(ys + j, ys + j + 1, u, prec); } arb_mul(u, ys + n - 1, xs + i, prec); arb_sub(ys + n - 1, t, u, prec); } _arb_poly_reverse(ys, ys, n, n); arb_clear(t); arb_clear(u); } void _arb_poly_interpolate_newton(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) { if (n == 1) { arb_set(poly, ys); } else { _arb_vec_set(poly, ys, n); _interpolate_newton(poly, xs, n, prec); while (n > 0 && arb_is_zero(poly + n - 1)) n--; _newton_to_monomial(poly, xs, n, prec); } } void arb_poly_interpolate_newton(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) { if (n == 0) { arb_poly_zero(poly); } else { arb_poly_fit_length(poly, n); _arb_poly_set_length(poly, n); _arb_poly_interpolate_newton(poly->coeffs, xs, ys, n, prec); _arb_poly_normalise(poly); } } arb-2.22.1/arb_poly/inv_borel_transform.c000066400000000000000000000017661417376376500204240ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_inv_borel_transform(arb_ptr res, arb_srcptr poly, slong len, slong prec) { slong i; arb_t t; arb_init(t); arb_one(t); for (i = 0; i < len; i++) { if (i > 1) arb_mul_ui(t, t, i, prec); arb_mul(res + i, poly + i, t, prec); } arb_clear(t); } void arb_poly_inv_borel_transform(arb_poly_t res, const arb_poly_t poly, slong prec) { arb_poly_fit_length(res, poly->length); _arb_poly_inv_borel_transform(res->coeffs, poly->coeffs, poly->length, prec); _arb_poly_set_length(res, poly->length); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/inv_series.c000066400000000000000000000054641417376376500165170ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #define MULLOW(z, x, xn, y, yn, nn, prec) \ if ((xn) >= (yn)) \ _arb_poly_mullow(z, x, xn, y, yn, nn, prec); \ else \ _arb_poly_mullow(z, y, yn, x, xn, nn, prec); \ void _arb_poly_inv_series(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong len, slong prec) { Qlen = FLINT_MIN(Qlen, len); arb_inv(Qinv, Q, prec); if (Qlen == 1) { _arb_vec_zero(Qinv + 1, len - 1); } else if (len == 2) { arb_mul(Qinv + 1, Qinv, Qinv, prec); arb_mul(Qinv + 1, Qinv + 1, Q + 1, prec); arb_neg(Qinv + 1, Qinv + 1); } else { slong i, blen; /* The basecase algorithm is faster for much larger Qlen or len than this, but unfortunately also much less numerically stable. */ if (Qlen == 2 || len <= 8) blen = len; else blen = FLINT_MIN(len, 4); for (i = 1; i < blen; i++) { arb_dot(Qinv + i, NULL, 1, Q + 1, 1, Qinv + i - 1, -1, FLINT_MIN(i, Qlen - 1), prec); if (!arb_is_one(Qinv)) arb_mul(Qinv + i, Qinv + i, Qinv, prec); } if (len > blen) { slong Qnlen, Wlen, W2len; arb_ptr W; W = _arb_vec_init(len); NEWTON_INIT(blen, len) NEWTON_LOOP(m, n) Qnlen = FLINT_MIN(Qlen, n); Wlen = FLINT_MIN(Qnlen + m - 1, n); W2len = Wlen - m; MULLOW(W, Q, Qnlen, Qinv, m, Wlen, prec); MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m, prec); _arb_vec_neg(Qinv + m, Qinv + m, n - m); NEWTON_END_LOOP NEWTON_END _arb_vec_clear(W, len); } } } void arb_poly_inv_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { if (n == 0) { arb_poly_zero(Qinv); return; } if (Q->length == 0) { arb_poly_fit_length(Qinv, n); _arb_vec_indeterminate(Qinv->coeffs, n); _arb_poly_set_length(Qinv, n); return; } if (Qinv == Q) { arb_poly_t t; arb_poly_init(t); arb_poly_inv_series(t, Q, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); return; } arb_poly_fit_length(Qinv, n); _arb_poly_inv_series(Qinv->coeffs, Q->coeffs, Q->length, n, prec); _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); } arb-2.22.1/arb_poly/lambertw_series.c000066400000000000000000000044341417376376500175340ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_lambertw_series(arb_ptr res, arb_srcptr z, slong zlen, int flags, slong len, slong prec) { arb_ptr w, ew, t, u; arb_t ew0; zlen = FLINT_MIN(zlen, len); if (zlen == 1) { arb_lambertw(res, z, flags, prec); _arb_vec_zero(res + 1, len - 1); return; } w = _arb_vec_init(len); ew = _arb_vec_init(len); t = _arb_vec_init(len); u = _arb_vec_init(len); arb_init(ew0); arb_lambertw(w, z, flags, prec); if (arb_contains_zero(w)) arb_exp(ew0, w, prec); else arb_div(ew0, z, w, prec); arb_add(t, ew0, z, prec); arb_div(w + 1, z + 1, t, prec); NEWTON_INIT(2, len) NEWTON_LOOP(m, n) /* _arb_poly_exp_series(ew, w, m, n, prec); */ arb_zero(t); _arb_vec_set(t + 1, w + 1, m - 1); _arb_poly_exp_series(ew, t, m, n, prec); _arb_vec_scalar_mul(ew, ew, n, ew0, prec); _arb_poly_mullow(t, ew, n, w, m, n, prec); _arb_poly_sub(u, t, n, z, FLINT_MIN(zlen, n), prec); _arb_vec_add(t, t, ew, n, prec); _arb_poly_div_series(ew, u, n, t, n, n, prec); _arb_vec_neg(w + m, ew + m, n - m); NEWTON_END_LOOP NEWTON_END _arb_vec_set(res, w, len); _arb_vec_clear(w, len); _arb_vec_clear(ew, len); _arb_vec_clear(t, len); _arb_vec_clear(u, len); arb_clear(ew0); } void arb_poly_lambertw_series(arb_poly_t res, const arb_poly_t z, int flags, slong len, slong prec) { if (len == 0 || (flags == 0 && z->length == 0)) { arb_poly_zero(res); return; } if (z->length == 0) { arb_poly_fit_length(res, len); _arb_vec_indeterminate(res->coeffs, len); _arb_poly_set_length(res, len); return; } arb_poly_fit_length(res, len); _arb_poly_lambertw_series(res->coeffs, z->coeffs, z->length, flags, len, prec); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/lgamma_series.c000066400000000000000000000061151417376376500171530ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "arb_hypgeom.h" slong arf_get_si(const arf_t x, arf_rnd_t rnd); void _arb_poly_lgamma_series_at_one(arb_ptr u, slong len, slong prec); void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec); void _arb_poly_gamma_stirling_eval(arb_ptr res, const arb_t z, slong n, slong num, slong prec); static __inline__ void _log_rising_ui_series(arb_ptr t, const arb_t x, slong r, slong len, slong prec) { slong rflen; rflen = FLINT_MIN(len, r + 1); arb_hypgeom_rising_ui_jet(t, x, r, rflen, prec); _arb_poly_log_series(t, t, rflen, len, prec); } void _arb_poly_lgamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong r, n, wp; arb_t zr; arb_ptr t, u; if (!arb_is_positive(h)) { _arb_vec_indeterminate(res, len); return; } hlen = FLINT_MIN(hlen, len); wp = prec + FLINT_BIT_COUNT(prec); t = _arb_vec_init(len); u = _arb_vec_init(len); arb_init(zr); /* use zeta values at small integers */ if (arb_is_int(h) && (arf_cmpabs_ui(arb_midref(h), prec / 2) < 0)) { r = arf_get_si(arb_midref(h), ARF_RND_DOWN); if (r <= 0) { _arb_vec_indeterminate(res, len); goto cleanup; } else { _arb_poly_lgamma_series_at_one(u, len, wp); if (r != 1) { arb_one(zr); _log_rising_ui_series(t, zr, r - 1, len, wp); _arb_vec_add(u, u, t, len, wp); } } } else if (len <= 2) { arb_lgamma(u, h, wp); if (len == 2) arb_digamma(u + 1, h, wp); } else { /* otherwise use Stirling series */ arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 0, 0, wp); arb_add_ui(zr, h, r, wp); _arb_poly_gamma_stirling_eval(u, zr, n, len, wp); if (r != 0) { _log_rising_ui_series(t, h, r, len, wp); _arb_vec_sub(u, u, t, len, wp); } } /* compose with nonconstant part */ arb_zero(t); _arb_vec_set(t + 1, h + 1, hlen - 1); _arb_poly_compose_series(res, u, len, t, hlen, len, prec); cleanup: arb_clear(zr); _arb_vec_clear(t, len); _arb_vec_clear(u, len); } void arb_poly_lgamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { arb_poly_fit_length(res, n); if (f->length == 0 || n == 0) _arb_vec_indeterminate(res->coeffs, n); else _arb_poly_lgamma_series(res->coeffs, f->coeffs, f->length, n, prec); _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/log1p_series.c000066400000000000000000000045411417376376500167400ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_log1p_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) { arb_t a; flen = FLINT_MIN(flen, n); arb_init(a); arb_log1p(a, f, prec); if (flen == 1) { _arb_vec_zero(res + 1, n - 1); } else if (n == 2) { arb_add_ui(res, f + 0, 1, prec); arb_div(res + 1, f + 1, res + 0, prec); } else if (_arb_vec_is_zero(f + 1, flen - 2)) /* f = a + bx^d */ { slong i, j, d = flen - 1; arb_add_ui(res, f + 0, 1, prec); for (i = 1, j = d; j < n; j += d, i++) { if (i == 1) arb_div(res + j, f + d, res, prec); else arb_mul(res + j, res + j - d, res + d, prec); _arb_vec_zero(res + j - d + 1, flen - 2); } _arb_vec_zero(res + j - d + 1, n - (j - d + 1)); for (i = 2, j = 2 * d; j < n; j += d, i++) arb_div_si(res + j, res + j, i % 2 ? i : -i, prec); } else { arb_ptr f_diff, f_inv; slong alloc; alloc = n + flen; f_inv = _arb_vec_init(alloc); f_diff = f_inv + n; arb_add_ui(f_diff, f, 1, prec); _arb_vec_set(f_diff + 1, f + 1, flen - 1); _arb_poly_inv_series(f_inv, f_diff, flen, n, prec); _arb_poly_derivative(f_diff, f, flen, prec); _arb_poly_mullow(res, f_inv, n - 1, f_diff, flen - 1, n - 1, prec); _arb_poly_integral(res, res, n, prec); _arb_vec_clear(f_inv, alloc); } arb_swap(res, a); arb_clear(a); } void arb_poly_log1p_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { slong flen = f->length; if (flen == 0 || n == 0) { arb_poly_zero(res); return; } if (flen == 1 /*&& !arb_contains_si(f->coeffs, -1)*/) n = 1; arb_poly_fit_length(res, n); _arb_poly_log1p_series(res->coeffs, f->coeffs, flen, n, prec); _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/log_series.c000066400000000000000000000045041417376376500164760ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_log_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) { flen = FLINT_MIN(flen, n); if (flen == 1) { arb_log(res, f, prec); _arb_vec_zero(res + 1, n - 1); } else if (n == 2) { arb_div(res + 1, f + 1, f + 0, prec); /* safe since hlen >= 2 */ arb_log(res, f, prec); } else if (_arb_vec_is_zero(f + 1, flen - 2)) /* f = a + bx^d */ { slong i, j, d = flen - 1; for (i = 1, j = d; j < n; j += d, i++) { if (i == 1) arb_div(res + j, f + d, f + 0, prec); else arb_mul(res + j, res + j - d, res + d, prec); _arb_vec_zero(res + j - d + 1, flen - 2); } _arb_vec_zero(res + j - d + 1, n - (j - d + 1)); for (i = 2, j = 2 * d; j < n; j += d, i++) arb_div_si(res + j, res + j, i % 2 ? i : -i, prec); arb_log(res, f, prec); /* done last to allow aliasing */ } else { arb_ptr f_diff, f_inv; arb_t a; slong alloc; alloc = n + flen - 1; f_inv = _arb_vec_init(alloc); f_diff = f_inv + n; arb_init(a); arb_log(a, f, prec); _arb_poly_derivative(f_diff, f, flen, prec); _arb_poly_inv_series(f_inv, f, flen, n, prec); _arb_poly_mullow(res, f_inv, n - 1, f_diff, flen - 1, n - 1, prec); _arb_poly_integral(res, res, n, prec); arb_swap(res, a); arb_clear(a); _arb_vec_clear(f_inv, alloc); } } void arb_poly_log_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { if (n == 0) { arb_poly_zero(res); return; } arb_poly_fit_length(res, n); if (f->length == 0) _arb_vec_indeterminate(res->coeffs, n); else _arb_poly_log_series(res->coeffs, f->coeffs, f->length, n, prec); _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/majorant.c000066400000000000000000000015661417376376500161630ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_majorant(arb_ptr res, arb_srcptr vec, slong len, slong prec) { slong i; for (i = 0; i < len; i++) { arb_get_abs_ubound_arf(arb_midref(res + i), vec + i, prec); mag_zero(arb_radref(res + i)); } } void arb_poly_majorant(arb_poly_t res, const arb_poly_t poly, slong prec) { arb_poly_fit_length(res, poly->length); _arb_poly_majorant(res->coeffs, poly->coeffs, poly->length, prec); _arb_poly_set_length(res, poly->length); } arb-2.22.1/arb_poly/mul.c000066400000000000000000000026551417376376500151450ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_mul(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) { _arb_poly_mullow(C, A, lenA, B, lenB, lenA + lenB - 1, prec); } void arb_poly_mul(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { slong len_out; if ((poly1->length == 0) || (poly2->length == 0)) { arb_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (res == poly1 || res == poly2) { arb_poly_t temp; arb_poly_init2(temp, len_out); _arb_poly_mul(temp->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); arb_poly_swap(res, temp); arb_poly_clear(temp); } else { arb_poly_fit_length(res, len_out); _arb_poly_mul(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); } _arb_poly_set_length(res, len_out); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/mullow.c000066400000000000000000000075201417376376500156630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_mullow(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) { if (n == 1) { arb_mul(res, poly1, poly2, prec); } else if (n <= 7 || len1 <= 7 || len2 <= 7) { _arb_poly_mullow_classical(res, poly1, len1, poly2, len2, n, prec); } else { slong cutoff; double p; if (prec <= 2 * FLINT_BITS) { cutoff = 110; } else { p = log(prec); cutoff = 10000.0 / (p * p * p); cutoff = FLINT_MIN(cutoff, 60); if (poly1 == poly2 && prec >= 256) cutoff *= 1.25; if (poly1 == poly2 && prec >= 4096) cutoff *= 1.25; cutoff = FLINT_MAX(cutoff, 8); } if (2 * FLINT_MIN(len1, len2) <= cutoff || n <= cutoff) _arb_poly_mullow_classical(res, poly1, len1, poly2, len2, n, prec); else _arb_poly_mullow_block(res, poly1, len1, poly2, len2, n, prec); } } void arb_poly_mullow(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; if (len1 == 0 || len2 == 0 || n == 0) { arb_poly_zero(res); return; } n = FLINT_MIN((len1 + len2 - 1), n); len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); /* Hack to avoid temporary allocations with first derivatives. */ if (n <= 2 && !(len1 == 2 && len2 == 2)) { arb_poly_fit_length(res, n); if (n == 1) { arb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); } else if (len2 == 1) { arb_mul(res->coeffs + 1, poly1->coeffs + 1, poly2->coeffs, prec); arb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); } else if (len1 == 1) { arb_mul(res->coeffs + 1, poly2->coeffs + 1, poly1->coeffs, prec); arb_mul(res->coeffs, poly2->coeffs, poly1->coeffs, prec); } else { abort(); if (res == poly1 || res == poly2) { arb_t t; arb_init(t); arb_mul(t, poly1->coeffs, poly2->coeffs + 1, prec); arb_addmul(t, poly2->coeffs, poly1->coeffs + 1, prec); arb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); arb_swap(t, res->coeffs + 1); arb_clear(t); } else { arb_mul(res->coeffs, poly1->coeffs, poly2->coeffs, prec); arb_mul(res->coeffs + 1, poly1->coeffs, poly2->coeffs + 1, prec); arb_addmul(res->coeffs + 1, poly2->coeffs, poly1->coeffs + 1, prec); } } _arb_poly_set_length(res, n); _arb_poly_normalise(res); return; } if (res == poly1 || res == poly2) { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_mullow(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); arb_poly_swap(res, t); arb_poly_clear(t); } else { arb_poly_fit_length(res, n); _arb_poly_mullow(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, prec); } _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/mullow_block.c000066400000000000000000000463241417376376500170420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arb_poly.h" void _arb_poly_get_scale(fmpz_t scale, arb_srcptr x, slong xlen, arb_srcptr y, slong ylen) { slong xa, xb, ya, yb, den; fmpz_zero(scale); /* ignore zeros (and infs/nans!); find the first and last finite nonzero entries to determine the scale */ xa = 0; xb = xlen - 1; while (xa < xlen && arf_is_special(arb_midref(x + xa))) xa++; while (xb > xa && arf_is_special(arb_midref(x + xb))) xb--; ya = 0; yb = ylen - 1; while (ya < ylen && arf_is_special(arb_midref(y + ya))) ya++; while (yb > ya && arf_is_special(arb_midref(y + yb))) yb--; /* compute average of exponent differences, weighted by the lengths */ if (xa <= xb && ya <= yb && (xa < xb || ya < yb)) { fmpz_add(scale, scale, ARF_EXPREF(arb_midref(x + xb))); fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(x + xa))); fmpz_add(scale, scale, ARF_EXPREF(arb_midref(y + yb))); fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(y + ya))); den = (xb - xa) + (yb - ya); /* scale = floor(scale / den + 1/2) = floor((2 scale + den) / (2 den)) */ fmpz_mul_2exp(scale, scale, 1); fmpz_add_ui(scale, scale, den); fmpz_fdiv_q_ui(scale, scale, 2 * den); } } /* Break vector into same-exponent blocks where the largest block has a height of at most ALPHA*prec + BETA bits. These are just tuning parameters. Note that ALPHA * MAG_BITS + BETA should be smaller than DOUBLE_BLOCK_MAX_HEIGHT if we want to use doubles for error bounding. */ #define ALPHA 3.0 #define BETA 512 /* Maximum length of block for which we use double multiplication (for longer blocks, we use fmpz_poly multiplication). This is essentially just a tuning parameter, but note that it must be considered when compensating for rounding error below. */ #define DOUBLE_BLOCK_MAX_LENGTH 1000 /* Computing a dot product of length DOUBLE_BLOCK_MAX_LENGTH involving only nonnegative numbers, and then multiplying by this factor, must give an upper bound for the exact dot product (we can assume that no overflow or underflow occurs). The following is certainly sufficient, but it would be nice to include a formal proof here. */ #define DOUBLE_ROUNDING_FACTOR (1.0 + 1e-9) /* Maximum height for which we use double multiplication. Since the dynamic exponent range of doubles is about +/- 1024, this must be less than about 1024 (to allow the product of two numbers). This must also account for adding MAG_BITS bits. */ #define DOUBLE_BLOCK_MAX_HEIGHT 800 /* We divide coefficients by 2^DOUBLE_BLOCK_SHIFT when converting them to doubles, in order to use the whole exponent range. Note that this means numbers of size (2^(-DOUBLE_BLOCK_SHIFT))^2 must not underflow. */ #define DOUBLE_BLOCK_SHIFT (DOUBLE_BLOCK_MAX_HEIGHT / 2) static void _mag_vec_get_fmpz_2exp_blocks(fmpz * coeffs, double * dblcoeffs, fmpz * exps, slong * blocks, const fmpz_t scale, arb_srcptr x, mag_srcptr xm, slong len) { fmpz_t top, bot, t, b, v, block_top, block_bot; slong i, j, s, block, bits, maxheight; int in_zero; mag_srcptr cur; fmpz_init(top); fmpz_init(bot); fmpz_init(t); fmpz_init(b); fmpz_init(v); fmpz_init(block_top); fmpz_init(block_bot); blocks[0] = 0; block = 0; in_zero = 1; maxheight = ALPHA * MAG_BITS + BETA; if (maxheight > DOUBLE_BLOCK_MAX_HEIGHT) flint_abort(); for (i = 0; i < len; i++) { cur = (x == NULL) ? (xm + i) : arb_radref(x + i); /* Skip (must be zero, since we assume there are no Infs/NaNs). */ if (mag_is_special(cur)) continue; /* Bottom and top exponent of current number */ bits = MAG_BITS; fmpz_set(top, MAG_EXPREF(cur)); fmpz_submul_ui(top, scale, i); fmpz_sub_ui(bot, top, bits); /* Extend current block. */ if (in_zero) { fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } else { fmpz_max(t, top, block_top); fmpz_min(b, bot, block_bot); fmpz_sub(v, t, b); /* extend current block */ if (fmpz_cmp_ui(v, maxheight) < 0) { fmpz_swap(block_top, t); fmpz_swap(block_bot, b); } else /* start new block */ { /* write exponent for previous block */ fmpz_set(exps + block, block_bot); block++; blocks[block] = i; fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } } in_zero = 0; } /* write exponent for last block */ fmpz_set(exps + block, block_bot); /* end marker */ blocks[block + 1] = len; /* write the block data */ for (i = 0; blocks[i] != len; i++) { for (j = blocks[i]; j < blocks[i + 1]; j++) { cur = (x == NULL) ? (xm + j) : arb_radref(x + j); if (mag_is_special(cur)) { fmpz_zero(coeffs + j); dblcoeffs[j] = 0.0; } else { mp_limb_t man; double c; man = MAG_MAN(cur); /* TODO: only write and use doubles when block is short? */ /* Divide by 2^(scale * j) */ fmpz_mul_ui(t, scale, j); fmpz_sub(t, MAG_EXPREF(cur), t); fmpz_sub_ui(t, t, MAG_BITS); /* bottom exponent */ s = _fmpz_sub_small(t, exps + i); if (s < 0) flint_abort(); /* Bug catcher */ fmpz_set_ui(coeffs + j, man); fmpz_mul_2exp(coeffs + j, coeffs + j, s); c = man; c = ldexp(c, s - DOUBLE_BLOCK_SHIFT); if (c < 1e-150 || c > 1e150) /* Bug catcher */ flint_abort(); dblcoeffs[j] = c; } } } fmpz_clear(top); fmpz_clear(bot); fmpz_clear(t); fmpz_clear(b); fmpz_clear(v); fmpz_clear(block_top); fmpz_clear(block_bot); } static void _arb_vec_get_fmpz_2exp_blocks(fmpz * coeffs, fmpz * exps, slong * blocks, const fmpz_t scale, arb_srcptr x, slong len, slong prec) { fmpz_t top, bot, t, b, v, block_top, block_bot; slong i, j, s, block, bits, maxheight; int in_zero; fmpz_init(top); fmpz_init(bot); fmpz_init(t); fmpz_init(b); fmpz_init(v); fmpz_init(block_top); fmpz_init(block_bot); blocks[0] = 0; block = 0; in_zero = 1; if (prec == ARF_PREC_EXACT) maxheight = ARF_PREC_EXACT; else maxheight = ALPHA * prec + BETA; for (i = 0; i < len; i++) { bits = arf_bits(arb_midref(x + i)); /* Skip (must be zero, since we assume there are no Infs/NaNs). */ if (bits == 0) continue; /* Bottom and top exponent of current number */ fmpz_set(top, ARF_EXPREF(arb_midref(x + i))); fmpz_submul_ui(top, scale, i); fmpz_sub_ui(bot, top, bits); /* Extend current block. */ if (in_zero) { fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } else { fmpz_max(t, top, block_top); fmpz_min(b, bot, block_bot); fmpz_sub(v, t, b); /* extend current block */ if (fmpz_cmp_ui(v, maxheight) < 0) { fmpz_swap(block_top, t); fmpz_swap(block_bot, b); } else /* start new block */ { /* write exponent for previous block */ fmpz_set(exps + block, block_bot); block++; blocks[block] = i; fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } } in_zero = 0; } /* write exponent for last block */ fmpz_set(exps + block, block_bot); /* end marker */ blocks[block + 1] = len; /* write the block data */ for (i = 0; blocks[i] != len; i++) { for (j = blocks[i]; j < blocks[i + 1]; j++) { if (arf_is_special(arb_midref(x + j))) { fmpz_zero(coeffs + j); } else { /* TODO: make this a single operation */ arf_get_fmpz_2exp(coeffs + j, bot, arb_midref(x + j)); fmpz_mul_ui(t, scale, j); fmpz_sub(t, bot, t); s = _fmpz_sub_small(t, exps + i); if (s < 0) flint_abort(); /* Bug catcher */ fmpz_mul_2exp(coeffs + j, coeffs + j, s); } } } fmpz_clear(top); fmpz_clear(bot); fmpz_clear(t); fmpz_clear(b); fmpz_clear(v); fmpz_clear(block_top); fmpz_clear(block_bot); } static void _arb_poly_addmullow_rad(arb_ptr z, fmpz * zz, const fmpz * xz, const double * xdbl, const fmpz * xexps, const slong * xblocks, slong xlen, const fmpz * yz, const double * ydbl, const fmpz * yexps, const slong * yblocks, slong ylen, slong n) { slong i, j, k, ii, xp, yp, xl, yl, bn; fmpz_t zexp; mag_t t; fmpz_init(zexp); mag_init(t); for (i = 0; (xp = xblocks[i]) != xlen; i++) { for (j = 0; (yp = yblocks[j]) != ylen; j++) { if (xp + yp >= n) continue; xl = xblocks[i + 1] - xp; yl = yblocks[j + 1] - yp; bn = FLINT_MIN(xl + yl - 1, n - xp - yp); xl = FLINT_MIN(xl, bn); yl = FLINT_MIN(yl, bn); fmpz_add_inline(zexp, xexps + i, yexps + j); if (xl > 1 && yl > 1 && (xl < DOUBLE_BLOCK_MAX_LENGTH || yl < DOUBLE_BLOCK_MAX_LENGTH)) { fmpz_add_ui(zexp, zexp, 2 * DOUBLE_BLOCK_SHIFT); for (k = 0; k < bn; k++) { /* Classical multiplication (may round down!) */ double ss = 0.0; for (ii = FLINT_MAX(0, k - yl + 1); ii <= FLINT_MIN(xl - 1, k); ii++) { ss += xdbl[xp + ii] * ydbl[yp + k - ii]; } /* Compensate for rounding error */ ss *= DOUBLE_ROUNDING_FACTOR; mag_set_d_2exp_fmpz(t, ss, zexp); mag_add(arb_radref(z + xp + yp + k), arb_radref(z + xp + yp + k), t); } } else { if (xl >= yl) _fmpz_poly_mullow(zz, xz + xp, xl, yz + yp, yl, bn); else _fmpz_poly_mullow(zz, yz + yp, yl, xz + xp, xl, bn); for (k = 0; k < bn; k++) { mag_set_fmpz_2exp_fmpz(t, zz + k, zexp); mag_add(arb_radref(z + xp + yp + k), arb_radref(z + xp + yp + k), t); } } } } fmpz_clear(zexp); mag_clear(t); } static void _arb_poly_addmullow_block(arb_ptr z, fmpz * zz, const fmpz * xz, const fmpz * xexps, const slong * xblocks, slong xlen, const fmpz * yz, const fmpz * yexps, const slong * yblocks, slong ylen, slong n, slong prec, int squaring) { slong i, j, k, xp, yp, xl, yl, bn; fmpz_t zexp; fmpz_init(zexp); if (squaring) { for (i = 0; (xp = xblocks[i]) != xlen; i++) { if (2 * xp >= n) continue; xl = xblocks[i + 1] - xp; bn = FLINT_MIN(2 * xl - 1, n - 2 * xp); xl = FLINT_MIN(xl, bn); _fmpz_poly_sqrlow(zz, xz + xp, xl, bn); _fmpz_add2_fast(zexp, xexps + i, xexps + i, 0); for (k = 0; k < bn; k++) arb_add_fmpz_2exp(z + 2 * xp + k, z + 2 * xp + k, zz + k, zexp, prec); } } for (i = 0; (xp = xblocks[i]) != xlen; i++) { for (j = squaring ? i + 1 : 0; (yp = yblocks[j]) != ylen; j++) { if (xp + yp >= n) continue; xl = xblocks[i + 1] - xp; yl = yblocks[j + 1] - yp; bn = FLINT_MIN(xl + yl - 1, n - xp - yp); xl = FLINT_MIN(xl, bn); yl = FLINT_MIN(yl, bn); if (xl >= yl) _fmpz_poly_mullow(zz, xz + xp, xl, yz + yp, yl, bn); else _fmpz_poly_mullow(zz, yz + yp, yl, xz + xp, xl, bn); _fmpz_add2_fast(zexp, xexps + i, yexps + j, squaring); for (k = 0; k < bn; k++) arb_add_fmpz_2exp(z + xp + yp + k, z + xp + yp + k, zz + k, zexp, prec); } } fmpz_clear(zexp); } void _arb_poly_mullow_block(arb_ptr z, arb_srcptr x, slong xlen, arb_srcptr y, slong ylen, slong n, slong prec) { slong xmlen, xrlen, ymlen, yrlen, i; fmpz *xz, *yz, *zz; fmpz *xe, *ye; slong *xblocks, *yblocks; int squaring; fmpz_t scale, t; xlen = FLINT_MIN(xlen, n); ylen = FLINT_MIN(ylen, n); squaring = (x == y) && (xlen == ylen); /* Strip trailing zeros */ xmlen = xrlen = xlen; while (xmlen > 0 && arf_is_zero(arb_midref(x + xmlen - 1))) xmlen--; while (xrlen > 0 && mag_is_zero(arb_radref(x + xrlen - 1))) xrlen--; if (squaring) { ymlen = xmlen; yrlen = xrlen; } else { ymlen = yrlen = ylen; while (ymlen > 0 && arf_is_zero(arb_midref(y + ymlen - 1))) ymlen--; while (yrlen > 0 && mag_is_zero(arb_radref(y + yrlen - 1))) yrlen--; } /* We don't know how to deal with infinities or NaNs */ if (!_arb_vec_is_finite(x, xlen) || (!squaring && !_arb_vec_is_finite(y, ylen))) { _arb_poly_mullow_classical(z, x, xlen, y, ylen, n, prec); return; } xlen = FLINT_MAX(xmlen, xrlen); ylen = FLINT_MAX(ymlen, yrlen); /* Start with the zero polynomial */ _arb_vec_zero(z, n); /* Nothing to do */ if (xlen == 0 || ylen == 0) return; n = FLINT_MIN(n, xlen + ylen - 1); fmpz_init(scale); fmpz_init(t); xz = _fmpz_vec_init(xlen); yz = _fmpz_vec_init(ylen); zz = _fmpz_vec_init(n); xe = _fmpz_vec_init(xlen); ye = _fmpz_vec_init(ylen); xblocks = flint_malloc(sizeof(slong) * (xlen + 1)); yblocks = flint_malloc(sizeof(slong) * (ylen + 1)); _arb_poly_get_scale(scale, x, xlen, y, ylen); /* Error propagation */ /* (xm + xr)*(ym + yr) = (xm*ym) + (xr*ym + xm*yr + xr*yr) = (xm*ym) + (xm*yr + xr*(ym + yr)) */ if (xrlen != 0 || yrlen != 0) { mag_ptr tmp; double *xdbl, *ydbl; tmp = _mag_vec_init(FLINT_MAX(xlen, ylen)); xdbl = flint_malloc(sizeof(double) * xlen); ydbl = flint_malloc(sizeof(double) * ylen); /* (xm + xr)^2 = (xm*ym) + (xr^2 + 2 xm xr) = (xm*ym) + xr*(2 xm + xr) */ if (squaring) { _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, x, NULL, xrlen); for (i = 0; i < xlen; i++) { arf_get_mag(tmp + i, arb_midref(x + i)); mag_mul_2exp_si(tmp + i, tmp + i, 1); mag_add(tmp + i, tmp + i, arb_radref(x + i)); } _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, NULL, tmp, xlen); _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xrlen, yz, ydbl, ye, yblocks, xlen, n); } else if (yrlen == 0) { /* xr * |ym| */ _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, x, NULL, xrlen); for (i = 0; i < ymlen; i++) arf_get_mag(tmp + i, arb_midref(y + i)); _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, NULL, tmp, ymlen); _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xrlen, yz, ydbl, ye, yblocks, ymlen, n); } else { /* |xm| * yr */ for (i = 0; i < xmlen; i++) arf_get_mag(tmp + i, arb_midref(x + i)); _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, NULL, tmp, xmlen); _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, y, NULL, yrlen); _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xmlen, yz, ydbl, ye, yblocks, yrlen, n); /* xr*(|ym| + yr) */ if (xrlen != 0) { _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, x, NULL, xrlen); for (i = 0; i < ylen; i++) arb_get_mag(tmp + i, y + i); _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, NULL, tmp, ylen); _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xrlen, yz, ydbl, ye, yblocks, ylen, n); } } _mag_vec_clear(tmp, FLINT_MAX(xlen, ylen)); flint_free(xdbl); flint_free(ydbl); } /* multiply midpoints */ if (xmlen != 0 && ymlen != 0) { _arb_vec_get_fmpz_2exp_blocks(xz, xe, xblocks, scale, x, xmlen, prec); if (squaring) { _arb_poly_addmullow_block(z, zz, xz, xe, xblocks, xmlen, xz, xe, xblocks, xmlen, n, prec, 1); } else { _arb_vec_get_fmpz_2exp_blocks(yz, ye, yblocks, scale, y, ymlen, prec); _arb_poly_addmullow_block(z, zz, xz, xe, xblocks, xmlen, yz, ye, yblocks, ymlen, n, prec, 0); } } /* Unscale. */ if (!fmpz_is_zero(scale)) { fmpz_zero(t); for (i = 0; i < n; i++) { arb_mul_2exp_fmpz(z + i, z + i, t); fmpz_add(t, t, scale); } } _fmpz_vec_clear(xz, xlen); _fmpz_vec_clear(yz, ylen); _fmpz_vec_clear(zz, n); _fmpz_vec_clear(xe, xlen); _fmpz_vec_clear(ye, ylen); flint_free(xblocks); flint_free(yblocks); fmpz_clear(scale); fmpz_clear(t); } void arb_poly_mullow_block(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong xlen, ylen, zlen; xlen = poly1->length; ylen = poly2->length; if (xlen == 0 || ylen == 0 || n == 0) { arb_poly_zero(res); return; } xlen = FLINT_MIN(xlen, n); ylen = FLINT_MIN(ylen, n); zlen = FLINT_MIN(xlen + ylen - 1, n); if (res == poly1 || res == poly2) { arb_poly_t tmp; arb_poly_init2(tmp, zlen); _arb_poly_mullow_block(tmp->coeffs, poly1->coeffs, xlen, poly2->coeffs, ylen, zlen, prec); arb_poly_swap(res, tmp); arb_poly_clear(tmp); } else { arb_poly_fit_length(res, zlen); _arb_poly_mullow_block(res->coeffs, poly1->coeffs, xlen, poly2->coeffs, ylen, zlen, prec); } _arb_poly_set_length(res, zlen); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/mullow_classical.c000066400000000000000000000064071417376376500177040ustar00rootroot00000000000000/* Copyright (C) 2008, 2009 William Hart Copyright (C) 2011 Sebastian Pancratz Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_mullow_classical(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) { len1 = FLINT_MIN(len1, n); len2 = FLINT_MIN(len2, n); if (n == 1) { arb_mul(res, poly1, poly2, prec); } else if (poly1 == poly2 && len1 == len2) { slong i, start, stop; arb_sqr(res, poly1, prec); arb_mul(res + 1, poly1, poly1 + 1, prec); arb_mul_2exp_si(res + 1, res + 1, 1); for (i = 2; i < FLINT_MIN(n, 2 * len1 - 3); i++) { start = FLINT_MAX(0, i - len1 + 1); stop = FLINT_MIN(len1 - 1, (i + 1) / 2 - 1); arb_dot(res + i, NULL, 0, poly1 + start, 1, poly1 + i - start, -1, stop - start + 1, prec); arb_mul_2exp_si(res + i, res + i, 1); if (i % 2 == 0 && i / 2 < len1) arb_addmul(res + i, poly1 + i / 2, poly1 + i / 2, prec); } if (len1 > 2 && n >= 2 * len1 - 2) { arb_mul(res + 2 * len1 - 3, poly1 + len1 - 1, poly1 + len1 - 2, prec); arb_mul_2exp_si(res + 2 * len1 - 3, res + 2 * len1 - 3, 1); } if (n >= 2 * len1 - 1) arb_sqr(res + 2 * len1 - 2, poly1 + len1 - 1, prec); } else if (len1 == 1) { _arb_vec_scalar_mul(res, poly2, n, poly1, prec); } else if (len2 == 1) { _arb_vec_scalar_mul(res, poly1, n, poly2, prec); } else { slong i, top1, top2; arb_mul(res, poly1, poly2, prec); for (i = 1; i < n; i++) { top1 = FLINT_MIN(len1 - 1, i); top2 = FLINT_MIN(len2 - 1, i); arb_dot(res + i, NULL, 0, poly1 + i - top2, 1, poly2 + top2, -1, top1 + top2 - i + 1, prec); } } } void arb_poly_mullow_classical(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong len_out; if (poly1->length == 0 || poly2->length == 0 || n == 0) { arb_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (n > len_out) n = len_out; if (res == poly1 || res == poly2) { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_mullow_classical(t->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n, prec); arb_poly_swap(res, t); arb_poly_clear(t); } else { arb_poly_fit_length(res, n); _arb_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n, prec); } _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/newton_convergence_factor.c000066400000000000000000000021171417376376500215670ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_newton_convergence_factor(arf_t convergence_factor, arb_srcptr poly, slong len, const arb_t convergence_interval, slong prec) { arb_ptr deriv; arb_t t, u; arb_init(t); arb_init(u); deriv = _arb_vec_init(len - 1); _arb_poly_derivative(deriv, poly, len, prec); _arb_poly_evaluate(t, deriv, len - 1, convergence_interval, prec); _arb_poly_derivative(deriv, deriv, len - 1, prec); _arb_poly_evaluate(u, deriv, len - 2, convergence_interval, prec); arb_div(t, u, t, prec); arb_mul_2exp_si(t, t, -1); arb_get_abs_ubound_arf(convergence_factor, t, prec); _arb_vec_clear(deriv, len - 1); arb_clear(t); arb_clear(u); } arb-2.22.1/arb_poly/newton_refine_root.c000066400000000000000000000031341417376376500202460ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" static __inline__ slong _arf_mag(const arf_t c) { slong m = arf_abs_bound_lt_2exp_si(c); return FLINT_MAX(m, 0); } void _arb_poly_newton_refine_root(arb_t r, arb_srcptr poly, slong len, const arb_t start, const arb_t convergence_interval, const arf_t convergence_factor, slong eval_extra_prec, slong prec) { slong precs[FLINT_BITS]; slong i, iters, wp, padding, start_prec; start_prec = arb_rel_accuracy_bits(start); padding = 5 + _arf_mag(convergence_factor); precs[0] = prec + padding; iters = 1; while ((iters < FLINT_BITS) && (precs[iters-1] + padding > 2*start_prec)) { precs[iters] = (precs[iters-1] / 2) + padding; iters++; if (iters == FLINT_BITS) { flint_printf("newton_refine_root: initial value too imprecise\n"); flint_abort(); } } arb_set(r, start); for (i = iters - 1; i >= 0; i--) { wp = precs[i] + eval_extra_prec; if (!_arb_poly_newton_step(r, poly, len, r, convergence_interval, convergence_factor, wp)) { flint_printf("warning: newton_refine_root: improvement failed\n"); break; } } } arb-2.22.1/arb_poly/newton_step.c000066400000000000000000000025571417376376500167160ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int _arb_poly_newton_step(arb_t xnew, arb_srcptr poly, slong len, const arb_t x, const arb_t convergence_interval, const arf_t convergence_factor, slong prec) { arf_t err; arb_t t, u, v; int result; arf_init(err); arb_init(t); arb_init(u); arb_init(v); arf_set_mag(err, arb_radref(x)); arf_mul(err, err, err, MAG_BITS, ARF_RND_UP); arf_mul(err, err, convergence_factor, MAG_BITS, ARF_RND_UP); arf_set(arb_midref(t), arb_midref(x)); mag_zero(arb_radref(t)); _arb_poly_evaluate2(u, v, poly, len, t, prec); arb_div(u, u, v, prec); arb_sub(u, t, u, prec); arb_add_error_arf(u, err); if (arb_contains(convergence_interval, u) && (mag_cmp(arb_radref(u), arb_radref(x)) < 0)) { arb_swap(xnew, u); result = 1; } else { arb_set(xnew, x); result = 0; } arb_clear(t); arb_clear(u); arb_clear(v); arf_clear(err); return result; } arb-2.22.1/arb_poly/normalise.c000066400000000000000000000011021417376376500163230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_normalise(arb_poly_t poly) { slong i; for (i = poly->length - 1; (i >= 0) && arb_is_zero(poly->coeffs + i); i--); poly->length = i + 1; } arb-2.22.1/arb_poly/overlaps.c000066400000000000000000000020371417376376500161750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int _arb_poly_overlaps(arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2) { slong i; for (i = 0; i < len2; i++) if (!arb_overlaps(poly1 + i, poly2 + i)) return 0; for (i = len2; i < len1; i++) if (!arb_contains_zero(poly1 + i)) return 0; return 1; } int arb_poly_overlaps(const arb_poly_t poly1, const arb_poly_t poly2) { slong len1 = poly1->length; slong len2 = poly2->length; if (len1 >= len2) return _arb_poly_overlaps(poly1->coeffs, len1, poly2->coeffs, len2); else return _arb_poly_overlaps(poly2->coeffs, len2, poly1->coeffs, len1); } arb-2.22.1/arb_poly/pow_arb_series.c000066400000000000000000000073021417376376500173450ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* (a + bx^c)^g where a = f[0] and b = f[flen-1] */ void _arb_poly_binomial_pow_arb_series(arb_ptr h, arb_srcptr f, slong flen, const arb_t g, slong len, slong prec) { slong i, j, d; arb_t t; arb_init(t); d = flen - 1; arb_pow(h, f, g, prec); arb_div(t, f + d, f, prec); for (i = 1, j = d; j < len; i++, j += d) { arb_sub_ui(h + j, g, i - 1, prec); arb_mul(h + j, h + j, h + j - d, prec); arb_mul(h + j, h + j, t, prec); arb_div_ui(h + j, h + j, i, prec); } if (d > 1) { for (i = 1; i < len; i++) if (i % d != 0) arb_zero(h + i); } arb_clear(t); return; } void _arb_poly_pow_arb_series(arb_ptr h, arb_srcptr f, slong flen, const arb_t g, slong len, slong prec) { int f_binomial, g_exact, g_int; while (flen > 0 && arb_is_zero(f + flen - 1)) flen--; if (flen <= 1) { arb_pow(h, f, g, prec); _arb_vec_zero(h + 1, len - 1); return; } g_exact = arb_is_exact(g); g_int = arb_is_int(g); f_binomial = _arb_vec_is_zero(f + 1, flen - 2); /* g = small integer */ if (g_exact && g_int && arf_cmpabs_2exp_si(arb_midref(g), FLINT_BITS - 1) < 0) { slong e, hlen; e = arf_get_si(arb_midref(g), ARF_RND_DOWN); hlen = poly_pow_length(flen, FLINT_ABS(e), len); if (e >= 0) { _arb_poly_pow_ui_trunc_binexp(h, f, flen, e, hlen, prec); _arb_vec_zero(h + hlen, len - hlen); return; } else if (!f_binomial) { arb_ptr t; t = _arb_vec_init(hlen); _arb_poly_pow_ui_trunc_binexp(t, f, flen, -e, hlen, prec); _arb_poly_inv_series(h, t, hlen, len, prec); _arb_vec_clear(t, hlen); return; } } /* (a + bx^c)^g */ if (f_binomial) { _arb_poly_binomial_pow_arb_series(h, f, flen, g, len, prec); return; } /* g = +/- 1/2 */ if (g_exact && arf_cmpabs_2exp_si(arb_midref(g), -1) == 0) { if (arf_sgn(arb_midref(g)) > 0) _arb_poly_sqrt_series(h, f, flen, len, prec); else _arb_poly_rsqrt_series(h, f, flen, len, prec); return; } /* f^g = exp(g*log(f)) */ _arb_poly_log_series(h, f, flen, len, prec); _arb_vec_scalar_mul(h, h, len, g, prec); _arb_poly_exp_series(h, h, len, len, prec); } void arb_poly_pow_arb_series(arb_poly_t h, const arb_poly_t f, const arb_t g, slong len, slong prec) { slong flen; flen = f->length; flen = FLINT_MIN(flen, len); if (len == 0) { arb_poly_zero(h); return; } if (arb_is_zero(g)) { arb_poly_one(h); return; } if (flen == 0) { arb_poly_zero(h); return; } if (f == h) { arb_poly_t t; arb_poly_init2(t, len); _arb_poly_pow_arb_series(t->coeffs, f->coeffs, flen, g, len, prec); _arb_poly_set_length(t, len); _arb_poly_normalise(t); arb_poly_swap(t, h); arb_poly_clear(t); } else { arb_poly_fit_length(h, len); _arb_poly_pow_arb_series(h->coeffs, f->coeffs, flen, g, len, prec); _arb_poly_set_length(h, len); _arb_poly_normalise(h); } } arb-2.22.1/arb_poly/pow_series.c000066400000000000000000000045221417376376500165220ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_pow_series(arb_ptr h, arb_srcptr f, slong flen, arb_srcptr g, slong glen, slong len, slong prec) { if (glen == 1) { _arb_poly_pow_arb_series(h, f, flen, g, len, prec); return; } /* f^g = exp(g * log(f)) */ if (flen == 1) { arb_t t; arb_init(t); arb_log(t, f, prec); _arb_vec_scalar_mul(h, g, glen, t, prec); _arb_poly_exp_series(h, h, glen, len, prec); arb_clear(t); } else { arb_ptr t; t = _arb_vec_init(len); _arb_poly_log_series(t, f, flen, len, prec); _arb_poly_mullow(h, t, len, g, glen, len, prec); _arb_poly_exp_series(h, h, len, len, prec); _arb_vec_clear(t, len); } } void arb_poly_pow_series(arb_poly_t h, const arb_poly_t f, const arb_poly_t g, slong len, slong prec) { slong flen, glen; flen = f->length; glen = g->length; flen = FLINT_MIN(flen, len); glen = FLINT_MIN(glen, len); if (len == 0) { arb_poly_zero(h); return; } if (glen == 0) { arb_poly_one(h); return; } if (flen == 0) { arb_poly_zero(h); return; } if (flen == 1 && glen == 1) { arb_poly_fit_length(h, 1); arb_pow(h->coeffs, f->coeffs, g->coeffs, prec); _arb_poly_set_length(h, 1); _arb_poly_normalise(h); return; } if (f == h || g == h) { arb_poly_t t; arb_poly_init2(t, len); _arb_poly_pow_series(t->coeffs, f->coeffs, flen, g->coeffs, glen, len, prec); _arb_poly_set_length(t, len); _arb_poly_normalise(t); arb_poly_swap(t, h); arb_poly_clear(t); } else { arb_poly_fit_length(h, len); _arb_poly_pow_series(h->coeffs, f->coeffs, flen, g->coeffs, glen, len, prec); _arb_poly_set_length(h, len); _arb_poly_normalise(h); } } arb-2.22.1/arb_poly/pow_ui.c000066400000000000000000000027161417376376500156500ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_pow_ui(arb_ptr res, arb_srcptr f, slong flen, ulong exp, slong prec) { _arb_poly_pow_ui_trunc_binexp(res, f, flen, exp, exp * (flen - 1) + 1, prec); } void arb_poly_pow_ui(arb_poly_t res, const arb_poly_t poly, ulong exp, slong prec) { slong flen, rlen; flen = poly->length; if (exp == 0) { arb_poly_one(res); } else if (flen == 0) { arb_poly_zero(res); } else { rlen = exp * (flen - 1) + 1; if (res != poly) { arb_poly_fit_length(res, rlen); _arb_poly_pow_ui(res->coeffs, poly->coeffs, flen, exp, prec); _arb_poly_set_length(res, rlen); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, rlen); _arb_poly_pow_ui(t->coeffs, poly->coeffs, flen, exp, prec); _arb_poly_set_length(t, rlen); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } } } arb-2.22.1/arb_poly/pow_ui_trunc_binexp.c000066400000000000000000000063161417376376500204300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #define MUL(z, zlen, x, xlen, y, ylen, trunc, prec) \ do { \ slong slen = FLINT_MIN(xlen + ylen - 1, trunc); \ _arb_poly_mullow(z, x, xlen, y, ylen, slen, prec); \ zlen = slen; \ } while (0) void _arb_poly_pow_ui_trunc_binexp(arb_ptr res, arb_srcptr f, slong flen, ulong exp, slong len, slong prec) { arb_ptr v, R, S, T; slong rlen; ulong bit; if (exp <= 1) { if (exp == 0) arb_one(res); else if (exp == 1) _arb_vec_set_round(res, f, len, prec); return; } /* (f * x^r)^m = x^(rm) * f^m */ while (flen > 1 && arb_is_zero(f)) { if (((ulong) len) > exp) { _arb_vec_zero(res, exp); len -= exp; res += exp; } else { _arb_vec_zero(res, len); return; } f++; flen--; } if (exp == 2) { _arb_poly_mullow(res, f, flen, f, flen, len, prec); return; } if (flen == 1) { arb_pow_ui(res, f, exp, prec); return; } v = _arb_vec_init(len); bit = UWORD(1) << (FLINT_BIT_COUNT(exp) - 2); if (n_zerobits(exp) % 2) { R = res; S = v; } else { R = v; S = res; } MUL(R, rlen, f, flen, f, flen, len, prec); if (bit & exp) { MUL(S, rlen, R, rlen, f, flen, len, prec); T = R; R = S; S = T; } while (bit >>= 1) { if (bit & exp) { MUL(S, rlen, R, rlen, R, rlen, len, prec); MUL(R, rlen, S, rlen, f, flen, len, prec); } else { MUL(S, rlen, R, rlen, R, rlen, len, prec); T = R; R = S; S = T; } } _arb_vec_clear(v, len); } void arb_poly_pow_ui_trunc_binexp(arb_poly_t res, const arb_poly_t poly, ulong exp, slong len, slong prec) { slong flen, rlen; flen = poly->length; if (exp == 0 && len != 0) { arb_poly_one(res); } else if (flen == 0 || len == 0) { arb_poly_zero(res); } else { rlen = poly_pow_length(flen, exp, len); if (res != poly) { arb_poly_fit_length(res, rlen); _arb_poly_pow_ui_trunc_binexp(res->coeffs, poly->coeffs, flen, exp, rlen, prec); _arb_poly_set_length(res, rlen); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, rlen); _arb_poly_pow_ui_trunc_binexp(t->coeffs, poly->coeffs, flen, exp, rlen, prec); _arb_poly_set_length(t, rlen); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } } } arb-2.22.1/arb_poly/product_roots.c000066400000000000000000000033731417376376500172540ustar00rootroot00000000000000/* Copyright (C) 2011 William Hart Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_product_roots(arb_ptr poly, arb_srcptr xs, slong n, slong prec) { if (n == 0) { arb_one(poly); } else if (n == 1) { arb_neg(poly, xs); arb_one(poly + 1); } else if (n == 2) { arb_mul(poly, xs + 0, xs + 1, prec); arb_add(poly + 1, xs + 0, xs + 1, prec); arb_neg(poly + 1, poly + 1); arb_one(poly + 2); } else if (n == 3) { arb_mul(poly + 1, xs, xs + 1, prec); arb_mul(poly, poly + 1, xs + 2, prec); arb_neg(poly, poly); arb_add(poly + 2, xs, xs + 1, prec); arb_addmul(poly + 1, poly + 2, xs + 2, prec); arb_add(poly + 2, poly + 2, xs + 2, prec); arb_neg(poly + 2, poly + 2); arb_one(poly + 3); } else { const slong m = (n + 1) / 2; arb_ptr tmp; tmp = _arb_vec_init(n + 2); _arb_poly_product_roots(tmp, xs, m, prec); _arb_poly_product_roots(tmp + m + 1, xs + m, n - m, prec); _arb_poly_mul_monic(poly, tmp, m + 1, tmp + m + 1, n - m + 1, prec); _arb_vec_clear(tmp, n + 2); } } void arb_poly_product_roots(arb_poly_t poly, arb_srcptr xs, slong n, slong prec) { arb_poly_fit_length(poly, n + 1); _arb_poly_product_roots(poly->coeffs, xs, n, prec); _arb_poly_set_length(poly, n + 1); } arb-2.22.1/arb_poly/product_roots_complex.c000066400000000000000000000054331417376376500210020ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_product_roots_complex(arb_ptr poly, arb_srcptr r, slong rn, acb_srcptr c, slong cn, slong prec) { if (rn == 0 && cn == 0) { arb_one(poly); } else if (rn == 1 && cn == 0) { arb_neg(poly, r); arb_one(poly + 1); } else if (rn == 2 && cn == 0) { arb_mul(poly, r + 0, r + 1, prec); arb_add(poly + 1, r + 0, r + 1, prec); arb_neg(poly + 1, poly + 1); arb_one(poly + 2); } else if (rn == 3 && cn == 0) { arb_mul(poly + 1, r, r + 1, prec); arb_mul(poly, poly + 1, r + 2, prec); arb_neg(poly, poly); arb_add(poly + 2, r, r + 1, prec); arb_addmul(poly + 1, poly + 2, r + 2, prec); arb_add(poly + 2, poly + 2, r + 2, prec); arb_neg(poly + 2, poly + 2); arb_one(poly + 3); } else if (rn == 0 && cn == 1) { arb_mul(poly, acb_realref(c), acb_realref(c), prec); arb_addmul(poly, acb_imagref(c), acb_imagref(c), prec); arb_mul_2exp_si(poly + 1, acb_realref(c), 1); arb_neg(poly + 1, poly + 1); arb_one(poly + 2); } else if (rn == 1 && cn == 1) { arb_mul(poly + 1, acb_realref(c), acb_realref(c), prec); arb_addmul(poly + 1, acb_imagref(c), acb_imagref(c), prec); arb_mul(poly, poly + 1, r, prec); arb_neg(poly, poly); arb_mul_2exp_si(poly + 2, acb_realref(c), 1); arb_addmul(poly + 1, poly + 2, r, prec); arb_add(poly + 2, poly + 2, r, prec); arb_neg(poly + 2, poly + 2); arb_one(poly + 3); } else { slong rm, cm, rm2, cm2; arb_ptr tmp, tmp2; rm = (rn + 1) / 2; cm = cn / 2; rm2 = rn - rm; cm2 = cn - cm; tmp = _arb_vec_init(rn + 2 * cn + 2); tmp2 = tmp + rm + (2 * cm) + 1; _arb_poly_product_roots_complex(tmp, r, rm, c, cm, prec); _arb_poly_product_roots_complex(tmp2, r + rm, rm2, c + cm, cm2, prec); _arb_poly_mul_monic(poly, tmp, rm + 2 * cm + 1, tmp2, rm2 + 2 * cm2 + 1, prec); _arb_vec_clear(tmp, rn + 2 * cn + 2); } } void arb_poly_product_roots_complex(arb_poly_t poly, arb_srcptr r, slong rn, acb_srcptr c, slong cn, slong prec) { arb_poly_fit_length(poly, rn + 2 * cn + 1); _arb_poly_product_roots_complex(poly->coeffs, r, rn, c, cn, prec); _arb_poly_set_length(poly, rn + 2 * cn + 1); } arb-2.22.1/arb_poly/randtest.c000066400000000000000000000015531417376376500161700ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_randtest(arb_poly_t poly, flint_rand_t state, slong len, slong prec, slong mag_bits) { slong i; arb_poly_fit_length(poly, len); if (n_randint(state, 2)) for (i = 0; i < len; i++) arb_randtest(poly->coeffs + i, state, prec, mag_bits); else for (i = 0; i < len; i++) arb_randtest_precise(poly->coeffs + i, state, prec, mag_bits); _arb_poly_set_length(poly, len); _arb_poly_normalise(poly); } arb-2.22.1/arb_poly/reverse.c000066400000000000000000000017101417376376500160120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_reverse(arb_ptr res, arb_srcptr poly, slong len, slong n) { if (res == poly) { slong i; for (i = 0; i < n / 2; i++) { arb_struct t = res[i]; res[i] = res[n - 1 - i]; res[n - 1 - i] = t; } for (i = 0; i < n - len; i++) arb_zero(res + i); } else { slong i; for (i = 0; i < n - len; i++) arb_zero(res + i); for (i = 0; i < len; i++) arb_set(res + (n - len) + i, poly + (len - 1) - i); } } arb-2.22.1/arb_poly/revert_series.c000066400000000000000000000026141417376376500172240ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_revert_series(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec) { _arb_poly_revert_series_lagrange_fast(Qinv, Q, Qlen, n, prec); } void arb_poly_revert_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !arb_is_zero(Q->coeffs) || arb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (arb_poly_revert_series). Input must \n" "have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { arb_poly_fit_length(Qinv, n); _arb_poly_revert_series(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_revert_series(t->coeffs, Q->coeffs, Qlen, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); } _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); } arb-2.22.1/arb_poly/revert_series_lagrange.c000066400000000000000000000041141417376376500210610ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_revert_series_lagrange(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec) { slong i; arb_ptr R, S, T, tmp; if (n <= 2) { if (n >= 1) arb_zero(Qinv); if (n == 2) arb_inv(Qinv + 1, Q + 1, prec); return; } R = _arb_vec_init(n - 1); S = _arb_vec_init(n - 1); T = _arb_vec_init(n - 1); arb_zero(Qinv); arb_inv(Qinv + 1, Q + 1, prec); _arb_poly_inv_series(R, Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); _arb_vec_set(S, R, n - 1); for (i = 2; i < n; i++) { _arb_poly_mullow(T, S, n - 1, R, n - 1, n - 1, prec); arb_div_ui(Qinv + i, T + i - 1, i, prec); tmp = S; S = T; T = tmp; } _arb_vec_clear(R, n - 1); _arb_vec_clear(S, n - 1); _arb_vec_clear(T, n - 1); } void arb_poly_revert_series_lagrange(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !arb_is_zero(Q->coeffs) || arb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (arb_poly_revert_series_lagrange). Input must \n" "have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { arb_poly_fit_length(Qinv, n); _arb_poly_revert_series_lagrange(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_revert_series_lagrange(t->coeffs, Q->coeffs, Qlen, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); } _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); } arb-2.22.1/arb_poly/revert_series_lagrange_fast.c000066400000000000000000000053041417376376500221000ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* pointer to (x/Q)^i */ #define Ri(ii) (R + (n-1)*((ii)-1)) void _arb_poly_revert_series_lagrange_fast(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec) { slong i, j, m; arb_ptr R, S, T, tmp; arb_t t; if (n <= 2) { if (n >= 1) arb_zero(Qinv); if (n == 2) arb_inv(Qinv + 1, Q + 1, prec); return; } m = n_sqrt(n); arb_init(t); R = _arb_vec_init((n - 1) * m); S = _arb_vec_init(n - 1); T = _arb_vec_init(n - 1); arb_zero(Qinv); arb_inv(Qinv + 1, Q + 1, prec); _arb_poly_inv_series(Ri(1), Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); for (i = 2; i <= m; i++) _arb_poly_mullow(Ri(i), Ri((i + 1) / 2), n - 1, Ri(i / 2), n - 1, n - 1, prec); for (i = 2; i < m; i++) arb_div_ui(Qinv + i, Ri(i) + i - 1, i, prec); _arb_vec_set(S, Ri(m), n - 1); for (i = m; i < n; i += m) { arb_div_ui(Qinv + i, S + i - 1, i, prec); for (j = 1; j < m && i + j < n; j++) { arb_dot(t, NULL, 0, S, 1, Ri(j) + i + j - 1, -1, i + j, prec); arb_div_ui(Qinv + i + j, t, i + j, prec); } if (i + 1 < n) { _arb_poly_mullow(T, S, n - 1, Ri(m), n - 1, n - 1, prec); tmp = S; S = T; T = tmp; } } arb_clear(t); _arb_vec_clear(R, (n - 1) * m); _arb_vec_clear(S, n - 1); _arb_vec_clear(T, n - 1); } void arb_poly_revert_series_lagrange_fast(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !arb_is_zero(Q->coeffs) || arb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (arb_poly_revert_series_lagrange_fast). Input \n" "must have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { arb_poly_fit_length(Qinv, n); _arb_poly_revert_series_lagrange_fast(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_revert_series_lagrange_fast(t->coeffs, Q->coeffs, Qlen, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); } _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); } arb-2.22.1/arb_poly/revert_series_newton.c000066400000000000000000000045711417376376500206220ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #define CUTOFF 5 void _arb_poly_revert_series_newton(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong n, slong prec) { slong i, k, a[FLINT_BITS]; arb_ptr T, U, V; if (n <= 2) { if (n >= 1) arb_zero(Qinv); if (n == 2) arb_inv(Qinv + 1, Q + 1, prec); return; } T = _arb_vec_init(n); U = _arb_vec_init(n); V = _arb_vec_init(n); k = n; for (i = 1; (WORD(1) << i) < k; i++); a[i = 0] = k; while (k >= CUTOFF) a[++i] = (k = (k + 1) / 2); _arb_poly_revert_series_lagrange(Qinv, Q, Qlen, k, prec); _arb_vec_zero(Qinv + k, n - k); for (i--; i >= 0; i--) { k = a[i]; _arb_poly_compose_series(T, Q, FLINT_MIN(Qlen, k), Qinv, k, k, prec); _arb_poly_derivative(U, T, k, prec); arb_zero(U + k - 1); arb_zero(T + 1); _arb_poly_div_series(V, T, k, U, k, k, prec); _arb_poly_derivative(T, Qinv, k, prec); _arb_poly_mullow(U, V, k, T, k, k, prec); _arb_vec_sub(Qinv, Qinv, U, k, prec); } _arb_vec_clear(T, n); _arb_vec_clear(U, n); _arb_vec_clear(V, n); } void arb_poly_revert_series_newton(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !arb_is_zero(Q->coeffs) || arb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (arb_poly_revert_series_newton). Input must \n" "have zero constant term and nonzero coefficient of x^1.\n"); flint_abort(); } if (Qinv != Q) { arb_poly_fit_length(Qinv, n); _arb_poly_revert_series_newton(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_revert_series_newton(t->coeffs, Q->coeffs, Qlen, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); } _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); } arb-2.22.1/arb_poly/rgamma_series.c000066400000000000000000000133431417376376500171620ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" slong arf_get_si(const arf_t x, arf_rnd_t rnd); void _arb_poly_lgamma_series_at_one(arb_ptr u, slong len, slong prec); void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec); void _arb_poly_gamma_stirling_eval(arb_ptr res, const arb_t z, slong n, slong num, slong prec); void _arb_poly_rgamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec) { int reflect, isint; slong i, rflen, r, n, wp; arb_ptr t, u, v; arb_struct f[2]; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_rgamma(res, h, prec); _arb_vec_zero(res + 1, len - 1); return; } isint = arb_is_int(h); if (len <= 2 && isint && arf_sgn(arb_midref(h)) <= 0) { int even = arf_is_int_2exp_si(arb_midref(h), 1); /* use res[0] as tmp to allow aliasing */ arb_sub_ui(res, h, 1, prec); arb_neg(res, res); arb_gamma(res, res, prec); arb_mul(res + 1, h + 1, res, prec); if (!even) arb_neg(res + 1, res + 1); arb_zero(res); return; } wp = prec + FLINT_BIT_COUNT(prec); t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(len); arb_init(f); arb_init(f + 1); /* use zeta values at small integers */ if (isint && (arf_cmpabs_ui(arb_midref(h), prec / 2) < 0)) { r = arf_get_si(arb_midref(h), ARF_RND_DOWN); _arb_poly_lgamma_series_at_one(u, len, wp); _arb_vec_neg(u, u, len); _arb_poly_exp_series(t, u, len, len, wp); if (r == 1) { _arb_vec_swap(v, t, len); } else if (r <= 0) { arb_set(f, h); arb_one(f + 1); rflen = FLINT_MIN(len, 2 - r); _arb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), 1 - r, rflen, wp); _arb_poly_mullow(v, t, len, u, rflen, len, wp); } else { arb_one(f); arb_one(f + 1); rflen = FLINT_MIN(len, r); _arb_poly_rising_ui_series(v, f, FLINT_MIN(2, len), r - 1, rflen, wp); /* TODO: use div_series? */ _arb_poly_inv_series(u, v, rflen, len, wp); _arb_poly_mullow(v, t, len, u, len, len, wp); } } else { /* otherwise use Stirling series */ arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 0, wp); /* rgamma(h) = (gamma(1-h+r) sin(pi h)) / (rf(1-h, r) * pi), h = h0 + t*/ if (reflect) { /* u = gamma(r+1-h) */ arb_sub_ui(f, h, r + 1, wp); arb_neg(f, f); _arb_poly_gamma_stirling_eval(t, f, n, len, wp); _arb_poly_exp_series(u, t, len, len, wp); for (i = 1; i < len; i += 2) arb_neg(u + i, u + i); /* v = sin(pi x) */ arb_set(f, h); arb_one(f + 1); _arb_poly_sin_pi_series(v, f, 2, len, wp); _arb_poly_mullow(t, u, len, v, len, len, wp); /* rf(1-h,r) * pi */ if (r == 0) { arb_const_pi(u, wp); _arb_vec_scalar_div(v, t, len, u, wp); } else { arb_sub_ui(f, h, 1, wp); arb_neg(f, f); arb_set_si(f + 1, -1); rflen = FLINT_MIN(len, r + 1); _arb_poly_rising_ui_series(v, f, FLINT_MIN(2, len), r, rflen, wp); arb_const_pi(u, wp); _arb_vec_scalar_mul(v, v, rflen, u, wp); /* divide by rising factorial */ /* TODO: might better to use div_series, when it has a good basecase */ _arb_poly_inv_series(u, v, rflen, len, wp); _arb_poly_mullow(v, t, len, u, len, len, wp); } } else { /* rgamma(h) = rgamma(h+r) rf(h,r) */ if (r == 0) { arb_add_ui(f, h, r, wp); _arb_poly_gamma_stirling_eval(t, f, n, len, wp); _arb_vec_neg(t, t, len); _arb_poly_exp_series(v, t, len, len, wp); } else { arb_set(f, h); arb_one(f + 1); rflen = FLINT_MIN(len, r + 1); _arb_poly_rising_ui_series(t, f, FLINT_MIN(2, len), r, rflen, wp); arb_add_ui(f, h, r, wp); _arb_poly_gamma_stirling_eval(v, f, n, len, wp); _arb_vec_neg(v, v, len); _arb_poly_exp_series(u, v, len, len, wp); _arb_poly_mullow(v, u, len, t, rflen, len, wp); } } } /* compose with nonconstant part */ arb_zero(t); _arb_vec_set(t + 1, h + 1, hlen - 1); _arb_poly_compose_series(res, v, len, t, hlen, len, prec); arb_clear(f); arb_clear(f + 1); _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, len); } void arb_poly_rgamma_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { if (f->length == 0 || n == 0) { arb_poly_zero(res); } else { arb_poly_fit_length(res, n); _arb_poly_rgamma_series(res->coeffs, f->coeffs, f->length, n, prec); _arb_poly_set_length(res, n); _arb_poly_normalise(res); } } arb-2.22.1/arb_poly/riemann_siegel_theta_series.c000066400000000000000000000036561417376376500220720ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "acb_poly.h" void _arb_poly_riemann_siegel_theta_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec) { acb_ptr s; arb_t u; slong i; hlen = FLINT_MIN(hlen, len); s = _acb_vec_init(len); arb_init(u); /* s = 1/4 + (1/2) i h */ for (i = 0; i < hlen; i++) arb_mul_2exp_si(acb_imagref(s + i), h + i, -1); arb_one(u); arb_mul_2exp_si(u, u, -2); arb_add(acb_realref(s), acb_realref(s), u, prec); /* log gamma */ _acb_poly_lgamma_series(s, s, hlen, len, prec); /* imaginary part */ for (i = 0; i < len; i++) arb_set(res + i, acb_imagref(s + i)); /* subtract log(pi)/2 * h */ arb_const_pi(u, prec); arb_log(u, u, prec); arb_mul_2exp_si(u, u, -1); arb_neg(u, u); _arb_vec_scalar_addmul(res, h, hlen, u, prec); _acb_vec_clear(s, len); arb_clear(u); } void arb_poly_riemann_siegel_theta_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { if (n == 0 || f->length == 0) { arb_poly_zero(res); return; } if (res == f) { arb_poly_t tmp; arb_poly_init2(tmp, n); _arb_poly_riemann_siegel_theta_series(tmp->coeffs, f->coeffs, f->length, n, prec); arb_poly_swap(res, tmp); arb_poly_clear(tmp); } else { arb_poly_fit_length(res, n); _arb_poly_riemann_siegel_theta_series(res->coeffs, f->coeffs, f->length, n, prec); } _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/riemann_siegel_z_series.c000066400000000000000000000050261417376376500212270ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "acb_poly.h" void _arb_poly_riemann_siegel_z_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec) { slong i, alloc; arb_ptr t, u, v, w, q; hlen = FLINT_MIN(hlen, len); alloc = 5 * len; t = _arb_vec_init(alloc); u = t + len; v = u + len; w = v + len; q = w + len; /* (v + wi) = zeta(1/2 + i (s+x)) */ { acb_ptr sx, z; acb_t a; slong slen = FLINT_MIN(len, 2); z = _acb_vec_init(len); sx = _acb_vec_init(slen); acb_init(a); acb_one(a); acb_one(sx); acb_mul_2exp_si(sx, sx, -1); arb_set(acb_imagref(sx), h); if (slen > 1) arb_one(acb_imagref(sx + 1)); _acb_poly_zeta_series(z, sx, slen, a, 0, len, prec); for (i = 0; i < len; i++) { arb_set(v + i, acb_realref(z + i)); arb_set(w + i, acb_imagref(z + i)); } acb_clear(a); _acb_vec_clear(z, len); _acb_vec_clear(sx, slen); } /* (t + ui) = exp(i theta(s+x)) */ arb_set(u, h); if (len > 1) arb_one(u + 1); _arb_poly_riemann_siegel_theta_series(t, u, 2, len, prec); _arb_poly_sin_cos_series(u, t, t, len, len, prec); /* (t+ui)(v+wi) = (tv-uw) + (tw+uv)i */ _arb_poly_mullow(q, t, len, v, len, len, prec); _arb_poly_mullow(t, u, len, w, len, len, prec); _arb_vec_sub(t, q, t, len, prec); /* compose with nonconstant part */ arb_zero(u); _arb_vec_set(u + 1, h + 1, hlen - 1); _arb_poly_compose_series(res, t, len, u, hlen, len, prec); _arb_vec_clear(t, alloc); } void arb_poly_riemann_siegel_z_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) { if (n == 0) { arb_poly_zero(res); return; } arb_poly_fit_length(res, n); if (f->length == 0) { arb_t t; arb_init(t); _arb_poly_riemann_siegel_z_series(res->coeffs, t, 1, n, prec); arb_clear(t); } else { _arb_poly_riemann_siegel_z_series(res->coeffs, f->coeffs, f->length, n, prec); } _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/rising_ui_series.c000066400000000000000000000047351417376376500177130ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" static void _arb_poly_rising_ui_series_bsplit(arb_ptr res, arb_srcptr f, slong flen, ulong a, ulong b, slong trunc, slong prec) { flen = FLINT_MIN(flen, trunc); if (b - a == 1) { arb_add_ui(res, f, a, prec); _arb_vec_set(res + 1, f + 1, flen - 1); } else { arb_ptr L, R; slong len1, len2; slong m = a + (b - a) / 2; len1 = poly_pow_length(flen, m - a, trunc); len2 = poly_pow_length(flen, b - m, trunc); L = _arb_vec_init(len1 + len2); R = L + len1; _arb_poly_rising_ui_series_bsplit(L, f, flen, a, m, trunc, prec); _arb_poly_rising_ui_series_bsplit(R, f, flen, m, b, trunc, prec); _arb_poly_mullow(res, L, len1, R, len2, FLINT_MIN(trunc, len1 + len2 - 1), prec); _arb_vec_clear(L, len1 + len2); } } void _arb_poly_rising_ui_series(arb_ptr res, arb_srcptr f, slong flen, ulong r, slong trunc, slong prec) { if (trunc == 1 || flen == 1) { arb_rising_ui(res, f, r, prec); _arb_vec_zero(res + 1, trunc - 1); } else if (trunc == 2) { arb_rising2_ui(res, res + 1, f, r, prec); arb_mul(res + 1, res + 1, f + 1, prec); } else { _arb_poly_rising_ui_series_bsplit(res, f, flen, 0, r, trunc, prec); } } void arb_poly_rising_ui_series(arb_poly_t res, const arb_poly_t f, ulong r, slong trunc, slong prec) { slong len; if ((f->length == 0 && r != 0) || trunc == 0) { arb_poly_zero(res); return; } if (r == 0) { arb_poly_one(res); return; } len = poly_pow_length(f->length, r, trunc); if (f == res) { arb_poly_t tmp; arb_poly_init(tmp); arb_poly_rising_ui_series(tmp, f, r, len, prec); arb_poly_swap(tmp, res); arb_poly_clear(tmp); } else { arb_poly_fit_length(res, len); _arb_poly_rising_ui_series(res->coeffs, f->coeffs, f->length, r, len, prec); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } } arb-2.22.1/arb_poly/root_bound_fujiwara.c000066400000000000000000000023201417376376500203770ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_root_bound_fujiwara(mag_t bound, arb_srcptr poly, slong len) { mag_t t, u, v; slong i; if (len <= 1) { mag_inf(bound); return; } mag_init(t); mag_init(u); mag_init(v); /* u = 1/leading */ arb_get_mag_lower(t, poly + len - 1); mag_one(u); mag_div(u, u, t); mag_zero(v); for (i = 0; i < len - 1; i++) { arb_get_mag(t, poly + len - 2 - i); mag_mul(t, t, u); if (i == len - 2) mag_mul_2exp_si(t, t, -1); mag_root(t, t, i + 1); mag_max(v, v, t); } mag_mul_2exp_si(bound, v, 1); mag_clear(t); mag_clear(u); mag_clear(v); } void arb_poly_root_bound_fujiwara(mag_t bound, arb_poly_t poly) { _arb_poly_root_bound_fujiwara(bound, poly->coeffs, poly->length); } arb-2.22.1/arb_poly/rsqrt_series.c000066400000000000000000000044601417376376500170710ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_rsqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); while (hlen > 0 && arb_is_zero(h + hlen - 1)) hlen--; if (hlen <= 1) { arb_rsqrt(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_rsqrt(g, h, prec); arb_div(g + 1, h + 1, h, prec); arb_mul(g + 1, g + 1, g, prec); arb_mul_2exp_si(g + 1, g + 1, -1); arb_neg(g + 1, g + 1); } else if (_arb_vec_is_zero(h + 1, hlen - 2)) { arb_t t; arb_init(t); arf_set_si_2exp_si(arb_midref(t), -1, -1); _arb_poly_binomial_pow_arb_series(g, h, hlen, t, len, prec); arb_clear(t); } else { arb_ptr t, u; slong tlen; t = _arb_vec_init(2 * len); u = t + len; arb_rsqrt(g, h, prec); NEWTON_INIT(1, len) NEWTON_LOOP(m, n) tlen = FLINT_MIN(2 * m - 1, n); _arb_poly_mullow(t, g, m, g, m, tlen, prec); _arb_poly_mullow(u, g, m, t, tlen, n, prec); _arb_poly_mullow(t, u, n, h, hlen, n, prec); _arb_vec_scalar_mul_2exp_si(g + m, t + m, n - m, -1); _arb_vec_neg(g + m, g + m, n - m); NEWTON_END_LOOP NEWTON_END _arb_vec_clear(t, 2 * len); } } void arb_poly_rsqrt_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { if (n == 0) { arb_poly_zero(g); return; } if (g == h) { arb_poly_t t; arb_poly_init(t); arb_poly_rsqrt_series(t, h, n, prec); arb_poly_swap(g, t); arb_poly_clear(t); return; } arb_poly_fit_length(g, n); if (h->length == 0) _arb_vec_indeterminate(g->coeffs, n); else _arb_poly_rsqrt_series(g->coeffs, h->coeffs, h->length, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/set.c000066400000000000000000000011621417376376500151330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set(arb_poly_t dest, const arb_poly_t src) { slong len = arb_poly_length(src); arb_poly_fit_length(dest, len); _arb_vec_set(dest->coeffs, src->coeffs, len); _arb_poly_set_length(dest, len); } arb-2.22.1/arb_poly/set_coeff_arb.c000066400000000000000000000013241417376376500171210ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_coeff_arb(arb_poly_t poly, slong n, const arb_t x) { arb_poly_fit_length(poly, n + 1); if (n + 1 > poly->length) { _arb_vec_zero(poly->coeffs + poly->length, n - poly->length); poly->length = n + 1; } arb_set(poly->coeffs + n, x); _arb_poly_normalise(poly); } arb-2.22.1/arb_poly/set_coeff_si.c000066400000000000000000000013201417376376500167640ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_coeff_si(arb_poly_t poly, slong n, slong x) { arb_poly_fit_length(poly, n + 1); if (n + 1 > poly->length) { _arb_vec_zero(poly->coeffs + poly->length, n - poly->length); poly->length = n + 1; } arb_set_si(poly->coeffs + n, x); _arb_poly_normalise(poly); } arb-2.22.1/arb_poly/set_fmpq_poly.c000066400000000000000000000014111417376376500172160ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_fmpq_poly(arb_poly_t poly, const fmpq_poly_t src, slong prec) { slong i, len = src->length; arb_poly_fit_length(poly, len); _arb_poly_set_length(poly, len); for (i = 0; i < len; i++) { fmpq t; t.num = (fmpz) src->coeffs[i]; t.den = (fmpz) *src->den; arb_set_fmpq(poly->coeffs + i, &t, prec); } } arb-2.22.1/arb_poly/set_fmpz_poly.c000066400000000000000000000012771417376376500172410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_fmpz_poly(arb_poly_t poly, const fmpz_poly_t src, slong prec) { slong i, len = fmpz_poly_length(src); arb_poly_fit_length(poly, len); _arb_poly_set_length(poly, len); for (i = 0; i < len; i++) arb_set_round_fmpz(poly->coeffs + i, src->coeffs + i, prec); } arb-2.22.1/arb_poly/set_length.c000066400000000000000000000011611417376376500164730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_set_length(arb_poly_t poly, slong len) { slong i; if (poly->length > len) { for (i = len; i < poly->length; i++) arb_zero(poly->coeffs + i); } poly->length = len; } arb-2.22.1/arb_poly/set_round.c000066400000000000000000000012211417376376500163360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_round(arb_poly_t dest, const arb_poly_t src, slong prec) { slong len = arb_poly_length(src); arb_poly_fit_length(dest, len); _arb_vec_set_round(dest->coeffs, src->coeffs, len, prec); _arb_poly_set_length(dest, len); } arb-2.22.1/arb_poly/set_si.c000066400000000000000000000012071417376376500156260ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_si(arb_poly_t poly, slong c) { if (c == 0) { arb_poly_zero(poly); } else { arb_poly_fit_length(poly, 1); arb_set_si(poly->coeffs, c); _arb_poly_set_length(poly, 1); } } arb-2.22.1/arb_poly/set_trunc.c000066400000000000000000000015301417376376500163450ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_trunc(arb_poly_t res, const arb_poly_t poly, slong n) { if (poly == res) { arb_poly_truncate(res, n); } else { slong rlen; rlen = FLINT_MIN(n, poly->length); while (rlen > 0 && arb_is_zero(poly->coeffs + rlen - 1)) rlen--; arb_poly_fit_length(res, rlen); _arb_vec_set(res->coeffs, poly->coeffs, rlen); _arb_poly_set_length(res, rlen); } } arb-2.22.1/arb_poly/set_trunc_round.c000066400000000000000000000016771417376376500175700ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_set_trunc_round(arb_poly_t res, const arb_poly_t poly, slong n, slong prec) { if (poly == res) { arb_poly_truncate(res, n); _arb_vec_set_round(res->coeffs, res->coeffs, res->length, prec); } else { slong rlen; rlen = FLINT_MIN(n, poly->length); while (rlen > 0 && arb_is_zero(poly->coeffs + rlen - 1)) rlen--; arb_poly_fit_length(res, rlen); _arb_vec_set_round(res->coeffs, poly->coeffs, rlen, prec); _arb_poly_set_length(res, rlen); } } arb-2.22.1/arb_poly/shift_left.c000066400000000000000000000024441417376376500164730ustar00rootroot00000000000000/* Copyright (C) 2008, 2009 William Hart Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_shift_left(arb_ptr res, arb_srcptr poly, slong len, slong n) { slong i; /* Copy in reverse to avoid writing over unshifted coefficients */ if (res != poly) { for (i = len; i--; ) arb_set(res + n + i, poly + i); } else { for (i = len; i--; ) arb_swap(res + n + i, res + i); } for (i = 0; i < n; i++) arb_zero(res + i); } void arb_poly_shift_left(arb_poly_t res, const arb_poly_t poly, slong n) { if (n == 0) { arb_poly_set(res, poly); return; } if (poly->length == 0) { arb_poly_zero(res); return; } arb_poly_fit_length(res, poly->length + n); _arb_poly_shift_left(res->coeffs, poly->coeffs, poly->length, n); _arb_poly_set_length(res, poly->length + n); } arb-2.22.1/arb_poly/shift_right.c000066400000000000000000000024101417376376500166470ustar00rootroot00000000000000/* Copyright (C) 2008, 2009 William Hart Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_shift_right(arb_ptr res, arb_srcptr poly, slong len, slong n) { slong i; /* Copy in forward order to avoid writing over unshifted coefficients */ if (res != poly) { for (i = 0; i < len - n; i++) arb_set(res + i, poly + n + i); } else { for (i = 0; i < len - n; i++) arb_swap(res + i, res + n + i); } } void arb_poly_shift_right(arb_poly_t res, const arb_poly_t poly, slong n) { if (n == 0) { arb_poly_set(res, poly); return; } if (poly->length <= n) { arb_poly_zero(res); return; } arb_poly_fit_length(res, poly->length - n); _arb_poly_shift_right(res->coeffs, poly->coeffs, poly->length, n); _arb_poly_set_length(res, poly->length - n); } arb-2.22.1/arb_poly/sin_cos_pi_series.c000066400000000000000000000040341417376376500200400ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sin_cos_pi_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin_cos_pi(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_const_pi(t, prec); arb_mul(t, t, h + 1, prec); arb_sin_cos_pi(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_neg(t, t); arb_mul(c + 1, s, t, prec); arb_clear(t); } else { slong cutoff; if (prec <= 128) { cutoff = 1400; } else { cutoff = 100000 / pow(log(prec), 3); cutoff = FLINT_MIN(cutoff, 700); } if (hlen < cutoff) _arb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 1); else _arb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 1); } } void arb_poly_sin_cos_pi_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } if (hlen == 1) n = 1; arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sin_cos_pi_series(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); } arb-2.22.1/arb_poly/sin_cos_series.c000066400000000000000000000037451417376376500173600ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sin_cos_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin_cos(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_set(t, h + 1); arb_sin_cos(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_neg(t, t); arb_mul(c + 1, s, t, prec); arb_clear(t); } else { slong cutoff; if (prec <= 128) { cutoff = 1400; } else { cutoff = 100000 / pow(log(prec), 3); cutoff = FLINT_MIN(cutoff, 700); } if (hlen < cutoff) _arb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 0); else _arb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 0); } } void arb_poly_sin_cos_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } if (hlen == 1) n = 1; arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sin_cos_series(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); } arb-2.22.1/arb_poly/sin_cos_series_basecase.c000066400000000000000000000040501417376376500211740ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sin_cos_series_basecase(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec, int times_pi) { slong k, alen = FLINT_MIN(n, hlen); arb_ptr a; arb_t t, u; if (times_pi) arb_sin_cos_pi(s, c, h, prec); else arb_sin_cos(s, c, h, prec); if (hlen == 1) { _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); return; } arb_init(t); arb_init(u); a = _arb_vec_init(alen); for (k = 1; k < alen; k++) arb_mul_ui(a + k, h + k, k, prec); if (times_pi) { arb_const_pi(t, prec); _arb_vec_scalar_mul(a + 1, a + 1, alen - 1, t, prec); } for (k = 1; k < n; k++) { arb_dot(t, NULL, 1, a + 1, 1, s + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); arb_dot(u, NULL, 0, a + 1, 1, c + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); arb_div_ui(c + k, t, k, prec); arb_div_ui(s + k, u, k, prec); } arb_clear(t); arb_clear(u); _arb_vec_clear(a, alen); } void arb_poly_sin_cos_series_basecase(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec, int times_pi) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sin_cos_series_basecase(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec, times_pi); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); } arb-2.22.1/arb_poly/sin_cos_series_tangent.c000066400000000000000000000060021417376376500210650ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sin_cos_series_tangent(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong len, slong prec, int times_pi) { arb_ptr t, u, v; arb_t s0, c0; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { if (times_pi) arb_sin_cos_pi(s, c, h, prec); else arb_sin_cos(s, c, h, prec); _arb_vec_zero(s + 1, len - 1); _arb_vec_zero(c + 1, len - 1); return; } /* sin(x) = 2*tan(x/2)/(1+tan(x/2)^2) cos(x) = (1-tan(x/2)^2)/(1+tan(x/2)^2) */ arb_init(s0); arb_init(c0); t = _arb_vec_init(3 * len); u = t + len; v = u + len; /* sin, cos of h0 */ if (times_pi) arb_sin_cos_pi(s0, c0, h, prec); else arb_sin_cos(s0, c0, h, prec); /* t = tan((h-h0)/2) */ arb_zero(u); _arb_vec_scalar_mul_2exp_si(u + 1, h + 1, hlen - 1, -1); if (times_pi) { arb_const_pi(t, prec); _arb_vec_scalar_mul(u + 1, u + 1, hlen - 1, t, prec); } _arb_poly_tan_series(t, u, hlen, len, prec); /* v = 1 + t^2 */ _arb_poly_mullow(v, t, len, t, len, len, prec); arb_add_ui(v, v, 1, prec); /* u = 1/(1+t^2) */ _arb_poly_inv_series(u, v, len, len, prec); /* sine */ _arb_poly_mullow(s, t, len, u, len, len, prec); _arb_vec_scalar_mul_2exp_si(s, s, len, 1); /* cosine */ arb_sub_ui(v, v, 2, prec); _arb_vec_neg(v, v, len); _arb_poly_mullow(c, v, len, u, len, len, prec); /* sin(h0 + h1) = cos(h0) sin(h1) + sin(h0) cos(h1) cos(h0 + h1) = cos(h0) cos(h1) - sin(h0) sin(h1) */ if (!arb_is_zero(s0)) { _arb_vec_scalar_mul(t, s, len, c0, prec); _arb_vec_scalar_mul(u, c, len, s0, prec); _arb_vec_scalar_mul(v, s, len, s0, prec); _arb_vec_add(s, t, u, len, prec); _arb_vec_scalar_mul(t, c, len, c0, prec); _arb_vec_sub(c, t, v, len, prec); } _arb_vec_clear(t, 3 * len); arb_clear(s0); arb_clear(c0); } void arb_poly_sin_cos_series_tangent(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec, int times_pi) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sin_cos_series_tangent(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec, times_pi); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); } arb-2.22.1/arb_poly/sin_pi_series.c000066400000000000000000000026411417376376500171760ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sin_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin_pi(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_sin_cos_pi(g, t, h, prec); arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ arb_const_pi(t, prec); arb_mul(g + 1, g + 1, t, prec); arb_clear(t); } else { arb_ptr t = _arb_vec_init(n); _arb_poly_sin_cos_pi_series(g, t, h, hlen, n, prec); _arb_vec_clear(t, n); } } void arb_poly_sin_pi_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { arb_poly_zero(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_sin_pi_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/sin_series.c000066400000000000000000000025101417376376500165010ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sin_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_sin_cos(g, t, h, prec); arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t = _arb_vec_init(n); _arb_poly_sin_cos_series(g, t, h, hlen, n, prec); _arb_vec_clear(t, n); } } void arb_poly_sin_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { arb_poly_zero(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_sin_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/sinc_pi_series.c000066400000000000000000000034301417376376500173360ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sinc_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sinc_pi(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else { arb_t pi; arb_ptr t, u; arb_init(pi); t = _arb_vec_init(n + 1); u = _arb_vec_init(hlen); arb_const_pi(pi, prec); _arb_vec_set(u, h, hlen); if (arb_is_zero(h)) { _arb_poly_sin_pi_series(t, u, hlen, n + 1, prec); _arb_poly_div_series(g, t + 1, n, u + 1, hlen - 1, n, prec); } else { _arb_poly_sin_pi_series(t, u, hlen, n, prec); _arb_poly_div_series(g, t, n, u, hlen, n, prec); } _arb_vec_scalar_div(g, g, n, pi, prec); arb_clear(pi); _arb_vec_clear(t, n + 1); _arb_vec_clear(u, hlen); } } void arb_poly_sinc_pi_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_one(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_sinc_pi_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/sinc_series.c000066400000000000000000000031201417376376500166420ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sinc_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sinc(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else { arb_ptr t, u; t = _arb_vec_init(n + 1); u = _arb_vec_init(hlen); _arb_vec_set(u, h, hlen); if (arb_is_zero(h)) { _arb_poly_sin_series(t, u, hlen, n + 1, prec); _arb_poly_div_series(g, t + 1, n, u + 1, hlen - 1, n, prec); } else { _arb_poly_sin_series(t, u, hlen, n, prec); _arb_poly_div_series(g, t, n, u, hlen, n, prec); } _arb_vec_clear(t, n + 1); _arb_vec_clear(u, hlen); } } void arb_poly_sinc_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_one(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_sinc_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/sinh_cosh_series.c000066400000000000000000000036031417376376500176710ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sinh_cosh_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sinh_cosh(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_set(t, h + 1); arb_sinh_cosh(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_mul(c + 1, s, t, prec); arb_clear(t); } else { slong cutoff; if (prec <= 128) cutoff = 400; else cutoff = 30000 / pow(log(prec), 3); if (hlen < cutoff) _arb_poly_sinh_cosh_series_basecase(s, c, h, hlen, n, prec); else _arb_poly_sinh_cosh_series_exponential(s, c, h, hlen, n, prec); } } void arb_poly_sinh_cosh_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } if (hlen == 1) n = 1; arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sinh_cosh_series(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); } arb-2.22.1/arb_poly/sinh_cosh_series_basecase.c000066400000000000000000000035101417376376500215140ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sinh_cosh_series_basecase(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { slong k, alen = FLINT_MIN(n, hlen); arb_ptr a; arb_t t, u; arb_sinh_cosh(s, c, h, prec); if (hlen == 1) { _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); return; } arb_init(t); arb_init(u); a = _arb_vec_init(alen); for (k = 1; k < alen; k++) arb_mul_ui(a + k, h + k, k, prec); for (k = 1; k < n; k++) { arb_dot(t, NULL, 0, a + 1, 1, s + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); arb_dot(u, NULL, 0, a + 1, 1, c + k - 1, -1, FLINT_MIN(k, hlen - 1), prec); arb_div_ui(c + k, t, k, prec); arb_div_ui(s + k, u, k, prec); } arb_clear(t); arb_clear(u); _arb_vec_clear(a, alen); } void arb_poly_sinh_cosh_series_basecase(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sinh_cosh_series_basecase(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); } arb-2.22.1/arb_poly/sinh_cosh_series_exponential.c000066400000000000000000000047751417376376500223120ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sinh_cosh_series_exponential(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong len, slong prec) { arb_ptr t, u, v; arb_t s0, c0; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_sinh_cosh(s, c, h, prec); _arb_vec_zero(s + 1, len - 1); _arb_vec_zero(c + 1, len - 1); return; } arb_init(s0); arb_init(c0); t = _arb_vec_init(3 * len); u = t + len; v = u + len; arb_sinh_cosh(s0, c0, h, prec); _arb_vec_set(t + 1, h + 1, hlen - 1); _arb_poly_exp_series(t, t, len, len, prec); /* todo: part of the inverse could be avoided since exp computes it internally to half the length */ _arb_poly_inv_series(u, t, len, len, prec); /* hyperbolic sine */ _arb_vec_sub(s, t, u, len, prec); _arb_vec_scalar_mul_2exp_si(s, s, len, -1); /* hyperbolic cosine */ _arb_vec_add(c, t, u, len, prec); _arb_vec_scalar_mul_2exp_si(c, c, len, -1); /* sinh(h0 + h1) = cosh(h0) sinh(h1) + sinh(h0) cosh(h1) cosh(h0 + h1) = cosh(h0) cosh(h1) + sinh(h0) sinh(h1) */ if (!arb_is_zero(s0)) { _arb_vec_scalar_mul(t, s, len, c0, prec); _arb_vec_scalar_mul(u, c, len, s0, prec); _arb_vec_scalar_mul(v, s, len, s0, prec); _arb_vec_add(s, t, u, len, prec); _arb_vec_scalar_mul(t, c, len, c0, prec); _arb_vec_add(c, t, v, len, prec); } _arb_vec_clear(t, 3 * len); arb_clear(s0); arb_clear(c0); } void arb_poly_sinh_cosh_series_exponential(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sinh_cosh_series_exponential(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); } arb-2.22.1/arb_poly/sinh_series.c000066400000000000000000000025201417376376500166520ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sinh_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sinh(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_sinh_cosh(g, t, h, prec); arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t = _arb_vec_init(n); _arb_poly_sinh_cosh_series(g, t, h, hlen, n, prec); _arb_vec_clear(t, n); } } void arb_poly_sinh_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (hlen == 0 || n == 0) { arb_poly_zero(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_sinh_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/sqrt_series.c000066400000000000000000000036211417376376500167050ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); while (hlen > 0 && arb_is_zero(h + hlen - 1)) hlen--; if (hlen <= 1) { arb_sqrt(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_sqrt(g, h, prec); arb_div(g + 1, h + 1, h, prec); arb_mul(g + 1, g + 1, g, prec); arb_mul_2exp_si(g + 1, g + 1, -1); } else if (_arb_vec_is_zero(h + 1, hlen - 2)) { arb_t t; arb_init(t); arf_set_si_2exp_si(arb_midref(t), 1, -1); _arb_poly_binomial_pow_arb_series(g, h, hlen, t, len, prec); arb_clear(t); } else { arb_ptr t; t = _arb_vec_init(len); _arb_poly_rsqrt_series(t, h, hlen, len, prec); _arb_poly_mullow(g, t, len, h, hlen, len, prec); _arb_vec_clear(t, len); } } void arb_poly_sqrt_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { if (n == 0) { arb_poly_zero(g); return; } if (g == h) { arb_poly_t t; arb_poly_init(t); arb_poly_sqrt_series(t, h, n, prec); arb_poly_swap(g, t); arb_poly_clear(t); return; } arb_poly_fit_length(g, n); if (h->length == 0) _arb_vec_indeterminate(g->coeffs, n); else _arb_poly_sqrt_series(g->coeffs, h->coeffs, h->length, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/sub.c000066400000000000000000000022601417376376500151310ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_sub(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) { slong i, min = FLINT_MIN(len1, len2); for (i = 0; i < min; i++) arb_sub(res + i, poly1 + i, poly2 + i, prec); for (i = min; i < len1; i++) arb_set_round(res + i, poly1 + i, prec); for (i = min; i < len2; i++) arb_neg_round(res + i, poly2 + i, prec); } void arb_poly_sub(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { slong max = FLINT_MAX(poly1->length, poly2->length); arb_poly_fit_length(res, max); _arb_poly_sub(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); _arb_poly_set_length(res, max); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/sub_series.c000066400000000000000000000015731417376376500165110ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void arb_poly_sub_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong len, slong prec) { slong len1, len2; len1 = poly1->length; len2 = poly2->length; len1 = FLINT_MIN(len1, len); len2 = FLINT_MIN(len2, len); len = FLINT_MAX(len1, len2); arb_poly_fit_length(res, len); _arb_poly_sub(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } arb-2.22.1/arb_poly/swinnerton_dyer_ui.c000066400000000000000000000056341417376376500202760ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* Bound based on binomial theorem */ slong _arb_poly_swinnerton_dyer_ui_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)) */ /* experimental heuristic: the bound is 2x too large */ return u * 0.5 + 15; } void _arb_poly_swinnerton_dyer_ui(arb_ptr T, ulong n, slong trunc, slong prec) { arb_ptr square_roots, tmp1, tmp2, tmp3; arb_t one; slong i, j, k, N; if (n == 0) { arb_zero(T); arb_one(T + 1); return; } if (prec == 0) prec = _arb_poly_swinnerton_dyer_ui_prec(n); N = WORD(1) << n; trunc = FLINT_MIN(trunc, N + 1); arb_init(one); arb_one(one); square_roots = _arb_vec_init(n); tmp1 = flint_malloc((N/2 + 1) * sizeof(arb_struct)); tmp2 = flint_malloc((N/2 + 1) * sizeof(arb_struct)); tmp3 = _arb_vec_init(N); for (i = 0; i < n; i++) arb_sqrt_ui(square_roots + i, n_nth_prime(i + 1), prec); /* Build linear factors */ for (i = 0; i < N; i++) { arb_zero(T + i); for (j = 0; j < n; j++) { if ((i >> j) & 1) arb_add(T + i, T + i, square_roots + j, prec); else arb_sub(T + i, T + i, square_roots + j, prec); } } /* 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; _arb_poly_mullow(tmp3, tmp1, stride + 1, tmp2, stride + 1, FLINT_MIN(2 * stride, trunc), prec); _arb_vec_set(T + j, tmp3, FLINT_MIN(2 * stride, trunc)); } } arb_one(T + N); _arb_vec_clear(square_roots, n); flint_free(tmp1); flint_free(tmp2); _arb_vec_clear(tmp3, UWORD(1) << n); arb_clear(one); } void arb_poly_swinnerton_dyer_ui(arb_poly_t poly, ulong n, slong prec) { slong N = WORD(1) << n; arb_poly_fit_length(poly, N + 1); _arb_poly_swinnerton_dyer_ui(poly->coeffs, n, N + 1, prec); _arb_poly_set_length(poly, N + 1); _arb_poly_normalise(poly); } arb-2.22.1/arb_poly/tan_series.c000066400000000000000000000041611417376376500164760ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #define TAN_NEWTON_CUTOFF 20 void _arb_poly_tan_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_tan(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_t t; arb_init(t); arb_tan(g, h, prec); arb_mul(t, g, g, prec); arb_add_ui(t, t, 1, prec); arb_mul(g + 1, t, h + 1, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t, u; t = _arb_vec_init(2 * len); u = t + len; NEWTON_INIT(TAN_NEWTON_CUTOFF, len) NEWTON_BASECASE(n) _arb_poly_sin_cos_series_basecase(t, u, h, hlen, n, prec, 0); _arb_poly_div_series(g, t, n, u, n, n, prec); NEWTON_END_BASECASE NEWTON_LOOP(m, n) _arb_poly_mullow(u, g, m, g, m, n, prec); arb_add_ui(u, u, 1, prec); _arb_poly_atan_series(t, g, m, n, prec); _arb_poly_sub(t + m, h + m, FLINT_MAX(0, hlen - m), t + m, n - m, prec); _arb_poly_mullow(g + m, u, n, t + m, n - m, n - m, prec); NEWTON_END_LOOP NEWTON_END _arb_vec_clear(t, 2 * len); } } void arb_poly_tan_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { if (h->length == 0 || n == 0) { arb_poly_zero(g); return; } if (g == h) { arb_poly_t t; arb_poly_init(t); arb_poly_tan_series(t, h, n, prec); arb_poly_swap(g, t); arb_poly_clear(t); return; } arb_poly_fit_length(g, n); _arb_poly_tan_series(g->coeffs, h->coeffs, h->length, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); } arb-2.22.1/arb_poly/taylor_shift.c000066400000000000000000000021001417376376500170400ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_taylor_shift(arb_ptr poly, const arb_t c, slong n, slong prec) { if (n <= 30 || (n <= 500 && arb_bits(c) == 1 && n < 30 + 3 * sqrt(prec)) || (n <= 100 && arb_bits(c) < 0.01 * prec)) { _arb_poly_taylor_shift_horner(poly, c, n, prec); } else if (prec > 2 * n) { _arb_poly_taylor_shift_convolution(poly, c, n, prec); } else { _arb_poly_taylor_shift_divconquer(poly, c, n, prec); } } void arb_poly_taylor_shift(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) { if (f != g) arb_poly_set_round(g, f, prec); _arb_poly_taylor_shift(g->coeffs, c, g->length, prec); } arb-2.22.1/arb_poly/taylor_shift_convolution.c000066400000000000000000000037571417376376500215220ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_taylor_shift_convolution(arb_ptr p, const arb_t c, slong len, slong prec) { slong i, n = len - 1; arb_t f, d; arb_ptr t, u; if (arb_is_zero(c) || len <= 1) return; t = _arb_vec_init(len); u = _arb_vec_init(len); arb_init(f); arb_init(d); arb_one(f); for (i = 2; i <= n; i++) { arb_mul_ui(f, f, i, prec); arb_mul(p + i, p + i, f, prec); } _arb_poly_reverse(p, p, len, len); arb_one(t + n); for (i = n; i > 0; i--) arb_mul_ui(t + i - 1, t + i, i, prec); if (arb_equal_si(c, -1)) { for (i = 1; i <= n; i += 2) arb_neg(t + i, t + i); } else if (!arb_is_one(c)) { arb_set(d, c); for (i = 1; i <= n; i++) { arb_mul(t + i, t + i, d, prec); arb_mul(d, d, c, prec); } } _arb_poly_mullow(u, p, len, t, len, len, prec); arb_mul(f, f, f, prec); if (arb_bits(f) > 0.25 * prec) { arb_inv(f, f, prec); } else { for (i = 0; i <= n; i++) arb_div(u + i, u + i, f, prec); arb_one(f); } for (i = n; i >= 0; i--) { arb_mul(p + i, u + n - i, f, prec); arb_mul_ui(f, f, (i == 0) ? 1 : i, prec); } _arb_vec_clear(t, len); _arb_vec_clear(u, len); arb_clear(f); arb_clear(d); } void arb_poly_taylor_shift_convolution(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) { if (f != g) arb_poly_set_round(g, f, prec); _arb_poly_taylor_shift_convolution(g->coeffs, c, g->length, prec); } arb-2.22.1/arb_poly/taylor_shift_divconquer.c000066400000000000000000000020241417376376500213040ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_taylor_shift_divconquer(arb_ptr poly, const arb_t c, slong len, slong prec) { arb_struct d[2]; if (len <= 1 || arb_is_zero(c)) return; if (len == 2) { arb_addmul(poly, poly + 1, c, prec); return; } d[0] = *c; arb_init(d + 1); arb_one(d + 1); /* no need to free */ _arb_poly_compose_divconquer(poly, poly, len, d, 2, prec); } void arb_poly_taylor_shift_divconquer(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) { if (f != g) arb_poly_set_round(g, f, prec); _arb_poly_taylor_shift_divconquer(g->coeffs, c, g->length, prec); } arb-2.22.1/arb_poly/taylor_shift_horner.c000066400000000000000000000024021417376376500204220ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" void _arb_poly_taylor_shift_horner(arb_ptr poly, const arb_t c, slong n, slong prec) { slong i, j; if (arb_is_one(c)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) arb_add(poly + j, poly + j, poly + j + 1, prec); } else if (arb_equal_si(c, -1)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) arb_sub(poly + j, poly + j, poly + j + 1, prec); } else if (!arb_is_zero(c)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) arb_addmul(poly + j, poly + j + 1, c, prec); } } void arb_poly_taylor_shift_horner(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) { if (f != g) arb_poly_set_round(g, f, prec); _arb_poly_taylor_shift_horner(g->coeffs, c, g->length, prec); } arb-2.22.1/arb_poly/test/000077500000000000000000000000001417376376500151535ustar00rootroot00000000000000arb-2.22.1/arb_poly/test/t-acos_series.c000066400000000000000000000045701417376376500200650ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("acos_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); arb_poly_acos_series(b, a, n, rbits2); /* Check cos(acos(x)) = x */ arb_poly_sin_cos_series_basecase(d, c, b, n, rbits2, 0); fmpq_poly_truncate(A, n); if (!arb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_acos_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-add.c000066400000000000000000000044501417376376500163130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("add...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; arb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_add(C, A, B); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_add(c, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-add_series.c000066400000000000000000000044531417376376500176700ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("add_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d; slong len, prec; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, 1 + n_randint(state, 10), 100, 10); arb_poly_randtest(b, state, 1 + n_randint(state, 10), 100, 10); arb_poly_randtest(c, state, 1 + n_randint(state, 10), 100, 10); arb_poly_randtest(d, state, 1 + n_randint(state, 10), 100, 10); prec = 2 + n_randint(state, 100); len = n_randint(state, 10); arb_poly_add_series(c, a, b, len, prec); arb_poly_add(d, a, b, prec); arb_poly_truncate(d, len); if (!arb_poly_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_add_series(d, d, b, len, prec); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_add_series(d, a, d, len, prec); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-add_si.c000066400000000000000000000035111417376376500170030ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("add_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d; slong v; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); arb_poly_randtest(b, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); arb_poly_randtest(c, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); arb_poly_randtest(d, state, 1 + n_randint(state, 10), 1 + n_randint(state, 200), 10); v = n_randtest(state); arb_poly_set_si(b, v); arb_poly_add(c, a, b, 2 + n_randint(state, 200)); arb_poly_add_si(d, a, v, 2 + n_randint(state, 200)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_abort(); } arb_poly_add_si(a, a, v, 2 + n_randint(state, 200)); if (!arb_poly_overlaps(a, d)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-asin_series.c000066400000000000000000000045701417376376500200720ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("asin_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); arb_poly_asin_series(b, a, n, rbits2); /* Check sin(asin(x)) = x */ arb_poly_sin_cos_series_basecase(c, d, b, n, rbits2, 0); fmpq_poly_truncate(A, n); if (!arb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_asin_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-atan_series.c000066400000000000000000000054721417376376500200650ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("atan_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); arb_poly_atan_series(b, a, n, rbits2); /* Check 2 atan(x) = atan(2x/(1-x^2)) + C */ arb_poly_mullow(c, a, a, n, rbits2); arb_poly_one(d); arb_poly_sub(c, d, c, rbits2); arb_poly_add(d, a, a, rbits2); if (arb_poly_length(c) != 0) { arb_poly_div_series(c, d, c, n, rbits2); arb_poly_atan_series(c, c, n, rbits2); arb_poly_add(d, b, b, rbits2); /* TODO: also check the first coefficient */ arb_poly_set_coeff_si(c, 0, 0); arb_poly_set_coeff_si(d, 0, 0); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } } arb_poly_atan_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-binomial_transform.c000066400000000000000000000060521417376376500214500ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("binomial_transform...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d; slong j, n, prec; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); n = n_randint(state, 20); prec = 2 + n_randint(state, 200); arb_poly_randtest(a, state, n, prec, 10); arb_poly_randtest(b, state, n, prec, 10); arb_poly_randtest(c, state, n, prec, 10); /* check self-inversion property */ arb_poly_binomial_transform(b, a, n, prec); arb_poly_binomial_transform(c, b, n, prec); arb_poly_set(d, a); arb_poly_truncate(d, n); if (!arb_poly_contains(c, d)) { flint_printf("FAIL (containment)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d: "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_binomial_transform(d, d, n, prec); if (!arb_poly_equal(d, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d: "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* compare with power series operations */ arb_poly_zero(d); for (j = 1; j < n; j++) arb_poly_set_coeff_si(d, j, -1); arb_poly_compose_series(c, a, d, n, prec); for (j = 0; j < n; j++) arb_poly_set_coeff_si(d, j, 1); arb_poly_mullow(c, c, d, n, prec); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL (power series)\n\n"); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-binomial_transform_basecase.c000066400000000000000000000061161417376376500232770ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("binomial_transform_basecase...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d; slong j, n, prec; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); n = n_randint(state, 20); prec = 2 + n_randint(state, 200); arb_poly_randtest(a, state, n, prec, 10); arb_poly_randtest(b, state, n, prec, 10); arb_poly_randtest(c, state, n, prec, 10); /* check self-inversion property */ arb_poly_binomial_transform_basecase(b, a, n, prec); arb_poly_binomial_transform_basecase(c, b, n, prec); arb_poly_set(d, a); arb_poly_truncate(d, n); if (!arb_poly_contains(c, d)) { flint_printf("FAIL (containment)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d: "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_binomial_transform_basecase(d, d, n, prec); if (!arb_poly_equal(d, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d: "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* compare with power series operations */ arb_poly_zero(d); for (j = 1; j < n; j++) arb_poly_set_coeff_si(d, j, -1); arb_poly_compose_series(c, a, d, n, prec); for (j = 0; j < n; j++) arb_poly_set_coeff_si(d, j, 1); arb_poly_mullow(c, c, d, n, prec); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL (power series)\n\n"); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-binomial_transform_convolution.c000066400000000000000000000061321417376376500241060ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("binomial_transform_convolution...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 5000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d; slong j, n, prec; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); n = n_randint(state, 20); prec = 2 + n_randint(state, 200); arb_poly_randtest(a, state, n, prec, 10); arb_poly_randtest(b, state, n, prec, 10); arb_poly_randtest(c, state, n, prec, 10); /* check self-inversion property */ arb_poly_binomial_transform_convolution(b, a, n, prec); arb_poly_binomial_transform_convolution(c, b, n, prec); arb_poly_set(d, a); arb_poly_truncate(d, n); if (!arb_poly_contains(c, d)) { flint_printf("FAIL (containment)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d: "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_binomial_transform_convolution(d, d, n, prec); if (!arb_poly_equal(d, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d: "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* compare with power series operations */ arb_poly_zero(d); for (j = 1; j < n; j++) arb_poly_set_coeff_si(d, j, -1); arb_poly_compose_series(c, a, d, n, prec); for (j = 0; j < n; j++) arb_poly_set_coeff_si(d, j, 1); arb_poly_mullow(c, c, d, n, prec); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL (power series)\n\n"); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-borel_transform.c000066400000000000000000000035251417376376500207630ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("borel_transform...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d; slong n, prec; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); n = n_randint(state, 30); prec = n_randint(state, 200); arb_poly_randtest(a, state, n, prec, 10); arb_poly_randtest(b, state, n, prec, 10); arb_poly_randtest(c, state, n, prec, 10); arb_poly_borel_transform(b, a, prec); arb_poly_inv_borel_transform(c, b, prec); if (!arb_poly_contains(c, a)) { flint_printf("FAIL (containment)\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_borel_transform(d, d, prec); if (!arb_poly_equal(d, b)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_inv_borel_transform(d, d, prec); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-compose.c000066400000000000000000000055171417376376500172350ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_compose(C, A, B); arb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 4); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_compose(c, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_compose(d, d, b, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_compose(d, a, d, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-compose_divconquer.c000066400000000000000000000054601417376376500214710ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_divconquer...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_compose(C, A, B); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_compose_divconquer(c, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_compose_divconquer(d, d, b, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_compose_divconquer(d, a, d, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-compose_horner.c000066400000000000000000000054401417376376500206050ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_compose(C, A, B); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_compose_horner(c, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_compose_horner(d, d, b, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_compose_horner(d, a, d, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-compose_series.c000066400000000000000000000057341417376376500206100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, n; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); fmpq_poly_set_coeff_ui(B, 0, 0); fmpq_poly_compose_series(C, A, B, n); arb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 4); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_compose_series(c, a, b, n, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits3 = %wd\n", n, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_compose_series(d, d, b, n, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_compose_series(d, a, d, n, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-compose_series_brent_kung.c000066400000000000000000000056751417376376500230320ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_series_brent_kung...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, n; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); fmpq_poly_set_coeff_ui(B, 0, 0); fmpq_poly_compose_series(C, A, B, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_compose_series_brent_kung(c, a, b, n, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits3 = %wd\n", n, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_compose_series_brent_kung(d, d, b, n, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_compose_series_brent_kung(d, a, d, n, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-compose_series_horner.c000066400000000000000000000056551417376376500221670ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("compose_series_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, n; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); fmpq_poly_set_coeff_ui(B, 0, 0); fmpq_poly_compose_series(C, A, B, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_compose_series_horner(c, a, b, n, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits3 = %wd\n", n, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_compose_series_horner(d, d, b, n, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_compose_series_horner(d, a, d, n, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-cos_pi_series.c000066400000000000000000000044631417376376500204150ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("cos_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; arb_poly_t S, A, B, C; arb_t pi; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); arb_poly_init(S); arb_poly_init(A); arb_poly_init(B); arb_poly_init(C); arb_init(pi); arb_poly_randtest(S, state, m, bits1, 3); arb_poly_randtest(A, state, m, bits1, 3); arb_poly_randtest(B, state, m, bits1, 3); arb_poly_cos_pi_series(A, S, n1, bits2); arb_const_pi(pi, bits3); arb_poly_set_arb(B, pi); arb_poly_mul(B, S, B, bits3); arb_poly_cos_series(B, B, n2, bits3); arb_poly_set(C, A); arb_poly_truncate(C, FLINT_MIN(n1, n2)); arb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); arb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); arb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_cos_pi_series(S, S, n1, bits2); if (!arb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(S); arb_poly_clear(A); arb_poly_clear(B); arb_poly_clear(C); arb_clear(pi); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-cot_pi_series.c000066400000000000000000000040401417376376500204050ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("cot_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, bits1, bits2, bits3; arb_poly_t S, A, B, C; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); arb_poly_init(S); arb_poly_init(A); arb_poly_init(B); arb_poly_init(C); arb_poly_randtest(S, state, m, bits1, 10); arb_poly_randtest(A, state, m, bits1, 10); arb_poly_randtest(B, state, m, bits1, 10); arb_poly_cot_pi_series(A, S, n1, bits2); arb_poly_sin_cos_pi_series(B, C, S, n1, bits3); arb_poly_div_series(B, C, B, n1, bits3); if (!arb_poly_overlaps(A, B)) { flint_printf("FAIL\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); arb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); arb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_cot_pi_series(S, S, n1, bits2); if (!arb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(S); arb_poly_clear(A); arb_poly_clear(B); arb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-digamma_series.c000066400000000000000000000055161417376376500205400ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("digamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; arb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 300); rbits2 = 2 + n_randint(state, 300); rbits3 = 2 + n_randint(state, 300); m = n_randint(state, 25); n1 = n_randint(state, 25); n2 = n_randint(state, 25); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, m, rbits1, 10); arb_poly_digamma_series(b, a, n1, rbits2); arb_poly_digamma_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); arb_poly_printd(a, 50); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 50); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 50); flint_printf("\n\n"); flint_abort(); } /* check psi(a) + 1/a = psi(a+1) */ arb_poly_inv_series(c, a, n1, rbits2); arb_poly_add(c, b, c, rbits2); arb_poly_add_si(d, a, 1, rbits2); arb_poly_digamma_series(d, d, n1, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_digamma_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-div_series.c000066400000000000000000000061061417376376500177170ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("div_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, p, qbits, rbits1, rbits2; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); p = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, m, qbits); do { fmpq_poly_randtest_not_zero(B, state, n, qbits); } while (B->coeffs[0] == 0); fmpq_poly_div_series(C, A, B, p); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits1); arb_poly_div_series(c, a, b, p, rbits2); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_div_series(d, d, b, p, rbits2); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_div_series(d, a, d, p, rbits2); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_div_series(c, d, d, p, rbits2); arb_poly_div_series(d, d, d, p, rbits2); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 3)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-divrem.c000066400000000000000000000066731417376376500170620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("divrem...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong m, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, Q, R; arb_poly_t a, b, q, r; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(Q); fmpq_poly_init(R); arb_poly_init(a); arb_poly_init(b); arb_poly_init(q); arb_poly_init(r); fmpq_poly_randtest(A, state, m, qbits1); fmpq_poly_randtest_not_zero(B, state, n, qbits2); fmpq_poly_divrem(Q, R, A, B); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_divrem(q, r, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(q, Q) || !arb_poly_contains_fmpq_poly(r, R)) { flint_printf("FAIL\n\n"); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("Q = "); fmpq_poly_print(Q); flint_printf("\n\n"); flint_printf("R = "); fmpq_poly_print(R); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("q = "); arb_poly_printd(q, 15); flint_printf("\n\n"); flint_printf("r = "); arb_poly_printd(r, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_divrem(a, r, a, b, rbits3); if (!arb_poly_equal(a, q)) { flint_printf("FAIL (aliasing q, a)\n\n"); } arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_divrem(b, r, a, b, rbits3); if (!arb_poly_equal(b, q)) { flint_printf("FAIL (aliasing q, b)\n\n"); flint_abort(); } arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_divrem(q, a, a, b, rbits3); if (!arb_poly_equal(a, r)) { flint_printf("FAIL (aliasing r, a)\n\n"); flint_abort(); } arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_divrem(q, b, a, b, rbits3); if (!arb_poly_equal(b, r)) { flint_printf("FAIL (aliasing r, b)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(Q); fmpq_poly_clear(R); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(q); arb_poly_clear(r); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate.c000066400000000000000000000045771417376376500174030ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq_t X, Y; arb_poly_t f; arb_t x, y; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(F); fmpq_init(X); fmpq_init(Y); arb_poly_init(f); arb_init(x); arb_init(y); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); fmpq_randtest(X, state, qbits2); fmpq_poly_evaluate_fmpq(Y, F, X); arb_poly_set_fmpq_poly(f, F, rbits1); arb_set_fmpq(x, X, rbits2); arb_poly_evaluate(y, f, x, rbits3); if (!arb_contains_fmpq(y, Y)) { flint_printf("FAIL\n\n"); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 15); flint_printf("\n\n"); flint_abort(); } /* aliasing */ arb_poly_evaluate(x, f, x, rbits3); if (!arb_contains_fmpq(x, Y)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(F); fmpq_clear(X); fmpq_clear(Y); arb_poly_clear(f); arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate2.c000066400000000000000000000043061417376376500174530ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate2...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t f, g; arb_t x, y1, z1, y2, z2; arb_init(x); arb_init(y1); arb_init(z1); arb_init(y2); arb_init(z2); arb_poly_init(f); arb_poly_init(g); arb_randtest(x, state, 2 + n_randint(state, 1000), 5); arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); arb_poly_derivative(g, f, 2 + n_randint(state, 1000)); arb_poly_evaluate2(y1, z1, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); if (!arb_overlaps(y1, y2) || !arb_overlaps(z1, z2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); arb_printd(y1, 15); flint_printf("\n\n"); flint_printf("z1 = "); arb_printd(z1, 15); flint_printf("\n\n"); flint_printf("y2 = "); arb_printd(y2, 15); flint_printf("\n\n"); flint_printf("z2 = "); arb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_clear(x); arb_clear(y1); arb_clear(z1); arb_clear(y2); arb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate2_acb_rectangular.c000066400000000000000000000043561417376376500226540ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate2_acb_rectangular...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t f, g; acb_t x, y1, z1, y2, z2; acb_init(x); acb_init(y1); acb_init(z1); acb_init(y2); acb_init(z2); arb_poly_init(f); arb_poly_init(g); acb_randtest(x, state, 2 + n_randint(state, 1000), 5); arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); arb_poly_derivative(g, f, 2 + n_randint(state, 1000)); arb_poly_evaluate2_acb_rectangular(y1, z1, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_acb_horner(y2, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_acb_horner(z2, g, x, 2 + n_randint(state, 1000)); if (!acb_overlaps(y1, y2) || !acb_overlaps(z1, z2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("y2 = "); acb_printd(y2, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); acb_clear(x); acb_clear(y1); acb_clear(z1); acb_clear(y2); acb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate2_horner.c000066400000000000000000000043241417376376500210300ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate2_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t f, g; arb_t x, y1, z1, y2, z2; arb_init(x); arb_init(y1); arb_init(z1); arb_init(y2); arb_init(z2); arb_poly_init(f); arb_poly_init(g); arb_randtest(x, state, 2 + n_randint(state, 1000), 5); arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); arb_poly_derivative(g, f, 2 + n_randint(state, 1000)); arb_poly_evaluate2_horner(y1, z1, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); if (!arb_overlaps(y1, y2) || !arb_overlaps(z1, z2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); arb_printd(y1, 15); flint_printf("\n\n"); flint_printf("z1 = "); arb_printd(z1, 15); flint_printf("\n\n"); flint_printf("y2 = "); arb_printd(y2, 15); flint_printf("\n\n"); flint_printf("z2 = "); arb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_clear(x); arb_clear(y1); arb_clear(z1); arb_clear(y2); arb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate2_rectangular.c000066400000000000000000000043361417376376500220450ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate2_rectangular...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t f, g; arb_t x, y1, z1, y2, z2; arb_init(x); arb_init(y1); arb_init(z1); arb_init(y2); arb_init(z2); arb_poly_init(f); arb_poly_init(g); arb_randtest(x, state, 2 + n_randint(state, 1000), 5); arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); arb_poly_derivative(g, f, 2 + n_randint(state, 1000)); arb_poly_evaluate2_rectangular(y1, z1, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); if (!arb_overlaps(y1, y2) || !arb_overlaps(z1, z2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); arb_printd(y1, 15); flint_printf("\n\n"); flint_printf("z1 = "); arb_printd(z1, 15); flint_printf("\n\n"); flint_printf("y2 = "); arb_printd(y2, 15); flint_printf("\n\n"); flint_printf("z2 = "); arb_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_clear(x); arb_clear(y1); arb_clear(z1); arb_clear(y2); arb_clear(z2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate_acb_rectangular.c000066400000000000000000000032771417376376500225730ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_acb_rectangular...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t f; acb_t x, y1, y2; acb_init(x); acb_init(y1); acb_init(y2); arb_poly_init(f); acb_randtest(x, state, 2 + n_randint(state, 1000), 5); arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); arb_poly_evaluate_acb_rectangular(y1, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_acb_horner(y2, f, x, 2 + n_randint(state, 1000)); if (!acb_overlaps(y1, y2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); acb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); acb_printd(y1, 15); flint_printf("\n\n"); flint_printf("y2 = "); acb_printd(y2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); acb_clear(x); acb_clear(y1); acb_clear(y2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate_horner.c000066400000000000000000000046241417376376500207510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq_t X, Y; arb_poly_t f; arb_t x, y; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(F); fmpq_init(X); fmpq_init(Y); arb_poly_init(f); arb_init(x); arb_init(y); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); fmpq_randtest(X, state, qbits2); fmpq_poly_evaluate_fmpq(Y, F, X); arb_poly_set_fmpq_poly(f, F, rbits1); arb_set_fmpq(x, X, rbits2); arb_poly_evaluate_horner(y, f, x, rbits3); if (!arb_contains_fmpq(y, Y)) { flint_printf("FAIL\n\n"); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y, 15); flint_printf("\n\n"); flint_abort(); } /* aliasing */ arb_poly_evaluate_horner(x, f, x, rbits3); if (!arb_contains_fmpq(x, Y)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(F); fmpq_clear(X); fmpq_clear(Y); arb_poly_clear(f); arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate_rectangular.c000066400000000000000000000032631417376376500217610ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_rectangular...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t f; arb_t x, y1, y2; arb_init(x); arb_init(y1); arb_init(y2); arb_poly_init(f); arb_randtest(x, state, 2 + n_randint(state, 1000), 5); arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); arb_poly_evaluate_rectangular(y1, f, x, 2 + n_randint(state, 1000)); arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); if (!arb_overlaps(y1, y2)) { flint_printf("FAIL\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x, 15); flint_printf("\n\n"); flint_printf("y1 = "); arb_printd(y1, 15); flint_printf("\n\n"); flint_printf("y2 = "); arb_printd(y2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_clear(x); arb_clear(y1); arb_clear(y2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate_vec_fast.c000066400000000000000000000051061417376376500212420ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_vec_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq * X, * Y; arb_poly_t f; arb_ptr x, y; qbits1 = 2 + n_randint(state, 100); qbits2 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = n_randint(state, 10); fmpq_poly_init(F); X = _fmpq_vec_init(n); Y = _fmpq_vec_init(n); arb_poly_init(f); x = _arb_vec_init(n); y = _arb_vec_init(n); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); for (i = 0; i < n; i++) fmpq_randtest(X + i, state, qbits2); for (i = 0; i < n; i++) fmpq_poly_evaluate_fmpq(Y + i, F, X + i); arb_poly_set_fmpq_poly(f, F, rbits1); for (i = 0; i < n; i++) arb_set_fmpq(x + i, X + i, rbits2); arb_poly_evaluate_vec_fast(y, f, x, n, rbits3); for (i = 0; i < n; i++) { if (!arb_contains_fmpq(y + i, Y + i)) { flint_printf("FAIL (%wd of %wd)\n\n", i, n); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X + i); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y + i); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x + i, 15); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y + i, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_poly_clear(F); _fmpq_vec_clear(X, n); _fmpq_vec_clear(Y, n); arb_poly_clear(f); _arb_vec_clear(x, n); _arb_vec_clear(y, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-evaluate_vec_iter.c000066400000000000000000000051061417376376500212500ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("evaluate_vec_iter...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq * X, * Y; arb_poly_t f; arb_ptr x, y; qbits1 = 2 + n_randint(state, 100); qbits2 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = n_randint(state, 10); fmpq_poly_init(F); X = _fmpq_vec_init(n); Y = _fmpq_vec_init(n); arb_poly_init(f); x = _arb_vec_init(n); y = _arb_vec_init(n); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); for (i = 0; i < n; i++) fmpq_randtest(X + i, state, qbits2); for (i = 0; i < n; i++) fmpq_poly_evaluate_fmpq(Y + i, F, X + i); arb_poly_set_fmpq_poly(f, F, rbits1); for (i = 0; i < n; i++) arb_set_fmpq(x + i, X + i, rbits2); arb_poly_evaluate_vec_iter(y, f, x, n, rbits3); for (i = 0; i < n; i++) { if (!arb_contains_fmpq(y + i, Y + i)) { flint_printf("FAIL (%wd of %wd)\n\n", i, n); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X + i); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y + i); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x + i, 15); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y + i, 15); flint_printf("\n\n"); flint_abort(); } } fmpq_poly_clear(F); _fmpq_vec_clear(X, n); _fmpq_vec_clear(Y, n); arb_poly_clear(f); _arb_vec_clear(x, n); _arb_vec_clear(y, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-exp_series.c000066400000000000000000000125701417376376500177330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" ARB_DLL extern slong arb_poly_newton_exp_cutoff; int main() { slong iter; flint_rand_t state; flint_printf("exp_series...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b; qbits = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 100); rbits2 = 2 + n_randint(state, 100); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); fmpq_poly_randtest(A, state, m, qbits); fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); fmpq_poly_exp_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_exp_series(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } /* test aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b; qbits = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 100); rbits2 = 2 + n_randint(state, 100); if (n_randint(state, 100) == 0) { m = 1 + n_randint(state, 300); n = 1 + n_randint(state, 300); } else { m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); } fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); fmpq_poly_randtest(A, state, m, qbits); arb_poly_randtest(a, state, 1 + n_randint(state, 300), rbits1, 5); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_exp_series(b, a, n, rbits2); arb_poly_exp_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); } /* test that log(exp(f)) contains f */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2, rbits3; fmpq_poly_t A; arb_poly_t a, b, c; qbits = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 100); rbits2 = 2 + n_randint(state, 100); rbits3 = 2 + n_randint(state, 100); if (iter > 100) { arb_poly_newton_exp_cutoff = 5 + n_randint(state, 50); } if (n_randint(state, 100) == 0) { m = 1 + n_randint(state, 100); n = 1 + n_randint(state, 100); } else { m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); } fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_randtest(b, state, 1 + n_randint(state, 300), rbits1, 5); do { fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_exp_series(b, a, n, rbits3); } while (b->length == 0 || arb_contains_zero(b->coeffs)); arb_poly_log_series(c, b, n, rbits2); fmpq_poly_truncate(A, n); if (!arb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-exp_series_basecase.c000066400000000000000000000121061417376376500215540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" /* hack: avoid overflow since exp currently uses mpfr */ void fmpq_poly_randtest_small(fmpq_poly_t A, flint_rand_t state, slong len, slong bits) { fmpq_poly_randtest(A, state, len, bits); if (A->length > 0) { bits = _fmpz_vec_max_bits(A->coeffs, A->length); bits = FLINT_ABS(bits); fmpz_mul_2exp(A->den, A->den, bits); _fmpq_poly_normalise(A); } } int main() { slong iter; flint_rand_t state; flint_printf("exp_series_basecase...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 40); n = 1 + n_randint(state, 40); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); fmpq_poly_randtest(A, state, m, qbits); fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); fmpq_poly_exp_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_exp_series_basecase(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } /* test aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 40); n = 1 + n_randint(state, 40); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); fmpq_poly_randtest_small(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_exp_series_basecase(b, a, n, rbits2); arb_poly_exp_series_basecase(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); } /* test that log(exp(f)) contains f */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2, rbits3; fmpq_poly_t A; arb_poly_t a, b, c; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 40); n = 1 + n_randint(state, 40); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); do { fmpq_poly_randtest_small(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_exp_series_basecase(b, a, n, rbits3); } while (b->length == 0 || arb_contains_zero(b->coeffs)); arb_poly_log_series(c, b, n, rbits2); fmpq_poly_truncate(A, n); if (!arb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-gamma_series.c000066400000000000000000000062521417376376500202210ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("gamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong m, n1, n2, qbits, rbits1, rbits2, rbits3; fmpq_poly_t A; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 400); rbits2 = 2 + n_randint(state, 400); rbits3 = 2 + n_randint(state, 400); m = 1 + n_randint(state, 25); n1 = 1 + n_randint(state, 25); n2 = 1 + n_randint(state, 25); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest_not_zero(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_gamma_series(b, a, n1, rbits2); arb_poly_gamma_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check gamma(a) * a = gamma(a+1) */ arb_poly_mullow(c, b, a, n1, rbits2); arb_poly_set(d, a); arb_add_ui(d->coeffs, d->coeffs, 1, rbits2); arb_poly_gamma_series(d, d, n1, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation, n1 = %wd)\n\n", n1); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_gamma_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-get_coeff_ptr.c000066400000000000000000000027221417376376500203710ustar00rootroot00000000000000/* Copyright (C) 2010 Sebastian Pancratz Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main(void) { int i, result; flint_rand_t state; flint_printf("get_coeff_ptr...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 1000; i++) { arb_poly_t A; arb_t a; slong n = n_randint(state, 100); arb_poly_init(A); arb_poly_randtest(A, state, n_randint(state, 100), 100, 10); arb_init(a); arb_poly_get_coeff_arb(a, A, n); result = n < arb_poly_length(A) ? arb_equal(a, arb_poly_get_coeff_ptr(A, n)) : arb_poly_get_coeff_ptr(A, n) == NULL; if (!result) { flint_printf("FAIL:\n"); flint_printf("A = "), arb_poly_printd(A, 10), flint_printf("\n\n"); flint_printf("a = "), arb_print(a), flint_printf("\n\n"); flint_printf("n = %wd\n\n", n); flint_abort(); } arb_poly_clear(A); arb_clear(a); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/arb_poly/test/t-get_set_coeff_arb.c000066400000000000000000000031531417376376500212020ustar00rootroot00000000000000/* Copyright (C) 2009 William Hart Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main(void) { int i, j, result; flint_rand_t state; flint_printf("get/set_coeff_arb...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 100; i++) { arb_poly_t a; arb_t x1, x2; slong coeff, len; arb_poly_init(a); arb_init(x1); arb_init(x2); len = n_randint(state, 100) + 1; for (j = 0; j < 100; j++) { arb_randtest(x1, state, 2 + n_randint(state, 200), 10); coeff = n_randint(state, len); arb_poly_set_coeff_arb(a, coeff, x1); arb_poly_get_coeff_arb(x2, a, coeff); result = (arb_equal(x1, x2)); if (!result) { flint_printf("FAIL:\n"); flint_printf("x1 = "), arb_print(x1), flint_printf("\n"); flint_printf("x2 = "), arb_print(x2), flint_printf("\n"); flint_printf("coeff = %wd, length = %wd\n", coeff, len); flint_abort(); } } arb_clear(x1); arb_clear(x2); arb_poly_clear(a); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/arb_poly/test/t-get_unique_fmpz_poly.c000066400000000000000000000041601417376376500220250ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("get_unique_fmpz_poly...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong prec, c; fmpz_poly_t A, B; arb_poly_t a, b; fmpz_poly_init(A); fmpz_poly_init(B); arb_poly_init(a); arb_poly_init(b); fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000)); fmpz_poly_randtest(B, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000)); c = 1 + n_randint(state, 1000); prec = 2 + n_randint(state, 100); for ( ; ; ) { arb_poly_set_fmpz_poly(a, A, prec); arb_poly_set_fmpz_poly(b, B, prec); arb_poly_scalar_mul_2exp_si(b, b, -c); arb_poly_add(a, a, b, prec); arb_poly_sub(a, a, b, prec); if (arb_poly_get_unique_fmpz_poly(B, a)) { if (!fmpz_poly_equal(A, B)) { flint_printf("FAIL\n\n"); flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_abort(); } break; } else { prec *= 2; } } fmpz_poly_clear(A); fmpz_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-graeffe_transform.c000066400000000000000000000050641417376376500212570ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; arb_poly_t a, b, c; arb_ptr roots; arb_t leading; flint_printf("graeffe_transform...."); fflush(stdout); flint_randinit(state); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_init(leading); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong n, prec, i; n = n_randint(state, 20); prec = 2 + n_randint(state, 256); roots = _arb_vec_init(n); arb_randtest(leading, state, prec, n_randint(state, 16)); for (i = 0; i < n; i++) arb_randtest(roots + i, state, prec, n_randint(state, 16)); arb_poly_product_roots(a, roots, n, prec); arb_poly_scalar_mul(a, a, leading, prec); for (i = 0; i < n; i++) arb_sqr(roots + i, roots + i, prec); arb_sqr(leading, leading, prec); arb_poly_product_roots(c, roots, n, prec); arb_poly_scalar_mul(c, c, leading, prec); arb_poly_graeffe_transform(b, a, prec); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL (overlap)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_graeffe_transform(a, a, prec); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("n = %wd, prec = %wd\n\n", n, prec); flint_printf("a: "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b: "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c: "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } _arb_vec_clear(roots, n); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_clear(leading); flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-interpolate_barycentric.c000066400000000000000000000047301417376376500224770ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("interpolate_barycentric...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t P; arb_poly_t R, S; fmpq_t t, u; arb_ptr xs, ys; fmpq_poly_init(P); arb_poly_init(R); arb_poly_init(S); fmpq_init(t); fmpq_init(u); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 5); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); n = P->length; xs = _arb_vec_init(n); ys = _arb_vec_init(n); arb_poly_set_fmpq_poly(R, P, rbits1); if (n > 0) { fmpq_randtest(t, state, qbits2); arb_set_fmpq(xs, t, rbits2); for (i = 1; i < n; i++) { fmpq_randtest_not_zero(u, state, qbits2); fmpq_abs(u, u); fmpq_add(t, t, u); arb_set_fmpq(xs + i, t, rbits2); } } for (i = 0; i < n; i++) arb_poly_evaluate(ys + i, R, xs + i, rbits2); arb_poly_interpolate_barycentric(S, xs, ys, n, rbits3); if (!arb_poly_contains_fmpq_poly(S, P)) { flint_printf("FAIL:\n"); flint_printf("P = "); fmpq_poly_print(P); flint_printf("\n\n"); flint_printf("R = "); arb_poly_printd(R, 15); flint_printf("\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(P); arb_poly_clear(R); arb_poly_clear(S); fmpq_clear(t); fmpq_clear(u); _arb_vec_clear(xs, n); _arb_vec_clear(ys, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-interpolate_fast.c000066400000000000000000000047121417376376500211270ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("interpolate_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t P; arb_poly_t R, S; fmpq_t t, u; arb_ptr xs, ys; fmpq_poly_init(P); arb_poly_init(R); arb_poly_init(S); fmpq_init(t); fmpq_init(u); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 5); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); n = P->length; xs = _arb_vec_init(n); ys = _arb_vec_init(n); arb_poly_set_fmpq_poly(R, P, rbits1); if (n > 0) { fmpq_randtest(t, state, qbits2); arb_set_fmpq(xs, t, rbits2); for (i = 1; i < n; i++) { fmpq_randtest_not_zero(u, state, qbits2); fmpq_abs(u, u); fmpq_add(t, t, u); arb_set_fmpq(xs + i, t, rbits2); } } for (i = 0; i < n; i++) arb_poly_evaluate(ys + i, R, xs + i, rbits2); arb_poly_interpolate_fast(S, xs, ys, n, rbits3); if (!arb_poly_contains_fmpq_poly(S, P)) { flint_printf("FAIL:\n"); flint_printf("P = "); fmpq_poly_print(P); flint_printf("\n\n"); flint_printf("R = "); arb_poly_printd(R, 15); flint_printf("\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(P); arb_poly_clear(R); arb_poly_clear(S); fmpq_clear(t); fmpq_clear(u); _arb_vec_clear(xs, n); _arb_vec_clear(ys, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-interpolate_newton.c000066400000000000000000000047161417376376500215100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("interpolate_newton...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t P; arb_poly_t R, S; fmpq_t t, u; arb_ptr xs, ys; fmpq_poly_init(P); arb_poly_init(R); arb_poly_init(S); fmpq_init(t); fmpq_init(u); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 5); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); n = P->length; xs = _arb_vec_init(n); ys = _arb_vec_init(n); arb_poly_set_fmpq_poly(R, P, rbits1); if (n > 0) { fmpq_randtest(t, state, qbits2); arb_set_fmpq(xs, t, rbits2); for (i = 1; i < n; i++) { fmpq_randtest_not_zero(u, state, qbits2); fmpq_abs(u, u); fmpq_add(t, t, u); arb_set_fmpq(xs + i, t, rbits2); } } for (i = 0; i < n; i++) arb_poly_evaluate(ys + i, R, xs + i, rbits2); arb_poly_interpolate_newton(S, xs, ys, n, rbits3); if (!arb_poly_contains_fmpq_poly(S, P)) { flint_printf("FAIL:\n"); flint_printf("P = "); fmpq_poly_print(P); flint_printf("\n\n"); flint_printf("R = "); arb_poly_printd(R, 15); flint_printf("\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(P); arb_poly_clear(R); arb_poly_clear(S); fmpq_clear(t); fmpq_clear(u); _arb_vec_clear(xs, n); _arb_vec_clear(ys, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-inv_series.c000066400000000000000000000043051417376376500177300ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("inv_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); do { fmpq_poly_randtest_not_zero(A, state, m, qbits); } while (A->coeffs[0] == 0); arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); fmpq_poly_inv_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_inv_series(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_inv_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-lambertw_series.c000066400000000000000000000104421417376376500207500ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("lambertw_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_poly_t x1, x2, t, w1, w2; slong prec1, prec2, n1, n2, ebits; int branch; arb_poly_init(x1); arb_poly_init(x2); arb_poly_init(t); arb_poly_init(w1); arb_poly_init(w2); branch = n_randint(state, 2); n1 = n_randint(state, 15); n2 = n_randint(state, 15); if (n_randint(state, 4) == 0) { prec1 = 2 + n_randint(state, 3000); prec2 = 2 + n_randint(state, 3000); ebits = 1 + n_randint(state, 1000); } else { prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 50); } arb_poly_randtest(x1, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); arb_poly_randtest(x2, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); arb_poly_randtest(t, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); arb_poly_randtest(w1, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); arb_poly_randtest(w2, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000), ebits); if (n_randint(state, 4) == 0) { arb_t u; arb_init(u); arb_const_e(u, 2 * prec1); arb_inv(u, u, 2 * prec1); arb_poly_set_arb(t, u); arb_poly_sub(x1, x1, t, 2 * prec1); arb_clear(u); } if (n_randint(state, 2)) { arb_poly_set(x2, x1); } else { arb_poly_add(x2, x1, t, 2 * prec1); arb_poly_sub(x2, x2, t, 2 * prec1); } arb_poly_lambertw_series(w1, x1, branch, n1, prec1); if (n_randint(state, 2)) { arb_poly_set(w2, x2); arb_poly_lambertw_series(w2, w2, branch, n2, prec1); } else { arb_poly_lambertw_series(w2, x2, branch, n2, prec1); } arb_poly_truncate(w1, FLINT_MIN(n1, n2)); arb_poly_truncate(w2, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(w1, w2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("branch = %d, prec1 = %wd, prec2 = %wd\n\n", branch, prec1, prec2); flint_printf("x1 = "); arb_poly_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); arb_poly_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); arb_poly_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); arb_poly_printd(w2, 50); flint_printf("\n\n"); flint_abort(); } arb_poly_exp_series(t, w1, FLINT_MIN(n1, n2), prec1); arb_poly_mullow(t, t, w1, FLINT_MIN(n1, n2), prec1); arb_poly_truncate(x1, FLINT_MIN(n1, n2)); if (!arb_poly_contains(t, x1)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("branch = %d, prec1 = %wd, prec2 = %wd\n\n", branch, prec1, prec2); flint_printf("x1 = "); arb_poly_printd(x1, 50); flint_printf("\n\n"); flint_printf("x2 = "); arb_poly_printd(x2, 50); flint_printf("\n\n"); flint_printf("w1 = "); arb_poly_printd(w1, 50); flint_printf("\n\n"); flint_printf("w2 = "); arb_poly_printd(w2, 50); flint_printf("\n\n"); flint_printf("t = "); arb_poly_printd(t, 50); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(x1); arb_poly_clear(x2); arb_poly_clear(t); arb_poly_clear(w1); arb_poly_clear(w2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-lgamma_series.c000066400000000000000000000063741417376376500204020ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("lgamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, qbits, rbits1, rbits2, rbits3; fmpq_poly_t A; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 400); rbits2 = 2 + n_randint(state, 400); rbits3 = 2 + n_randint(state, 400); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest_not_zero(A, state, m, qbits); fmpz_abs(A->coeffs, A->coeffs); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_lgamma_series(b, a, n1, rbits2); arb_poly_lgamma_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check loggamma(a) + log(a) = loggamma(a+1) */ arb_poly_log_series(c, a, n1, rbits2); arb_poly_add(c, b, c, rbits2); arb_poly_set(d, a); arb_add_ui(d->coeffs, d->coeffs, 1, rbits2); arb_poly_lgamma_series(d, d, n1, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_lgamma_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-log1p_series.c000066400000000000000000000040661417376376500201620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("log1p_series...."); fflush(stdout); flint_randinit(state); /* compare with log_series */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c; slong m, n, prec; prec = 2 + n_randint(state, 200); m = n_randint(state, 10); n = n_randint(state, 10); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_randtest(a, state, 1 + n_randint(state, 10), prec, 5); arb_poly_randtest(b, state, 1 + n_randint(state, 10), prec, 5); arb_poly_randtest(c, state, 1 + n_randint(state, 10), prec, 5); if (n_randint(state, 2)) arb_poly_log1p_series(b, a, n, prec); else { arb_poly_set(b, a); arb_poly_log1p_series(b, b, n, prec); } arb_poly_add_si(c, a, 1, prec); arb_poly_log_series(c, c, m, prec); arb_poly_truncate(b, FLINT_MIN(m, n)); arb_poly_truncate(c, FLINT_MIN(m, n)); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL\n\n"); flint_printf("m = %wd, n = %wd\n\n", m, n); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-log_series.c000066400000000000000000000115401417376376500177140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("log_series...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); fmpq_poly_randtest_not_zero(A, state, m, qbits); fmpq_poly_set_coeff_ui(A, 0, UWORD(1)); fmpq_poly_log_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); arb_poly_log_series(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } /* test aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); do { fmpq_poly_randtest_not_zero(A, state, m, qbits); } while (fmpz_sgn(A->coeffs + 0) <= 0); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_log_series(b, a, n, rbits2); arb_poly_log_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); } /* test that exp(log(f)) contains f */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2, rbits3; fmpq_poly_t A; arb_poly_t a, b, c; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); do { fmpq_poly_randtest_not_zero(A, state, m, qbits); } while (fmpz_sgn(A->coeffs + 0) <= 0); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); arb_poly_log_series(b, a, n, rbits2); arb_poly_exp_series_basecase(c, b, n, rbits3); fmpq_poly_truncate(A, n); if (!arb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-mul.c000066400000000000000000000072761417376376500163710ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_mul(C, A, B); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_mul(c, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_mul(d, d, b, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_mul(d, a, d, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ arb_poly_set(b, a); arb_poly_mul(c, a, b, rbits3); arb_poly_mul(d, a, a, rbits3); if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_mul(a, a, a, rbits3); if (!arb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-mullow.c000066400000000000000000000076071417376376500171110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mullow...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_mullow(C, A, B, trunc); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_mullow(c, a, b, trunc, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_mullow(d, d, b, trunc, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_mullow(d, a, d, trunc, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ arb_poly_set(b, a); arb_poly_mullow(c, a, b, trunc, rbits3); arb_poly_mullow(d, a, a, trunc, rbits3); if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_mullow(a, a, a, trunc, rbits3); if (!arb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-mullow_block.c000066400000000000000000000153721417376376500202610ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mullow_block...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 1000); qbits2 = 2 + n_randint(state, 1000); rbits1 = 2 + n_randint(state, 1000); rbits2 = 2 + n_randint(state, 1000); rbits3 = 2 + n_randint(state, 1000); trunc = n_randint(state, 100); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 100), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 100), qbits2); fmpq_poly_mullow(C, A, B, trunc); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_mullow_block(c, a, b, trunc, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_mullow_block(d, d, b, trunc, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_mullow_block(d, a, d, trunc, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ arb_poly_set(b, a); arb_poly_mullow_block(c, a, b, trunc, rbits3); arb_poly_mullow_block(d, a, a, trunc, rbits3); if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_mullow_block(a, a, a, trunc, rbits3); if (!arb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong rbits1, rbits2, rbits3, trunc; arb_poly_t a, b, c, ab, ac, bc, abc, abc2; rbits1 = 2 + n_randint(state, 300); rbits2 = 2 + n_randint(state, 300); rbits3 = 2 + n_randint(state, 300); trunc = n_randint(state, 100); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(ab); arb_poly_init(ac); arb_poly_init(bc); arb_poly_init(abc); arb_poly_init(abc2); arb_poly_randtest(a, state, 1 + n_randint(state, 100), rbits1, 1 + n_randint(state, 100)); arb_poly_randtest(b, state, 1 + n_randint(state, 100), rbits2, 1 + n_randint(state, 100)); arb_poly_randtest(c, state, 1 + n_randint(state, 100), rbits2, 1 + n_randint(state, 100)); /* check a*(b+c) = a*b + a*c */ arb_poly_mullow_block(ab, a, b, trunc, rbits3); arb_poly_mullow_block(ac, a, c, trunc, rbits3); arb_poly_add(abc, ab, ac, rbits3); arb_poly_add(bc, b, c, rbits3); arb_poly_mullow_block(abc2, a, bc, trunc, rbits3); if (!arb_poly_overlaps(abc, abc2)) { flint_printf("FAIL (a*(b+c) = a*b + a*c) \n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check (b+c)^2 = b^2 + 2bc + c^2 */ arb_poly_mullow_block(a, b, c, trunc, rbits3); arb_poly_scalar_mul_2exp_si(a, a, 1); arb_poly_mullow_block(abc, b, b, trunc, rbits3); arb_poly_mullow_block(abc2, c, c, trunc, rbits3); arb_poly_add(abc, abc, a, rbits3); arb_poly_add(abc, abc, abc2, rbits3); arb_poly_mullow_block(abc2, bc, bc, trunc, rbits3); if (!arb_poly_overlaps(abc, abc2)) { flint_printf("FAIL ((b+c)^2 = b^2 + 2bc + c^2) \n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("abc = "); arb_poly_printd(abc, 15); flint_printf("\n\n"); flint_printf("abc2 = "); arb_poly_printd(abc2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(ab); arb_poly_clear(ac); arb_poly_clear(bc); arb_poly_clear(abc); arb_poly_clear(abc2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-mullow_classical.c000066400000000000000000000077151417376376500211270ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("mullow_classical...."); fflush(stdout); flint_randinit(state); /* compare with fmpq_poly */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3, trunc; fmpq_poly_t A, B, C; arb_poly_t a, b, c, d; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); trunc = n_randint(state, 10); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_mullow(C, A, B, trunc); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_mullow_classical(c, a, b, trunc, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_mullow_classical(d, d, b, trunc, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_mullow_classical(d, a, d, trunc, rbits3); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } /* test squaring */ arb_poly_set(b, a); arb_poly_mullow_classical(c, a, b, trunc, rbits3); arb_poly_mullow_classical(d, a, a, trunc, rbits3); if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ { flint_printf("FAIL (squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_mullow_classical(a, a, a, trunc, rbits3); if (!arb_poly_equal(d, a)) { flint_printf("FAIL (aliasing, squaring)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-pow_arb_series.c000066400000000000000000000052551417376376500205720ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_arb_series...."); fflush(stdout); flint_randinit(state); /* compare with exp/log */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong prec, trunc; arb_poly_t f, g, h1, h2; arb_t c; prec = 2 + n_randint(state, 200); trunc = n_randint(state, 20); arb_poly_init(f); arb_poly_init(g); arb_poly_init(h1); arb_poly_init(h2); arb_init(c); /* generate binomials */ if (n_randint(state, 20) == 0) { arb_randtest(c, state, prec, 10); arb_poly_set_coeff_arb(f, 0, c); arb_randtest(c, state, prec, 10); arb_poly_set_coeff_arb(f, 1 + n_randint(state, 20), c); } else { arb_poly_randtest(f, state, 1 + n_randint(state, 20), prec, 10); } arb_poly_randtest(h1, state, 1 + n_randint(state, 20), prec, 10); arb_randtest(c, state, prec, 10); arb_poly_set_arb(g, c); /* f^c */ arb_poly_pow_arb_series(h1, f, c, trunc, prec); /* f^c = exp(c*log(f)) */ arb_poly_log_series(h2, f, trunc, prec); arb_poly_mullow(h2, h2, g, trunc, prec); arb_poly_exp_series(h2, h2, trunc, prec); if (!arb_poly_overlaps(h1, h2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("trunc = %wd\n", trunc); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("h1 = "); arb_poly_printd(h1, 15); flint_printf("\n\n"); flint_printf("h2 = "); arb_poly_printd(h2, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_pow_arb_series(f, f, c, trunc, prec); if (!arb_poly_overlaps(f, h1)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_poly_clear(h1); arb_poly_clear(h2); arb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-pow_series.c000066400000000000000000000055551417376376500177510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 50000 * arb_test_multiplier(); iter++) { slong rbits1, rbits2, len; arb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); len = n_randint(state, 25); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); if (n_randint(state, 4) == 0) arb_poly_randtest(a, state, 1, rbits1, 25); else arb_poly_randtest(a, state, 1 + n_randint(state, 20), rbits1, 5); if (n_randint(state, 4) == 0) arb_poly_randtest(b, state, 1, rbits1, 25); else arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); arb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 5); arb_poly_pow_series(c, a, b, len, rbits2); /* a^b = exp(b log a) */ arb_poly_log_series(d, a, len, rbits2); arb_poly_mullow(d, d, b, len, rbits2); arb_poly_exp_series(d, d, len, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (iter %wd)\n\n", iter); flint_printf("bits2 = %wd\n", rbits2); flint_printf("len = %wd\n", len); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } /* check aliasing */ if (iter < 5000) { arb_poly_set(d, a); arb_poly_pow_series(d, d, b, len, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (aliasing 1)\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_pow_series(d, a, d, len, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (aliasing 2)\n"); flint_abort(); } } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-pow_ui.c000066400000000000000000000041531417376376500170650ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_ui...."); fflush(stdout); flint_randinit(state); /* compare with fmpz_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong zbits1, rbits1, rbits2; ulong e; fmpz_poly_t A, B; arb_poly_t a, b; zbits1 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); e = n_randint(state, 30); fmpz_poly_init(A); fmpz_poly_init(B); arb_poly_init(a); arb_poly_init(b); fmpz_poly_randtest(A, state, 1 + n_randint(state, 8), zbits1); fmpz_poly_pow(B, A, e); arb_poly_set_fmpz_poly(a, A, rbits1); arb_poly_pow_ui(b, a, e, rbits2); if (!arb_poly_contains_fmpz_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("e = %wu\n", e); flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_pow_ui(a, a, e, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpz_poly_clear(A); fmpz_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-pow_ui_trunc_binexp.c000066400000000000000000000044151417376376500216460ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_ui_trunc_binexp...."); fflush(stdout); flint_randinit(state); /* compare with fmpz_poly */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong zbits1, rbits1, rbits2, trunc; ulong e; fmpz_poly_t A, B; arb_poly_t a, b; zbits1 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); e = n_randint(state, 50); trunc = n_randint(state, 40); fmpz_poly_init(A); fmpz_poly_init(B); arb_poly_init(a); arb_poly_init(b); fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), zbits1); fmpz_poly_pow_trunc(B, A, e, trunc); arb_poly_set_fmpz_poly(a, A, rbits1); arb_poly_pow_ui_trunc_binexp(b, a, e, trunc, rbits2); if (!arb_poly_contains_fmpz_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("e = %wu\n", e); flint_printf("trunc = %wd\n", trunc); flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_pow_ui_trunc_binexp(a, a, e, trunc, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpz_poly_clear(A); fmpz_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-product_roots.c000066400000000000000000000042311417376376500204660ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("product_roots...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { slong prec, len, m, i; arb_poly_t a, b, c, d; arb_ptr r; prec = 2 + n_randint(state, 200); len = n_randint(state, 12); if (len > 0) m = n_randint(state, len); else m = 0; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); r = _arb_vec_init(len); for (i = 0; i < len; i++) arb_randtest(r + i, state, 1 + n_randint(state, 200), 10); arb_poly_product_roots(a, r, len, prec); arb_poly_product_roots(b, r, m, prec); arb_poly_product_roots(c, r + m, len - m, prec); arb_poly_mul(d, b, c, prec); if (!arb_poly_overlaps(a, d)) { flint_printf("FAIL\n\n"); flint_printf("len = %wd, m = %wd\n\n", len, m); for (i = 0; i < len; i++) { arb_printd(r + i, 15); flint_printf("\n"); } flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); _arb_vec_clear(r, len); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-product_roots_complex.c000066400000000000000000000052461417376376500222240ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "acb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("product_roots_complex...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong prec, len1, len2, i; arb_poly_t a; acb_poly_t b, c; arb_ptr r; acb_ptr r2, r3; prec = 2 + n_randint(state, 200); len1 = n_randint(state, 12); len2 = n_randint(state, 8); arb_poly_init(a); acb_poly_init(b); acb_poly_init(c); r = _arb_vec_init(len1); r2 = _acb_vec_init(len2); r3 = _acb_vec_init(len1 + 2 * len2); for (i = 0; i < len1; i++) arb_randtest(r + i, state, 1 + n_randint(state, 200), 3); for (i = 0; i < len2; i++) acb_randtest(r2 + i, state, 1 + n_randint(state, 200), 3); for (i = 0; i < len1; i++) acb_set_arb(r3 + i, r + i); for (i = 0; i < len2; i++) acb_set(r3 + len1 + i, r2 + i); for (i = 0; i < len2; i++) acb_conj(r3 + len1 + len2 + i, r2 + i); arb_poly_product_roots_complex(a, r, len1, r2, len2, prec); acb_poly_product_roots(b, r3, len1 + 2 * len2, prec); acb_poly_set_arb_poly(c, a); if (!acb_poly_overlaps(b, c)) { flint_printf("FAIL\n\n"); flint_printf("len1 = %wd, len2 = %wd\n\n", len1, len2); for (i = 0; i < len1; i++) { arb_printd(r + i, 15); flint_printf("\n"); } for (i = 0; i < len2; i++) { acb_printd(r2 + i, 15); flint_printf("\n"); } flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); _arb_vec_clear(r, len1); _acb_vec_clear(r2, len2); _acb_vec_clear(r3, len1 + 2 * len2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-revert_series.c000066400000000000000000000044251417376376500204460ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; arb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_revert_series(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(c, a); arb_poly_revert_series(c, c, n, rbits2); if (!arb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-revert_series_lagrange.c000066400000000000000000000044601417376376500223050ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series_lagrange...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; arb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_revert_series_lagrange(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(c, a); arb_poly_revert_series_lagrange(c, c, n, rbits2); if (!arb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-revert_series_lagrange_fast.c000066400000000000000000000044771417376376500233320ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series_lagrange_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; arb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_revert_series_lagrange_fast(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(c, a); arb_poly_revert_series_lagrange_fast(c, c, n, rbits2); if (!arb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-revert_series_newton.c000066400000000000000000000044521417376376500220400ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("revert_series_newton...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong qbits1, rbits1, rbits2, n; fmpq_poly_t A, B; arb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); n = 2 + n_randint(state, 25); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); do { fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); fmpq_poly_set_coeff_ui(A, 0, 0); } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); fmpq_poly_revert_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_revert_series_newton(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, bits2 = %wd\n", n, rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(c, a); arb_poly_revert_series_newton(c, c, n, rbits2); if (!arb_poly_equal(c, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-rgamma_series.c000066400000000000000000000062061417376376500204020ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rgamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong m, n1, n2, qbits, rbits1, rbits2, rbits3; fmpq_poly_t A; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 400); rbits2 = 2 + n_randint(state, 400); rbits3 = 2 + n_randint(state, 400); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest_not_zero(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_rgamma_series(b, a, n1, rbits2); arb_poly_rgamma_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check rgamma(a) = a gamma(a+1) */ arb_poly_add_si(d, a, 1, rbits2); arb_poly_rgamma_series(d, d, n1, rbits2); arb_poly_mullow(c, d, a, n1, rbits2); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL (functional equation, n1 = %wd)\n\n", n1); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_rgamma_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-riemann_siegel_theta_series.c000066400000000000000000000060331417376376500233020ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("riemann_siegel_theta_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 300 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; arb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 150); rbits2 = 2 + n_randint(state, 150); rbits3 = 2 + n_randint(state, 150); m = 1 + n_randint(state, 15); n1 = 1 + n_randint(state, 15); n2 = 1 + n_randint(state, 15); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, m, rbits1, 10); /* if (a->length != 0) arb_randtest_precise(a->coeffs, state, rbits1, 1); */ arb_poly_randtest(b, state, m, rbits1, 10); arb_poly_randtest(c, state, m, rbits1, 10); arb_poly_riemann_siegel_theta_series(b, a, n1, rbits2); arb_poly_riemann_siegel_theta_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check theta(a) = -theta(-a) */ arb_poly_neg(d, a); arb_poly_riemann_siegel_theta_series(c, d, n1, rbits2); arb_poly_neg(c, c); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL (symmetry, n1 = %wd)\n\n", n1); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_riemann_siegel_theta_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-riemann_siegel_z_series.c000066400000000000000000000057341417376376500224550ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("riemann_siegel_z_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 300 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; arb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 150); rbits2 = 2 + n_randint(state, 150); rbits3 = 2 + n_randint(state, 150); m = 1 + n_randint(state, 15); n1 = 1 + n_randint(state, 15); n2 = 1 + n_randint(state, 15); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, m, rbits1, 10); if (a->length != 0) arb_randtest_precise(a->coeffs, state, rbits1, 1); arb_poly_randtest(b, state, m, rbits1, 10); arb_poly_randtest(c, state, m, rbits1, 10); arb_poly_riemann_siegel_z_series(b, a, n1, rbits2); arb_poly_riemann_siegel_z_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } /* check Z(a) = Z(-a) */ arb_poly_neg(d, a); arb_poly_riemann_siegel_z_series(c, d, n1, rbits2); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL (symmetry, n1 = %wd)\n\n", n1); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_riemann_siegel_z_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-rising_ui_series.c000066400000000000000000000064711417376376500211320ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rising_ui_series...."); fflush(stdout); flint_randinit(state); /* check rf(f, a) * rf(f + a, b) = rf(f, a + b) */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong bits, trunc; ulong a, b; arb_poly_t f, g, h1, h2, h1h2, h3; bits = 2 + n_randint(state, 200); trunc = 1 + n_randint(state, 20); a = n_randint(state, 10); b = n_randint(state, 10); arb_poly_init(f); arb_poly_init(g); arb_poly_init(h1); arb_poly_init(h2); arb_poly_init(h1h2); arb_poly_init(h3); arb_poly_randtest(f, state, 1 + n_randint(state, 20), bits, 4); arb_poly_set(g, f); /* g = f + 1 */ if (g->length == 0) { arb_poly_fit_length(g, 1); arb_set_ui(g->coeffs, a); _arb_poly_set_length(g, 1); _arb_poly_normalise(g); } else { arb_add_ui(g->coeffs, g->coeffs, a, bits); _arb_poly_normalise(g); } arb_poly_rising_ui_series(h1, f, a, trunc, bits); arb_poly_rising_ui_series(h2, g, b, trunc, bits); arb_poly_rising_ui_series(h3, f, a + b, trunc, bits); arb_poly_mullow(h1h2, h1, h2, trunc, bits); if (!arb_poly_overlaps(h1h2, h3)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = %wu\n", a); flint_printf("b = %wu\n", a); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_printf("h1 = "); arb_poly_printd(h1, 15); flint_printf("\n\n"); flint_printf("h2 = "); arb_poly_printd(h2, 15); flint_printf("\n\n"); flint_printf("h1h2 = "); arb_poly_printd(h1h2, 15); flint_printf("\n\n"); flint_printf("h3 = "); arb_poly_printd(h3, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_rising_ui_series(f, f, a, trunc, bits); if (!arb_poly_equal(f, h1)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("trunc = %wd\n", trunc); flint_printf("a = %wu\n", a); flint_printf("b = %wu\n", a); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("h1 = "); arb_poly_printd(h1, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_poly_clear(h1); arb_poly_clear(h2); arb_poly_clear(h1h2); arb_poly_clear(h3); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-root_bound_fujiwara.c000066400000000000000000000044631417376376500216310ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("root_bound_fujiwara...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_poly_t a; arb_ptr roots; arb_t t; mag_t mag1, mag2; slong i, deg, prec; prec = 10 + n_randint(state, 400); deg = n_randint(state, 10); arb_init(t); arb_poly_init(a); mag_init(mag1); mag_init(mag2); roots = _arb_vec_init(deg); for (i = 0; i < deg; i++) arb_randtest(roots + i, state, prec, 1 + n_randint(state, 20)); arb_poly_product_roots(a, roots, deg, prec); arb_randtest(t, state, prec, 1 + n_randint(state, 20)); arb_poly_scalar_mul(a, a, t, prec); arb_poly_root_bound_fujiwara(mag1, a); for (i = 0; i < deg; i++) { arb_get_mag(mag2, roots + i); /* arb_get_mag gives an upper bound which due to rounding could be larger than mag1, so we pick a slightly smaller number */ mag_mul_ui(mag2, mag2, 10000); mag_div_ui(mag2, mag2, 10001); if (mag_cmp(mag2, mag1) > 0) { flint_printf("FAIL\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("root = "); arb_printd(roots + i, 15); flint_printf("\n\n"); flint_printf("mag1 = "); mag_printd(mag1, 10); flint_printf("\n\n"); flint_printf("mag2 = "); mag_printd(mag2, 10); flint_printf("\n\n"); flint_abort(); } } _arb_vec_clear(roots, deg); arb_clear(t); arb_poly_clear(a); mag_clear(mag1); mag_clear(mag2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-rsqrt_series.c000066400000000000000000000044331417376376500203110ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("rsqrt_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b, c; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); fmpq_poly_randtest_not_zero(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); arb_poly_rsqrt_series(b, a, n, rbits2); /* Check 1/((1/sqrt(a))^2) = a */ arb_poly_mullow(c, b, b, n, rbits2); arb_poly_inv_series(c, c, n, rbits2); fmpq_poly_truncate(A, n); if (!arb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_rsqrt_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-set_trunc_round.c000066400000000000000000000044151417376376500210010ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main(void) { int iter; flint_rand_t state; flint_printf("set_trunc_round...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d, e; slong n, prec; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); arb_poly_randtest(a, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); arb_poly_randtest(b, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); arb_poly_randtest(c, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); arb_poly_randtest(d, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); arb_poly_randtest(e, state, n_randint(state, 10), 2 + n_randint(state, 200), 10); n = n_randint(state, 10); prec = 2 + n_randint(state, 200); arb_poly_set_trunc(b, a, n); arb_poly_set_round(b, b, prec); arb_poly_set_round(c, a, prec); arb_poly_set_trunc(c, c, n); arb_poly_set_trunc_round(d, a, n, prec); arb_poly_set(e, a); arb_poly_set_trunc_round(e, e, n, prec); if (!arb_poly_equal(b, c) || !arb_poly_equal(c, d) || !arb_poly_equal(d, e)) { flint_printf("FAIL\n\n"); arb_poly_printd(a, 50), flint_printf("\n\n"); arb_poly_printd(b, 50), flint_printf("\n\n"); arb_poly_printd(c, 50), flint_printf("\n\n"); arb_poly_printd(d, 50), flint_printf("\n\n"); arb_poly_printd(e, 50), flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/arb_poly/test/t-shift_left_right.c000066400000000000000000000055731417376376500211160ustar00rootroot00000000000000/* Copyright (C) 2009 William Hart Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main(void) { int i, result; flint_rand_t state; flint_printf("shift_left/right...."); fflush(stdout); flint_randinit(state); /* Check aliasing of a and b for left shift */ for (i = 0; i < 1000; i++) { arb_poly_t a, b; slong shift = n_randint(state, 100); arb_poly_init(a); arb_poly_init(b); arb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); arb_poly_shift_left(b, a, shift); arb_poly_shift_left(a, a, shift); result = (arb_poly_equal(a, b)); if (!result) { flint_printf("FAIL:\n"); arb_poly_printd(a, 10), flint_printf("\n\n"); arb_poly_printd(b, 10), flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); } /* Check aliasing of a and b for right shift */ for (i = 0; i < 1000; i++) { arb_poly_t a, b; slong shift = n_randint(state, 100); arb_poly_init(a); arb_poly_init(b); arb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); arb_poly_shift_right(b, a, shift); arb_poly_shift_right(a, a, shift); result = (arb_poly_equal(a, b)); if (!result) { flint_printf("FAIL:\n"); arb_poly_printd(a, 10), flint_printf("\n\n"); arb_poly_printd(b, 10), flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); } /* Check shift left then right does nothing */ for (i = 0; i < 1000; i++) { arb_poly_t a, b, c; slong shift = n_randint(state, 100); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); arb_poly_shift_left(b, a, shift); arb_poly_shift_right(c, b, shift); result = (arb_poly_equal(c, a)); if (!result) { flint_printf("FAIL:\n"); arb_poly_printd(a, 10), flint_printf("\n\n"); arb_poly_printd(b, 10), flint_printf("\n\n"); arb_poly_printd(c, 10), flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/arb_poly/test/t-sin_cos_pi_series.c000066400000000000000000000053551417376376500212670ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b, c, d, e; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_sin_cos_pi_series(b, c, a, n, rbits2); /* Check sin(x)^2 + cos(x)^2 = 1 */ arb_poly_mullow(d, b, b, n, rbits2); arb_poly_mullow(e, c, c, n, rbits2); arb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!arb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_pi_series(d, c, d, n, rbits2); if (!arb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_pi_series(b, d, d, n, rbits2); if (!arb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sin_cos_series.c000066400000000000000000000053411417376376500205720ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b, c, d, e; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_sin_cos_series(b, c, a, n, rbits2); /* Check sin(x)^2 + cos(x)^2 = 1 */ arb_poly_mullow(d, b, b, n, rbits2); arb_poly_mullow(e, c, c, n, rbits2); arb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!arb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_series(d, c, d, n, rbits2); if (!arb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_series(b, d, d, n, rbits2); if (!arb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sin_cos_series_basecase.c000066400000000000000000000055421417376376500224230ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_series_basecase...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b, c, d, e; int times_pi; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); times_pi = n_randint(state, 2); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_sin_cos_series_basecase(b, c, a, n, rbits2, times_pi); /* Check sin(x)^2 + cos(x)^2 = 1 */ arb_poly_mullow(d, b, b, n, rbits2); arb_poly_mullow(e, c, c, n, rbits2); arb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!arb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_series_basecase(d, c, d, n, rbits2, times_pi); if (!arb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_series_basecase(b, d, d, n, rbits2, times_pi); if (!arb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sin_cos_series_tangent.c000066400000000000000000000055361417376376500223200ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_series_tangent...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b, c, d, e; int times_pi; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); times_pi = n_randint(state, 2); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_sin_cos_series_tangent(b, c, a, n, rbits2, times_pi); /* Check sin(x)^2 + cos(x)^2 = 1 */ arb_poly_mullow(d, b, b, n, rbits2); arb_poly_mullow(e, c, c, n, rbits2); arb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!arb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_series_tangent(d, c, d, n, rbits2, times_pi); if (!arb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_cos_series_tangent(b, d, d, n, rbits2, times_pi); if (!arb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sin_pi_series.c000066400000000000000000000044631417376376500204220ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; arb_poly_t S, A, B, C; arb_t pi; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); arb_poly_init(S); arb_poly_init(A); arb_poly_init(B); arb_poly_init(C); arb_init(pi); arb_poly_randtest(S, state, m, bits1, 3); arb_poly_randtest(A, state, m, bits1, 3); arb_poly_randtest(B, state, m, bits1, 3); arb_poly_sin_pi_series(A, S, n1, bits2); arb_const_pi(pi, bits3); arb_poly_set_arb(B, pi); arb_poly_mul(B, S, B, bits3); arb_poly_sin_series(B, B, n2, bits3); arb_poly_set(C, A); arb_poly_truncate(C, FLINT_MIN(n1, n2)); arb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); arb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); arb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_sin_pi_series(S, S, n1, bits2); if (!arb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(S); arb_poly_clear(A); arb_poly_clear(B); arb_poly_clear(C); arb_clear(pi); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sin_series_cos_series.c000066400000000000000000000054011417376376500221410ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sin_series/cos_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b, c, d, e; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_sin_series(b, a, n, rbits2); arb_poly_cos_series(c, a, n, rbits2); /* Check sin(x)^2 + cos(x)^2 = 1 */ arb_poly_mullow(d, b, b, n, rbits2); arb_poly_mullow(e, c, c, n, rbits2); arb_poly_add(d, d, e, rbits2); fmpq_poly_one(B); if (!arb_poly_contains_fmpq_poly(d, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sin_series(d, d, n, rbits2); if (!arb_poly_equal(b, d)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_cos_series(d, d, n, rbits2); if (!arb_poly_equal(c, d)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sinc_pi_series.c000066400000000000000000000061451417376376500205640ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson Copyright (C) 2019 D.H.J. Polymath This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sinc_pi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3, rbits4; arb_poly_t a, b, c, d; arb_t pi; rbits1 = 2 + n_randint(state, 300); rbits2 = 2 + n_randint(state, 300); rbits3 = 2 + n_randint(state, 300); rbits4 = 2 + n_randint(state, 300); m = n_randint(state, 15); n1 = n_randint(state, 15); n2 = n_randint(state, 15); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_init(pi); arb_poly_randtest(a, state, m, rbits1, 10); arb_poly_randtest(b, state, 10, rbits1, 10); arb_poly_randtest(c, state, 10, rbits1, 10); arb_poly_sinc_pi_series(b, a, n1, rbits2); arb_poly_sinc_pi_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); arb_const_pi(pi, rbits4); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd, bits4 = %wd\n", n1, n2, rbits2, rbits3, rbits4); flint_printf("a = "); arb_poly_printd(a, 50); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 50); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 50); flint_printf("\n\n"); flint_abort(); } /* check pi x sinc_pi(x) = sin_pi(x) */ arb_poly_mullow(c, b, a, n1, rbits2); arb_poly_scalar_mul(c, c, pi, rbits2); arb_poly_sin_pi_series(d, a, n1, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_sinc_pi_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_clear(pi); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sinc_series.c000066400000000000000000000055141417376376500200730ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sinc_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; arb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 300); rbits2 = 2 + n_randint(state, 300); rbits3 = 2 + n_randint(state, 300); m = n_randint(state, 15); n1 = n_randint(state, 15); n2 = n_randint(state, 15); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, m, rbits1, 10); arb_poly_randtest(b, state, 10, rbits1, 10); arb_poly_randtest(c, state, 10, rbits1, 10); arb_poly_sinc_series(b, a, n1, rbits2); arb_poly_sinc_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); arb_poly_printd(a, 50); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 50); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 50); flint_printf("\n\n"); flint_abort(); } /* check x sinc(x) = sin(x) */ arb_poly_mullow(c, b, a, n1, rbits2); arb_poly_sin_series(d, a, n1, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_sinc_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sinh_cosh_series.c000066400000000000000000000100261417376376500211060ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sinh_cosh_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d, e; slong n1, n2, prec; int alg1, alg2; prec = 2 + n_randint(state, 200); if (n_randint(state, 40) == 0) { n1 = n_randint(state, 300); n2 = n_randint(state, 300); } else { n1 = n_randint(state, 30); n2 = n_randint(state, 30); } arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); arb_poly_randtest(a, state, 20, prec, 10); arb_poly_randtest(b, state, 20, prec, 10); arb_poly_randtest(c, state, 20, prec, 10); arb_poly_randtest(d, state, 20, prec, 10); arb_poly_randtest(e, state, 20, prec, 10); alg1 = n_randint(state, 4); alg2 = n_randint(state, 7); switch (alg1) { case 0: arb_poly_sinh_cosh_series(b, c, a, n1, prec); break; case 1: arb_poly_sinh_cosh_series_basecase(b, c, a, n1, prec); break; case 2: arb_poly_sinh_cosh_series_exponential(b, c, a, n1, prec); break; default: arb_poly_sinh_series(b, a, n1, prec); arb_poly_cosh_series(c, a, n1, prec); break; } switch (alg2) { case 0: arb_poly_sinh_cosh_series(d, e, a, n2, prec); break; case 1: arb_poly_sinh_cosh_series_basecase(d, e, a, n2, prec); break; case 2: arb_poly_sinh_cosh_series_exponential(d, e, a, n2, prec); break; case 3: arb_poly_sinh_series(d, a, n2, prec); arb_poly_cosh_series(e, a, n2, prec); break; case 4: arb_poly_set(d, a); arb_poly_sinh_cosh_series(d, e, d, n2, prec); break; case 5: arb_poly_set(e, a); arb_poly_sinh_cosh_series(d, e, e, n2, prec); break; default: arb_poly_set(d, a); arb_poly_sinh_series(d, d, n2, prec); arb_poly_set(e, a); arb_poly_cosh_series(e, e, n2, prec); break; } arb_poly_truncate(b, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(e, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(b, d) || !arb_poly_overlaps(c, e)) { flint_printf("FAIL\n\n"); flint_printf("alg1 = %d, alg2 = %d, n1 = %wd, n2 = %wd\n\n", alg1, alg2, n1, n2); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(e, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sqrt_series.c000066400000000000000000000042271417376376500201300ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b, c; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); fmpq_poly_randtest_not_zero(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_sqrt_series(b, a, n, rbits2); /* Check sqrt(a)^2 = a */ arb_poly_mullow(c, b, b, n, rbits2); fmpq_poly_truncate(A, n); if (!arb_poly_contains_fmpq_poly(c, A)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_sqrt_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sub.c000066400000000000000000000044501417376376500163540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sub...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, C; arb_poly_t a, b, c; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(C); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); fmpq_poly_sub(C, A, B); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_sub(c, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(c, C)) { flint_printf("FAIL\n\n"); flint_printf("bits3 = %wd\n", rbits3); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("C = "); fmpq_poly_print(C); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(C); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-sub_series.c000066400000000000000000000044531417376376500177310ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_poly_t a, b, c, d; slong len, prec; arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, 1 + n_randint(state, 10), 100, 10); arb_poly_randtest(b, state, 1 + n_randint(state, 10), 100, 10); arb_poly_randtest(c, state, 1 + n_randint(state, 10), 100, 10); arb_poly_randtest(d, state, 1 + n_randint(state, 10), 100, 10); prec = 2 + n_randint(state, 100); len = n_randint(state, 10); arb_poly_sub_series(c, a, b, len, prec); arb_poly_sub(d, a, b, prec); arb_poly_truncate(d, len); if (!arb_poly_equal(c, d)) { flint_printf("FAIL\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_set(d, a); arb_poly_sub_series(d, d, b, len, prec); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } arb_poly_set(d, b); arb_poly_sub_series(d, a, d, len, prec); if (!arb_poly_equal(d, c)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-swinnerton_dyer_ui.c000066400000000000000000000037661417376376500215220ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("swinnerton_dyer_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 50 * arb_test_multiplier(); iter++) { arb_poly_t a, b; arb_t x, y; fmpz_poly_t c; slong i, n, prec; arb_poly_init(a); arb_poly_init(b); fmpz_poly_init(c); arb_init(x); arb_init(y); n = n_randint(state, 10); arb_poly_swinnerton_dyer_ui(a, n, 0); prec = 2 + n_randint(state, 10000); if (!arb_poly_get_unique_fmpz_poly(c, a)) { flint_printf("FAIL (uniqueness)\n\n"); flint_abort(); } arb_poly_set_fmpz_poly(b, c, prec); arb_zero(x); for (i = 0; i < n; i++) { arb_sqrt_ui(y, n_nth_prime(i + 1), prec); if (n_randint(state, 2)) arb_add(x, x, y, prec); else arb_sub(x, x, y, prec); } arb_poly_evaluate(y, b, x, prec); if (!arb_contains_zero(y)) { flint_printf("FAIL (containment)\n\n"); flint_abort(); } arb_poly_swinnerton_dyer_ui(b, n, 2 + n_randint(state, 1000)); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (overlap)\n\n"); flint_abort(); } arb_poly_clear(a); arb_poly_clear(b); fmpz_poly_clear(c); arb_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-tan_series.c000066400000000000000000000050511417376376500177150ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("tan_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b, c, d, e; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 50); n = 1 + n_randint(state, 50); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_init(e); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 50), rbits1, 5); arb_poly_tan_series(b, a, n, rbits2); /* check tan(x) = 2*tan(x/2)/(1-tan(x/2)^2) */ arb_poly_scalar_mul_2exp_si(c, a, -1); arb_poly_tan_series(c, c, n, rbits2); arb_poly_mullow(d, c, c, n, rbits2); arb_poly_one(e); arb_poly_sub(e, e, d, rbits2); arb_poly_div_series(c, c, e, n, rbits2); arb_poly_scalar_mul_2exp_si(c, c, 1); if (!arb_poly_overlaps(b, c)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_tan_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpq_poly_clear(A); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); arb_poly_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-taylor_shift.c000066400000000000000000000044561417376376500203000ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong prec1, prec2; arb_poly_t f, g; arb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); arb_poly_init(f); arb_poly_init(g); arb_init(c); arb_init(d); arb_init(e); arb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); arb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) arb_set_si(c, n_randint(state, 5) - 2); else arb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) arb_set_si(d, n_randint(state, 5) - 2); else arb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); arb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ arb_poly_taylor_shift(g, f, e, prec2); arb_poly_taylor_shift(f, f, c, prec1); arb_poly_taylor_shift(f, f, d, prec1); if (!arb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_clear(c); arb_clear(d); arb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-taylor_shift_convolution.c000066400000000000000000000045361417376376500227360ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift_convolution...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong prec1, prec2; arb_poly_t f, g; arb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); arb_poly_init(f); arb_poly_init(g); arb_init(c); arb_init(d); arb_init(e); arb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); arb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) arb_set_si(c, n_randint(state, 5) - 2); else arb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) arb_set_si(d, n_randint(state, 5) - 2); else arb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); arb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ arb_poly_taylor_shift_convolution(g, f, e, prec2); arb_poly_taylor_shift_convolution(f, f, c, prec1); arb_poly_taylor_shift_convolution(f, f, d, prec1); if (!arb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_clear(c); arb_clear(d); arb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-taylor_shift_divconquer.c000066400000000000000000000045321417376376500225320ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift_divconquer...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong prec1, prec2; arb_poly_t f, g; arb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); arb_poly_init(f); arb_poly_init(g); arb_init(c); arb_init(d); arb_init(e); arb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); arb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) arb_set_si(c, n_randint(state, 5) - 2); else arb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) arb_set_si(d, n_randint(state, 5) - 2); else arb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); arb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ arb_poly_taylor_shift_divconquer(g, f, e, prec2); arb_poly_taylor_shift_divconquer(f, f, c, prec1); arb_poly_taylor_shift_divconquer(f, f, d, prec1); if (!arb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_clear(c); arb_clear(d); arb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-taylor_shift_horner.c000066400000000000000000000045121417376376500216460ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("taylor_shift_horner...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { slong prec1, prec2; arb_poly_t f, g; arb_t c, d, e; prec1 = 2 + n_randint(state, 500); prec2 = 2 + n_randint(state, 500); arb_poly_init(f); arb_poly_init(g); arb_init(c); arb_init(d); arb_init(e); arb_poly_randtest(f, state, 1 + n_randint(state, 40), 1 + n_randint(state, 500), 10); arb_poly_randtest(g, state, 1 + n_randint(state, 20), 1 + n_randint(state, 500), 10); if (n_randint(state, 2)) arb_set_si(c, n_randint(state, 5) - 2); else arb_randtest(c, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); if (n_randint(state, 2)) arb_set_si(d, n_randint(state, 5) - 2); else arb_randtest(d, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100)); arb_add(e, c, d, prec1); /* check f(x+c)(x+d) = f(x+c+d) */ arb_poly_taylor_shift_horner(g, f, e, prec2); arb_poly_taylor_shift_horner(f, f, c, prec1); arb_poly_taylor_shift_horner(f, f, d, prec1); if (!arb_poly_overlaps(f, g)) { flint_printf("FAIL\n\n"); flint_printf("c = "); arb_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_printd(d, 15); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("g = "); arb_poly_printd(g, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_clear(f); arb_poly_clear(g); arb_clear(c); arb_clear(d); arb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/test/t-zeta_series.c000066400000000000000000000070021417376376500200740ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" int main() { slong iter; flint_rand_t state; flint_printf("zeta_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; int deflate; arb_poly_t S, A, B, C, D, E, F; arb_t a, a1; bits1 = 2 + n_randint(state, 300); bits2 = 2 + n_randint(state, 300); bits3 = 2 + n_randint(state, 300); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); arb_poly_init(S); arb_poly_init(A); arb_poly_init(B); arb_poly_init(C); arb_poly_init(D); arb_poly_init(E); arb_poly_init(F); arb_init(a); arb_init(a1); deflate = n_randint(state, 2); arb_poly_randtest(S, state, m, bits1, 3); arb_randtest_precise(a, state, bits1, 3); arb_poly_set_coeff_arb(S, 0, a); if (n_randint(state, 2)) arb_randtest(a, state, bits1, 3); else arb_one(a); arb_poly_zeta_series(A, S, a, deflate, n1, bits2); arb_poly_zeta_series(B, S, a, deflate, n2, bits3); arb_poly_set(C, A); arb_poly_truncate(C, FLINT_MIN(n1, n2)); arb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("A = "); arb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("B = "); arb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } /* check zeta(s,a) = zeta(s,a+1) + a^(-s) */ arb_poly_set_arb(D, a); arb_poly_log_series(D, D, n1, bits2); arb_poly_mullow(D, D, S, n1, bits2); arb_poly_neg(D, D); arb_poly_exp_series(D, D, n1, bits2); arb_add_ui(a1, a, 1, bits2); arb_poly_zeta_series(E, S, a1, deflate, n1, bits2); arb_poly_add(E, E, D, bits2); if (!arb_poly_overlaps(A, E)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("S = "); arb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("a = "); arb_printd(a, 15); flint_printf("\n\n"); flint_printf("A = "); arb_poly_printd(A, 15); flint_printf("\n\n"); flint_printf("E = "); arb_poly_printd(A, 15); flint_printf("\n\n"); flint_abort(); } arb_poly_zeta_series(S, S, a, deflate, n1, bits2); if (!arb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } arb_poly_clear(S); arb_poly_clear(A); arb_poly_clear(B); arb_poly_clear(C); arb_poly_clear(D); arb_poly_clear(E); arb_poly_clear(F); arb_clear(a); arb_clear(a1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arb_poly/tree.c000066400000000000000000000047641417376376500153120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" arb_ptr * _arb_poly_tree_alloc(slong len) { arb_ptr * tree = NULL; if (len) { slong i, height = FLINT_CLOG2(len); tree = flint_malloc(sizeof(arb_ptr) * (height + 1)); for (i = 0; i <= height; i++) tree[i] = _arb_vec_init(len + (len >> i) + 1); } return tree; } void _arb_poly_tree_free(arb_ptr * tree, slong len) { if (len) { slong i, height = FLINT_CLOG2(len); for (i = 0; i <= height; i++) _arb_vec_clear(tree[i], len + (len >> i) + 1); flint_free(tree); } } void _arb_poly_tree_build(arb_ptr * tree, arb_srcptr roots, slong len, slong prec) { slong height, pow, left, i; arb_ptr pa, pb; arb_srcptr a, b; if (len == 0) return; height = FLINT_CLOG2(len); /* zeroth level, (x-a) */ for (i = 0; i < len; i++) { arb_one(tree[0] + (2 * i + 1)); arb_neg(tree[0] + (2 * i), roots + i); } /* first level, (x-a)(x-b) = x^2 + (-a-b)*x + a*b */ if (height > 1) { pa = tree[1]; for (i = 0; i < len / 2; i++) { a = (arb_srcptr) (roots + (2 * i)); b = (arb_srcptr) (roots + (2 * i + 1)); arb_mul(pa + (3 * i), a, b, prec); arb_add(pa + (3 * i + 1), a, b, prec); arb_neg(pa + (3 * i + 1), pa + (3 * i + 1)); arb_one(pa + (3 * i + 2)); } if (len & 1) { arb_neg(pa + (3 * (len / 2)), roots + len - 1); arb_one(pa + (3 * (len / 2) + 1)); } } for (i = 1; i < height - 1; i++) { left = len; pow = WORD(1) << i; pa = tree[i]; pb = tree[i + 1]; while (left >= 2 * pow) { _arb_poly_mul_monic(pb, pa, pow + 1, pa + pow + 1, pow + 1, prec); left -= 2 * pow; pa += 2 * pow + 2; pb += 2 * pow + 1; } if (left > pow) { _arb_poly_mul_monic(pb, pa, pow + 1, pa + pow + 1, left - pow + 1, prec); } else if (left > 0) _arb_vec_set(pb, pa, left + 1); } } arb-2.22.1/arb_poly/valuation.c000066400000000000000000000011321417376376500163370ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" slong arb_poly_valuation(const arb_poly_t poly) { slong i, len = poly->length; for (i = 0; i < len; i++) if (!arb_is_zero(poly->coeffs + i)) return i; return -1; } arb-2.22.1/arb_poly/zeta_series.c000066400000000000000000000106161417376376500166610ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arb_poly.h" #include "acb_poly.h" /* series of c^(d+x) */ static __inline__ void _arb_poly_pow_cpx(arb_ptr res, const arb_t c, const arb_t d, slong trunc, slong prec) { slong i; arb_t logc; arb_init(logc); arb_log(logc, c, prec); arb_mul(res + 0, logc, d, prec); arb_exp(res + 0, res + 0, prec); for (i = 1; i < trunc; i++) { arb_mul(res + i, res + i - 1, logc, prec); arb_div_ui(res + i, res + i, i, prec); } arb_clear(logc); } void _arb_poly_zeta_series(arb_ptr res, arb_srcptr h, slong hlen, const arb_t a, int deflate, slong len, slong prec) { slong i; acb_t cs, ca; acb_ptr z; arb_ptr t, u; if (arb_contains_nonpositive(a)) { _arb_vec_indeterminate(res, len); return; } hlen = FLINT_MIN(hlen, len); z = _acb_vec_init(len); t = _arb_vec_init(len); u = _arb_vec_init(len); acb_init(cs); acb_init(ca); /* use reflection formula */ if (arf_sgn(arb_midref(h)) < 0 && arb_is_one(a)) { /* zeta(s) = (2*pi)**s * sin(pi*s/2) / pi * gamma(1-s) * zeta(1-s) */ arb_t pi; arb_ptr f, s1, s2, s3, s4; arb_init(pi); f = _arb_vec_init(2); s1 = _arb_vec_init(len); s2 = _arb_vec_init(len); s3 = _arb_vec_init(len); s4 = _arb_vec_init(len); arb_const_pi(pi, prec); /* s1 = (2*pi)**s */ arb_mul_2exp_si(pi, pi, 1); _arb_poly_pow_cpx(s1, pi, h, len, prec); arb_mul_2exp_si(pi, pi, -1); /* s2 = sin(pi*s/2) / pi */ arb_set(f, h); arb_one(f + 1); arb_mul_2exp_si(f, f, -1); arb_mul_2exp_si(f + 1, f + 1, -1); _arb_poly_sin_pi_series(s2, f, 2, len, prec); _arb_vec_scalar_div(s2, s2, len, pi, prec); /* s3 = gamma(1-s) */ arb_sub_ui(f, h, 1, prec); arb_neg(f, f); arb_set_si(f + 1, -1); _arb_poly_gamma_series(s3, f, 2, len, prec); /* s4 = zeta(1-s) */ arb_sub_ui(f, h, 1, prec); arb_neg(f, f); acb_set_arb(cs, f); acb_one(ca); _acb_poly_zeta_cpx_series(z, cs, ca, 0, len, prec); for (i = 0; i < len; i++) arb_set(s4 + i, acb_realref(z + i)); for (i = 1; i < len; i += 2) arb_neg(s4 + i, s4 + i); _arb_poly_mullow(u, s1, len, s2, len, len, prec); _arb_poly_mullow(s1, s3, len, s4, len, len, prec); _arb_poly_mullow(t, u, len, s1, len, len, prec); /* add 1/(1-(s+t)) = 1/(1-s) + t/(1-s)^2 + ... */ if (deflate) { arb_sub_ui(u, h, 1, prec); arb_neg(u, u); arb_inv(u, u, prec); for (i = 1; i < len; i++) arb_mul(u + i, u + i - 1, u, prec); _arb_vec_add(t, t, u, len, prec); } arb_clear(pi); _arb_vec_clear(f, 2); _arb_vec_clear(s1, len); _arb_vec_clear(s2, len); _arb_vec_clear(s3, len); _arb_vec_clear(s4, len); } else { acb_set_arb(cs, h); acb_set_arb(ca, a); _acb_poly_zeta_cpx_series(z, cs, ca, deflate, len, prec); for (i = 0; i < len; i++) arb_set(t + i, acb_realref(z + i)); } /* compose with nonconstant part */ arb_zero(u); _arb_vec_set(u + 1, h + 1, hlen - 1); _arb_poly_compose_series(res, t, len, u, hlen, len, prec); _acb_vec_clear(z, len); _arb_vec_clear(t, len); _arb_vec_clear(u, len); acb_clear(cs); acb_clear(ca); } void arb_poly_zeta_series(arb_poly_t res, const arb_poly_t f, const arb_t a, int deflate, slong n, slong prec) { if (n == 0) { arb_poly_zero(res); return; } arb_poly_fit_length(res, n); if (f->length == 0) { arb_t t; arb_init(t); _arb_poly_zeta_series(res->coeffs, t, 1, a, deflate, n, prec); arb_clear(t); } else { _arb_poly_zeta_series(res->coeffs, f->coeffs, f->length, a, deflate, n, prec); } _arb_poly_set_length(res, n); _arb_poly_normalise(res); } arb-2.22.1/arf.h000066400000000000000000000775621417376376500133270ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson 2x2 mul code taken from MPFR 2.3.0 (Copyright (C) 1991-2007 Free Software Foundation, Inc.) This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef ARF_H #define ARF_H #ifdef ARF_INLINES_C #define ARF_INLINE #else #define ARF_INLINE static __inline__ #endif #include #include #include "flint/flint.h" #include "fmpr.h" #include "mag.h" #ifndef flint_abort #if __FLINT_RELEASE <= 20502 #define flint_abort abort #endif #endif #ifdef __cplusplus extern "C" { #endif #define arf_rnd_t fmpr_rnd_t #define ARF_RND_DOWN FMPR_RND_DOWN #define ARF_RND_UP FMPR_RND_UP #define ARF_RND_FLOOR FMPR_RND_FLOOR #define ARF_RND_CEIL FMPR_RND_CEIL #define ARF_RND_NEAR FMPR_RND_NEAR ARF_INLINE int arf_rounds_down(arf_rnd_t rnd, int sgnbit) { if (rnd == ARF_RND_DOWN) return 1; if (rnd == ARF_RND_UP) return 0; if (rnd == ARF_RND_FLOOR) return !sgnbit; return sgnbit; } ARF_INLINE int arf_rounds_up(arf_rnd_t rnd, int sgnbit) { if (rnd == ARF_RND_DOWN) return 0; if (rnd == ARF_RND_UP) return 1; if (rnd == ARF_RND_FLOOR) return sgnbit; return !sgnbit; } ARF_INLINE mpfr_rnd_t arf_rnd_to_mpfr(arf_rnd_t rnd) { if (rnd == ARF_RND_DOWN) return MPFR_RNDZ; else if (rnd == ARF_RND_UP) return MPFR_RNDA; else if (rnd == ARF_RND_FLOOR) return MPFR_RNDD; else if (rnd == ARF_RND_CEIL) return MPFR_RNDU; else return MPFR_RNDN; } /* Allow 'infinite' precision for operations where a result can be computed exactly. */ #define ARF_PREC_EXACT WORD_MAX #define ARF_PREC_ADD(prec,extra) ((prec) == ARF_PREC_EXACT ? ARF_PREC_EXACT : (prec) + (extra)) #define ARF_RESULT_EXACT 0 #define ARF_RESULT_INEXACT 1 /* Range where we can skip fmpz overflow checks for exponent manipulation. */ #define ARF_MAX_LAGOM_EXP MAG_MAX_LAGOM_EXP #define ARF_MIN_LAGOM_EXP MAG_MIN_LAGOM_EXP /* Exponent values used to encode special values. */ #define ARF_EXP_ZERO 0 #define ARF_EXP_NAN COEFF_MIN #define ARF_EXP_POS_INF (COEFF_MIN+1) #define ARF_EXP_NEG_INF (COEFF_MIN+2) /* Direct access to the exponent. */ #define ARF_EXP(x) ((x)->exp) #define ARF_EXPREF(x) (&(x)->exp) /* Finite and with lagom big exponents. */ #define ARF_IS_LAGOM(x) (ARF_EXP(x) >= ARF_MIN_LAGOM_EXP && \ ARF_EXP(x) <= ARF_MAX_LAGOM_EXP) /* More than two limbs (needs pointer). */ #define ARF_HAS_PTR(x) ((x)->size > ((2 << 1) + 1)) /* Raw size field (encodes both limb size and sign). */ #define ARF_XSIZE(x) ((x)->size) /* Construct size field value from size in limbs and sign bit. */ #define ARF_MAKE_XSIZE(size, sgnbit) ((((mp_size_t) size) << 1) | (sgnbit)) /* The limb size, and the sign bit. */ #define ARF_SIZE(x) (ARF_XSIZE(x) >> 1) #define ARF_SGNBIT(x) (ARF_XSIZE(x) & 1) /* Assumes non-special value */ #define ARF_NEG(x) (ARF_XSIZE(x) ^= 1) /* Note: may also be hardcoded in a few places. */ #define ARF_NOPTR_LIMBS 2 /* Direct access to the limb data. */ #define ARF_NOPTR_D(x) ((x)->d.noptr.d) #define ARF_PTR_D(x) ((x)->d.ptr.d) #define ARF_PTR_ALLOC(x) ((x)->d.ptr.alloc) /* Encoding for special values. */ #define ARF_IS_SPECIAL(x) (ARF_XSIZE(x) == 0) /* Value is +/- a power of two */ #define ARF_IS_POW2(x) (ARF_SIZE(x) == 1) && (ARF_NOPTR_D(x)[0] == LIMB_TOP) /* To set a special value, first call this and then set the exponent. */ #define ARF_MAKE_SPECIAL(x) \ do { \ fmpz_clear(ARF_EXPREF(x)); \ ARF_DEMOTE(x); \ ARF_XSIZE(x) = 0; \ } while (0) typedef struct { mp_limb_t d[ARF_NOPTR_LIMBS]; } mantissa_noptr_struct; typedef struct { mp_size_t alloc; mp_ptr d; } mantissa_ptr_struct; typedef union { mantissa_noptr_struct noptr; mantissa_ptr_struct ptr; } mantissa_struct; typedef struct { fmpz exp; mp_size_t size; mantissa_struct d; } arf_struct; typedef arf_struct arf_t[1]; typedef arf_struct * arf_ptr; typedef const arf_struct * arf_srcptr; void _arf_promote(arf_t x, mp_size_t n); void _arf_demote(arf_t x); /* Warning: does not set size! -- also doesn't demote exponent. */ #define ARF_DEMOTE(x) \ do { \ if (ARF_HAS_PTR(x)) \ _arf_demote(x); \ } while (0) /* Get mpn pointer and size (xptr, xn) for read-only use. */ #define ARF_GET_MPN_READONLY(xptr, xn, x) \ do { \ xn = ARF_SIZE(x); \ if (xn <= ARF_NOPTR_LIMBS) \ xptr = ARF_NOPTR_D(x); \ else \ xptr = ARF_PTR_D(x); \ } while (0) /* Assumes non-special! */ #define ARF_GET_TOP_LIMB(lmb, x) \ do { \ mp_srcptr __xptr; \ mp_size_t __xn; \ ARF_GET_MPN_READONLY(__xptr, __xn, (x)); \ (lmb) = __xptr[__xn - 1]; \ } while (0) /* Get mpn pointer xptr for writing *exactly* xn limbs to x. */ #define ARF_GET_MPN_WRITE(xptr, xn, x) \ do { \ mp_size_t __xn = (xn); \ if ((__xn) <= ARF_NOPTR_LIMBS) \ { \ ARF_DEMOTE(x); \ xptr = ARF_NOPTR_D(x); \ } \ else \ { \ if (!ARF_HAS_PTR(x)) \ { \ _arf_promote(x, __xn); \ } \ else if (ARF_PTR_ALLOC(x) < (__xn)) \ { \ ARF_PTR_D(x) = (mp_ptr) \ flint_realloc(ARF_PTR_D(x), \ (xn) * sizeof(mp_limb_t)); \ ARF_PTR_ALLOC(x) = (__xn); \ } \ xptr = ARF_PTR_D(x); \ } \ ARF_XSIZE(x) = ARF_MAKE_XSIZE(__xn, 0); \ } while (0) ARF_INLINE void arf_init(arf_t x) { fmpz_init(ARF_EXPREF(x)); ARF_XSIZE(x) = 0; } void arf_clear(arf_t x); ARF_INLINE void arf_zero(arf_t x) { ARF_MAKE_SPECIAL(x); ARF_EXP(x) = ARF_EXP_ZERO; } ARF_INLINE void arf_pos_inf(arf_t x) { ARF_MAKE_SPECIAL(x); ARF_EXP(x) = ARF_EXP_POS_INF; } ARF_INLINE void arf_neg_inf(arf_t x) { ARF_MAKE_SPECIAL(x); ARF_EXP(x) = ARF_EXP_NEG_INF; } ARF_INLINE void arf_nan(arf_t x) { ARF_MAKE_SPECIAL(x); ARF_EXP(x) = ARF_EXP_NAN; } ARF_INLINE int arf_is_special(const arf_t x) { return ARF_IS_SPECIAL(x); } ARF_INLINE int arf_is_zero(const arf_t x) { return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_ZERO); } ARF_INLINE int arf_is_pos_inf(const arf_t x) { return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_POS_INF); } ARF_INLINE int arf_is_neg_inf(const arf_t x) { return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_NEG_INF); } ARF_INLINE int arf_is_nan(const arf_t x) { return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_NAN); } ARF_INLINE int arf_is_normal(const arf_t x) { return !ARF_IS_SPECIAL(x); } ARF_INLINE int arf_is_finite(const arf_t x) { return !ARF_IS_SPECIAL(x) || (ARF_EXP(x) == ARF_EXP_ZERO); } ARF_INLINE int arf_is_inf(const arf_t x) { return ARF_IS_SPECIAL(x) && (ARF_EXP(x) == ARF_EXP_POS_INF || ARF_EXP(x) == ARF_EXP_NEG_INF); } ARF_INLINE void arf_one(arf_t x) { fmpz_clear(ARF_EXPREF(x)); ARF_DEMOTE(x); ARF_EXP(x) = 1; ARF_XSIZE(x) = ARF_MAKE_XSIZE(1, 0); ARF_NOPTR_D(x)[0] = LIMB_TOP; } ARF_INLINE int arf_is_one(const arf_t x) { return (ARF_EXP(x) == 1) && (ARF_XSIZE(x) == ARF_MAKE_XSIZE(1, 0)) && ARF_NOPTR_D(x)[0] == LIMB_TOP; } ARF_INLINE int arf_sgn(const arf_t x) { if (arf_is_special(x)) { if (arf_is_zero(x) || arf_is_nan(x)) return 0; return arf_is_pos_inf(x) ? 1 : -1; } else { return ARF_SGNBIT(x) ? -1 : 1; } } int arf_cmp(const arf_t x, const arf_t y); int arf_cmpabs(const arf_t x, const arf_t y); int arf_cmpabs_ui(const arf_t x, ulong y); int arf_cmpabs_d(const arf_t x, double y); int arf_cmp_si(const arf_t x, slong y); int arf_cmp_ui(const arf_t x, ulong y); int arf_cmp_d(const arf_t x, double y); ARF_INLINE void arf_swap(arf_t y, arf_t x) { if (x != y) { arf_struct t = *x; *x = *y; *y = t; } } ARF_INLINE void arf_set(arf_t y, const arf_t x) { if (x != y) { /* Fast path */ if (!COEFF_IS_MPZ(ARF_EXP(x)) && !COEFF_IS_MPZ(ARF_EXP(y))) ARF_EXP(y) = ARF_EXP(x); else fmpz_set(ARF_EXPREF(y), ARF_EXPREF(x)); /* Fast path */ if (!ARF_HAS_PTR(x)) { ARF_DEMOTE(y); (y)->d = (x)->d; } else { mp_ptr yptr; mp_srcptr xptr; mp_size_t n; ARF_GET_MPN_READONLY(xptr, n, x); ARF_GET_MPN_WRITE(yptr, n, y); flint_mpn_copyi(yptr, xptr, n); } /* Important. */ ARF_XSIZE(y) = ARF_XSIZE(x); } } ARF_INLINE void arf_neg(arf_t y, const arf_t x) { arf_set(y, x); if (arf_is_special(y)) { if (arf_is_pos_inf(y)) arf_neg_inf(y); else if (arf_is_neg_inf(y)) arf_pos_inf(y); } else { ARF_NEG(y); } } ARF_INLINE void arf_init_set_ui(arf_t x, ulong v) { if (v == 0) { ARF_EXP(x) = ARF_EXP_ZERO; ARF_XSIZE(x) = 0; } else { unsigned int c; count_leading_zeros(c, v); ARF_EXP(x) = FLINT_BITS - c; ARF_NOPTR_D(x)[0] = v << c; ARF_XSIZE(x) = ARF_MAKE_XSIZE(1, 0); } } /* FLINT_ABS is unsafe for x = WORD_MIN */ #define UI_ABS_SI(x) (((slong)(x) < 0) ? (-(ulong)(x)) : ((ulong)(x))) ARF_INLINE void arf_init_set_si(arf_t x, slong v) { arf_init_set_ui(x, UI_ABS_SI(v)); if (v < 0) ARF_NEG(x); } ARF_INLINE void arf_set_ui(arf_t x, ulong v) { ARF_DEMOTE(x); _fmpz_demote(ARF_EXPREF(x)); if (v == 0) { ARF_EXP(x) = ARF_EXP_ZERO; ARF_XSIZE(x) = 0; } else { unsigned int c; count_leading_zeros(c, v); ARF_EXP(x) = FLINT_BITS - c; ARF_NOPTR_D(x)[0] = v << c; ARF_XSIZE(x) = ARF_MAKE_XSIZE(1, 0); } } ARF_INLINE void arf_set_si(arf_t x, slong v) { arf_set_ui(x, UI_ABS_SI(v)); if (v < 0) ARF_NEG(x); } ARF_INLINE void arf_init_set_shallow(arf_t z, const arf_t x) { *z = *x; } ARF_INLINE void arf_init_neg_shallow(arf_t z, const arf_t x) { *z = *x; arf_neg(z, z); } ARF_INLINE void arf_init_set_mag_shallow(arf_t y, const mag_t x) { mp_limb_t t = MAG_MAN(x); ARF_XSIZE(y) = ARF_MAKE_XSIZE(t != 0, 0); ARF_EXP(y) = MAG_EXP(x); ARF_NOPTR_D(y)[0] = t << (FLINT_BITS - MAG_BITS); } ARF_INLINE void arf_init_neg_mag_shallow(arf_t z, const mag_t x) { arf_init_set_mag_shallow(z, x); arf_neg(z, z); } ARF_INLINE int arf_cmpabs_mag(const arf_t x, const mag_t y) { arf_t t; arf_init_set_mag_shallow(t, y); /* no need to free */ return arf_cmpabs(x, t); } ARF_INLINE int arf_mag_cmpabs(const mag_t x, const arf_t y) { arf_t t; arf_init_set_mag_shallow(t, x); /* no need to free */ return arf_cmpabs(t, y); } /* Assumes xn > 0, x[xn-1] != 0. */ /* TBD: 1, 2 limb versions */ void arf_set_mpn(arf_t y, mp_srcptr x, mp_size_t xn, int sgnbit); ARF_INLINE void arf_set_mpz(arf_t y, const mpz_t x) { slong size = x->_mp_size; if (size == 0) arf_zero(y); else arf_set_mpn(y, x->_mp_d, FLINT_ABS(size), size < 0); } ARF_INLINE void arf_set_fmpz(arf_t y, const fmpz_t x) { if (!COEFF_IS_MPZ(*x)) arf_set_si(y, *x); else arf_set_mpz(y, COEFF_TO_PTR(*x)); } int _arf_set_round_ui(arf_t x, ulong v, int sgnbit, slong prec, arf_rnd_t rnd); int _arf_set_round_uiui(arf_t z, slong * fix, mp_limb_t hi, mp_limb_t lo, int sgnbit, slong prec, arf_rnd_t rnd); int _arf_set_round_mpn(arf_t y, slong * exp_shift, mp_srcptr x, mp_size_t xn, int sgnbit, slong prec, arf_rnd_t rnd); ARF_INLINE int arf_set_round_ui(arf_t x, ulong v, slong prec, arf_rnd_t rnd) { return _arf_set_round_ui(x, v, 0, prec, rnd); } ARF_INLINE int arf_set_round_si(arf_t x, slong v, slong prec, arf_rnd_t rnd) { return _arf_set_round_ui(x, UI_ABS_SI(v), v < 0, prec, rnd); } ARF_INLINE int arf_set_round_mpz(arf_t y, const mpz_t x, slong prec, arf_rnd_t rnd) { int inexact; slong size = x->_mp_size; slong fix; if (size == 0) { arf_zero(y); return 0; } inexact = _arf_set_round_mpn(y, &fix, x->_mp_d, FLINT_ABS(size), (size < 0), prec, rnd); _fmpz_demote(ARF_EXPREF(y)); ARF_EXP(y) = FLINT_ABS(size) * FLINT_BITS + fix; return inexact; } ARF_INLINE int arf_set_round_fmpz(arf_t y, const fmpz_t x, slong prec, arf_rnd_t rnd) { if (!COEFF_IS_MPZ(*x)) return arf_set_round_si(y, *x, prec, rnd); else return arf_set_round_mpz(y, COEFF_TO_PTR(*x), prec, rnd); } int arf_set_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd); int arf_neg_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd); void arf_get_fmpr(fmpr_t y, const arf_t x); void arf_set_fmpr(arf_t y, const fmpr_t x); int arf_get_mpfr(mpfr_t x, const arf_t y, mpfr_rnd_t rnd); void arf_set_mpfr(arf_t x, const mpfr_t y); int arf_equal(const arf_t x, const arf_t y); int arf_equal_si(const arf_t x, slong y); int arf_equal_ui(const arf_t x, ulong y); int arf_equal_d(const arf_t x, double y); ARF_INLINE void arf_min(arf_t z, const arf_t a, const arf_t b) { if (arf_cmp(a, b) <= 0) arf_set(z, a); else arf_set(z, b); } ARF_INLINE void arf_max(arf_t z, const arf_t a, const arf_t b) { if (arf_cmp(a, b) > 0) arf_set(z, a); else arf_set(z, b); } ARF_INLINE void arf_abs(arf_t y, const arf_t x) { if (arf_sgn(x) < 0) arf_neg(y, x); else arf_set(y, x); } ARF_INLINE slong arf_bits(const arf_t x) { if (arf_is_special(x)) return 0; else { mp_srcptr xp; mp_size_t xn; slong c; ARF_GET_MPN_READONLY(xp, xn, x); count_trailing_zeros(c, xp[0]); return xn * FLINT_BITS - c; } } ARF_INLINE void arf_bot(fmpz_t e, const arf_t x) { if (arf_is_special(x)) fmpz_zero(e); else fmpz_sub_si(e, ARF_EXPREF(x), arf_bits(x)); } int arf_is_int(const arf_t x); int arf_is_int_2exp_si(const arf_t x, slong e); int arf_cmp_2exp_si(const arf_t x, slong e); int arf_cmpabs_2exp_si(const arf_t x, slong e); ARF_INLINE void arf_set_si_2exp_si(arf_t x, slong man, slong exp) { arf_set_si(x, man); if (man != 0) fmpz_add_si_inline(ARF_EXPREF(x), ARF_EXPREF(x), exp); } ARF_INLINE void arf_set_ui_2exp_si(arf_t x, ulong man, slong exp) { arf_set_ui(x, man); if (man != 0) fmpz_add_si_inline(ARF_EXPREF(x), ARF_EXPREF(x), exp); } ARF_INLINE void arf_mul_2exp_si(arf_t y, const arf_t x, slong e) { arf_set(y, x); if (!arf_is_special(y)) fmpz_add_si_inline(ARF_EXPREF(y), ARF_EXPREF(y), e); } ARF_INLINE void arf_mul_2exp_fmpz(arf_t y, const arf_t x, const fmpz_t e) { arf_set(y, x); if (!arf_is_special(y)) fmpz_add_inline(ARF_EXPREF(y), ARF_EXPREF(y), e); } ARF_INLINE int arf_set_round_fmpz_2exp(arf_t y, const fmpz_t x, const fmpz_t exp, slong prec, arf_rnd_t rnd) { if (fmpz_is_zero(x)) { arf_zero(y); return 0; } else { int r = arf_set_round_fmpz(y, x, prec, rnd); fmpz_add_inline(ARF_EXPREF(y), ARF_EXPREF(y), exp); return r; } } ARF_INLINE void arf_abs_bound_lt_2exp_fmpz(fmpz_t b, const arf_t x) { if (arf_is_special(x)) fmpz_zero(b); else fmpz_set(b, ARF_EXPREF(x)); } ARF_INLINE void arf_abs_bound_le_2exp_fmpz(fmpz_t b, const arf_t x) { if (arf_is_special(x)) fmpz_zero(b); else if (ARF_IS_POW2(x)) fmpz_sub_ui(b, ARF_EXPREF(x), 1); else fmpz_set(b, ARF_EXPREF(x)); } slong arf_abs_bound_lt_2exp_si(const arf_t x); void arf_frexp(arf_t man, fmpz_t exp, const arf_t x); void arf_get_fmpz_2exp(fmpz_t man, fmpz_t exp, const arf_t x); int _arf_get_integer_mpn(mp_ptr y, mp_srcptr x, mp_size_t xn, slong exp); int _arf_set_mpn_fixed(arf_t z, mp_srcptr xp, mp_size_t xn, mp_size_t fixn, int negative, slong prec, arf_rnd_t rnd); int arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd); slong arf_get_si(const arf_t x, arf_rnd_t rnd); int arf_get_fmpz_fixed_fmpz(fmpz_t y, const arf_t x, const fmpz_t e); int arf_get_fmpz_fixed_si(fmpz_t y, const arf_t x, slong e); ARF_INLINE void arf_set_fmpz_2exp(arf_t x, const fmpz_t man, const fmpz_t exp) { arf_set_fmpz(x, man); if (!arf_is_zero(x)) fmpz_add_inline(ARF_EXPREF(x), ARF_EXPREF(x), exp); } void arf_floor(arf_t z, const arf_t x); void arf_ceil(arf_t z, const arf_t x); void arf_debug(const arf_t x); char * arf_get_str(const arf_t x, slong d); void arf_fprint(FILE * file, const arf_t x); void arf_fprintd(FILE * file, const arf_t y, slong d); ARF_INLINE void arf_print(const arf_t x) { arf_fprint(stdout, x); } ARF_INLINE void arf_printd(const arf_t y, slong d) { arf_fprintd(stdout, y, d); } void arf_randtest(arf_t x, flint_rand_t state, slong bits, slong mag_bits); void arf_randtest_not_zero(arf_t x, flint_rand_t state, slong bits, slong mag_bits); void arf_randtest_special(arf_t x, flint_rand_t state, slong bits, slong mag_bits); void arf_urandom(arf_t x, flint_rand_t state, slong bits, arf_rnd_t rnd); #define MUL_MPFR_MIN_LIMBS 25 #define MUL_MPFR_MAX_LIMBS 10000 #define nn_mul_2x1(r2, r1, r0, a1, a0, b0) \ do { \ mp_limb_t t1; \ umul_ppmm(r1, r0, a0, b0); \ umul_ppmm(r2, t1, a1, b0); \ add_ssaaaa(r2, r1, r2, r1, 0, t1); \ } while (0) #define nn_mul_2x2(r3, r2, r1, r0, a1, a0, b1, b0) \ do { \ mp_limb_t t1, t2, t3; \ umul_ppmm(r1, r0, a0, b0); \ umul_ppmm(r2, t1, a1, b0); \ add_ssaaaa(r2, r1, r2, r1, 0, t1); \ umul_ppmm(t1, t2, a0, b1); \ umul_ppmm(r3, t3, a1, b1); \ add_ssaaaa(r3, t1, r3, t1, 0, t3); \ add_ssaaaa(r2, r1, r2, r1, t1, t2); \ r3 += r2 < t1; \ } while (0) #define ARF_MPN_MUL(_z, _x, _xn, _y, _yn) \ if ((_xn) == (_yn)) \ { \ if ((_xn) == 1) \ { \ umul_ppmm((_z)[1], (_z)[0], (_x)[0], (_y)[0]); \ } \ else if ((_xn) == 2) \ { \ mp_limb_t __arb_x1, __arb_x0, __arb_y1, __arb_y0; \ __arb_x0 = (_x)[0]; \ __arb_x1 = (_x)[1]; \ __arb_y0 = (_y)[0]; \ __arb_y1 = (_y)[1]; \ nn_mul_2x2((_z)[3], (_z)[2], (_z)[1], (_z)[0], __arb_x1, __arb_x0, __arb_y1, __arb_y0); \ } \ else if ((_x) == (_y)) \ { \ mpn_sqr((_z), (_x), (_xn)); \ } \ else \ { \ mpn_mul_n((_z), (_x), (_y), (_xn)); \ } \ } \ else if ((_xn) > (_yn)) \ { \ if ((_yn) == 1) \ (_z)[(_xn) + (_yn) - 1] = mpn_mul_1((_z), (_x), (_xn), (_y)[0]); \ else \ mpn_mul((_z), (_x), (_xn), (_y), (_yn)); \ } \ else \ { \ if ((_xn) == 1) \ (_z)[(_xn) + (_yn) - 1] = mpn_mul_1((_z), (_y), (_yn), (_x)[0]); \ else \ mpn_mul((_z), (_y), (_yn), (_x), (_xn)); \ } #define ARF_MUL_STACK_ALLOC 40 #define ARF_MUL_TLS_ALLOC 1000 extern TLS_PREFIX mp_ptr __arf_mul_tmp; extern TLS_PREFIX slong __arf_mul_alloc; ARB_DLL extern void _arf_mul_tmp_cleanup(void); #define ARF_MUL_TMP_DECL \ mp_limb_t tmp_stack[ARF_MUL_STACK_ALLOC]; \ #define ARF_MUL_TMP_ALLOC(tmp, alloc) \ if (alloc <= ARF_MUL_STACK_ALLOC) \ { \ tmp = tmp_stack; \ } \ else if (alloc <= ARF_MUL_TLS_ALLOC) \ { \ if (__arf_mul_alloc < alloc) \ { \ if (__arf_mul_alloc == 0) \ { \ flint_register_cleanup_function(_arf_mul_tmp_cleanup); \ } \ __arf_mul_tmp = flint_realloc(__arf_mul_tmp, sizeof(mp_limb_t) * alloc); \ __arf_mul_alloc = alloc; \ } \ tmp = __arf_mul_tmp; \ } \ else \ { \ tmp = flint_malloc(sizeof(mp_limb_t) * alloc); \ } #define ARF_MUL_TMP_FREE(tmp, alloc) \ if (alloc > ARF_MUL_TLS_ALLOC) \ flint_free(tmp); void arf_mul_special(arf_t z, const arf_t x, const arf_t y); int arf_mul_via_mpfr(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd); int arf_mul_rnd_any(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd); int arf_mul_rnd_down(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec); #define arf_mul(z, x, y, prec, rnd) \ ((rnd == FMPR_RND_DOWN) \ ? arf_mul_rnd_down(z, x, y, prec) \ : arf_mul_rnd_any(z, x, y, prec, rnd)) ARF_INLINE int arf_neg_mul(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (arf_is_special(y)) { arf_mul(z, x, y, prec, rnd); arf_neg(z, z); return 0; } else { arf_t t; *t = *y; ARF_NEG(t); return arf_mul(z, x, t, prec, rnd); } } ARF_INLINE int arf_mul_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ return arf_mul(z, x, t, prec, rnd); } ARF_INLINE int arf_mul_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_si(t, y); /* no need to free */ return arf_mul(z, x, t, prec, rnd); } int arf_mul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd); ARF_INLINE int arf_mul_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd) { if (!COEFF_IS_MPZ(*y)) return arf_mul_si(z, x, *y, prec, rnd); else return arf_mul_mpz(z, x, COEFF_TO_PTR(*y), prec, rnd); } #define ARF_ADD_STACK_ALLOC 40 #define ARF_ADD_TLS_ALLOC 1000 extern TLS_PREFIX mp_ptr __arf_add_tmp; extern TLS_PREFIX slong __arf_add_alloc; ARB_DLL extern void _arf_add_tmp_cleanup(void); #define ARF_ADD_TMP_DECL \ mp_limb_t tmp_stack[ARF_ADD_STACK_ALLOC]; \ #define ARF_ADD_TMP_ALLOC(tmp, alloc) \ if (alloc <= ARF_ADD_STACK_ALLOC) \ { \ tmp = tmp_stack; \ } \ else if (alloc <= ARF_ADD_TLS_ALLOC) \ { \ if (__arf_add_alloc < alloc) \ { \ if (__arf_add_alloc == 0) \ { \ flint_register_cleanup_function(_arf_add_tmp_cleanup); \ } \ __arf_add_tmp = flint_realloc(__arf_add_tmp, sizeof(mp_limb_t) * alloc); \ __arf_add_alloc = alloc; \ } \ tmp = __arf_add_tmp; \ } \ else \ { \ tmp = flint_malloc(sizeof(mp_limb_t) * alloc); \ } #define ARF_ADD_TMP_FREE(tmp, alloc) \ if (alloc > ARF_ADD_TLS_ALLOC) \ flint_free(tmp); int _arf_add_mpn(arf_t z, mp_srcptr xp, mp_size_t xn, int xsgnbit, const fmpz_t xexp, mp_srcptr yp, mp_size_t yn, int ysgnbit, flint_bitcnt_t shift, slong prec, arf_rnd_t rnd); int arf_add(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd); int arf_add_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd); int arf_add_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd); int arf_add_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd); int arf_add_fmpz_2exp(arf_ptr z, arf_srcptr x, const fmpz_t y, const fmpz_t exp, slong prec, arf_rnd_t rnd); int arf_sub(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd); int arf_sub_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd); int arf_sub_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd); int arf_sub_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd); int arf_addmul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd); ARF_INLINE int arf_addmul_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ return arf_addmul(z, x, t, prec, rnd); } ARF_INLINE int arf_addmul_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_si(t, y); /* no need to free */ return arf_addmul(z, x, t, prec, rnd); } int arf_addmul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd); ARF_INLINE int arf_addmul_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd) { if (!COEFF_IS_MPZ(*y)) return arf_addmul_si(z, x, *y, prec, rnd); else return arf_addmul_mpz(z, x, COEFF_TO_PTR(*y), prec, rnd); } int arf_submul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd); ARF_INLINE int arf_submul_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ return arf_submul(z, x, t, prec, rnd); } ARF_INLINE int arf_submul_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_si(t, y); /* no need to free */ return arf_submul(z, x, t, prec, rnd); } int arf_submul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd); ARF_INLINE int arf_submul_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd) { if (!COEFF_IS_MPZ(*y)) return arf_submul_si(z, x, *y, prec, rnd); else return arf_submul_mpz(z, x, COEFF_TO_PTR(*y), prec, rnd); } int arf_fma(arf_ptr res, arf_srcptr x, arf_srcptr y, arf_srcptr z, slong prec, arf_rnd_t rnd); int arf_sosq(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd); int arf_div(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd); ARF_INLINE int arf_div_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ return arf_div(z, x, t, prec, rnd); } ARF_INLINE int arf_ui_div(arf_ptr z, ulong x, arf_srcptr y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_ui(t, x); /* no need to free */ return arf_div(z, t, y, prec, rnd); } ARF_INLINE int arf_div_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_si(t, y); /* no need to free */ return arf_div(z, x, t, prec, rnd); } ARF_INLINE int arf_si_div(arf_ptr z, slong x, arf_srcptr y, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_si(t, x); /* no need to free */ return arf_div(z, t, y, prec, rnd); } ARF_INLINE int arf_div_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_fmpz(t, y); r = arf_div(z, x, t, prec, rnd); arf_clear(t); return r; } ARF_INLINE int arf_fmpz_div(arf_ptr z, const fmpz_t x, arf_srcptr y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_fmpz(t, x); r = arf_div(z, t, y, prec, rnd); arf_clear(t); return r; } ARF_INLINE int arf_fmpz_div_fmpz(arf_ptr z, const fmpz_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) { arf_t t, u; int r; arf_init(t); arf_init(u); arf_set_fmpz(t, x); arf_set_fmpz(u, y); r = arf_div(z, t, u, prec, rnd); arf_clear(t); arf_clear(u); return r; } int arf_sqrt(arf_ptr z, arf_srcptr x, slong prec, arf_rnd_t rnd); int arf_sqrt_ui(arf_t z, ulong x, slong prec, arf_rnd_t rnd); int arf_sqrt_fmpz(arf_t z, const fmpz_t x, slong prec, arf_rnd_t rnd); int arf_rsqrt(arf_ptr z, arf_srcptr x, slong prec, arf_rnd_t rnd); int arf_root(arf_t z, const arf_t x, ulong k, slong prec, arf_rnd_t rnd); /* Magnitude bounds */ void arf_get_mag(mag_t y, const arf_t x); void arf_get_mag_lower(mag_t y, const arf_t x); ARF_INLINE void arf_set_mag(arf_t y, const mag_t x) { if (mag_is_zero(x)) { arf_zero(y); } else if (mag_is_inf(x)) { arf_pos_inf(y); } else { _fmpz_set_fast(ARF_EXPREF(y), MAG_EXPREF(x)); ARF_DEMOTE(y); ARF_XSIZE(y) = ARF_MAKE_XSIZE(1, 0); ARF_NOPTR_D(y)[0] = MAG_MAN(x) << (FLINT_BITS - MAG_BITS); } } ARF_INLINE void mag_init_set_arf(mag_t y, const arf_t x) { mag_init(y); arf_get_mag(y, x); } ARF_INLINE void mag_fast_init_set_arf(mag_t y, const arf_t x) { if (ARF_IS_SPECIAL(x)) /* x == 0 */ { mag_fast_zero(y); } else { mp_srcptr xp; mp_size_t xn; ARF_GET_MPN_READONLY(xp, xn, x); MAG_MAN(y) = (xp[xn - 1] >> (FLINT_BITS - MAG_BITS)) + LIMB_ONE; MAG_EXP(y) = ARF_EXP(x); MAG_FAST_ADJUST_ONE_TOO_LARGE(y); } } ARF_INLINE void arf_mag_fast_add_ulp(mag_t z, const mag_t x, const arf_t y, slong prec) { mag_fast_add_2exp_si(z, x, ARF_EXP(y) - prec); } ARF_INLINE void arf_mag_add_ulp(mag_t z, const mag_t x, const arf_t y, slong prec) { if (ARF_IS_SPECIAL(y)) { flint_printf("error: ulp error not defined for special value!\n"); flint_abort(); } else if (MAG_IS_LAGOM(z) && MAG_IS_LAGOM(x) && ARF_IS_LAGOM(y)) { arf_mag_fast_add_ulp(z, x, y, prec); } else { fmpz_t e; fmpz_init(e); fmpz_sub_ui(e, ARF_EXPREF(y), prec); mag_add_2exp_fmpz(z, x, e); fmpz_clear(e); } } ARF_INLINE void arf_mag_set_ulp(mag_t z, const arf_t y, slong prec) { if (ARF_IS_SPECIAL(y)) { flint_printf("error: ulp error not defined for special value!\n"); flint_abort(); } else { _fmpz_add_fast(MAG_EXPREF(z), ARF_EXPREF(y), 1 - prec); MAG_MAN(z) = MAG_ONE_HALF; } } void arf_get_fmpq(fmpq_t y, const arf_t x); ARF_INLINE int arf_set_fmpq(arf_t y, const fmpq_t x, slong prec, arf_rnd_t rnd) { return arf_fmpz_div_fmpz(y, fmpq_numref(x), fmpq_denref(x), prec, rnd); } int arf_complex_mul(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd); int arf_complex_mul_fallback(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd); int arf_complex_sqr(arf_t e, arf_t f, const arf_t a, const arf_t b, slong prec, arf_rnd_t rnd); int arf_sum(arf_t s, arf_srcptr terms, slong len, slong prec, arf_rnd_t rnd); double arf_get_d(const arf_t x, arf_rnd_t rnd); void arf_set_d(arf_t x, double v); ARF_INLINE slong arf_allocated_bytes(const arf_t x) { slong size = fmpz_allocated_bytes(ARF_EXPREF(x)); if (ARF_HAS_PTR(x)) size += ARF_PTR_ALLOC(x) * sizeof(mp_limb_t); return size; } int arf_load_str(arf_t res, const char * data); char * arf_dump_str(const arf_t x); int arf_load_file(arf_t res, FILE *stream); int arf_dump_file(FILE* stream, const arf_t x); #ifdef __cplusplus } #endif #endif arb-2.22.1/arf/000077500000000000000000000000001417376376500131355ustar00rootroot00000000000000arb-2.22.1/arf/abs_bound_lt_2exp_si.c000066400000000000000000000017321417376376500173700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" slong arf_abs_bound_lt_2exp_si(const arf_t x) { slong res; if (arf_is_special(x)) { if (arf_is_zero(x)) return -ARF_PREC_EXACT; else return ARF_PREC_EXACT; } if (!COEFF_IS_MPZ(ARF_EXP(x))) return ARF_EXP(x); if (fmpz_fits_si(ARF_EXPREF(x))) res = fmpz_get_si(ARF_EXPREF(x)); else res = fmpz_sgn(ARF_EXPREF(x)) < 0 ? -ARF_PREC_EXACT : ARF_PREC_EXACT; if (res < -ARF_PREC_EXACT) res = -ARF_PREC_EXACT; if (res > ARF_PREC_EXACT) res = ARF_PREC_EXACT; return res; } arb-2.22.1/arf/add.c000066400000000000000000000136721417376376500140420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_add_special(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (arf_is_zero(x)) { if (arf_is_zero(y)) { arf_zero(z); return 0; } else return arf_set_round(z, y, prec, rnd); } else if (arf_is_zero(y)) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_nan(x) || arf_is_nan(y) || (arf_is_pos_inf(x) && arf_is_neg_inf(y)) || (arf_is_neg_inf(x) && arf_is_pos_inf(y))) { arf_nan(z); return 0; } else if (arf_is_special(x)) { arf_set(z, x); return 0; } else { arf_set(z, y); return 0; } } int arf_add(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; slong shift; if (arf_is_special(x) || arf_is_special(y)) { return arf_add_special(z, x, y, prec, rnd); } shift = _fmpz_sub_small(ARF_EXPREF(x), ARF_EXPREF(y)); if (shift < 0) { arf_srcptr __t; __t = x; x = y; y = __t; shift = -shift; } ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); return _arf_add_mpn(z, xptr, xn, ARF_SGNBIT(x), ARF_EXPREF(x), yptr, yn, ARF_SGNBIT(y), shift, prec, rnd); } int arf_add_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; mp_limb_t ytmp; int xsgnbit, ysgnbit; fmpz yexp; slong shift; if (y == 0) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_special(x)) { if (arf_is_zero(x)) return arf_set_round_si(z, y, prec, rnd); else { arf_set(z, x); return 0; } } ysgnbit = (y < 0); if (ysgnbit) ytmp = -y; else ytmp = y; yptr = &ytmp; yn = 1; yexp = FLINT_BITS; /* XXX: worth the trouble to top-align y? */ shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp); xsgnbit = ARF_SGNBIT(x); ARF_GET_MPN_READONLY(xptr, xn, x); if (shift >= 0) return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), yptr, yn, ysgnbit, shift, prec, rnd); else return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp, xptr, xn, xsgnbit, -shift, prec, rnd); } int arf_add_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; mp_limb_t ytmp; int xsgnbit, ysgnbit; fmpz yexp; slong shift; if (y == 0) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_special(x)) { if (arf_is_zero(x)) return arf_set_round_ui(z, y, prec, rnd); else { arf_set(z, x); return 0; } } ysgnbit = 0; ytmp = y; yptr = &ytmp; yn = 1; yexp = FLINT_BITS; shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp); xsgnbit = ARF_SGNBIT(x); ARF_GET_MPN_READONLY(xptr, xn, x); if (shift >= 0) return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), yptr, yn, ysgnbit, shift, prec, rnd); else return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp, xptr, xn, xsgnbit, -shift, prec, rnd); } int arf_add_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; mp_limb_t ytmp; int xsgnbit, ysgnbit; fmpz yexp; slong shift; if (fmpz_is_zero(y)) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_special(x)) { if (arf_is_zero(x)) return arf_set_round_fmpz(z, y, prec, rnd); else { arf_set(z, x); return 0; } } FMPZ_GET_MPN_READONLY(ysgnbit, yn, yptr, ytmp, *y) yexp = yn * FLINT_BITS; shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp); xsgnbit = ARF_SGNBIT(x); ARF_GET_MPN_READONLY(xptr, xn, x); if (shift >= 0) return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), yptr, yn, ysgnbit, shift, prec, rnd); else return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp, xptr, xn, xsgnbit, -shift, prec, rnd); } int arf_add_fmpz_2exp(arf_ptr z, arf_srcptr x, const fmpz_t y, const fmpz_t exp, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; mp_limb_t ytmp; int xsgnbit, ysgnbit, inexact; fmpz_t yexp; slong shift; if (fmpz_is_zero(y)) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_special(x)) { if (arf_is_zero(x)) { inexact = arf_set_round_fmpz(z, y, prec, rnd); arf_mul_2exp_fmpz(z, z, exp); return inexact; } else { arf_set(z, x); return 0; } } FMPZ_GET_MPN_READONLY(ysgnbit, yn, yptr, ytmp, *y) fmpz_init(yexp); fmpz_add_ui(yexp, exp, yn * FLINT_BITS); shift = _fmpz_sub_small(ARF_EXPREF(x), yexp); xsgnbit = ARF_SGNBIT(x); ARF_GET_MPN_READONLY(xptr, xn, x); if (shift >= 0) inexact = _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), yptr, yn, ysgnbit, shift, prec, rnd); else inexact = _arf_add_mpn(z, yptr, yn, ysgnbit, yexp, xptr, xn, xsgnbit, -shift, prec, rnd); fmpz_clear(yexp); return inexact; } arb-2.22.1/arf/add_mpn.c000066400000000000000000000252541417376376500147130ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" TLS_PREFIX mp_ptr __arf_add_tmp = NULL; TLS_PREFIX slong __arf_add_alloc = 0; void _arf_add_tmp_cleanup(void) { flint_free(__arf_add_tmp); __arf_add_tmp = NULL; __arf_add_alloc = 0; } /* Assumptions: top limbs of x and y nonzero. */ int _arf_add_mpn(arf_t z, mp_srcptr xp, mp_size_t xn, int xsgnbit, const fmpz_t xexp, mp_srcptr yp, mp_size_t yn, int ysgnbit, flint_bitcnt_t shift, slong prec, arf_rnd_t rnd) { mp_size_t wn, zn, zn_original, alloc, xbase, wbase; mp_size_t shift_limbs; flint_bitcnt_t shift_bits; int inexact; slong fix; mp_limb_t cy; mp_ptr tmp; ARF_ADD_TMP_DECL /* very fast case */ if (xn == 1 && yn == 1 && shift < FLINT_BITS - 1) { mp_limb_t hi, lo, xhi, xlo, yhi, ylo; xhi = xp[0]; yhi = yp[0]; xlo = xhi << (FLINT_BITS - 1); xhi = xhi >> 1; ylo = yhi << (FLINT_BITS - (shift + 1)); yhi = yhi >> (shift + 1); if (xsgnbit == ysgnbit) { add_ssaaaa(hi, lo, xhi, xlo, yhi, ylo); } else { if (xhi > yhi) { sub_ddmmss(hi, lo, xhi, xlo, yhi, ylo); } else if (xhi < yhi) { sub_ddmmss(hi, lo, yhi, ylo, xhi, xlo); xsgnbit = ysgnbit; } else { if (xlo > ylo) { sub_ddmmss(hi, lo, xhi, xlo, yhi, ylo); } else if (xlo < ylo) { sub_ddmmss(hi, lo, yhi, ylo, xhi, xlo); xsgnbit = ysgnbit; } else { arf_zero(z); return 0; } } } inexact = _arf_set_round_uiui(z, &fix, hi, lo, xsgnbit, prec, rnd); _fmpz_add_fast(ARF_EXPREF(z), xexp, fix + 1); return inexact; } /* somewhat fast case */ if (xn <= 2 && yn <= 2 && shift <= 2 * FLINT_BITS) { mp_limb_t t[5], xtmp[4], ytmp[4], yhi, ylo; slong fix2; xtmp[0] = 0; xtmp[1] = 0; if (xn == 1) { xtmp[2] = 0; xtmp[3] = xp[0]; } else { xtmp[2] = xp[0]; xtmp[3] = xp[1]; } ytmp[0] = 0; ytmp[1] = 0; ytmp[2] = 0; ytmp[3] = 0; if (yn == 1) { yhi = yp[0]; ylo = 0; } else { yhi = yp[1]; ylo = yp[0]; } shift_limbs = shift / FLINT_BITS; shift_bits = shift % FLINT_BITS; if (shift_bits == 0) { ytmp[3 - shift_limbs] = yhi; ytmp[2 - shift_limbs] = ylo; } else { ytmp[3 - shift_limbs] = yhi >> shift_bits; ytmp[2 - shift_limbs] = (yhi << (FLINT_BITS - shift_bits)) | (ylo >> (shift_bits)); ytmp[1 - shift_limbs] = ylo << (FLINT_BITS - shift_bits); } if (xsgnbit == ysgnbit) { t[4] = cy = mpn_add_n(t, xtmp, ytmp, 4); fix2 = cy * FLINT_BITS; zn = 4 + cy; while (t[zn - 1] == 0) { zn--; fix2 -= FLINT_BITS; } } else { #if 1 cy = mpn_sub_n(t, xtmp, ytmp, 4); if (cy) { mpn_neg_n(t, t, 4); xsgnbit = ysgnbit; } zn = 4; fix2 = 0; while (t[zn - 1] == 0) { zn--; fix2 -= FLINT_BITS; if (zn == 0) { arf_zero(z); return 0; } } #else int cmp; cmp = mpn_cmp(xtmp, ytmp, 4); if (cmp > 0) { mpn_sub_n(t, xtmp, ytmp, 4); } else if (cmp < 0) { mpn_sub_n(t, ytmp, xtmp, 4); xsgnbit = ysgnbit; } else { arf_zero(z); return 0; } fix2 = 0; zn = 4; while (t[zn - 1] == 0) { zn--; fix2 -= FLINT_BITS; } #endif } inexact = _arf_set_round_mpn(z, &fix, t, zn, xsgnbit, prec, rnd); _fmpz_add_fast(ARF_EXPREF(z), xexp, fix + fix2); return inexact; } /* x +/- eps */ if (shift > prec + FLINT_BITS + 1 && prec != ARF_PREC_EXACT && shift > (xn + 1) * FLINT_BITS) { zn = (prec + FLINT_BITS - 1) / FLINT_BITS; zn_original = zn = FLINT_MAX(zn, xn) + 2; shift_limbs = zn - xn; alloc = zn + 1; ARF_ADD_TMP_ALLOC(tmp, alloc) flint_mpn_zero(tmp, shift_limbs); flint_mpn_copyi(tmp + shift_limbs, xp, xn); if (xsgnbit == ysgnbit) { tmp[0] = 1; } else { mpn_sub_1(tmp, tmp, zn, 1); while (tmp[zn-1] == 0) zn--; } _arf_set_round_mpn(z, &fix, tmp, zn, xsgnbit, prec, rnd); fix += (zn - zn_original) * FLINT_BITS; _fmpz_add_fast(ARF_EXPREF(z), xexp, fix); ARF_ADD_TMP_FREE(tmp, alloc) return 1; } shift_limbs = shift / FLINT_BITS; shift_bits = shift % FLINT_BITS; /* TODO: shift == 0 optimization! (common case) */ /* w = y shifted */ wn = yn + (shift_bits != 0); /* Size of sum (possibly one more limb than this for carry). */ zn_original = zn = FLINT_MAX(xn, wn + shift_limbs); alloc = zn + 1; ARF_ADD_TMP_ALLOC(tmp, alloc) /* Low limbs of both operands */ xbase = zn - xn; wbase = zn - shift_limbs - wn; /* Shift y to its correct offset in the sum. */ if (shift_bits == 0) flint_mpn_copyi(tmp + wbase, yp, yn); else tmp[wbase] = cy = mpn_rshift(tmp + wbase + 1, yp, yn, shift_bits); if (xsgnbit == ysgnbit) { if (shift_limbs >= xn) { /* XXXXXX WWWWWWW */ flint_mpn_zero(tmp + wn, zn - xn - wn); flint_mpn_copyi(tmp + zn - xn, xp, xn); cy = 0; } else if (shift_limbs == 0) { /* XXXXXX or XXXXX WWWW WWWWWWW */ if (wn < xn) { flint_mpn_copyi(tmp, xp, xn - wn); cy = mpn_add_n(tmp + wbase, xp + wbase, tmp + wbase, wn); } else { cy = mpn_add_n(tmp + xbase, xp, tmp + xbase, xn); } } else if (xbase >= wbase) { /* XXXXXX or XXXXXX WWWWWWW WWWW */ cy = mpn_add_n(tmp + xbase, tmp + xbase, xp, wn - xbase); cy = mpn_add_1(tmp + wn, xp + wn - xbase, zn - wn, cy); } else { /* XXXXXXXX todo: merge with above? WWW */ flint_mpn_copyi(tmp, xp, wbase); cy = mpn_add_n(tmp + wbase, tmp + wbase, xp + wbase, wn); cy = mpn_add_1(tmp + zn - shift_limbs, xp + xn - shift_limbs, shift_limbs, cy); } /* There could be a carry. */ tmp[zn] = cy; zn += cy; } else { if (shift_limbs >= xn) { /* XXXXXX WWWWWWW */ mpn_neg(tmp, tmp, wn); flint_mpn_store(tmp + wn, zn - xn - wn, -LIMB_ONE); mpn_sub_1(tmp + zn - xn, xp, xn, 1); } else if (shift_limbs == 0) { /* XXXXXX (1) or XXXXX (2) WWWW WWWWWWW */ if (wn <= xn) /* (1) */ { if (mpn_cmp(xp + wbase, tmp + wbase, wn) >= 0) { flint_mpn_copyi(tmp, xp, wbase); mpn_sub_n(tmp + wbase, xp + wbase, tmp + wbase, wn); } else { xsgnbit = ysgnbit; mpn_sub_n(tmp + wbase, tmp + wbase, xp + wbase, wn); if (wbase != 0) { cy = mpn_neg_n(tmp, xp, wbase); mpn_sub_1(tmp + wbase, tmp + wbase, wn, cy); } } } else /* (2) */ { if (mpn_cmp(tmp + xbase, xp, xn) >= 0) { xsgnbit = ysgnbit; mpn_sub_n(tmp + xbase, tmp + xbase, xp, xn); } else { cy = mpn_neg(tmp, tmp, xbase); mpn_sub_n(tmp + xbase, xp, tmp + xbase, xn); mpn_sub_1(tmp + xbase, tmp + xbase, xn, cy); } } } else if (xbase >= wbase) { /* XXXXXX or XXXXXX WWWWWWW WWWW */ if (xbase > 0) { cy = mpn_sub_n(tmp + xbase, xp, tmp + xbase, wn - xbase); cy = mpn_sub_1(tmp + wn, xp + xn - shift_limbs, shift_limbs, cy); cy = mpn_neg(tmp, tmp, xbase); mpn_sub_1(tmp + xbase, tmp + xbase, xn, cy); } else { cy = mpn_sub_n(tmp, xp, tmp, wn); cy = mpn_sub_1(tmp + wn, xp + wn, xn - wn, cy); } } else { /* XXXXXXXX WWW */ flint_mpn_copyi(tmp, xp, wbase); cy = mpn_sub_n(tmp + wbase, xp + wbase, tmp + wbase, wn); mpn_sub_1(tmp + zn - shift_limbs, xp + xn - shift_limbs, shift_limbs, cy); } /* There could be cancellation. */ while (zn > 0 && tmp[zn - 1] == 0) zn--; } if (zn == 0) { arf_zero(z); inexact = 0; } else { inexact = _arf_set_round_mpn(z, &fix, tmp, zn, xsgnbit, prec, rnd); fix += (zn - zn_original) * FLINT_BITS; _fmpz_add_fast(ARF_EXPREF(z), xexp, fix); } ARF_ADD_TMP_FREE(tmp, alloc) return inexact; } arb-2.22.1/arf/addmul.c000066400000000000000000000073561417376376500145620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_addmul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn, zn, tn, alloc; mp_srcptr xptr, yptr, zptr; mp_ptr tptr, tptr2; fmpz_t texp; slong shift; int tsgnbit, inexact; ARF_MUL_TMP_DECL if (arf_is_special(x) || arf_is_special(y) || arf_is_special(z)) { if (arf_is_zero(z)) { return arf_mul(z, x, y, prec, rnd); } else if (arf_is_finite(x) && arf_is_finite(y)) { return arf_set_round(z, z, prec, rnd); } else { /* todo: speed up */ arf_t t; arf_init(t); arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(z, z, t, prec, rnd); arf_clear(t); return inexact; } } tsgnbit = ARF_SGNBIT(x) ^ ARF_SGNBIT(y); ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); ARF_GET_MPN_READONLY(zptr, zn, z); fmpz_init(texp); _fmpz_add2_fast(texp, ARF_EXPREF(x), ARF_EXPREF(y), 0); shift = _fmpz_sub_small(ARF_EXPREF(z), texp); alloc = tn = xn + yn; ARF_MUL_TMP_ALLOC(tptr2, alloc) tptr = tptr2; ARF_MPN_MUL(tptr, xptr, xn, yptr, yn); tn -= (tptr[0] == 0); tptr += (tptr[0] == 0); if (shift >= 0) inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z), tptr, tn, tsgnbit, shift, prec, rnd); else inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp, zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd); ARF_MUL_TMP_FREE(tptr2, alloc) fmpz_clear(texp); return inexact; } int arf_addmul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn, zn, tn, alloc; mp_srcptr xptr, yptr, zptr; mp_ptr tptr, tptr2; fmpz_t texp, yexp; slong shift; int tsgnbit, ysgnbit, inexact; ARF_MUL_TMP_DECL yn = FLINT_ABS(y->_mp_size); if (arf_is_special(x) || yn == 0 || arf_is_special(z)) { if (arf_is_zero(z)) { return arf_mul_mpz(z, x, y, prec, rnd); } else if (arf_is_finite(x)) { return arf_set_round(z, z, prec, rnd); } else { /* todo: speed up */ arf_t t; arf_init(t); arf_mul_mpz(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(z, z, t, prec, rnd); arf_clear(t); return inexact; } } ARF_GET_MPN_READONLY(xptr, xn, x); yptr = y->_mp_d; ysgnbit = (y->_mp_size < 0); *yexp = yn * FLINT_BITS; ARF_GET_MPN_READONLY(zptr, zn, z); fmpz_init(texp); tsgnbit = ARF_SGNBIT(x) ^ ysgnbit; alloc = tn = xn + yn; ARF_MUL_TMP_ALLOC(tptr2, alloc) tptr = tptr2; ARF_MPN_MUL(tptr, xptr, xn, yptr, yn); shift = (tptr[tn - 1] == 0) * FLINT_BITS; tn -= (tptr[tn - 1] == 0); _fmpz_add2_fast(texp, ARF_EXPREF(x), yexp, -shift); shift = _fmpz_sub_small(ARF_EXPREF(z), texp); if (shift >= 0) inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z), tptr, tn, tsgnbit, shift, prec, rnd); else inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp, zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd); ARF_MUL_TMP_FREE(tptr2, alloc) fmpz_clear(texp); return inexact; } arb-2.22.1/arf/ceil.c000066400000000000000000000020001417376376500142050ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_ceil(arf_t z, const arf_t x) { if (arf_is_special(x) || arf_is_int(x)) { arf_set(z, x); } else { slong exp = ARF_EXP(x); /* now exp cannot be too large, as we would have caught this in arf_is_int() */ if (COEFF_IS_MPZ(exp) || exp <= 0) { if (ARF_SGNBIT(x)) arf_zero(z); else arf_one(z); } else if (exp == 1) { arf_set_si(z, ARF_SGNBIT(x) ? -1 : 2); } else { arf_set_round(z, x, exp, ARF_RND_CEIL); } } } arb-2.22.1/arf/clear.c000066400000000000000000000010731417376376500143700ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_clear(arf_t x) { ARF_DEMOTE(x); /* fmpz_clear(), but avoids a redundant store */ if (COEFF_IS_MPZ(ARF_EXP(x))) _fmpz_clear_mpz(ARF_EXP(x)); } arb-2.22.1/arf/cmp.c000066400000000000000000000034411417376376500140620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_cmp(const arf_t x, const arf_t y) { int xs, ys, ec, mc; mp_size_t xn, yn; mp_srcptr xp, yp; if (arf_is_special(x) || arf_is_special(y)) { if (arf_equal(x, y)) return 0; if (arf_is_nan(x) || arf_is_nan(y)) return 0; if (arf_is_zero(y)) return arf_sgn(x); if (arf_is_zero(x)) return -arf_sgn(y); if (arf_is_pos_inf(x)) return 1; if (arf_is_neg_inf(y)) return 1; return -1; } xs = ARF_SGNBIT(x); ys = ARF_SGNBIT(y); if (xs != ys) return xs ? -1 : 1; ec = fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y)); if (ec != 0) return ((ec < 0) ^ xs) ? -1 : 1; ARF_GET_MPN_READONLY(xp, xn, x); ARF_GET_MPN_READONLY(yp, yn, y); if (xn >= yn) mc = mpn_cmp(xp + xn - yn, yp, yn); else mc = mpn_cmp(xp, yp + yn - xn, xn); if (mc != 0) return ((mc < 0) ^ xs) ? -1 : 1; if (xn != yn) return ((xn < yn) ^ xs) ? -1 : 1; return 0; } int arf_cmp_si(const arf_t x, slong y) { arf_t t; arf_init_set_si(t, y); /* no need to free */ return arf_cmp(x, t); } int arf_cmp_ui(const arf_t x, ulong y) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ return arf_cmp(x, t); } int arf_cmp_d(const arf_t x, double y) { arf_t t; arf_init(t); /* no need to free */ arf_set_d(t, y); return arf_cmp(x, t); } arb-2.22.1/arf/cmp_2exp_si.c000066400000000000000000000022521417376376500155120ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_cmp_2exp_si(const arf_t x, slong e) { if (arf_is_special(x)) { if (arf_is_zero(x)) return -1; if (arf_is_pos_inf(x)) return 1; if (arf_is_neg_inf(x)) return -1; return 0; } if (ARF_SGNBIT(x)) return -1; /* Fast path. */ if (!COEFF_IS_MPZ(ARF_EXP(x))) { if (ARF_IS_POW2(x) && (ARF_EXP(x) - 1 == e)) return 0; else return (ARF_EXP(x) <= e) ? -1 : 1; } if (ARF_IS_POW2(x)) { fmpz_t t; fmpz_init(t); fmpz_one(t); fmpz_add_si(t, t, e); if (fmpz_equal(ARF_EXPREF(x), t)) { fmpz_clear(t); return 0; } fmpz_clear(t); } return (fmpz_cmp_si(ARF_EXPREF(x), e) <= 0) ? -1 : 1; } arb-2.22.1/arf/cmpabs.c000066400000000000000000000030521417376376500145460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_cmpabs(const arf_t x, const arf_t y) { int ec, mc; mp_size_t xn, yn; mp_srcptr xp, yp; if (arf_is_special(x) || arf_is_special(y)) { if (arf_equal(x, y)) return 0; if (arf_is_nan(x) || arf_is_nan(y)) return 0; if (arf_is_zero(x)) return -1; if (arf_is_zero(y)) return 1; if (arf_is_inf(x)) return arf_is_inf(y) ? 0 : 1; if (arf_is_inf(y)) return -1; return -1; } ec = fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y)); if (ec != 0) return (ec < 0) ? -1 : 1; ARF_GET_MPN_READONLY(xp, xn, x); ARF_GET_MPN_READONLY(yp, yn, y); if (xn >= yn) mc = mpn_cmp(xp + xn - yn, yp, yn); else mc = mpn_cmp(xp, yp + yn - xn, xn); if (mc != 0) return (mc < 0) ? -1 : 1; if (xn != yn) return (xn < yn) ? -1 : 1; return 0; } int arf_cmpabs_ui(const arf_t x, ulong y) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ return arf_cmpabs(x, t); } int arf_cmpabs_d(const arf_t x, double y) { arf_t t; arf_init(t); /* no need to free */ arf_set_d(t, y); return arf_cmpabs(x, t); } arb-2.22.1/arf/cmpabs_2exp_si.c000066400000000000000000000021271417376376500162010ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_cmpabs_2exp_si(const arf_t x, slong e) { if (arf_is_special(x)) { if (arf_is_zero(x)) return -1; if (arf_is_inf(x)) return 1; return 0; } /* Fast path. */ if (!COEFF_IS_MPZ(ARF_EXP(x))) { if (ARF_IS_POW2(x) && (ARF_EXP(x) - 1 == e)) return 0; else return (ARF_EXP(x) <= e) ? -1 : 1; } if (ARF_IS_POW2(x)) { fmpz_t t; fmpz_init(t); fmpz_one(t); fmpz_add_si(t, t, e); if (fmpz_equal(ARF_EXPREF(x), t)) { fmpz_clear(t); return 0; } fmpz_clear(t); } return (fmpz_cmp_si(ARF_EXPREF(x), e) <= 0) ? -1 : 1; } arb-2.22.1/arf/complex_mul.c000066400000000000000000000170761417376376500156400ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_complex_mul_fallback(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd) { int inex1, inex2; /* here the operations are ordered to allow aliasing */ if (arf_is_zero(d)) { /* (a + bi) * c */ inex2 = arf_mul(f, b, c, prec, rnd); inex1 = arf_mul(e, a, c, prec, rnd); } else if (arf_is_zero(b)) { /* a * (c + di) */ inex2 = arf_mul(f, a, d, prec, rnd); inex1 = arf_mul(e, a, c, prec, rnd); } else if (arf_is_zero(c)) { /* (a + bi) * di = -bd + adi */ inex2 = arf_mul(e, a, d, prec, rnd); inex1 = arf_neg_mul(f, b, d, prec, rnd); arf_swap(e, f); } else if (arf_is_zero(a)) { /* bi * (c + di) = -bd + bci */ inex2 = arf_mul(e, b, c, prec, rnd); inex1 = arf_neg_mul(f, b, d, prec, rnd); arf_swap(e, f); } else { arf_t t, u, v, w; arf_init(t); arf_init(u); arf_init(v); arf_init(w); arf_mul(t, a, c, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(u, b, d, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(v, b, c, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(w, a, d, ARF_PREC_EXACT, ARF_RND_DOWN); inex1 = arf_sub(e, t, u, prec, rnd); inex2 = arf_add(f, v, w, prec, rnd); arf_clear(t); arf_clear(u); arf_clear(v); arf_clear(w); } return inex1 | (inex2 << 1); } int arf_complex_mul(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd) { mp_srcptr ap, bp, cp, dp; int asgn, bsgn, csgn, dsgn, inex1, inex2; mp_ptr tmp, acp, bdp, adp, bcp; mp_size_t an, bn, cn, dn, acn, bdn, adn, bcn, alloc; slong shift; slong aexp, bexp, cexp, dexp; fmpz texp, uexp; if (!ARF_IS_LAGOM(a) || !ARF_IS_LAGOM(b) || !ARF_IS_LAGOM(c) || !ARF_IS_LAGOM(d) || ARF_IS_SPECIAL(d) || ARF_IS_SPECIAL(a) || ARF_IS_SPECIAL(b) || ARF_IS_SPECIAL(c)) { return arf_complex_mul_fallback(e, f, a, b, c, d, prec, rnd); } ARF_GET_MPN_READONLY(ap, an, a); asgn = ARF_SGNBIT(a); aexp = ARF_EXP(a); ARF_GET_MPN_READONLY(bp, bn, b); bsgn = ARF_SGNBIT(b); bexp = ARF_EXP(b); ARF_GET_MPN_READONLY(cp, cn, c); csgn = ARF_SGNBIT(c); cexp = ARF_EXP(c); ARF_GET_MPN_READONLY(dp, dn, d); dsgn = ARF_SGNBIT(d); dexp = ARF_EXP(d); /* Gauss multiplication e = ac - bd f = (a+b)(c+d) - ac - bd */ if (an >= 20 && cn >= 20 && FLINT_ABS(an - bn) <= 2 && FLINT_ABS(cn - dn) <= 2 && FLINT_ABS(aexp - bexp) <= 64 && FLINT_ABS(cexp - dexp) <= 64) { fmpz_t za, zb, zc, zd, t, u, v; slong abot, bbot, cbot, dbot; abot = aexp - an * FLINT_BITS; bbot = bexp - bn * FLINT_BITS; cbot = cexp - cn * FLINT_BITS; dbot = dexp - dn * FLINT_BITS; texp = FLINT_MIN(abot, bbot); uexp = FLINT_MIN(cbot, dbot); fmpz_init(za); fmpz_init(zb); fmpz_init(zc); fmpz_init(zd); fmpz_init(t); fmpz_init(u); fmpz_init(v); /* todo: could avoid two copies */ fmpz_lshift_mpn(za, ap, an, asgn, abot - texp); fmpz_lshift_mpn(zb, bp, bn, bsgn, bbot - texp); fmpz_lshift_mpn(zc, cp, cn, csgn, cbot - uexp); fmpz_lshift_mpn(zd, dp, dn, dsgn, dbot - uexp); fmpz_add(t, za, zb); fmpz_add(v, zc, zd); fmpz_mul(u, t, v); fmpz_mul(t, za, zc); fmpz_mul(v, zb, zd); fmpz_sub(u, u, t); fmpz_sub(u, u, v); fmpz_sub(t, t, v); texp += uexp; inex1 = arf_set_round_fmpz_2exp(e, t, &texp, prec, rnd); inex2 = arf_set_round_fmpz_2exp(f, u, &texp, prec, rnd); fmpz_clear(za); fmpz_clear(zb); fmpz_clear(zc); fmpz_clear(zd); fmpz_clear(t); fmpz_clear(u); fmpz_clear(v); } else { ARF_MUL_TMP_DECL acn = an + cn; bdn = bn + dn; adn = an + dn; bcn = bn + cn; alloc = acn + bdn + adn + bcn; ARF_MUL_TMP_ALLOC(tmp, alloc) acp = tmp; bdp = acp + acn; adp = bdp + bdn; bcp = adp + adn; ARF_MPN_MUL(acp, ap, an, cp, cn) acn -= (acp[0] == 0); acp += (acp[0] == 0); ARF_MPN_MUL(bdp, bp, bn, dp, dn) bdn -= (bdp[0] == 0); bdp += (bdp[0] == 0); ARF_MPN_MUL(adp, ap, an, dp, dn) adn -= (adp[0] == 0); adp += (adp[0] == 0); ARF_MPN_MUL(bcp, bp, bn, cp, cn) bcn -= (bcp[0] == 0); bcp += (bcp[0] == 0); texp = aexp + cexp; uexp = bexp + dexp; shift = texp - uexp; if (shift >= 0) inex1 = _arf_add_mpn(e, acp, acn, asgn ^ csgn, &texp, bdp, bdn, bsgn ^ dsgn ^ 1, shift, prec, rnd); else inex1 = _arf_add_mpn(e, bdp, bdn, bsgn ^ dsgn ^ 1, &uexp, acp, acn, asgn ^ csgn, -shift, prec, rnd); texp = aexp + dexp; uexp = bexp + cexp; shift = texp - uexp; if (shift >= 0) inex2 = _arf_add_mpn(f, adp, adn, asgn ^ dsgn, &texp, bcp, bcn, bsgn ^ csgn, shift, prec, rnd); else inex2 = _arf_add_mpn(f, bcp, bcn, bsgn ^ csgn, &uexp, adp, adn, asgn ^ dsgn, -shift, prec, rnd); ARF_MUL_TMP_FREE(tmp, alloc) } return inex1 | (inex2 << 1); } int arf_complex_sqr(arf_t e, arf_t f, const arf_t a, const arf_t b, slong prec, arf_rnd_t rnd) { if (!ARF_IS_LAGOM(a) || !ARF_IS_LAGOM(b) || ARF_IS_SPECIAL(a) || ARF_IS_SPECIAL(b)) { return arf_complex_mul_fallback(e, f, a, b, a, b, prec, rnd); } else { mp_srcptr ap, bp; int inex1, inex2; mp_ptr tmp, aap, bbp; mp_size_t an, bn, aan, bbn, alloc; slong shift; slong aexp, bexp; fmpz texp, uexp; TMP_INIT; ARF_GET_MPN_READONLY(ap, an, a); aexp = ARF_EXP(a); ARF_GET_MPN_READONLY(bp, bn, b); bexp = ARF_EXP(b); aan = 2 * an; bbn = 2 * bn; alloc = aan + bbn; TMP_START; tmp = TMP_ALLOC(alloc * sizeof(mp_limb_t)); aap = tmp; bbp = tmp + aan; ARF_MPN_MUL(aap, ap, an, ap, an) aan -= (aap[0] == 0); aap += (aap[0] == 0); ARF_MPN_MUL(bbp, bp, bn, bp, bn) bbn -= (bbp[0] == 0); bbp += (bbp[0] == 0); texp = aexp + aexp; uexp = bexp + bexp; shift = texp - uexp; inex2 = arf_mul(f, a, b, prec, rnd); ARF_EXP(f) += 1; if (shift >= 0) inex1 = _arf_add_mpn(e, aap, aan, 0, &texp, bbp, bbn, 1, shift, prec, rnd); else inex1 = _arf_add_mpn(e, bbp, bbn, 1, &uexp, aap, aan, 0, -shift, prec, rnd); TMP_END; return inex1 | (inex2 << 1); } } arb-2.22.1/arf/debug.c000066400000000000000000000013451417376376500143720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_debug(const arf_t x) { mp_srcptr d; mp_size_t n; slong i; flint_printf("{exp="); fmpz_print(&x->exp); flint_printf("; size=%wu; sgnbit=%wd; digits=[", ARF_SIZE(x), ARF_SGNBIT(x)); ARF_GET_MPN_READONLY(d, n, x); for (i = 0; i < n; i++) flint_printf(" %wu", d[i]); flint_printf("]}"); } arb-2.22.1/arf/div.c000066400000000000000000000075001417376376500140650ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/mpn_extras.h" #include "arf.h" #if !defined(__MPIR_VERSION) #define USE_GMP_DIV_Q 1 void __gmpn_div_q(mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr); #else #define USE_GMP_DIV_Q 0 #endif void arf_div_special(arf_t z, const arf_t x, const arf_t y) { if ((arf_is_zero(x) && !arf_is_zero(y) && !arf_is_nan(y)) || (arf_is_inf(y) && !arf_is_special(x))) { arf_zero(z); } else if (arf_is_zero(y) || (arf_is_special(x) && arf_is_special(y)) || arf_is_nan(x) || arf_is_nan(y)) { arf_nan(z); } else if (arf_sgn(x) == arf_sgn(y)) arf_pos_inf(z); else arf_neg_inf(z); } int arf_div(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn, zn, sn, tn, alloc; mp_srcptr xptr, yptr; mp_ptr tmp; mp_ptr tptr, zptr; int inexact; slong fix, fix2; ARF_MUL_TMP_DECL if (arf_is_special(x) || arf_is_special(y)) { arf_div_special(z, x, y); return 0; } ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); /* Division by a power of two */ if (yn == 1 && yptr[0] == LIMB_TOP) { fmpz_t t; fmpz_init_set(t, ARF_EXPREF(y)); if (ARF_SGNBIT(y)) inexact = arf_neg_round(z, x, prec, rnd); else inexact = arf_set_round(z, x, prec, rnd); _fmpz_sub2_fast(ARF_EXPREF(z), ARF_EXPREF(z), t, 1); fmpz_clear(t); return inexact; } sn = FLINT_MAX(prec - xn * FLINT_BITS + yn * FLINT_BITS, 0) + 32; sn = (sn + FLINT_BITS - 1) / FLINT_BITS; /* Need space for numerator (tn), quotient (zn), and one extra limb at the top of tptr for the multiplication to check the remainder. */ tn = xn + sn; zn = tn - yn + 1; alloc = zn + (tn + 1); /* need tn + 1 extra temporary limbs, which we store at the end of tptr */ #if USE_GMP_DIV_Q alloc += tn + 1; #endif ARF_MUL_TMP_ALLOC(tmp, alloc) zptr = tmp; tptr = tmp + zn; flint_mpn_zero(tptr, sn); flint_mpn_copyi(tptr + sn, xptr, xn); /* uses tn + 1 extra temporary limbs, tn limbs after tptr */ #if USE_GMP_DIV_Q __gmpn_div_q(zptr, tptr, tn, yptr, yn, tptr + tn); #else mpn_tdiv_q(zptr, tptr, tn, yptr, yn); #endif if (zptr[zn - 1] == 0) { zn--; fix2 = 0; } else { fix2 = FLINT_BITS; } /* The remainder can only be zero if the last several bits of the extended quotient are zero. */ if ((zptr[0] & ((LIMB_ONE << 24) - 1)) == 0) { /* The quotient is exact iff multiplying by y gives back the input. Note: the multiplication may write sn + xn + 1 limbs, but tptr[sn + xn] is guaranteed to be zero in that case since the approximate quotient cannot be larger than the true quotient. */ if (zn >= yn) mpn_mul(tptr, zptr, zn, yptr, yn); else mpn_mul(tptr, yptr, yn, zptr, zn); /* The quotient is not exact. Perturbing the approximate quotient and rounding gives the correct the result. */ if (!flint_mpn_zero_p(tptr, sn) || mpn_cmp(tptr + sn, xptr, xn) != 0) { zptr[0]++; } } inexact = _arf_set_round_mpn(z, &fix, zptr, zn, ARF_SGNBIT(x) ^ ARF_SGNBIT(y), prec, rnd); _fmpz_sub2_fast(ARF_EXPREF(z), ARF_EXPREF(x), ARF_EXPREF(y), fix + fix2); ARF_MUL_TMP_FREE(tmp, alloc) return inexact; } arb-2.22.1/arf/dump_file.c000066400000000000000000000011701417376376500152440ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arf.h" int arf_dump_file(FILE* stream, const arf_t x) { int nwrite; char* data = arf_dump_str(x); nwrite = fputs(data, stream); if (nwrite == EOF) return nwrite; flint_free(data); return 0; } arb-2.22.1/arf/dump_str.c000066400000000000000000000030701417376376500151360ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arf.h" static void arf_get_fmpz_2exp_dump(fmpz_t m, fmpz_t e, const arf_t x) { if (arf_is_special(x)) { fmpz_zero(m); if (arf_is_zero(x)) fmpz_zero(e); else if (arf_is_pos_inf(x)) fmpz_set_si(e, -1); else if (arf_is_neg_inf(x)) fmpz_set_si(e, -2); else if (arf_is_nan(x)) fmpz_set_si(e, -3); else { /* Impossible to happen; all the special values have been treated above. */ flint_abort(); } return; } arf_get_fmpz_2exp(m, e, x); } char * arf_dump_str(const arf_t x) { size_t res_len; char * res; fmpz_t mantissa, exponent; fmpz_init(mantissa); fmpz_init(exponent); arf_get_fmpz_2exp_dump(mantissa, exponent, x); res_len = (fmpz_sgn(mantissa) < 0) + fmpz_sizeinbase(mantissa, 16) + 1 + (fmpz_sgn(exponent) < 0) + fmpz_sizeinbase(exponent, 16); res = (char*)flint_malloc(res_len + 1); fmpz_get_str(res, 16, mantissa); strcat(res, " "); fmpz_get_str(res + strlen(res), 16, exponent); fmpz_clear(mantissa); fmpz_clear(exponent); if(strlen(res) != res_len) flint_abort(); /* assert */ return res; } arb-2.22.1/arf/equal.c000066400000000000000000000025221417376376500144110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_equal(const arf_t x, const arf_t y) { mp_size_t n; if (x == y) return 1; if (ARF_XSIZE(x) != ARF_XSIZE(y)) return 0; if (!fmpz_equal(ARF_EXPREF(x), ARF_EXPREF(y))) return 0; n = ARF_SIZE(x); if (n == 0) return 1; if (n == 1) return ARF_NOPTR_D(x)[0] == ARF_NOPTR_D(y)[0]; if (n == 2) return (ARF_NOPTR_D(x)[0] == ARF_NOPTR_D(y)[0] && ARF_NOPTR_D(x)[1] == ARF_NOPTR_D(y)[1]); return mpn_cmp(ARF_PTR_D(x), ARF_PTR_D(y), n) == 0; } int arf_equal_si(const arf_t x, slong y) { arf_t t; arf_init_set_si(t, y); return arf_equal(x, t); /* no need to free */ } int arf_equal_ui(const arf_t x, ulong y) { arf_t t; arf_init_set_ui(t, y); return arf_equal(x, t); /* no need to free */ } int arf_equal_d(const arf_t x, double y) { arf_t t; arf_init(t); arf_set_d(t, y); return arf_equal(x, t); /* no need to free */ } arb-2.22.1/arf/floor.c000066400000000000000000000020111417376376500144140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_floor(arf_t z, const arf_t x) { if (arf_is_special(x) || arf_is_int(x)) { arf_set(z, x); } else { slong exp = ARF_EXP(x); /* now exp cannot be too large, as we would have caught this in arf_is_int() */ if (COEFF_IS_MPZ(exp) || exp <= 0) { if (ARF_SGNBIT(x)) arf_set_si(z, -1); else arf_zero(z); } else if (exp == 1) { arf_set_si(z, ARF_SGNBIT(x) ? -2 : 1); } else { arf_set_round(z, x, exp, ARF_RND_FLOOR); } } } arb-2.22.1/arf/fma.c000066400000000000000000000040471417376376500140510ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_fma(arf_ptr res, arf_srcptr x, arf_srcptr y, arf_srcptr z, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn, zn, tn, alloc; mp_srcptr xptr, yptr, zptr; mp_ptr tptr, tptr2; fmpz_t texp; slong shift; int tsgnbit, inexact; ARF_MUL_TMP_DECL if (arf_is_special(x) || arf_is_special(y) || arf_is_special(z)) { if (arf_is_zero(z)) { return arf_mul(res, x, y, prec, rnd); } else if (arf_is_finite(x) && arf_is_finite(y)) { return arf_set_round(res, z, prec, rnd); } else { /* todo: speed up */ arf_t t; arf_init(t); arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(res, z, t, prec, rnd); arf_clear(t); return inexact; } } tsgnbit = ARF_SGNBIT(x) ^ ARF_SGNBIT(y); ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); ARF_GET_MPN_READONLY(zptr, zn, z); fmpz_init(texp); _fmpz_add2_fast(texp, ARF_EXPREF(x), ARF_EXPREF(y), 0); shift = _fmpz_sub_small(ARF_EXPREF(z), texp); alloc = tn = xn + yn; ARF_MUL_TMP_ALLOC(tptr2, alloc) tptr = tptr2; ARF_MPN_MUL(tptr, xptr, xn, yptr, yn); tn -= (tptr[0] == 0); tptr += (tptr[0] == 0); if (shift >= 0) inexact = _arf_add_mpn(res, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z), tptr, tn, tsgnbit, shift, prec, rnd); else inexact = _arf_add_mpn(res, tptr, tn, tsgnbit, texp, zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd); ARF_MUL_TMP_FREE(tptr2, alloc) fmpz_clear(texp); return inexact; } arb-2.22.1/arf/fprint.c000066400000000000000000000034761417376376500146150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arf.h" #include "arb.h" char * arf_get_str(const arf_t x, slong d) { if (arf_is_special(x)) { char * s = flint_malloc(5); if (arf_is_zero(x)) strcpy(s, "0"); else if (arf_is_pos_inf(x)) strcpy(s, "+inf"); else if (arf_is_neg_inf(x)) strcpy(s, "-inf"); else strcpy(s, "nan"); return s; } else { arb_t t; *arb_midref(t) = *x; mag_init(arb_radref(t)); /* no need to free */ return arb_get_str(t, FLINT_MAX(d, 1), ARB_STR_NO_RADIUS); } } void arf_fprint(FILE * file, const arf_t x) { if (arf_is_normal(x)) { fmpz_t man, exp; fmpz_init(man); fmpz_init(exp); arf_get_fmpz_2exp(man, exp, x); flint_fprintf(file, "("); fmpz_fprint(file, man); flint_fprintf(file, " * 2^"); fmpz_fprint(file, exp); flint_fprintf(file, ")"); fmpz_clear(man); fmpz_clear(exp); } else { if (arf_is_zero(x)) flint_fprintf(file, "(0)"); else if (arf_is_pos_inf(x)) flint_fprintf(file, "(+inf)"); else if (arf_is_neg_inf(x)) flint_fprintf(file, "(-inf)"); else flint_fprintf(file, "(nan)"); } } void arf_fprintd(FILE * file, const arf_t x, slong d) { char * s = arf_get_str(x, d); fprintf(file, "%s", s); flint_free(s); } arb-2.22.1/arf/frexp.c000066400000000000000000000010711417376376500144240ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_frexp(arf_t man, fmpz_t exp, const arf_t x) { arf_set(man, x); fmpz_zero(exp); if (!arf_is_special(man)) fmpz_swap(exp, ARF_EXPREF(man)); } arb-2.22.1/arf/get_d.c000066400000000000000000000047241417376376500143720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arf.h" /* most double: (2^53-1) * 2^971 */ /* least normal: 2^-1022 */ /* least subnormal: 2^-1074 */ static double huge_double(arf_rnd_t rnd, int negative) { double v; if (rnd == ARF_RND_NEAR || rounds_up(rnd, negative)) v = D_INF; else v = ldexp(9007199254740991.0, 971); return negative ? -v : v; } static double tiny_double(arf_rnd_t rnd, int negative) { double v; if (rnd == ARF_RND_NEAR || !rounds_up(rnd, negative)) v = 0.0; else v = ldexp(1.0, -1074); return negative ? -v : v; } double arf_get_d(const arf_t x, arf_rnd_t rnd) { if (arf_is_special(x)) { if (arf_is_zero(x)) return 0.0; else if (arf_is_pos_inf(x)) return D_INF; else if (arf_is_neg_inf(x)) return -D_INF; else return D_NAN; } else { arf_t t; mp_srcptr tp; mp_size_t tn; double v; /* also catches bignum exponents */ if (ARF_EXP(x) > 1030 || ARF_EXP(x) < -1080) { if (fmpz_sgn(ARF_EXPREF(x)) > 0) return huge_double(rnd, ARF_SGNBIT(x)); else return tiny_double(rnd, ARF_SGNBIT(x)); } /* allow mpfr to take care of corner cases for now */ if (ARF_EXP(x) > 1020 || ARF_EXP(x) <= -1020 || rnd == ARF_RND_NEAR) { mpfr_t xx; ARF_GET_MPN_READONLY(tp, tn, x); xx->_mpfr_d = (mp_ptr) tp; xx->_mpfr_prec = tn * FLINT_BITS; xx->_mpfr_sign = ARF_SGNBIT(x) ? -1 : 1; xx->_mpfr_exp = ARF_EXP(x); return mpfr_get_d(xx, rnd_to_mpfr(rnd)); } arf_init(t); arf_set_round(t, x, 53, rnd); ARF_GET_MPN_READONLY(tp, tn, t); if (tn == 1) v = (double)(tp[0]); else v = (double)(tp[1]) + (double)(tp[0]) * ldexp(1,-32); v = ldexp(v, ARF_EXP(t) - FLINT_BITS); if (ARF_SGNBIT(t)) v = -v; arf_clear(t); return v; } } arb-2.22.1/arf/get_fmpq.c000066400000000000000000000022231417376376500151020ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_get_fmpq(fmpq_t y, const arf_t x) { if (arf_is_zero(x)) { fmpq_zero(y); } else if (arf_is_special(x) || !ARF_IS_LAGOM(x)) { flint_printf("exception: arf_get_fmpq: cannot convert to rational\n"); flint_abort(); } else { fmpz_t man, exp; slong e; fmpz_init(man); fmpz_init(exp); arf_get_fmpz_2exp(man, exp, x); e = *exp; fmpz_set_ui(fmpq_denref(y), UWORD(1)); if (e >= 0) { fmpz_mul_2exp(fmpq_numref(y), man, e); } else { fmpz_set(fmpq_numref(y), man); fmpz_mul_2exp(fmpq_denref(y), fmpq_denref(y), -e); } fmpz_clear(man); fmpz_clear(exp); } } arb-2.22.1/arf/get_fmpr.c000066400000000000000000000014261417376376500151070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_get_fmpr(fmpr_t y, const arf_t x) { if (arf_is_special(x)) { if (arf_is_zero(x)) fmpr_zero(y); else if (arf_is_pos_inf(x)) fmpr_pos_inf(y); else if (arf_is_neg_inf(x)) fmpr_neg_inf(y); else fmpr_nan(y); } else { arf_get_fmpz_2exp(fmpr_manref(y), fmpr_expref(y), x); } } arb-2.22.1/arf/get_fmpz.c000066400000000000000000000127751417376376500151300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd) { slong exp; int negative, inexact, value, roundup; mp_size_t xn, zn; mp_srcptr xp; __mpz_struct * zz; mp_ptr zp; mp_limb_t v, v2, v3; if (arf_is_special(x)) { if (arf_is_zero(x)) { fmpz_zero(z); return 0; } else { flint_printf("arf_get_fmpz: cannot convert infinity or nan to integer\n"); flint_abort(); } } exp = ARF_EXP(x); negative = ARF_SGNBIT(x); if (COEFF_IS_MPZ(exp)) { /* tiny */ if (fmpz_sgn(ARF_EXPREF(x)) < 0) { if (rnd == ARF_RND_NEAR || rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { fmpz_zero(z); } else { fmpz_set_si(z, negative ? -1 : 1); } return 1; } else { flint_printf("arf_get_fmpz: number too large to convert to integer\n"); flint_abort(); } } /* |x| < 1 */ if (exp <= 0) { if (rnd == ARF_RND_NEAR) { if (exp == 0) { /* check for the special case +/- 1/2 */ ARF_GET_MPN_READONLY(xp, xn, x); if (xp[xn - 1] < LIMB_TOP || (xn == 1 && xp[xn - 1] == LIMB_TOP)) value = 0; else value = negative ? -1 : 1; } else { value = 0; } } else if (rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { value = 0; } else { value = negative ? -1 : 1; } _fmpz_demote(z); *z = value; return 1; } ARF_GET_MPN_READONLY(xp, xn, x); /* Fast case: |x| < 2^31 or 2^63 (must save 1 bit for rounding up!) */ if (exp < FLINT_BITS) { v = xp[xn - 1]; v2 = v >> (FLINT_BITS - exp); /* integral part */ v3 = v << exp; /* fractional part (truncated, at least 1 bit) */ inexact = (xn > 1) || (v3 != 0); if (inexact && rnd != ARF_RND_DOWN) { if (rnd == ARF_RND_NEAR) { /* round up of fractional part is > 1/2, or if equal to 1/2 and the integral part is odd */ v2 += (v3 > LIMB_TOP) || (v3 == LIMB_TOP && (xn > 1 || (v2 & 1))); } else { v2 += (rnd == ARF_RND_UP) || (negative ^ (rnd == ARF_RND_CEIL)); } } if (negative) fmpz_neg_ui(z, v2); else fmpz_set_ui(z, v2); return inexact; } /* |x| >= 1 */ /* Allocate space for result + 1 extra bit. We need one extra bit temporarily to check rounding to nearest. We also need one extra bit to round up. */ zn = (exp + (rnd != ARF_RND_DOWN) + FLINT_BITS - 1) / FLINT_BITS; zz = _fmpz_promote(z); if (zz->_mp_alloc < zn) mpz_realloc2(zz, zn * FLINT_BITS); zp = zz->_mp_d; if (rnd == ARF_RND_DOWN) { /* zn is the exact size */ inexact = _arf_get_integer_mpn(zp, xp, xn, exp); } else { zp[zn - 1] = 0; inexact = _arf_get_integer_mpn(zp, xp, xn, exp + (rnd == ARF_RND_NEAR)); if (rnd == ARF_RND_NEAR) { v = zp[0]; /* round up if fractional part is >= 1/2 and (there are more discarded bits, or the truncated value would be odd) */ roundup = (v & 1) & (inexact | (v >> 1)); inexact |= (v & 1); mpn_rshift(zp, zp, zn, 1); mpn_add_1(zp, zp, zn, roundup); } else if (inexact && ((rnd == ARF_RND_UP) || (negative ^ (rnd == ARF_RND_CEIL)))) { mpn_add_1(zp, zp, zn, 1); } zn -= (zp[zn - 1] == 0); } zz->_mp_size = negative ? -zn : zn; _fmpz_demote_val(z); return inexact; } int arf_get_fmpz_fixed_fmpz(fmpz_t y, const arf_t x, const fmpz_t e) { if (arf_is_special(x)) { return arf_get_fmpz(y, x, ARF_RND_DOWN); } else { int inexact; fmpz_t exp; arf_t tmp; fmpz_init(exp); fmpz_sub(exp, ARF_EXPREF(x), e); arf_init_set_shallow(tmp, x); ARF_EXP(tmp) = *exp; inexact = arf_get_fmpz(y, tmp, ARF_RND_DOWN); fmpz_clear(exp); return inexact; } } int arf_get_fmpz_fixed_si(fmpz_t y, const arf_t x, slong e) { if (arf_is_special(x)) { return arf_get_fmpz(y, x, ARF_RND_DOWN); } else { int inexact; fmpz_t exp; arf_t tmp; fmpz_init(exp); fmpz_sub_si(exp, ARF_EXPREF(x), e); arf_init_set_shallow(tmp, x); ARF_EXP(tmp) = *exp; inexact = arf_get_fmpz(y, tmp, ARF_RND_DOWN); fmpz_clear(exp); return inexact; } } arb-2.22.1/arf/get_fmpz_2exp.c000066400000000000000000000025631417376376500160600ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_get_fmpz_2exp(fmpz_t man, fmpz_t exp, const arf_t x) { if (arf_is_special(x)) { fmpz_zero(man); fmpz_zero(exp); } else { mp_srcptr xptr; mp_size_t xn; int shift; ARF_GET_MPN_READONLY(xptr, xn, x); count_trailing_zeros(shift, xptr[0]); fmpz_sub_ui(exp, ARF_EXPREF(x), xn * FLINT_BITS - shift); if (xn == 1) { if (ARF_SGNBIT(x)) fmpz_neg_ui(man, xptr[0] >> shift); else fmpz_set_ui(man, xptr[0] >> shift); } else { __mpz_struct * z = _fmpz_promote(man); if (z->_mp_alloc < xn) mpz_realloc(z, xn); if (shift == 0) flint_mpn_copyi(z->_mp_d, xptr, xn); else mpn_rshift(z->_mp_d, xptr, xn, shift); /* top limb cannot be zero */ z->_mp_size = ARF_SGNBIT(x) ? -xn : xn; } } } arb-2.22.1/arf/get_integer_mpn.c000066400000000000000000000030711417376376500164500ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int _arf_get_integer_mpn(mp_ptr y, mp_srcptr x, mp_size_t xn, slong exp) { slong bot_exp = exp - xn * FLINT_BITS; if (bot_exp >= 0) { mp_size_t bot_limbs; flint_bitcnt_t bot_bits; bot_limbs = bot_exp / FLINT_BITS; bot_bits = bot_exp % FLINT_BITS; flint_mpn_zero(y, bot_limbs); if (bot_bits == 0) flint_mpn_copyi(y + bot_limbs, x, xn); else y[bot_limbs + xn] = mpn_lshift(y + bot_limbs, x, xn, bot_bits); /* exact */ return 0; } else if (exp <= 0) { /* inexact */ return 1; } else { mp_size_t top_limbs; flint_bitcnt_t top_bits; mp_limb_t cy; top_limbs = exp / FLINT_BITS; top_bits = exp % FLINT_BITS; if (top_bits == 0) { flint_mpn_copyi(y, x + xn - top_limbs, top_limbs); /* inexact */ return 1; } else { /* can be inexact */ cy = mpn_rshift(y, x + xn - top_limbs - 1, top_limbs + 1, FLINT_BITS - top_bits); return (cy != 0) || (top_limbs + 1 != xn); } } } arb-2.22.1/arf/get_mag.c000066400000000000000000000025671417376376500147160ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_get_mag(mag_t y, const arf_t x) { if (arf_is_zero(x)) { mag_zero(y); } else if (arf_is_special(x)) { mag_inf(y); } else { mp_limb_t t, u; ARF_GET_TOP_LIMB(t, x); t = (t >> (FLINT_BITS - MAG_BITS)) + LIMB_ONE; /* may have rounded up to next power of two */ u = t >> MAG_BITS; /* todo: avoid the addition? check agreement with mag_fast_init_set_arf */ t = (t >> u) + (u & t); _fmpz_add_fast(MAG_EXPREF(y), ARF_EXPREF(x), u); MAG_MAN(y) = t; } } void arf_get_mag_lower(mag_t y, const arf_t x) { if (arf_is_zero(x)) { mag_zero(y); } else if (arf_is_special(x)) { if (arf_is_nan(x)) mag_zero(y); else mag_inf(y); } else { mp_limb_t t; ARF_GET_TOP_LIMB(t, x); MAG_MAN(y) = t >> (FLINT_BITS - MAG_BITS); _fmpz_set_fast(MAG_EXPREF(y), ARF_EXPREF(x)); } } arb-2.22.1/arf/get_mpfr.c000066400000000000000000000046541417376376500151150ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_get_mpfr(mpfr_t x, const arf_t y, mpfr_rnd_t rnd) { int r; if (arf_is_special(y)) { if (arf_is_zero(y)) mpfr_set_zero(x, 0); else if (arf_is_pos_inf(y)) mpfr_set_inf(x, 1); else if (arf_is_neg_inf(y)) mpfr_set_inf(x, -1); else mpfr_set_nan(x); r = 0; } else if (COEFF_IS_MPZ(*ARF_EXPREF(y))) { /* Incidentally, COEFF_MIN and COEFF_MAX are exactly the same as the minimum and maximum allowed MPFR exponents. We assert this to make sure the following code is valid. Unfortunately, MPFR provides no convenient function to assign a big exponent with automatic underflow/overflow. */ if (COEFF_MIN > mpfr_get_emin_min() || COEFF_MAX < mpfr_get_emax_max()) { flint_printf("unsupported MPFR exponent range: %wd, %wd, %wd, %wd\n", COEFF_MIN, mpfr_get_emin_min(), COEFF_MAX, mpfr_get_emax_max()); flint_abort(); } if (fmpz_sgn(ARF_EXPREF(y)) > 0) { if (arf_sgn(y) > 0) { mpfr_set_inf(x, 1); mpfr_nextbelow(x); } else { mpfr_set_inf(x, -1); mpfr_nextabove(x); } r = mpfr_mul_2si(x, x, 1, rnd); } else { if (arf_sgn(y) > 0) { mpfr_set_zero(x, 1); mpfr_nextabove(x); } else { mpfr_set_zero(x, -1); mpfr_nextbelow(x); } r = mpfr_mul_2si(x, x, -1, rnd); } } else { __mpfr_struct t; mp_size_t n; mp_srcptr d; ARF_GET_MPN_READONLY(d, n, y); t._mpfr_d = (mp_ptr) d; t._mpfr_exp = ARF_EXP(y); t._mpfr_prec = n * FLINT_BITS; t._mpfr_sign = ARF_SGNBIT(y) ? -1 : 1; r = mpfr_set(x, &t, rnd); } return r; } arb-2.22.1/arf/get_si.c000066400000000000000000000013171417376376500145550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" slong arf_get_si(const arf_t x, arf_rnd_t rnd) { fmpz_t t; slong v; fmpz_init(t); arf_get_fmpz(t, x, rnd); if (!fmpz_fits_si(t)) { flint_printf("arf_get_si: result does not fit in a signed slong\n"); flint_abort(); } v = fmpz_get_si(t); fmpz_clear(t); return v; } arb-2.22.1/arf/inlines.c000066400000000000000000000006441417376376500147460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define ARF_INLINES_C #include "arf.h" arb-2.22.1/arf/is_int.c000066400000000000000000000013761417376376500145750ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_is_int(const arf_t x) { mp_size_t xn; mp_srcptr xp; slong exp, c; exp = ARF_EXP(x); if (ARF_IS_SPECIAL(x)) return exp == ARF_EXP_ZERO; if (COEFF_IS_MPZ(exp)) return mpz_sgn(COEFF_TO_PTR(exp)) > 0; ARF_GET_MPN_READONLY(xp, xn, x); count_trailing_zeros(c, xp[0]); return exp - xn * FLINT_BITS + c >= 0; } arb-2.22.1/arf/is_int_2exp_si.c000066400000000000000000000012541417376376500162210ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_is_int_2exp_si(const arf_t x, slong e) { if (arf_is_special(x)) return arf_is_zero(x); else { fmpz_t t; int r; fmpz_init(t); arf_bot(t, x); r = fmpz_cmp_si(t, e) >= 0; fmpz_clear(t); return r; } } arb-2.22.1/arf/load.c000066400000000000000000000045441417376376500142270ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arf.h" static void arf_set_fmpz_2exp_dump(arf_t x, const fmpz_t m, const fmpz_t e) { if (fmpz_is_zero(m)) { if (fmpz_get_si(e) == 0) arf_zero(x); else if (fmpz_get_si(e) == -1) arf_pos_inf(x); else if (fmpz_get_si(e) == -2) arf_neg_inf(x); else if (fmpz_get_si(e) == -3) arf_nan(x); else { /* Impossible to happen; all the special values have been treated above. */ flint_abort(); } return; } arf_set_fmpz_2exp(x, m, e); } int arf_load_str(arf_t x, const char* data) { fmpz_t mantissa, exponent; char * e_str; char * m_str; int err = 0; fmpz_init(mantissa); fmpz_init(exponent); e_str = strchr(data, ' '); if (e_str == NULL) return 1; m_str = (char*)flint_malloc(e_str - data + 1); strncpy(m_str, data, e_str - data); m_str[e_str - data] = '\0'; e_str++; err = fmpz_set_str(mantissa, m_str, 16); flint_free(m_str); if (err) { fmpz_clear(exponent); fmpz_clear(mantissa); return err; } err = fmpz_set_str(exponent, e_str, 16); if (err) { fmpz_clear(exponent); fmpz_clear(mantissa); return err; } arf_set_fmpz_2exp_dump(x, mantissa, exponent); fmpz_clear(exponent); fmpz_clear(mantissa); return err; } int arf_load_file(arf_t x, FILE* stream) { fmpz_t mantissa, exponent; __mpz_struct *mpz_mantissa, *mpz_exponent; int err; fmpz_init(mantissa); fmpz_init(exponent); mpz_mantissa = _fmpz_promote(mantissa); mpz_exponent = _fmpz_promote(exponent); err = 0; if (mpz_inp_str(mpz_mantissa, stream, 16) == 0) err = 1; if (!err && mpz_inp_str(mpz_exponent, stream, 16) == 0) err = 1; _fmpz_demote_val(mantissa); _fmpz_demote_val(exponent); if (!err) arf_set_fmpz_2exp_dump(x, mantissa, exponent); fmpz_clear(mantissa); fmpz_clear(exponent); return err; } arb-2.22.1/arf/memory_manager.c000066400000000000000000000042521417376376500163060ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #define ARF_USE_CACHE 0 #define ARF_MAX_CACHE_LIMBS 64 FLINT_TLS_PREFIX mp_ptr * arf_free_arr = NULL; FLINT_TLS_PREFIX ulong arf_free_num = 0; FLINT_TLS_PREFIX ulong arf_free_alloc = 0; FLINT_TLS_PREFIX int arf_have_registered_cleanup = 0; void _arf_cleanup(void) { slong i; for (i = 0; i < arf_free_num; i++) flint_free(arf_free_arr[i]); flint_free(arf_free_arr); arf_free_arr = NULL; arf_free_num = 0; arf_free_alloc = 0; } void _arf_promote(arf_t x, mp_size_t n) { if (ARF_USE_CACHE && n <= ARF_MAX_CACHE_LIMBS && arf_free_num != 0) { mp_ptr ptr; mp_size_t alloc; ptr = arf_free_arr[--arf_free_num]; alloc = ptr[0]; if (alloc >= n) { ARF_PTR_ALLOC(x) = ptr[0]; ARF_PTR_D(x) = ptr; } else { ptr = flint_realloc(ptr, n * sizeof(mp_limb_t)); ARF_PTR_ALLOC(x) = n; ARF_PTR_D(x) = ptr; } } else { ARF_PTR_ALLOC(x) = n; ARF_PTR_D(x) = flint_malloc(n * sizeof(mp_limb_t)); } } void _arf_demote(arf_t x) { mp_ptr ptr; mp_size_t alloc; alloc = ARF_PTR_ALLOC(x); ptr = ARF_PTR_D(x); if (ARF_USE_CACHE && alloc <= ARF_MAX_CACHE_LIMBS) { if (arf_free_num == arf_free_alloc) { if (!arf_have_registered_cleanup) { flint_register_cleanup_function(_arf_cleanup); arf_have_registered_cleanup = 1; } arf_free_alloc = FLINT_MAX(64, arf_free_alloc * 2); arf_free_arr = flint_realloc(arf_free_arr, arf_free_alloc * sizeof(mp_ptr)); } ptr[0] = alloc; arf_free_arr[arf_free_num++] = ptr; } else { flint_free(ptr); } } arb-2.22.1/arf/mul_rnd_any.c000066400000000000000000000033731417376376500156160ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_mul_rnd_any(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; slong fix; int sgnbit, inexact; xn = ARF_XSIZE(x); yn = ARF_XSIZE(y); sgnbit = (xn ^ yn) & 1; xn >>= 1; yn >>= 1; if (yn > xn) { arf_srcptr __t; mp_size_t __u; __t = x; x = y; y = __t; __u = xn; xn = yn; yn = __u; } /* Either operand is a special value. */ if (yn == 0) { arf_mul_special(z, x, y); return 0; } else { mp_size_t zn, alloc; mp_srcptr xptr, yptr; mp_ptr tmp; ARF_MUL_TMP_DECL ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); alloc = zn = xn + yn; ARF_MUL_TMP_ALLOC(tmp, alloc) if (yn == 1) { tmp[zn - 1] = mpn_mul_1(tmp, xptr, xn, yptr[0]); } else if (xn == yn) { if (xptr == yptr) mpn_sqr(tmp, xptr, xn); else mpn_mul_n(tmp, xptr, yptr, yn); } else { mpn_mul(tmp, xptr, xn, yptr, yn); } inexact = _arf_set_round_mpn(z, &fix, tmp, zn, sgnbit, prec, rnd); _fmpz_add2_fast(ARF_EXPREF(z), ARF_EXPREF(x), ARF_EXPREF(y), fix); ARF_MUL_TMP_FREE(tmp, alloc) return inexact; } } arb-2.22.1/arf/mul_rnd_down.c000066400000000000000000000155501417376376500157760ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_mul_rnd_down(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec) { mp_size_t xn, yn, zn; mp_limb_t hi, lo; slong expfix; int sgnbit, ret, fix; mp_ptr zptr; xn = ARF_XSIZE(x); yn = ARF_XSIZE(y); sgnbit = (xn ^ yn) & 1; xn >>= 1; yn >>= 1; if (yn > xn) { arf_srcptr __t; mp_size_t __u; __t = x; x = y; y = __t; __u = xn; xn = yn; yn = __u; } /* Either operand is a special value. */ if (yn == 0) { arf_mul_special(z, x, y); return 0; } /* xn == yn == 1 */ if (xn == 1) { lo = ARF_NOPTR_D(x)[0]; hi = ARF_NOPTR_D(y)[0]; umul_ppmm(hi, lo, hi, lo); /* Shift so that the top bit is set (branch free version). */ fix = !(hi >> (FLINT_BITS - 1)); hi = (hi << fix) | ((lo >> (FLINT_BITS - 1)) & fix); lo = (lo << fix); ARF_DEMOTE(z); if (lo == 0) { zn = 1; if (prec >= FLINT_BITS) { lo = hi; ret = 0; } else { lo = MASK_LIMB(hi, FLINT_BITS - prec); ret = (lo != hi); } } else { zn = 2; if (prec <= FLINT_BITS) /* Must be inexact. */ { lo = MASK_LIMB(hi, FLINT_BITS - prec); zn = ret = 1; } else if (prec >= 2 * FLINT_BITS) /* Must be exact. */ { ret = 0; } else /* prec < FLINT_BITS < 2 * FLINT_BITS */ { ret = MASK_LIMB(lo, 2 * FLINT_BITS - prec) != lo; lo = MASK_LIMB(lo, 2 * FLINT_BITS - prec); if (lo == 0) { zn = 1; lo = hi; } } } _fmpz_add2_fast(ARF_EXPREF(z), ARF_EXPREF(x), ARF_EXPREF(y), -fix); ARF_XSIZE(z) = ARF_MAKE_XSIZE(zn, sgnbit); zptr = ARF_NOPTR_D(z); zptr[0] = lo; zptr[1] = hi; return ret; } else if (xn == 2) { mp_limb_t zz[4]; mp_limb_t x1, x0, y1, y0; x0 = ARF_NOPTR_D(x)[0]; x1 = ARF_NOPTR_D(x)[1]; if (yn == 2) { y0 = ARF_NOPTR_D(y)[0]; y1 = ARF_NOPTR_D(y)[1]; nn_mul_2x2(zz[3], zz[2], zz[1], zz[0], x1, x0, y1, y0); /* Likely case, must be inexact */ if (prec <= 2 * FLINT_BITS) { ARF_DEMOTE(z); fix = !(zz[3] >> (FLINT_BITS - 1)); zz[3] = (zz[3] << fix) | ((zz[2] >> (FLINT_BITS - 1)) & fix); zz[2] = (zz[2] << fix) | ((zz[1] >> (FLINT_BITS - 1)) & fix); _fmpz_add2_fast(ARF_EXPREF(z), ARF_EXPREF(x), ARF_EXPREF(y), -fix); /* Rounding */ if (prec != 2 * FLINT_BITS) { if (prec > FLINT_BITS) { zz[2] &= (LIMB_ONES << (2 * FLINT_BITS - prec)); } else if (prec == FLINT_BITS) { zz[2] = 0; } else { zz[3] &= (LIMB_ONES << (FLINT_BITS - prec)); zz[2] = 0; } } if (zz[2] == 0) { ARF_XSIZE(z) = ARF_MAKE_XSIZE(1, sgnbit); ARF_NOPTR_D(z)[0] = zz[3]; } else { ARF_XSIZE(z) = ARF_MAKE_XSIZE(2, sgnbit); ARF_NOPTR_D(z)[0] = zz[2]; ARF_NOPTR_D(z)[1] = zz[3]; } return 1; } } else { y0 = ARF_NOPTR_D(y)[0]; nn_mul_2x1(zz[2], zz[1], zz[0], x1, x0, y0); } zn = xn + yn; ret = _arf_set_round_mpn(z, &expfix, zz, zn, sgnbit, prec, ARF_RND_DOWN); _fmpz_add2_fast(ARF_EXPREF(z), ARF_EXPREF(x), ARF_EXPREF(y), expfix); return ret; } else if (yn > MUL_MPFR_MIN_LIMBS && prec != ARF_PREC_EXACT && xn + yn > 1.25 * prec / FLINT_BITS && xn < MUL_MPFR_MAX_LIMBS) /* FIXME: proper cutoffs */ { return arf_mul_via_mpfr(z, x, y, prec, ARF_RND_DOWN); } else { mp_size_t zn, alloc; mp_srcptr xptr, yptr; mp_ptr tmp; ARF_MUL_TMP_DECL ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); alloc = zn = xn + yn; ARF_MUL_TMP_ALLOC(tmp, alloc) if (xn == yn) { if (xptr == yptr) mpn_sqr(tmp, xptr, xn); else mpn_mul_n(tmp, xptr, yptr, yn); } else if (yn == 1) { tmp[zn - 1] = mpn_mul_1(tmp, xptr, xn, yptr[0]); } else { mpn_mul(tmp, xptr, xn, yptr, yn); } ret = _arf_set_round_mpn(z, &expfix, tmp, zn, sgnbit, prec, ARF_RND_DOWN); _fmpz_add2_fast(ARF_EXPREF(z), ARF_EXPREF(x), ARF_EXPREF(y), expfix); ARF_MUL_TMP_FREE(tmp, alloc) return ret; } } int arf_mul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; slong fix, shift; int sgnbit, inexact; yn = FLINT_ABS(y->_mp_size); xn = ARF_XSIZE(x); xn >>= 1; sgnbit = ARF_SGNBIT(x) ^ (y->_mp_size < 0); /* Either operand is a special value. */ if (xn == 0 || yn == 0) { if (arf_is_finite(x)) { arf_zero(z); } else { arf_t t; arf_init_set_si(t, mpz_sgn(y)); arf_mul(z, x, t, prec, rnd); arf_clear(t); } return 0; } else { mp_size_t zn, alloc; mp_srcptr xptr, yptr; mp_ptr tmp; ARF_MUL_TMP_DECL ARF_GET_MPN_READONLY(xptr, xn, x); yptr = y->_mp_d; alloc = zn = xn + yn; ARF_MUL_TMP_ALLOC(tmp, alloc) ARF_MPN_MUL(tmp, xptr, xn, yptr, yn); shift = yn * FLINT_BITS - (tmp[zn - 1] == 0) * FLINT_BITS; zn -= (tmp[zn - 1] == 0); inexact = _arf_set_round_mpn(z, &fix, tmp, zn, sgnbit, prec, rnd); _fmpz_add_fast(ARF_EXPREF(z), ARF_EXPREF(x), fix + shift); ARF_MUL_TMP_FREE(tmp, alloc) return inexact; } } arb-2.22.1/arf/mul_special.c000066400000000000000000000015651417376376500156050ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_mul_special(arf_t z, const arf_t x, const arf_t y) { if (arf_is_zero(x)) { if (arf_is_finite(y)) arf_zero(z); else arf_nan(z); } else if (arf_is_zero(y)) { if (arf_is_finite(x)) arf_zero(z); else arf_nan(z); } else if (arf_is_nan(x) || arf_is_nan(y)) arf_nan(z); else if (arf_sgn(x) == arf_sgn(y)) arf_pos_inf(z); else arf_neg_inf(z); } arb-2.22.1/arf/mul_tmp_cleanup.c000066400000000000000000000011231417376376500164620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" TLS_PREFIX mp_ptr __arf_mul_tmp = NULL; TLS_PREFIX slong __arf_mul_alloc = 0; void _arf_mul_tmp_cleanup(void) { flint_free(__arf_mul_tmp); __arf_mul_tmp = NULL; __arf_mul_alloc = 0; } arb-2.22.1/arf/mul_via_mpfr.c000066400000000000000000000034771417376376500157740ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_mul_via_mpfr(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn, zn, val; mp_srcptr xptr, yptr; mp_ptr tmp, zptr; mpfr_t xf, yf, zf; int ret; ARF_MUL_TMP_DECL if (arf_is_special(x) || arf_is_special(y)) { arf_mul_special(z, x, y); return 0; } ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); prec = FLINT_MIN((xn + yn) * FLINT_BITS, prec); zn = (prec + FLINT_BITS - 1) / FLINT_BITS; ARF_MUL_TMP_ALLOC(tmp, zn) zf->_mpfr_d = tmp; zf->_mpfr_prec = prec; zf->_mpfr_sign = 1; zf->_mpfr_exp = 0; xf->_mpfr_d = (mp_ptr) xptr; xf->_mpfr_prec = xn * FLINT_BITS; xf->_mpfr_sign = ARF_SGNBIT(x) ? -1 : 1; xf->_mpfr_exp = 0; if (x == y) { ret = mpfr_sqr(zf, xf, arf_rnd_to_mpfr(rnd)); } else { yf->_mpfr_d = (mp_ptr) yptr; yf->_mpfr_prec = yn * FLINT_BITS; yf->_mpfr_sign = ARF_SGNBIT(y) ? -1 : 1; yf->_mpfr_exp = 0; ret = mpfr_mul(zf, xf, yf, arf_rnd_to_mpfr(rnd)); } ret = (ret != 0); _fmpz_add2_fast(ARF_EXPREF(z), ARF_EXPREF(x), ARF_EXPREF(y), zf->_mpfr_exp); val = 0; while (tmp[val] == 0) val++; ARF_GET_MPN_WRITE(zptr, zn - val, z); flint_mpn_copyi(zptr, tmp + val, zn - val); ARF_XSIZE(z) |= (zf->_mpfr_sign < 0); ARF_MUL_TMP_FREE(tmp, zn) return ret; } arb-2.22.1/arf/neg_round.c000066400000000000000000000020321417376376500152560ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_neg_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd) { if (arf_is_special(x)) { arf_neg(y, x); return 0; } else { int inexact; slong fix; mp_size_t xn; mp_srcptr xptr; if (y == x) { ARF_NEG(y); return arf_set_round(y, y, prec, rnd); } else { ARF_GET_MPN_READONLY(xptr, xn, x); inexact = _arf_set_round_mpn(y, &fix, xptr, xn, !ARF_SGNBIT(x), prec, rnd); _fmpz_add_fast(ARF_EXPREF(y), ARF_EXPREF(x), fix); return inexact; } } } arb-2.22.1/arf/randtest.c000066400000000000000000000025501417376376500151270ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_randtest(arf_t x, flint_rand_t state, slong bits, slong mag_bits) { fmpz_t t; fmpz_init(t); fmpz_randtest(t, state, bits); arf_set_fmpz(x, t); if (!arf_is_zero(x)) fmpz_randtest(ARF_EXPREF(x), state, mag_bits); fmpz_clear(t); } void arf_randtest_not_zero(arf_t x, flint_rand_t state, slong bits, slong mag_bits) { fmpz_t t; fmpz_init(t); fmpz_randtest_not_zero(t, state, bits); arf_set_fmpz(x, t); fmpz_randtest(ARF_EXPREF(x), state, mag_bits); fmpz_clear(t); } void arf_randtest_special(arf_t x, flint_rand_t state, slong bits, slong mag_bits) { switch (n_randint(state, 32)) { case 0: arf_zero(x); break; case 1: arf_pos_inf(x); break; case 2: arf_neg_inf(x); break; case 3: arf_nan(x); break; default: arf_randtest_not_zero(x, state, bits, mag_bits); } } arb-2.22.1/arf/root.c000066400000000000000000000040251417376376500142650ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_root(arf_ptr z, arf_srcptr x, ulong k, slong prec, arf_rnd_t rnd) { mp_size_t xn, zn, val; mp_srcptr xptr; mp_ptr tmp, zptr; mpfr_t xf, zf; fmpz_t q, r; int inexact; if (k == 0) { arf_nan(z); return 0; } if (k == 1) return arf_set_round(z, x, prec, rnd); if (k == 2) return arf_sqrt(z, x, prec, rnd); if (arf_is_special(x)) { if (arf_is_neg_inf(x)) arf_nan(z); else arf_set(z, x); return 0; } if (ARF_SGNBIT(x)) { arf_nan(z); return 0; } fmpz_init(q); fmpz_init(r); /* x = m * 2^e where e = qk + r */ /* x^(1/k) = (m * 2^(qk+r))^(1/k) */ /* x^(1/k) = (m * 2^r)^(1/k) * 2^q */ fmpz_set_ui(r, k); fmpz_fdiv_qr(q, r, ARF_EXPREF(x), r); ARF_GET_MPN_READONLY(xptr, xn, x); zn = (prec + FLINT_BITS - 1) / FLINT_BITS; zf->_mpfr_d = tmp = flint_malloc(zn * sizeof(mp_limb_t)); zf->_mpfr_prec = prec; zf->_mpfr_sign = 1; zf->_mpfr_exp = 0; xf->_mpfr_d = (mp_ptr) xptr; xf->_mpfr_prec = xn * FLINT_BITS; xf->_mpfr_sign = 1; xf->_mpfr_exp = fmpz_get_ui(r); #if MPFR_VERSION_MAJOR >= 4 inexact = mpfr_rootn_ui(zf, xf, k, arf_rnd_to_mpfr(rnd)); #else inexact = mpfr_root(zf, xf, k, arf_rnd_to_mpfr(rnd)); #endif inexact = (inexact != 0); val = 0; while (tmp[val] == 0) val++; ARF_GET_MPN_WRITE(zptr, zn - val, z); flint_mpn_copyi(zptr, tmp + val, zn - val); fmpz_add_si(ARF_EXPREF(z), q, zf->_mpfr_exp); flint_free(tmp); fmpz_clear(q); fmpz_clear(r); return inexact; } arb-2.22.1/arf/rsqrt.c000066400000000000000000000037231417376376500144610ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_rsqrt(arf_ptr z, arf_srcptr x, slong prec, arf_rnd_t rnd) { mp_size_t xn, zn, val; mp_srcptr xptr; mp_ptr tmp, zptr; mpfr_t xf, zf; int inexact, odd_exp; ARF_MUL_TMP_DECL if (arf_is_special(x)) { if (arf_is_zero(x)) arf_pos_inf(z); else if (arf_is_pos_inf(x)) arf_zero(z); else arf_nan(z); return 0; } if (ARF_SGNBIT(x)) { arf_nan(z); return 0; } if (ARF_IS_POW2(x) && fmpz_is_odd(ARF_EXPREF(x))) { arf_set(z, x); fmpz_neg(ARF_EXPREF(z), ARF_EXPREF(z)); fmpz_cdiv_q_2exp(ARF_EXPREF(z), ARF_EXPREF(z), 1); fmpz_add_ui(ARF_EXPREF(z), ARF_EXPREF(z), 1); return 0; } ARF_GET_MPN_READONLY(xptr, xn, x); odd_exp = fmpz_is_odd(ARF_EXPREF(x)) ? 1 : 0; zn = (prec + FLINT_BITS - 1) / FLINT_BITS; ARF_MUL_TMP_ALLOC(tmp, zn) zf->_mpfr_d = tmp; zf->_mpfr_prec = prec; zf->_mpfr_sign = 1; zf->_mpfr_exp = 0; xf->_mpfr_d = (mp_ptr) xptr; xf->_mpfr_prec = xn * FLINT_BITS; xf->_mpfr_sign = 1; xf->_mpfr_exp = odd_exp; inexact = mpfr_rec_sqrt(zf, xf, arf_rnd_to_mpfr(rnd)); inexact = (inexact != 0); val = 0; while (tmp[val] == 0) val++; ARF_GET_MPN_WRITE(zptr, zn - val, z); flint_mpn_copyi(zptr, tmp + val, zn - val); fmpz_fdiv_q_2exp(ARF_EXPREF(z), ARF_EXPREF(x), 1); fmpz_neg(ARF_EXPREF(z), ARF_EXPREF(z)); fmpz_add_si(ARF_EXPREF(z), ARF_EXPREF(z), zf->_mpfr_exp); ARF_MUL_TMP_FREE(tmp, zn) return inexact; } arb-2.22.1/arf/set_d.c000066400000000000000000000031631417376376500144020ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arf.h" void arf_set_d(arf_t x, double v) { #if FLINT_BITS == 64 mp_limb_t h, sign, exp, frac; slong real_exp, real_man; union { double uf; mp_limb_t ul; } u; u.uf = v; h = u.ul; sign = h >> 63; exp = (h << 1) >> 53; frac = (h << 12) >> 12; if (exp == 0 && frac == 0) { arf_zero(x); return; } else if (exp == 0x7ff) { if (frac == 0) { if (sign) arf_neg_inf(x); else arf_pos_inf(x); } else { arf_nan(x); } return; } /* handle subnormals */ if (exp == 0 && frac != 0) { int exp2; v = frexp(v, &exp2); u.uf = v; h = u.ul; sign = h >> 63; exp = (h << 1) >> 53; frac = (h << 12) >> 12; exp += exp2; } real_exp = exp - 1023 - 52; frac |= (UWORD(1) << 52); real_man = sign ? (-frac) : frac; arf_set_si_2exp_si(x, real_man, real_exp); #else mpfr_t t; mp_limb_t tmp[2]; t->_mpfr_prec = 53; t->_mpfr_sign = 1; t->_mpfr_exp = 0; t->_mpfr_d = tmp; mpfr_set_d(t, v, MPFR_RNDD); arf_set_mpfr(x, t); #endif } arb-2.22.1/arf/set_fmpr.c000066400000000000000000000015101417376376500151150ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_set_fmpr(arf_t y, const fmpr_t x) { if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) arf_zero(y); else if (fmpr_is_pos_inf(x)) arf_pos_inf(y); else if (fmpr_is_neg_inf(x)) arf_neg_inf(y); else arf_nan(y); } else { arf_set_fmpz(y, fmpr_manref(x)); fmpz_add_inline(ARF_EXPREF(y), ARF_EXPREF(y), fmpr_expref(x)); } } arb-2.22.1/arf/set_mpfr.c000066400000000000000000000016441417376376500151250ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_set_mpfr(arf_t x, const mpfr_t y) { if (!mpfr_regular_p(y)) { if (mpfr_zero_p(y)) arf_zero(x); else if (mpfr_inf_p(y) && mpfr_sgn(y) > 0) arf_pos_inf(x); else if (mpfr_inf_p(y) && mpfr_sgn(y) < 0) arf_neg_inf(x); else arf_nan(x); } else { mp_size_t n = (y->_mpfr_prec + FLINT_BITS - 1) / FLINT_BITS; arf_set_mpn(x, y->_mpfr_d, n, y->_mpfr_sign < 0); fmpz_set_si(ARF_EXPREF(x), y->_mpfr_exp); } } arb-2.22.1/arf/set_mpn.c000066400000000000000000000022411417376376500147450ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_set_mpn(arf_t y, mp_srcptr x, mp_size_t xn, int sgnbit) { unsigned int leading; mp_size_t yn, xn1; mp_ptr yptr; mp_limb_t bot; xn1 = xn; while (x[0] == 0) { x++; xn--; } count_leading_zeros(leading, x[xn - 1]); bot = x[0]; /* This works when leading == 0, since x[0] != 0. */ yn = xn - ((bot << leading) == 0); ARF_GET_MPN_WRITE(yptr, yn, y); ARF_XSIZE(y) |= sgnbit; if (leading == 0) { flint_mpn_copyi(yptr, x, xn); } else if (xn == yn) { mpn_lshift(yptr, x, yn, leading); } else { mpn_lshift(yptr, x + 1, yn, leading); yptr[0] |= (bot >> (FLINT_BITS - leading)); } fmpz_set_ui(ARF_EXPREF(y), xn1 * FLINT_BITS - leading); } arb-2.22.1/arf/set_mpn_fixed.c000066400000000000000000000016721417376376500161330ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int _arf_set_mpn_fixed(arf_t z, mp_srcptr xp, mp_size_t xn, mp_size_t fixn, int negative, slong prec, arf_rnd_t rnd) { slong exp, exp_shift; int inexact; exp = (slong)(xn - fixn) * FLINT_BITS; while (xn > 0 && xp[xn-1] == 0) { xn--; exp -= FLINT_BITS; } if (xn == 0) { arf_zero(z); return 0; } else { inexact = _arf_set_round_mpn(z, &exp_shift, xp, xn, negative, prec, rnd); fmpz_set_si(ARF_EXPREF(z), exp + exp_shift); return inexact; } } arb-2.22.1/arf/set_round.c000066400000000000000000000032601417376376500153040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_set_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd) { if (arf_is_special(x)) { arf_set(y, x); return 0; } else { int inexact; slong fix; mp_size_t xn; mp_srcptr xptr; if (y == x) { mp_ptr xtmp; TMP_INIT; ARF_GET_MPN_READONLY(xptr, xn, x); /* exact */ if (xn * FLINT_BITS <= prec) return 0; if ((xn - 1) * FLINT_BITS < prec) { /* exact */ if ((xptr[0] << (prec - (xn-1) * FLINT_BITS)) == 0) return 0; } /* inexact */ TMP_START; xtmp = TMP_ALLOC(xn * sizeof(mp_limb_t)); flint_mpn_copyi(xtmp, xptr, xn); inexact = _arf_set_round_mpn(y, &fix, xtmp, xn, ARF_SGNBIT(x), prec, rnd); _fmpz_add_fast(ARF_EXPREF(y), ARF_EXPREF(x), fix); TMP_END; return inexact; } else { ARF_GET_MPN_READONLY(xptr, xn, x); inexact = _arf_set_round_mpn(y, &fix, xptr, xn, ARF_SGNBIT(x), prec, rnd); _fmpz_add_fast(ARF_EXPREF(y), ARF_EXPREF(x), fix); return inexact; } } } arb-2.22.1/arf/set_round_mpn.c000066400000000000000000000110121417376376500161500ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int _arf_set_round_mpn(arf_t y, slong * exp_shift, mp_srcptr x, mp_size_t xn, int sgnbit, slong prec, arf_rnd_t rnd) { unsigned int leading; flint_bitcnt_t exp, bc, val, val_bits; mp_size_t yn, val_limbs; mp_ptr yptr; mp_limb_t t; int increment, inexact; /* Compute the total bit length of x. */ count_leading_zeros(leading, x[xn - 1]); exp = xn * FLINT_BITS - leading; /* Set exponent. */ *exp_shift = -(slong) leading; /* Find first nonzero bit. */ val_limbs = 0; while (x[val_limbs] == 0) val_limbs++; count_trailing_zeros(val_bits, x[val_limbs]); val = val_limbs * FLINT_BITS + val_bits; if (exp - val <= prec) { inexact = 0; increment = 0; } else { inexact = 1; /* Limb and bit of the truncation point. */ val_limbs = (exp - prec) / FLINT_BITS; val_bits = (exp - prec) % FLINT_BITS; if (rnd == ARF_RND_DOWN) { increment = 0; } else if (rnd == ARF_RND_NEAR) { /* If exactly one excess bit, there is a tie; the rounding direction is determined by the bit to the left of the truncation point. */ if (exp - val - 1 == prec) { increment = (x[val_limbs] >> val_bits) & 1; } else { /* The bit to the right of the truncation point determines the rounding direction. */ mp_size_t exc_limbs = (exp - prec - 1) / FLINT_BITS; flint_bitcnt_t exc_bits = (exp - prec - 1) % FLINT_BITS; increment = (x[exc_limbs] >> exc_bits) & 1; } } else { if (rnd == ARF_RND_UP) increment = 1; else if (rnd == ARF_RND_FLOOR) increment = sgnbit; else increment = !sgnbit; } if (!increment) { /* Find first nonzero bit from the truncation point. */ t = x[val_limbs] & (LIMB_ONES << val_bits); while (t == 0) { val_limbs++; t = x[val_limbs]; } count_trailing_zeros(val_bits, t); val = val_limbs * FLINT_BITS + val_bits; } else { /* Find first zero bit from the truncation point */ t = (~x[val_limbs]) & (LIMB_ONES << val_bits); while (t == 0) { val_limbs++; if (val_limbs < xn) t = ~x[val_limbs]; else /* The array is all ones up to the highest limb. */ { val_bits = 0; goto END_SCAN1; } } count_trailing_zeros(val_bits, t); END_SCAN1: val = val_limbs * FLINT_BITS + val_bits; /* Overflow to next power of two (unlikely). */ if (val == exp) { exp_shift[0]++; ARF_DEMOTE(y); ARF_NOPTR_D(y)[0] = LIMB_TOP; ARF_XSIZE(y) = ARF_MAKE_XSIZE(1, sgnbit); return 1; } } } /* Now copy the result to destination. */ x += val_limbs; xn -= val_limbs; bc = exp - val; yn = (bc + FLINT_BITS - 1) / FLINT_BITS; ARF_GET_MPN_WRITE(yptr, yn, y); ARF_XSIZE(y) |= sgnbit; if (leading == 0) { flint_mpn_copyi(yptr, x, xn); } else if (xn == yn) { mpn_lshift(yptr, x, yn, leading); } else { mpn_lshift(yptr, x + 1, yn, leading); yptr[0] |= (x[0] >> (FLINT_BITS - leading)); } if (increment) { /* Mask off bits from the last limb. */ yptr[0] &= LIMB_ONES << (yn * FLINT_BITS - bc); /* Increment (no carry propagation). */ yptr[0] += LIMB_ONE << (yn * FLINT_BITS - bc); } else if (inexact && prec < yn * FLINT_BITS) { /* Mask off bits from the last limb. */ yptr[0] &= LIMB_ONES << (yn * FLINT_BITS - prec); } return inexact; } arb-2.22.1/arf/set_round_ui.c000066400000000000000000000044751417376376500160120ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" /* Top-aligns the single-limb integer value v and rounds it to prec bits. Writes inexact, v, exp. Warning: macro without parentheses. */ #define ARF_NORMALISE_ROUND_LIMB(inexact, exp, v, sgnbit, prec, rnd) \ do { \ count_leading_zeros(exp, v); \ v <<= exp; \ exp = FLINT_BITS - exp; \ if (prec >= exp) \ { \ inexact = 0; \ } \ else \ { \ mp_limb_t hi_mask, lo_mask, rndn_mask, __t, __u; \ hi_mask = LIMB_ONES << (FLINT_BITS - prec); \ __t = v & hi_mask; \ inexact = (__t != v); \ if (inexact && rnd != ARF_RND_DOWN) \ { \ if (rnd == ARF_RND_NEAR) \ { \ lo_mask = LIMB_ONES >> prec; \ rndn_mask = LIMB_ONE << (FLINT_BITS - prec - 1); \ __u = v & lo_mask; \ if (__u > rndn_mask || (__u == rndn_mask && \ (__t << (prec - 1)))) \ __t += (LIMB_ONE << (FLINT_BITS - prec)); \ } \ else if (arf_rounds_up(rnd, sgnbit)) \ { \ __t += (LIMB_ONE << (FLINT_BITS - prec)); \ } \ if (__t == 0) \ { \ __t = LIMB_TOP; \ exp++; \ } \ } \ v = __t; \ } \ } while (0) int _arf_set_round_ui(arf_t x, ulong v, int sgnbit, slong prec, arf_rnd_t rnd) { _fmpz_demote(ARF_EXPREF(x)); ARF_DEMOTE(x); if (v == 0) { ARF_EXP(x) = ARF_EXP_ZERO; ARF_XSIZE(x) = 0; return 0; } else { int exp, inexact; ARF_NORMALISE_ROUND_LIMB(inexact, exp, v, sgnbit, prec, rnd); ARF_EXP(x) = exp; ARF_XSIZE(x) = ARF_MAKE_XSIZE(1, sgnbit); ARF_NOPTR_D(x)[0] = v; return inexact; } } arb-2.22.1/arf/set_round_uiui.c000066400000000000000000000131311417376376500163350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" /* Top-aligns the single-limb integer value v and rounds it to prec bits. Writes inexact, v, exp. Warning: macro without parentheses. */ #define ARF_NORMALISE_ROUND_LIMB(inexact, exp, v, sgnbit, prec, rnd) \ do { \ count_leading_zeros(exp, v); \ v <<= exp; \ exp = FLINT_BITS - exp; \ if (prec >= exp) \ { \ inexact = 0; \ } \ else \ { \ mp_limb_t hi_mask, lo_mask, rndn_mask, __t, __u; \ hi_mask = LIMB_ONES << (FLINT_BITS - prec); \ __t = v & hi_mask; \ inexact = (__t != v); \ if (inexact && rnd != ARF_RND_DOWN) \ { \ if (rnd == ARF_RND_NEAR) \ { \ lo_mask = LIMB_ONES >> prec; \ rndn_mask = LIMB_ONE << (FLINT_BITS - prec - 1); \ __u = v & lo_mask; \ if (__u > rndn_mask || (__u == rndn_mask && \ (__t << (prec - 1)))) \ __t += (LIMB_ONE << (FLINT_BITS - prec)); \ } \ else if (arf_rounds_up(rnd, sgnbit)) \ { \ __t += (LIMB_ONE << (FLINT_BITS - prec)); \ } \ if (__t == 0) \ { \ __t = LIMB_TOP; \ exp++; \ } \ } \ v = __t; \ } \ } while (0) int _arf_set_round_uiui(arf_t z, slong * fix, mp_limb_t hi, mp_limb_t lo, int sgnbit, slong prec, arf_rnd_t rnd) { int leading, trailing, bc, inexact, zn, up, exp; if (hi == 0) { ARF_NORMALISE_ROUND_LIMB(inexact, exp, lo, sgnbit, prec, rnd); leading = 2 * FLINT_BITS - exp; zn = 1; } else if (lo == 0) { ARF_NORMALISE_ROUND_LIMB(inexact, exp, hi, sgnbit, prec, rnd); leading = FLINT_BITS - exp; lo = hi; zn = 1; } else { count_leading_zeros(leading, hi); count_trailing_zeros(trailing, lo); bc = 2 * FLINT_BITS - leading - trailing; if (bc <= prec) { inexact = 0; zn = 2; if (leading != 0) { if (bc <= FLINT_BITS) { lo = (hi << leading) | (lo >> (FLINT_BITS - leading)); zn = 1; } else { hi = (hi << leading) | (lo >> (FLINT_BITS - leading)); lo = (lo << leading); } } } else { inexact = 1; if (rnd == ARF_RND_DOWN) { up = 0; } else if (rnd == ARF_RND_NEAR) { if (bc == prec + 1) { /* exactly one excess bit; check the parity bit which must be either the lsb of hi or a bit in lo */ if (trailing == FLINT_BITS - 1) up = hi & 1; else up = (lo >> (trailing + 1)) & 1; } else { /* two or more excess bits; test the first excess bit */ flint_bitcnt_t pos = 2 * FLINT_BITS - leading - prec - 1; if (pos < FLINT_BITS) up = (lo >> pos) & 1; else up = (hi >> (pos - FLINT_BITS)) & 1; } } else { up = arf_rounds_up(rnd, sgnbit); } if (prec <= FLINT_BITS) { zn = 1; if (leading == 0) lo = hi; else lo = (hi << leading) | (lo >> (FLINT_BITS - leading)); lo = lo & (LIMB_ONES << (FLINT_BITS - prec)); if (up) { mp_limb_t t, ovf; t = lo + (LIMB_ONE << (FLINT_BITS - prec)); ovf = (t == 0); leading -= ovf; lo = (t >> ovf) | (ovf << (FLINT_BITS - 1)); } } else { zn = 2; if (leading != 0) { hi = (hi << leading) | (lo >> (FLINT_BITS - leading)); lo = (lo << leading); } lo = lo & (LIMB_ONES << (2 * FLINT_BITS - prec)); if (up) { add_ssaaaa(hi, lo, hi, lo, 0, (LIMB_ONE << (2 * FLINT_BITS - prec))); } if (lo == 0) { if (hi == 0) { leading -= 1; lo = LIMB_TOP; } else { lo = hi; } zn = 1; } } } } *fix = -leading; ARF_DEMOTE(z); ARF_XSIZE(z) = ARF_MAKE_XSIZE(zn, sgnbit); ARF_NOPTR_D(z)[0] = lo; ARF_NOPTR_D(z)[1] = hi; return inexact; } arb-2.22.1/arf/sosq.c000066400000000000000000000041231417376376500142660ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_sosq(arf_t res, const arf_t a, const arf_t b, slong prec, arf_rnd_t rnd) { if (arf_is_special(a) || arf_is_special(b)) { if (arf_is_zero(a)) return arf_mul(res, b, b, prec, rnd); if (arf_is_zero(b)) return arf_mul(res, a, a, prec, rnd); if (arf_is_nan(a) || arf_is_nan(b)) arf_nan(res); else arf_pos_inf(res); return 0; } else { mp_srcptr ap, bp; int inexact; mp_ptr tmp, aap, bbp; mp_size_t an, bn, aan, bbn, alloc; slong shift; fmpz_t texp, uexp; ARF_MUL_TMP_DECL ARF_GET_MPN_READONLY(ap, an, a); ARF_GET_MPN_READONLY(bp, bn, b); fmpz_init(texp); fmpz_init(uexp); _fmpz_add2_fast(texp, ARF_EXPREF(a), ARF_EXPREF(a), 0); _fmpz_add2_fast(uexp, ARF_EXPREF(b), ARF_EXPREF(b), 0); shift = _fmpz_sub_small(texp, uexp); aan = 2 * an; bbn = 2 * bn; alloc = aan + bbn; ARF_MUL_TMP_ALLOC(tmp, alloc) aap = tmp; bbp = tmp + aan; ARF_MPN_MUL(aap, ap, an, ap, an) aan -= (aap[0] == 0); aap += (aap[0] == 0); ARF_MPN_MUL(bbp, bp, bn, bp, bn) bbn -= (bbp[0] == 0); bbp += (bbp[0] == 0); if (shift >= 0) inexact = _arf_add_mpn(res, aap, aan, 0, texp, bbp, bbn, 0, shift, prec, rnd); else inexact = _arf_add_mpn(res, bbp, bbn, 0, uexp, aap, aan, 0, -shift, prec, rnd); ARF_MUL_TMP_FREE(tmp, alloc) fmpz_clear(texp); fmpz_clear(uexp); return inexact; } } arb-2.22.1/arf/sqrt.c000066400000000000000000000042071417376376500142750ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_sqrt(arf_ptr z, arf_srcptr x, slong prec, arf_rnd_t rnd) { mp_size_t xn, zn, val; mp_srcptr xptr; mp_ptr tmp, zptr; mpfr_t xf, zf; int inexact, odd_exp; ARF_MUL_TMP_DECL if (arf_is_special(x)) { if (arf_is_neg_inf(x)) arf_nan(z); else arf_set(z, x); return 0; } if (ARF_SGNBIT(x)) { arf_nan(z); return 0; } if (ARF_IS_POW2(x) && fmpz_is_odd(ARF_EXPREF(x))) { arf_set(z, x); fmpz_cdiv_q_2exp(ARF_EXPREF(z), ARF_EXPREF(z), 1); return 0; } ARF_GET_MPN_READONLY(xptr, xn, x); odd_exp = fmpz_is_odd(ARF_EXPREF(x)) ? 1 : 0; zn = (prec + FLINT_BITS - 1) / FLINT_BITS; ARF_MUL_TMP_ALLOC(tmp, zn) zf->_mpfr_d = tmp; zf->_mpfr_prec = prec; zf->_mpfr_sign = 1; zf->_mpfr_exp = 0; xf->_mpfr_d = (mp_ptr) xptr; xf->_mpfr_prec = xn * FLINT_BITS; xf->_mpfr_sign = 1; xf->_mpfr_exp = odd_exp; inexact = mpfr_sqrt(zf, xf, arf_rnd_to_mpfr(rnd)); inexact = (inexact != 0); val = 0; while (tmp[val] == 0) val++; ARF_GET_MPN_WRITE(zptr, zn - val, z); flint_mpn_copyi(zptr, tmp + val, zn - val); fmpz_fdiv_q_2exp(ARF_EXPREF(z), ARF_EXPREF(x), 1); fmpz_add_si(ARF_EXPREF(z), ARF_EXPREF(z), zf->_mpfr_exp); ARF_MUL_TMP_FREE(tmp, zn) return inexact; } int arf_sqrt_ui(arf_t z, ulong x, slong prec, arf_rnd_t rnd) { arf_t t; arf_init_set_ui(t, x); /* no need to free */ return arf_sqrt(z, t, prec, rnd); } int arf_sqrt_fmpz(arf_t z, const fmpz_t x, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_set_fmpz(t, x); inexact = arf_sqrt(z, t, prec, rnd); arf_clear(t); return inexact; } arb-2.22.1/arf/sub.c000066400000000000000000000116761417376376500141050ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_sub_special(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (arf_is_zero(x)) { if (arf_is_zero(y)) { arf_zero(z); return 0; } else return arf_neg_round(z, y, prec, rnd); } else if (arf_is_zero(y)) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_nan(x) || arf_is_nan(y) || (arf_is_pos_inf(x) && arf_is_pos_inf(y)) || (arf_is_neg_inf(x) && arf_is_neg_inf(y))) { arf_nan(z); return 0; } else if (arf_is_special(x)) { arf_set(z, x); return 0; } else { arf_neg(z, y); return 0; } } int arf_sub(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; slong shift; if (arf_is_special(x) || arf_is_special(y)) { return arf_sub_special(z, x, y, prec, rnd); } shift = _fmpz_sub_small(ARF_EXPREF(x), ARF_EXPREF(y)); ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); if (shift >= 0) return _arf_add_mpn(z, xptr, xn, ARF_SGNBIT(x), ARF_EXPREF(x), yptr, yn, ARF_SGNBIT(y) ^ 1, shift, prec, rnd); else return _arf_add_mpn(z, yptr, yn, ARF_SGNBIT(y) ^ 1, ARF_EXPREF(y), xptr, xn, ARF_SGNBIT(x), -shift, prec, rnd); } int arf_sub_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; mp_limb_t ytmp; int xsgnbit, ysgnbit; fmpz yexp; slong shift; if (y == 0) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_special(x)) { if (arf_is_zero(x)) { arf_set_si(z, y); return arf_neg_round(z, z, prec, rnd); } else { arf_set(z, x); return 0; } } ysgnbit = (y < 0); if (ysgnbit) ytmp = -y; else ytmp = y; yptr = &ytmp; yn = 1; yexp = FLINT_BITS; ysgnbit ^= 1; shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp); xsgnbit = ARF_SGNBIT(x); ARF_GET_MPN_READONLY(xptr, xn, x); if (shift >= 0) return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), yptr, yn, ysgnbit, shift, prec, rnd); else return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp, xptr, xn, xsgnbit, -shift, prec, rnd); } int arf_sub_ui(arf_ptr z, arf_srcptr x, ulong y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; mp_limb_t ytmp; int xsgnbit, ysgnbit; fmpz yexp; slong shift; if (y == 0) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_special(x)) { if (arf_is_zero(x)) { arf_set_ui(z, y); return arf_neg_round(z, z, prec, rnd); } else { arf_set(z, x); return 0; } } ysgnbit = 1; ytmp = y; yptr = &ytmp; yn = 1; yexp = FLINT_BITS; shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp); xsgnbit = ARF_SGNBIT(x); ARF_GET_MPN_READONLY(xptr, xn, x); if (shift >= 0) return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), yptr, yn, ysgnbit, shift, prec, rnd); else return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp, xptr, xn, xsgnbit, -shift, prec, rnd); } int arf_sub_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn; mp_srcptr xptr, yptr; mp_limb_t ytmp; int xsgnbit, ysgnbit; fmpz yexp; slong shift; if (fmpz_is_zero(y)) { return arf_set_round(z, x, prec, rnd); } else if (arf_is_special(x)) { if (arf_is_zero(x)) { arf_set_fmpz(z, y); return arf_neg_round(z, z, prec, rnd); } else { arf_set(z, x); return 0; } } FMPZ_GET_MPN_READONLY(ysgnbit, yn, yptr, ytmp, *y) yexp = yn * FLINT_BITS; shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp); ysgnbit ^= 1; xsgnbit = ARF_SGNBIT(x); ARF_GET_MPN_READONLY(xptr, xn, x); if (shift >= 0) return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), yptr, yn, ysgnbit, shift, prec, rnd); else return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp, xptr, xn, xsgnbit, -shift, prec, rnd); } arb-2.22.1/arf/submul.c000066400000000000000000000075301417376376500146150ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_submul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn, zn, tn, alloc; mp_srcptr xptr, yptr, zptr; mp_ptr tptr, tptr2; fmpz_t texp; slong shift; int tsgnbit, inexact; ARF_MUL_TMP_DECL if (arf_is_special(x) || arf_is_special(y) || arf_is_special(z)) { if (arf_is_zero(z)) { return arf_neg_mul(z, x, y, prec, rnd); } else if (arf_is_finite(x) && arf_is_finite(y)) { return arf_set_round(z, z, prec, rnd); } else { /* todo: speed up */ arf_t t; arf_init(t); arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_sub(z, z, t, prec, rnd); arf_clear(t); return inexact; } } tsgnbit = ARF_SGNBIT(x) ^ ARF_SGNBIT(y) ^ 1; ARF_GET_MPN_READONLY(xptr, xn, x); ARF_GET_MPN_READONLY(yptr, yn, y); ARF_GET_MPN_READONLY(zptr, zn, z); fmpz_init(texp); _fmpz_add2_fast(texp, ARF_EXPREF(x), ARF_EXPREF(y), 0); shift = _fmpz_sub_small(ARF_EXPREF(z), texp); alloc = tn = xn + yn; ARF_MUL_TMP_ALLOC(tptr2, alloc) tptr = tptr2; ARF_MPN_MUL(tptr, xptr, xn, yptr, yn); tn -= (tptr[0] == 0); tptr += (tptr[0] == 0); if (shift >= 0) inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z), tptr, tn, tsgnbit, shift, prec, rnd); else inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp, zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd); ARF_MUL_TMP_FREE(tptr2, alloc) fmpz_clear(texp); return inexact; } int arf_submul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd) { mp_size_t xn, yn, zn, tn, alloc; mp_srcptr xptr, yptr, zptr; mp_ptr tptr, tptr2; fmpz_t texp, yexp; slong shift; int tsgnbit, ysgnbit, inexact; ARF_MUL_TMP_DECL yn = FLINT_ABS(y->_mp_size); if (arf_is_special(x) || yn == 0 || arf_is_special(z)) { if (arf_is_zero(z)) { /* TODO: make more efficient */ arf_mul_mpz(z, x, y, ARF_PREC_EXACT, rnd); return arf_neg_round(z, z, prec, rnd); } else if (arf_is_finite(x)) { return arf_set_round(z, z, prec, rnd); } else { /* todo: speed up */ arf_t t; arf_init(t); arf_mul_mpz(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_sub(z, z, t, prec, rnd); arf_clear(t); return inexact; } } ARF_GET_MPN_READONLY(xptr, xn, x); yptr = y->_mp_d; ysgnbit = (y->_mp_size > 0); *yexp = yn * FLINT_BITS; ARF_GET_MPN_READONLY(zptr, zn, z); fmpz_init(texp); tsgnbit = ARF_SGNBIT(x) ^ ysgnbit; alloc = tn = xn + yn; ARF_MUL_TMP_ALLOC(tptr2, alloc) tptr = tptr2; ARF_MPN_MUL(tptr, xptr, xn, yptr, yn); shift = (tptr[tn - 1] == 0) * FLINT_BITS; tn -= (tptr[tn - 1] == 0); _fmpz_add2_fast(texp, ARF_EXPREF(x), yexp, -shift); shift = _fmpz_sub_small(ARF_EXPREF(z), texp); if (shift >= 0) inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z), tptr, tn, tsgnbit, shift, prec, rnd); else inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp, zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd); ARF_MUL_TMP_FREE(tptr2, alloc) fmpz_clear(texp); return inexact; } arb-2.22.1/arf/sum.c000066400000000000000000000106271417376376500141130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int _arf_are_close(const arf_t x, const arf_t y, slong prec) { fmpz_t xb, yb; fmpz_t delta; int result; fmpz_init(xb); fmpz_init(yb); fmpz_init(delta); arf_bot(xb, x); arf_bot(yb, y); if (fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y)) >= 0) fmpz_sub(delta, xb, ARF_EXPREF(y)); else fmpz_sub(delta, yb, ARF_EXPREF(x)); fmpz_sub_ui(delta, delta, 64); result = (fmpz_cmp_ui(delta, prec) < 0); fmpz_clear(xb); fmpz_clear(yb); fmpz_clear(delta); return result; } int _arf_add_eps(arf_t s, const arf_t x, int sgn, slong prec, arf_rnd_t rnd) { arf_t t; slong bits; bits = arf_bits(x); if (bits == 0) { flint_printf("_arf_add_eps\n"); flint_abort(); } bits = FLINT_MAX(bits, prec) + 10; arf_init(t); arf_set_si(t, sgn); arf_mul_2exp_fmpz(t, t, ARF_EXPREF(x)); arf_mul_2exp_si(t, t, -bits); arf_add(s, x, t, prec, rnd); arf_clear(t); return 1; } int arf_sum(arf_t s, arf_srcptr terms, slong len, slong prec, arf_rnd_t rnd) { arf_ptr blocks; slong i, j, used; int have_merged, res; /* first check if the result is inf or nan */ { int have_pos_inf = 0; int have_neg_inf = 0; for (i = 0; i < len; i++) { if (arf_is_pos_inf(terms + i)) { if (have_neg_inf) { arf_nan(s); return 0; } have_pos_inf = 1; } else if (arf_is_neg_inf(terms + i)) { if (have_pos_inf) { arf_nan(s); return 0; } have_neg_inf = 1; } else if (arf_is_nan(terms + i)) { arf_nan(s); return 0; } } if (have_pos_inf) { arf_pos_inf(s); return 0; } if (have_neg_inf) { arf_neg_inf(s); return 0; } } blocks = flint_malloc(sizeof(arf_struct) * len); for (i = 0; i < len; i++) arf_init(blocks + i); /* put all terms into blocks */ used = 0; for (i = 0; i < len; i++) { if (!arf_is_zero(terms + i)) { arf_set(blocks + used, terms + i); used++; } } /* merge blocks until all are well separated */ have_merged = 1; while (used >= 2 && have_merged) { have_merged = 0; for (i = 0; i < used && !have_merged; i++) { for (j = i + 1; j < used && !have_merged; j++) { if (_arf_are_close(blocks + i, blocks + j, prec)) { arf_add(blocks + i, blocks + i, blocks + j, ARF_PREC_EXACT, ARF_RND_DOWN); /* remove the merged block */ arf_swap(blocks + j, blocks + used - 1); used--; /* remove the updated block if the sum is zero */ if (arf_is_zero(blocks + i)) { arf_swap(blocks + i, blocks + used - 1); used--; } have_merged = 1; } } } } if (used == 0) { arf_zero(s); res = 0; } else if (used == 1) { res = arf_set_round(s, blocks + 0, prec, rnd); } else { /* find the two largest blocks */ for (i = 1; i < used; i++) if (arf_cmpabs(blocks + 0, blocks + i) < 0) arf_swap(blocks + 0, blocks + i); for (i = 2; i < used; i++) if (arf_cmpabs(blocks + 1, blocks + i) < 0) arf_swap(blocks + 1, blocks + i); res = _arf_add_eps(s, blocks + 0, arf_sgn(blocks + 1), prec, rnd); } for (i = 0; i < len; i++) arf_clear(blocks + i); flint_free(blocks); return res; } arb-2.22.1/arf/test/000077500000000000000000000000001417376376500141145ustar00rootroot00000000000000arb-2.22.1/arf/test/t-abs_bound_le_2exp_fmpz.c000066400000000000000000000031541417376376500211320ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("abs_bound_le_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y; fmpz_t b; int cmp1, cmp2; arf_init(x); arf_init(y); fmpz_init(b); arf_randtest_not_zero(x, state, 2 + n_randint(state, 1000), 100); arf_abs_bound_le_2exp_fmpz(b, x); arf_one(y); arf_mul_2exp_fmpz(y, y, b); cmp1 = (arf_cmpabs(x, y) <= 0); arf_mul_2exp_si(y, y, -1); cmp2 = (arf_cmpabs(y, x) < 0); arf_mul_2exp_si(y, y, 1); if (!cmp1 || !cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } arf_clear(x); arf_clear(y); fmpz_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-abs_bound_lt_2exp_fmpz.c000066400000000000000000000031541417376376500211510ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("abs_bound_lt_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y; fmpz_t b; int cmp1, cmp2; arf_init(x); arf_init(y); fmpz_init(b); arf_randtest_not_zero(x, state, 2 + n_randint(state, 1000), 100); arf_abs_bound_lt_2exp_fmpz(b, x); arf_one(y); arf_mul_2exp_fmpz(y, y, b); cmp1 = (arf_cmpabs(x, y) < 0); arf_mul_2exp_si(y, y, -1); cmp2 = (arf_cmpabs(y, x) <= 0); arf_mul_2exp_si(y, y, 1); if (!cmp1 || !cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } arf_clear(x); arf_clear(y); fmpz_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-abs_bound_lt_2exp_si.c000066400000000000000000000043151417376376500206100ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("abs_bound_lt_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x; fmpz_t b; slong c; arf_init(x); fmpz_init(b); if (iter < 5) { arf_set_ui_2exp_si(x, 1, LONG_MIN + 2); arf_mul_2exp_si(x, x, -iter); } else if (iter < 10) { arf_set_ui_2exp_si(x, 1, WORD_MAX - 2); arf_mul_2exp_si(x, x, iter - 5); } else { arf_randtest_special(x, state, 2 + n_randint(state, 1000), 100); } arf_abs_bound_lt_2exp_fmpz(b, x); c = arf_abs_bound_lt_2exp_si(x); if (c == -ARF_PREC_EXACT) { if (!(arf_is_zero(x) || fmpz_cmp_si(b, -ARF_PREC_EXACT) <= 0)) { flint_printf("FAIL (small/zero)\n\n"); flint_abort(); } } else if (c == ARF_PREC_EXACT) { if (!(arf_is_inf(x) || arf_is_nan(x) || fmpz_cmp_si(b, ARF_PREC_EXACT) >= 0)) { flint_printf("FAIL (large/inf/nan)\n\n"); flint_abort(); } } else { if (fmpz_cmp_si(b, c) != 0) { flint_printf("FAIL (normal)\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf("c = %wd\n\n", c); flint_abort(); } } arf_clear(x); fmpz_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-add.c000066400000000000000000000143571417376376500152630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_add_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (rnd == ARF_RND_NEAR) { arf_add(z, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); return arf_set_round(z, z, prec, rnd); } else { fmpr_t a, b; slong r; fmpr_init(a); fmpr_init(b); arf_get_fmpr(a, x); arf_get_fmpr(b, y); r = fmpr_add(a, a, b, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); fmpr_clear(b); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } } int main() { slong iter, iter2; flint_rand_t state; flint_printf("add...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; fmpz_t t; arf_init(x); arf_init(y); arf_init(z); arf_init(v); fmpz_init(t); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } rnd = ARF_RND_DOWN; if (arf_is_normal(x) && arf_is_normal(y)) { fmpz_sub(t, ARF_EXPREF(x), ARF_EXPREF(y)); /* if not too far apart, sometimes test exact addition */ if (fmpz_bits(t) < 10) { if (n_randint(state, 10) == 0) prec = ARF_PREC_EXACT; } else if (rnd == ARF_RND_NEAR) { /* large shift not supported in add_naive */ rnd = ARF_RND_DOWN; } } switch (n_randint(state, 5)) { case 0: r1 = arf_add(z, x, y, prec, rnd); r2 = arf_add_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_add(z, x, x, prec, rnd); r2 = arf_add_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_add_naive(v, x, x, prec, rnd); r1 = arf_add(x, x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_add_naive(v, x, y, prec, rnd); r1 = arf_add(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_add_naive(v, x, y, prec, rnd); r1 = arf_add(x, y, x, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-add_fmpz.c000066400000000000000000000066101417376376500163100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_add_fmpz_naive(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_fmpz(t, y); r = arf_add(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("add_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; fmpz_t y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); fmpz_init(y); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); fmpz_randtest(y, state, 2000); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_add_fmpz(z, x, y, prec, rnd); r2 = arf_add_fmpz_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_add_fmpz_naive(v, x, y, prec, rnd); r1 = arf_add_fmpz(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); fmpz_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-add_fmpz_2exp.c000066400000000000000000000073111417376376500172450ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_add_fmpz_2exp_naive(arf_t z, const arf_t x, const fmpz_t y, const fmpz_t e, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_fmpz_2exp(t, y, e); r = arf_add(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("add_fmpz_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; fmpz_t y, e; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); fmpz_init(y); fmpz_init(e); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); fmpz_randtest(y, state, 2000); fmpz_randtest(e, state, 10); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_add_fmpz_2exp(z, x, y, e, prec, rnd); r2 = arf_add_fmpz_2exp_naive(v, x, y, e, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_add_fmpz_2exp_naive(v, x, y, e, prec, rnd); r1 = arf_add_fmpz_2exp(x, x, y, e, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); fmpz_clear(y); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-add_si.c000066400000000000000000000066161417376376500157550ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/long_extras.h" int arf_add_si_naive(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_si(t, y); r = arf_add(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("add_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); y = z_randtest(state); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 1)) { case 0: r1 = arf_add_si(z, x, y, prec, rnd); r2 = arf_add_si_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL! (ha iter %wd, %wd)\n", iter, iter2); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_add_si_naive(v, x, y, prec, rnd); r1 = arf_add_si(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-add_ui.c000066400000000000000000000065571417376376500157630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/ulong_extras.h" int arf_add_ui_naive(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_ui(t, y); r = arf_add(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("add_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; ulong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); y = n_randtest(state); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_add_ui(z, x, y, prec, rnd); r2 = arf_add_ui_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_add_ui_naive(v, x, y, prec, rnd); r1 = arf_add_ui(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-addmul.c000066400000000000000000000131531417376376500157720ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_addmul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("addmul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(y)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 5)) { case 0: r1 = arf_addmul(z, x, y, prec, rnd); r2 = arf_addmul_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_addmul(z, x, x, prec, rnd); r2 = arf_addmul_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_addmul_naive(v, v, v, prec, rnd); r1 = arf_addmul(z, z, z, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_addmul_naive(v, v, y, prec, rnd); r1 = arf_addmul(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_addmul_naive(v, x, v, prec, rnd); r1 = arf_addmul(z, x, z, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-addmul_fmpz.c000066400000000000000000000071451417376376500170320ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_addmul_fmpz_naive(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul_fmpz(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("addmul_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; fmpz_t y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); fmpz_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); fmpz_randtest(y, state, 2000); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_addmul_fmpz(z, x, y, prec, rnd); r2 = arf_addmul_fmpz_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_debug(z); flint_printf("\n\n"); flint_printf("v = "); arf_debug(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_addmul_fmpz_naive(v, v, y, prec, rnd); r1 = arf_addmul_fmpz(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); fmpz_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-addmul_si.c000066400000000000000000000070471417376376500164720ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/long_extras.h" int arf_addmul_si_naive(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul_si(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("addmul_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); y = z_randtest(state); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_addmul_si(z, x, y, prec, rnd); r2 = arf_addmul_si_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = %wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_debug(z); flint_printf("\n\n"); flint_printf("v = "); arf_debug(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_addmul_si_naive(v, v, y, prec, rnd); r1 = arf_addmul_si(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = %wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-addmul_ui.c000066400000000000000000000070101417376376500164620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_addmul_ui_naive(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul_ui(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("addmul_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; ulong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); y = n_randtest(state); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_addmul_ui(z, x, y, prec, rnd); r2 = arf_addmul_ui_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = %wu", y); flint_printf("\n\n"); flint_printf("z = "); arf_debug(z); flint_printf("\n\n"); flint_printf("v = "); arf_debug(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_addmul_ui_naive(v, v, y, prec, rnd); r1 = arf_addmul_ui(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = %wu", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-ceil.c000066400000000000000000000044021417376376500154350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("ceil...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y; int result; arf_init(x); arf_init(y); arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); arf_ceil(y, x); result = 1; if (arf_is_int(x) || !arf_is_finite(x)) { result = arf_equal(y, x); } else if (!arf_is_int(y)) { result = 0; } else if (arf_cmp(y, x) <= 0) { result = 0; } else { arf_t s, t[3]; /* check x - ceil(x) + 1 > 0 */ arf_init(s); arf_init(t[0]); arf_init(t[1]); arf_init(t[2]); arf_set(t[0], x); arf_neg(t[1], y); arf_one(t[2]); arf_sum(s, (arf_ptr) t, 3, 32, ARF_RND_DOWN); result = arf_sgn(s) > 0; arf_clear(s); arf_clear(t[0]); arf_clear(t[1]); arf_clear(t[2]); } if (!result) { flint_printf("FAIL!\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_abort(); } arf_ceil(x, x); if (!arf_equal(x, y)) { flint_printf("FAIL (aliasing)!\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-cmp.c000066400000000000000000000060311417376376500153000ustar00rootroot00000000000000/* Copyright (C) 2012, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("cmp...."); fflush(stdout); flint_randinit(state); /* compare with fmpz */ { arf_t x, y; fmpz_t X, Y; arf_init(x); arf_init(y); fmpz_init(X); fmpz_init(Y); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { int cmp1, cmp2; fmpz_randtest(X, state, 1 + n_randint(state, 1000)); switch (n_randint(state, 8)) { case 0: fmpz_neg(Y, X); break; case 1: fmpz_set(Y, X); break; default: fmpz_randtest(Y, state, 1 + n_randint(state, 1000)); } arf_set_fmpz(x, X); arf_set_fmpz(y, Y); cmp1 = arf_cmp(x, y); cmp2 = fmpz_cmp(X, Y); cmp2 = (cmp2 > 0) - (cmp2 < 0); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_debug(x); flint_printf("\n\n"); flint_printf("y = "); arf_debug(y); flint_printf("\n\n"); flint_printf("X = "); fmpz_print(X); flint_printf("\n\n"); flint_printf("Y = "); fmpz_print(Y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } } arf_clear(x); arf_clear(y); fmpz_clear(X); fmpz_clear(Y); } /* compare with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits; arf_t x, y; mpfr_t X, Y; int cmp1, cmp2; bits = 2 + n_randint(state, 200); arf_init(x); arf_init(y); mpfr_init2(X, bits); mpfr_init2(Y, bits); arf_randtest_special(x, state, bits, 10); arf_randtest_special(y, state, bits, 10); arf_get_mpfr(X, x, MPFR_RNDN); arf_get_mpfr(Y, y, MPFR_RNDN); cmp1 = arf_cmp(x, y); cmp2 = mpfr_cmp(X, Y); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } arf_clear(x); arf_clear(y); mpfr_clear(X); mpfr_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-cmp_2exp_si.c000066400000000000000000000027531417376376500167400ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("cmp_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits, e; arf_t x, y; int cmp1, cmp2; bits = 2 + n_randint(state, 1000); e = n_randtest(state); arf_init(x); arf_init(y); if (iter % 10 == 0) arf_set_ui_2exp_si(x, 1, e); else arf_randtest_special(x, state, bits, 100); arf_set_ui_2exp_si(y, 1, e); cmp1 = arf_cmp(x, y); cmp2 = arf_cmp_2exp_si(x, e); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-cmpabs.c000066400000000000000000000061541417376376500157740ustar00rootroot00000000000000/* Copyright (C) 2012, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("cmpabs...."); fflush(stdout); flint_randinit(state); /* compare with fmpz */ { arf_t x, y; fmpz_t X, Y; arf_init(x); arf_init(y); fmpz_init(X); fmpz_init(Y); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { int cmp1, cmp2; fmpz_randtest(X, state, 1 + n_randint(state, 1000)); switch (n_randint(state, 8)) { case 0: fmpz_neg(Y, X); break; case 1: fmpz_set(Y, X); break; default: fmpz_randtest(Y, state, 1 + n_randint(state, 1000)); } arf_set_fmpz(x, X); arf_set_fmpz(y, Y); cmp1 = arf_cmpabs(x, y); cmp2 = fmpz_cmpabs(X, Y); cmp2 = (cmp2 > 0) - (cmp2 < 0); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_debug(x); flint_printf("\n\n"); flint_printf("y = "); arf_debug(y); flint_printf("\n\n"); flint_printf("X = "); fmpz_print(X); flint_printf("\n\n"); flint_printf("Y = "); fmpz_print(Y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } } arf_clear(x); arf_clear(y); fmpz_clear(X); fmpz_clear(Y); } /* compare with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits; arf_t x, y; mpfr_t X, Y; int cmp1, cmp2; bits = 2 + n_randint(state, 200); arf_init(x); arf_init(y); mpfr_init2(X, bits); mpfr_init2(Y, bits); arf_randtest_special(x, state, bits, 10); arf_randtest_special(y, state, bits, 10); arf_get_mpfr(X, x, MPFR_RNDN); arf_get_mpfr(Y, y, MPFR_RNDN); mpfr_abs(X, X, MPFR_RNDN); mpfr_abs(Y, Y, MPFR_RNDN); cmp1 = arf_cmpabs(x, y); cmp2 = mpfr_cmp(X, Y); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } arf_clear(x); arf_clear(y); mpfr_clear(X); mpfr_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-cmpabs_2exp_si.c000066400000000000000000000027641417376376500174300ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("cmpabs_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits, e; arf_t x, y; int cmp1, cmp2; bits = 2 + n_randint(state, 1000); e = n_randtest(state); arf_init(x); arf_init(y); if (iter % 10 == 0) arf_set_ui_2exp_si(x, 1, e); else arf_randtest_special(x, state, bits, 100); arf_set_ui_2exp_si(y, 1, e); cmp1 = arf_cmpabs(x, y); cmp2 = arf_cmpabs_2exp_si(x, e); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-complex_mul.c000066400000000000000000000157371417376376500170620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter, iter2; flint_rand_t state; flint_printf("complex_mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t e1, f1, e2, f2, a, b, c, d; slong prec, r1, r2; arf_rnd_t rnd; arf_init(a); arf_init(b); arf_init(c); arf_init(d); arf_init(e1); arf_init(f1); arf_init(e2); arf_init(f2); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(a, state, 3000, 100); arf_randtest_special(b, state, 3000, 100); arf_randtest_special(c, state, 3000, 100); arf_randtest_special(d, state, 3000, 100); prec = 2 + n_randint(state, 3000); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 5)) { case 0: r1 = arf_complex_mul(e1, f1, a, b, c, d, prec, rnd); r2 = arf_complex_mul_fallback(e2, f2, a, b, c, d, prec, rnd); if (!arf_equal(e1, e2) || !arf_equal(f1, f2) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("c = "); arf_print(c); flint_printf("\n\n"); flint_printf("d = "); arf_print(d); flint_printf("\n\n"); flint_printf("e1 = "); arf_print(e1); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("e2 = "); arf_print(e2); flint_printf("\n\n"); flint_printf("f2 = "); arf_print(f2); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: arf_set(c, a); arf_set(d, b); r1 = arf_complex_mul(e1, f1, a, b, a, b, prec, rnd); r2 = arf_complex_mul_fallback(e2, f2, a, b, c, d, prec, rnd); if (!arf_equal(e1, e2) || !arf_equal(f1, f2) || r1 != r2) { flint_printf("FAIL! (aliasing 1)\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("c = "); arf_print(c); flint_printf("\n\n"); flint_printf("d = "); arf_print(d); flint_printf("\n\n"); flint_printf("e1 = "); arf_print(e1); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("e2 = "); arf_print(e2); flint_printf("\n\n"); flint_printf("f2 = "); arf_print(f2); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r1 = arf_complex_mul_fallback(e1, f1, a, b, a, b, prec, rnd); r2 = arf_complex_mul(a, b, a, b, a, b, prec, rnd); if (!arf_equal(e1, a) || !arf_equal(f1, b) || r1 != r2) { flint_printf("FAIL! (aliasing 2)\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("e1 = "); arf_print(e1); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r1 = arf_complex_mul_fallback(e1, f1, a, b, c, d, prec, rnd); r2 = arf_complex_mul(a, b, a, b, c, d, prec, rnd); if (!arf_equal(e1, a) || !arf_equal(f1, b) || r1 != r2) { flint_printf("FAIL! (aliasing 3)\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("c = "); arf_print(c); flint_printf("\n\n"); flint_printf("d = "); arf_print(d); flint_printf("\n\n"); flint_printf("e1 = "); arf_print(e1); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r1 = arf_complex_mul_fallback(e1, f1, a, b, c, d, prec, rnd); r2 = arf_complex_mul(c, d, a, b, c, d, prec, rnd); if (!arf_equal(e1, c) || !arf_equal(f1, d) || r1 != r2) { flint_printf("FAIL! (aliasing 4)\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("c = "); arf_print(c); flint_printf("\n\n"); flint_printf("d = "); arf_print(d); flint_printf("\n\n"); flint_printf("e1 = "); arf_print(e1); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(a); arf_clear(b); arf_clear(c); arf_clear(d); arf_clear(e1); arf_clear(f1); arf_clear(e2); arf_clear(f2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-complex_sqr.c000066400000000000000000000067141417376376500170650ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter, iter2; flint_rand_t state; flint_printf("complex_sqr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t e1, f1, e2, f2, a, b; slong prec, r1, r2; arf_rnd_t rnd; arf_init(a); arf_init(b); arf_init(e1); arf_init(f1); arf_init(e2); arf_init(f2); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(a, state, 3000, 100); arf_randtest_special(b, state, 3000, 100); prec = 2 + n_randint(state, 3000); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_complex_sqr(e1, f1, a, b, prec, rnd); r2 = arf_complex_mul_fallback(e2, f2, a, b, a, b, prec, rnd); if (!arf_equal(e1, e2) || !arf_equal(f1, f2) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("e1 = "); arf_print(e1); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("e2 = "); arf_print(e2); flint_printf("\n\n"); flint_printf("f2 = "); arf_print(f2); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r1 = arf_complex_mul_fallback(e1, f1, a, b, a, b, prec, rnd); r2 = arf_complex_sqr(a, b, a, b, prec, rnd); if (!arf_equal(e1, a) || !arf_equal(f1, b) || r1 != r2) { flint_printf("FAIL! (aliasing)\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("a = "); arf_print(a); flint_printf("\n\n"); flint_printf("b = "); arf_print(b); flint_printf("\n\n"); flint_printf("e1 = "); arf_print(e1); flint_printf("\n\n"); flint_printf("f1 = "); arf_print(f1); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(a); arf_clear(b); arf_clear(e1); arf_clear(f1); arf_clear(e2); arf_clear(f2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-div.c000066400000000000000000000146621417376376500153140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_div_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (rnd == ARF_RND_NEAR) { arf_t m, n; fmpz_t e, f; mpfr_t a, b, c; int inexact; if (arf_is_zero(y)) { arf_nan(z); return 0; } arf_init(m); arf_init(n); fmpz_init(e); fmpz_init(f); mpfr_init2(a, FLINT_MAX(2, arf_bits(x))); mpfr_init2(b, FLINT_MAX(2, arf_bits(y))); mpfr_init2(c, prec); arf_frexp(m, e, x); arf_frexp(n, f, y); arf_get_mpfr(a, m, MPFR_RNDD); arf_get_mpfr(b, n, MPFR_RNDD); inexact = (mpfr_div(c, a, b, arf_rnd_to_mpfr(rnd)) != 0); arf_set_mpfr(z, c); fmpz_sub(e, e, f); arf_mul_2exp_fmpz(z, z, e); arf_clear(m); arf_clear(n); fmpz_clear(e); fmpz_clear(f); mpfr_clear(a); mpfr_clear(b); mpfr_clear(c); return inexact; } else { fmpr_t a, b; slong r; fmpr_init(a); fmpr_init(b); arf_get_fmpr(a, x); arf_get_fmpr(b, y); r = fmpr_div(a, a, b, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); fmpr_clear(b); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } } int main() { slong iter, iter2; flint_rand_t state; flint_printf("div...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); prec = 2 + n_randint(state, 2000); if (n_randint(state, 20) == 0) arf_mul(x, x, y, 2 + n_randint(state, 3000), ARF_RND_FLOOR); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 5)) { case 0: r1 = arf_div(z, x, y, prec, rnd); r2 = arf_div_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_div(z, x, x, prec, rnd); r2 = arf_div_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_div_naive(v, x, x, prec, rnd); r1 = arf_div(x, x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_div_naive(v, x, y, prec, rnd); r1 = arf_div(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_div_naive(v, y, x, prec, rnd); r1 = arf_div(x, y, x, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-dump_file.c000066400000000000000000000052111417376376500164640ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "arb.h" int main() { flint_rand_t state; slong iter; flint_printf("dump_file/load_file...."); fflush(stdout); flint_randinit(state); /* assume tmpfile() is broken on windows */ #if !defined(_MSC_VER) && !defined(__MINGW32__) /* just test no crashing... */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x; FILE* tmp; arf_init(x); arf_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); tmp = tmpfile(); arf_dump_file(tmp, x); fflush(tmp); rewind(tmp); arf_load_file(x, tmp); fclose(tmp); arf_clear(x); } for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t x, y, z; int conversion_error; FILE* tmp; arf_init(x); arf_init(y); arf_init(z); arf_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arf_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arf_randtest_special(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); tmp = tmpfile(); arf_dump_file(tmp, x); fputc(' ', tmp); arf_dump_file(tmp, y); fflush(tmp); rewind(tmp); conversion_error = arf_load_file(z, tmp); if (conversion_error || !arf_equal(x, z)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n"); flint_printf("z = "); arf_printd(z, 50); flint_printf("\n\n"); flint_abort(); } conversion_error = arf_load_file(z, tmp); if (conversion_error || !arf_equal(y, z)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("y = "); arf_printd(y, 50); flint_printf("\n\n"); flint_printf("z = "); arf_printd(z, 50); flint_printf("\n\n"); flint_abort(); } fclose(tmp); arf_clear(x); arf_clear(y); arf_clear(z); } #endif flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-dump_str.c000066400000000000000000000035621417376376500163640ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arf.h" int main() { flint_rand_t state; slong iter; flint_printf("dump_str/load_str...."); fflush(stdout); flint_randinit(state); /* just test no crashing... */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x; char * s; arf_init(x); arf_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); s = arf_dump_str(x); flint_free(s); arf_clear(x); } for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t x, y; char * s; int conversion_error; arf_init(x); arf_init(y); arf_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arf_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); s = arf_dump_str(x); conversion_error = arf_load_str(y, s); if (conversion_error || !arf_equal(x, y)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n"); flint_printf("s = %s", s); flint_printf("\n\n"); flint_printf("y = "); arf_printd(y, 50); flint_printf("\n\n"); flint_abort(); } flint_free(s); arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-floor.c000066400000000000000000000044061417376376500156460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("floor...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y; int result; arf_init(x); arf_init(y); arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); arf_floor(y, x); result = 1; if (arf_is_int(x) || !arf_is_finite(x)) { result = arf_equal(y, x); } else if (!arf_is_int(y)) { result = 0; } else if (arf_cmp(y, x) >= 0) { result = 0; } else { arf_t s, t[3]; /* check floor(x) - x + 1 > 0 */ arf_init(s); arf_init(t[0]); arf_init(t[1]); arf_init(t[2]); arf_set(t[0], y); arf_neg(t[1], x); arf_one(t[2]); arf_sum(s, (arf_ptr) t, 3, 32, ARF_RND_DOWN); result = arf_sgn(s) > 0; arf_clear(s); arf_clear(t[0]); arf_clear(t[1]); arf_clear(t[2]); } if (!result) { flint_printf("FAIL!\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_abort(); } arf_floor(x, x); if (!arf_equal(x, y)) { flint_printf("FAIL (aliasing)!\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-fma.c000066400000000000000000000101751417376376500152700ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_fma_naive(arf_t res, const arf_t x, const arf_t y, const arf_t z, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(res, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter; flint_rand_t state; flint_printf("fma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y, z, res1, res2; slong prec, r1, r2; arf_rnd_t rnd; int aliasing; arf_init(x); arf_init(y); arf_init(z); arf_init(res1); arf_init(res2); prec = 2 + n_randint(state, 200); arf_randtest_special(x, state, 200, 100); arf_randtest_special(y, state, 200, 100); arf_randtest_special(z, state, 200, 100); arf_randtest_special(res1, state, 200, 100); arf_randtest_special(res2, state, 200, 100); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(y)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } aliasing = n_randint(state, 7); switch (aliasing) { case 0: r1 = arf_fma(res1, x, y, z, prec, rnd); r2 = arf_fma_naive(res2, x, y, z, prec, rnd); break; case 1: arf_set(res1, z); r1 = arf_fma(res1, x, y, res1, prec, rnd); r2 = arf_fma_naive(res2, x, y, z, prec, rnd); break; case 2: arf_set(res1, x); r1 = arf_fma(res1, res1, y, z, prec, rnd); r2 = arf_fma_naive(res2, x, y, z, prec, rnd); break; case 3: arf_set(res1, y); r1 = arf_fma(res1, x, res1, z, prec, rnd); r2 = arf_fma_naive(res2, x, y, z, prec, rnd); break; case 4: r1 = arf_fma(res1, x, x, z, prec, rnd); r2 = arf_fma_naive(res2, x, x, z, prec, rnd); break; case 5: arf_set(res1, x); r1 = arf_fma(res1, res1, res1, z, prec, rnd); r2 = arf_fma_naive(res2, x, x, z, prec, rnd); break; default: arf_set(res1, x); r1 = arf_fma(res1, res1, res1, res1, prec, rnd); r2 = arf_fma_naive(res2, x, x, x, prec, rnd); break; } if (!arf_equal(res1, res2) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d, aliasing = %d\n\n", prec, rnd, aliasing); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("res1 = "); arf_print(res1); flint_printf("\n\n"); flint_printf("res2 = "); arf_print(res2); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(res1); arf_clear(res2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-frexp.c000066400000000000000000000044221417376376500156470ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("frexp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y, z; fmpz_t e, f; int ok; arf_init(x); arf_init(y); arf_init(z); fmpz_init(e); fmpz_init(f); arf_randtest_special(x, state, 200, 100); arf_randtest_special(y, state, 200, 100); fmpz_randtest(e, state, 100); fmpz_randtest(f, state, 100); arf_frexp(y, e, x); arf_mul_2exp_fmpz(z, y, e); ok = 1; if (!arf_equal(z, x)) ok = 0; if (arf_is_special(x) && !fmpz_is_zero(e)) ok = 0; if (!arf_is_special(x) && !(arf_cmpabs_2exp_si(y, 0) < 0 && arf_cmpabs_2exp_si(y, -1) >= 0)) ok = 0; if (!ok) { printf("FAIL\n"); printf("x = "); arf_print(x); printf("\n\n"); printf("y = "); arf_print(y); printf("\n\n"); printf("z = "); arf_print(z); printf("\n\n"); printf("e = "); fmpz_print(e); printf("\n\n"); printf("f = "); fmpz_print(f); printf("\n\n"); flint_abort(); } arf_frexp(x, f, x); if (!arf_equal(x, y) || !fmpz_equal(e, f)) { printf("FAIL (aliasing)\n"); printf("x = "); arf_print(x); printf("\n\n"); printf("y = "); arf_print(y); printf("\n\n"); printf("z = "); arf_print(z); printf("\n\n"); printf("e = "); fmpz_print(e); printf("\n\n"); printf("f = "); fmpz_print(f); printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(y); arf_clear(z); fmpz_clear(e); fmpz_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-get_d.c000066400000000000000000000077131417376376500156130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("get_d...."); fflush(stdout); flint_randinit(state); /* test exact roundtrip */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t x, z; double y; arf_rnd_t rnd; arf_init(x); arf_init(z); switch (n_randint(state, 4)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } arf_randtest_special(x, state, 53, 8); y = arf_get_d(x, rnd); arf_set_d(z, y); if (!arf_equal(x, z)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = %.17g\n\n", y); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(z); } /* test rounding */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t x, z, w; arf_rnd_t rnd; double y; arf_init(x); arf_init(z); arf_init(w); arf_randtest_special(x, state, 300, 8); switch (n_randint(state, 4)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; default: rnd = ARF_RND_CEIL; break; } y = arf_get_d(x, rnd); arf_set_d(w, y); arf_set_round(z, x, 53, rnd); if (!arf_equal(w, z)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = %.17g\n\n", y); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("w = "); arf_print(w); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(z); arf_clear(w); } /* compare with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { arf_t x, r1, r2; arf_rnd_t rnd; mpfr_t t; double d1, d2; arf_init(x); arf_init(r1); arf_init(r2); mpfr_init2(t, 300); arf_randtest_special(x, state, 300, 20); arf_get_mpfr(t, x, MPFR_RNDD); switch (n_randint(state, 4)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } d1 = arf_get_d(x, rnd); d2 = mpfr_get_d(t, rnd_to_mpfr(rnd)); arf_set_d(r1, d1); arf_set_d(r2, d2); if (!arf_equal(r1, r2)) { flint_printf("FAIL:\n\n"); flint_printf("rnd = %i\n\n", rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("d1 = %.17g\n\n", d1); flint_printf("d2 = %.17g\n\n", d2); flint_printf("r1 = "); arf_print(r1); flint_printf("\n\n"); flint_printf("r2 = "); arf_print(r2); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(r1); arf_clear(r2); mpfr_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-get_fmpz.c000066400000000000000000000115731417376376500163430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("get_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, x2; fmpz_t z, z2, e; int ret1, ret2; arf_init(x); arf_init(x2); fmpz_init(z); fmpz_init(z2); fmpz_init(e); arf_randtest(x, state, 2 + n_randint(state, 1000), 10); fmpz_randtest(z, state, 1 + n_randint(state, 1000)); fmpz_randtest(z2, state, 1 + n_randint(state, 1000)); fmpz_randtest(e, state, 1 + n_randint(state, 200)); arf_mul_2exp_fmpz(x2, x, e); ret1 = arf_get_fmpz(z, x, ARF_RND_DOWN); ret2 = arf_get_fmpz_fixed_fmpz(z2, x2, e); if (!fmpz_equal(z, z2) || (ret1 != ret2)) { flint_printf("FAIL (fixed_fmpz)\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("x2 = "); arf_print(x2); flint_printf("\n\n"); flint_printf("z = "); fmpz_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpz_print(z2); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); arf_clear(x2); fmpz_clear(z); fmpz_clear(z2); fmpz_clear(e); } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, x2; fmpz_t z, z2; slong e; int ret1, ret2; arf_init(x); arf_init(x2); fmpz_init(z); fmpz_init(z2); arf_randtest(x, state, 2 + n_randint(state, 1000), 10); fmpz_randtest(z, state, 1 + n_randint(state, 1000)); fmpz_randtest(z2, state, 1 + n_randint(state, 1000)); e = n_randtest(state); arf_mul_2exp_si(x2, x, e); ret1 = arf_get_fmpz(z, x, ARF_RND_DOWN); ret2 = arf_get_fmpz_fixed_si(z2, x2, e); if (!fmpz_equal(z, z2) || (ret1 != ret2)) { flint_printf("FAIL (fixed_si)\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("x2 = "); arf_print(x2); flint_printf("\n\n"); flint_printf("z = "); fmpz_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpz_print(z2); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); arf_clear(x2); fmpz_clear(z); fmpz_clear(z2); } for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { slong bits; arf_t x; mpfr_t y; fmpz_t z, z2; mpz_t w; int ret1, ret2; bits = 2 + n_randint(state, 1000); arf_init(x); mpfr_init2(y, bits); fmpz_init(z); fmpz_init(z2); mpz_init(w); arf_randtest(x, state, bits, 10); fmpz_randtest(z, state, 1 + n_randint(state, 1000)); arf_get_mpfr(y, x, MPFR_RNDN); switch (n_randint(state, 5)) { case 0: ret1 = arf_get_fmpz(z, x, ARF_RND_FLOOR); ret2 = mpfr_get_z(w, y, MPFR_RNDD); break; case 1: ret1 = arf_get_fmpz(z, x, ARF_RND_CEIL); ret2 = mpfr_get_z(w, y, MPFR_RNDU); break; case 2: ret1 = arf_get_fmpz(z, x, ARF_RND_DOWN); ret2 = mpfr_get_z(w, y, MPFR_RNDZ); break; case 3: ret1 = arf_get_fmpz(z, x, ARF_RND_UP); ret2 = mpfr_get_z(w, y, MPFR_RNDA); break; default: ret1 = arf_get_fmpz(z, x, ARF_RND_NEAR); ret2 = mpfr_get_z(w, y, MPFR_RNDN); break; } fmpz_set_mpz(z2, w); if (!fmpz_equal(z, z2) || (ret1 != (ret2 != 0))) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpz_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpz_print(z2); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); mpfr_clear(y); fmpz_clear(z); fmpz_clear(z2); mpz_clear(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-get_mpfr.c000066400000000000000000000066071417376376500163350ustar00rootroot00000000000000/* Copyright (C) 2012, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mpfr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits; arf_t x, z; mpfr_t y; bits = 2 + n_randint(state, 200); arf_init(x); arf_init(z); mpfr_init2(y, bits); arf_randtest_special(x, state, bits, 10); arf_get_mpfr(y, x, MPFR_RNDN); arf_set_mpfr(z, y); if (!arf_equal(x, z)) { flint_printf("FAIL\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(z); mpfr_clear(y); } /* test set_mpfr out of range */ { arf_t x, z; mpfr_t y; fmpz_t e; int r; fmpz_init(e); arf_init(x); arf_init(z); mpfr_init2(y, 53); fmpz_one(e); fmpz_mul_2exp(e, e, 100); arf_set_si(x, 1); arf_mul_2exp_fmpz(x, x, e); r = arf_get_mpfr(y, x, MPFR_RNDN); arf_set_mpfr(x, y); if (!mpfr_inf_p(y) || mpfr_sgn(y) <= 0 || !mpfr_overflow_p()) { flint_printf("expected +inf with overflow\n\n"); arf_print(z); flint_printf("\n\n"); flint_printf("r = %d \n\n", r); flint_abort(); } mpfr_clear_flags(); arf_set_si(x, -1); arf_mul_2exp_fmpz(x, x, e); r = arf_get_mpfr(y, x, MPFR_RNDN); arf_set_mpfr(x, y); if (!mpfr_inf_p(y) || mpfr_sgn(y) >= 0 || !mpfr_overflow_p()) { flint_printf("expected -inf with overflow\n\n"); arf_print(z); flint_printf("\n\n"); flint_printf("r = %d \n\n", r); flint_abort(); } mpfr_clear_flags(); fmpz_neg(e, e); arf_set_si(x, 1); arf_mul_2exp_fmpz(x, x, e); r = arf_get_mpfr(y, x, MPFR_RNDN); arf_set_mpfr(x, y); if (!mpfr_zero_p(y) || mpfr_signbit(y) || !mpfr_underflow_p()) { flint_printf("expected +0 with underflow\n\n"); arf_print(z); flint_printf("\n\n"); flint_printf("r = %d \n\n", r); flint_abort(); } mpfr_clear_flags(); arf_set_si(x, -1); arf_mul_2exp_fmpz(x, x, e); r = arf_get_mpfr(y, x, MPFR_RNDN); arf_set_mpfr(x, y); if (!mpfr_zero_p(y) || !mpfr_signbit(y) || !mpfr_underflow_p()) { flint_printf("expected -0 with underflow\n\n"); arf_print(z); flint_printf("\n\n"); flint_printf("r = %d \n\n", r); flint_abort(); } mpfr_clear_flags(); arf_clear(x); arf_clear(z); mpfr_clear(y); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-get_str.c000066400000000000000000000032151417376376500161710ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "arf.h" #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("get_str...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x; arb_t y; char *s1, * s2; slong d; arf_init(x); arb_init(y); arf_randtest_special(x, state, 2 + n_randint(state, 200), 2 + n_randint(state, 100)); arb_set_arf(y, x); d = 1 + n_randint(state, 200); s1 = arf_get_str(x, d); s2 = arb_get_str(y, d, ARB_STR_NO_RADIUS); if ((arf_is_pos_inf(x) && strcmp(s1, "+inf")) || (arf_is_neg_inf(x) && strcmp(s1, "-inf")) || (arf_is_nan(x) && strcmp(s1, "nan")) || (arf_is_finite(x) && strcmp(s1, s2))) { flint_printf("FAIL\n"); arf_print(x); flint_printf("\n"); arb_print(y); flint_printf("\n"); flint_printf("%s\n", s1); flint_printf("%s\n", s2); flint_abort(); } flint_free(s1); flint_free(s2); arf_clear(x); arb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-is_int_2exp_si.c000066400000000000000000000050601417376376500174400ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("is_int_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y; fmpz_t t; slong e; int res1, res2; arf_init(x); arf_init(y); fmpz_init(t); arf_randtest_special(x, state, 2000, 100); e = n_randtest(state); arf_mul_2exp_si(y, x, e); res1 = arf_is_int(x); res2 = arf_is_int_2exp_si(y, e); if (res1 != res2) { flint_printf("FAIL! (1)\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("res1 = %d, res2 = %d\n\n", res1, res2); flint_abort(); } if (res1) { if (n_randint(state, 2)) arf_floor(y, x); else arf_ceil(y, x); if (!arf_equal(x, y) || !arf_is_finite(x)) { flint_printf("FAIL! (2)\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("res1 = %d\n\n", res1); flint_abort(); } } if (arf_is_finite(x) && !arf_is_zero(x)) { arf_bot(t, x); fmpz_neg(t, t); arf_mul_2exp_fmpz(x, x, t); res1 = arf_is_int(x); arf_mul_2exp_si(y, x, -1); res2 = arf_is_int(y); if (!arf_is_int(x) || arf_is_int(y)) { flint_printf("FAIL! (3)\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("res1 = %d, res2 = %d\n\n", res1, res2); flint_abort(); } } arf_clear(x); arf_clear(y); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-mul.c000066400000000000000000000132631417376376500153230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (rnd == ARF_RND_NEAR) { arf_mul(z, x, y, ARF_PREC_EXACT, rnd); return arf_set_round(z, z, prec, rnd); } else { fmpr_t a, b; slong r; fmpr_init(a); fmpr_init(b); arf_get_fmpr(a, x); arf_get_fmpr(b, y); r = fmpr_mul_naive(a, a, b, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); fmpr_clear(b); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); prec = 2 + n_randint(state, 2000); if (n_randint(state, 50) == 0) prec = ARF_PREC_EXACT; switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 5)) { case 0: r1 = arf_mul(z, x, y, prec, rnd); r2 = arf_mul_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_mul(z, x, x, prec, rnd); r2 = arf_mul_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_mul_naive(v, x, x, prec, rnd); r1 = arf_mul(x, x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_mul_naive(v, x, y, prec, rnd); r1 = arf_mul(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_mul_naive(v, x, y, prec, rnd); r1 = arf_mul(x, y, x, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-mul_fmpz.c000066400000000000000000000065061417376376500163610ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_mul_fmpz_naive(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_fmpz(t, y); r = arf_mul(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; fmpz_t y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); fmpz_init(y); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); fmpz_randtest(y, state, 2000); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10)) prec = ARF_PREC_EXACT; switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_mul_fmpz(z, x, y, prec, rnd); r2 = arf_mul_fmpz_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_mul_fmpz_naive(v, x, y, prec, rnd); r1 = arf_mul_fmpz(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); fmpz_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-mul_si.c000066400000000000000000000064611417376376500160200ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/long_extras.h" int arf_mul_si_naive(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_si(t, y); r = arf_mul(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); y = z_randtest(state); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0) prec = ARF_PREC_EXACT; switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_mul_si(z, x, y, prec, rnd); r2 = arf_mul_si_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_mul_si_naive(v, x, y, prec, rnd); r1 = arf_mul_si(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-mul_ui.c000066400000000000000000000064621417376376500160230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/ulong_extras.h" int arf_mul_ui_naive(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_ui(t, y); r = arf_mul(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; ulong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); y = n_randtest(state); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0) prec = ARF_PREC_EXACT; switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_mul_ui(z, x, y, prec, rnd); r2 = arf_mul_ui_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_mul_ui_naive(v, x, y, prec, rnd); r1 = arf_mul_ui(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-mul_via_mpfr.c000066400000000000000000000133511417376376500172040ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (rnd == ARF_RND_NEAR) { arf_mul(z, x, y, ARF_PREC_EXACT, rnd); return arf_set_round(z, z, prec, rnd); } else { fmpr_t a, b; slong r; fmpr_init(a); fmpr_init(b); arf_get_fmpr(a, x); arf_get_fmpr(b, y); r = fmpr_mul_naive(a, a, b, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); fmpr_clear(b); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul_via_mpfr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); prec = 2 + n_randint(state, 2000); if (n_randint(state, 50) == 0) prec = ARF_PREC_EXACT; switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 5)) { case 0: r1 = arf_mul_via_mpfr(z, x, y, prec, rnd); r2 = arf_mul_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_mul_via_mpfr(z, x, x, prec, rnd); r2 = arf_mul_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_mul_naive(v, x, x, prec, rnd); r1 = arf_mul_via_mpfr(x, x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_mul_naive(v, x, y, prec, rnd); r1 = arf_mul_via_mpfr(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_mul_naive(v, x, y, prec, rnd); r1 = arf_mul_via_mpfr(x, y, x, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-neg_round.c000066400000000000000000000102751417376376500165060ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("neg_round...."); fflush(stdout); flint_randinit(state); { arf_t x, y, z; arf_init(x); arf_init(y); arf_init(z); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits1, bits2; int ret1, ret2; mpfr_t g1, g2; fmpz_t e; arf_rnd_t rnd; bits1 = 1 + n_randint(state, 1000); bits2 = 2 + n_randint(state, 1000); if (n_randint(state, 100) == 0) bits2 = ARF_PREC_EXACT; switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } fmpz_init(e); mpfr_init2(g1, FLINT_MAX(2, bits1)); mpfr_init2(g2, FLINT_MIN(bits2, 10000)); if (n_randint(state, 100) == 0) { arf_clear(x); arf_clear(y); arf_clear(z); arf_init(x); arf_init(y); arf_init(z); } /* dirty output variables */ if (n_randint(state, 2)) { arf_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arf_randtest_special(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); } arf_randtest_special(x, state, bits1, 1 + n_randint(state, 10)); arf_get_mpfr(g1, x, MPFR_RNDD); /* exact */ /* test large exponents */ if (n_randint(state, 4) == 0) fmpz_randtest(e, state, 1 + n_randint(state, 100)); if (!arf_is_special(x)) fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e); ret1 = arf_neg_round(y, x, bits2, rnd); ret2 = mpfr_neg(g2, g1, arf_rnd_to_mpfr(rnd)); arf_set_mpfr(z, g2); if (!arf_is_special(y)) fmpz_sub(ARF_EXPREF(y), ARF_EXPREF(y), e); if (!arf_equal(y, z) || ((ret1 == ARF_RESULT_EXACT) != (ret2 == 0))) { flint_printf("FAIL\n\n"); flint_printf("bits1: %wd\n", bits1); flint_printf("bits2: %wd\n", bits2); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } if (!arf_is_special(x)) fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e); ret1 = arf_neg_round(y, x, bits2, rnd); arf_set(z, x); ret2 = arf_neg_round(z, z, bits2, rnd); if (!arf_equal(y, z) || ret1 != ret2) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("bits1: %wd\n", bits1); flint_printf("bits2: %wd\n", bits2); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } mpfr_clear(g1); mpfr_clear(g2); fmpz_clear(e); } arf_clear(x); arf_clear(y); arf_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-root.c000066400000000000000000000063651417376376500155160ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_root_naive(arf_t z, const arf_t x, ulong k, slong prec, arf_rnd_t rnd) { fmpr_t a; slong r; fmpr_init(a); arf_get_fmpr(a, x); r = fmpr_root(a, a, k, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("root...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong prec, r1, r2; ulong k; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 10; iter2++) { arf_randtest_special(x, state, 2000, 100); prec = 2 + n_randint(state, 2000); k = n_randint(state, 50); if (n_randint(state, 20) == 0) arf_mul(x, x, x, prec, ARF_RND_DOWN); else if (n_randint(state, 20) == 0) arf_mul(x, x, x, prec, ARF_RND_UP); switch (n_randint(state, 4)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; default: rnd = ARF_RND_CEIL; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_root(z, x, k, prec, rnd); r2 = arf_root_naive(v, x, k, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("k = %wu, prec = %wd, rnd = %d\n\n", k, prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_root_naive(v, x, k, prec, rnd); r1 = arf_root(x, x, k, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("k = %wu, prec = %wd, rnd = %d\n\n", k, prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-rsqrt.c000066400000000000000000000057211417376376500157010ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_rsqrt_naive(arf_t z, const arf_t x, slong prec, arf_rnd_t rnd) { fmpr_t a; slong r; fmpr_init(a); arf_get_fmpr(a, x); r = fmpr_rsqrt(a, a, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("rsqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 4)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; default: rnd = ARF_RND_CEIL; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_rsqrt(z, x, prec, rnd); r2 = arf_rsqrt_naive(v, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_rsqrt_naive(v, x, prec, rnd); r1 = arf_rsqrt(x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_d.c000066400000000000000000000026031417376376500156200ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_d...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { double x; arf_t y, z; mpfr_t m; arf_init(y); arf_init(z); mpfr_init2(m, 53); x = d_randtest_special(state, -1200, 1200); arf_set_d(y, x); mpfr_set_d(m, x, MPFR_RNDN); arf_set_mpfr(z, m); if (!arf_equal(y, z) || !arf_equal_d(y, x)) { flint_printf("FAIL:\n\n"); flint_printf("x = %.17g\n\n", x); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_abort(); } arf_clear(y); arf_clear(z); mpfr_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_fmpq.c000066400000000000000000000030231417376376500163350ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_fmpq...."); fflush(stdout); flint_randinit(state); /* test exact roundtrip R -> Q -> R */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits, res; arf_t x, z; fmpq_t y; bits = 2 + n_randint(state, 200); arf_init(x); arf_init(z); fmpq_init(y); arf_randtest(x, state, bits, 10); arf_randtest(z, state, bits, 10); arf_get_fmpq(y, x); res = arf_set_fmpq(z, y, bits, ARF_RND_DOWN); if (!arf_equal(x, z) || res != 0) { flint_printf("FAIL\n\n"); flint_printf("bits: %wd\n", bits); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(z); fmpq_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_fmpr.c000066400000000000000000000047271417376376500163520ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_fmpr...."); fflush(stdout); flint_randinit(state); /* test exact roundtrip R -> Q -> R */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits; arf_t x, z; fmpr_t y; bits = 2 + n_randint(state, 1000); arf_init(x); arf_init(z); fmpr_init(y); arf_randtest_special(x, state, bits, 1 + n_randint(state, 100)); arf_randtest_special(z, state, bits, 1 + n_randint(state, 100)); arf_get_fmpr(y, x); arf_set_fmpr(z, y); if (!arf_equal(x, z)) { flint_printf("FAIL\n\n"); flint_printf("bits: %wd\n", bits); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(z); fmpr_clear(y); } /* test exact roundtrip Q -> R -> Q */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, z; arf_t y; bits = 2 + n_randint(state, 1000); fmpr_init(x); fmpr_init(z); arf_init(y); fmpr_randtest_special(x, state, bits, 1 + n_randint(state, 100)); fmpr_randtest_special(z, state, bits, 1 + n_randint(state, 100)); arf_set_fmpr(y, x); arf_get_fmpr(z, y); if (!fmpr_equal(x, z)) { flint_printf("FAIL (2)\n\n"); flint_printf("bits: %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_fmpz_2exp.c000066400000000000000000000032411417376376500173060ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_fmpz_2exp...."); fflush(stdout); flint_randinit(state); /* test exact roundtrip R -> Q -> R */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits; arf_t x, z; fmpz_t y, e; bits = 2 + n_randint(state, 200); arf_init(x); arf_init(z); fmpz_init(y); fmpz_init(e); arf_randtest(x, state, bits, 1 + n_randint(state, 100)); arf_randtest(z, state, bits, 1 + n_randint(state, 100)); arf_get_fmpz_2exp(y, e, x); arf_set_fmpz_2exp(z, y, e); if (!arf_equal(x, z)) { flint_printf("FAIL\n\n"); flint_printf("bits: %wd\n", bits); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_abort(); } arf_clear(x); arf_clear(z); fmpz_clear(y); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_round.c000066400000000000000000000102751417376376500165300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round...."); fflush(stdout); flint_randinit(state); { arf_t x, y, z; arf_init(x); arf_init(y); arf_init(z); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits1, bits2; int ret1, ret2; mpfr_t g1, g2; fmpz_t e; arf_rnd_t rnd; bits1 = 1 + n_randint(state, 1000); bits2 = 2 + n_randint(state, 1000); if (n_randint(state, 100) == 0) bits2 = ARF_PREC_EXACT; switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } fmpz_init(e); mpfr_init2(g1, FLINT_MAX(2, bits1)); mpfr_init2(g2, FLINT_MIN(bits2, 10000)); if (n_randint(state, 100) == 0) { arf_clear(x); arf_clear(y); arf_clear(z); arf_init(x); arf_init(y); arf_init(z); } /* dirty output variables */ if (n_randint(state, 2)) { arf_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arf_randtest_special(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); } arf_randtest_special(x, state, bits1, 1 + n_randint(state, 10)); arf_get_mpfr(g1, x, MPFR_RNDD); /* exact */ /* test large exponents */ if (n_randint(state, 4) == 0) fmpz_randtest(e, state, 1 + n_randint(state, 100)); if (!arf_is_special(x)) fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e); ret1 = arf_set_round(y, x, bits2, rnd); ret2 = mpfr_set(g2, g1, arf_rnd_to_mpfr(rnd)); arf_set_mpfr(z, g2); if (!arf_is_special(y)) fmpz_sub(ARF_EXPREF(y), ARF_EXPREF(y), e); if (!arf_equal(y, z) || ((ret1 == ARF_RESULT_EXACT) != (ret2 == 0))) { flint_printf("FAIL\n\n"); flint_printf("bits1: %wd\n", bits1); flint_printf("bits2: %wd\n", bits2); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } if (!arf_is_special(x)) fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e); ret1 = arf_set_round(y, x, bits2, rnd); arf_set(z, x); ret2 = arf_set_round(z, z, bits2, rnd); if (!arf_equal(y, z) || ret1 != ret2) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("bits1: %wd\n", bits1); flint_printf("bits2: %wd\n", bits2); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } mpfr_clear(g1); mpfr_clear(g2); fmpz_clear(e); } arf_clear(x); arf_clear(y); arf_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_round_fmpz.c000066400000000000000000000060131417376376500175570ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round_fmpz...."); fflush(stdout); flint_randinit(state); { arf_t x, y; arf_init(x); arf_init(y); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits1, bits2; int ret1, ret2; fmpz_t a; mpz_t b; mpfr_t g; arf_rnd_t rnd; bits1 = 1 + n_randint(state, 1000); bits2 = 2 + n_randint(state, 1000); if (n_randint(state, 100) == 0) bits2 = ARF_PREC_EXACT; fmpz_init(a); mpz_init(b); mpfr_init2(g, FLINT_MIN(bits2, 10000)); if (n_randint(state, 100) == 0) { arf_clear(x); arf_clear(y); arf_init(x); arf_init(y); } /* dirty output variables */ if (n_randint(state, 2)) { arf_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arf_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); } fmpz_randtest(a, state, bits1); fmpz_get_mpz(b, a); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } ret1 = arf_set_round_fmpz(x, a, bits2, rnd); ret2 = mpfr_set_z(g, b, arf_rnd_to_mpfr(rnd)); arf_set_mpfr(y, g); arf_equal(x, y); if (!arf_equal(x, y) || ((ret1 == ARF_RESULT_EXACT) != (ret2 == 0))) { flint_printf("FAIL\n\n"); flint_printf("bits1: %wd\n", bits1); flint_printf("bits2: %wd\n", bits2); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } fmpz_clear(a); mpz_clear(b); mpfr_clear(g); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_round_mpz.c000066400000000000000000000060111417376376500174070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round_mpz...."); fflush(stdout); flint_randinit(state); { arf_t x, y; arf_init(x); arf_init(y); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits1, bits2; int ret1, ret2; fmpz_t a; mpz_t b; mpfr_t g; arf_rnd_t rnd; bits1 = 1 + n_randint(state, 1000); bits2 = 2 + n_randint(state, 1000); if (n_randint(state, 100) == 0) bits2 = ARF_PREC_EXACT; fmpz_init(a); mpz_init(b); mpfr_init2(g, FLINT_MIN(bits2, 10000)); if (n_randint(state, 100) == 0) { arf_clear(x); arf_clear(y); arf_init(x); arf_init(y); } /* dirty output variables */ if (n_randint(state, 2)) { arf_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); arf_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); } fmpz_randtest(a, state, bits1); fmpz_get_mpz(b, a); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } ret1 = arf_set_round_mpz(x, b, bits2, rnd); ret2 = mpfr_set_z(g, b, arf_rnd_to_mpfr(rnd)); arf_set_mpfr(y, g); arf_equal(x, y); if (!arf_equal(x, y) || ((ret1 == ARF_RESULT_EXACT) != (ret2 == 0))) { flint_printf("FAIL\n\n"); flint_printf("bits1: %wd\n", bits1); flint_printf("bits2: %wd\n", bits2); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } fmpz_clear(a); mpz_clear(b); mpfr_clear(g); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_round_ui.c000066400000000000000000000043421417376376500172230ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { arf_t x, y; slong prec, fix1; int ret1, ret2; mp_limb_t t; arf_rnd_t rnd; prec = 2 + n_randint(state, 1000); arf_init(x); arf_init(y); arf_randtest_special(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arf_randtest_special(y, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); t = n_randtest(state); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } if (t == 0) { arf_zero(x); ret1 = 0; } else { ret1 = _arf_set_round_mpn(x, &fix1, &t, 1, 0, prec, rnd); fmpz_set_si(ARF_EXPREF(x), FLINT_BITS + fix1); } ret2 = arf_set_round_ui(y, t, prec, rnd); if (!arf_equal(x, y) || (ret1 != ret2) || (ret2 == 0 && !arf_equal_ui(y, t))) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd", prec); flint_printf("\n\n"); flint_printf("t = %wu\n\n", t); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-set_round_uiui.c000066400000000000000000000050471417376376500175640ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round_uiui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { arf_t x, y; slong prec, fix1, fix2; int ret1, ret2, sgnbit; mp_limb_t t[2]; arf_rnd_t rnd; prec = 2 + n_randint(state, 1000); arf_init(x); arf_init(y); arf_randtest_special(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); arf_randtest_special(y, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100)); do { t[0] = n_randtest(state); t[1] = n_randtest(state); } while (t[0] == 0 && t[1] == 0); sgnbit = n_randint(state, 2); switch (n_randint(state, 10)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } if (t[1] != 0) { ret1 = _arf_set_round_mpn(x, &fix1, t, 2, sgnbit, prec, rnd); fmpz_set_si(ARF_EXPREF(x), 2 * FLINT_BITS + fix1); } else { ret1 = _arf_set_round_mpn(x, &fix1, t, 1, sgnbit, prec, rnd); fmpz_set_si(ARF_EXPREF(x), FLINT_BITS + fix1); } ret2 = _arf_set_round_uiui(y, &fix2, t[1], t[0], sgnbit, prec, rnd); fmpz_set_si(ARF_EXPREF(y), 2 * FLINT_BITS + fix2); if (!arf_equal(x, y) || (ret1 != ret2)) { flint_printf("FAIL\n\n"); flint_printf("prec = %wd", prec); flint_printf("\n\n"); flint_printf("hi = %wu, lo = %wu\n\n", t[1], t[0]); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2); flint_abort(); } arf_clear(x); arf_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-sosq.c000066400000000000000000000131561417376376500155140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_sosq_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul(t, x, x, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(z, y, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_add(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("sosq...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); arf_randtest_special(z, state, 2000, 100); arf_randtest_special(v, state, 2000, 100); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(y)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 5)) { case 0: r1 = arf_sosq(z, x, y, prec, rnd); r2 = arf_sosq_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_sosq(z, x, x, prec, rnd); r2 = arf_sosq_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_sosq_naive(v, x, y, prec, rnd); r1 = arf_sosq(x, x, y, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_sosq_naive(v, x, y, prec, rnd); r1 = arf_sosq(y, x, y, prec, rnd); if (!arf_equal(v, y) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_sosq_naive(v, x, x, prec, rnd); r1 = arf_sosq(x, x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-sqrt.c000066400000000000000000000062201417376376500155120ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_sqrt_naive(arf_t z, const arf_t x, slong prec, arf_rnd_t rnd) { fmpr_t a; slong r; fmpr_init(a); arf_get_fmpr(a, x); r = fmpr_sqrt(a, a, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("sqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); prec = 2 + n_randint(state, 2000); if (n_randint(state, 20) == 0) arf_mul(x, x, x, prec, ARF_RND_DOWN); else if (n_randint(state, 20) == 0) arf_mul(x, x, x, prec, ARF_RND_UP); switch (n_randint(state, 4)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; default: rnd = ARF_RND_CEIL; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_sqrt(z, x, prec, rnd); r2 = arf_sqrt_naive(v, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_sqrt_naive(v, x, prec, rnd); r1 = arf_sqrt(x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-sub.c000066400000000000000000000143571417376376500153240ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_sub_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (rnd == ARF_RND_NEAR) { arf_sub(z, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); return arf_set_round(z, z, prec, rnd); } else { fmpr_t a, b; slong r; fmpr_init(a); fmpr_init(b); arf_get_fmpr(a, x); arf_get_fmpr(b, y); r = fmpr_sub(a, a, b, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); fmpr_clear(b); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } } int main() { slong iter, iter2; flint_rand_t state; flint_printf("sub...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; fmpz_t t; arf_init(x); arf_init(y); arf_init(z); arf_init(v); fmpz_init(t); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } rnd = ARF_RND_DOWN; if (arf_is_normal(x) && arf_is_normal(y)) { fmpz_sub(t, ARF_EXPREF(x), ARF_EXPREF(y)); /* if not too far apart, sometimes test exact addition */ if (fmpz_bits(t) < 10) { if (n_randint(state, 10) == 0) prec = ARF_PREC_EXACT; } else if (rnd == ARF_RND_NEAR) { /* large shift not supported in add_naive */ rnd = ARF_RND_DOWN; } } switch (n_randint(state, 5)) { case 0: r1 = arf_sub(z, x, y, prec, rnd); r2 = arf_sub_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_sub(z, x, x, prec, rnd); r2 = arf_sub_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_sub_naive(v, x, x, prec, rnd); r1 = arf_sub(x, x, x, prec, rnd); if (!arf_equal(v, x) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_sub_naive(v, x, y, prec, rnd); r1 = arf_sub(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_sub_naive(v, y, x, prec, rnd); r1 = arf_sub(x, y, x, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); fmpz_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-sub_fmpz.c000066400000000000000000000066101417376376500163510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_sub_fmpz_naive(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_fmpz(t, y); r = arf_sub(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("sub_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; fmpz_t y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); fmpz_init(y); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); fmpz_randtest(y, state, 2000); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_sub_fmpz(z, x, y, prec, rnd); r2 = arf_sub_fmpz_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_sub_fmpz_naive(v, x, y, prec, rnd); r1 = arf_sub_fmpz(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); fmpz_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-sub_si.c000066400000000000000000000065561417376376500160210ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/long_extras.h" int arf_sub_si_naive(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_si(t, y); r = arf_sub(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("sub_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); y = z_randtest(state); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_sub_si(z, x, y, prec, rnd); r2 = arf_sub_si_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_sub_si_naive(v, x, y, prec, rnd); r1 = arf_sub_si(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-sub_ui.c000066400000000000000000000065571417376376500160240ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/ulong_extras.h" int arf_sub_ui_naive(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; int r; arf_init(t); arf_set_ui(t, y); r = arf_sub(z, x, t, prec, rnd); arf_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("sub_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arf_t x, z, v; ulong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 10); y = n_randtest(state); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_sub_ui(z, x, y, prec, rnd); r2 = arf_sub_ui_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_sub_ui_naive(v, x, y, prec, rnd); r1 = arf_sub_ui(x, x, y, prec, rnd); if (!arf_equal(x, v) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); flint_printf("%wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-submul.c000066400000000000000000000131531417376376500160330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_submul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_sub(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("submul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, y, z, v; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); arf_randtest_special(y, state, 2000, 100); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(y)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 5)) { case 0: r1 = arf_submul(z, x, y, prec, rnd); r2 = arf_submul_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = arf_submul(z, x, x, prec, rnd); r2 = arf_submul_naive(v, x, x, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = arf_submul_naive(v, v, v, prec, rnd); r1 = arf_submul(z, z, z, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = arf_submul_naive(v, v, y, prec, rnd); r1 = arf_submul(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = "); arf_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_submul_naive(v, x, v, prec, rnd); r1 = arf_submul(z, x, z, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-submul_fmpz.c000066400000000000000000000071451417376376500170730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_submul_fmpz_naive(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul_fmpz(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_sub(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("submul_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; fmpz_t y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); fmpz_init(y); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); fmpz_randtest(y, state, 2000); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_submul_fmpz(z, x, y, prec, rnd); r2 = arf_submul_fmpz_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); arf_debug(z); flint_printf("\n\n"); flint_printf("v = "); arf_debug(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_submul_fmpz_naive(v, v, y, prec, rnd); r1 = arf_submul_fmpz(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); fmpz_clear(y); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-submul_si.c000066400000000000000000000070471417376376500165330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "flint/long_extras.h" int arf_submul_si_naive(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul_si(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_sub(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("submul_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; slong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); y = z_randtest(state); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_submul_si(z, x, y, prec, rnd); r2 = arf_submul_si_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = %wd", y); flint_printf("\n\n"); flint_printf("z = "); arf_debug(z); flint_printf("\n\n"); flint_printf("v = "); arf_debug(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_submul_si_naive(v, v, y, prec, rnd); r1 = arf_submul_si(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = %wd", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-submul_ui.c000066400000000000000000000070101417376376500165230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int arf_submul_ui_naive(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) { arf_t t; int inexact; arf_init(t); arf_mul_ui(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); inexact = arf_sub(z, z, t, prec, rnd); arf_clear(t); return inexact; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("submul_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arf_t x, z, v; ulong y; slong prec, r1, r2; arf_rnd_t rnd; arf_init(x); arf_init(z); arf_init(v); for (iter2 = 0; iter2 < 100; iter2++) { arf_randtest_special(x, state, 2000, 100); y = n_randtest(state); arf_randtest_special(z, state, 2000, 100); arf_set(v, z); prec = 2 + n_randint(state, 2000); if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10 && fmpz_bits(ARF_EXPREF(z)) < 10) { prec = ARF_PREC_EXACT; } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } switch (n_randint(state, 2)) { case 0: r1 = arf_submul_ui(z, x, y, prec, rnd); r2 = arf_submul_ui_naive(v, x, y, prec, rnd); if (!arf_equal(z, v) || r1 != r2) { flint_printf("FAIL!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("x = "); arf_print(x); flint_printf("\n\n"); flint_printf("y = %wu", y); flint_printf("\n\n"); flint_printf("z = "); arf_debug(z); flint_printf("\n\n"); flint_printf("v = "); arf_debug(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = arf_submul_ui_naive(v, v, y, prec, rnd); r1 = arf_submul_ui(z, z, y, prec, rnd); if (!arf_equal(v, z) || r1 != r2) { flint_printf("FAIL (aliasing)!\n"); flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd); flint_printf("y = %wu", y); flint_printf("\n\n"); flint_printf("v = "); arf_print(v); flint_printf("\n\n"); flint_printf("z = "); arf_print(z); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } arf_clear(x); arf_clear(z); arf_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/test/t-sum.c000066400000000000000000000071501417376376500153300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" int main() { slong iter; flint_rand_t state; flint_printf("sum...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { slong i, len, prec, bits, expbits; int res1, res2; arf_t s1, s2, s3, err; mag_t err_bound; arf_struct terms[20]; arf_rnd_t rnd; len = n_randint(state, 20); bits = 2 + n_randint(state, 1000); prec = 2 + n_randint(state, 1000); expbits = n_randint(state, 14); arf_init(s1); arf_init(s2); arf_init(s3); arf_init(err); mag_init(err_bound); for (i = 0; i < len; i++) { arf_init(terms + i); arf_randtest_special(terms + i, state, bits, expbits); } switch (n_randint(state, 5)) { case 0: rnd = ARF_RND_DOWN; break; case 1: rnd = ARF_RND_UP; break; case 2: rnd = ARF_RND_FLOOR; break; case 3: rnd = ARF_RND_CEIL; break; default: rnd = ARF_RND_NEAR; break; } res1 = arf_sum(s1, terms, len, prec, rnd); arf_zero(s2); for (i = 0; i < len; i++) arf_add(s2, s2, terms + i, ARF_PREC_EXACT, ARF_RND_DOWN); res2 = arf_set_round(s3, s2, prec, rnd); if (!arf_equal(s1, s3) || res1 != res2) { flint_printf("FAIL (%wd)\n\n", iter); flint_printf("prec = %wd\n\n", prec); for (i = 0; i < len; i++) { flint_printf("terms[%wd] = ", i); arf_print(terms + i); flint_printf("\n\n"); } flint_printf("s1 = "); arf_print(s1); flint_printf("\n\n"); flint_printf("s2 = "); arf_print(s2); flint_printf("\n\n"); flint_printf("s3 = "); arf_print(s3); flint_printf("\n\n"); flint_printf("res1 = %d, res2 = %d\n\n", res1, res2); flint_abort(); } arf_sub(err, s1, s2, ARF_PREC_EXACT, ARF_RND_DOWN); arf_abs(err, err); if (res1) arf_mag_set_ulp(err_bound, s1, prec); else mag_zero(err_bound); if (arf_cmpabs_mag(err, err_bound) > 0) { flint_printf("FAIL (error bound)!\n"); flint_printf("prec = %wd\n\n", prec); for (i = 0; i < len; i++) { flint_printf("terms[%wd] = ", i); arf_print(terms + i); flint_printf("\n\n"); } flint_printf("s1 = "); arf_print(s1); flint_printf("\n\n"); flint_printf("s2 = "); arf_print(s2); flint_printf("\n\n"); flint_printf("s3 = "); arf_print(s3); flint_printf("\n\n"); flint_printf("error: "); arf_print(err); flint_printf("\n\n"); flint_printf("error bound: "); mag_print(err_bound); flint_printf("\n\n"); flint_printf("res1 = %d, res2 = %d\n\n", res1, res2); flint_abort(); } arf_clear(s1); arf_clear(s2); arf_clear(s3); arf_clear(err); mag_clear(err_bound); for (i = 0; i < len; i++) arf_clear(terms + i); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/arf/urandom.c000066400000000000000000000014141417376376500147460ustar00rootroot00000000000000/* Copyright (C) 2021 Albin Ahlbäck This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" void arf_urandom(arf_t x, flint_rand_t state, slong bits, arf_rnd_t rnd) { slong prec = bits; fmpz_t n; fmpz_t t; prec += 128; fmpz_init(n); fmpz_one(n); fmpz_mul_2exp(n, n, (ulong) prec); fmpz_init(t); fmpz_randm(t, state, n); arf_set_round_fmpz(x, t, bits, rnd); arf_mul_2exp_si(x, x, -prec); fmpz_clear(n); fmpz_clear(t); } arb-2.22.1/bernoulli.h000066400000000000000000000055051417376376500145360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef BERNOULLI_H #define BERNOULLI_H #include #include "flint/flint.h" #include "flint/fmpz.h" #include "flint/fmpz_vec.h" #include "flint/fmpq.h" #include "flint/arith.h" #include "arb.h" #ifdef __cplusplus extern "C" { #endif extern slong TLS_PREFIX bernoulli_cache_num; extern TLS_PREFIX fmpq * bernoulli_cache; void bernoulli_cache_compute(slong n); /* Crude bound for the bits in d(n) = denom(B_n). By von Staudt-Clausen, d(n) = prod_{p-1 | n} p <= prod_{k | n} 2k <= n^{sigma_0(n)}. We get a more accurate estimate taking the square root of this. Further, at least for sufficiently large n, sigma_0(n) < exp(1.066 log(n) / log(log(n))). */ static __inline__ slong bernoulli_denom_size(slong n) { return 0.5 * 1.4427 * log(n) * pow(n, 1.066 / log(log(n))); } static __inline__ slong bernoulli_zeta_terms(ulong s, slong prec) { slong N; N = pow(2.0, (prec + 1.0) / (s - 1.0)); N += ((N % 2) == 0); return N; } static __inline__ slong bernoulli_power_prec(slong i, ulong s1, slong wp) { slong p = wp - s1 * log(i) * 1.44269504088896341; return FLINT_MAX(p, 10); } /* we should technically add O(log(n)) guard bits, but this is unnecessary in practice since the denominator estimate is quite a bit larger than the true denominators */ static __inline__ slong bernoulli_global_prec(ulong nmax) { return arith_bernoulli_number_size(nmax) + bernoulli_denom_size(nmax); } /* avoid potential numerical problems for very small n */ #define BERNOULLI_REV_MIN 32 typedef struct { slong alloc; slong prec; slong max_power; fmpz * powers; fmpz_t pow_error; arb_t prefactor; arb_t two_pi_squared; ulong n; } bernoulli_rev_struct; typedef bernoulli_rev_struct bernoulli_rev_t[1]; void bernoulli_rev_init(bernoulli_rev_t iter, ulong nmax); void bernoulli_rev_next(fmpz_t numer, fmpz_t denom, bernoulli_rev_t iter); void bernoulli_rev_clear(bernoulli_rev_t iter); #define BERNOULLI_ENSURE_CACHED(n) \ do { \ slong __n = (n); \ if (__n >= bernoulli_cache_num) \ bernoulli_cache_compute(__n + 1); \ } while (0); \ slong bernoulli_bound_2exp_si(ulong n); ulong bernoulli_mod_p_harvey(ulong k, ulong p); void _bernoulli_fmpq_ui_multi_mod(fmpz_t num, fmpz_t den, ulong n, double alpha); void _bernoulli_fmpq_ui_zeta(fmpz_t num, fmpz_t den, ulong n); void _bernoulli_fmpq_ui(fmpz_t num, fmpz_t den, ulong n); void bernoulli_fmpq_ui(fmpq_t b, ulong n); #ifdef __cplusplus } #endif #endif arb-2.22.1/bernoulli/000077500000000000000000000000001417376376500143605ustar00rootroot00000000000000arb-2.22.1/bernoulli/bound_2exp_si.c000066400000000000000000000063361417376376500172740ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" const short bernoulli_bound_tab[256] = { 1, -2, -4, -5, -4, -3, -1, 1, 3, 6, 10, 13, 17, 21, 25, 30, 34, 39, 44, 49, 55, 60, 66, 71, 77, 83, 89, 95, 102, 108, 115, 121, 128, 135, 141, 148, 155, 162, 170, 177, 184, 192, 199, 207, 214, 222, 230, 237, 245, 253, 261, 269, 277, 285, 294, 302, 310, 318, 327, 335, 344, 352, 361, 370, 378, 387, 396, 405, 413, 422, 431, 440, 449, 458, 467, 477, 486, 495, 504, 514, 523, 532, 542, 551, 561, 570, 580, 589, 599, 608, 618, 628, 638, 647, 657, 667, 677, 687, 697, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 849, 859, 870, 880, 890, 901, 911, 922, 932, 943, 953, 964, 975, 985, 996, 1007, 1017, 1028, 1039, 1050, 1061, 1071, 1082, 1093, 1104, 1115, 1126, 1137, 1148, 1159, 1170, 1181, 1192, 1203, 1214, 1225, 1236, 1247, 1258, 1270, 1281, 1292, 1303, 1315, 1326, 1337, 1349, 1360, 1371, 1383, 1394, 1405, 1417, 1428, 1440, 1451, 1463, 1474, 1486, 1497, 1509, 1520, 1532, 1544, 1555, 1567, 1579, 1590, 1602, 1614, 1625, 1637, 1649, 1661, 1672, 1684, 1696, 1708, 1720, 1732, 1743, 1755, 1767, 1779, 1791, 1803, 1815, 1827, 1839, 1851, 1863, 1875, 1887, 1899, 1911, 1923, 1935, 1948, 1960, 1972, 1984, 1996, 2008, 2021, 2033, 2045, 2057, 2070, 2082, 2094, 2106, 2119, 2131, 2143, 2156, 2168, 2180, 2193, 2205, 2218, 2230, 2243, 2255, 2267, 2280, 2292, 2305, 2317, 2330, 2342, 2355, 2368, 2380, 2393, 2405, 2418, 2430, 2443, 2456, 2468, 2481, 2494, 2506, }; #define LOG_PREC 6 /* table of ceil(log(n,2) * M - log_prec * M) for n from M to 2M inclusive where M = 2^LOG_PREC */ const unsigned char log_tab[] = { 0, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 59, 60, 61, 62, 62, 63, 64, 64 }; slong bernoulli_bound_2exp_si(ulong n) { if (n % 2) { if (n == 1) return -WORD(1); else return LONG_MIN; } else if (n < 512) { return bernoulli_bound_tab[n / 2]; } else { /* |B_n| < 4 * n! / (2*pi)^n < 4 * (n+1)^(n+1) e^(-n) / (2*pi)^n */ mp_limb_t l, u, hi, lo; int b, shift; b = FLINT_BIT_COUNT(n + 1); shift = b - (LOG_PREC + 1); /* (n+1) * log_2(n+1) */ u = n + 1; l = log_tab[((u >> shift) + 1) - (1 << LOG_PREC)]; l += (LOG_PREC << LOG_PREC); umul_ppmm(hi, lo, l, u); if (hi || n > (UWORD(1) << (FLINT_BITS - 6))) { flint_printf("bernoulli_bound_2exp_si: n too large\n"); flint_abort(); } l = (lo >> LOG_PREC) + 1; l += shift * u; /* log_2(2*pi*e) > 131 / 32 */ return l + 2 - (131 * n) / 32; } } arb-2.22.1/bernoulli/cache_compute.c000066400000000000000000000036351417376376500173320ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" TLS_PREFIX slong bernoulli_cache_num = 0; TLS_PREFIX fmpq * bernoulli_cache = NULL; void bernoulli_cleanup(void) { slong i; for (i = 0; i < bernoulli_cache_num; i++) fmpq_clear(bernoulli_cache + i); flint_free(bernoulli_cache); bernoulli_cache = NULL; bernoulli_cache_num = 0; } void bernoulli_cache_compute(slong n) { if (bernoulli_cache_num < n) { slong i, new_num; bernoulli_rev_t iter; if (bernoulli_cache_num == 0) { flint_register_cleanup_function(bernoulli_cleanup); } if (n <= 128) new_num = FLINT_MAX(bernoulli_cache_num + 32, n); else new_num = FLINT_MAX(bernoulli_cache_num + 128, n); bernoulli_cache = flint_realloc(bernoulli_cache, new_num * sizeof(fmpq)); for (i = bernoulli_cache_num; i < new_num; i++) fmpq_init(bernoulli_cache + i); if (new_num <= 128) { arith_bernoulli_number_vec(bernoulli_cache, new_num); } else { i = new_num - 1; i -= (i % 2); bernoulli_rev_init(iter, i); for ( ; i >= bernoulli_cache_num; i -= 2) { bernoulli_rev_next(fmpq_numref(bernoulli_cache + i), fmpq_denref(bernoulli_cache + i), iter); } bernoulli_rev_clear(iter); if (new_num > 1) fmpq_set_si(bernoulli_cache + 1, -1, 2); } bernoulli_cache_num = new_num; } } arb-2.22.1/bernoulli/fmpq_ui.c000066400000000000000000000016211417376376500161640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" void _bernoulli_fmpq_ui(fmpz_t num, fmpz_t den, ulong n) { if (n < (ulong) bernoulli_cache_num) { fmpz_set(num, fmpq_numref(bernoulli_cache + n)); fmpz_set(den, fmpq_denref(bernoulli_cache + n)); } else if (n < 18000 || n % 2 == 1) { _bernoulli_fmpq_ui_zeta(num, den, n); } else { _bernoulli_fmpq_ui_multi_mod(num, den, n, -1.0); } } void bernoulli_fmpq_ui(fmpq_t b, ulong n) { _bernoulli_fmpq_ui(fmpq_numref(b), fmpq_denref(b), n); } arb-2.22.1/bernoulli/fmpq_ui_multi_mod.c000066400000000000000000000112761417376376500202440ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" #include "arb.h" #define TIMING 0 #define DEBUG 0 static void _fmpz_crt_combine(fmpz_t r1r2, fmpz_t m1m2, const fmpz_t r1, const fmpz_t m1, const fmpz_t r2, const fmpz_t m2) { fmpz_invmod(m1m2, m1, m2); fmpz_mul(m1m2, m1m2, m1); fmpz_sub(r1r2, r2, r1); fmpz_mul(r1r2, r1r2, m1m2); fmpz_add(r1r2, r1r2, r1); fmpz_mul(m1m2, m1, m2); fmpz_mod(r1r2, r1r2, m1m2); } static void tree_crt(fmpz_t r, fmpz_t m, mp_srcptr residues, mp_srcptr primes, slong len) { if (len == 0) { fmpz_zero(r); fmpz_one(m); } else if (len == 1) { fmpz_set_ui(r, residues[0]); fmpz_set_ui(m, primes[0]); } else { fmpz_t r1, m1, r2, m2; fmpz_init(r1); fmpz_init(m1); fmpz_init(r2); fmpz_init(m2); tree_crt(r1, m1, residues, primes, len / 2); tree_crt(r2, m2, residues + len / 2, primes + len / 2, len - len / 2); _fmpz_crt_combine(r, m, r1, m1, r2, m2); fmpz_clear(r1); fmpz_clear(m1); fmpz_clear(r2); fmpz_clear(m2); } } void _bernoulli_fmpq_ui_multi_mod(fmpz_t num, fmpz_t den, ulong n, double alpha) { slong i, bits, mod_bits, zeta_bits, num_primes; ulong p; mp_ptr primes, residues; mag_t primes_product; fmpz_t M; #if TIMING double t1, t2; #endif if (n < 10 || n % 2 != 0) { _bernoulli_fmpq_ui_zeta(num, den, n); return; } if (alpha < 0) { if (n < 18000) alpha = 0.0; else if (n < 60000) alpha = 0.005 + 3.6e-6 * n; else alpha = FLINT_MIN(0.18 + 0.5e-6 * n, 0.28); } #if TIMING t1 = clock(); #endif arith_bernoulli_number_denom(den, n); bits = arith_bernoulli_number_size(n) + fmpz_bits(den) + 2; mod_bits = bits * alpha; zeta_bits = bits - mod_bits; num_primes = 0; mag_init(primes_product); mag_one(primes_product); for (p = 5; mag_cmp_2exp_si(primes_product, mod_bits) < 0; p = n_nextprime(p, 1)) { if (n % (p - 1) != 0) { mag_mul_ui_lower(primes_product, primes_product, p); num_primes++; } } #if DEBUG printf("\nn = %lu, bits = %lu, num_primes = %ld\n", n, bits, num_primes); #endif primes = flint_malloc(sizeof(mp_limb_t) * num_primes); residues = flint_malloc(sizeof(mp_limb_t) * num_primes); for (p = 5, i = 0; i < num_primes; p = n_nextprime(p, 1)) { if (n % (p - 1) != 0) { primes[i] = p; i++; } } #if TIMING t2 = clock(); printf("init time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); printf("num_primes = %ld\n", num_primes); #endif for (i = 0; i < num_primes; i++) { #if TIMING if (i % 10000 == 0) printf("%ld / %ld\n", i, num_primes); #endif residues[i] = bernoulli_mod_p_harvey(n, primes[i]); } #if TIMING t2 = clock(); printf("mod time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); printf("start CRT\n"); t1 = clock(); #endif fmpz_init(M); tree_crt(num, M, residues, primes, num_primes); fmpz_mul(num, num, den); fmpz_mod(num, num, M); if (n % 4 == 0) { fmpz_sub(num, M, num); fmpz_neg(num, num); } #if TIMING printf("end CRT\n"); t2 = clock(); printf("CRT time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); t1 = clock(); #endif if (zeta_bits > 0) { slong prec; arb_t b; fmpz_t t; arb_init(b); fmpz_init(t); for (prec = zeta_bits + 10; ; prec += 32) { arb_bernoulli_ui_zeta(b, n, prec); arb_mul_fmpz(b, b, den, prec); arb_sub_fmpz(b, b, num, prec); arb_div_fmpz(b, b, M, prec); if (arb_get_unique_fmpz(t, b)) { fmpz_addmul(num, t, M); break; } flint_printf("bernoulli: n = %wu, bits = %wd, mod = %wd, zeta = %wd: get_unique_fmpz failed!\n", n, bits, mod_bits, zeta_bits); } arb_clear(b); fmpz_clear(t); } #if TIMING printf("end zeta\n"); t2 = clock(); printf("zeta time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC); #endif flint_free(primes); flint_free(residues); fmpz_clear(M); mag_clear(primes_product); } arb-2.22.1/bernoulli/fmpq_ui_zeta.c000066400000000000000000000021661417376376500172140ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" #include "arb.h" void _bernoulli_fmpq_ui_zeta(fmpz_t num, fmpz_t den, ulong n) { slong prec; arb_t t; 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; } arb_init(t); for (prec = arith_bernoulli_number_size(n) + fmpz_bits(den) + 2; ; prec += 20) { arb_bernoulli_ui_zeta(t, n, prec); arb_mul_fmpz(t, t, den, prec); if (arb_get_unique_fmpz(num, t)) break; flint_printf("warning: %wd insufficient precision for Bernoulli number %wu\n", prec, n); } arb_clear(t); } arb-2.22.1/bernoulli/mod_p_harvey.c000066400000000000000000000623361417376376500172120ustar00rootroot00000000000000/* Copyright (C) 2008, 2009, David Harvey Copyright (C) 2021 Fredrik Johansson This file has been adapted from the BSD-licensed bernmm package by David Harvey (see original copyright text below). Changes in the Arb version: * Use FLINT functions instead of NTL functions. (Some helper functions have been added -- these should probably be moved to FLINT.) * C instead of C++; some renaming and reformatting for better consistency with FLINT/Arb coding conventions. Important note on performance: * The modular arithmetic in FLINT is quite a bit slower than NTL since it is designed to support full 64-bit moduli which we don't need here. This mainly affects bernoulli_sum_powg and bernsum_pow2, which fortunately don't get called often for multimodular computation. However, we'd want to re-optimize these in case they find some other use. */ /* =============================================================================== bernmm: an implementation of the algorithm described in "A multimodular algorithm for computing Bernoulli numbers", by David Harvey, 2008. version 1.1 Copyright (C) 2008, 2009, David Harvey All rights reserved. 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 COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 COPYRIGHT HOLDERS OR CONTRIBUTORS 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 #include "flint/ulong_extras.h" #include "bernoulli.h" #define DEBUG 0 #define TIMING 1 /****************************************************************************** Computing the main sum (general case) ******************************************************************************/ /* todo: this should be a function in ulong_extras */ ulong _bernoulli_n_muldivrem_precomp(ulong * q, ulong a, ulong b, ulong n, double bnpre) { ulong qq, r; qq = (double) a * bnpre; r = a * b - qq * n; if ((slong) r < 0) { qq--; r += n; } if (r >= n) { qq++; r -= n; } *q = qq; return r; } /* Returns (1 - g^k) B_k / 2k mod p. PRECONDITIONS: 5 <= p < 2^FLINT_D_BITS, p prime 2 <= k <= p-3, k even pinv = n_preinvert_limb(p) g = a multiplicative generator of GF(p), in [0, p) */ static ulong bernoulli_sum_powg(ulong p, ulong pinv, ulong k, ulong g) { ulong half_gm1, sum, g_to_km1, g_to_jm1, g_to_km1_to_j, q, h; slong j; double g_pinv; g_pinv = (double) g / (double) p; half_gm1 = (g + ((g & 1) ? 0 : p) - 1) / 2; /* (g-1)/2 mod p */ g_to_km1 = n_powmod2_preinv(g, k-1, p, pinv); g_to_jm1 = 1; g_to_km1_to_j = g_to_km1; sum = 0; for (j = 1; j <= (p - 1) / 2; j++) { g_to_jm1 = _bernoulli_n_muldivrem_precomp(&q, g_to_jm1, g, p, g_pinv); h = n_submod(q, half_gm1, p); sum = n_submod(sum, n_mulmod2_preinv(h, g_to_km1_to_j, p, pinv), p); g_to_km1_to_j = n_mulmod2_preinv(g_to_km1_to_j, g_to_km1, p, pinv); } return sum; } /****************************************************************************** Computing the main sum (c = 1/2 case) ******************************************************************************/ /* The Expander class stores precomputed information for a fixed integer p, that subsequently permits fast computation of the binary expansion of s/p for any 0 < s < p. The constructor takes p and max_words as input. Must have 1 <= max_words <= MAX_INV. It computes an approximation to 1/p. The function expand(mp_ptr res, long s, long n) computes n limbs of s/p. Must have 0 < s < p and 1 <= n <= max_words. The output is written to res. The first word of output is junk. The next n words are the digits of s/p, from least to most significant. The buffer must be at least n+2 words long (even though the first and last words are never used for output). */ #define MAX_INV 256 typedef struct { /* Approximation to 1/p. We store (max_words + 1) limbs. */ mp_limb_t pinv[MAX_INV + 2]; mp_limb_t p; int max_words; } expander_t; static void expander_init(expander_t * this, ulong p, int max_words) { mp_limb_t one; FLINT_ASSERT(max_words >= 1); FLINT_ASSERT(max_words <= MAX_INV); this->max_words = max_words; this->p = p; one = 1; mpn_divrem_1(this->pinv, max_words + 1, &one, 1, p); } static void expander_expand(mp_ptr res, expander_t * this, ulong s, ulong n) { slong i; FLINT_ASSERT(s > 0 && s < p); FLINT_ASSERT(n >= 1); FLINT_ASSERT(n <= max_words); if (s == 1) { /* already have 1/p; just copy it */ for (i = 1; i <= n; i++) res[i] = this->pinv[this->max_words - n + i]; } else { mpn_mul_1(res, this->pinv + this->max_words - n, n + 1, (mp_limb_t) s); /* If the first output limb is really close to 0xFFFF..., then there's a possibility of overflow, so fall back on doing division directly. This should happen extremely rarely --- essentially never on a 64-bit system, and very occasionally on a 32-bit system. */ if (res[0] > -((mp_limb_t) s)) { mp_limb_t ss = s; mpn_divrem_1(res, n + 1, &ss, 1, this->p); } } } /* Returns (2^(-k) - 1) 2 B_k / k mod p. (Note: this is useless if 2^k = 1 mod p.) PRECONDITIONS: 5 <= p, p prime 2 <= k <= p-3, k even pinv = n_preinvert_limb(p) g = a multiplicative generator of GF(p), in [0, p) n = multiplicative n_multiplicative_order of 2 in GF(p) */ #define TABLE_LG_SIZE 8 #define TABLE_SIZE (WORD(1) << TABLE_LG_SIZE) #define TABLE_MASK (TABLE_SIZE - 1) #define NUM_TABLES (FLINT_BITS / TABLE_LG_SIZE) #if FLINT_BITS % TABLE_LG_SIZE != 0 #error Number of bits in a ulong must be divisible by TABLE_LG_SIZE #endif ulong bernsum_pow2(ulong p, ulong pinv, ulong k, ulong g, ulong n) { slong i, m; ulong g_to_km1, two_to_km1, B_to_km1, s_jump; ulong tables[NUM_TABLES][TABLE_SIZE]; ulong g_to_km1_to_i; ulong g_to_i; ulong sum; expander_t expander; slong h; ulong x; ulong weights[TABLE_SIZE]; ulong x_jump; /* In the main summation loop we accumulate data into the _tables_ array; tables[y][z] contributes to the final answer with a weight of sum(-(-1)^z[t] * (2^(k-1))^(FLINT_BITS - 1 - y * TABLE_LG_SIZE - t) : 0 <= t < TABLE_LG_SIZE), where z[t] denotes the t-th binary digit of z (LSB is t = 0). The memory footprint for _tables_ is 4KB on a 32-bit machine, or 16KB on a 64-bit machine, so should fit easily into L1 cache. */ memset(tables, 0, sizeof(ulong) * NUM_TABLES * TABLE_SIZE); m = (p-1) / n; /* take advantage of symmetry (n' and m' from the paper) */ if (n & 1) m >>= 1; else n >>= 1; /* g^(k-1) */ g_to_km1 = n_powmod2_preinv(g, k - 1, p, pinv); /* 2^(k-1) */ two_to_km1 = n_powmod2_preinv(2, k - 1, p, pinv); /* B^(k-1), where B = 2^FLINT_BITS */ B_to_km1 = n_powmod2_preinv(two_to_km1, FLINT_BITS, p, pinv); /* B^(MAX_INV) */ s_jump = n_powmod2_preinv(2, MAX_INV * FLINT_BITS, p, pinv); /* todo - help speed up modmuls mulmod_precon_t g_pinv = PrepMulModPrecon(g, p, pinv); mulmod_precon_t g_to_km1_pinv = PrepMulModPrecon(g_to_km1, p, pinv); mulmod_precon_t two_to_km1_pinv = PrepMulModPrecon(two_to_km1, p, pinv); mulmod_precon_t B_to_km1_pinv = PrepMulModPrecon(B_to_km1, p, pinv); mulmod_precon_t s_jump_pinv = PrepMulModPrecon(s_jump, p, pinv); */ g_to_km1_to_i = 1; g_to_i = 1; sum = 0; /* Precompute some of the binary expansion of 1/p; at most MAX_INV words, or possibly less if n is sufficiently small */ expander_init(&expander, p, (n >= MAX_INV * FLINT_BITS) ? MAX_INV : ((n - 1) / FLINT_BITS + 1)); /* =========== phase 1: main summation loop */ /* loop over outer sum */ for (i = 0; i < m; i++) { ulong s, x, y; slong nn; /* s keeps track of g^i*2^j mod p */ s = g_to_i; /* x keeps track of (g^i*2^j)^(k-1) mod p */ x = g_to_km1_to_i; /* loop over inner sum; break it up into chunks of length at most */ /* MAX_INV * FLINT_BITS. If n is large, this allows us to do most of */ /* the work with mpn_mul_1 instead of mpn_divrem_1, and also improves */ /* memory locality. */ for (nn = n; nn > 0; nn -= MAX_INV * FLINT_BITS) { mp_limb_t s_over_p[MAX_INV + 2]; slong bits, words; mp_ptr next; if (nn >= MAX_INV * FLINT_BITS) { /* do one chunk of length exactly MAX_INV * FLINT_BITS */ bits = MAX_INV * FLINT_BITS; words = MAX_INV; } else { /* last chunk of length less than MAX_INV * FLINT_BITS */ bits = nn; words = (nn - 1) / FLINT_BITS + 1; } /* compute some bits of the binary expansion of s/p */ expander_expand(s_over_p, &expander, s, words); next = s_over_p + words; /* loop over whole words */ for (; bits >= FLINT_BITS; bits -= FLINT_BITS, next--) { mp_limb_t y; #if NUM_TABLES != 8 && NUM_TABLES != 4 mp_ptr target; #else mp_ptr target0, target1, target2, target3, target4, target5, target6, target7; #endif y = *next; #if NUM_TABLES != 8 && NUM_TABLES != 4 /* generic version */ for (h = 0; h < NUM_TABLES; h++) { target = &(tables[h][y & TABLE_MASK]); *target = n_submod(*target, x, p); y >>= TABLE_LG_SIZE; } #else /* unrolled versions for 32-bit/64-bit machines */ target0 = &(tables[0][y & TABLE_MASK]); *target0 = n_submod(*target0, x, p); target1 = &(tables[1][(y >> TABLE_LG_SIZE) & TABLE_MASK]); *target1 = n_submod(*target1, x, p); target2 = &(tables[2][(y >> (2*TABLE_LG_SIZE)) & TABLE_MASK]); *target2 = n_submod(*target2, x, p); target3 = &(tables[3][(y >> (3*TABLE_LG_SIZE)) & TABLE_MASK]); *target3 = n_submod(*target3, x, p); #if NUM_TABLES == 8 target4 = &(tables[4][(y >> (4*TABLE_LG_SIZE)) & TABLE_MASK]); *target4 = n_submod(*target4, x, p); target5 = &(tables[5][(y >> (5*TABLE_LG_SIZE)) & TABLE_MASK]); *target5 = n_submod(*target5, x, p); target6 = &(tables[6][(y >> (6*TABLE_LG_SIZE)) & TABLE_MASK]); *target6 = n_submod(*target6, x, p); target7 = &(tables[7][(y >> (7*TABLE_LG_SIZE)) & TABLE_MASK]); *target7 = n_submod(*target7, x, p); #endif #endif x = n_mulmod2_preinv(x, B_to_km1, p, pinv); /* todo: precond */ } /* loop over remaining bits in the last word */ y = *next; for (; bits > 0; bits--) { if (y & (UWORD(1) << (FLINT_BITS - 1))) sum = n_submod(sum, x, p); else sum = n_addmod(sum, x, p); x = n_mulmod2_preinv(x, two_to_km1, p, pinv); /* todo: precond */ y <<= 1; } s = n_mulmod2_preinv(s, s_jump, p, pinv); /* todo: precond */ } /* update g^i and (g^(k-1))^i */ g_to_i = n_mulmod2_preinv(g_to_i, g, p, pinv); g_to_km1_to_i = n_mulmod2_preinv(g_to_km1_to_i, g_to_km1, p, pinv); } #if DEBUG { slong i, j; for (i = 0; i < NUM_TABLES; i++) { printf("tab[%lu] = ", i); for (j = 0; j < TABLE_SIZE; j++) printf("%lu ", tables[i][j]); printf("\n"); } } #endif /* =========== phase 2: consolidate table data */ /* compute weights[z] = sum((-1)^z[t] * (2^(k-1))^(TABLE_LG_SIZE - 1 - t) : 0 <= t < TABLE_LG_SIZE). */ weights[0] = 0; for (h = 0, x = 1; h < TABLE_LG_SIZE; h++, x = n_mulmod2_preinv(x, two_to_km1, p, pinv)) { for (i = (WORD(1) << h) - 1; i >= 0; i--) { weights[2*i+1] = n_submod(weights[i], x, p); weights[2*i] = n_addmod(weights[i], x, p); } } /* combine table data with weights */ x_jump = n_powmod2_preinv(two_to_km1, TABLE_LG_SIZE, p, pinv); for (h = NUM_TABLES - 1, x = 1; h >= 0; h--) { for (i = 0; i < TABLE_SIZE; i++) { ulong y = n_mulmod2_preinv(tables[h][i], weights[i], p, pinv); y = n_mulmod2_preinv(y, x, p, pinv); sum = n_submod(sum, y, p); } x = n_mulmod2_preinv(x_jump, x, p, pinv); } return sum; } /****************************************************************************** Computing the main sum (c = 1/2 case, with REDC arithmetic) Throughout this section F denotes 2^(FLINT_BITS / 2). ******************************************************************************/ /* Returns x/F mod n. Output is in [0, 2n), i.e. *not* reduced completely into [0, n). PRECONDITIONS: 3 <= n < F, n odd 0 <= x < nF (if n < F/2) 0 <= x < nF/2 (if n > F/2) ninv2 = -1/n mod F */ #define LOW_MASK ((UWORD(1) << (FLINT_BITS / 2)) - 1) static __inline__ ulong RedcFast(ulong x, ulong n, ulong ninv2) { ulong y = (x * ninv2) & LOW_MASK; ulong z = x + (n * y); return z >> (FLINT_BITS / 2); } /* Same as RedcFast(), but reduces output into [0, n). */ static __inline__ ulong Redc(ulong x, ulong n, ulong ninv2) { ulong y = RedcFast(x, n, ninv2); if (y >= n) y -= n; return y; } /* Computes -1/n mod F, in [0, F). PRECONDITIONS: 3 <= n < F, n odd */ static ulong PrepRedc(ulong n) { ulong bits; ulong ninv2 = -n; /* already correct mod 8 */ /* Newton's method for 2-adic inversion */ for (bits = 3; bits < FLINT_BITS/2; bits *= 2) ninv2 = 2*ninv2 + n * ninv2 * ninv2; return ninv2 & LOW_MASK; } /* Same as bernsum_pow2(), but uses REDC arithmetic, and various delayed reduction strategies. PRECONDITIONS: Same as bernsum_pow2(), and in addition: p < 2^(FLINT_BITS/2 - 1) (See bernsum_pow2() for code comments; we only add comments here where something is different from bernsum_pow2()) */ ulong bernsum_pow2_redc(ulong p, ulong pinv, ulong k, ulong g, ulong n) { ulong pinv2 = PrepRedc(p); ulong F = (UWORD(1) << (FLINT_BITS/2)) % p; ulong x; slong h, i, m; ulong weights[TABLE_SIZE]; ulong x_jump; ulong x_jump_redc; ulong g_to_km1; ulong two_to_km1; ulong B_to_km1; ulong s_jump; ulong g_redc; ulong g_to_km1_redc; ulong two_to_km1_redc; ulong B_to_km1_redc; ulong s_jump_redc; ulong g_to_km1_to_i; ulong g_to_i; ulong sum; ulong tables[NUM_TABLES][TABLE_SIZE]; expander_t expander; memset(tables, 0, sizeof(ulong) * NUM_TABLES * TABLE_SIZE); m = (p-1) / n; if (n & 1) m >>= 1; else n >>= 1; g_to_km1 = n_powmod2_preinv(g, k-1, p, pinv); two_to_km1 = n_powmod2_preinv(2, k-1, p, pinv); B_to_km1 = n_powmod2_preinv(two_to_km1, FLINT_BITS, p, pinv); s_jump = n_powmod2_preinv(2, MAX_INV * FLINT_BITS, p, pinv); g_redc = n_mulmod2_preinv(g, F, p, pinv); g_to_km1_redc = n_mulmod2_preinv(g_to_km1, F, p, pinv); two_to_km1_redc = n_mulmod2_preinv(two_to_km1, F, p, pinv); B_to_km1_redc = n_mulmod2_preinv(B_to_km1, F, p, pinv); s_jump_redc = n_mulmod2_preinv(s_jump, F, p, pinv); g_to_km1_to_i = 1; /* always in [0, 2p) */ g_to_i = 1; /* always in [0, 2p) */ sum = 0; #if DEBUG printf("%lu %lu %lu %lu %lu %lu %lu %lu %lu\n", F, g_to_km1, two_to_km1, B_to_km1, s_jump, g_redc, g_to_km1_redc, B_to_km1_redc, s_jump_redc); #endif expander_init(&expander, p, (n >= MAX_INV * FLINT_BITS) ? MAX_INV : ((n - 1) / FLINT_BITS + 1)); /* =========== phase 1: main summation loop */ for (i = 0; i < m; i++) { ulong s, x, y; slong nn, bits, words; mp_ptr next; s = g_to_i; /* always in [0, p) */ if (s >= p) s -= p; x = g_to_km1_to_i; /* always in [0, 2p) */ for (nn = n; nn > 0; nn -= MAX_INV * FLINT_BITS) { ulong s_over_p[MAX_INV + 2]; if (nn >= MAX_INV * FLINT_BITS) { bits = MAX_INV * FLINT_BITS; words = MAX_INV; } else { bits = nn; words = (nn - 1) / FLINT_BITS + 1; } expander_expand(s_over_p, &expander, s, words); next = s_over_p + words; for (; bits >= FLINT_BITS; bits -= FLINT_BITS, next--) { y = *next; #if DEBUG printf("i = %lu nn = %lu words = %lu bits = %lu y = %lu\n", i, nn, words, bits, y); #endif /* note: we add the values into tables *without* reduction mod p */ #if NUM_TABLES != 8 && NUM_TABLES != 4 /* generic version */ for (h = 0; h < NUM_TABLES; h++) { tables[h][y & TABLE_MASK] += x; y >>= TABLE_LG_SIZE; } #else /* unrolled versions for 32-bit/64-bit machines */ tables[0][ y & TABLE_MASK] += x; tables[1][(y >> TABLE_LG_SIZE ) & TABLE_MASK] += x; tables[2][(y >> (2*TABLE_LG_SIZE)) & TABLE_MASK] += x; tables[3][(y >> (3*TABLE_LG_SIZE)) & TABLE_MASK] += x; #if NUM_TABLES == 8 tables[4][(y >> (4*TABLE_LG_SIZE)) & TABLE_MASK] += x; tables[5][(y >> (5*TABLE_LG_SIZE)) & TABLE_MASK] += x; tables[6][(y >> (6*TABLE_LG_SIZE)) & TABLE_MASK] += x; tables[7][(y >> (7*TABLE_LG_SIZE)) & TABLE_MASK] += x; #endif #endif x = RedcFast(x * B_to_km1_redc, p, pinv2); } /* bring x into [0, p) for next loop */ if (x >= p) x -= p; y = *next; for (; bits > 0; bits--) { if (y & (UWORD(1) << (FLINT_BITS - 1))) sum = n_submod(sum, x, p); else sum = n_addmod(sum, x, p); x = Redc(x * two_to_km1_redc, p, pinv2); y <<= 1; } s = Redc(s * s_jump_redc, p, pinv2); } g_to_i = RedcFast(g_to_i * g_redc, p, pinv2); g_to_km1_to_i = RedcFast(g_to_km1_to_i * g_to_km1_redc, p, pinv2); } /* At this point, each table entry is at most p^2 (since x was always */ /* in [0, 2p), and the inner loop was called at most (p/2) / FLINT_BITS */ /* times, and 2p * p/2 / FLINT_BITS * TABLE_LG_SIZE <= p^2). */ #if DEBUG { slong i, j; for (i = 0; i < NUM_TABLES; i++) { printf("tab[%lu] = ", i); for (j = 0; j < TABLE_SIZE; j++) printf("%lu ", tables[i][j]); printf("\n"); } } #endif /* =========== phase 2: consolidate table data */ weights[0] = 0; /* we store the weights multiplied by a factor of 2^(3*FLINT_BITS/2) to */ /* compensate for the three rounds of REDC reduction in the loop below */ for (h = 0, x = n_powmod2_preinv(2, 3*FLINT_BITS/2, p, pinv); h < TABLE_LG_SIZE; h++, x = Redc(x * two_to_km1_redc, p, pinv2)) { for (i = (WORD(1) << h) - 1; i >= 0; i--) { weights[2*i+1] = n_submod(weights[i], x, p); weights[2*i] = n_addmod(weights[i], x, p); } } x_jump = n_powmod2_preinv(two_to_km1, TABLE_LG_SIZE, p, pinv); x_jump_redc = n_mulmod2_preinv(x_jump, F, p, pinv); for (h = NUM_TABLES - 1, x = 1; h >= 0; h--) { for (i = 0; i < TABLE_SIZE; i++) { ulong y; y = RedcFast(tables[h][i], p, pinv2); y = RedcFast(y * weights[i], p, pinv2); y = RedcFast(y * x, p, pinv2); sum += y; } x = Redc(x * x_jump_redc, p, pinv2); } return sum % p; } /****************************************************************************** Wrappers for bernsum_* ******************************************************************************/ /* Returns B_k/k mod p, in the range [0, p). PRECONDITIONS: 5 <= p < NTL_SP_BOUND, p prime 2 <= k <= p-3, k even pinv = PrepMulMod(p) Algorithm: uses bernoulli_sum_powg() to compute the main sum. */ ulong _bernoulli_mod_p_harvey_powg(ulong p, ulong pinv, ulong k) { ulong x, g, t, g_to_k; g = n_primitive_root_prime(p); /* compute main sum */ x = bernoulli_sum_powg(p, pinv, k, g); /* divide by (1 - g^k) and multiply by 2 */ g_to_k = n_powmod2_preinv(g, k, p, pinv); t = n_invmod(p + 1 - g_to_k, p); x = n_mulmod2_preinv(x, t, p, pinv); x = n_addmod(x, x, p); return x; } static ulong n_multiplicative_order(ulong x, ulong p, ulong pinv, n_factor_t * F) { ulong m, q, mm; slong i; /* in the loop below, m is always some multiple of the n_multiplicative_order of x */ m = p - 1; /* try to remove factors from m until we can't remove any more */ for (i = 0; i < F->num; i++) { q = F->p[i]; while (m % q == 0) { mm = m / q; if (n_powmod2_preinv(x, mm, p, pinv) != 1) break; m = mm; } } return m; } /* Returns B_k/k mod p, in the range [0, p). PRECONDITIONS: 5 <= p < NTL_SP_BOUND, p prime 2 <= k <= p-3, k even pinv = PrepMulMod(p) 2^k != 1 mod p Algorithm: uses bernsum_pow2() (or bernsum_pow2_redc() if p is small enough) to compute the main sum. */ ulong _bernoulli_mod_p_harvey_pow2(ulong p, ulong pinv, ulong k) { n_factor_t F; ulong g, n, x, t; n_factor_init(&F); n_factor(&F, p - 1, 1); g = n_primitive_root_prime_prefactor(p, &F); n = n_multiplicative_order(2, p, pinv, &F); #if DEBUG printf("g = %lu, n = %lu\n", g, n); #endif if (p < (UWORD(1) << (FLINT_BITS/2 - 1))) x = bernsum_pow2_redc(p, pinv, k, g, n); else x = bernsum_pow2(p, pinv, k, g, n); /* divide by 2*(2^(-k) - 1) */ t = n_submod(n_invmod(n_powmod2_preinv(2, k, p, pinv), p), 1, p); t = n_addmod(t, t, p); t = n_invmod(t, p); x = n_mulmod2_preinv(x, t, p, pinv); return x; } /* Returns B_k/k mod p, in the range [0, p). PRECONDITIONS: 5 <= p < NTL_SP_BOUND, p prime 2 <= k <= p-3, k even pinv = PrepMulMod(p) */ ulong _bernoulli_mod_p_harvey(ulong p, ulong pinv, ulong k) { if (n_powmod2_preinv(2, k, p, pinv) != 1) { /* 2^k != 1 mod p, so we use the faster version */ return _bernoulli_mod_p_harvey_pow2(p, pinv, k); } else { /* forced to use slower version */ return _bernoulli_mod_p_harvey_powg(p, pinv, k); } } /****************************************************************************** Main bernoulli_mod_p routine ******************************************************************************/ /* beware: opposite argument order to bernmm */ ulong bernoulli_mod_p_harvey(ulong k, ulong p) { ulong m, x, pinv; FLINT_ASSERT(k >= 0); FLINT_ASSERT(2 <= p && p < (UWORD(1) << FLINT_D_BITS)); if (k == 0) return 1; if (k == 1) { if (p == 2) return -1; return (p - 1) / 2; } if (k & 1) return 0; /* denominator of B_k is always divisible by 6 for k >= 2 */ if (p <= 3) return UWORD_MAX; /* use Kummer's congruence (k = m mod p-1 => B_k/k = B_m/m mod p) */ m = k % (p - 1); if (m == 0) return UWORD_MAX; pinv = n_preinvert_limb(p); x = _bernoulli_mod_p_harvey(p, pinv, m); /* = B_m/m mod p */ return n_mulmod2_preinv(x, k % p, p, pinv); } arb-2.22.1/bernoulli/rev_clear.c000066400000000000000000000012241417376376500164650ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" void bernoulli_rev_clear(bernoulli_rev_t iter) { if (iter->alloc != 0) { _fmpz_vec_clear(iter->powers, iter->alloc); fmpz_clear(iter->pow_error); arb_clear(iter->prefactor); arb_clear(iter->two_pi_squared); } } arb-2.22.1/bernoulli/rev_init.c000066400000000000000000000040041417376376500163410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" void bernoulli_rev_init(bernoulli_rev_t iter, ulong nmax) { slong j; fmpz_t t; arb_t x; arf_t u; int round1, round2; slong wp; nmax -= (nmax % 2); iter->n = nmax; iter->alloc = 0; if (nmax < BERNOULLI_REV_MIN) return; iter->prec = wp = bernoulli_global_prec(nmax); iter->max_power = bernoulli_zeta_terms(nmax, iter->prec); iter->alloc = iter->max_power + 1; iter->powers = _fmpz_vec_init(iter->alloc); fmpz_init(iter->pow_error); arb_init(iter->prefactor); arb_init(iter->two_pi_squared); arb_init(x); fmpz_init(t); arf_init(u); /* precompute powers */ for (j = 3; j <= iter->max_power; j += 2) { arb_ui_pow_ui(x, j, nmax, bernoulli_power_prec(j, nmax, wp)); arb_inv(x, x, bernoulli_power_prec(j, nmax, wp)); round1 = arf_get_fmpz_fixed_si(t, arb_midref(x), -wp); fmpz_set(iter->powers + j, t); /* error: the radius, plus two roundings */ arf_set_mag(u, arb_radref(x)); round2 = arf_get_fmpz_fixed_si(t, u, -wp); fmpz_add_ui(t, t, (round1 != 0) + (round2 != 0)); if (fmpz_cmp(iter->pow_error, t) < 0) fmpz_set(iter->pow_error, t); } /* precompute (2pi)^2 and 2*(n!)/(2pi)^n */ arb_fac_ui(iter->prefactor, nmax, wp); arb_mul_2exp_si(iter->prefactor, iter->prefactor, 1); arb_const_pi(x, wp); arb_mul_2exp_si(x, x, 1); arb_mul(iter->two_pi_squared, x, x, wp); arb_pow_ui(x, iter->two_pi_squared, nmax / 2, wp); arb_div(iter->prefactor, iter->prefactor, x, wp); fmpz_clear(t); arb_clear(x); arf_clear(u); } arb-2.22.1/bernoulli/rev_next.c000066400000000000000000000074051417376376500163640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bernoulli.h" static __inline__ void mag_ui_div(mag_t z, ulong c, const mag_t x) { mag_t t; mag_init(t); mag_set_ui(t, c); mag_div(z, t, x); mag_clear(t); } void bernoulli_rev_next(fmpz_t numer, fmpz_t denom, bernoulli_rev_t iter) { ulong n; slong j, wp; fmpz_t sum; mag_t err; arb_t z, h; n = iter->n; wp = iter->prec; if (n < BERNOULLI_REV_MIN) { _arith_bernoulli_number(numer, denom, n); if (n != 0) iter->n -= 2; return; } fmpz_init(sum); mag_init(err); arb_init(z); arb_init(h); /* add all odd powers */ fmpz_zero(sum); for (j = iter->max_power; j >= 3; j -= 2) fmpz_add(sum, sum, iter->powers + j); arb_set_fmpz(z, sum); /* bound numerical error from the powers */ fmpz_mul_ui(sum, iter->pow_error, iter->max_power / 2); mag_set_fmpz(err, sum); mag_add(arb_radref(z), arb_radref(z), err); arb_mul_2exp_si(z, z, -wp); arb_add_ui(z, z, 1, wp); /* add truncation error: sum_{k > N} 1/k^n <= 1/N^(i-1) */ mag_set_ui_lower(err, iter->max_power); mag_pow_ui_lower(err, err, n - 1); mag_ui_div(err, 1, err); mag_add(arb_radref(z), arb_radref(z), err); /* convert zeta to Bernoulli number */ arb_div_2expm1_ui(h, z, n, wp); arb_add(z, z, h, wp); arb_mul(z, z, iter->prefactor, wp); arith_bernoulli_number_denom(denom, n); arb_mul_fmpz(z, z, denom, wp); if (n % 4 == 0) arb_neg(z, z); /* flint_printf("%wd: ", n); arb_printd(z, 5); flint_printf("\n"); */ if (!arb_get_unique_fmpz(numer, z)) { flint_printf("warning: insufficient precision for B_%wd\n", n); _bernoulli_fmpq_ui(numer, denom, n); } /* update prefactor */ if (n > 0) { arb_mul(iter->prefactor, iter->prefactor, iter->two_pi_squared, wp); arb_div_ui(iter->prefactor, iter->prefactor, n, wp); arb_div_ui(iter->prefactor, iter->prefactor, n - 1, wp); } /* update powers */ for (j = 3; j <= iter->max_power; j += 2) fmpz_mul2_uiui(iter->powers + j, iter->powers + j, j, j); /* bound error after update */ fmpz_mul2_uiui(iter->pow_error, iter->pow_error, iter->max_power, iter->max_power); /* readjust precision */ if (n % 64 == 0 && n > BERNOULLI_REV_MIN) { slong new_prec, new_max; new_prec = bernoulli_global_prec(n); new_max = bernoulli_zeta_terms(n, new_prec); if (new_prec < iter->prec && new_max <= iter->max_power) { /* change precision of the powers */ for (j = 3; j <= new_max; j += 2) fmpz_tdiv_q_2exp(iter->powers + j, iter->powers + j, iter->prec - new_prec); /* the error also changes precision */ fmpz_cdiv_q_2exp(iter->pow_error, iter->pow_error, iter->prec - new_prec); /* contribution of rounding error when changing the precision of the powers */ fmpz_add_ui(iter->pow_error, iter->pow_error, 1); /* speed improvement (could be skipped with better multiplication) */ arb_set_round(iter->two_pi_squared, iter->two_pi_squared, new_prec); iter->max_power = new_max; iter->prec = new_prec; } } iter->n -= 2; fmpz_clear(sum); mag_clear(err); arb_clear(z); arb_clear(h); } arb-2.22.1/bernoulli/test/000077500000000000000000000000001417376376500153375ustar00rootroot00000000000000arb-2.22.1/bernoulli/test/t-bound_2exp_si.c000066400000000000000000000032571417376376500205130ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "bernoulli.h" double log2bern_approx(double n) { return 1 + ((n+0.5)*log(n) - n - (n-0.5)*log(2*3.14159265358979323)) * (1. / log(2)); } int main() { slong i, bound; double a, b; fmpq_t q; fmpr_t t; flint_printf("bound_2exp_si...."); fflush(stdout); fmpq_init(q); fmpr_init(t); for (i = 0; i < 1000; i++) { arith_bernoulli_number(q, i); bound = bernoulli_bound_2exp_si(i); fmpr_set_round_fmpz(t, fmpq_numref(q), 32, FMPR_RND_UP); fmpr_div_fmpz(t, t, fmpq_denref(q), 32, FMPR_RND_UP); if (fmpr_cmpabs_2exp_si(t, bound) > 0) { flint_printf("FAIL: %wd\n", i); fmpr_print(t); flint_printf("\n\n"); flint_printf("%wd\n", bound); flint_printf("\n\n"); flint_abort(); } } fmpq_clear(q); fmpr_clear(t); for (i = 100; i < 4000000; i += 1) { i += (i & 1); a = bernoulli_bound_2exp_si(i); b = log2bern_approx(i); if (a < b || a > 1.01 * b) { flint_printf("FAIL: %wd\n", i); flint_printf("%wd: %f %f %f\n", i, a, b, (float) a / b); flint_abort(); } } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bernoulli/test/t-fmpq_ui.c000066400000000000000000000033101417376376500174010ustar00rootroot00000000000000/* Copyright (C) 2011, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "flint/fmpz_vec.h" #include "flint/arith.h" #include "bernoulli.h" int main() { fmpz * num1; fmpz * den1; fmpz_t num2; fmpz_t den2; slong n, N; flint_printf("fmpq_ui...."); fflush(stdout); N = 4000 * FLINT_MIN(1.0, arb_test_multiplier()); 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++) { _bernoulli_fmpq_ui(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"); flint_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"); flint_abort(); } } _fmpz_vec_clear(num1, N); _fmpz_vec_clear(den1, N); fmpz_clear(num2); fmpz_clear(den2); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/bernoulli/test/t-fmpq_ui_multi_mod.c000066400000000000000000000072731417376376500214660ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "flint/fmpz_vec.h" #include "flint/arith.h" #include "bernoulli.h" int main() { flint_rand_t state; fmpz * num1; fmpz * den1; fmpz_t num2; fmpz_t den2; slong n, N; double alpha; flint_randinit(state); flint_printf("fmpq_ui_multi_mod...."); fflush(stdout); N = 1500 * FLINT_MIN(1.0, arb_test_multiplier()); 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++) { if (n_randint(state, 2)) alpha = -1.0; else alpha = n_randint(state, 11) / (double) 10; _bernoulli_fmpq_ui_multi_mod(num2, den2, n, alpha); 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"); flint_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"); flint_abort(); } } { _bernoulli_fmpq_ui_multi_mod(num1, den1, 10000, 0.3); _bernoulli_fmpq_ui_multi_mod(num2, den2, 10000, 1.0); if (!fmpz_equal(num1, num2) || !fmpz_equal(den1, den2)) { flint_printf("FAIL: n = 10000\n", n); flint_printf("num1 "); fmpz_print(num1); flint_printf("\n"); flint_printf("num2 "); fmpz_print(num2); flint_printf("\n"); flint_printf("den1 "); fmpz_print(den1); flint_printf("\n"); flint_printf("den2 "); fmpz_print(den2); flint_printf("\n"); flint_abort(); } _bernoulli_fmpq_ui_multi_mod(num1, den1, 30000, -1.0); _bernoulli_fmpq_ui_multi_mod(num2, den2, 30000, 0.8); if (!fmpz_equal(num1, num2) || !fmpz_equal(den1, den2)) { flint_printf("FAIL: n = 30000\n", n); flint_printf("num1 "); fmpz_print(num1); flint_printf("\n"); flint_printf("num2 "); fmpz_print(num2); flint_printf("\n"); flint_printf("den1 "); fmpz_print(den1); flint_printf("\n"); flint_printf("den2 "); fmpz_print(den2); flint_printf("\n"); flint_abort(); } _bernoulli_fmpq_ui_multi_mod(num1, den1, 80000, -1.0); _bernoulli_fmpq_ui_multi_mod(num2, den2, 80000, 0.5); if (!fmpz_equal(num1, num2) || !fmpz_equal(den1, den2)) { flint_printf("FAIL: n = 80000\n", n); flint_printf("num1 "); fmpz_print(num1); flint_printf("\n"); flint_printf("num2 "); fmpz_print(num2); flint_printf("\n"); flint_printf("den1 "); fmpz_print(den1); flint_printf("\n"); flint_printf("den2 "); fmpz_print(den2); flint_printf("\n"); flint_abort(); } } _fmpz_vec_clear(num1, N); _fmpz_vec_clear(den1, N); fmpz_clear(num2); fmpz_clear(den2); flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/bernoulli/test/t-mod_p_harvey.c000066400000000000000000000116251417376376500204250ustar00rootroot00000000000000/* Copyright (C) 2008, 2009 David Harvey Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "flint/fmpz_vec.h" #include "flint/arith.h" #include "bernoulli.h" /* test this internal function which should really be in FLINT */ ulong _bernoulli_n_muldivrem_precomp(ulong * q, ulong a, ulong b, ulong n, double bnpre); ulong _bernoulli_mod_p_harvey_powg(ulong p, ulong pinv, ulong k); ulong _bernoulli_mod_p_harvey_pow2(ulong p, ulong pinv, ulong k); void test_bern_modp_pow2(ulong p, ulong k) { ulong x, y; ulong pinv = n_preinvert_limb(p); if (n_powmod2_preinv(2, k, p, pinv) == 1) return; x = _bernoulli_mod_p_harvey_powg(p, pinv, k); y = _bernoulli_mod_p_harvey_pow2(p, pinv, k); if (x != y) { flint_printf("FAIL\n"); flint_printf("p = %wu\n", p); flint_printf("k = %wu\n", k); flint_printf("x = %wu\n", x); flint_printf("y = %wu\n", y); flint_abort(); } } int main() { slong iter; flint_rand_t state; flint_printf("mod_p_harvey...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { ulong a, b, n, q1, r1, r2; mp_limb_t q2[2]; double bnpre; a = n_randtest_bits(state, FLINT_D_BITS); b = n_randtest_bits(state, FLINT_D_BITS); do { n = n_randtest_bits(state, FLINT_D_BITS); } while (n == 0); a = a % n; b = b % n; bnpre = (double) b / (double) n; r1 = _bernoulli_n_muldivrem_precomp(&q1, a, b, n, bnpre); umul_ppmm(q2[1], q2[0], a, b); r2 = mpn_divrem_1(q2, 0, q2, 2, n); if (q2[0] != q1 || r1 != r2) { flint_printf("FAIL\n"); flint_printf("a = %wu\n", a); flint_printf("b = %wu\n", b); flint_printf("n = %wu\n", n); flint_printf("q1 = %wu\n", q1); flint_printf("r1 = %wu\n", r1); flint_printf("q2 = %wu\n", q2); flint_printf("r2 = %wu\n", r2); flint_abort(); } } { slong n, N, iter; ulong x, y, z, p, pinv; fmpz * num; fmpz * den; N = 300; num = _fmpz_vec_init(N); den = _fmpz_vec_init(N); _arith_bernoulli_number_vec_recursive(num, den, N); for (n = 2; n < N; n += 2) { for (iter = 0; iter < 10 * arb_test_multiplier(); iter++) { if (n_randint(state, 100) == 0) { p = 1000003; } else { p = n + 2 + n_randint(state, 2 * N); p = n_nextprime(p, 1); } pinv = n_preinvert_limb(p); x = _bernoulli_mod_p_harvey_powg(p, pinv, n); y = fmpz_fdiv_ui(num + n, p); z = fmpz_fdiv_ui(den + n, p); if (y != n_mulmod2_preinv(z, n_mulmod2_preinv(x, n, p, pinv), p, pinv)) { flint_printf("FAIL\n"); flint_printf("n = %wu\n", n); flint_printf("x = %wu\n", x); flint_printf("y = %wu\n", y); flint_printf("z = %wu\n", z); flint_abort(); } } } _fmpz_vec_clear(num, N); _fmpz_vec_clear(den, N); } { ulong p, k; /* exhaustive comparison over some small p and k */ for (p = 5; p < 1000; p = n_nextprime(p, 1)) { for (k = 2; k <= p - 3; k += 2) test_bern_modp_pow2(p, k); } /* a few larger values of p */ for (p = n_nextprime(1000000, 1); p < 1000000 + 1000 * FLINT_MIN(10, arb_test_multiplier()); p = n_nextprime(p, 1)) { k = 2 * (rand() % ((p-3)/2)) + 2; test_bern_modp_pow2(p, k); } /* these are slow */ if (FLINT_BITS == 64 && arb_test_multiplier() >= 10) { test_bern_modp_pow2(2147483647, 10); test_bern_modp_pow2(2147483629, 10); test_bern_modp_pow2(2147483659, 10); } for (p = n_nextprime((1 << 15) - 1000, 1); p < (1 << 15); p = n_nextprime(p, 1)) { for (iter = 0; iter < 10 * arb_test_multiplier(); iter++) { test_bern_modp_pow2(p, 2 * (n_randlimb(state) % ((p - 3)/2)) + 2); } } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/bernoulli/test/t-rev.c000066400000000000000000000047121417376376500165440ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "bernoulli.h" #include "flint/ulong_extras.h" #include "flint/nmod_poly.h" #include "flint/nmod_vec.h" int main() { flint_rand_t state; slong nmax, n, bound, count; mp_limb_t p, pinv, m1, m2; nmod_poly_t A; flint_printf("rev...."); fflush(stdout); flint_randinit(state); bound = 100000 * FLINT_MIN(1.0, arb_test_multiplier()); p = n_nextprime(UWORD(1) << (FLINT_BITS - 1), 0); pinv = n_preinvert_limb(p); nmod_poly_init(A, p); nmod_poly_set_coeff_ui(A, 1, 1); nmod_poly_exp_series(A, A, bound); nmod_poly_shift_right(A, A, 1); nmod_poly_inv_series(A, A, bound); m1 = 1; for (n = 0; n < A->length; n++) { A->coeffs[n] = n_mulmod2_preinv(A->coeffs[n], m1, p, pinv); m1 = n_mulmod2_preinv(m1, n + 1, p, pinv); } for (nmax = 0; nmax < bound; nmax = 1.5 * nmax + 2) { fmpz_t numer, denom; bernoulli_rev_t iter; fmpz_init(numer); fmpz_init(denom); nmax += (nmax % 2); bernoulli_rev_init(iter, nmax); if (nmax < 8000) count = 4000; else count = 100; /* flint_printf("nmax = %wd, count = %wd\n", nmax, count); */ for (n = nmax; n >= 0 && count > 0; n -= 2, count--) { bernoulli_rev_next(numer, denom, iter); m1 = fmpz_fdiv_ui(numer, p); m2 = fmpz_fdiv_ui(denom, p); m2 = n_invmod(m2, p); m1 = n_mulmod2_preinv(m1, m2, p, pinv); m2 = nmod_poly_get_coeff_ui(A, n); if (m1 != m2) { flint_printf("FAIL:\n"); flint_printf("nmax = %wd, n = %wd\n", nmax, n); flint_printf("m1 = %wu mod %wu\n", m1, p); flint_printf("m2 = %wu mod %wu\n", m2, p); flint_abort(); } } bernoulli_rev_clear(iter); fmpz_clear(numer); fmpz_clear(denom); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat.h000066400000000000000000000072611417376376500143400ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef BOOL_MAT_H #define BOOL_MAT_H #ifdef BOOL_MAT_INLINES_C #define BOOL_MAT_INLINE #else #define BOOL_MAT_INLINE static __inline__ #endif #include #include "flint/flint.h" #include "flint/fmpz_mat.h" #ifndef flint_abort #if __FLINT_RELEASE <= 20502 #define flint_abort abort #endif #endif #ifdef __cplusplus extern "C" { #endif /* currently defined in the arb module, but global to the library */ double arb_test_multiplier(void); typedef struct { int *entries; slong r; slong c; int **rows; } bool_mat_struct; typedef bool_mat_struct bool_mat_t[1]; #define bool_mat_nrows(mat) ((mat)->r) #define bool_mat_ncols(mat) ((mat)->c) BOOL_MAT_INLINE int bool_mat_get_entry(const bool_mat_t mat, slong i, slong j) { return mat->rows[i][j]; } BOOL_MAT_INLINE void bool_mat_set_entry(bool_mat_t mat, slong i, slong j, int value) { mat->rows[i][j] = value; } /* Memory management */ void bool_mat_init(bool_mat_t mat, slong r, slong c); void bool_mat_clear(bool_mat_t mat); BOOL_MAT_INLINE void bool_mat_swap(bool_mat_t mat1, bool_mat_t mat2) { bool_mat_struct t = *mat1; *mat1 = *mat2; *mat2 = t; } /* Conversions */ void bool_mat_set(bool_mat_t dest, const bool_mat_t src); /* Random generation */ void bool_mat_randtest(bool_mat_t mat, flint_rand_t state); void bool_mat_randtest_diagonal(bool_mat_t mat, flint_rand_t state); void bool_mat_randtest_nilpotent(bool_mat_t mat, flint_rand_t state); /* I/O */ void bool_mat_fprint(FILE * file, const bool_mat_t mat); BOOL_MAT_INLINE void bool_mat_print(const bool_mat_t mat) { bool_mat_fprint(stdout, mat); } /* Comparisons */ int bool_mat_equal(const bool_mat_t mat1, const bool_mat_t mat2); int bool_mat_any(const bool_mat_t mat); int bool_mat_all(const bool_mat_t mat); int bool_mat_is_diagonal(const bool_mat_t mat); int bool_mat_is_lower_triangular(const bool_mat_t mat); int bool_mat_is_transitive(const bool_mat_t mat); int bool_mat_is_nilpotent(const bool_mat_t mat); BOOL_MAT_INLINE int bool_mat_is_empty(const bool_mat_t mat) { return (mat->r == 0) || (mat->c == 0); } BOOL_MAT_INLINE int bool_mat_is_square(const bool_mat_t mat) { return (mat->r == mat->c); } /* Special matrices */ void bool_mat_zero(bool_mat_t mat); void bool_mat_one(bool_mat_t mat); void bool_mat_directed_path(bool_mat_t mat); void bool_mat_directed_cycle(bool_mat_t mat); /* Transpose */ void bool_mat_transpose(bool_mat_t mat1, const bool_mat_t mat2); /* Arithmetic */ void bool_mat_complement(bool_mat_t mat1, const bool_mat_t mat2); void bool_mat_add(bool_mat_t res, const bool_mat_t mat1, const bool_mat_t mat2); void bool_mat_mul(bool_mat_t res, const bool_mat_t mat1, const bool_mat_t mat2); void bool_mat_mul_entrywise(bool_mat_t res, const bool_mat_t mat1, const bool_mat_t mat2); void bool_mat_pow_ui(bool_mat_t B, const bool_mat_t A, ulong exp); BOOL_MAT_INLINE void bool_mat_sqr(bool_mat_t B, const bool_mat_t A) { bool_mat_mul(B, A, A); } /* Special functions */ int bool_mat_trace(const bool_mat_t mat); slong bool_mat_nilpotency_degree(const bool_mat_t mat); void bool_mat_transitive_closure(bool_mat_t dest, const bool_mat_t src); slong bool_mat_get_strongly_connected_components(slong *partition, const bool_mat_t A); slong bool_mat_all_pairs_longest_walk(fmpz_mat_t B, const bool_mat_t A); #ifdef __cplusplus } #endif #endif arb-2.22.1/bool_mat/000077500000000000000000000000001417376376500141615ustar00rootroot00000000000000arb-2.22.1/bool_mat/add.c000066400000000000000000000014371417376376500150620ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_add(bool_mat_t res, const bool_mat_t mat1, const bool_mat_t mat2) { slong i, j; if (bool_mat_is_empty(mat1)) return; for (i = 0; i < bool_mat_nrows(mat1); i++) for (j = 0; j < bool_mat_ncols(mat1); j++) bool_mat_set_entry(res, i, j, (bool_mat_get_entry(mat1, i, j) | bool_mat_get_entry(mat2, i, j))); } arb-2.22.1/bool_mat/all.c000066400000000000000000000012651417376376500151010ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int bool_mat_all(const bool_mat_t mat) { slong i, j; if (bool_mat_is_empty(mat)) return 1; for (i = 0; i < bool_mat_nrows(mat); i++) for (j = 0; j < bool_mat_ncols(mat); j++) if (!bool_mat_get_entry(mat, i, j)) return 0; return 1; } arb-2.22.1/bool_mat/all_pairs_longest_walk.c000066400000000000000000000201171417376376500210450ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" /* * Condensation of a matrix. * This is the directed acyclic graph of strongly connected components. */ typedef struct { slong n; /* number of vertices in the original graph */ slong k; /* number of strongly connnected components (sccs) */ bool_mat_t C; /* adjacency matrix of the sccs in the condensation */ slong *partition; /* maps the vertex index to the scc index */ } _condensation_struct; typedef _condensation_struct _condensation_t[1]; static void _condensation_init(_condensation_t c, const bool_mat_t A) { slong i, j, u, v; if (!bool_mat_is_square(A)) flint_abort(); /* assert */ c->n = bool_mat_nrows(A); c->partition = flint_malloc(c->n * sizeof(slong)); c->k = bool_mat_get_strongly_connected_components(c->partition, A); /* * Compute the adjacency matrix of the condensation. * This should be strict lower triangular, so that visiting the * vertices in increasing order corresponds to a postorder traversal. */ bool_mat_init(c->C, c->k, c->k); bool_mat_zero(c->C); for (i = 0; i < c->n; i++) { for (j = 0; j < c->n; j++) { if (bool_mat_get_entry(A, i, j)) { u = c->partition[i]; v = c->partition[j]; if (u != v) { bool_mat_set_entry(c->C, u, v, 1); } } } } /* assert */ if (!bool_mat_is_lower_triangular(c->C) || bool_mat_trace(c->C)) { flint_printf("_condensation_init: internal error: " "unexpected matrix structure\n"); bool_mat_print(c->C); flint_printf("\n"); flint_abort(); } } static void _condensation_clear(_condensation_t c) { bool_mat_clear(c->C); flint_free(c->partition); } typedef struct { _condensation_t con; bool_mat_t T; /* transitive closure of condensation */ bool_mat_t P; /* is there a cycle in any component on a path from u to v */ fmpz_mat_t Q; /* longest path, if any, from u to v */ int *scc_has_cycle; } _connectivity_struct; typedef _connectivity_struct _connectivity_t[1]; static void _connectivity_clear(_connectivity_t c) { bool_mat_clear(c->T); bool_mat_clear(c->P); fmpz_mat_clear(c->Q); flint_free(c->scc_has_cycle); _condensation_clear(c->con); } static void _connectivity_init_scc_has_cycle(_connectivity_t c, const bool_mat_t A) { slong n, i, u; slong *scc_size; n = bool_mat_nrows(A); c->scc_has_cycle = flint_calloc(n, sizeof(int)); /* * If a vertex of the original graph has a loop, * then the strongly connected component to which it belongs has a cycle. */ for (i = 0; i < n; i++) { if (bool_mat_get_entry(A, i, i)) { u = c->con->partition[i]; c->scc_has_cycle[u] = 1; } } /* * If a strongly connected component contains more than one vertex, * then that component has a cycle. */ scc_size = flint_calloc(c->con->k, sizeof(slong)); for (i = 0; i < n; i++) { u = c->con->partition[i]; scc_size[u]++; } for (u = 0; u < c->con->k; u++) { if (scc_size[u] > 1) { c->scc_has_cycle[u] = 1; } } flint_free(scc_size); } static void _connectivity_init(_connectivity_t c, const bool_mat_t A) { slong u, v, w; slong k; slong curr, rest; /* compute the condensation */ _condensation_init(c->con, A); k = c->con->k; /* check whether each scc contains a cycle */ _connectivity_init_scc_has_cycle(c, A); /* compute the transitive closure of the condensation */ bool_mat_init(c->T, k, k); bool_mat_transitive_closure(c->T, c->con->C); /* * Is there a walk from u to v that passes through a cycle-containing scc? * Cycles in the components u and v themselves are not considered. * Remember that the condensation is a directed acyclic graph. */ bool_mat_init(c->P, k, k); bool_mat_zero(c->P); for (w = 0; w < k; w++) { if (c->scc_has_cycle[w]) { for (u = 0; u < k; u++) { for (v = 0; v < k; v++) { if (bool_mat_get_entry(c->T, u, w) && bool_mat_get_entry(c->T, w, v)) { bool_mat_set_entry(c->P, u, v, 1); } } } } } /* * What is the max length path from u to v in the condensation graph? * If u==v or if v is unreachable from u then let this be zero. * Remember that the condensation is a directed acyclic graph, * and that the components are indexed in a post-order traversal. */ fmpz_mat_init(c->Q, k, k); fmpz_mat_zero(c->Q); for (u = 0; u < k; u++) { for (w = 0; w < k; w++) { if (bool_mat_get_entry(c->con->C, u, w)) { curr = fmpz_get_si(fmpz_mat_entry(c->Q, u, w)); fmpz_set_si( fmpz_mat_entry(c->Q, u, w), FLINT_MAX(curr, 1)); for (v = 0; v < k; v++) { if (bool_mat_get_entry(c->T, w, v)) { rest = fmpz_get_si(fmpz_mat_entry(c->Q, w, v)); curr = fmpz_get_si(fmpz_mat_entry(c->Q, u, v)); fmpz_set_si( fmpz_mat_entry(c->Q, u, v), FLINT_MAX(curr, rest + 1)); } } } } } } static void _connectivity_entrywise_nilpotence_degree( fmpz_t N, _connectivity_t c, slong i, slong j) { slong u, v; u = c->con->partition[i]; v = c->con->partition[j]; if (u == v) { if (c->scc_has_cycle[u]) { fmpz_set_si(N, -1); } else { fmpz_one(N); } } else if (!bool_mat_get_entry(c->T, u, v)) { fmpz_zero(N); } else if ( c->scc_has_cycle[u] || c->scc_has_cycle[v] || bool_mat_get_entry(c->P, u, v)) { fmpz_set_si(N, -1); } else { fmpz_add_ui(N, fmpz_mat_entry(c->Q, u, v), 1); } } slong bool_mat_all_pairs_longest_walk(fmpz_mat_t B, const bool_mat_t A) { slong n; if (!bool_mat_is_square(A)) { flint_printf("bool_mat_all_pairs_longest_walk: " "a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(A)) return -1; n = bool_mat_nrows(A); if (n == 1) { if (bool_mat_get_entry(A, 0, 0)) { fmpz_set_si(fmpz_mat_entry(B, 0, 0), -2); return -2; } else { fmpz_set_si(fmpz_mat_entry(B, 0, 0), 0); return 0; } } else { slong i, j, result; _connectivity_t c; _connectivity_init(c, A); result = -1; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { slong x; fmpz *p = fmpz_mat_entry(B, i, j); _connectivity_entrywise_nilpotence_degree(p, c, i, j); fmpz_sub_ui(p, p, 1); if (result != -2) { x = fmpz_get_si(p); if (x == -2) { result = -2; } else { result = FLINT_MAX(result, x); } } } } _connectivity_clear(c); return result; } } arb-2.22.1/bool_mat/any.c000066400000000000000000000012641417376376500151170ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int bool_mat_any(const bool_mat_t mat) { slong i, j; if (bool_mat_is_empty(mat)) return 0; for (i = 0; i < bool_mat_nrows(mat); i++) for (j = 0; j < bool_mat_ncols(mat); j++) if (bool_mat_get_entry(mat, i, j)) return 1; return 0; } arb-2.22.1/bool_mat/clear.c000066400000000000000000000010401417376376500154060ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_clear(bool_mat_t mat) { if (mat->entries != NULL) { flint_free(mat->entries); flint_free(mat->rows); } } arb-2.22.1/bool_mat/complement.c000066400000000000000000000012771417376376500164770ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_complement(bool_mat_t dest, const bool_mat_t src) { slong i, j; if (bool_mat_is_empty(src)) return; for (i = 0; i < bool_mat_nrows(src); i++) for (j = 0; j < bool_mat_ncols(src); j++) bool_mat_set_entry(dest, i, j, !bool_mat_get_entry(src, i, j)); } arb-2.22.1/bool_mat/directed_cycle.c000066400000000000000000000013431417376376500172700ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_directed_cycle(bool_mat_t mat) { if (!bool_mat_is_square(mat)) { flint_printf("bool_mat_directed_cycle: a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(mat)) return; bool_mat_directed_path(mat); bool_mat_set_entry(mat, bool_mat_nrows(mat) - 1, 0, 1); } arb-2.22.1/bool_mat/directed_path.c000066400000000000000000000014241417376376500171250ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_directed_path(bool_mat_t mat) { slong i; if (!bool_mat_is_square(mat)) { flint_printf("bool_mat_directed_path: a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(mat)) return; bool_mat_zero(mat); for (i = 0; i < bool_mat_nrows(mat) - 1; i++) { bool_mat_set_entry(mat, i, i+1, 1); } } arb-2.22.1/bool_mat/equal.c000066400000000000000000000015611417376376500154370ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int bool_mat_equal(const bool_mat_t mat1, const bool_mat_t mat2) { slong i, j; if ((bool_mat_nrows(mat1) != bool_mat_nrows(mat2)) || (bool_mat_ncols(mat1) != bool_mat_ncols(mat2))) return 0; for (i = 0; i < bool_mat_nrows(mat1); i++) for (j = 0; j < bool_mat_ncols(mat1); j++) if (bool_mat_get_entry(mat1, i, j) != bool_mat_get_entry(mat2, i, j)) { return 0; } return 1; } arb-2.22.1/bool_mat/fprint.c000066400000000000000000000015011417376376500156240ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_fprint(FILE * file, const bool_mat_t mat) { slong i, j; for (i = 0; i < bool_mat_nrows(mat); i++) { flint_fprintf(file, "["); for (j = 0; j < bool_mat_ncols(mat); j++) { flint_fprintf(file, "%d", bool_mat_get_entry(mat, i, j)); if (j < bool_mat_ncols(mat) - 1) flint_fprintf(file, ", "); } flint_fprintf(file, "]\n"); } } arb-2.22.1/bool_mat/get_strongly_connected_components.c000066400000000000000000000106071417376376500233400ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" /* fixed-capacity stack */ typedef struct { slong *data; slong capacity; slong size; } _si_stack_struct; typedef _si_stack_struct _si_stack_t[1]; static void _si_stack_init(_si_stack_t s, slong capacity) { s->data = flint_malloc(capacity * sizeof(slong)); s->capacity = capacity; s->size = 0; } static void _si_stack_clear(_si_stack_t s) { flint_free(s->data); } static void _si_stack_push(_si_stack_t s, slong x) { if (s->size >= s->capacity) flint_abort(); /* assert */ s->data[s->size++] = x; } static slong _si_stack_pop(_si_stack_t s) { slong x; if (s->size <= 0) flint_abort(); /* assert */ x = s->data[s->size - 1]; s->size--; return x; } /* struct for Tarjan's strongly connected components algorithm */ typedef struct { slong *index; slong *lowlink; int *onstack; _si_stack_t S; slong nsccs; slong dim; slong idx; } _tarjan_struct; typedef _tarjan_struct _tarjan_t[1]; static const slong _tarjan_UNDEFINED = -1; static slong * _tarjan_index(_tarjan_t t, slong i) { return t->index + i; } static slong * _tarjan_lowlink(_tarjan_t t, slong i) { return t->lowlink + i; } static int _tarjan_onstack(_tarjan_t t, slong i) { return t->onstack[i]; } static void _tarjan_push(_tarjan_t t, slong v) { _si_stack_push(t->S, v); t->onstack[v] = 1; } static slong _tarjan_pop(_tarjan_t t) { slong v; v = _si_stack_pop(t->S); t->onstack[v] = 0; return v; } static slong _tarjan_next_scc(_tarjan_t t) { return t->nsccs++; } static slong _tarjan_next_idx(_tarjan_t t) { return t->idx++; } static void _tarjan_init(_tarjan_t t, slong dim) { slong i; t->index = flint_calloc(dim, sizeof(slong)); t->lowlink = flint_calloc(dim, sizeof(slong)); t->onstack = flint_calloc(dim, sizeof(int)); _si_stack_init(t->S, dim); t->dim = dim; t->nsccs = 0; t->idx = 0; for (i = 0; i < dim; i++) { t->index[i] = _tarjan_UNDEFINED; } } static void _tarjan_clear(_tarjan_t t) { flint_free(t->index); flint_free(t->lowlink); flint_free(t->onstack); _si_stack_clear(t->S); } static void _tarjan_strongconnect(slong *sccs, _tarjan_t t, const bool_mat_t A, slong v) { slong idx, w, scc; idx = _tarjan_next_idx(t); *_tarjan_index(t, v) = idx; *_tarjan_lowlink(t, v) = idx; _tarjan_push(t, v); for (w = 0; w < t->dim; w++) { if (bool_mat_get_entry(A, v, w)) { if (*_tarjan_index(t, w) == _tarjan_UNDEFINED) { _tarjan_strongconnect(sccs, t, A, w); *_tarjan_lowlink(t, v) = FLINT_MIN( *_tarjan_lowlink(t, v), *_tarjan_lowlink(t, w)); } else if (_tarjan_onstack(t, w)) { *_tarjan_lowlink(t, v) = FLINT_MIN( *_tarjan_lowlink(t, v), *_tarjan_index(t, w)); } } } if (*_tarjan_lowlink(t, v) == *_tarjan_index(t, v)) { scc = _tarjan_next_scc(t); while (w != v) { w = _tarjan_pop(t); if (sccs[w] != _tarjan_UNDEFINED) flint_abort(); /* assert */ sccs[w] = scc; } } } /* following Tarjan */ slong bool_mat_get_strongly_connected_components(slong *partition, const bool_mat_t A) { slong i, n, result; _tarjan_t t; if (!bool_mat_is_square(A)) { flint_printf("bool_mat_get_strongly_connected_components: " "a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(A)) return 0; n = bool_mat_nrows(A); if (n == 1) { partition[0] = 0; return 1; } _tarjan_init(t, n); for (i = 0; i < n; i++) { partition[i] = _tarjan_UNDEFINED; } for (i = 0; i < n; i++) { if (*_tarjan_index(t, i) == _tarjan_UNDEFINED) { _tarjan_strongconnect(partition, t, A, i); } } result = t->nsccs; _tarjan_clear(t); return result; } arb-2.22.1/bool_mat/init.c000066400000000000000000000014131417376376500152670ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_init(bool_mat_t mat, slong r, slong c) { mat->entries = NULL; mat->rows = NULL; mat->r = r; mat->c = c; if (r != 0 && c != 0) { slong i; mat->entries = flint_calloc(r * c, sizeof(int)); mat->rows = flint_malloc(r * sizeof(int *)); for (i = 0; i < r; i++) mat->rows[i] = mat->entries + i * c; } } arb-2.22.1/bool_mat/is_diagonal.c000066400000000000000000000013061417376376500165760ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int bool_mat_is_diagonal(const bool_mat_t mat) { slong i, j; if (bool_mat_is_empty(mat)) return 1; for (i = 0; i < bool_mat_nrows(mat); i++) for (j = 0; j < bool_mat_ncols(mat); j++) if (i != j && bool_mat_get_entry(mat, i, j)) return 0; return 1; } arb-2.22.1/bool_mat/is_lower_triangular.c000066400000000000000000000013151417376376500204000ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int bool_mat_is_lower_triangular(const bool_mat_t mat) { slong i, j; if (bool_mat_is_empty(mat)) return 1; for (j = 0; j < bool_mat_ncols(mat); j++) for (i = 0; i < bool_mat_nrows(mat) && i < j; i++) if (bool_mat_get_entry(mat, i, j)) return 0; return 1; } arb-2.22.1/bool_mat/is_nilpotent.c000066400000000000000000000037731417376376500170460ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" /* * Cycle detection, following * https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search */ typedef struct { int *u; /* 'temporary mark' */ int *v; /* 'permanent mark' */ slong size; } _cycle_detection_s; static void _cycle_detection_init(_cycle_detection_s *s, slong size) { s->size = size; s->u = flint_calloc(size, sizeof(int)); s->v = flint_calloc(size, sizeof(int)); } static void _cycle_detection_clear(_cycle_detection_s *s) { flint_free(s->u); flint_free(s->v); } static int _cycle_detection_visit(_cycle_detection_s *s, const bool_mat_t A, slong n) { if (s->u[n]) return 1; if (!s->v[n]) { slong m; s->u[n] = 1; for (m = 0; m < s->size; m++) if (bool_mat_get_entry(A, n, m)) if (_cycle_detection_visit(s, A, m)) return 1; s->v[n] = 1; s->u[n] = 0; } return 0; } int bool_mat_is_nilpotent(const bool_mat_t A) { slong n; if (!bool_mat_is_square(A)) { flint_printf("bool_mat_is_nilpotent: a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(A)) return 0; n = bool_mat_nrows(A); if (n == 1) { return !bool_mat_get_entry(A, 0, 0); } else { _cycle_detection_s s; slong i; int has_cycle; _cycle_detection_init(&s, n); for (has_cycle = 0, i = 0; !has_cycle && i < n; i++) if (!s.v[i]) has_cycle = _cycle_detection_visit(&s, A, i); _cycle_detection_clear(&s); return !has_cycle; } } arb-2.22.1/bool_mat/is_transitive.c000066400000000000000000000020231417376376500172050ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int bool_mat_is_transitive(const bool_mat_t mat) { slong n, i, j, k; if (!bool_mat_is_square(mat)) { flint_printf("bool_mat_is_transitive: a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(mat)) return 1; n = bool_mat_nrows(mat); for (i = 0; i < n; i++) for (j = 0; j < n; j++) for (k = 0; k < n; k++) if (bool_mat_get_entry(mat, i, j) && bool_mat_get_entry(mat, j, k) && !bool_mat_get_entry(mat, i, k)) { return 0; } return 1; } arb-2.22.1/bool_mat/mul.c000066400000000000000000000025471417376376500151320ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_mul(bool_mat_t C, const bool_mat_t A, const bool_mat_t B) { slong ar, ac, br, bc, i, j, k; ar = bool_mat_nrows(A); ac = bool_mat_ncols(A); br = bool_mat_nrows(B); bc = bool_mat_ncols(B); if (ac != br || ar != bool_mat_nrows(C) || bc != bool_mat_ncols(C)) { flint_printf("bool_mat_mul: incompatible dimensions\n"); flint_abort(); } if (br == 0) { bool_mat_zero(C); return; } if (A == C || B == C) { bool_mat_t T; bool_mat_init(T, ar, bc); bool_mat_mul(T, A, B); bool_mat_swap(T, C); bool_mat_clear(T); return; } for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { int any = 0; for (k = 0; k < br && !any; k++) any |= (bool_mat_get_entry(A, i, k) & bool_mat_get_entry(B, k, j)); bool_mat_set_entry(C, i, j, any); } } } arb-2.22.1/bool_mat/mul_entrywise.c000066400000000000000000000017201417376376500172330ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_mul_entrywise(bool_mat_t C, const bool_mat_t A, const bool_mat_t B) { slong i, j; if (bool_mat_nrows(A) != bool_mat_nrows(B) || bool_mat_ncols(A) != bool_mat_ncols(B)) { flint_printf("bool_mat_mul_entrywise: incompatible dimensions\n"); flint_abort(); } for (i = 0; i < bool_mat_nrows(A); i++) { for (j = 0; j < bool_mat_ncols(A); j++) { bool_mat_set_entry(C, i, j, (bool_mat_get_entry(A, i, j) & bool_mat_get_entry(B, i, j))); } } } arb-2.22.1/bool_mat/nilpotency_degree.c000066400000000000000000000064771417376376500200420ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/fmpz_mat.h" #include "bool_mat.h" /* * Postorder traversal of a DAG follows * https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search */ typedef struct { int *u; /* 'temporary mark' */ int *v; /* 'permanent mark' */ slong *post; /* postorder nodes */ slong npost; /* number of postorder nodes so far */ slong size; } _toposort_s; static void _toposort_init(_toposort_s *s, slong size) { s->size = size; s->u = flint_calloc(size, sizeof(int)); s->v = flint_calloc(size, sizeof(int)); s->post = flint_malloc(size * sizeof(slong)); s->npost = 0; } static void _toposort_clear(_toposort_s *s) { flint_free(s->u); flint_free(s->v); flint_free(s->post); } static int _toposort_visit(_toposort_s *s, const bool_mat_t A, slong n) { if (s->u[n]) return 1; if (!s->v[n]) { slong m; s->u[n] = 1; for (m = 0; m < s->size; m++) if (bool_mat_get_entry(A, n, m)) if (_toposort_visit(s, A, m)) return 1; s->v[n] = 1; s->u[n] = 0; s->post[s->npost++] = n; } return 0; } slong bool_mat_nilpotency_degree(const bool_mat_t A) { slong n; if (!bool_mat_is_square(A)) { flint_printf("bool_mat_nilpotency_degree: a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(A)) return 0; n = bool_mat_nrows(A); if (n == 1) { return bool_mat_get_entry(A, 0, 0) ? -1 : 1; } else { _toposort_s s; slong i; int has_cycle; int result; _toposort_init(&s, n); for (has_cycle = 0, i = 0; !has_cycle && i < n; i++) if (!s.v[i]) has_cycle = _toposort_visit(&s, A, i); if (has_cycle) { result = -1; } else { /* Find the length of the longest path within the DAG */ /* http://stackoverflow.com/a/10737524/4072759 */ slong x, y, z; slong max_overall; fmpz_mat_t E; fmpz_mat_init(E, n, n); fmpz_mat_zero(E); max_overall = 0; for (i = n - 1; i >= 0; i--) { slong max_in = 0; y = s.post[i]; for (x = 0; x < n; x++) { max_in = FLINT_MAX(max_in, fmpz_get_si(fmpz_mat_entry(E, x, y))); } for (z = 0; z < n; z++) { if (bool_mat_get_entry(A, y, z)) { fmpz_set_si(fmpz_mat_entry(E, y, z), max_in + 1); max_overall = FLINT_MAX(max_overall, max_in + 1); } } } fmpz_mat_clear(E); result = max_overall + 1; } _toposort_clear(&s); return result; } } arb-2.22.1/bool_mat/one.c000066400000000000000000000011271417376376500151070ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_one(bool_mat_t mat) { slong i, j; for (i = 0; i < bool_mat_nrows(mat); i++) for (j = 0; j < bool_mat_ncols(mat); j++) bool_mat_set_entry(mat, i, j, i == j); } arb-2.22.1/bool_mat/pow_ui.c000066400000000000000000000030441417376376500156300ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_pow_ui(bool_mat_t B, const bool_mat_t A, ulong exp) { slong d; if (!bool_mat_is_square(A)) { flint_printf("bool_mat_pow_ui: a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(A)) return; d = bool_mat_nrows(A); if (exp <= 2 || d <= 1) { if (exp == 0) { bool_mat_one(B); } else if (d == 1) { bool_mat_set_entry(B, 0, 0, bool_mat_get_entry(A, 0, 0)); } else if (exp == 1) { bool_mat_set(B, A); } else if (exp == 2) { bool_mat_sqr(B, A); } } else { slong i; bool_mat_t T, U; bool_mat_init(T, d, d); bool_mat_set(T, A); bool_mat_init(U, d, d); for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--) { bool_mat_sqr(U, T); if (exp & (WORD(1) << i)) bool_mat_mul(T, U, A); else bool_mat_swap(T, U); } bool_mat_swap(B, T); bool_mat_clear(T); bool_mat_clear(U); } } arb-2.22.1/bool_mat/randtest.c000066400000000000000000000046061417376376500161570ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/perm.h" #include "bool_mat.h" void bool_mat_randtest(bool_mat_t mat, flint_rand_t state) { slong i, j; mp_limb_t density; density = n_randint(state, 101); for (i = 0; i < bool_mat_nrows(mat); i++) for (j = 0; j < bool_mat_ncols(mat); j++) bool_mat_set_entry(mat, i, j, n_randint(state, 100) < density); } void bool_mat_randtest_diagonal(bool_mat_t mat, flint_rand_t state) { slong n, i; slong density; n = FLINT_MIN(bool_mat_nrows(mat), bool_mat_ncols(mat)); density = n_randint(state, 101); bool_mat_zero(mat); for (i = 0; i < n; i++) bool_mat_set_entry(mat, i, i, n_randint(state, 100) < density); } void bool_mat_randtest_nilpotent(bool_mat_t mat, flint_rand_t state) { slong n, i, j; slong density; if (!bool_mat_is_square(mat)) { flint_printf("bool_mat_randtest_nilpotent: " "a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(mat)) { flint_printf("bool_mat_randtest_nilpotent: " "a non-empty matrix is required!\n"); flint_abort(); } n = bool_mat_nrows(mat); if (n == 1) { bool_mat_set_entry(mat, 0, 0, 0); return; } /* sample a strictly triangular matrix */ density = n_randint(state, 101); bool_mat_zero(mat); for (i = 0; i < n; i++) { for (j = 0; j < i; j++) { bool_mat_set_entry(mat, i, j, n_randint(state, 100) < density); } } /* permute rows and columns */ { slong *p; bool_mat_t A; bool_mat_init(A, n, n); bool_mat_set(A, mat); p = flint_malloc(n * sizeof(slong)); _perm_randtest(p, n, state); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { bool_mat_set_entry( mat, p[i], p[j], bool_mat_get_entry(A, i, j)); } } flint_free(p); bool_mat_clear(A); } } arb-2.22.1/bool_mat/set.c000066400000000000000000000013061417376376500151200ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_set(bool_mat_t dest, const bool_mat_t src) { slong i, j; if (dest == src || bool_mat_is_empty(src)) return; for (i = 0; i < bool_mat_nrows(src); i++) for (j = 0; j < bool_mat_ncols(src); j++) bool_mat_set_entry(dest, i, j, bool_mat_get_entry(src, i, j)); } arb-2.22.1/bool_mat/test/000077500000000000000000000000001417376376500151405ustar00rootroot00000000000000arb-2.22.1/bool_mat/test/t-all_pairs_longest_walk.c000066400000000000000000000233621417376376500222720ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" #include "flint/perm.h" int _is_superficially_ok_entrywise(const fmpz_mat_t A) { slong n, i, j, d; if (!fmpz_mat_is_square(A)) return 0; n = fmpz_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { d = fmpz_get_si(fmpz_mat_entry(A, i, j)); if (d < -2 || d > n-1) return 0; if (i == j && d == -1) return 0; if (i != j && d == 0) return 0; } } return 1; } void _bool_mat_permute(bool_mat_t B, const bool_mat_t A, const slong *perm) { slong n, i, j; if (!bool_mat_is_square(A)) flint_abort(); /* assert */ if (A == B) flint_abort(); /* assert */ n = bool_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { bool_mat_set_entry( B, perm[i], perm[j], bool_mat_get_entry(A, i, j)); } } } void _fmpz_mat_permute(fmpz_mat_t B, const fmpz_mat_t A, const slong *perm) { slong n, i, j; if (!fmpz_mat_is_square(A)) flint_abort(); /* assert */ if (A == B) flint_abort(); /* assert */ n = fmpz_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { fmpz_set( fmpz_mat_entry(B, perm[i], perm[j]), fmpz_mat_entry(A, i, j)); } } } void _brute_force_all_pairs_longest_walk(fmpz_mat_t B, const bool_mat_t A) { slong i, j, n; n = bool_mat_nrows(A); /* set entries of B according to the longest observed walk */ { slong k; bool_mat_t T; bool_mat_init(T, n, n); bool_mat_one(T); fmpz_mat_zero(B); for (k = 0; k < 2*n+1; k++) { for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (bool_mat_get_entry(T, i, j)) { fmpz_set_si(fmpz_mat_entry(B, i, j), k); } } } bool_mat_mul(T, T, A); } bool_mat_clear(T); } /* set special values 0, -1, -2 */ { for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { slong x; fmpz *p; p = fmpz_mat_entry(B, i, j); x = fmpz_get_si(p); if (x < 1) { x = (i == j) ? 0 : -1; } else if (x > n-1) { x = -2; } fmpz_set_si(p, x); } } } } int main() { slong iter; flint_rand_t state; flint_printf("all_pairs_longest_walk...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, degree; bool_mat_t A; fmpz_mat_t B, C, D; m = n_randint(state, 50); bool_mat_init(A, m, m); fmpz_mat_init(B, m, m); fmpz_mat_init(C, m, m); fmpz_mat_init(D, m, m); bool_mat_randtest(A, state); degree = bool_mat_all_pairs_longest_walk(B, A); /* entrywise reasonability */ if (!_is_superficially_ok_entrywise(B)) { flint_printf("FAIL (entrywise)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); flint_abort(); } /* nilpotency degree */ { slong nildegree = bool_mat_nilpotency_degree(A); if (nildegree != degree + 1) { flint_printf("FAIL (nilpotency degree)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); flint_printf("nildegree=%wd degree=%wd\n", nildegree, degree); flint_abort(); } } /* transitive closure */ { slong i, j; bool_mat_t U, V; bool_mat_init(U, m, m); bool_mat_transitive_closure(U, A); bool_mat_init(V, m, m); for (i = 0; i < m; i++) { for (j = 0; j < m; j++) { slong x = fmpz_get_si(fmpz_mat_entry(B, i, j)); bool_mat_set_entry(V, i, j, (x != -1 && x != 0)); } } if (!bool_mat_equal(U, V)) { flint_printf("FAIL (transitive closure)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); bool_mat_print(U); flint_printf("\n"); bool_mat_print(V); flint_printf("\n"); flint_abort(); } bool_mat_clear(U); bool_mat_clear(V); } /* test commutativity of all-pairs-longest-walk with permutation */ { bool_mat_t Ap; slong *perm; bool_mat_init(Ap, m, m); perm = flint_malloc(m * sizeof(slong)); _perm_randtest(perm, m, state); /* C is the all-pairs-longest-walk of the permutation of A */ _bool_mat_permute(Ap, A, perm); bool_mat_all_pairs_longest_walk(C, Ap); /* D is the permutation of the all-pairs-longest-walk of A */ _fmpz_mat_permute(D, B, perm); if (!fmpz_mat_equal(C, D)) { flint_printf("FAIL (permutation)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); fmpz_mat_print_pretty(C); flint_printf("\n"); fmpz_mat_print_pretty(D); flint_printf("\n"); flint_abort(); } flint_free(perm); bool_mat_clear(Ap); } bool_mat_clear(A); fmpz_mat_clear(B); fmpz_mat_clear(C); fmpz_mat_clear(D); } /* use powering to check small random examples */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m; bool_mat_t A; fmpz_mat_t B, C; m = n_randint(state, 10); bool_mat_init(A, m, m); fmpz_mat_init(B, m, m); fmpz_mat_init(C, m, m); bool_mat_randtest(A, state); bool_mat_all_pairs_longest_walk(B, A); _brute_force_all_pairs_longest_walk(C, A); if (!fmpz_mat_equal(B, C)) { flint_printf("FAIL (powering)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); fmpz_mat_print_pretty(C); flint_printf("\n"); flint_abort(); } bool_mat_clear(A); fmpz_mat_clear(B); fmpz_mat_clear(C); } /* special matrices */ { slong m; for (m = 1; m < 100; m++) { slong i, j, length; bool_mat_t A; fmpz_mat_t B; bool_mat_init(A, m, m); fmpz_mat_init(B, m, m); /* directed path */ { bool_mat_directed_path(A); length = bool_mat_all_pairs_longest_walk(B, A); if (length != m-1) { flint_printf("FAIL (directed path)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); flint_printf("m=%wd length=%wd\n", m, length); flint_abort(); } for (i = 0; i < m; i++) { for (j = 0; j < m; j++) { if (fmpz_get_si(fmpz_mat_entry(B, i, j)) != FLINT_MAX(-1, j - i)) { flint_printf("FAIL (directed path)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); flint_abort(); } } } } /* directed cycle */ { bool_mat_directed_cycle(A); length = bool_mat_all_pairs_longest_walk(B, A); if (length != -2) { flint_printf("FAIL (directed cycle)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); flint_printf("m=%wd length=%wd\n", m, length); flint_abort(); } for (i = 0; i < m; i++) { for (j = 0; j < m; j++) { if (fmpz_get_si(fmpz_mat_entry(B, i, j)) != -2) { flint_printf("FAIL (directed cycle)\n"); bool_mat_print(A); flint_printf("\n"); fmpz_mat_print_pretty(B); flint_printf("\n"); flint_abort(); } } } } bool_mat_clear(A); fmpz_mat_clear(B); } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-complement.c000066400000000000000000000060641417376376500177160ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("complement...."); fflush(stdout); flint_randinit(state); /* zero matrix */ { slong m, n; for (m = 1; m < 10; m++) { for (n = 1; n < 10; n++) { bool_mat_t zero, C; bool_mat_init(zero, m, n); bool_mat_init(C, m, n); bool_mat_zero(zero); bool_mat_complement(C, zero); if (bool_mat_any(zero) || bool_mat_all(zero) || !bool_mat_any(C) || !bool_mat_all(C)) { flint_printf("FAIL (zero matrix)\n"); flint_abort(); } bool_mat_clear(zero); bool_mat_clear(C); } } } /* identity matrix */ { slong n; for (n = 2; n < 10; n++) { bool_mat_t one, C; bool_mat_init(one, n, n); bool_mat_init(C, n, n); bool_mat_one(one); bool_mat_complement(C, one); if (!bool_mat_any(one) || bool_mat_all(one) || !bool_mat_any(C) || bool_mat_all(C)) { flint_printf("FAIL (identity matrix)\n"); flint_abort(); } bool_mat_clear(one); bool_mat_clear(C); } } /* random matrices */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n; bool_mat_t A, C; m = n_randint(state, 10) + 1; n = n_randint(state, 10) + 1; bool_mat_init(A, m, n); bool_mat_init(C, m, n); bool_mat_randtest(A, state); bool_mat_randtest(C, state); bool_mat_complement(C, A); if ((bool_mat_all(A) && bool_mat_any(C)) || (bool_mat_all(C) && bool_mat_any(A))) { flint_printf("FAIL\n"); flint_abort(); } /* involution */ { bool_mat_t CC; bool_mat_init(CC, m, n); bool_mat_randtest(CC, state); bool_mat_complement(CC, C); if (!bool_mat_equal(A, CC)) { flint_printf("FAIL (involution)\n"); flint_abort(); } bool_mat_clear(CC); } /* aliasing */ bool_mat_complement(A, A); if (!bool_mat_equal(A, C)) { flint_printf("FAIL (aliasing)\n"); flint_abort(); } bool_mat_clear(A); bool_mat_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-is_diagonal.c000066400000000000000000000052551417376376500200250ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("is_diagonal...."); fflush(stdout); flint_randinit(state); /* all zero matrices are diagonal */ { slong m, n; for (m = 0; m < 10; m++) { for (n = 0; n < 10; n++) { bool_mat_t zero; bool_mat_init(zero, m, n); bool_mat_zero(zero); if (!bool_mat_is_diagonal(zero)) { flint_printf("FAIL (zero matrix)\n"); flint_abort(); } bool_mat_clear(zero); } } } /* all identity matrices are diagonal */ { slong n; for (n = 0; n < 10; n++) { bool_mat_t one; bool_mat_init(one, n, n); bool_mat_one(one); if (!bool_mat_is_diagonal(one)) { flint_printf("FAIL (identity matrix)\n"); flint_abort(); } bool_mat_clear(one); } } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n; bool_mat_t A; m = n_randint(state, 10) + 1; n = n_randint(state, 10) + 1; bool_mat_init(A, m, n); /* random diagonal */ { bool_mat_randtest_diagonal(A, state); if (!bool_mat_is_diagonal(A)) { flint_printf("FAIL (random diagonal)\n"); flint_printf("A:\n"); bool_mat_print(A); flint_printf("\n"); flint_abort(); } } /* random non-diagonal */ { slong i, j; bool_mat_randtest(A, state); i = n_randint(state, m); j = n_randint(state, n); if (i != j) { bool_mat_set_entry(A, i, j, 1); if (bool_mat_is_diagonal(A)) { flint_printf("FAIL (random non-diagonal)\n"); flint_printf("A:\n"); bool_mat_print(A); flint_printf("\n"); flint_abort(); } } } bool_mat_clear(A); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-is_nilpotent.c000066400000000000000000000042021417376376500202520ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("is_nilpotent...."); fflush(stdout); flint_randinit(state); /* empty matrix is not nilpotent(?) */ { bool_mat_t A; bool_mat_init(A, 0, 0); if (bool_mat_is_nilpotent(A)) { flint_printf("FAIL (empty)\n"); flint_abort(); } bool_mat_clear(A); } /* detect nilpotency of matrices that are constructed to be nilpotent */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m; bool_mat_t A; m = n_randint(state, 10) + 1; bool_mat_init(A, m, m); bool_mat_randtest_nilpotent(A, state); if (!bool_mat_is_nilpotent(A)) { flint_printf("FAIL (nilpotent by construction)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n"); flint_abort(); } bool_mat_clear(A); } /* check nilpotency by computing a matrix power */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m; bool_mat_t A, B; m = n_randint(state, 10) + 1; bool_mat_init(A, m, m); bool_mat_init(B, m, m); bool_mat_randtest(A, state); bool_mat_pow_ui(B, A, m); if (bool_mat_is_nilpotent(A) != !bool_mat_any(B)) { flint_printf("FAIL (A^m)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n"); flint_printf("B = \n"); bool_mat_print(B); flint_printf("\n"); flint_abort(); } bool_mat_clear(A); bool_mat_clear(B); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-is_transitive.c000066400000000000000000000035141417376376500204330ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("is_transitive...."); fflush(stdout); flint_randinit(state); /* special matrices */ { slong n; for (n = 0; n < 10; n++) { bool_mat_t A; bool_mat_init(A, n, n); /* identity matrices are transitive */ bool_mat_one(A); if (!bool_mat_is_transitive(A)) { flint_printf("FAIL (identity matrix)\n"); flint_abort(); } /* square zero matrices are transitive */ bool_mat_zero(A); if (!bool_mat_is_transitive(A)) { flint_printf("FAIL (zero matrix)\n"); flint_abort(); } bool_mat_clear(A); } } for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong n; bool_mat_t A; n = n_randint(state, 10); bool_mat_init(A, n, n); /* all square diagonal matrices are transitive */ bool_mat_randtest_diagonal(A, state); if (!bool_mat_is_transitive(A)) { flint_printf("FAIL (diagonal)\n"); flint_printf("A:\n"); bool_mat_print(A); flint_printf("\n"); flint_abort(); } bool_mat_clear(A); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-mul.c000066400000000000000000000141631417376376500163470ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); /* test aliasing */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n; bool_mat_t A, B, C, D; m = n_randint(state, 10); n = n_randint(state, 10); /* test aliasing with a */ { bool_mat_init(A, m, n); bool_mat_init(B, n, n); bool_mat_init(C, m, n); bool_mat_init(D, m, n); bool_mat_randtest(A, state); bool_mat_randtest(B, state); bool_mat_mul(C, A, B); bool_mat_set(D, A); bool_mat_mul(D, D, B); if (!bool_mat_equal(D, C)) { flint_printf("FAIL (aliasing 1)\n"); flint_abort(); } bool_mat_clear(A); bool_mat_clear(B); bool_mat_clear(C); bool_mat_clear(D); } /* test aliasing with b */ { bool_mat_init(A, m, m); bool_mat_init(B, m, n); bool_mat_init(C, m, n); bool_mat_init(D, m, n); bool_mat_randtest(A, state); bool_mat_randtest(B, state); bool_mat_mul(C, A, B); bool_mat_set(D, B); bool_mat_mul(D, A, D); if (!bool_mat_equal(D, C)) { flint_printf("FAIL (aliasing 2)\n"); flint_abort(); } bool_mat_clear(A); bool_mat_clear(B); bool_mat_clear(C); bool_mat_clear(D); } } for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n, k, l; bool_mat_t a, b, c, d, ab, ac, bd, cd, s; m = n_randint(state, 10); n = n_randint(state, 10); k = n_randint(state, 10); l = n_randint(state, 10); bool_mat_init(a, m, n); bool_mat_init(b, n, k); bool_mat_init(c, n, k); bool_mat_init(d, k, l); bool_mat_randtest(a, state); bool_mat_randtest(b, state); bool_mat_randtest(c, state); bool_mat_randtest(d, state); bool_mat_init(ab, m, k); bool_mat_init(ac, m, k); bool_mat_init(bd, n, l); bool_mat_init(cd, n, l); bool_mat_init(s, n, k); bool_mat_mul(ab, a, b); bool_mat_mul(ac, a, c); bool_mat_mul(bd, b, d); bool_mat_mul(cd, c, d); bool_mat_add(s, b, c); /* check associativity of multiplication */ /* (A*B)*D = A*(B*D) */ { bool_mat_t lhs, rhs; bool_mat_init(lhs, m, l); bool_mat_init(rhs, m, l); bool_mat_mul(lhs, ab, d); bool_mat_mul(rhs, a, bd); if (!bool_mat_equal(lhs, rhs)) { flint_printf("FAIL (associativity)\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_abort(); } bool_mat_clear(lhs); bool_mat_clear(rhs); } /* check left distributivity of multiplication over addition */ /* A*(B + C) = A*B + A*C */ { bool_mat_t lhs, rhs; bool_mat_init(lhs, m, k); bool_mat_init(rhs, m, k); bool_mat_mul(lhs, a, s); bool_mat_add(rhs, ab, ac); if (!bool_mat_equal(lhs, rhs)) { flint_printf("FAIL (left distributivity)\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_abort(); } bool_mat_clear(lhs); bool_mat_clear(rhs); } /* check right distributivity of multiplication over addition */ /* (B + C)*D = B*D + C*D */ { bool_mat_t lhs, rhs; bool_mat_init(lhs, n, l); bool_mat_init(rhs, n, l); bool_mat_mul(lhs, s, d); bool_mat_add(rhs, bd, cd); if (!bool_mat_equal(lhs, rhs)) { flint_printf("FAIL (right distributivity)\n"); flint_printf("m, n, k, l = %wd, %wd, %wd, %wd\n", m, n, k, l); flint_abort(); } bool_mat_clear(lhs); bool_mat_clear(rhs); } /* check left multiplicative identity I*D = D */ { bool_mat_t one, lhs; bool_mat_init(one, k, k); bool_mat_init(lhs, k, l); bool_mat_one(one); bool_mat_mul(lhs, one, d); if (!bool_mat_equal(lhs, d)) { flint_printf("FAIL (left identity)\n"); flint_printf("k = %wd, l = %wd\n", k, l); flint_abort(); } bool_mat_clear(one); bool_mat_clear(lhs); } /* check right multiplicative identity A*I = A */ { bool_mat_t one, lhs; bool_mat_init(one, n, n); bool_mat_init(lhs, m, n); bool_mat_one(one); bool_mat_mul(lhs, a, one); if (!bool_mat_equal(lhs, a)) { flint_printf("FAIL (right identity)\n"); flint_printf("m = %wd, n = %wd\n", m, n); flint_abort(); } bool_mat_clear(one); bool_mat_clear(lhs); } bool_mat_clear(a); bool_mat_clear(b); bool_mat_clear(c); bool_mat_clear(d); bool_mat_clear(ab); bool_mat_clear(ac); bool_mat_clear(bd); bool_mat_clear(cd); bool_mat_clear(s); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-nilpotency_degree.c000066400000000000000000000035111417376376500212440ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("nilpotency_degree...."); fflush(stdout); flint_randinit(state); /* empty matrix */ { bool_mat_t A; bool_mat_init(A, 0, 0); if (bool_mat_nilpotency_degree(A) != 0) { flint_printf("FAIL (empty)\n"); flint_abort(); } bool_mat_clear(A); } /* check nilpotency degree by looking at each power of a matrix */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, i; bool_mat_t A, B; slong degree; m = n_randint(state, 10) + 1; bool_mat_init(A, m, m); bool_mat_init(B, m, m); bool_mat_randtest(A, state); bool_mat_one(B); for (degree = -1, i = 0; i < m && degree < 0; i++) { bool_mat_mul(B, B, A); if (!bool_mat_any(B)) degree = i+1; } if (bool_mat_nilpotency_degree(A) != degree) { flint_printf("FAIL (matrix powers)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n"); flint_printf("B = \n"); bool_mat_print(B); flint_printf("\n"); flint_printf("i = %wd\n", i); flint_abort(); } bool_mat_clear(A); bool_mat_clear(B); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-trace.c000066400000000000000000000113671417376376500166530ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("trace...."); fflush(stdout); flint_randinit(state); /* trace(empty) == 0 */ { bool_mat_t A; bool_mat_init(A, 0, 0); bool_mat_one(A); if (bool_mat_trace(A) != 0) { flint_printf("FAIL (empty)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n\n"); flint_abort(); } bool_mat_clear(A); } /* trace(zero) == 0 */ { slong n; bool_mat_t A; for (n = 1; n < 10; n++) { bool_mat_init(A, n, n); bool_mat_zero(A); if (bool_mat_trace(A) != 0) { flint_printf("FAIL (zero)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n\n"); flint_abort(); } bool_mat_clear(A); } } /* trace(one) == 1 */ { slong n; bool_mat_t A; for (n = 1; n < 10; n++) { bool_mat_init(A, n, n); bool_mat_one(A); if (bool_mat_trace(A) != 1) { flint_printf("FAIL (one)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n\n"); flint_abort(); } bool_mat_clear(A); } } /* traces of random matrices with modified diagonal */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong n, i; bool_mat_t A; n = n_randint(state, 10) + 1; bool_mat_init(A, n, n); bool_mat_randtest(A, state); i = (slong) n_randint(state, n); bool_mat_set_entry(A, i, i, 1); if (bool_mat_trace(A) != 1) { flint_printf("FAIL (diagonal has a non-zero entry)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n\n"); flint_abort(); } for (i = 0; i < n; i++) { bool_mat_set_entry(A, i, i, 0); } if (bool_mat_trace(A) != 0) { flint_printf("FAIL (diagonal is zero)\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n\n"); flint_abort(); } bool_mat_clear(A); } /* trace(A + B) == trace(A) + trace(B) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong n; bool_mat_t A, B, C; n = n_randint(state, 10); bool_mat_init(A, n, n); bool_mat_init(B, n, n); bool_mat_init(C, n, n); bool_mat_randtest(A, state); bool_mat_randtest(B, state); bool_mat_add(C, A, B); if (bool_mat_trace(C) != (bool_mat_trace(A) | bool_mat_trace(B))) { flint_printf("FAIL (trace(A+B) == trace(A) | trace(B))\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n\n"); flint_printf("B = \n"); bool_mat_print(B); flint_printf("\n\n"); flint_printf("A+B = \n"); bool_mat_print(C); flint_printf("\n\n"); flint_abort(); } bool_mat_clear(A); bool_mat_clear(B); bool_mat_clear(C); } /* trace(A*B) == trace(B*A) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong n, m; bool_mat_t A, B, AB, BA; n = n_randint(state, 10); m = n_randint(state, 10); bool_mat_init(A, n, m); bool_mat_init(B, m, n); bool_mat_init(AB, n, n); bool_mat_init(BA, m, m); bool_mat_randtest(A, state); bool_mat_randtest(B, state); bool_mat_mul(AB, A, B); bool_mat_mul(BA, B, A); if (bool_mat_trace(AB) != bool_mat_trace(BA)) { flint_printf("FAIL (trace(AB) == trace(BA))\n"); flint_printf("A = \n"); bool_mat_print(A); flint_printf("\n\n"); flint_printf("B = \n"); bool_mat_print(B); flint_printf("\n\n"); flint_printf("AB = \n"); bool_mat_print(AB); flint_printf("\n\n"); flint_printf("BA = \n"); bool_mat_print(BA); flint_printf("\n\n"); flint_abort(); } bool_mat_clear(A); bool_mat_clear(B); bool_mat_clear(AB); bool_mat_clear(BA); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-transitive_closure.c000066400000000000000000000116561417376376500215020ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" #include "flint/perm.h" /* permute rows and columns of a square matrix */ void _bool_mat_permute(bool_mat_t B, const bool_mat_t A, const slong *perm) { slong n, i, j; if ((A == B) || !bool_mat_is_square(A)) flint_abort(); /* assert */ n = bool_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { bool_mat_set_entry( B, perm[i], perm[j], bool_mat_get_entry(A, i, j)); } } } void _bool_mat_transitive_closure_powering(bool_mat_t B, const bool_mat_t A) { slong n, k; bool_mat_t T; if ((A == B) || !bool_mat_is_square(A)) flint_abort(); /* assert */ n = bool_mat_nrows(A); bool_mat_init(T, n, n); bool_mat_one(T); bool_mat_zero(B); for (k = 0; k < n; k++) { bool_mat_mul(T, T, A); bool_mat_add(B, B, T); } bool_mat_clear(T); } int main() { slong iter; flint_rand_t state; flint_printf("transitive_closure...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m; bool_mat_t A, B, C, D; m = n_randint(state, 50); bool_mat_init(A, m, m); bool_mat_init(B, m, m); bool_mat_init(C, m, m); bool_mat_init(D, m, m); bool_mat_randtest(A, state); bool_mat_randtest(B, state); bool_mat_transitive_closure(B, A); /* transitivity */ if (!bool_mat_is_transitive(B)) { flint_printf("FAIL (transitivity)\n"); bool_mat_print(A); flint_printf("\n"); bool_mat_print(B); flint_printf("\n"); flint_abort(); } /* monotonicity */ { bool_mat_complement(C, B); bool_mat_mul_entrywise(D, A, C); if (bool_mat_any(D)) { flint_printf("FAIL (monotonicity)\n"); bool_mat_print(A); flint_printf("\n"); bool_mat_print(B); flint_printf("\n"); flint_abort(); } } /* aliasing */ { bool_mat_set(C, A); bool_mat_transitive_closure(C, C); if (!bool_mat_equal(B, C)) { flint_printf("FAIL (aliasing)\n"); bool_mat_print(A); flint_printf("\n"); bool_mat_print(B); flint_printf("\n"); bool_mat_print(C); flint_printf("\n"); flint_abort(); } } /* test commutativity of permutation with transitive closure */ { slong *perm; perm = flint_malloc(m * sizeof(slong)); _perm_randtest(perm, m, state); /* C is the transitive closure of the permutation of A */ bool_mat_randtest(C, state); _bool_mat_permute(C, A, perm); bool_mat_transitive_closure(C, C); /* D is the permutation of the transitive closure of A */ bool_mat_randtest(D, state); _bool_mat_permute(D, B, perm); if (!bool_mat_equal(C, D)) { flint_printf("FAIL (commutativity with permutation)\n"); bool_mat_print(A); flint_printf("\n"); bool_mat_print(B); flint_printf("\n"); bool_mat_print(C); flint_printf("\n"); bool_mat_print(D); flint_printf("\n"); flint_abort(); } flint_free(perm); } bool_mat_clear(A); bool_mat_clear(B); bool_mat_clear(C); bool_mat_clear(D); } /* check transitive closure using brute force with smallish matrices */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m; bool_mat_t A, B, C; m = n_randint(state, 10); bool_mat_init(A, m, m); bool_mat_init(B, m, m); bool_mat_init(C, m, m); bool_mat_randtest(A, state); bool_mat_randtest(B, state); bool_mat_randtest(C, state); bool_mat_transitive_closure(B, A); _bool_mat_transitive_closure_powering(C, A); if (!bool_mat_equal(B, C)) { flint_printf("FAIL (brute force)\n"); bool_mat_print(A); flint_printf("\n"); bool_mat_print(B); flint_printf("\n"); bool_mat_print(C); flint_printf("\n"); flint_abort(); } bool_mat_clear(A); bool_mat_clear(B); bool_mat_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/test/t-transpose.c000066400000000000000000000033331417376376500175650ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int main() { slong iter; flint_rand_t state; flint_printf("transpose...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n; bool_mat_t a, b; m = n_randint(state, 10); n = n_randint(state, 10); bool_mat_init(a, m, n); bool_mat_init(b, n, m); bool_mat_randtest(a, state); bool_mat_randtest(b, state); bool_mat_transpose(b, a); /* involution */ { bool_mat_t c; bool_mat_init(c, m, n); bool_mat_randtest(c, state); bool_mat_transpose(c, b); if (!bool_mat_equal(c, a)) { flint_printf("FAIL (involution)\n"); flint_printf("m = %wd, n = %wd\n", m, n); flint_abort(); } bool_mat_clear(c); } /* aliasing */ if (bool_mat_is_square(a)) { bool_mat_transpose(a, a); if (!bool_mat_equal(a, b)) { flint_printf("FAIL (aliasing)\n"); flint_abort(); } } bool_mat_clear(a); bool_mat_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/bool_mat/trace.c000066400000000000000000000014071417376376500154250ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" int bool_mat_trace(const bool_mat_t mat) { slong i; if (!bool_mat_is_square(mat)) { flint_printf("bool_mat_trace: a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(mat)) return 0; for (i = 0; i < bool_mat_nrows(mat); i++) if (bool_mat_get_entry(mat, i, i)) return 1; return 0; } arb-2.22.1/bool_mat/transitive_closure.c000066400000000000000000000025721417376376500202570ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" /* Warshall's algorithm */ void bool_mat_transitive_closure(bool_mat_t dest, const bool_mat_t src) { slong k, i, j, dim; if (bool_mat_nrows(dest) != bool_mat_nrows(src) || bool_mat_ncols(dest) != bool_mat_ncols(src)) { flint_printf("bool_mat_transitive_closure: incompatible dimensions\n"); flint_abort(); } dim = bool_mat_nrows(src); if (dim != bool_mat_ncols(src)) { flint_printf("bool_mat_transitive_closure: a square matrix is required!\n"); flint_abort(); } bool_mat_set(dest, src); for (k = 0; k < dim; k++) { for (i = 0; i < dim; i++) { for (j = 0; j < dim; j++) { if (!bool_mat_get_entry(dest, i, j)) { bool_mat_set_entry(dest, i, j, ( bool_mat_get_entry(dest, i, k) & bool_mat_get_entry(dest, k, j))); } } } } } arb-2.22.1/bool_mat/transpose.c000066400000000000000000000025361417376376500163510ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_transpose(bool_mat_t B, const bool_mat_t A) { slong i, j; if (bool_mat_nrows(B) != bool_mat_ncols(A) || bool_mat_ncols(B) != bool_mat_nrows(A)) { flint_printf("bool_mat_transpose: Incompatible dimensions.\n"); flint_abort(); } if (bool_mat_is_empty(A)) return; if (A == B) /* In-place, guaranteed to be square */ { int tmp; for (i = 0; i < bool_mat_nrows(B) - 1; i++) { for (j = i + 1; j < bool_mat_ncols(B); j++) { tmp = bool_mat_get_entry(B, i, j); bool_mat_set_entry(B, i, j, bool_mat_get_entry(B, j, i)); bool_mat_set_entry(B, j, i, tmp); } } } else /* Not aliased; general case */ { for (i = 0; i < bool_mat_nrows(B); i++) for (j = 0; j < bool_mat_ncols(B); j++) bool_mat_set_entry(B, i, j, bool_mat_get_entry(A, j, i)); } } arb-2.22.1/bool_mat/zero.c000066400000000000000000000011231417376376500153010ustar00rootroot00000000000000/* Copyright (C) 2016 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "bool_mat.h" void bool_mat_zero(bool_mat_t mat) { slong i, j; for (i = 0; i < bool_mat_nrows(mat); i++) for (j = 0; j < bool_mat_ncols(mat); j++) bool_mat_set_entry(mat, i, j, 0); } arb-2.22.1/configure000077500000000000000000000410311417376376500142730ustar00rootroot00000000000000#!/bin/sh # (C) 2007, Robert Bradshaw, William Hart, William Stein, Michael Abshoff # (C) 2011, William Hart # (C) 2012, William Hart, Jean-Pierre Flori, Thomas DuBuisson # (C) 2012, Jan Engelhardt # soname version # # arb => soname # 2.7.0 => 0.0.0 ARB_MAJOR=2 ARB_MINOR=13 ARB_PATCH=1 PREFIX="/usr/local" GMP_DIR="/usr/local" MPFR_DIR="/usr/local" FLINT_DIR="/usr/local" NTL_DIR="/usr/local" GC_DIR="/usr/local" BLAS_DIR="/usr/local" WANT_NTL=0 WANT_BLAS=0 SHARED=1 STATIC=1 TLS=1 PTHREAD=1 REENTRANT=0 WANT_GC=0 WANT_TLS=0 WANT_CXX=0 ASSERT=0 BUILD= EXTENSIONS= EXT_MODS= EXTRA_BUILD= usage() { echo "Usage: ./configure " echo " where may be" echo " -h display usage information" echo " where may be:" echo " --prefix= Specify path to installation location (default: /usr/local)" echo " --with-mpir= Specify location of MPIR (default: /usr/local)" echo " --with-gmp= Specify location of GMP (default: /usr/local)" echo " --with-mpfr= Specify location of MPFR (default: /usr/local)" echo " --with-flint= Specify location of FLINT (default: /usr/local)" echo " --with-blas[=] Use BLAS and specify its location (default: /usr/local)" echo " --without-blas Do not use BLAS (default)" echo " --extensions= Specify location of extension modules" echo " --build=arch-os Specify architecture/OS combination rather than use values from uname -m/-s" echo " --enable-shared Build a shared library (default)" echo " --disable-shared Do not build a shared library" echo " --enable-static Build a static library (default)" echo " --disable-static Do not build a static library" echo " --single Faster [non-reentrant if tls or pthread not used] version of library (default)" echo " --reentrant Build fully reentrant [with or without tls, with pthread] version of library" echo " --with-gc= GC safe build with path to gc" echo " --enable-pthread Use pthread (default)" echo " --disable-pthread Do not use pthread" echo " --enable-tls Use thread-local storage (default)" echo " --disable-tls Do not use thread-local storage" echo " --enable-assert Enable use of asserts (use for debug builds only)" echo " --disable-assert Disable use of asserts (default)" echo " --enable-cxx Enable C++ wrapper tests" echo " --disable-cxx Disable C++ wrapper tests (default)" echo " CC= Use the C compiler with the given name (default: gcc)" echo " CXX= Use the C++ compiler with the given name (default: g++)" echo " AR= Use the AR library builder with the given name (default: ar)" echo " CFLAGS= Pass the given flags to the compiler" echo " ABI=[32|64] Tell the compiler to use given ABI (default: empty)" } absolute_path(){ dirlist="$1" retval="" for dir in $dirlist; do case $dir in /*) dir=$dir;; *) dir=$PWD/$dir;; esac retval=$retval" "$dir done echo $retval } while [ "$1" != "" ]; do PARAM=`echo $1 | sed 's/=.*//'` VALUE=`echo $1 | sed 's/[^=]*//; s/=//'` case "$PARAM" in -h|--help) usage exit 0 ;; --with-mpir|--with-gmp) GMP_DIR=$(absolute_path "$VALUE") ;; --with-mpfr) MPFR_DIR=$(absolute_path "$VALUE") ;; --with-flint) FLINT_DIR=$(absolute_path "$VALUE") ;; --with-blas) WANT_BLAS=1 if [ ! -z "$VALUE" ]; then BLAS_DIR=$(absolute_path "$VALUE") fi ;; --without-blas) WANT_BLAS=0 ;; --extensions) EXTENSIONS=$(absolute_path "$VALUE") ;; --build) BUILD="$VALUE" ;; --prefix) PREFIX=$VALUE ;; --enable-shared) SHARED=1 ;; --disable-shared) SHARED=0 ;; --enable-static) STATIC=1 ;; --disable-static) STATIC=0 ;; --single) REENTRANT=0 ;; --reentrant) REENTRANT=1 ;; --with-gc) WANT_GC=1 if [ ! -z "$VALUE" ]; then GC_DIR="$VALUE" fi ;; --enable-pthread) PTHREAD=1 ;; --disable-pthread) PTHREAD=0 ;; --enable-tls) TLS=1 WANT_TLS=1;; --disable-tls) TLS=0 ;; --enable-assert) ASSERT=1 ;; --disable-assert) ASSERT=0 ;; --enable-cxx) WANT_CXX=1 ;; --disable-cxx) WANT_CXX=0 ;; AR) AR="$VALUE" ;; CC) CC="$VALUE" ;; CXX) CXX="$VALUE" ;; CFLAGS) CFLAGS="$VALUE" ;; ABI) ABI="$VALUE" ;; *) usage exit 1 ;; esac shift done #find dependencies LIBS="m" if [ -d "${GMP_DIR}/lib" ]; then GMP_LIB_DIR="${GMP_DIR}/lib" GMP_INC_DIR="${GMP_DIR}/include" elif [ -d "${GMP_DIR}/lib64" ]; then GMP_LIB_DIR="${GMP_DIR}/lib64" GMP_INC_DIR="${GMP_DIR}/include" elif [ -d "${GMP_DIR}/.libs" ]; then GMP_LIB_DIR="${GMP_DIR}/.libs" GMP_INC_DIR="${GMP_DIR}" else echo "Invalid GMP directory" exit 1 fi LIB_DIRS="${LIB_DIRS} ${GMP_LIB_DIR}" INC_DIRS="${INC_DIRS} ${GMP_INC_DIR}" LIBS="${LIBS} gmp" if [ -d "${MPFR_DIR}/lib" ]; then MPFR_LIB_DIR="${MPFR_DIR}/lib" MPFR_INC_DIR="${MPFR_DIR}/include" elif [ -d "${MPFR_DIR}/lib64" ]; then MPFR_LIB_DIR="${MPFR_DIR}/lib64" MPFR_INC_DIR="${MPFR_DIR}/include" elif [ -d "${MPFR_DIR}/.libs" ]; then MPFR_LIB_DIR="${MPFR_DIR}/.libs" MPFR_INC_DIR="${MPFR_DIR}" elif [ -d "${MPFR_DIR}/src/.libs" ]; then MPFR_LIB_DIR="${MPFR_DIR}/src/.libs" MPFR_INC_DIR="${MPFR_DIR}/src" else echo "Invalid MPFR directory" exit 1 fi LIB_DIRS="${LIB_DIRS} ${MPFR_LIB_DIR}" INC_DIRS="${INC_DIRS} ${MPFR_INC_DIR}" LIBS="${LIBS} mpfr" if [ -d "${FLINT_DIR}/lib" ]; then FLINT_LIB_DIR="${FLINT_DIR}/lib" FLINT_INC_DIR="${FLINT_DIR}/include" elif [ -d "${FLINT_DIR}/lib64" ]; then FLINT_LIB_DIR="${FLINT_DIR}/lib64" FLINT_INC_DIR="${FLINT_DIR}/include" elif [ -d "${FLINT_DIR}/.libs" ]; then FLINT_LIB_DIR="${FLINT_DIR}/.libs" FLINT_INC_DIR="${FLINT_DIR}" elif [ -d "${FLINT_DIR}" ]; then FLINT_LIB_DIR="${FLINT_DIR}" FLINT_INC_DIR="${FLINT_DIR}" else echo "Invalid FLINT directory" exit 1 fi if [ -d "${FLINT_INC_DIR}/flint" ]; then FLINT_INC_DIR="${FLINT_INC_DIR}" elif [ -f "${FLINT_INC_DIR}/flint.h" ]; then mkdir -p build/include ln -sf ${FLINT_INC_DIR} build/include/flint FLINT_INC_DIR="${PWD}/build/include" fi echo "FLINT_LIB_DIR set to ${FLINT_LIB_DIR}" echo "FLINT_INC_DIR set to ${FLINT_INC_DIR}" LIB_DIRS="${LIB_DIRS} ${FLINT_LIB_DIR}" INC_DIRS="${INC_DIRS} ${FLINT_INC_DIR}" LIBS="${LIBS} flint" #configure extra libraries if [ "$WANT_BLAS" = "1" ]; then if [ -d "${BLAS_DIR}" ]; then BLAS_LIB_DIR="${BLAS_DIR}" BLAS_INC_DIR="${BLAS_DIR}" else echo "Invalid BLAS directory" exit 1 fi EXTRA_INC_DIRS="${EXTRA_INC_DIRS} ${BLAS_INC_DIR}" EXTRA_LIB_DIRS="${EXTRA_LIB_DIRS} ${BLAS_LIB_DIR}" EXTRA_LIBS="${EXTRA_LIBS} openblas" fi CONFIG_BLAS="#define HAVE_BLAS ${WANT_BLAS}" if [ "$WANT_GC" = "1" ]; then if [ -d "${GC_DIR}" ]; then GC_LIB_DIR="${GC_DIR}/lib" GC_INC_DIR="${GC_DIR}/include" else echo "Invalid GC directory" exit 1 fi EXTRA_INC_DIRS="${EXTRA_INC_DIRS} ${GC_INC_DIR}" EXTRA_LIB_DIRS="${EXTRA_LIB_DIRS} ${GC_LIB_DIR}" EXTRA_LIBS="${EXTRA_LIBS} gc" fi CONFIG_GC="#define HAVE_GC ${WANT_GC}" # defaults for CC, CXX and AR if [ -z "$CC" ]; then CC=gcc fi if [ -z "$CXX" ]; then CXX=g++ fi if [ -z "$AR" ]; then AR=ar fi # Architecture handler KERNEL=`uname` if [ -z "$BUILD" ]; then ARCH=`uname -m` if [ "$(uname | cut -d_ -f1)" = "MINGW32" ]; then if [ "$ABI" = "64" ]; then OS="MINGW64" else OS="MINGW32" fi elif [ "$(uname | cut -d_ -f1)" = "CYGWIN" ]; then if [ "$ARCH" = "x86_64" ]; then if [ "$ABI" = "32" ]; then OS="CYGWIN32" else OS="CYGWIN64" ABI="64" fi else OS="CYGWIN32" fi else OS=`uname -s` fi else ARCH=`echo "$BUILD" | cut -d- -f1` OS=`echo "$BUILD" | cut -d- -f2` fi case "$ARCH" in x86_64 | amd64) MACHINE="x86_64";; x86 | i*86 | pc) MACHINE="x86";; ia64) MACHINE="ia64";; sparc | sun4*) MACHINE="sparc";; sparc64) MACHINE="sparc64";; ppc64 | powerpc64) MACHINE="ppc64";; ppc | powerpc | [P|p]ower*) MACHINE="ppc";; *) MACHINE="unknown";; esac #ABI flag if [ "$ABI" = "32" ]; then ABI_FLAG="-m32" case "$MACHINE" in x86_64) MACHINE="x86";; sparc64) MACHINE="sparc";; ppc64) MACHINE="ppc";; *) ;; esac elif [ "$ABI" = "64" ]; then ABI_FLAG="-m64" if [ "$MACHINE" = "sparc" ]; then MACHINE="sparc64" fi if [ "$MACHINE" = "x86" ]; then MACHINE="x86_64" fi fi if [ "$MACHINE" = "sparc" ] || [ "$MACHINE" = "sparc64" ]; then if [ "$CC" = "gcc" ]; then CC="gcc -mno-relax" fi fi echo "Configuring...${MACHINE}-${OS}" #name for ARB shared library ARB_SOLIB=0 if [ -z "$ARB_LIB" ]; then case "$OS" in Darwin) ARB_LIBNAME="libarb.dylib" ARB_LIB="libarb-$ARB_MAJOR.$ARB_MINOR.$ARB_PATCH.dylib" EXTRA_SHARED_FLAGS="-install_name $PREFIX/lib/$ARB_LIB -compatibility_version $ARB_MAJOR.$ARB_MINOR -current_version $ARB_MAJOR.$ARB_MINOR.$ARB_PATCH";; CYGWIN* | MINGW*) ARB_LIBNAME="libarb.dll" ARB_LIB="libarb-$ARB_MAJOR.dll" EXTRA_SHARED_FLAGS="-static-libgcc -shared -Wl,--export-all-symbols -Wl,-soname,libarb-$ARB_MAJOR.dll.$ARB_MINOR.$ARB_PATCH";; android) ARB_LIBNAME="libarb.so" ARB_LIB="libarb.so.$ARB_MAJOR.$ARB_MINOR.$ARB_PATCH" EXTRA_SHARED_FLAGS="-Wl,-soname,libarb.so" ARB_SOLIB=1;; *) ARB_LIBNAME="libarb.so" ARB_LIB="libarb.so.$ARB_MAJOR.$ARB_MINOR.$ARB_PATCH" EXTRA_SHARED_FLAGS="-Wl,-soname,libarb.so.$ARB_MAJOR" ARB_SOLIB=1;; esac EXTRA_SHARED_FLAGS="$EXTRA_SHARED_FLAGS -Wl,-rpath,${GMP_LIB_DIR} -Wl,-rpath,${MPFR_LIB_DIR} -Wl,-rpath,${FLINT_LIB_DIR}" fi # sometimes LDCONFIG is not to be found in the path. Look at some common places. case "$OS" in MINGW*|CYGWIN*|Darwin) LDCONFIG="true";; *) if [ -z "$LDCONFIG" ]; then LDCONFIG="true" if [ "$ARB_SOLIB" = "1" ]; then if command -v ldconfig > /dev/null; then LDCONFIG="ldconfig" elif [ -x /sbin/ldconfig ]; then LDCONFIG="/sbin/ldconfig" fi fi fi;; esac #extension for executables if [ -z "$EXEEXT" ]; then case "$OS" in CYGWIN* | MINGW*) EXEEXT=".exe";; *) EXEEXT="";; esac fi #don't build both shared and static lib on MinGW and Cygwin case "$OS" in CYGWIN* | MINGW*) if [ "$STATIC" = "1" ] && [ "$SHARED" = "1" ]; then echo "Building both static and shared versions of MPIR/GMP on $OS is currently" echo "unsupported, and so is it for MPFR, FLINT and ARB." echo "You should pass --disable-shared or --disable-static to configure" echo "depending on the versions of MPIR/GMP, MPFR and FLINT you built." exit 1 fi ;; *) ;; esac #test for popcnt flag and set needed CFLAGS mkdir -p build rm -f build/test-popcnt > /dev/null 2>&1 MSG="Testing __builtin_popcountl..." printf "%s" "$MSG" echo "int main(int argc, char ** argv) { #if defined(_WIN64) return __builtin_popcountll(argc) == 100; #else return __builtin_popcountl(argc) == 100; #endif }" > build/test-popcnt.c $CC build/test-popcnt.c -o ./build/test-popcnt > /dev/null 2>&1 if [ $? -eq 0 ]; then printf "%s\n" "yes" CONFIG_POPCNT_INTRINSICS="#define POPCNT_INTRINSICS" if [ "$MACHINE" = "x86_64" ]; then MSG="Testing native popcount..." printf "%s" "$MSG" touch build/test-popcnt.c rm build/test-popcnt $CC -mpopcnt build/test-popcnt.c -o ./build/test-popcnt > /dev/null 2>&1 build/test-popcnt > /dev/null 2>&1 if [ $? -eq 0 ]; then printf "%s\n" "yes" POPCNT_FLAG="-mpopcnt" else printf "%s\n" "no" fi rm -f build/test-popcnt{,.c} #in case -mpopcnt is not available, the test program will use an illegal #instruction and that will print out something on stderr when the if #construction is exited, whence the following "2> /dev/null" fi 2> /dev/null else rm -f build/test-popcnt.c printf "%s\n" "no" fi #defaults for CFLAGS if [ -z "$CFLAGS" ]; then if [ "$OS" = "MINGW64" ]; then CFLAGS="-O2 -funroll-loops -g $POPCNT_FLAG $ABI_FLAG" elif [ "$OS" = "CYGWIN64" ]; then CFLAGS="-O2 -funroll-loops -g -D _WIN64 $POPCNT_FLAG $ABI_FLAG" else CFLAGS="-ansi -pedantic -Wall -O2 -funroll-loops -g $POPCNT_FLAG $ABI_FLAG" fi fi #this is needed on PPC G5 and does not hurt on other OS Xes if [ "$KERNEL" = Darwin ]; then CFLAGS="-fno-common $CFLAGS" fi #PIC flag if [ -z "$PIC_FLAG" ]; then case "$OS" in CYGWIN* | MINGW*) ;; *) PIC_FLAG="-fPIC";; esac fi #test support for thread-local storage CONFIG_TLS="#define HAVE_TLS 0" if [ "$TLS" = "1" ]; then mkdir -p build rm -f build/test-tls > /dev/null 2>&1 MSG="Testing __thread..." printf "%s" "$MSG" echo "__thread int x = 42; int main(int argc, char ** argv) { return x != 42; }" > build/test-tls.c $CC build/test-tls.c -o ./build/test-tls > /dev/null 2>&1 if [ $? -eq 0 ]; then build/test-tls > /dev/null 2>&1 if [ $? -eq 0 ]; then printf "%s\n" "yes" CONFIG_TLS="#define HAVE_TLS 1" else printf "%s\n" "no" fi rm -f build/test-tls{,.c} else rm -f build/test-tls.c printf "%s\n" "no" #build-tls can segfault on systems where tls is not available fi 2> /dev/null fi #pthread configuration CONFIG_PTHREAD="#define HAVE_PTHREAD ${PTHREAD}" #pocess external modules EXTRA_INC_DIRS="${EXTRA_INC_DIRS} ${EXTENSIONS}" if [ -d "${EXTENSIONS}/examples" ]; then cp ${EXTENSIONS}/examples/*.c ./examples/ fi #include paths INCS="-I\$(CURDIR)" for INC_DIR in ${INC_DIRS} ${EXTRA_INC_DIRS}; do INCS="${INCS} -I${INC_DIR}" done #library paths LLIBS="-L\$(CURDIR)" for LIB_DIR in ${LIB_DIRS} ${EXTRA_LIB_DIRS}; do LLIBS="${LLIBS} -L${LIB_DIR}" done #linker params if [ "$PTHREAD" = "1" ]; then lLIBS2="-lpthread ${lLIBS2}" fi for LIB in ${EXTRA_LIBS} ${LIBS}; do lLIBS2="-l${LIB} ${lLIBS2}" done lLIBS="-larb $lLIBS2" LIBS2="$LLIBS $lLIBS2" LIBS="$LLIBS $lLIBS" #paths for dynamic linker case "$OS" in CYGWIN* | MINGW*) DLPATH="PATH";; Darwin) DLPATH="DYLD_LIBRARY_PATH";; sparc) DLPATH="LD_LIBRARY_PATH32";; sparc64) DLPATH="LD_LIBRARY_PATH64";; *) DLPATH="LD_LIBRARY_PATH";; esac DLPATH_ADD="\$(CURDIR)" for LIB_DIR in ${LIB_DIRS} ${EXTRA_LIB_DIRS}; do DLPATH_ADD="${DLPATH_ADD}:${LIB_DIR}" done #cxx if [ "$WANT_CXX" = "1" ]; then EXTRA_BUILD="$EXTRA_BUILD arbxx" fi #write out Makefile echo "# This file is autogenerated by ./configure -- do not edit!" > Makefile echo "" >> Makefile echo "SHELL=/bin/sh" >> Makefile echo "" >> Makefile echo "ARB_STATIC=$STATIC" >> Makefile echo "ARB_SHARED=$SHARED" >> Makefile echo "ARB_LIB=$ARB_LIB" >> Makefile echo "ARB_LIBNAME=$ARB_LIBNAME" >> Makefile echo "ARB_MAJOR=$ARB_MAJOR" >> Makefile echo "ARB_SOLIB=$ARB_SOLIB" >> Makefile echo "EXEEXT=$EXEEXT" >> Makefile echo "PREFIX=$PREFIX" >> Makefile echo "" >> Makefile echo "WANT_NTL=$WANT_NTL" >> Makefile echo "" >> Makefile echo "INCS=$INCS" >> Makefile echo "LIBS=$LIBS" >> Makefile echo "LIBS2=$LIBS2" >> Makefile echo "" >> Makefile echo "CC=$CC" >> Makefile echo "CXX=$CXX" >> Makefile echo "AR=$AR" >> Makefile echo "LDCONFIG=$LDCONFIG" >> Makefile echo "" >> Makefile echo "CFLAGS=$CFLAGS" >> Makefile echo "ABI_FLAG=$ABI_FLAG" >> Makefile echo "PIC_FLAG=$PIC_FLAG" >> Makefile echo "EXTRA_SHARED_FLAGS=$EXTRA_SHARED_FLAGS" >> Makefile echo "" >> Makefile echo "DLPATH=$DLPATH" >> Makefile echo "DLPATH_ADD=$DLPATH_ADD" >> Makefile echo "EXTENSIONS=$EXTENSIONS" >> Makefile echo "EXTRA_BUILD_DIRS=$EXTRA_BUILD" >> Makefile echo "" >> Makefile cat Makefile.in >> Makefile echo "ARB was successfully configured." arb-2.22.1/dirichlet.h000066400000000000000000000143511417376376500145110ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef DIRICHLET_H #define DIRICHLET_H #ifdef DIRICHLET_INLINES_C #define DIRICHLET_INLINE #else #define DIRICHLET_INLINE static __inline__ #endif #include "dlog.h" #ifdef __cplusplus extern "C" { #endif #define MAX_FACTORS 15 /* should this dlog pointer be in the prime or the global group? */ typedef struct { ulong p; /* underlying prime */ int e; /* exponent */ nmod_t pe; /* modulus */ nmod_t phi; /* phi(p^e) */ ulong g; /* conrey generator */ dlog_precomp_struct * dlog; /* precomputed data for discrete log mod p^e */ } dirichlet_prime_group_struct; typedef struct { ulong q; /* modulus */ ulong q_even; /* even part of modulus */ nmod_t mod; /* modulus with precomputed inverse */ ulong rad_q; /* radical = product of odd primes */ ulong phi_q; /* phi(q) = group size */ slong neven; /* number of even components (in 0,1,2)*/ slong num; /* number of prime components (even + odd) */ ulong expo; /* exponent = largest order in G */ dirichlet_prime_group_struct * P; ulong * generators; /* generators lifted mod q */ ulong * PHI; /* PHI(k) = expo / phi(k) */ } dirichlet_group_struct; typedef dirichlet_group_struct dirichlet_group_t[1]; DIRICHLET_INLINE ulong dirichlet_group_size(const dirichlet_group_t G) { return G->phi_q; } ulong dirichlet_group_num_primitive(const dirichlet_group_t G); void dirichlet_group_init(dirichlet_group_t G, ulong q); void dirichlet_subgroup_init(dirichlet_group_t H, const dirichlet_group_t G, ulong h); void dirichlet_group_clear(dirichlet_group_t G); void dirichlet_group_dlog_precompute(dirichlet_group_t G, ulong num); void dirichlet_group_dlog_clear(dirichlet_group_t G); /* properties of elements without log */ ulong dirichlet_conductor_ui(const dirichlet_group_t G, ulong a); int dirichlet_parity_ui(const dirichlet_group_t G, ulong a); ulong dirichlet_order_ui(const dirichlet_group_t G, ulong a); /* characters, keep both number and log */ typedef struct { ulong n; /* number */ ulong * log; /* s.t. prod generators[k]^log[k] = number */ } dirichlet_char_struct; typedef dirichlet_char_struct dirichlet_char_t[1]; void dirichlet_char_init(dirichlet_char_t x, const dirichlet_group_t G); void dirichlet_char_clear(dirichlet_char_t x); void dirichlet_char_print(const dirichlet_group_t G, const dirichlet_char_t x); DIRICHLET_INLINE void dirichlet_char_set(dirichlet_char_t x, const dirichlet_group_t G, const dirichlet_char_t y) { slong k; x->n = y->n; for (k = 0; k < G->num; k++) x->log[k] = y->log[k]; } DIRICHLET_INLINE int dirichlet_char_eq(const dirichlet_char_t x, const dirichlet_char_t y) { return (x->n == y->n); } int dirichlet_char_eq_deep(const dirichlet_group_t G, const dirichlet_char_t x, const dirichlet_char_t y); int dirichlet_parity_char(const dirichlet_group_t G, const dirichlet_char_t x); ulong dirichlet_conductor_char(const dirichlet_group_t G, const dirichlet_char_t x); ulong dirichlet_order_char(const dirichlet_group_t G, const dirichlet_char_t x); void dirichlet_char_log(dirichlet_char_t x, const dirichlet_group_t G, ulong m); DIRICHLET_INLINE ulong dirichlet_char_exp(const dirichlet_group_t G, const dirichlet_char_t x) { return x->n; } ulong _dirichlet_char_exp(dirichlet_char_t x, const dirichlet_group_t G); void dirichlet_char_index(dirichlet_char_t x, const dirichlet_group_t G, ulong j); ulong dirichlet_index_char(const dirichlet_group_t G, const dirichlet_char_t x); void dirichlet_char_one(dirichlet_char_t x, const dirichlet_group_t G); void dirichlet_char_first_primitive(dirichlet_char_t x, const dirichlet_group_t G); int dirichlet_char_next(dirichlet_char_t x, const dirichlet_group_t G); int dirichlet_char_next_primitive(dirichlet_char_t x, const dirichlet_group_t G); void dirichlet_char_mul(dirichlet_char_t c, const dirichlet_group_t G, const dirichlet_char_t a, const dirichlet_char_t b); void dirichlet_char_pow(dirichlet_char_t c, const dirichlet_group_t G, const dirichlet_char_t a, ulong n); void dirichlet_char_lower(dirichlet_char_t y, const dirichlet_group_t H, const dirichlet_char_t x, const dirichlet_group_t G); void dirichlet_char_lift(dirichlet_char_t y, const dirichlet_group_t G, const dirichlet_char_t x, const dirichlet_group_t H); #define DIRICHLET_CHI_NULL UWORD_MAX ulong dirichlet_pairing(const dirichlet_group_t G, ulong m, ulong n); ulong dirichlet_pairing_char(const dirichlet_group_t G, const dirichlet_char_t a, const dirichlet_char_t b); DIRICHLET_INLINE int dirichlet_char_is_principal(const dirichlet_group_t G, const dirichlet_char_t chi) { return (chi->n == 1); } DIRICHLET_INLINE int dirichlet_char_is_real(const dirichlet_group_t G, const dirichlet_char_t chi) { return G->q <= 4 || (nmod_mul(chi->n, chi->n, G->mod) == 1); } DIRICHLET_INLINE int dirichlet_char_is_primitive(const dirichlet_group_t G, const dirichlet_char_t chi) { return (dirichlet_conductor_char(G, chi) == G->q); } ulong dirichlet_chi(const dirichlet_group_t G, const dirichlet_char_t chi, ulong n); void dirichlet_vec_set_null(ulong *v, const dirichlet_group_t G, slong nv); void dirichlet_chi_vec_loop(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv); void dirichlet_chi_vec_primeloop(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv); void dirichlet_chi_vec(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv); void dirichlet_chi_vec_loop_order(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv); void dirichlet_chi_vec_primeloop_order(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv); void dirichlet_chi_vec_order(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv); #ifdef __cplusplus } #endif #endif arb-2.22.1/dirichlet/000077500000000000000000000000001417376376500143345ustar00rootroot00000000000000arb-2.22.1/dirichlet/char.c000066400000000000000000000011671417376376500154220ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_init(dirichlet_char_t x, const dirichlet_group_t G) { x->log = flint_malloc(G->num * sizeof(ulong)); dirichlet_char_one(x, G); } void dirichlet_char_clear(dirichlet_char_t x) { flint_free(x->log); } arb-2.22.1/dirichlet/char_conductor.c000066400000000000000000000020741417376376500175000ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong dirichlet_conductor_char(const dirichlet_group_t G, const dirichlet_char_t x) { int k, f; ulong cond = 1; if (G->neven >= 1 && x->log[0] == 1) cond = 4; if (G->neven == 2 && x->log[1]) { ulong l2 = x->log[1]; f = n_remove(&l2, 2); cond = UWORD(1) << (G->P[1].e - f); } for (k = G->neven; k < G->num; k++) { if (x->log[k]) { ulong p, lp; p = G->P[k].p; lp = x->log[k]; f = n_remove(&lp, p); if (f) cond *= n_pow(p, G->P[k].e - f); else cond *= G->P[k].pe.n; } } return cond; } arb-2.22.1/dirichlet/char_eq_deep.c000066400000000000000000000012361417376376500171010ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" int dirichlet_char_eq_deep(const dirichlet_group_t G, const dirichlet_char_t x, const dirichlet_char_t y) { slong k; if (x->n != y->n) return 0; for (k = 0; k < G->num; k++) if (x->log[k] != y->log[k]) return 0; return 1; } arb-2.22.1/dirichlet/char_exp.c000066400000000000000000000012001417376376500162620ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong _dirichlet_char_exp(dirichlet_char_t x, const dirichlet_group_t G) { ulong k, n = 1; for (k = 0; k < G->num; k++) n = nmod_mul(n, nmod_pow_ui(G->generators[k], x->log[k], G->mod), G->mod); x->n = n; return n; } arb-2.22.1/dirichlet/char_first_primitive.c000066400000000000000000000016141417376376500207160ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_first_primitive(dirichlet_char_t x, const dirichlet_group_t G) { ulong k; if (G->q % 4 == 2) { flint_printf("Exception (dirichlet_char_first_primitive). No primitive element mod %wu.\n",G->q); flint_abort(); } x->n = 1; for (k = 0; k < G->num ; k++) { if (k == 0 && G->neven == 2) x->log[k] = 0; else { x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k] = 1; } } } arb-2.22.1/dirichlet/char_index.c000066400000000000000000000025171417376376500166110ustar00rootroot00000000000000/*============================================================================= This file is part of ARB. ARB 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. ARB 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 ARB; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =============================================================================*/ /****************************************************************************** Copyright (C) 2016 Pascal Molin ******************************************************************************/ #include "dirichlet.h" void dirichlet_char_index(dirichlet_char_t x, const dirichlet_group_t G, ulong j) { slong k; for (k = G->num - 1; k >= 0; k--) { x->log[k] = j % G->P[k].phi.n; j = j / G->P[k].phi.n; } _dirichlet_char_exp(x, G); } arb-2.22.1/dirichlet/char_lift.c000066400000000000000000000017161417376376500164400ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_lift(dirichlet_char_t y, const dirichlet_group_t G, const dirichlet_char_t x, const dirichlet_group_t H) { slong k, l; if (G->q % H->q != 0) { flint_printf("conrey_lift: lower modulus %wu does not divide %wu\n", H->q, G->q); flint_abort(); } for (k = 0, l = 0; k < G->num && l < H->num; k++) { if (G->P[k].p == H->P[l].p) { slong e = n_pow(G->P[k].p, G->P[k].e - H->P[l].e); y->log[k] = x->log[l] * e; l++; } } _dirichlet_char_exp(y, G); } arb-2.22.1/dirichlet/char_log.c000066400000000000000000000025641417376376500162650ustar00rootroot00000000000000/* Copyright (C) 2015 Jonathan Bober Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include "dirichlet.h" /* assume m is invertible */ void dirichlet_char_log(dirichlet_char_t x, const dirichlet_group_t G, ulong m) { slong k; /* even part */ if (G->neven >= 1) { x->log[0] = (m % 4 == 3); if (G->neven == 2) { ulong m2 = (x->log[0]) ? -m % G->q_even : m % G->q_even; if (G->P[1].dlog == NULL) x->log[1] = dlog_mod2e_1mod4(m2, G->P[1].e, nmod_inv(5, G->P[1].pe), G->P[1].pe); else x->log[1] = dlog_precomp(G->P[1].dlog, m2); } } /* odd part */ for (k = G->neven; k < G->num; k++) { dirichlet_prime_group_struct P = G->P[k]; if (P.dlog == NULL) { x->log[k] = dlog_once(m % P.pe.n, P.g, P.pe, P.phi.n); } else { x->log[k] = dlog_precomp(P.dlog, m % P.pe.n); } } /* keep value m */ x->n = m; } arb-2.22.1/dirichlet/char_lower.c000066400000000000000000000022761417376376500166340ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_lower(dirichlet_char_t y, const dirichlet_group_t H, const dirichlet_char_t x, const dirichlet_group_t G) { slong k, l; if (G->q % H->q != 0) { flint_printf("conrey_lower: lower modulus %wu does not divide %wu\n", H->q, G->q); flint_abort(); } for (k = 0, l = 0; k < G->num && l < H->num; k++) { ulong p = G->P[k].p; if (p == H->P[l].p) { ulong pef = n_pow(G->P[k].p, G->P[k].e - H->P[l].e); ulong a = x->log[k]; if (a % pef) { flint_printf("conrey_lower: conductor does not divide lower modulus %wu", H->q); flint_abort(); } y->log[l] = a / pef; l++; } } _dirichlet_char_exp(y, H); } arb-2.22.1/dirichlet/char_mul.c000066400000000000000000000012471417376376500162760ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_mul(dirichlet_char_t c, const dirichlet_group_t G, const dirichlet_char_t a, const dirichlet_char_t b) { ulong k; for (k = 0; k < G->num ; k++) c->log[k] = nmod_add(a->log[k], b->log[k], G->P[k].phi); c->n = nmod_mul(a->n, b->n, G->mod); } arb-2.22.1/dirichlet/char_next.c000066400000000000000000000014031417376376500164510ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" int dirichlet_char_next(dirichlet_char_t x, const dirichlet_group_t G) { /* update index */ int k; for (k = G->num - 1; k >= 0; k--) { x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k] += 1; if (x->log[k] < G->P[k].phi.n) break; x->log[k] = 0; } /* return last index modified */ return k; } arb-2.22.1/dirichlet/char_next_primitive.c000066400000000000000000000031631417376376500205460ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" int dirichlet_char_next_primitive(dirichlet_char_t x, const dirichlet_group_t G) { /* update index avoiding multiples of p except for first component if 8|q */ slong k; /* if (G->neven == 2) { x->n = nmod_mul(x->n, G->generators[0], G->mod); x->log[0]++; if (x->log[0] == 1) return 0; x->log[0] = 0; k = 1; } */ for (k = G->num - 1; k >= 0; k--) { #if 1 x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k]++; if (x->log[k] % G->P[k].p == 0) { x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k]++; } if (x->log[k] < G->P[k].phi.n) break; if (x->log[k] == G->P[k].phi.n) x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k] = 1; #else do { x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k]++; } while (x->log[k] % G->P[k].p == 0); if (x->log[k] < G->P[k].phi) break; if (x->log[k] == G->P[k].phi) x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k] = 1; #endif } /* return last index modified */ return k; } arb-2.22.1/dirichlet/char_one.c000066400000000000000000000010561417376376500162600ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_one(dirichlet_char_t x, const dirichlet_group_t G) { ulong k; for (k = 0; k < G->num ; k++) x->log[k] = 0; x->n = 1; } arb-2.22.1/dirichlet/char_order.c000066400000000000000000000011541417376376500166110ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong dirichlet_order_char(const dirichlet_group_t G, const dirichlet_char_t x) { ulong k, g; g = G->expo; for (k = 0; k < G->num; k++) g = n_gcd(g, G->PHI[k] * x->log[k]); return G->expo / g; } arb-2.22.1/dirichlet/char_parity.c000066400000000000000000000012441417376376500170060ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" int dirichlet_parity_char(const dirichlet_group_t G, const dirichlet_char_t x) { int k, odd = 0; for (k = 0; k < G->num; k++) { if (k == 1 && G->neven == 2) continue; if (x->log[k] % 2) odd = 1 - odd; } return odd; } arb-2.22.1/dirichlet/char_pow.c000066400000000000000000000012161417376376500163020ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_pow(dirichlet_char_t c, const dirichlet_group_t G, const dirichlet_char_t a, ulong n) { ulong k; for (k = 0; k < G->num ; k++) c->log[k] = nmod_mul(a->log[k], n, G->P[k].phi); c->n = nmod_pow_ui(a->n, n, G->mod); } arb-2.22.1/dirichlet/char_print.c000066400000000000000000000012561417376376500166350ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_char_print(const dirichlet_group_t G, const dirichlet_char_t x) { slong k; if (G->num) flint_printf("[%wu", x->log[0]); else flint_printf("["); for (k = 1; k < G->num; k++) flint_printf(", %wu", x->log[k]); flint_printf("]"); } arb-2.22.1/dirichlet/chi.c000066400000000000000000000014401417376376500152420ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong dirichlet_chi(const dirichlet_group_t G, const dirichlet_char_t chi, ulong n) { if (n_gcd(G->q, n) > 1) { return DIRICHLET_CHI_NULL; } else { ulong v; dirichlet_char_t x; dirichlet_char_init(x, G); dirichlet_char_log(x, G, n); v = dirichlet_pairing_char(G, chi, x); dirichlet_char_clear(x); return v; } } arb-2.22.1/dirichlet/chi_vec.c000066400000000000000000000016271417376376500161060ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_chi_vec(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv) { if (2 * nv > G->phi_q) dirichlet_chi_vec_loop(v, G, chi, nv); else dirichlet_chi_vec_primeloop(v, G, chi, nv); } void dirichlet_chi_vec_order(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv) { if (2 * nv > G->phi_q) dirichlet_chi_vec_loop_order(v, G, chi, order, nv); else dirichlet_chi_vec_primeloop_order(v, G, chi, order, nv); } arb-2.22.1/dirichlet/chi_vec_loop.c000066400000000000000000000034441417376376500171360ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" static void dirichlet_exponents_char(ulong * expo, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order) { slong k; ulong factor = G->expo / order; for (k = 0; k < G->num; k++) /* no overflow: log[k] < phi[k] and G->expo = phi[k] * PHI[k] */ expo[k] = (chi->log[k] * G->PHI[k]) / factor; } /* loop over whole group */ void dirichlet_chi_vec_loop_order(ulong * v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv) { int j; ulong t; slong k; ulong expo[MAX_FACTORS]; dirichlet_char_t x; nmod_t o; dirichlet_char_init(x, G); dirichlet_char_one(x, G); dirichlet_exponents_char(expo, G, chi, order); nmod_init(&o, order); for (k = 0; k < nv; k++) v[k] = DIRICHLET_CHI_NULL; t = v[1] = 0; while ( (j = dirichlet_char_next(x, G)) >= 0 ) { /* exponents were modified up to j */ for (k = G->num - 1; k >= j; k--) t = nmod_add(t, expo[k], o); if (x->n < nv) v[x->n] = t; } /* fix result outside primes */ /* dirichlet_vec_set_null(v, G, nv);*/ /* copy outside modulus */ for (k = G->q; k < nv ; k++ ) v[k] = v[k - G->q]; dirichlet_char_clear(x); } void dirichlet_chi_vec_loop(ulong * v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv) { dirichlet_chi_vec_loop_order(v, G, chi, G->expo, nv); } arb-2.22.1/dirichlet/chi_vec_primeloop.c000066400000000000000000000043471417376376500201760ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" static void dirichlet_chi_vec_evenpart(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv) { ulong mult = G->expo / order; if (G->neven >= 1 && chi->log[0]) { ulong x, c3 = G->PHI[0] / mult; for (x = 3; x < nv; x += 4) v[x] = c3; } if (G->neven == 2 && chi->log[1]) { ulong x, g, vx, xp, c4; nmod_t pe, o; nmod_init(&o, order); pe = G->P[1].pe; g = G->P[1].g; vx = c4 = (chi->log[1] * G->PHI[1]) / mult; for (x = g; x > 1;) { for (xp = x; xp < nv; xp += pe.n) v[xp] = nmod_add(v[xp], vx, o); for (xp = pe.n - x; xp < nv; xp += pe.n) v[xp] = nmod_add(v[xp], vx, o); x = nmod_mul(x, g, pe); vx = nmod_add(vx, c4, o); } } } /* loop over primary components */ void dirichlet_chi_vec_primeloop_order(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv) { slong k, l; ulong mult = G->expo / order; nmod_t o; nmod_init(&o, order); for (k = 0; k < nv; k++) v[k] = 0; if (G->neven) dirichlet_chi_vec_evenpart(v, G, chi, order, nv); for (l = G->neven; l < G->num; l++) { dirichlet_prime_group_struct P = G->P[l]; /* FIXME: there may be some precomputed dlog in P if needed */ if (P.dlog == NULL) dlog_vec_add(v, nv, P.g, (chi->log[l] * G->PHI[l]) / mult, P.pe, P.phi.n, o); else dlog_vec_add_precomp(v, nv, P.dlog, P.g, (chi->log[l] * G->PHI[l]) / mult, P.pe, P.phi.n, o); } dirichlet_vec_set_null(v, G, nv); } void dirichlet_chi_vec_primeloop(ulong *v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv) { dirichlet_chi_vec_primeloop_order(v, G, chi, G->expo, nv); } arb-2.22.1/dirichlet/group_clear.c000066400000000000000000000010731417376376500170030ustar00rootroot00000000000000/* Copyright (C) 2015 Jonathan Bober Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_group_clear(dirichlet_group_t G) { flint_free(G->P); flint_free(G->generators); flint_free(G->PHI); } arb-2.22.1/dirichlet/group_dlog_precompute.c000066400000000000000000000022761417376376500211130ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_prime_group_dlog_precompute(dirichlet_prime_group_struct * P, ulong num) { P->dlog = flint_malloc(sizeof(dlog_precomp_t)); /* even if e = 1 use modpe struct, more flexible if reused in bigger group */ dlog_precomp_modpe_init(P->dlog, P->g, P->p, P->e, P->pe.n, num); } void dirichlet_group_dlog_precompute(dirichlet_group_t G, ulong num) { slong k; for (k = 0; k < G->num; k++) { if (G->P[k].dlog == NULL) dirichlet_prime_group_dlog_precompute(&G->P[k], num); } } void dirichlet_group_dlog_clear(dirichlet_group_t G) { slong k; for (k = 0; k < G->num; k++) { if (G->P[k].dlog != NULL) { dlog_precomp_clear(G->P[k].dlog); flint_free(G->P[k].dlog); G->P[k].dlog = NULL; } } } arb-2.22.1/dirichlet/group_init.c000066400000000000000000000122301417376376500166550ustar00rootroot00000000000000/* Copyright (C) 2015 Jonathan Bober Copyright (C) 2016 Fredrik Johansson Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" static ulong primitive_root_p_and_p2(ulong p) { if (p == 40487) return 10; #if FLINT_BITS == 64 if (p == UWORD(6692367337)) return 7; if (p > UWORD(1000000000000)) { printf("primitive root: p > 10^12 not implemented"); flint_abort(); } #endif return n_primitive_root_prime(p); } void dirichlet_prime_group_init(dirichlet_prime_group_struct * P, ulong p, int e) { P->p = p; P->e = e; if (p == 2 || p == 4) { P->p = 2; nmod_init(&P->pe, UWORD(1) << e); if (p == 2) { P->e = 2; nmod_init(&P->phi, 2); P->g = (UWORD(1) << e) - 1; } else { nmod_init(&P->phi, UWORD(1) << (e - 2)); P->g = 5; } } else { ulong pe1; pe1 = n_pow(p, e - 1); nmod_init(&P->phi, (p-1) * pe1); nmod_init(&P->pe, p * pe1); P->g = primitive_root_p_and_p2(p); } P->dlog = NULL; } static void dirichlet_group_lift_generators(dirichlet_group_t G) { slong k; dirichlet_prime_group_struct * P = G->P; G->expo = G->phi_q = 1; if (G->neven) { G->phi_q = G->q_even / 2; G->expo = P[G->neven - 1].phi.n; } for (k = G->neven; k < G->num; k++) { G->phi_q *= P[k].phi.n; G->expo *= P[k].phi.n / n_gcd(G->expo, P[k].p - 1); } for (k = 0; k < G->num; k++) { nmod_t pe; ulong qpe, v; G->PHI[k] = G->expo / G->P[k].phi.n; /* lift generators mod q */ /* u * p^e + v * q/p^e = 1 -> g mod q = 1 + (g-1) * v*(q/p^e) */ pe = G->P[k].pe; qpe = G->q / pe.n; if (G->q < G->P[k].pe.n) { flint_printf("lift generator %wu from %wu to %wu e=%wu\n", G->P[k].g, G->P[k].pe.n, G->q, G->P[k].e); } v = nmod_inv(qpe % pe.n, pe); /* v * qpe < q */ G->generators[k] = (1 + nmod_mul(G->P[k].g-1, v * qpe, G->mod)) % G->q; } } void dirichlet_group_init(dirichlet_group_t G, ulong q) { slong k; ulong e2; n_factor_t fac; G->q = q; nmod_init(&G->mod, q); e2 = n_remove(&q, 2); G->q_even = UWORD(1) << e2; /* number of components at p=2 */ G->neven = (e2 >= 3) ? 2 : (e2 == 2) ? 1 : 0; /* warning: only factor odd part */ n_factor_init(&fac); n_factor(&fac, q, 1); G->num = fac.num + G->neven; G->P = flint_malloc(G->num * sizeof(dirichlet_prime_group_struct)); G->generators = flint_malloc(G->num * sizeof(ulong)); G->PHI = flint_malloc(G->num * sizeof(ulong)); /* even part */ if (G->neven >= 1) dirichlet_prime_group_init(&G->P[0], 2, e2); if (G->neven == 2) dirichlet_prime_group_init(&G->P[1], 4, e2); /* odd part */ G->rad_q = 1; for (k = G->neven; k < G->num; k++) { ulong p, e; p = fac.p[k - G->neven]; e = fac.exp[k - G->neven]; G->rad_q *= p; dirichlet_prime_group_init(&G->P[k], p, e); } dirichlet_group_lift_generators(G); } void dirichlet_subgroup_init(dirichlet_group_t H, const dirichlet_group_t G, ulong h) { int s[15]; /* selected components */ slong k, j, e2; H->q = h; nmod_init(&H->mod, h); /* even components */ e2 = n_remove(&h, 2); H->q_even = UWORD(1) << e2; s[0] = s[1] = 0; j = 0; if (e2 >= 2) s[j++] = 2; if (e2 >= 3) s[j++] = e2; H->neven = j; /* odd components */ for (k = G->neven; k < G->num; k++) { ulong p = G->P[k].p; s[k] = n_remove(&h, p); if (s[k] > 0) { j++; H->rad_q *= p; } } H->num = j; H->P = flint_malloc(j * sizeof(dirichlet_prime_group_struct)); H->generators = flint_malloc(j * sizeof(ulong)); H->PHI = flint_malloc(j * sizeof(ulong)); j = 0; for (k = 0; k < H->neven; k++) { H->P[j] = G->P[k]; if (H->q_even < G->q_even) { nmod_init(&H->P[j].pe, H->q_even); H->P[j].e = s[k]; if (k == 0) H->P[j].g = H->q_even - 1; else nmod_init(&H->P[j].phi, H->q_even / 4); } j++; } for (k = G->neven; k < G->num; k++) { if (s[k]) { H->P[j] = G->P[k]; if (s[k] < G->P[k].e) { ulong pf, p = H->P[j].p; H->P[j].e = s[k]; pf = n_pow(p, s[k]); nmod_init(&H->P[j].pe, pf); nmod_init(&H->P[j].phi, (p-1) * pf / p); } j++; } } dirichlet_group_lift_generators(H); } arb-2.22.1/dirichlet/group_num_primitive.c000066400000000000000000000015571417376376500206130ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong dirichlet_group_num_primitive(const dirichlet_group_t G) { if (G->q % 4 == 2) return 0; else { slong k; ulong n = 1; /* no overflow since result < G->q */ for (k = (G->neven == 2); k < G->num; k++) { ulong p = G->P[k].p, e = G->P[k].e; if (e == 1) n *= p - 2; else n *= (p * (p - 2) + 1) * n_pow(p, e - 2); } return n; } } arb-2.22.1/dirichlet/index_char.c000066400000000000000000000024411417376376500166050ustar00rootroot00000000000000/*============================================================================= This file is part of ARB. ARB 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. ARB 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 ARB; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =============================================================================*/ /****************************************************************************** Copyright (C) 2016 Pascal Molin ******************************************************************************/ #include "dirichlet.h" ulong dirichlet_index_char(const dirichlet_group_t G, const dirichlet_char_t x) { slong k; ulong j = 0; for (k = 0; k < G->num; k++) j = j * G->P[k].phi.n + x->log[k]; return j; } arb-2.22.1/dirichlet/pairing.c000066400000000000000000000015131417376376500161310ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong dirichlet_pairing(const dirichlet_group_t G, ulong m, ulong n) { ulong x; dirichlet_char_t a, b; if (n_gcd(G->q, m) > 1 || n_gcd(G->q, n) > 1) return DIRICHLET_CHI_NULL; dirichlet_char_init(a, G); dirichlet_char_init(b, G); dirichlet_char_log(a, G, m); dirichlet_char_log(b, G, n); x = dirichlet_pairing_char(G, a, b); dirichlet_char_clear(a); dirichlet_char_clear(b); return x; } arb-2.22.1/dirichlet/pairing_char.c000066400000000000000000000013241417376376500171260ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong dirichlet_pairing_char(const dirichlet_group_t G, const dirichlet_char_t chi, const dirichlet_char_t x) { ulong v = 0, k; nmod_t order; nmod_init(&order, G->expo); for (k = 0; k < G->num; k++) v = nmod_add(v, G->PHI[k] * nmod_mul(chi->log[k], x->log[k], G->P[k].phi), order); return v; } arb-2.22.1/dirichlet/profile/000077500000000000000000000000001417376376500157745ustar00rootroot00000000000000arb-2.22.1/dirichlet/profile/p-conrey.c000066400000000000000000000112371417376376500177000ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "dirichlet.h" #include "flint/profiler.h" #define LOG 0 #define CSV 1 #define JSON 2 typedef ulong (*do_f) (ulong q1, ulong q2); static ulong do_gcd(ulong q1, ulong q2) { ulong n, q, k; for (n = 0, q = q1; q <= q2; q++) for (k = 1; k < q; k++) n += (n_gcd(k, q) == 1); return n; } static ulong do_char(ulong q1, ulong q2) { ulong n, q; for (n = 0, q = q1; q <= q2; q++) { dirichlet_group_t G; dirichlet_char_t x; dirichlet_group_init(G, q); dirichlet_char_init(x, G); dirichlet_char_one(x, G); n++; for (; dirichlet_char_next(x, G) >= 0; n++); dirichlet_char_clear(x); dirichlet_group_clear(G); } return n; } static ulong do_gcdpluscond(ulong q1, ulong q2) { ulong n, q, k; for (n = 0, q = q1; q <= q2; q++) { dirichlet_group_t G; dirichlet_group_init(G, q); for (k = 1; k < q; k++) { /* known factors -> faster gcd */ slong i; if (G->q_even > 1 && k % 2 == 0) continue; for (i = G->neven; i < G->num; i++) if (k % G->P[i].p == 0) break; if (i == G->num) dirichlet_conductor_ui(G, k); } n += G->phi_q; dirichlet_group_clear(G); } return n; } static ulong do_charpluscond(ulong q1, ulong q2) { ulong n, q, k; for (n = 0, q = q1; q <= q2; q++) { dirichlet_group_t G; dirichlet_char_t x; dirichlet_group_init(G, q); dirichlet_char_init(x, G); dirichlet_char_one(x, G); n++; for (; dirichlet_char_next(x, G) >= 0; n++) dirichlet_conductor_char(G, x); dirichlet_char_clear(x); dirichlet_group_clear(G); } return n; } static ulong do_charplusorder(ulong q1, ulong q2) { ulong n, q, k; for (n = 0, q = q1; q <= q2; q++) { dirichlet_group_t G; dirichlet_char_t x; dirichlet_group_init(G, q); dirichlet_char_init(x, G); dirichlet_char_one(x, G); n++; for (; dirichlet_char_next(x, G) >= 0; n++) dirichlet_order_char(G, x); dirichlet_char_clear(x); dirichlet_group_clear(G); } return n; } int main(int argc, char *argv[]) { int out; ulong n, nref, maxq = 5000; int l, nf = 5; do_f func[5] = { do_gcd, do_char, do_gcdpluscond, do_charpluscond, do_charplusorder }; char * name[5] = { "gcd", "char", "gcd + cond", "char + cond", "char + order" }; int i, ni = 5; ulong qmin[5] = { 2, 1000, 10000, 100000, 1000000 }; ulong qmax[5] = { 500, 3000, 11000, 100100, 1000010 }; if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } if (out == CSV) flint_printf("# %-12s, %7s, %7s, %7s\n","name", "qmin", "qmax", "time"); for (i = 0; i < ni; i++) { if (out == LOG) { flint_printf("loop over all (Z/q)* for %wu<=q<=%wu\n", qmin[i], qmax[i]); } for (l = 0; l < nf; l++) { if (out == LOG) flint_printf("%-14s ... ",name[l]); else if (out == CSV) flint_printf("%-12s, %7d, %7d, ",name[l],qmin[i],qmax[i]); else if (out == JSON) flint_printf("{ \"name\": \"%s\", \"qmin\": %d, \"qmax\": %d, \"time\": ", name[l],qmin[i],qmax[i]); TIMEIT_ONCE_START (func[l])(qmin[i], qmax[i]); TIMEIT_ONCE_STOP if (l == 0) nref = n; else if (n != nref) { flint_printf("FAIL: wrong number of elements %wu != %wu\n\n",n, nref); flint_abort(); } if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } } flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/dirichlet/test/000077500000000000000000000000001417376376500153135ustar00rootroot00000000000000arb-2.22.1/dirichlet/test/t-chars.c000066400000000000000000000116371417376376500170300ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" #include "arb.h" /* for test_multiplier */ int main() { slong iter; flint_rand_t state; flint_printf("char...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { dirichlet_group_t G; dirichlet_char_t x, y; ulong q, n, k, sum; slong ref; q = 1 + n_randint(state, 1000 * (1 + iter / 100)); dirichlet_group_init(G, q); dirichlet_char_init(x, G); dirichlet_char_init(y, G); /* check group size and elements */ dirichlet_char_one(x, G); sum = 1; for (n = 1; dirichlet_char_next(x, G) >= 0; n++) sum += x->n * x->n; if (FLINT_BITS == 64 || q < 1024) { /* use http://oeis.org/A053818 to check all elements * are gone through */ ref = (q % 4 == 2) ? -2 : 1; for (k = (G->neven == 2); k < G->num; k++) ref = - ref * G->P[k].p; ref = ( G->phi_q * (2 * q * q + ref) ) / 6; if (n != G->phi_q) { flint_printf("FAIL: group size\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("phi(q) = %wu\n\n", G->phi_q); flint_printf("loop index = %wu\n\n", n); flint_abort(); } if (sum != ref && q > 1) { flint_printf("FAIL: sum test\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("sum k^2 = %wu\n\n", ref); flint_printf("sum obtained = %wu\n\n", sum); flint_abort(); } } if (q % 4 != 2) { dirichlet_char_first_primitive(x, G); for (n = 1; dirichlet_char_next_primitive(x, G) >= 0; n++); ref = dirichlet_group_num_primitive(G); if (n != ref) { flint_printf("FAIL: number of primitive elements\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("# primitive = %wu\n\n", ref); flint_printf("loop index = %wu\n\n", n); flint_abort(); } /* some random elements, check log and exp */ for (n = 0; n < 30; n++) { slong k; ulong m; for (m = 1; n_gcd(m, q) > 1; m = n_randint(state, q)); dirichlet_char_log(x, G, m); if (m != _dirichlet_char_exp(x, G)) { flint_printf("FAIL: char log and exp\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("char = "); dirichlet_char_print(G, x); flint_printf("\n\nnumber = %wu\n\n", x->n); flint_abort(); } for (k = 0; k < G->num; k++) x->log[k] = n_randint(state, G->P[k].phi.n); m = _dirichlet_char_exp(x, G); dirichlet_char_log(y, G, m); if (!dirichlet_char_eq_deep(G, x, y)) { flint_printf("FAIL: char exp and log\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("char = "); dirichlet_char_print(G, x); flint_printf("\n\nm = %wu\n\n", m); flint_printf("log = "); dirichlet_char_print(G, y); flint_printf("\n\nnumber = %wu\n\n", y->n); flint_abort(); } dirichlet_char_next_primitive(x, G); m = x->n; if (m != _dirichlet_char_exp(x, G)) { flint_printf("FAIL: char number next primitive\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("char = "); dirichlet_char_print(G, y); flint_printf(", m = %wu\n\n", y->n); flint_printf("next primitive = "); dirichlet_char_print(G, x); flint_printf(", m = %wu\n\n", m); flint_printf("exp = %wu\n\n", x->n); flint_abort(); } } } dirichlet_char_clear(x); dirichlet_char_clear(y); dirichlet_group_clear(G); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dirichlet/test/t-properties.c000066400000000000000000000155661417376376500201310ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" static void check_eq(ulong p1, ulong p2, ulong q, ulong m, char * fct1, char * fct2) { if (p1 != p2) { flint_printf("FAIL:\n\n"); flint_printf("chi_%wu(%wu,.)\n\n", q, m); flint_printf("%s = %wu\n\n", fct1, p1); flint_printf("%s = %wu\n\n", fct2, p2); flint_abort(); } } static ulong random_divisor(flint_rand_t state, const dirichlet_group_t G) { ulong d; slong k; d = 1; for (k = (G->neven == 2); k < G->num; k++) d *= n_pow(G->P[k].p, n_randint(state, G->P[k].e)); return d; } int main() { slong iter, bits; flint_rand_t state; flint_printf("properties...."); fflush(stdout); flint_randinit(state); for (bits = 5; bits <= 30; bits += 5) { for (iter = 0; iter < 50; iter++) { dirichlet_group_t G; dirichlet_char_t chi, psi; ulong q, iter2; q = 2 + n_randint(state, 1 << bits); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_init(psi, G); /* check number char properties */ for (iter2 = 0; iter2 < 100; iter2++) { ulong m, n; ulong p1, p2, pairing, cm, cn, q2, q3; dirichlet_group_t G2, G3; dirichlet_char_t chi2, chi3; if (iter2 == 50) dirichlet_group_dlog_precompute(G, 5); /* one random character */ do m = n_randint(state, q); while (n_gcd(q, m) > 1); dirichlet_char_log(chi, G, m); p1 = dirichlet_order_ui(G, m); p2 = dirichlet_order_char(G, chi); check_eq(p1, p2, q, m, "order m", "order chi"); p1 = dirichlet_conductor_ui(G, m); p2 = dirichlet_conductor_char(G, chi); check_eq(p1, p2, q, m, "conductor m", "conductor chi"); p1 = dirichlet_parity_ui(G, m); p2 = dirichlet_parity_char(G, chi); check_eq(p1, p2, q, m, "parity m", "parity chi"); p1 = dirichlet_char_is_real(G, chi); p2 = (dirichlet_order_char(G, chi) <= 2); check_eq(p1, p2, q, m, "is_real", "(order <= 2)"); /* check index */ p1 = dirichlet_index_char(G, chi); dirichlet_char_index(psi, G, p1); if (!dirichlet_char_eq_deep(G, chi, psi)) { flint_printf("FAIL: index\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("chi = "); dirichlet_char_print(G, chi); flint_printf("\n\nindex(chi) = %wu\n\n", p1); flint_printf("psi(index) = %wu\n\n", psi->n); flint_printf("psi = "); dirichlet_char_print(G, psi); flint_printf("\n\n"); flint_abort(); } /* lift to higher modulus */ do { q2 = q * (1 + n_randint(state, 100)); } while (q2 % q); /* in case of overflow */ dirichlet_group_init(G2, q2); dirichlet_char_init(chi2, G2); dirichlet_char_lift(chi2, G2, chi, G); p1 = dirichlet_conductor_char(G, chi); p2 = dirichlet_conductor_char(G2, chi2); check_eq(p1, p2, q, m, "conductor chi", "conductor lift"); p1 = dirichlet_order_char(G, chi); p2 = dirichlet_order_char(G2, chi2); check_eq(p1, p2, q, m, "order chi", "order lift"); /* and lower */ dirichlet_char_lower(psi, G, chi2, G2); if (!dirichlet_char_eq_deep(G, chi, psi)) { flint_printf("FAIL: lift and lower back\n\n"); flint_printf("q = %wu\n\nchi = ", q); dirichlet_char_print(G, chi); flint_printf("\n\nq2 = %wu\n\nchi2 = ", q2); dirichlet_char_print(G2, chi2); flint_printf("\n\nq = %wu\n\npsi = ", q); dirichlet_char_print(G, psi); flint_printf("\n\n"); flint_abort(); } /* choose q3 s.t. conductor | q3 | q */ q3 = dirichlet_conductor_char(G, chi) * random_divisor(state, G); q3 = n_gcd(q, q3); /* discard if overflow */ if (q3 % p1 == 0) { dirichlet_group_init(G3, q3); dirichlet_char_init(chi3, G3); dirichlet_char_lower(chi3, G3, chi2, G2); p1 = dirichlet_conductor_char(G, chi); p2 = dirichlet_conductor_char(G3, chi3); check_eq(p1, p2, q, m, "conductor chi", "conductor lower"); p1 = dirichlet_order_char(G, chi); p2 = dirichlet_order_char(G3, chi3); check_eq(p1, p2, q, m, "order chi", "order lower"); dirichlet_char_clear(chi3); dirichlet_group_clear(G3); } dirichlet_char_clear(chi2); dirichlet_group_clear(G2); /* another random character */ do n = n_randint(state, q); while (n_gcd(q, n) > 1); dirichlet_char_log(psi, G, n); pairing = dirichlet_pairing(G, m, n); cn = dirichlet_chi(G, chi, n); cm = dirichlet_chi(G, psi, m); if (pairing != cn || pairing != cm) { flint_printf("FAIL: pairing\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("n = %wu\n\n", n); flint_printf("chi(m,n) = %wu\n\n", pairing); flint_printf("chi(m)(n) = %wu\n\n", cn); flint_printf("chi(n)(m) = %wu\n\n", cm); flint_abort(); } } dirichlet_group_dlog_clear(G); dirichlet_char_clear(chi); dirichlet_char_clear(psi); dirichlet_group_clear(G); } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dirichlet/test/t-vec.c000066400000000000000000000045671417376376500165110ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" static ulong vec_diff(ulong * v, ulong * ref, ulong nv) { ulong k; for (k = 1; k < nv; k++) if (ref[k] != v[k]) return k; return 0; } int main() { ulong q; flint_printf("vec...."); fflush(stdout); for (q = 2; q < 600; q ++) { dirichlet_group_t G; dirichlet_char_t chi; ulong * v1, * v2, nv, k; dirichlet_group_init(G, q); dirichlet_char_init(chi, G); nv = 100; v1 = flint_malloc(nv * sizeof(ulong)); v2 = flint_malloc(nv * sizeof(ulong)); dirichlet_char_one(chi, G); do { ulong order; dirichlet_chi_vec_loop(v1, G, chi, nv); dirichlet_chi_vec_primeloop(v2, G, chi, nv); if ((k = vec_diff(v1, v2, nv))) { flint_printf("FAIL: chi_%wu(%wu,%wu) [mod %wu]\n", q, chi->n, k, G->expo); flint_printf("vec_loop -> %wu\n", v1[k]); flint_printf("vec_primeloop -> %wu\n", v2[k]); flint_printf("pairing = %wu\n", dirichlet_pairing(G, chi->n, k)); flint_abort(); } order = dirichlet_order_char(G, chi); dirichlet_chi_vec_loop_order(v1, G, chi, order, nv); dirichlet_chi_vec_primeloop_order(v2, G, chi, order, nv); if ((k = vec_diff(v1, v2, nv))) { flint_printf("FAIL: chi_%wu(%wu,%wu) [mod %wu]\n", q, chi->n, k, order); flint_printf("vec_loop -> %wu\n", v1[k]); flint_printf("vec_primeloop -> %wu\n", v2[k]); flint_printf("pairing = %wu mod %wu\n", dirichlet_pairing(G, chi->n, k), G->expo); flint_abort(); } } while (dirichlet_char_next(chi, G) >= 0); flint_free(v1); flint_free(v2); dirichlet_group_clear(G); dirichlet_char_clear(chi); } flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dirichlet/ui_conductor.c000066400000000000000000000020651417376376500172000ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" ulong dirichlet_conductor_ui(const dirichlet_group_t G, ulong a) { slong k; ulong ap, cond; cond = 1; for (k = (G->neven == 2); k < G->num; k++) { ulong p; nmod_t pe; p = G->P[k].p; pe = G->P[k].pe; ap = a % pe.n; if (ap == 1) continue; if (p == 2) { cond = 4; if (a % 4 == 3) ap = pe.n - ap; } else { cond *= p; ap = nmod_pow_ui(ap, p - 1, pe); } while (ap != 1) { cond *= p; ap = nmod_pow_ui(ap, p, pe); } } return cond; } arb-2.22.1/dirichlet/ui_order.c000066400000000000000000000020431417376376500163070ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" /* order of an element knowing the factorization of a multiple */ ulong nmod_order_precomp(ulong a, nmod_t mod, ulong expo, n_factor_t fac) { int k; ulong pe, ap, order = 1; for (k = 0; k < fac.num; k++) { pe = n_pow(fac.p[k], fac.exp[k]); ap = nmod_pow_ui(a, expo / pe, mod); while ( ap != 1) { ap = nmod_pow_ui(ap, fac.p[k], mod); order *= fac.p[k]; } } return order; } ulong dirichlet_order_ui(const dirichlet_group_t G, ulong a) { n_factor_t fac; n_factor_init(&fac); n_factor(&fac, G->expo, 1); return nmod_order_precomp(a, G->mod, G->expo, fac); } arb-2.22.1/dirichlet/ui_parity.c000066400000000000000000000011551417376376500165070ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" int dirichlet_parity_ui(const dirichlet_group_t G, ulong a) { int par; par = 0; if (G->neven && a % 4 == 3) par++; if (n_jacobi_unsigned(a, G->rad_q) == -1) par++; return par % 2; } arb-2.22.1/dirichlet/ui_vec_set_null.c000066400000000000000000000013521417376376500176600ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dirichlet.h" void dirichlet_vec_set_null(ulong *v, const dirichlet_group_t G, slong nv) { slong k, l; if (G->q_even > 1) { for (k = 2; k < nv; k += 2) v[k] = -1; } for (l = G->neven; l < G->num; l++) { ulong p = G->P[l].p; for (k = p; k < nv; k += p) v[k] = DIRICHLET_CHI_NULL; } } arb-2.22.1/dlog.h000066400000000000000000000165701417376376500134740ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef DLOG_H #define DLOG_H #ifdef DLOG_INLINES_C #define DLOG_INLINE #else #define DLOG_INLINE static __inline__ #endif #include "flint/flint.h" #ifndef flint_abort #if __FLINT_RELEASE <= 20502 #define flint_abort abort #endif #endif #include "flint/ulong_extras.h" #include "flint/nmod_vec.h" #ifdef __cplusplus extern "C" { #endif enum { DLOG_MODPE, DLOG_CRT, DLOG_POWER, DLOG_BSGS, DLOG_TABLE, DLOG_23 }; typedef struct dlog_precomp_struct dlog_precomp_struct; typedef struct dlog_precomp_struct * dlog_precomp_ptr; /* log in (1+pZ/p^eZ), e small: use recursion formulas * could use padic log instead but exponent is small * for ulongs */ typedef struct { ulong inv1p; /* 1 / (1 + p) */ ulong invloga1; /* 1 / log(a^(p-1),1+p) */ } dlog_1modpe_struct; typedef dlog_1modpe_struct dlog_1modpe_t[1]; /* log in (Z/p^eZ)^* */ typedef struct { ulong p; ulong e; ulong pe1; /* p^(e-1) */ ulong inva; nmod_t pe; dlog_precomp_struct * modp; dlog_1modpe_t modpe; } dlog_modpe_struct; typedef dlog_modpe_struct dlog_modpe_t[1]; /* all logs precomputed in (Z/modZ)^ast */ typedef struct { ulong mod; ulong * table; } dlog_table_struct; typedef dlog_table_struct dlog_table_t[1]; /* bsgs table, already in flint */ typedef struct apow { ulong k; ulong ak; } apow_t; int apow_cmp(const apow_t * x, const apow_t * y); typedef struct { nmod_t mod; ulong m; ulong am; ulong g; apow_t * table; } dlog_bsgs_struct; typedef dlog_bsgs_struct dlog_bsgs_t[1]; /* typedef bsgs_t dlog_bsgs_t; */ /* Pollard rho */ typedef struct { ulong a; nmod_t n; nmod_t mod; int nisprime; } dlog_rho_struct; typedef dlog_rho_struct dlog_rho_t[1]; /* CRT decomposition (Pohlig-Hellman) */ typedef struct { nmod_t mod; nmod_t n; ulong num; ulong * expo; ulong * crt_coeffs; dlog_precomp_ptr pre; } dlog_crt_struct; typedef dlog_crt_struct dlog_crt_t[1]; /* dlog when generator has prime power order */ typedef struct { nmod_t mod; ulong p; ulong e; ulong * apk; dlog_precomp_struct * pre; } dlog_power_struct; typedef dlog_power_struct dlog_power_t[1]; typedef ulong dlog_order23_t[1]; /* generic decomposition */ /*typedef */ struct dlog_precomp_struct { int type; ulong cost; union { dlog_table_t table; dlog_bsgs_t bsgs; dlog_crt_t crt; dlog_power_t power; dlog_modpe_t modpe; dlog_order23_t order23; } t; }; typedef dlog_precomp_struct dlog_precomp_t[1]; void dlog_precomp_modpe_init(dlog_precomp_t pre, ulong a, ulong p, ulong e, ulong pe, ulong num); void dlog_precomp_small_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num); void dlog_precomp_n_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num); void dlog_precomp_p_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong num); void dlog_precomp_pe_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong e, ulong pe, ulong num); void dlog_precomp_clear(dlog_precomp_t pre); ulong dlog_precomp(const dlog_precomp_t pre, ulong b); ulong dlog_order23_init(dlog_order23_t t, ulong a); ulong dlog_table_init(dlog_table_t t, ulong a, ulong mod); ulong dlog_crt_init(dlog_crt_t t, ulong a, ulong mod, ulong n, ulong num); ulong dlog_power_init(dlog_power_t t, ulong a, ulong mod, ulong p, ulong e, ulong num); ulong dlog_modpe_init(dlog_modpe_t t, ulong a, ulong p, ulong e, ulong pe, ulong num); ulong dlog_bsgs_init(dlog_bsgs_t t, ulong a, ulong mod, ulong n, ulong m); void dlog_1modpe_init(dlog_1modpe_t t, ulong a1, ulong p, ulong e, nmod_t pe); void dlog_rho_init(dlog_rho_t t, ulong a, ulong mod, ulong n); /*#define dlog_bsgs_init(t, a, n, m) bsgs_table_init(t, a, n, m)*/ ulong dlog_once(ulong b, ulong a, const nmod_t mod, ulong n); DLOG_INLINE void dlog_order23_clear(dlog_order23_t t) { return; } DLOG_INLINE void dlog_table_clear(dlog_table_t t) { flint_free(t->table); } void dlog_crt_clear(dlog_crt_t t); DLOG_INLINE void dlog_power_clear(dlog_power_t t) { flint_free(t->apk); dlog_precomp_clear(t->pre); flint_free(t->pre); } DLOG_INLINE void dlog_modpe_clear(dlog_modpe_t t) { dlog_precomp_clear(t->modp); flint_free(t->modp); } DLOG_INLINE void dlog_bsgs_clear(dlog_bsgs_t t) { flint_free(t->table); } DLOG_INLINE void dlog_rho_clear(dlog_rho_t t) { return; } DLOG_INLINE ulong dlog_bsgs_size(ulong n, ulong num) { if (2 * num < n) return (1 + n_sqrt(n)) * (1 + n_sqrt(num)); else return n; } /*#define dlog_bsgs_clear(t) bsgs_table_clear(t)*/ ulong dlog_order23(const dlog_order23_t t, ulong b); ulong dlog_table(const dlog_table_t t, ulong b); ulong dlog_crt(const dlog_crt_t t, ulong b); ulong dlog_power(const dlog_power_t t, ulong b); ulong dlog_modpe(const dlog_modpe_t t, ulong b); ulong dlog_bsgs(const dlog_bsgs_t t, ulong b); ulong dlog_rho(const dlog_rho_t t, ulong b); ulong dlog_1modpe_1modp(ulong b1, ulong p, ulong e, ulong inv1p, nmod_t pe); ulong dlog_1modpe(const dlog_1modpe_t t, ulong b1, ulong p, ulong e, nmod_t pe); ulong dlog_mod2e_1mod4(ulong b1, ulong e, ulong inva, nmod_t pe); ulong dlog_mod2e(const dlog_modpe_t t, ulong b); /*#define dlog_bsgs(t, b) n_discrete_log_bsgs_table(t, b)*/ #define DLOG_SMALL_LIM 50 #define DLOG_TABLE_LIM 50 #define DLOG_TABLE_P_LIM 50 #define DLOG_TABLE_MODPE_LIM 50 #define DLOG_TABLE_PE_LIM 50 #define DLOG_TABLE_N_LIM 50 #define DLOG_BSGS_LIM 500 #define DLOG_LOOP_MAX_FACTOR 6 #define DLOG_G_SMALL 0 #define DLOG_G_BIG 1 void dlog_n_factor_group(n_factor_t * fac, ulong bound); #define DLOG_NOT_FOUND UWORD_MAX #define DLOG_NONE UWORD_MAX ulong dlog_vec_pindex_factorgcd(ulong * v, ulong nv, ulong p, nmod_t mod, ulong a, ulong na, ulong loga, ulong logm1, nmod_t order, int maxtry); void dlog_vec_fill(ulong * v, ulong nv, ulong x); void dlog_vec_set_not_found(ulong *v, ulong nv, nmod_t mod); void dlog_vec_loop(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_loop_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_eratos_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_eratos(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_sieve_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_sieve(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_sieve_precomp(ulong *v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_sieve_add_precomp(ulong *v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); void dlog_vec_add_precomp(ulong *v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order); #ifdef __cplusplus } #endif #endif arb-2.22.1/dlog/000077500000000000000000000000001417376376500133125ustar00rootroot00000000000000arb-2.22.1/dlog/1modpe.c000066400000000000000000000012721417376376500146450ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_1modpe(const dlog_1modpe_t t, ulong b1, ulong p, ulong e, nmod_t pe) { if (e == 1) return 0; else { ulong logb1; logb1 = dlog_1modpe_1modp(b1, p, e, t->inv1p, pe); /* only need mod p^(e-1) */ return nmod_mul(logb1, t->invloga1, pe); } } arb-2.22.1/dlog/1modpe_init.c000066400000000000000000000015451417376376500156730ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_1modpe_init(dlog_1modpe_t t, ulong a1, ulong p, ulong e, nmod_t pe) { if (e == 1) { t->inv1p = 1; t->invloga1 = 0; } else { ulong loga1; if (a1 == 1) flint_abort(); t->inv1p = nmod_inv(1 + p, pe); /* 1 - p + p^2 - ... */ loga1 = dlog_1modpe_1modp(a1, p, e, t->inv1p, pe); /* only need inverse mod p^(e-1) but does not hurt */ t->invloga1 = nmod_inv(loga1, pe); } } arb-2.22.1/dlog/1modpe_mod1p.c000066400000000000000000000017511417376376500157470ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* for odd prime p, assume b1 = 1 mod p */ ulong dlog_1modpe_1modp(ulong b1, ulong p, ulong e, ulong inv1p, nmod_t pe) { int f; ulong x, xf, pf, pf1; pf1 = 1; pf = p; x = 0; for (f = 1; f < e; f++) { if (b1 % pf != 1) { flint_printf("ERROR dlog_1modpe_1modp: %wu %% %wu != 1 mod %wu\n\n", b1, pf, pe.n); flint_abort(); } xf = (b1 - 1) / pf; xf = (xf % p) * pf1; x += xf; b1 = nmod_mul(b1, nmod_pow_ui(inv1p, xf, pe), pe); pf1 = pf; pf *= p; } return x; } arb-2.22.1/dlog/bsgs.c000066400000000000000000000020601417376376500144120ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "dlog.h" ulong dlog_bsgs(const dlog_bsgs_t t, ulong b) { ulong i; apow_t c, * x; c.ak = b; for (i = 0; i < t->g; i++) { x = bsearch(&c, t->table, t->m, sizeof(apow_t), (int(*)(const void*,const void*))apow_cmp); if (x != NULL) return i * t->m + x->k; c.ak = nmod_mul(c.ak, t->am, t->mod); } flint_printf("Exception (dlog_bsgs). discrete log not found.\n"); flint_printf(" table size %wu, cosize %wu mod %wu. %wu not found (a^-m=%wu)\n", t->m, t->g, t->mod.n, b, t->am); flint_abort(); return 0; /* dummy return because flint_abort() is not declared noreturn */ } arb-2.22.1/dlog/bsgs_init.c000066400000000000000000000020201417376376500154310ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "dlog.h" int apow_cmp(const apow_t * x, const apow_t * y) { return (x->ak < y->ak) ? -1 : (x->ak > y->ak); } ulong dlog_bsgs_init(dlog_bsgs_t t, ulong a, ulong mod, ulong n, ulong m) { ulong k, ak; if (m >= n) m = n; t->table = (apow_t *)flint_malloc(m * sizeof(apow_t)); nmod_init(&t->mod, mod); t->m = m; t->g = n / m + 1; for (k = 0, ak = 1; k < m; k++) { t->table[k].k = k; t->table[k].ak = ak; ak = nmod_mul(ak, a, t->mod); } t->am = nmod_inv(ak, t->mod); qsort(t->table, m, sizeof(apow_t), (int(*)(const void*,const void*))apow_cmp); return t->g; } arb-2.22.1/dlog/crt.c000066400000000000000000000015561417376376500142550ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_crt(const dlog_crt_t t, ulong b) { int k; ulong r = 0; for (k = 0; k < t->num; k++) { ulong bk, rk; bk = nmod_pow_ui(b, t->expo[k], t->mod); rk = dlog_precomp(t->pre + k, bk); #if 0 flint_printf("##[crt-%d]: log(%wu)=log(%wu^%wu) = %wu [size %wu mod %wu]\n", k, bk, b, t->expo[k], rk, t->n/t->expo[k], t->mod); #endif r = nmod_add(r, nmod_mul(t->crt_coeffs[k], rk, t->n), t->n); } return r; } arb-2.22.1/dlog/crt_clear.c000066400000000000000000000011241417376376500154120ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_crt_clear(dlog_crt_t t) { int k; flint_free(t->expo); flint_free(t->crt_coeffs); for (k = 0; k < t->num; k++) dlog_precomp_clear(t->pre + k); flint_free(t->pre); } arb-2.22.1/dlog/crt_init.c000066400000000000000000000031161417376376500152720ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_crt_init(dlog_crt_t t, ulong a, ulong mod, ulong n, ulong num) { int k; n_factor_t fac; ulong * M, * u; ulong cost = 0; n_factor_init(&fac); n_factor(&fac, n, 1); t->num = fac.num; nmod_init(&t->mod,mod); nmod_init(&t->n, n); M = t->expo = flint_malloc(t->num * sizeof(ulong)); u = t->crt_coeffs = flint_malloc(t->num * sizeof(ulong)); t->pre = flint_malloc(t->num * sizeof(dlog_precomp_struct)); for (k = 0; k < t->num; k++) { ulong p, e, mk; p = fac.p[k]; e = fac.exp[k]; if (0 && mod % p == 0) { flint_printf("dlog_crt_init: modulus must be prime to order.\n"); flint_abort(); } mk = n_pow(p, e); M[k] = n / mk; u[k] = nmod_mul(M[k], n_invmod(M[k] % mk, mk), t->n); /* depends on the power */ #if 0 flint_printf("[sub-crt -- init for size %wu mod %wu]\n", mk, mod); #endif dlog_precomp_pe_init(t->pre + k, nmod_pow_ui(a, M[k], t->mod), mod, p, e, mk, num); cost += t->pre[k].cost; } #if 0 if (cost > 500) flint_printf("[crt init for size %wu mod %wu -> cost %wu]\n", n,mod,cost); #endif return cost; } arb-2.22.1/dlog/factor_group.c000066400000000000000000000022601417376376500161500ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* group components up to bound and return cofactor */ void dlog_n_factor_group(n_factor_t * fac, ulong bound) { int i, j, k; ulong m[FLINT_MAX_FACTORS_IN_LIMB]; ulong c = 1; i = 0; for (k = fac->num - 1; k >= 0; k--) { ulong qe = n_pow(fac->p[k], fac->exp[k]); if (qe > bound) c *= qe; else { /* try to insert somewhere in m */ for (j = 0; j < i && (m[j] * qe > bound); j++); if (j == i) m[i++] = qe; else m[j] *= qe; } } for (j = 0; j < i; j++) { fac->p[j] = m[j]; fac->exp[j] = DLOG_G_SMALL; } if (c > 1) { fac->p[i] = c; fac->exp[i] = DLOG_G_BIG; i++; } fac->num = i; } arb-2.22.1/dlog/mod2e.c000066400000000000000000000021621417376376500144650ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_mod2e_1mod4(ulong b1, ulong e, ulong inv5, nmod_t pe) { slong f; ulong pf1, pf, x, xf; pf1 = 1; pf = 4; x = 0; for (f = 2; f < e; f++) { if (b1 % pf != 1) { flint_printf("ERROR dlog_mod2e: %wu %% %wu != 1 mod %wu\n\n", b1, pf, pe.n); flint_abort(); } xf = (b1 - 1) / pf; xf = (f == 2) ? xf % 4 : (xf % 2) * (pf1 / 2); b1 = nmod_mul(b1, nmod_pow_ui(inv5, xf, pe), pe); x += xf; pf1 = pf; pf *= 2; } return x; } ulong dlog_mod2e(const dlog_modpe_t t, ulong b1) { if (t->e == 2) return (b1 % 4) == 3; else return dlog_mod2e_1mod4(b1, t->e, t->inva, t->pe); } arb-2.22.1/dlog/modpe.c000066400000000000000000000020051417376376500145570ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_modpe(const dlog_modpe_t t, ulong b) { ulong x; if (t->p == 2) return dlog_mod2e(t, b); x = dlog_precomp(t->modp, b % t->p); if (t->e > 1) { ulong b1, y; #if 0 b1 = nmod_mul(b, nmod_pow_ui(t->inva, x, t->pe), t->pe); y = dlog_1modpe(t->modpe.rec, b1, t->p, t->e, t->pe); y = y % t->pe1; x = x + (t->p - 1) * y; #else b1 = nmod_pow_ui(b, t->p - 1, t->pe); y = dlog_1modpe(t->modpe, b1, t->p, t->e, t->pe); y = y % t->pe1; x = n_submod(x, y % (t->p - 1), t->p - 1); x = y + t->pe1 * x; #endif } return x; } arb-2.22.1/dlog/modpe_init.c000066400000000000000000000021641417376376500156100ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* todo: recursion could be made quadratic (not very useful for ulongs) */ ulong dlog_modpe_init(dlog_modpe_t t, ulong a, ulong p, ulong e, ulong pe, ulong num) { ulong a1; t->p = p; t->e = e; nmod_init(&t->pe, pe); t->inva = nmod_inv(a, t->pe); if (p == 2) { t->modp = NULL; t->pe1 = (e <= 2) ? 2 : pe / 4; t->modpe->inv1p = t->inva; t->modpe->invloga1 = 1; return e - 2; } else { t->modp = flint_malloc(sizeof(dlog_precomp_struct)); t->pe1 = pe / p; dlog_precomp_n_init(t->modp, a, p, p - 1, num); a1 = nmod_pow_ui(a, p - 1, t->pe); dlog_1modpe_init(t->modpe, a1, p, e, t->pe); return t->modp->cost + e; } } arb-2.22.1/dlog/once.c000066400000000000000000000021521417376376500144020ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_once(ulong b, ulong a, const nmod_t mod, ulong n) { if (b == 1) return 0; if (n < 50) { slong k; ulong ak = 1; for (k = 0; k < n; k++) { if (ak == b) return k; ak = nmod_mul(ak, a, mod); } flint_printf("FAIL[dlog once]: log(%wu,%wu) mod %wu not found (size %wu)\n", b, a, mod.n, n); flint_abort(); return 0; /* dummy return because flint_abort() is not declared noreturn */ } else { ulong l; dlog_precomp_t pre; dlog_precomp_n_init(pre, a, mod.n, n, 1); l = dlog_precomp(pre, b); dlog_precomp_clear(pre); return l; } } arb-2.22.1/dlog/order23.c000066400000000000000000000007571417376376500147470ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_order23(const dlog_order23_t t, ulong b) { return (b == *t) ? 1 : (b == 1) ? 0 : 2; } arb-2.22.1/dlog/order23_init.c000066400000000000000000000007341417376376500157650ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_order23_init(dlog_order23_t t, ulong a) { * t = a; return 0; } arb-2.22.1/dlog/power.c000066400000000000000000000015611417376376500146150ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_power(const dlog_power_t t, ulong b) { int k; ulong x, pk[30]; /* 3^30*2+1, 2^30*3+1 are primes */ pk[0] = 1; for (k = 1; k < t->e; k++) pk[k] = pk[k-1] * t->p; x = 0; for(k = 0; k < t->e; k++) { ulong bk, xk; bk = nmod_pow_ui(b, pk[t->e-1-k], t->mod); xk = dlog_precomp(t->pre, bk); b = nmod_mul(b, nmod_pow_ui(t->apk[k], xk, t->mod), t->mod); x += xk * pk[k]; /* cannot overflow */ } return x; } arb-2.22.1/dlog/power_init.c000066400000000000000000000015721417376376500156420ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_power_init(dlog_power_t t, ulong a, ulong mod, ulong p, ulong e, ulong num) { int k; nmod_init(&t->mod, mod); t->p = p; t->e = e; t->apk = flint_malloc(e * sizeof(ulong)); t->pre = flint_malloc(sizeof(dlog_precomp_struct)); t->apk[0] = nmod_inv(a, t->mod); for (k = 1; k < e; k++) t->apk[k] = nmod_pow_ui(t->apk[k-1], p, t->mod); dlog_precomp_p_init(t->pre, nmod_inv(t->apk[e-1], t->mod), mod, p, e * num); return e * t->pre->cost; } arb-2.22.1/dlog/precomp.c000066400000000000000000000020651417376376500151260ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_precomp(const dlog_precomp_t pre, ulong b) { if (b == 1) return 0; switch (pre->type) { case DLOG_MODPE: return dlog_modpe(pre->t.modpe, b); case DLOG_CRT: return dlog_crt(pre->t.crt, b); case DLOG_POWER: return dlog_power(pre->t.power, b); case DLOG_TABLE: return dlog_table(pre->t.table, b); case DLOG_BSGS: return dlog_bsgs(pre->t.bsgs, b); case DLOG_23: return dlog_order23(pre->t.order23, b); default: flint_abort(); } return 0; /* dummy return because flint_abort() is not declared noreturn */ } arb-2.22.1/dlog/precomp_clear.c000066400000000000000000000022271417376376500162740ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_precomp_clear(dlog_precomp_t pre) { if (pre == NULL) return; switch (pre->type) { case DLOG_MODPE: dlog_modpe_clear(pre->t.modpe); break; case DLOG_CRT: dlog_crt_clear(pre->t.crt); break; case DLOG_POWER: dlog_power_clear(pre->t.power); break; case DLOG_TABLE: dlog_table_clear(pre->t.table); break; case DLOG_BSGS: dlog_bsgs_clear(pre->t.bsgs); break; case DLOG_23: dlog_order23_clear(pre->t.order23); break; default: flint_printf("dlog_precomp_clear: unknown type %d\n", pre->type); flint_abort(); break; } } arb-2.22.1/dlog/precomp_modpe_init.c000066400000000000000000000016011417376376500173300ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* log mod p^e */ void dlog_precomp_modpe_init(dlog_precomp_t pre, ulong a, ulong p, ulong e, ulong pe, ulong num) { if (pe < DLOG_TABLE_MODPE_LIM) { dlog_precomp_small_init(pre, a, pe, pe - pe / p, num); return; } else { if (e > 1) { pre->type = DLOG_MODPE; pre->cost = dlog_modpe_init(pre->t.modpe, a, p, e, pe, num); } else { dlog_precomp_n_init(pre, a, p, p - 1, num); } } } arb-2.22.1/dlog/precomp_n_init.c000066400000000000000000000022551417376376500164670ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include "math.h" /* group of order n modulo mod, mod a prime and no information on n */ void dlog_precomp_n_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num) { if (n % 2 && n_is_probabprime(n)) dlog_precomp_p_init(pre, a, mod, n, num); else { if (n < DLOG_TABLE_N_LIM) { dlog_precomp_small_init(pre, a, mod, n, num); } else { if (n < DLOG_BSGS_LIM) { ulong m; m = dlog_bsgs_size(n, num); pre->type = DLOG_BSGS; pre->cost = dlog_bsgs_init(pre->t.bsgs, a, mod, n, m); } else { pre->type = DLOG_CRT; pre->cost = dlog_crt_init(pre->t.crt, a, mod, n, num); } } } } arb-2.22.1/dlog/precomp_p_init.c000066400000000000000000000014151417376376500164660ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* we known the order is prime */ void dlog_precomp_p_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong num) { if (p < DLOG_TABLE_P_LIM) { dlog_precomp_small_init(pre, a, mod, p, num); } else { ulong m; m = dlog_bsgs_size(p, num); pre->type = DLOG_BSGS; pre->cost = dlog_bsgs_init(pre->t.bsgs, a, mod, p, m); } } arb-2.22.1/dlog/precomp_pe_init.c000066400000000000000000000015341417376376500166350ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_precomp_pe_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong e, ulong pe, ulong num) { if (pe < DLOG_TABLE_PE_LIM) { dlog_precomp_small_init(pre, a, mod, pe, num); } else { if (e == 1) { dlog_precomp_p_init(pre, a, mod, p, num); } else { pre->type = DLOG_POWER; pre->cost = dlog_power_init(pre->t.power, a, mod, p, e, num); } } } arb-2.22.1/dlog/precomp_small_init.c000066400000000000000000000016171417376376500173430ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_precomp_small_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num) { if (n <= 3) { pre->type = DLOG_23; pre->cost = dlog_order23_init(pre->t.order23, a); } else { if (mod < DLOG_TABLE_LIM) { pre->type = DLOG_TABLE; pre->cost = dlog_table_init(pre->t.table, a, mod); } else { pre->type = DLOG_BSGS; pre->cost = dlog_bsgs_init(pre->t.bsgs, a, mod, n, n); } } } arb-2.22.1/dlog/profile/000077500000000000000000000000001417376376500147525ustar00rootroot00000000000000arb-2.22.1/dlog/profile/p-precomp.c000066400000000000000000000102051417376376500170160ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "dlog.h" #include "flint/profiler.h" #define NUMPRIMES 400 #define LOG 0 #define CSV 1 #define JSON 2 typedef void (*log_f) (ulong p, ulong a, ulong num); void flog_table(ulong p, ulong a, ulong num) { int k; dlog_table_t t; dlog_table_init(t, a, p); for (k = 1; k < num; k++) { if (k % p == 0) continue; dlog_table(t, k % p); } dlog_table_clear(t); } void flog_bsgs(ulong p, ulong a, ulong num) { int k; dlog_bsgs_t t; dlog_bsgs_init(t, a, p, p-1, dlog_bsgs_size(p, num)); for (k = 1; k < num; k++) { if (k % p == 0) continue; dlog_bsgs(t, k % p); } dlog_bsgs_clear(t); } void flog_rho(ulong p, ulong a, ulong num) { int k; dlog_rho_t t; dlog_rho_init(t, a, p, p-1); for (k = 1; k < num; k++) { if (k % p == 0) continue; dlog_rho(t, k % p); } dlog_rho_clear(t); } void flog_crt(ulong p, ulong a, ulong num) { int k; dlog_crt_t t; dlog_crt_init(t, a, p, p-1, num); for (k = 1; k < num; k++) { if (k % p == 0) continue; dlog_crt(t, k % p); } dlog_crt_clear(t); } void flog_gen(ulong p, ulong a, ulong num) { int k; dlog_precomp_t t; dlog_precomp_n_init(t, a, p, p-1, num); for (k = 1; k < num; k++) { if (k % p == 0) continue; dlog_precomp(t, k % p); } dlog_precomp_clear(t); } int main(int argc, char *argv[]) { int out = LOG; slong iter, k, nv, nref, r, nr; ulong minq, maxq; ulong * rand; int nbits, nl = 5; int l[5] = { 1, 10, 100, 1000 , 5000}; int nf = 4; log_f func[4] = { flog_table, flog_bsgs, flog_crt, flog_gen }; char * n[4] = { "table", "bsgs", "crt", "generic" }; int np = NUMPRIMES; flint_rand_t state; if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } flint_randinit(state); for (nbits = 10; nbits <= 40; nbits += 5) { int i; ulong p[NUMPRIMES], a[NUMPRIMES]; if (nbits >= 25) np /= 2; for (i=0; i < np; i++) { p[i] = n_randprime(state, nbits, 0); a[i] = n_primitive_root_prime(p[i]); } for (i = 0; i < nl; i++) { int f; if (out == LOG) flint_printf("%d * logs mod primes of size %d.....\n", l[i], nbits); for (f = 0; f < nf; f++) { int j; /* skip useless */ if (f == 0 && nbits >= 20) continue; if (f == 1 && nbits >= 30 && l[i] > 10) continue; if (out == LOG) { flint_printf("%-20s... ",n[f]); fflush(stdout); } else if (out == CSV) flint_printf("%-8s, %2d, %4d, %3d, ",n[f],nbits,l[i],np); else if (out == JSON) flint_printf("{ \"name\": \"%s\", \"bits\": %d, \"nlogs\": %d, \"nprimes\": %d, \"time\": ", n[f],nbits,l[i],np); TIMEIT_ONCE_START for (j = 0; j < np; j ++) (func[f])(p[j], a[j], l[i]); TIMEIT_ONCE_STOP if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dlog/profile/p-vec.c000066400000000000000000000070261417376376500161350ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "dlog.h" #include "flint/profiler.h" #define NPRIMES 640 #define LOG 0 #define CSV 1 #define JSON 2 typedef void (*vec_f) (ulong *v, ulong nv, ulong a, ulong va, const nmod_t mod, ulong na, const nmod_t order); void f_empty(ulong *v, ulong nv, ulong a, ulong va, const nmod_t mod, ulong na, const nmod_t order) { return; } int main(int argc, char *argv[]) { int out = LOG; int i, ni = 8; int bits[9] = { 10, 15, 20, 25, 30, 35, 40, 45, 50 }; int j, nj = 6; ulong * v; ulong nv[6] = { 50, 200, 1000, 2000, 10000, 30000 }; int k, np = NPRIMES; nmod_t * p; ulong * a; int l, nf = 5; vec_f func[5] = { f_empty, dlog_vec_loop, dlog_vec_eratos, dlog_vec_sieve, dlog_vec }; char * n[5] = { "empty", "loop", "eratos", "sieve", "default" }; flint_rand_t state; nmod_t order; nmod_init(&order, 100); p = flint_malloc(np * sizeof(nmod_t)); a = flint_malloc(np * sizeof(ulong)); flint_randinit(state); if (argc < 2) out = LOG; else if (!strcmp(argv[1], "json")) out = JSON; else if (!strcmp(argv[1], "csv")) out = CSV; else if (!strcmp(argv[1], "log")) out = LOG; else { printf("usage: %s [log|csv|json]\n", argv[0]); flint_abort(); } for (i = 0; i < ni; i++) { for (k = 0; k < np; k++) { nmod_init(&p[k], n_randprime(state, bits[i], 0)); a[k] = n_primitive_root_prime(p[k].n); } for (j = 0; j < nj; j++) { v = flint_malloc(nv[j] * sizeof(ulong)); if (out == LOG) { flint_printf("log(1..%wu) mod %d primes of size %d bits....\n", nv[j], np, bits[i]); fflush(stdout); } for (l = 0; l < nf; l++) { if (l == 1 && i > 2) continue; if (l == 2 && i > 5) continue; if (out == LOG) { flint_printf("%-20s... ",n[l]); fflush(stdout); } else if (out == CSV) { flint_printf("%-8s, %2d, %4d, %3d, ",n[l],bits[i],nv[j],np); } else if (out == JSON) { flint_printf("{ \"name\": \"%s\", \"bits\": %d, \"nv\": %d, \"nprimes\": %d, \"time\": ", n[l],bits[i],nv[j],np); } TIMEIT_ONCE_START for (k = 0; k < np; k++) { int kk; for (kk=0; kk < nv[j]; kk++) v[kk] = 0; (func[l])(v, nv[j], a[k], 1, p[k], p[k].n - 1, order); } TIMEIT_ONCE_STOP if (out == JSON) flint_printf("}\n"); else flint_printf("\n"); } flint_free(v); } np /= 2; } flint_free(p); flint_free(a); flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dlog/profile/precomp_160905.json000066400000000000000000000176251417376376500201510ustar00rootroot00000000000000{ "name": "table", "bits": 10, "nlogs": 1, "nprimes": 400, "time": 0.003} { "name": "bsgs", "bits": 10, "nlogs": 1, "nprimes": 400, "time": 0.002} { "name": "crt", "bits": 10, "nlogs": 1, "nprimes": 400, "time": 0.001} { "name": "generic", "bits": 10, "nlogs": 1, "nprimes": 400, "time": 0.001} { "name": "table", "bits": 10, "nlogs": 10, "nprimes": 400, "time": 0.004} { "name": "bsgs", "bits": 10, "nlogs": 10, "nprimes": 400, "time": 0.004} { "name": "crt", "bits": 10, "nlogs": 10, "nprimes": 400, "time": 0.003} { "name": "generic", "bits": 10, "nlogs": 10, "nprimes": 400, "time": 0.003} { "name": "table", "bits": 10, "nlogs": 100, "nprimes": 400, "time": 0.004} { "name": "bsgs", "bits": 10, "nlogs": 100, "nprimes": 400, "time": 0.016} { "name": "crt", "bits": 10, "nlogs": 100, "nprimes": 400, "time": 0.019} { "name": "generic", "bits": 10, "nlogs": 100, "nprimes": 400, "time": 0.017} { "name": "table", "bits": 10, "nlogs": 1000, "nprimes": 400, "time": 0.01} { "name": "bsgs", "bits": 10, "nlogs": 1000, "nprimes": 400, "time": 0.054} { "name": "crt", "bits": 10, "nlogs": 1000, "nprimes": 400, "time": 0.143} { "name": "generic", "bits": 10, "nlogs": 1000, "nprimes": 400, "time": 0.143} { "name": "table", "bits": 10, "nlogs": 5000, "nprimes": 400, "time": 0.036} { "name": "bsgs", "bits": 10, "nlogs": 5000, "nprimes": 400, "time": 0.147} { "name": "crt", "bits": 10, "nlogs": 5000, "nprimes": 400, "time": 0.692} { "name": "generic", "bits": 10, "nlogs": 5000, "nprimes": 400, "time": 0.694} { "name": "table", "bits": 15, "nlogs": 1, "nprimes": 400, "time": 0.108} { "name": "bsgs", "bits": 15, "nlogs": 1, "nprimes": 400, "time": 0.01} { "name": "crt", "bits": 15, "nlogs": 1, "nprimes": 400, "time": 0.003} { "name": "generic", "bits": 15, "nlogs": 1, "nprimes": 400, "time": 0.002} { "name": "table", "bits": 15, "nlogs": 10, "nprimes": 400, "time": 0.108} { "name": "bsgs", "bits": 15, "nlogs": 10, "nprimes": 400, "time": 0.025} { "name": "crt", "bits": 15, "nlogs": 10, "nprimes": 400, "time": 0.008} { "name": "generic", "bits": 15, "nlogs": 10, "nprimes": 400, "time": 0.007} { "name": "table", "bits": 15, "nlogs": 100, "nprimes": 400, "time": 0.109} { "name": "bsgs", "bits": 15, "nlogs": 100, "nprimes": 400, "time": 0.092} { "name": "crt", "bits": 15, "nlogs": 100, "nprimes": 400, "time": 0.038} { "name": "generic", "bits": 15, "nlogs": 100, "nprimes": 400, "time": 0.038} { "name": "table", "bits": 15, "nlogs": 1000, "nprimes": 400, "time": 0.114} { "name": "bsgs", "bits": 15, "nlogs": 1000, "nprimes": 400, "time": 0.321} { "name": "crt", "bits": 15, "nlogs": 1000, "nprimes": 400, "time": 0.275} { "name": "generic", "bits": 15, "nlogs": 1000, "nprimes": 400, "time": 0.273} { "name": "table", "bits": 15, "nlogs": 5000, "nprimes": 400, "time": 0.14} { "name": "bsgs", "bits": 15, "nlogs": 5000, "nprimes": 400, "time": 0.784} { "name": "crt", "bits": 15, "nlogs": 5000, "nprimes": 400, "time": 1.228} { "name": "generic", "bits": 15, "nlogs": 5000, "nprimes": 400, "time": 1.232} { "name": "bsgs", "bits": 20, "nlogs": 1, "nprimes": 400, "time": 0.069} { "name": "crt", "bits": 20, "nlogs": 1, "nprimes": 400, "time": 0.011} { "name": "generic", "bits": 20, "nlogs": 1, "nprimes": 400, "time": 0.01} { "name": "bsgs", "bits": 20, "nlogs": 10, "nprimes": 400, "time": 0.176} { "name": "crt", "bits": 20, "nlogs": 10, "nprimes": 400, "time": 0.027} { "name": "generic", "bits": 20, "nlogs": 10, "nprimes": 400, "time": 0.027} { "name": "bsgs", "bits": 20, "nlogs": 100, "nprimes": 400, "time": 0.622} { "name": "crt", "bits": 20, "nlogs": 100, "nprimes": 400, "time": 0.114} { "name": "generic", "bits": 20, "nlogs": 100, "nprimes": 400, "time": 0.114} { "name": "bsgs", "bits": 20, "nlogs": 1000, "nprimes": 400, "time": 2.166} { "name": "crt", "bits": 20, "nlogs": 1000, "nprimes": 400, "time": 0.589} { "name": "generic", "bits": 20, "nlogs": 1000, "nprimes": 400, "time": 0.591} { "name": "bsgs", "bits": 20, "nlogs": 5000, "nprimes": 400, "time": 5.333} { "name": "crt", "bits": 20, "nlogs": 5000, "nprimes": 400, "time": 2.252} { "name": "generic", "bits": 20, "nlogs": 5000, "nprimes": 400, "time": 2.238} { "name": "bsgs", "bits": 25, "nlogs": 1, "nprimes": 200, "time": 0.23} { "name": "crt", "bits": 25, "nlogs": 1, "nprimes": 200, "time": 0.025} { "name": "generic", "bits": 25, "nlogs": 1, "nprimes": 200, "time": 0.026} { "name": "bsgs", "bits": 25, "nlogs": 10, "nprimes": 200, "time": 0.585} { "name": "crt", "bits": 25, "nlogs": 10, "nprimes": 200, "time": 0.065} { "name": "generic", "bits": 25, "nlogs": 10, "nprimes": 200, "time": 0.065} { "name": "bsgs", "bits": 25, "nlogs": 100, "nprimes": 200, "time": 2.099} { "name": "crt", "bits": 25, "nlogs": 100, "nprimes": 200, "time": 0.243} { "name": "generic", "bits": 25, "nlogs": 100, "nprimes": 200, "time": 0.243} { "name": "bsgs", "bits": 25, "nlogs": 1000, "nprimes": 200, "time": 7.338} { "name": "crt", "bits": 25, "nlogs": 1000, "nprimes": 200, "time": 0.967} { "name": "generic", "bits": 25, "nlogs": 1000, "nprimes": 200, "time": 0.967} { "name": "bsgs", "bits": 25, "nlogs": 5000, "nprimes": 200, "time": 19.051} { "name": "crt", "bits": 25, "nlogs": 5000, "nprimes": 200, "time": 2.893} { "name": "generic", "bits": 25, "nlogs": 5000, "nprimes": 200, "time": 2.882} { "name": "bsgs", "bits": 30, "nlogs": 1, "nprimes": 100, "time": 0.742} { "name": "crt", "bits": 30, "nlogs": 1, "nprimes": 100, "time": 0.07} { "name": "generic", "bits": 30, "nlogs": 1, "nprimes": 100, "time": 0.071} { "name": "bsgs", "bits": 30, "nlogs": 10, "nprimes": 100, "time": 1.914} { "name": "crt", "bits": 30, "nlogs": 10, "nprimes": 100, "time": 0.178} { "name": "generic", "bits": 30, "nlogs": 10, "nprimes": 100, "time": 0.178} { "name": "crt", "bits": 30, "nlogs": 100, "nprimes": 100, "time": 0.652} { "name": "generic", "bits": 30, "nlogs": 100, "nprimes": 100, "time": 0.655} { "name": "crt", "bits": 30, "nlogs": 1000, "nprimes": 100, "time": 2.495} { "name": "generic", "bits": 30, "nlogs": 1000, "nprimes": 100, "time": 2.493} { "name": "crt", "bits": 30, "nlogs": 5000, "nprimes": 100, "time": 6.465} { "name": "generic", "bits": 30, "nlogs": 5000, "nprimes": 100, "time": 6.432} { "name": "bsgs", "bits": 35, "nlogs": 1, "nprimes": 50, "time": 2.357} { "name": "crt", "bits": 35, "nlogs": 1, "nprimes": 50, "time": 0.118} { "name": "generic", "bits": 35, "nlogs": 1, "nprimes": 50, "time": 0.118} { "name": "bsgs", "bits": 35, "nlogs": 10, "nprimes": 50, "time": 6.562} { "name": "crt", "bits": 35, "nlogs": 10, "nprimes": 50, "time": 0.307} { "name": "generic", "bits": 35, "nlogs": 10, "nprimes": 50, "time": 0.308} { "name": "crt", "bits": 35, "nlogs": 100, "nprimes": 50, "time": 1.171} { "name": "generic", "bits": 35, "nlogs": 100, "nprimes": 50, "time": 1.175} { "name": "crt", "bits": 35, "nlogs": 1000, "nprimes": 50, "time": 4.329} { "name": "generic", "bits": 35, "nlogs": 1000, "nprimes": 50, "time": 4.297} { "name": "crt", "bits": 35, "nlogs": 5000, "nprimes": 50, "time": 10.904} { "name": "generic", "bits": 35, "nlogs": 5000, "nprimes": 50, "time": 10.916} { "name": "bsgs", "bits": 40, "nlogs": 1, "nprimes": 25, "time": 7.623} { "name": "crt", "bits": 40, "nlogs": 1, "nprimes": 25, "time": 0.472} { "name": "generic", "bits": 40, "nlogs": 1, "nprimes": 25, "time": 0.463} { "name": "bsgs", "bits": 40, "nlogs": 10, "nprimes": 25, "time": 21.817} { "name": "crt", "bits": 40, "nlogs": 10, "nprimes": 25, "time": 1.395} { "name": "generic", "bits": 40, "nlogs": 10, "nprimes": 25, "time": 1.389} { "name": "crt", "bits": 40, "nlogs": 100, "nprimes": 25, "time": 5.191} { "name": "generic", "bits": 40, "nlogs": 100, "nprimes": 25, "time": 5.158} { "name": "crt", "bits": 40, "nlogs": 1000, "nprimes": 25, "time": 19.911} { "name": "generic", "bits": 40, "nlogs": 1000, "nprimes": 25, "time": 19.722} { "name": "crt", "bits": 40, "nlogs": 5000, "nprimes": 25, "time": 51.207} { "name": "generic", "bits": 40, "nlogs": 5000, "nprimes": 25, "time": 51.084} arb-2.22.1/dlog/profile/vec160905.json000066400000000000000000000344331417376376500171160ustar00rootroot00000000000000{ "name": "empty", "bits": 10, "nv": 50, "nprimes": 640, "time": 0} { "name": "loop", "bits": 10, "nv": 50, "nprimes": 640, "time": 0.006} { "name": "eratos", "bits": 10, "nv": 50, "nprimes": 640, "time": 0.007} { "name": "sieve", "bits": 10, "nv": 50, "nprimes": 640, "time": 0.009} { "name": "default", "bits": 10, "nv": 50, "nprimes": 640, "time": 0.01} { "name": "empty", "bits": 10, "nv": 200, "nprimes": 640, "time": 0} { "name": "loop", "bits": 10, "nv": 200, "nprimes": 640, "time": 0.007} { "name": "eratos", "bits": 10, "nv": 200, "nprimes": 640, "time": 0.016} { "name": "sieve", "bits": 10, "nv": 200, "nprimes": 640, "time": 0.013} { "name": "default", "bits": 10, "nv": 200, "nprimes": 640, "time": 0.013} { "name": "empty", "bits": 10, "nv": 1000, "nprimes": 640, "time": 0} { "name": "loop", "bits": 10, "nv": 1000, "nprimes": 640, "time": 0.007} { "name": "eratos", "bits": 10, "nv": 1000, "nprimes": 640, "time": 0.04} { "name": "sieve", "bits": 10, "nv": 1000, "nprimes": 640, "time": 0.024} { "name": "default", "bits": 10, "nv": 1000, "nprimes": 640, "time": 0.023} { "name": "empty", "bits": 10, "nv": 2000, "nprimes": 640, "time": 0} { "name": "loop", "bits": 10, "nv": 2000, "nprimes": 640, "time": 0.006} { "name": "eratos", "bits": 10, "nv": 2000, "nprimes": 640, "time": 0.04} { "name": "sieve", "bits": 10, "nv": 2000, "nprimes": 640, "time": 0.026} { "name": "default", "bits": 10, "nv": 2000, "nprimes": 640, "time": 0.025} { "name": "empty", "bits": 10, "nv": 10000, "nprimes": 640, "time": 0.002} { "name": "loop", "bits": 10, "nv": 10000, "nprimes": 640, "time": 0.011} { "name": "eratos", "bits": 10, "nv": 10000, "nprimes": 640, "time": 0.045} { "name": "sieve", "bits": 10, "nv": 10000, "nprimes": 640, "time": 0.05} { "name": "default", "bits": 10, "nv": 10000, "nprimes": 640, "time": 0.011} { "name": "empty", "bits": 10, "nv": 30000, "nprimes": 640, "time": 0.005} { "name": "loop", "bits": 10, "nv": 30000, "nprimes": 640, "time": 0.022} { "name": "eratos", "bits": 10, "nv": 30000, "nprimes": 640, "time": 0.055} { "name": "sieve", "bits": 10, "nv": 30000, "nprimes": 640, "time": 0.109} { "name": "default", "bits": 10, "nv": 30000, "nprimes": 640, "time": 0.022} { "name": "empty", "bits": 15, "nv": 50, "nprimes": 320, "time": 0} { "name": "loop", "bits": 15, "nv": 50, "nprimes": 320, "time": 0.09} { "name": "eratos", "bits": 15, "nv": 50, "nprimes": 320, "time": 0.008} { "name": "sieve", "bits": 15, "nv": 50, "nprimes": 320, "time": 0.014} { "name": "default", "bits": 15, "nv": 50, "nprimes": 320, "time": 0.013} { "name": "empty", "bits": 15, "nv": 200, "nprimes": 320, "time": 0} { "name": "loop", "bits": 15, "nv": 200, "nprimes": 320, "time": 0.09} { "name": "eratos", "bits": 15, "nv": 200, "nprimes": 320, "time": 0.018} { "name": "sieve", "bits": 15, "nv": 200, "nprimes": 320, "time": 0.02} { "name": "default", "bits": 15, "nv": 200, "nprimes": 320, "time": 0.02} { "name": "empty", "bits": 15, "nv": 1000, "nprimes": 320, "time": 0} { "name": "loop", "bits": 15, "nv": 1000, "nprimes": 320, "time": 0.092} { "name": "eratos", "bits": 15, "nv": 1000, "nprimes": 320, "time": 0.05} { "name": "sieve", "bits": 15, "nv": 1000, "nprimes": 320, "time": 0.029} { "name": "default", "bits": 15, "nv": 1000, "nprimes": 320, "time": 0.03} { "name": "empty", "bits": 15, "nv": 2000, "nprimes": 320, "time": 0} { "name": "loop", "bits": 15, "nv": 2000, "nprimes": 320, "time": 0.097} { "name": "eratos", "bits": 15, "nv": 2000, "nprimes": 320, "time": 0.085} { "name": "sieve", "bits": 15, "nv": 2000, "nprimes": 320, "time": 0.037} { "name": "default", "bits": 15, "nv": 2000, "nprimes": 320, "time": 0.039} { "name": "empty", "bits": 15, "nv": 10000, "nprimes": 320, "time": 0.001} { "name": "loop", "bits": 15, "nv": 10000, "nprimes": 320, "time": 0.126} { "name": "eratos", "bits": 15, "nv": 10000, "nprimes": 320, "time": 0.301} { "name": "sieve", "bits": 15, "nv": 10000, "nprimes": 320, "time": 0.098} { "name": "default", "bits": 15, "nv": 10000, "nprimes": 320, "time": 0.096} { "name": "empty", "bits": 15, "nv": 30000, "nprimes": 320, "time": 0.003} { "name": "loop", "bits": 15, "nv": 30000, "nprimes": 320, "time": 0.094} { "name": "eratos", "bits": 15, "nv": 30000, "nprimes": 320, "time": 0.641} { "name": "sieve", "bits": 15, "nv": 30000, "nprimes": 320, "time": 0.193} { "name": "default", "bits": 15, "nv": 30000, "nprimes": 320, "time": 0.192} { "name": "empty", "bits": 20, "nv": 50, "nprimes": 160, "time": 0} { "name": "loop", "bits": 20, "nv": 50, "nprimes": 160, "time": 1.445} { "name": "eratos", "bits": 20, "nv": 50, "nprimes": 160, "time": 0.015} { "name": "sieve", "bits": 20, "nv": 50, "nprimes": 160, "time": 0.026} { "name": "default", "bits": 20, "nv": 50, "nprimes": 160, "time": 0.027} { "name": "empty", "bits": 20, "nv": 200, "nprimes": 160, "time": 0} { "name": "loop", "bits": 20, "nv": 200, "nprimes": 160, "time": 1.445} { "name": "eratos", "bits": 20, "nv": 200, "nprimes": 160, "time": 0.03} { "name": "sieve", "bits": 20, "nv": 200, "nprimes": 160, "time": 0.034} { "name": "default", "bits": 20, "nv": 200, "nprimes": 160, "time": 0.032} { "name": "empty", "bits": 20, "nv": 1000, "nprimes": 160, "time": 0} { "name": "loop", "bits": 20, "nv": 1000, "nprimes": 160, "time": 1.45} { "name": "eratos", "bits": 20, "nv": 1000, "nprimes": 160, "time": 0.07} { "name": "sieve", "bits": 20, "nv": 1000, "nprimes": 160, "time": 0.041} { "name": "default", "bits": 20, "nv": 1000, "nprimes": 160, "time": 0.041} { "name": "empty", "bits": 20, "nv": 2000, "nprimes": 160, "time": 0} { "name": "loop", "bits": 20, "nv": 2000, "nprimes": 160, "time": 1.454} { "name": "eratos", "bits": 20, "nv": 2000, "nprimes": 160, "time": 0.107} { "name": "sieve", "bits": 20, "nv": 2000, "nprimes": 160, "time": 0.048} { "name": "default", "bits": 20, "nv": 2000, "nprimes": 160, "time": 0.047} { "name": "empty", "bits": 20, "nv": 10000, "nprimes": 160, "time": 0.001} { "name": "loop", "bits": 20, "nv": 10000, "nprimes": 160, "time": 1.465} { "name": "eratos", "bits": 20, "nv": 10000, "nprimes": 160, "time": 0.308} { "name": "sieve", "bits": 20, "nv": 10000, "nprimes": 160, "time": 0.082} { "name": "default", "bits": 20, "nv": 10000, "nprimes": 160, "time": 0.081} { "name": "empty", "bits": 20, "nv": 30000, "nprimes": 160, "time": 0.001} { "name": "loop", "bits": 20, "nv": 30000, "nprimes": 160, "time": 1.505} { "name": "eratos", "bits": 20, "nv": 30000, "nprimes": 160, "time": 0.685} { "name": "sieve", "bits": 20, "nv": 30000, "nprimes": 160, "time": 0.152} { "name": "default", "bits": 20, "nv": 30000, "nprimes": 160, "time": 0.152} { "name": "empty", "bits": 25, "nv": 50, "nprimes": 80, "time": 0} { "name": "eratos", "bits": 25, "nv": 50, "nprimes": 80, "time": 0.029} { "name": "sieve", "bits": 25, "nv": 50, "nprimes": 80, "time": 0.052} { "name": "default", "bits": 25, "nv": 50, "nprimes": 80, "time": 0.051} { "name": "empty", "bits": 25, "nv": 200, "nprimes": 80, "time": 0} { "name": "eratos", "bits": 25, "nv": 200, "nprimes": 80, "time": 0.056} { "name": "sieve", "bits": 25, "nv": 200, "nprimes": 80, "time": 0.06} { "name": "default", "bits": 25, "nv": 200, "nprimes": 80, "time": 0.06} { "name": "empty", "bits": 25, "nv": 1000, "nprimes": 80, "time": 0} { "name": "eratos", "bits": 25, "nv": 1000, "nprimes": 80, "time": 0.117} { "name": "sieve", "bits": 25, "nv": 1000, "nprimes": 80, "time": 0.072} { "name": "default", "bits": 25, "nv": 1000, "nprimes": 80, "time": 0.073} { "name": "empty", "bits": 25, "nv": 2000, "nprimes": 80, "time": 0} { "name": "eratos", "bits": 25, "nv": 2000, "nprimes": 80, "time": 0.168} { "name": "sieve", "bits": 25, "nv": 2000, "nprimes": 80, "time": 0.082} { "name": "default", "bits": 25, "nv": 2000, "nprimes": 80, "time": 0.08} { "name": "empty", "bits": 25, "nv": 10000, "nprimes": 80, "time": 0.001} { "name": "eratos", "bits": 25, "nv": 10000, "nprimes": 80, "time": 0.409} { "name": "sieve", "bits": 25, "nv": 10000, "nprimes": 80, "time": 0.092} { "name": "default", "bits": 25, "nv": 10000, "nprimes": 80, "time": 0.093} { "name": "empty", "bits": 25, "nv": 30000, "nprimes": 80, "time": 0.001} { "name": "eratos", "bits": 25, "nv": 30000, "nprimes": 80, "time": 0.8} { "name": "sieve", "bits": 25, "nv": 30000, "nprimes": 80, "time": 0.132} { "name": "default", "bits": 25, "nv": 30000, "nprimes": 80, "time": 0.132} { "name": "empty", "bits": 30, "nv": 50, "nprimes": 40, "time": 0} { "name": "eratos", "bits": 30, "nv": 50, "nprimes": 40, "time": 0.073} { "name": "sieve", "bits": 30, "nv": 50, "nprimes": 40, "time": 0.121} { "name": "default", "bits": 30, "nv": 50, "nprimes": 40, "time": 0.122} { "name": "empty", "bits": 30, "nv": 200, "nprimes": 40, "time": 0} { "name": "eratos", "bits": 30, "nv": 200, "nprimes": 40, "time": 0.138} { "name": "sieve", "bits": 30, "nv": 200, "nprimes": 40, "time": 0.136} { "name": "default", "bits": 30, "nv": 200, "nprimes": 40, "time": 0.136} { "name": "empty", "bits": 30, "nv": 1000, "nprimes": 40, "time": 0} { "name": "eratos", "bits": 30, "nv": 1000, "nprimes": 40, "time": 0.282} { "name": "sieve", "bits": 30, "nv": 1000, "nprimes": 40, "time": 0.151} { "name": "default", "bits": 30, "nv": 1000, "nprimes": 40, "time": 0.15} { "name": "empty", "bits": 30, "nv": 2000, "nprimes": 40, "time": 0} { "name": "eratos", "bits": 30, "nv": 2000, "nprimes": 40, "time": 0.409} { "name": "sieve", "bits": 30, "nv": 2000, "nprimes": 40, "time": 0.166} { "name": "default", "bits": 30, "nv": 2000, "nprimes": 40, "time": 0.162} { "name": "empty", "bits": 30, "nv": 10000, "nprimes": 40, "time": 0} { "name": "eratos", "bits": 30, "nv": 10000, "nprimes": 40, "time": 0.924} { "name": "sieve", "bits": 30, "nv": 10000, "nprimes": 40, "time": 0.226} { "name": "default", "bits": 30, "nv": 10000, "nprimes": 40, "time": 0.225} { "name": "empty", "bits": 30, "nv": 30000, "nprimes": 40, "time": 0} { "name": "eratos", "bits": 30, "nv": 30000, "nprimes": 40, "time": 1.665} { "name": "sieve", "bits": 30, "nv": 30000, "nprimes": 40, "time": 0.207} { "name": "default", "bits": 30, "nv": 30000, "nprimes": 40, "time": 0.207} { "name": "empty", "bits": 35, "nv": 50, "nprimes": 20, "time": 0} { "name": "eratos", "bits": 35, "nv": 50, "nprimes": 20, "time": 0.22} { "name": "sieve", "bits": 35, "nv": 50, "nprimes": 20, "time": 0.355} { "name": "default", "bits": 35, "nv": 50, "nprimes": 20, "time": 0.352} { "name": "empty", "bits": 35, "nv": 200, "nprimes": 20, "time": 0} { "name": "eratos", "bits": 35, "nv": 200, "nprimes": 20, "time": 0.432} { "name": "sieve", "bits": 35, "nv": 200, "nprimes": 20, "time": 0.403} { "name": "default", "bits": 35, "nv": 200, "nprimes": 20, "time": 0.407} { "name": "empty", "bits": 35, "nv": 1000, "nprimes": 20, "time": 0} { "name": "eratos", "bits": 35, "nv": 1000, "nprimes": 20, "time": 0.864} { "name": "sieve", "bits": 35, "nv": 1000, "nprimes": 20, "time": 0.426} { "name": "default", "bits": 35, "nv": 1000, "nprimes": 20, "time": 0.428} { "name": "empty", "bits": 35, "nv": 2000, "nprimes": 20, "time": 0} { "name": "eratos", "bits": 35, "nv": 2000, "nprimes": 20, "time": 1.23} { "name": "sieve", "bits": 35, "nv": 2000, "nprimes": 20, "time": 0.442} { "name": "default", "bits": 35, "nv": 2000, "nprimes": 20, "time": 0.439} { "name": "empty", "bits": 35, "nv": 10000, "nprimes": 20, "time": 0} { "name": "eratos", "bits": 35, "nv": 10000, "nprimes": 20, "time": 2.717} { "name": "sieve", "bits": 35, "nv": 10000, "nprimes": 20, "time": 0.528} { "name": "default", "bits": 35, "nv": 10000, "nprimes": 20, "time": 0.53} { "name": "empty", "bits": 35, "nv": 30000, "nprimes": 20, "time": 0} { "name": "eratos", "bits": 35, "nv": 30000, "nprimes": 20, "time": 4.735} { "name": "sieve", "bits": 35, "nv": 30000, "nprimes": 20, "time": 0.739} { "name": "default", "bits": 35, "nv": 30000, "nprimes": 20, "time": 0.74} { "name": "empty", "bits": 40, "nv": 50, "nprimes": 10, "time": 0} { "name": "sieve", "bits": 40, "nv": 50, "nprimes": 10, "time": 1.31} { "name": "default", "bits": 40, "nv": 50, "nprimes": 10, "time": 1.306} { "name": "empty", "bits": 40, "nv": 200, "nprimes": 10, "time": 0} { "name": "sieve", "bits": 40, "nv": 200, "nprimes": 10, "time": 1.537} { "name": "default", "bits": 40, "nv": 200, "nprimes": 10, "time": 1.537} { "name": "empty", "bits": 40, "nv": 1000, "nprimes": 10, "time": 0} { "name": "sieve", "bits": 40, "nv": 1000, "nprimes": 10, "time": 1.58} { "name": "default", "bits": 40, "nv": 1000, "nprimes": 10, "time": 1.574} { "name": "empty", "bits": 40, "nv": 2000, "nprimes": 10, "time": 0} { "name": "sieve", "bits": 40, "nv": 2000, "nprimes": 10, "time": 1.597} { "name": "default", "bits": 40, "nv": 2000, "nprimes": 10, "time": 1.596} { "name": "empty", "bits": 40, "nv": 10000, "nprimes": 10, "time": 0} { "name": "sieve", "bits": 40, "nv": 10000, "nprimes": 10, "time": 1.753} { "name": "default", "bits": 40, "nv": 10000, "nprimes": 10, "time": 1.748} { "name": "empty", "bits": 40, "nv": 30000, "nprimes": 10, "time": 0} { "name": "sieve", "bits": 40, "nv": 30000, "nprimes": 10, "time": 2.396} { "name": "default", "bits": 40, "nv": 30000, "nprimes": 10, "time": 2.397} { "name": "empty", "bits": 45, "nv": 50, "nprimes": 5, "time": 0} { "name": "sieve", "bits": 45, "nv": 50, "nprimes": 5, "time": 1.623} { "name": "default", "bits": 45, "nv": 50, "nprimes": 5, "time": 1.617} { "name": "empty", "bits": 45, "nv": 200, "nprimes": 5, "time": 0} { "name": "sieve", "bits": 45, "nv": 200, "nprimes": 5, "time": 2.039} { "name": "default", "bits": 45, "nv": 200, "nprimes": 5, "time": 2.072} { "name": "empty", "bits": 45, "nv": 1000, "nprimes": 5, "time": 0} { "name": "sieve", "bits": 45, "nv": 1000, "nprimes": 5, "time": 2.194} { "name": "default", "bits": 45, "nv": 1000, "nprimes": 5, "time": 2.142} { "name": "empty", "bits": 45, "nv": 2000, "nprimes": 5, "time": 0} { "name": "sieve", "bits": 45, "nv": 2000, "nprimes": 5, "time": 2.147} { "name": "default", "bits": 45, "nv": 2000, "nprimes": 5, "time": 2.182} { "name": "empty", "bits": 45, "nv": 10000, "nprimes": 5, "time": 0} { "name": "sieve", "bits": 45, "nv": 10000, "nprimes": 5, "time": 2.22} { "name": "default", "bits": 45, "nv": 10000, "nprimes": 5, "time": 2.222} { "name": "empty", "bits": 45, "nv": 30000, "nprimes": 5, "time": 0} { "name": "sieve", "bits": 45, "nv": 30000, "nprimes": 5, "time": 2.448} { "name": "default", "bits": 45, "nv": 30000, "nprimes": 5, "time": 2.445} arb-2.22.1/dlog/rho.c000066400000000000000000000055541417376376500142570ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include static ulong dlog_single(ulong b, ulong a, const nmod_t mod, ulong n) { if (n < 50) { int k; ulong ak = 1; for (k=0; k < n; k++) { if (ak == b) return k; ak = nmod_mul(ak, a, mod); } flint_printf("FAIL[dlog single]: log(%wu,%wu) mod %wu not found (size %wu)\n", b, a, mod.n, n); flint_abort(); return 0; /* dummy return because flint_abort() is not declared noreturn */ } else { dlog_rho_t t; dlog_rho_init(t, a, mod.n, n); return dlog_rho(t, b); } } /* solve log knowing equation e = f * log(b) [n] */ static ulong dlog_quotient(const dlog_rho_t t, ulong e, ulong f, ulong g, ulong b) { ulong r, b_ar, an; nmod_t n = t->n; if (g == n.n) { flint_printf("FAIL[dlog quotient]: trivial relation e = %wu, f = %wu mod %wu\n", e, f, n.n); flint_abort(); } nmod_init(&n, n.n / g); e = e / g; f = f / g; r = nmod_div(e, f, n); an = nmod_pow_ui(t->a, n.n, t->mod); b_ar = nmod_div(b, nmod_pow_ui(t->a, r, t->mod), t->mod); return r + n.n * dlog_single(b_ar, an, t->mod, g); } #define RWALK 20 ulong dlog_rho(const dlog_rho_t t, ulong b) { int j, k, l; ulong m[RWALK], n[RWALK], ab[RWALK]; ulong x[2], e[2], f[2], g; flint_rand_t state; flint_randinit(state); do { for (k = 0; k < RWALK; k++) { m[k] = 1 + n_randint(state, t->n.n - 1); n[k] = 1 + n_randint(state, t->n.n - 1); ab[k] = nmod_mul(nmod_pow_ui(t->a, m[k], t->mod), nmod_pow_ui(b, n[k], t->mod), t->mod); } /* x[l] = a^e[l] * b^f[l] */ x[0] = x[1] = 1; e[0] = e[1] = 0; f[0] = f[1] = 0; do { for(j = 0; j < 3; j++) { l = (j > 0); k = floor( (double) RWALK * x[l] / t->mod.n ); x[l] = nmod_mul(x[l], ab[k], t->mod); e[l] = nmod_add(e[l], m[k], t->n); f[l] = nmod_add(f[l], n[k], t->n); } } while (x[0] != x[1]); } while (e[0] == e[1] && f[0] == f[1]); flint_randclear(state); /* e = f * log(b) */ e[0] = nmod_sub(e[0], e[1], t->n); f[0] = nmod_sub(f[1], f[0], t->n); if (!t->nisprime && (g = n_gcd(f[0], t->n.n)) > 1) return dlog_quotient(t, e[0], f[0], g, b); else return nmod_div(e[0], f[0], t->n); } arb-2.22.1/dlog/rho_init.c000066400000000000000000000010611417376376500152670ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_rho_init(dlog_rho_t t, ulong a, ulong mod, ulong n) { t->a = a; nmod_init(&t->n, n); nmod_init(&t->mod, mod); t->nisprime = n_is_prime(n); } arb-2.22.1/dlog/table.c000066400000000000000000000007371417376376500145540ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" ulong dlog_table(const dlog_table_t t, ulong b) { return t->table[b % t->mod]; } arb-2.22.1/dlog/table_init.c000066400000000000000000000014151417376376500155710ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* assume mod is small so no overflow */ ulong dlog_table_init(dlog_table_t t, ulong a, ulong mod) { int k; ulong ak; t->mod = mod; t->table = flint_malloc(mod * sizeof(ulong)); ak = 1; k = 0; /* warning: do not check a is invertible modulo mod */ do { t->table[ak] = k++; ak = (ak * a) % mod; } while (ak != 1); return 1; } arb-2.22.1/dlog/test/000077500000000000000000000000001417376376500142715ustar00rootroot00000000000000arb-2.22.1/dlog/test/t-dlog.c000066400000000000000000000043111417376376500156220ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" int main() { slong iter; flint_rand_t state; flint_printf("dlog...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000; iter++) { dlog_table_t table; dlog_bsgs_t bsgs; dlog_crt_t crt; dlog_precomp_t pre1, pre100; ulong p, a, k; nmod_t modp; if (iter < 10) p = n_nth_prime(iter + 2); else p = n_randprime(state, 15, 0); nmod_init(&modp, p); a = n_primitive_root_prime(p); dlog_table_init(table, a, p); dlog_bsgs_init(bsgs, a, p, p-1, dlog_bsgs_size(p, 1)); dlog_crt_init(crt, a, p, p-1, 10); dlog_precomp_n_init(pre1, a, p, p-1, 1); dlog_precomp_n_init(pre100, a, p, p-1, 100); for (k = 1; k < 100 && k < p; k++) { ulong l0, l1, l2, l3, l4, l5; l1 = dlog_table(table, k); l2 = dlog_bsgs(bsgs, k); l3 = dlog_crt(crt, k); l4 = dlog_precomp(pre1, k); l5 = dlog_precomp(pre100, k); if (iter < 50 && k <= 7) l0 = dlog_once(k, a, modp, p-1); else l0 = l1; if (l0 != l1 || l1 != l2 || l1 != l3 || l1 != l4 || l1 != l5) { flint_printf("\n\nFAIL: log(%wu,%wu) mod %wu\n\n",k,a,p); flint_printf("once: %wu\ntable: %wu\nbsgs: %wu\ncrt: %wu\nprecomp1: %wu\nprecomp100: %wu\n\n", l0, l1, l2, l3, l4, l5); flint_abort(); } } dlog_table_clear(table); dlog_bsgs_clear(bsgs); dlog_crt_clear(crt); dlog_precomp_clear(pre1); dlog_precomp_clear(pre100); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dlog/test/t-modpe.c000066400000000000000000000040041417376376500160000ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include #if FLINT_BITS == 64 #define LIM UWORD(1000000000000) #else #define LIM UWORD(1000000000) #endif int main() { slong iter; flint_rand_t state; flint_printf("modpe...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000; iter++) { ulong p, e, pe, a; if (iter == 0) { p = 2; pe = 8; a = 5; e = 3; } else { p = pe = n_randprime(state, 10, 0); a = (p == 40487) ? 10 : n_primitive_root_prime(p); e = 1; } for (; pe < LIM; pe *= p, e++) { ulong k, phi; nmod_t mod; dlog_modpe_t modpe; nmod_init(&mod, pe); phi = (p == 2) ? pe / 4 : pe - pe / p; dlog_modpe_init(modpe, a, p, e, pe, 10); for (k = 0; k < 100 && k < p; k++) { ulong l, b, x; l = n_randint(state, phi); b = nmod_pow_ui(a, l, mod); if ((x = dlog_modpe(modpe, b)) != l) { flint_printf("FAIL modpe: %wu^%wu = %wu [%wu^%wu]\n\n", a, l, b, p, e); flint_printf("modpe returned %wu\n\n", x); flint_abort(); } } dlog_modpe_clear(modpe); /* multiplication can overflow on 32-bit */ if ((double) pe * p > LIM) break; } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dlog/test/t-vec.c000066400000000000000000000055321417376376500154600ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" typedef void (*vec_f) (ulong *v, ulong nv, ulong a, ulong va, const nmod_t mod, ulong na, const nmod_t order); void dlog_vec_trivial(ulong *v, ulong nv, ulong a, ulong va, const nmod_t mod, ulong na, const nmod_t order) { ulong k; dlog_precomp_t pre; dlog_precomp_n_init(pre, a, mod.n, na, 50); for (k = 1; k < nv; k++) if (n_gcd(k, mod.n) > 1) v[k] = DLOG_NOT_FOUND; else v[k] = dlog_precomp(pre, k % mod.n); dlog_precomp_clear(pre); } static ulong dlog_vec_diff(ulong * v, ulong * ref, ulong nv) { ulong k; for (k = 1; k < nv; k++) if (ref[k] != v[k]) return k; return 0; } int main() { slong bits, nv, iter; flint_rand_t state; int f, nf = 4; vec_f func[4] = { dlog_vec_trivial, dlog_vec_loop, dlog_vec_eratos, dlog_vec_sieve }; char * n[4] = { "trivial", "loop", "eratos", "sieve" }; flint_printf("vec...."); fflush(stdout); flint_randinit(state); for (bits = 10; bits <= FLINT_MIN(35, FLINT_BITS); bits += 5) { for (nv = 10; nv <= 10000; nv *= 10) { ulong *v, *ref; int iref; iref = (bits == 10 && nv <= 1000) ? 0 : 2; ref = flint_malloc(nv * sizeof(ulong)); v = flint_malloc(nv * sizeof(ulong)); for (iter = 0; iter < 10; iter++) { int k; ulong p, a, va, na; nmod_t mod, order; p = n_randprime(state, bits, 0); a = n_primitive_root_prime(p); nmod_init(&mod, p); va = 1; na = p - 1; nmod_init(&order, na); dlog_vec_fill(ref, nv, 0); (func[iref])(ref, nv, a, va, mod, na, order); /* compare */ for (f = iref + 1; f < nf; f++) { dlog_vec_fill(v, nv, 0); (func[f])(v, nv, a, va, mod, na, order); if ((k = dlog_vec_diff(v, ref, nv))) { flint_printf("FAIL: log(%wu,%wu) mod %wu: %s->%w != %s->%w\n", k, a, p, n[iref], ref[k], n[f], v[k]); flint_abort(); } } } flint_free(ref); flint_free(v); } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/dlog/vec.c000066400000000000000000000012441417376376500142340ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec(ulong *v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { if (va == 0) return; if (na * DLOG_LOOP_MAX_FACTOR < nv) dlog_vec_loop(v, nv, a, va, mod, na, order); else dlog_vec_sieve(v, nv, a, va, mod, na, order); } arb-2.22.1/dlog/vec_add.c000066400000000000000000000012601417376376500150420ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec_add(ulong *v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { if (va == 0) return; if (na * DLOG_LOOP_MAX_FACTOR < nv) dlog_vec_loop_add(v, nv, a, va, mod, na, order); else dlog_vec_sieve_add(v, nv, a, va, mod, na, order); } arb-2.22.1/dlog/vec_add_precomp.c000066400000000000000000000013311417376376500165660ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec_add_precomp(ulong *v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { if (va == 0) return; if (na * DLOG_LOOP_MAX_FACTOR < nv) dlog_vec_loop_add(v, nv, a, va, mod, na, order); else dlog_vec_sieve_add_precomp(v, nv, pre, a, va, mod, na, order); } arb-2.22.1/dlog/vec_eratos.c000066400000000000000000000011521417376376500156070ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec_eratos(ulong *v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { dlog_vec_fill(v, nv, 0); dlog_vec_set_not_found(v, nv, mod); dlog_vec_eratos_add(v, nv, a, va, mod, na, order); } arb-2.22.1/dlog/vec_eratos_add.c000066400000000000000000000025671417376376500164320ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* assume non invertible and 1 mod n already set */ void dlog_vec_eratos_add(ulong *v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong p, k, n; dlog_precomp_t pre; n_primes_t iter; /* discrete log on primes */ n = (nv < mod.n) ? nv : mod.n; dlog_precomp_n_init(pre, a, mod.n, na, n_prime_pi(n)); n_primes_init(iter); while ((p = n_primes_next(iter)) < n) { ulong wp, pe; if (v[p] == DLOG_NOT_FOUND) continue; /* won't be attained another time */ wp = nmod_mul(dlog_precomp(pre, p), va, order); /* FIXME: could be faster sieving m*pe? but cannot * use v[p*m]=v[p]*v[m]... */ for (pe = p; pe < n; pe *= p) for (k = pe; k < n; k += pe) if (v[k] != DLOG_NOT_FOUND) v[k] = nmod_add(v[k], wp, order); } n_primes_clear(iter); for (k = mod.n + 1; k < nv; k++) v[k] = v[k - mod.n]; dlog_precomp_clear(pre); } arb-2.22.1/dlog/vec_fill.c000066400000000000000000000007721417376376500152470ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec_fill(ulong *v, ulong nv, ulong x) { ulong k; for (k = 0; k < nv; k++) v[k] = x; } arb-2.22.1/dlog/vec_loop.c000066400000000000000000000015061417376376500152660ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* vector of log(k,a)*loga % order in Z/modZ */ void dlog_vec_loop(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong x, vx; dlog_vec_fill(v, nv, DLOG_NOT_FOUND); x = 1; vx = 0; do { if (x < nv) v[x] = vx; x = nmod_mul(x, a, mod); vx = nmod_add(vx, va, order); } while (x != 1); for (x = mod.n + 1; x < nv; x++) v[x] = v[x - mod.n]; } arb-2.22.1/dlog/vec_loop_add.c000066400000000000000000000014451417376376500161000ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" /* vector of log(k,a)*loga % order in Z/modZ */ void dlog_vec_loop_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong x, xp, vx; vx = 0; for (x = a; x != 1; x = nmod_mul(x, a, mod)) { vx = nmod_add(vx, va, order); for(xp = x; xp < nv; xp+=mod.n) if (v[xp] != DLOG_NONE) v[xp] = nmod_add(v[xp], vx, order); } } arb-2.22.1/dlog/vec_pindex_factorgcd.c000066400000000000000000000060521417376376500176210ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include #define vbs 1 #define FACTOR_RATIO 4 static int factor_until(ulong * n, ulong nlim, const ulong * p, ulong pmax, ulong * fp, int * fe) { int i, j; for (i = 0, j = 0; *n >= nlim && p[j] < pmax; j++) { int e = n_remove(n, p[j]); if (e) { fp[i] = p[j]; fe[i] = e; i++; } } return i; } ulong dlog_vec_pindex_factorgcd(ulong * v, ulong nv, ulong p, nmod_t mod, ulong a, ulong na, ulong loga, ulong logm1, nmod_t order, int maxtry) { int nm = 0, ng = 0; ulong pm, logm, pmax; ulong u[2], r[2], t; ulong up[15], rp[15]; int ue[15], re[15]; const ulong * prime; prime = n_primes_arr_readonly(p); pmax = p / FACTOR_RATIO; pm = p; logm = 0; while (nm++ < maxtry) { int i, j, iu, ir; ulong logr; pm = nmod_mul(pm, a, mod); logm = nmod_add(logm, loga, order); /* if (2 * pm > mod.n) { pm = nmod_neg(pm, mod); logm = nmod_add(logm, logm1, order); } */ /* half gcd u * pm + v * mod = r, ignore v */ u[0] = 0; r[0] = mod.n; u[1] = 1; r[1] = pm; i = 1; j = 0; /* flip flap */ while (r[i] > u[i]) { ng++; if (r[i] < nv && v[r[i]] != DLOG_NOT_FOUND && u[i] < nv && v[u[i]] != DLOG_NOT_FOUND) { /* early smooth detection: occurs for primes < 30 bits */ ulong x; /* chi(-1)^j*chi(u)*chi(p)*chi(m)=chi(r) */ x = nmod_sub(v[r[i]], nmod_add(v[u[i]], logm, order), order); if (j) x = nmod_add(x, logm1, order); return x; } j = i; i = 1 - i; /* switch */ t = r[i] / r[j]; r[i] = r[i] % r[j]; u[i] = u[i] + t * u[j]; /* times (-1)^j */ }; /* try to factor both r[i] and u[i] */ iu = factor_until(&u[i], nv, prime, pmax, up, ue); if (u[i] >= nv || v[u[i]] == DLOG_NOT_FOUND) continue; ir = factor_until(&r[i], nv, prime, pmax, rp, re); if (r[i] >= nv || v[r[i]] == DLOG_NOT_FOUND) continue; /* log(u)+log(p)+log(m)=log(r) */ logm = nmod_add(logm, v[u[i]], order); logr = (j) ? logm1 : 0; logr = nmod_add(logr, v[r[i]], order); for (i=0; i < ir; i++) logr = nmod_add(logr, nmod_mul(re[i], v[rp[i]], order), order); for (i=0; i < iu; i++) logm = nmod_add(logm, nmod_mul(ue[i], v[up[i]], order), order); return nmod_sub(logr, logm, order); } return DLOG_NOT_FOUND; } arb-2.22.1/dlog/vec_set_not_found.c000066400000000000000000000013021417376376500171550ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec_set_not_found(ulong *v, ulong nv, nmod_t mod) { n_factor_t fac; ulong i; n_factor_init(&fac); n_factor(&fac, mod.n, 1); for (i = 0; i < fac.num; i++) { ulong p, k; p = fac.p[i]; for (k = p; k < nv; k += p) v[k] = DLOG_NOT_FOUND; } } arb-2.22.1/dlog/vec_sieve.c000066400000000000000000000014261417376376500154310ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include #define vbs 0 /* TODO: tune the limit dlog -> index calculus */ void dlog_vec_sieve(ulong *v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong p1 = 50; /* FIXME: tune this limit! */ dlog_precomp_t pre; dlog_precomp_n_init(pre, a, mod.n, na, p1); dlog_vec_sieve_precomp(v, nv, pre, a, va, mod, na, order); dlog_precomp_clear(pre); } arb-2.22.1/dlog/vec_sieve_add.c000066400000000000000000000014151417376376500162370ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec_sieve_add(ulong *v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong * w, k; /* store size */ w = flint_malloc(nv * sizeof(ulong)); dlog_vec_sieve(w, nv, a, va, mod, na, order); /* write in v */ for (k = 0; k < nv; k++) if (v[k] != DLOG_NOT_FOUND) v[k] = nmod_add(v[k], w[k], order); flint_free(w); } arb-2.22.1/dlog/vec_sieve_add_precomp.c000066400000000000000000000014661417376376500177720ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" void dlog_vec_sieve_add_precomp(ulong *v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong * w, k; /* store size */ w = flint_malloc(nv * sizeof(ulong)); dlog_vec_sieve_precomp(w, nv, pre, a, va, mod, na, order); /* write in v */ for (k = 0; k < nv; k++) if (v[k] != DLOG_NOT_FOUND) v[k] = nmod_add(v[k], w[k], order); flint_free(w); } arb-2.22.1/dlog/vec_sieve_precomp.c000066400000000000000000000052571417376376500171640ustar00rootroot00000000000000/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include #define vbs 0 /* TODO: tune the limit dlog -> index calculus */ void dlog_vec_sieve_precomp(ulong *v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong smooth = 0, sievecount = 0, logcount = 0, missed = 0; ulong logcost; #if 0 ulong limcount; #endif ulong k, p, pmax, logm1; n_primes_t iter; ulong X, aX, vaX; dlog_vec_fill(v, nv, DLOG_NOT_FOUND); v[1] = 0; logm1 = (na % 2) ? 0 : nmod_mul(na / 2, va, order); /* discrete log on first primes, then sieve */ pmax = (nv < mod.n) ? nv : mod.n; logcost = pre->cost; #if 0 if (logcost < 15) { /* p1 = pmax; */ limcount = mod.n; } else { limcount = ceil(pow((double)mod.n,1./2.3) * 40 / logcost); } #endif /* take big power of gen */ X = n_nextprime(3 * na / 2, 0) % na; aX = nmod_pow_ui(a, X, mod); vaX = nmod_mul(va, X % order.n, order); n_primes_init(iter); while ((p = n_primes_next(iter)) < pmax) { double cost; ulong m, vp; if (mod.n % p == 0) continue; /* won't be attained another time */ cost = log(mod.n)/log(p); cost = pow(cost,cost); sievecount++; /* if (p < p1 || (wp = logp_sieve(w, nv, p, mod.n, logm1, order, logcost)) == NOT_FOUND) */ /* if (smooth < limcount || (wp = logp_sieve_factor(w, nv, p, mod.n, a, na, va, logm1, order, logcost)) == NOT_FOUND)*/ if (logcost < cost || (vp = dlog_vec_pindex_factorgcd(v, nv, p, mod, aX, na, vaX, logm1, order, cost)) == DLOG_NOT_FOUND) { if (logcost < cost) sievecount--; else missed++; logcount++; vp = nmod_mul(dlog_precomp(pre, p), va, order); } for (k = p, m = 1; k < nv; k += p, m++) { if (v[m] == DLOG_NOT_FOUND) continue; smooth++; v[k] = nmod_add(v[m], vp, order); } } #if vbs if (missed) flint_printf("[sieve: got %wu / %wu, n = %wu, cost %wu, logs %wu, sieve %wu missed %wu]\n", smooth, limcount, mod.n, logcost, logcount, sievecount, missed); #endif n_primes_clear(iter); for (k = mod.n + 1; k < nv; k++) v[k] = v[k - mod.n]; } arb-2.22.1/doc/000077500000000000000000000000001417376376500131325ustar00rootroot00000000000000arb-2.22.1/doc/Makefile000066400000000000000000000126711417376376500146010ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Arb.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Arb.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Arb" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Arb" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." arb-2.22.1/doc/source/000077500000000000000000000000001417376376500144325ustar00rootroot00000000000000arb-2.22.1/doc/source/_static/000077500000000000000000000000001417376376500160605ustar00rootroot00000000000000arb-2.22.1/doc/source/_static/arb.ico000066400000000000000000000102761417376376500173260ustar00rootroot00000000000000  ¨( @ ììÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥3¤Lÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢`£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢`£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€¡&¢U¤·¥Ò£Y¢!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢!©À¥÷!!®ðVVÂñZZÄþCC»ÿ]]Äò!!¯ï §ñª½¥%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¥n©òššÛüøøüÿÿÿÿÿÿÿÿÿŸŸÜÿooËÿÿÿÿÿÿÿÿÿõõûÿ¤¤Þþ©ò¦mÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢©ÌDD¼òååöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸŸÜÿooËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿååöÿ<<¸ò¨ÅŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÂÖüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿííùÿääõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿ……Òû©Ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¥iCC»ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿBB»ò¥oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥"ªðèè÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿååöÿ©ò¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª»¨¨ßþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸŸÝüªÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ §ñööüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ………ÿ¤¤¤ÿÿÿÿÿ„„„ÿðððÿÿÿÿÿÿÿÿÿõõõÿŽŽŽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýþÿ §ô€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢!""¯ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúÿ³³³ÿvvvÿÚÚÚÿ‘‘‘ÿöööÿ»»»ÿäääÿÿÿÿÿÿÏÏÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ++²î¢)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£Y^^ÅòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëëëÿJJJÿ~~~ÿßßßÿ›››ÿÎÎÎÿ———ÿÇÇÇÿ€€€ÿöööÿÓÓÓÿ„„„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿaaÅó¤Zÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥3¢`¢`¦¾aaÆÿŸŸÜÿŸŸÜÿííùÿÿÿÿÿ§§§ÿûûûÿÿÿÿÿÿÿÿÿfffÿïïïÿÿÿÿÿjjjÿDDDÿúúúÿòòòÿ```ÿÿÿÿÿííùÿŸŸÜÿŸŸÜÿ__Åÿ¥¼¢`¢`¥3ÿÿÿÿÿÿ¤L££¤Í??ºÿooËÿooËÿääõÿÿÿÿÿ¾¾¾ÿ°°°ÿÿÿÿÿÿÿÿÿzzzÿÛÛÛÿÿÿÿÿuuuÿ———ÿÖÖÖÿÞÞÞÿ………ÿÿÿÿÿääõÿooËÿooËÿGG½ÿ¥×££¤Lÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£VXXÃñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿSSSÿªªªÿÿÿÿÿ²²²ÿ²²²ÿÿÿÿÿôôôÿÚÚÚÿÿÿÿÿµµµÿÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhhÉõ¤bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡&##°ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÉÉÿ@@@ÿBBBÿxxxÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿrrrÿúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ))²î +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ ¦öúúýÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿöööÿÿÿÿÿ÷÷÷ÿÿÿÿÿëëëÿíííÿÿÿÿÿÿÿÿÿîîîÿçççÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùýÿ §ô€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª½˜˜Úýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨¨àÿªÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢©òââõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèè÷ÿ©ô +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¥n>>¹òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿEE¼ô ¨xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©Í……Òûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿííùÿääõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ••ÙýªÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£©Æ==¹ñææöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸŸÜÿooËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëëøÿSSÁó©Ö¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦p©ñ¦¦ßýùùýÿÿÿÿÿÿÿÿÿŸŸÜÿooËÿÿÿÿÿÿÿÿÿþþÿÿ§§ßþªñ ¦x€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£'ªÀ §ó''²íeeÇóddÇÿCC»ÿddÇó,,´í §ö©Ç #ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢)£a§Ä¥Ñ¤_£/ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢`£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢`£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥3¤LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿðÿÿÀÿÿÿþþ?ü?øøøðð€€ðððøøü?ü?þÿÿÿÀÿÿðÿÿþÿÿþÿÿþÿÿÿÿÿarb-2.22.1/doc/source/_static/arb.png000066400000000000000000000160451417376376500173400ustar00rootroot00000000000000‰PNG  IHDRÅÅä86ðsBIT|dˆ pHYs±±’Þ¤ÁtEXtSoftwarewww.inkscape.org›î<¢IDATxœíw¸\UՇ߄.¤øÑ©b"5‘ËÅ-U¤F@QD:ˆ~€À"¨éM¤„€€IèH %¡I²¾?Öîäܳ§Ï9gæî÷yæ¹wÎ9sf%w~³÷^{QU"‘ȳm@$R6¢("‘Q‘HŠ(ŠH$EE$’"Š"IE‰¤ˆ¢ˆDRÌQ´CDä `éÔá)Nu¥"ì‰DQ”¹ü#},Rqú‰¤ˆ¢ˆDRDQD")¢("‘Q‘HŠ(ŠH$EE$’"Š"IE‰¤ˆ¢ˆDRDQD")¢("‘Q‘HŠ(ŠH$EE$’"æSäL""ÀüÀBþ‘•;1,YxÇ?¦¹XÊ17$þ_wžDdà3Àç€Uüc%`a`A`ö&où.0 xºêñ”ÿ9É©~ØË#EÑ‘Ï#M0!,G~SÓéÀÀ­þqS}?§÷îK¢(Z YØ å.Q¬E³ðp7&€ÛãÔ«9¢($YpÀŽÀê›Ó Ï8Õ‡‹6¦ˆ¢¨A"2°%°+°50¬X‹ÚæQàà"§:¥hcÊJE‰ÈòÀÀw€Å:tÛiÀ3ÀTàMà ÿø6¶ø®æmà2`^ÌSµ$°<0_‡lQàoÀ1Nõ®ݳoˆ¢¨"Yø6MjÕ]ý60x,õx&knŸˆL&»îÓ2×.¬àËkëÃ[´líqŒS½¦{ôQ€ß8[/4+†À=Àuþq·SÑÄ{O¦AQ^?æñÚÐ?¾Dk£Û?_ㆺ‹wH‹"Yv¢91¼\މàF§úF6L¦ Qî¹2°=°ðé&_þ00Ö©ÞÖêû÷:CR‰È0à Ló4ø²À5ÀÙÀNõ¿²e2Eêþkcâø&°x/ýpS}¾vôCN‰ÈúÀ™Ø.s#< œœëT_è‚=“é¢(ªÞg6lƒñ l¥¦GÇ;Õ:iO™2¢HD†Ç»ÒÀKî~éTÿÚe»&“ƒ(Rï¹p06Åj$ää)`g§zG·l*CB‰ÈhàÀ'¸ü^à§zew­2ŠEÕ{/ˆíÃÌ[çòÀÀQÍ8z‘¾E"2;6üLýÑá>à0§ú÷®VE‘¢¨²aqà8lϤ·Ω>Û]«Š£oó)¼OÿFàGÔÄ[À¾À:y ¢,8Õª6©sù†ÀC‰È×»oY1ô¥(‘ ±?r-Æ+;ÕÓœêÌî[Vn¼vM`l×=Äpà²Dä?÷}'ŠDä`à&jo`M¶qªßè†G©—qª3œêIXþÇeu.ßøK"Ro=ÒSô(IDNÃvek}{¬âT¯ÊDzÞÄ©¾ìT·öÆÂÑClÜœˆ,’eݧ/Dá7ãìâ}`O§º£Sže½S=L¬qÙ`¼¤ìyz^>õórl×6Äd`§zf.FõNõ`màÿj\¶pg"2"«ºGO‹"Y¸Ëuq5ðy§z_>Võ'Nõ§º;°rJ,ÜØëÂèYQ$"ó×cQ¡!NÄÔ¯çcUÿãTOÆ^gÌ\íóÖ{’ž…w^|¡Æe‡9Õb~rçqªã€/c SY, \çwÌ{Ž^­ûô;`«À9ÅBŸOËÑž–QËàŒºÒ;œê?|på5ÀR—, \ŸˆlàT_Î׺öè¹0Dä0àÓbkähÒ&ùàv²…ð°q;9'yÓS¢HDvÎ œžlçTÿ’£I Yøá€Ë€Í{%j gÖ‰È(,"ÄÞQÅàTŸ¤öc$ðóü,jž)|pßCÀ¢K~éTËѤH‰È±Q!«êÈL`+§zm¾V5OéEá _K8[ìl§º[Ž&EjˆŒ®æÌ8ý*°¦S}._«š£¦OÄß±úL‘’àToÀ—²øp±Ë)-¥E"²pdàôd`‡¡^Ž¥Œ8ÕS±}¤,Ö~•£9MSZQøŽ‹ÈÞKùøV/¹ù† ßÅŠ>dq@"RkãµPJ+ àx`ÙÀ¹Cc¹ÇrãTß¶Ãzk¤™ ø}Y”J) ÿ-²kàôuÀ±9ši_å|làôÀ9šÓ0¥ó>yoÓÀ:§_Vïµ°¡N"r–Œ”f:–ðUª èe)v&[{DAô$ûÏ5pzζԥT¢ð‹ëc§¯îva²HwpªÏÞÑÞ*ùJžöÔ£T¢'{×ú},¹%Ò»œˆU6Ï¢T! ¥E"²$áëãœêSyÚé,¾ªàdgí­å«8–‚ÒˆøÙ¡S€£s¶%Òœê=X5•,J»V QøâÇß œ>È©fùº#½É‘X˜šµ‘PâX®”BXQ­ù3ŽOþœ³-‘.â§Á¡$°R¬- …¯.÷ýÀéccŽu_-F$"›çmLšÂEì†EO¦©ôŽô>)éÂÀé}ò´%‹2ˆ"äj=¾S-´"¥$4Zl™ˆ4ÒG¤k* žUjñujW£‹ô8Nõ_@Vcœ9°þå…QôHjrf¬÷:$8'p|ç$ ™‰È—Eä$±*ê¾÷’"r²Xá²²šBñmŽs§7õåó³z¦ÍÄšš)DäçXÅ’unxÜ>ÄÖoE$+¯¡0|™ÿû3N}X+gs€âFŠMe¿¥Èv["òy9ZD6Kvjä5 ŠÈž"2V¬z3ï'"r:ü*°½v¡ƒZŠæƉÈ~68>2W+–gƒ—¼E‘Z]o8/~À@üÓkÀ6~“«-Ddf-á3M›l'àçù `ë›uTõæT˜ùDÖfð.Bð¯Ôó\çï„Z¶-8ÞqòżÇ /P ‰YIzš lç¡ =e|¾…{ŒfàÃz‚ÚÜ;͘۷§¼÷Ë lâ,í]ÒEú"Êm ÕÐæ]"ò‡ß.Y÷X-™ÜîÆ~GõŠ_> û¸XUoiמ*–J=oEÕµ±B;ÿéhÒ†"ŽUõyÑL€•±µKÜ/2Zf i•Žßžˆ|Ðæ½ßwªõbØÞÑ^šÎˆ"‹¹ ‡a7CSYo)*Ag3°,¸Nò©ÔóVö8ª7ÕFYÍkÆ•Å/bý åUfâ-Ò”uÆ|tæïbñÜ£¡hä\Ãd=' €Ä:…ŽÃJ.†8Ò©¦Æ—ŽDd2ƒ;MqªËäoMãÔYTƒ›ÞƵ֋¯PzjúTÁÇËŒnªqÙ¡‰È¹±~TgID$9ŽÚ‚¸ ض=* §ú>6RÜU㲫bdmgðWÕ¸ìz`¤HèIzVðQ(È(¬yJˆQÀ}‰ÈZ5®‰Ô!YÛ+ÚªÆeƦLÓó±ª;ô´(à#aŒέqÙŠÀ‰Èþ~¡i‚Dd?àXhMˆ³€1®\µj[¢çE¶Æpª;Þ< "<¸ÂW»ŽÔ!žˆŒN$ìr8Ω~שfåÀô}!Š Nõ§ÀÞdw_­°5ðßpŠHDvÀB÷·­qÙ‡ÀNµT9ÖíÒW¢pªg`Ó©Wk\¶¶ÿ[¬2+‰Èò‰ÈuXåïOÖ¸ôy`c¿¡ÚWô(œêÕXמz†F‘#|™!K"2,ù Ö®¬^—Úë5êÝ·,úRΚŸŒ~Fv¾w…¹ý5‘í†ÚBÜ‹aw¬ÅØQØÿGˆ™Xè÷>H³/éÉífñ%V.¤¶÷¤Â¬ZÝ…y$Õµ£íK‘î ü˜Æþ_¦»;ÕPô¾¡oGŠjü0¿ÉYï[`̽ût"²ŸoiÛ7$"sùÂOcÕÞë bp<°ÊP ‘‘¢šDdp*ð…_òVVç<§úDì™L#E"òy¬w÷@£¹í÷ßóÕU† CNðQ¤í®XüÎ"M¼ô~Ì+ó'§úb‡l™L—Dá3° áœé,ÞNõu¸†CR‘…°…ãÞdwé 1ól]ÜìTŸjÆÉtH^ì«b†QXîf"§c¡à¿)Có”¢Ò¢¨ˆ,ˆYeYêñÝuL +cknó–2+Iy“S}3‡÷ík¢(º„ß8[¡ê±¢ÿ¹8æö—ÚÁwobýÿ*©XhÆà1`¢S}«[öe¢( Ä/ä'1ØÃUú7ýÌ,+>„"~+•Œ(ŠH$EE$’"Š"IE‰¤ˆ¢ˆDRDQD")¢("‘Q‘HŠ(ŠH$EE$’"Š"IE‰¤ˆ¢ˆDRDQD")¢("‘ÍTÅ‹t‡÷ý#},R1ó.I§O‘HŠ(ŠH$EE$’"Š"IE‰¤ˆ¢ˆDRDQD")¢("‘ÿ^ˆe&“3ÄIEND®B`‚arb-2.22.1/doc/source/_static/arb.svg000066400000000000000000000111461417376376500173500ustar00rootroot00000000000000 image/svg+xml ζ(s) arb-2.22.1/doc/source/_static/arb32x32.png000066400000000000000000000025171417376376500200410ustar00rootroot00000000000000‰PNG  IHDR szzôsBIT|dˆ pHYsììy(q½tEXtSoftwarewww.inkscape.org›î<ÌIDATX…ÅWQLSWþÎ¥´Üj-½­Û„9G…lÌŒ‘@ã[_Œ ²g3/ìa‹ÆGû@x .1ÑÄ™8¡…61KÆFp 3ŽAáXâ" «ÆZH)³¥½mooï¿j#j¡.|É}¸çÜó}ßùÏ9ÿù/#"ì$¸B»«s2vrÇ ¤€ °í˜7¶å=Àë>dÀ§ª’’6E–u$Ëßp_üý‘ô¿ègìÁðm*‘¨Ûµ¿´·¡A ¢Ý¯»+*"Áñqie~žç´Ú?cÁà™/ˆæó"&¢ÜÀ\M§[¯y]®T*‘ —ø§·—&;:2ï¤(äP<‚rét.ÜëøsvöûÜ{öŒ =Ÿ?§õÈ2F< _OZq úw·g`n½~j¦«+™¥F"¤è³g›uÓëWSƒáJ/õ– 8yþìpCCxSöôô"^¯–©Õçú«Üþœè'Uúů÷ ¨¨¨f·Ù CmíªCž,..¢¹¹9ã|ii &“)[·n¡­­ ñx< Ïgx¤/Æ|”Öá&§‰¦L@?c J¥ê¶´è^ •ÍfCSSêëëÑÚÚ ‹Å¯×‹‰‰ Øív C–e²—,áðâÅœ=pÀÛÛwlBüPeœ:) UQêOcDOîQ‚ƒi5híÆŽ¥ÍðáÕó͘»&DQž?¶mãðâÅþôS rr¼¹õSài›Ç|bHQçD¡*J_`öUæJi”@»1ch7z4 Zù~9¢¦EQ†(-%wÍö¾õ9ééžÞvx˜a¢È§ù1uFª¢DÓGׯ†¦Ý»ÓuÚ4®¼ã޵Ë,Q”çÌöíìyã ²—,A””xrK&ðg›kÌ(?¢NxɪŠ2ØÁaaîªÖ«Šc’i5N­…c1NÆÕ ®_Ÿ^|@Ÿ… ‰ˆ0ϸ§Ã_ÿÊà­[i’˜è®ZOà'‡#eÀð¢p„~~ <`T§a\)6ðØcæV‹ˆìÚ•ÁÛ¶Ñþ/qW­=°IU”ž&™Uc´(TEi|‹=ÖA—ÖC†0ä—_hÖ£‡y†ÕBBÂù~þ|zÌšånR"XèÂXQ¨Š¤7Õéôä“ X¾œÐ¦MÍ3¬–ÓiâDnüì3w㌆ÀJGÜz@¢pL.’êt{é%z¼óŽn ƒ¤z´1‚[V¯&4*ʨJ3`µª(q¦åCÒ÷IU”ù€~WQHž=›ŽOÚKïêö¨$³f 뇥´H7Pïp­Mˆ£&›åÐ}šŒ Z Ìõó {T h9p ÝgÌ0*Ž>s¸åø-~- UQz/ë•5Œ‹ã†Å‹QBänþFÇñã‰9Ò¨¸ðš‰æxßvŸ.@¼¶L á¶$úúëÍ7LâÅçα²{wÎ<¨W\ \oâg“Íòn)f #€k^~Y Âϩרý–.%¸n¡ àÿùk€’_ŠBU”dìI]h™’BçÉ“M¶HR¢®¾šäÙ³Š¯RM4Çcü®ûä˜mÚôÒ–…5oΰ;kî6ÄÏX?|8Ç–/×+ºtö· èþØRüAôš7O "é9gŽQ`Wð¾ÉæTŠ_‰Â1¸ž®WÖzÈZ›‡©¶Ѷ-Ý^ÔuW¢*ÊífÚS~% àtV­ƒëקǬYæ[#ñž|’¨k®1*ö+¿…ª(­1ˆ±Nzæµoo²E_¢sý¼yFQ{×9²8ú~# àÿ¡Ú‹±±t™2Ås$¾¦YÏžÄeTü¼™¶¸Ã/DáH~ü¨^Y÷·Þ2šë– ]§N5ÚÔ¦‡ª(C̶G¿ö¤Z µ#;w¦í=÷X`ޤ¦hÔ¾½» 0¿[X. Gv¹‰zeI“'ËëZˆ›Ö¢§ª(·™mËE<ŒÝ{²áW^IÜý÷[`ޤ¦i”@ü†iº,®÷QLÒ»˜ôÔS>ÛBKât1n-«Šbé ­¥¢p¸†»¤Z mÚ´²lt’§q‡´Ñß$ûþå–auK¡;âêðØc2ßkàª1cŒŠþl¢.Xæèp>†ÎC·ïÛGãNÌ7Jb*¥ÅÅü»M OžÔ+îiU¼…•-Å@tÑôºë¤ êAõê¹›ž5lFj+E¡;ýPW™­^½šI“&QPPàóg;vŒ‰'òÛo¿ùüÙÕ¥qê>UQ,ù|ZòRGú|—=Ó”  âþô' ,²–_|‘Ûn»M›6Q¯fÜBBBX´h‰‰‰,×k°ŒÈ®]iÚ½»^QSà:“ͬk)ni/6¿é&K·Ûúå—_˜2e ëׯÇÓ±V~~>|ð³gÏæ‚~¾#C„Œ7Ž^xèèh–,YBH $bhÞ¼9ªªRPPÀˆ#Xµj•ÏßQbGŒ0*h¦N„¦ŸÀŸ€ÐûçÎV‘šš*瑚šê¶~aa¡xóÍ7ETT”óž¶mÛŠË—/{üÎiÓ¦ @„„„ˆuëÖU÷W¨”3f@„……‰ôôôŸ§üñË/.ŸDZFXðù´J[ôþùûöùêïìgΜŠ¢TEhh¨8räˆKÝ’’ññÇ‹ØØØ õËŽ•+WzôÎE‹9ï™2eН%C $.222L{¯[JKÅ’èh=Q|aÂäϧéÝ'UQ¢ÓW kÞܲY§¬¬,—îRQQ?ýô“ó\Á_|A×®]=z4ÙÙúaÅüñG¥ï;xð <ò:uâùçÍóšž;w.\¼x‘‘#GrîÜ9ÓÞmˆ¢Ðâ–[ôJ€L¶Æ’1Eì«–hÞßí–×5JË–-u¯¿÷Þ{¨ªÊ¤I“HLLdĈìÝ»×ð9M›6åÎJ’<—””0zôh.^¼À;ï¼Cýúõ«n¼—ÄÅÅñì³ÏvqŽ?Þ´w»£UJŠQ‘ùã ³›¦OàÝñÄœ9¾jŒ«Äu×]§ÛòôèÝ»·8|øp¥ï™5k–óžž={šð›¹’——'"##vlذÁ;ÊsáÈ£qÅ¢¶wŸ€~z¯°°¥˜3g11ÞoÅœ9sذa±±±nëæååñR¹ìèS,Š(lÒ¤ &LpžO˜0Á¥ûh6áW^Iø8½"Ó÷Î3ÝÍCU”³h¦cÃbbqâ„å±¹¹¹,_¾œ_ý•˜˜JKK™6m%%%ºõÇŒÃ믿þö·¿ñúë¯ЪU+Ž9B°¾§h“M||¼S _}õ·ßnmRõÆqlÅ ½¢fnfjvb‡K°ËúDÓîÝ-@‹-ø‹Ã;777—Þ½{ë âŠ+®àÃ?dèPÊ]8þ<|ðó|Ô¨Q–  66–þýûóÝwß0cÆ ËEÑ$1ÑHI€i¢0»û¤›’£QB‚Éf¸çüùó :”Ç»” 6Œ]»vy%€?þ˜üü|çù}÷ÝW]3«My~øá¶mÛf¡5¸›}4µ å¢hìg¢7nÿùÏ*\kРsçÎ%--+®ÐÝPÉ-óçÏwþÍ5Æ9LãÖ[+nû1Ïâ½>š$&™* ³7wÐýôûSN§Ï?ÿœO>ù¤Âµ˜˜ÒÒÒèÕK7›g¥:tˆ;v8Ïo¾ùf?è.¶k׎øøx:ÀŠ+BXf›Qt6Ó¿h)ü¥ûtüøqüñ ×:tèÀæÍ›«,€eË–U8¿¾Û”””°jÕ*FMrr2mÚ´¡}ûöÜzë­L:•Æ;”êÒ·o_çÏ999dddTÙ¶êE˜~+|•™vX.Š zõŒ¦âL'55•Ó§O;Ïûöí˦M›¸êªêýŸ¬[·®Ây×®]«ôœÝ»w“œœÌàÁƒY¸p!Û·o',,ŒS§N±fÍ^yåâââ\Z:wh»q+ôº¦Ñ@!5ÒLÌ…KPQƒV­üb‹®;wòùçŸ;Ï;uêÄŠ+hÚ´iµŸ½yóæ çUÅ®]»èÛ·/$$$°nÝ: ÈÌÌ$//íÛ·Ó·o_ yøá‡]Þi„V[¶lñÚ6_©ûùodæ/f‹Â%ðº^C—h–ðöÛo;çì›5kÆòåËiÒ¤IµŸ›™™É©S§œç 6¤¹—Û !¸ÿþû9{ö,111lÙ²…Tp3OLL¤½clV\\ÌÒ¥K=zv‡*œïÙ³Ç+Û|(ªÿŸá!f‹"\{!Øòå—_ÄÒ¥Ki×Î%ÉH•ÈÌ̬pÞºuk¯Ÿ‘––æü°¦¦¦¥³‰ûŒ3øøãçðèÙÍ›7¯0°ÎÎÎæüùó^Ûè+ê™Ö…ò¨ß¢*Ê~À^k.ÏÈÛ¹“/}0¦Hž=›6ë–¸:==³gÏö¹û›nº©Úö”qäÈ‘ çUŬrÛ$%éÏNnذ¡Ây'=ŽCCCiÖ¬™³5B°oß>’““½²ñhZ?—s©*EåÆt6¨Š¢»9·\² ѱ²Jžvæcñ(\(),ä‚¶7\ö2ê­}ú°råJÀîõûä“Ozüüèèè ]¼ßÿÝk/_¸à“ÿG7è»2{Ç%O*Y?Âõ~þÙžIåÞ{ïuécW—ò«Øaaa^ß_ÖŠÝq±¨¨ˆ &Ð¥Kg×ç™gž!66–K—.a³Ù¼rG¯Ø«-ÿ¾ºˆÿû6ïÓ§ÏŸ]7Q†·±Mš4¡qãÆ>¨óçÏgþüùDEEѧOúöí˨Q£°ÙlU²QŠ¢"Vgô òòò¸úê«}þlmÊšÐP—}i*ÅÈQïÌ™3¬X±‚)S¦ÀôéºÛVжõò‹h< ñ´¥È¦úcŠ àJíÅàðpªÇ ¥:i6 »;·¯Ñ~àŒÜÐÝñÚk¯±uëV·3J………üýïçÔ©S¼õÖ[^=¿¸¸¸ÂyU2Š„DDQI<‰'9C±~K•T{ íI%~{OFì•áHlu¨àXsEŸ>Ü’ž^ÝÇW‹¨¨(òóóÉÊÊ"ÁÇ.'Uô”¿tÉ£ÿ— ´iÓ†ŒŒ žzê© îçz¼ýöÛÜ}÷Ý^uµ­™¶;å‘ÇWyö¯<[œƒúމ7Û„øµÚ/ðÓºO6!J— ð"G×ÅJÊb´?üðCŸ?»qãÆΫ" °PçÎËÞ½{™5kwÞy§îj»UU½z¶V®¹™E¼hTàkÌSäk/øƒ(úõ³GÈ.]ºÔã•`OÑ®ŠçyñûnݺUU+øc%&&2qâD¾üòKN:EZZšËŒ™»ä zhgÈZ´háÕý¾¤.ŠÂ¥³Xœï¢Óy¶ve<''Ç£û¦L™B¯^½5j­[·&++Ë¥Ž¢( 6ŒÍ›7WèòDG»l å­gmÛ¶m½ºß—\6ä×ZQøeKÑ¿zôèØó=¥¦¦ÏsÏ=GFF†s ^ºtéRáüøñã•ÞóÓO?ñÚk¯9Ï Ýz¾FEEqï½÷:Ï»uëæ±}§OŸ®Ð¥S…+¯t™1óŽØ §mBÔZQ¸¬á—S›k²®üãÿ¨p~äÈ^}õU®»î:ÂÃÃiÑ¢:u¢OŸ>Œ;–¹sçzô¯ð-~âĉJEöÍ7߸\«ìÛ»üÚÂ0ý‚tÑ®¸'%%™š‡ª<¥ÅÅœ× 2õ.Öf‹Âµä{Ù®  äÌÚ§EÁ‰'Ø¿?›6mâ£>bܸqÄÆÆrÏ=÷pðàAÃçUh-JKKÙ·oŸ[[´ëmÚ´a¸›™'N8c6îºë.®½öZ·Ï/ÏÎ;+œ÷îÝÛã{}ÍùC‡úSÖµZºŸ~ÀÌ™30`€Çõ/_¾Ì¿ÿýoºvíÊœ9s ë¥h²ßUæž]~:õÚk¯eëÖ­†it._¾Ì#!!!¼øâ‹Û°}ûö çå#ñÌæœñ—‹…U„‡‡³råJFŽéÕ}—.]büøñΜNZ´™?*Ëš1hÐ ñÊû÷ïGUU._¾ìRoóæÍôèу´´4‚‚‚X¸p¡×Lå41dȯî÷%nDaÜ×f¦#üšê¥F\Ý¿u³.úœµk׊ˆàà`Sg‹M›6¹<«¤¤DDGG;ë]}õÕ•¾?;;[tìØÑyOýúõERR’HII]ºt⤤$ñÝwßyý;ˆ°°0çsn¸á¯ŸáK¶Œg”:ózaâçÔŠ ¹hÂRëGGsoÜ•ÍàôéÓlܸ‘œœNžúè#—´š5ɼyóœép¦L™b©[G‡/6*ÒÖ4V‰b:G9éé\ò`wQ«p»|ß}÷±lÙ2‚‚<û“.X°€nݺ!„àá‡6%ÙáÇê»îºËk—šàò… ü¦I@í@+M6°H6!ŠÑiK‹ŠÜ}kXÎý÷ßïr­K—.¬[·ŽO?ý” xü¬ÈÈHÒÓÓIJJâðáÃ<ðÀUŠßö”‹/rçwröìY’““QUÕ/¶8úÕWFElBÑ+¨i¬Ìæñ/½‹YåR?ú#GŽdõêÕ¼ùæ›|ñÅdee±sçN¯œËÃÚµkéСiii5ºšÀ0]÷®—_æ§Ñ£eþ(_#ÿyæ™Ê±¸'* ›—°·›êüwáBÖ*=k}DÑéÓ¬6Œ½o¹ ¥N:<’€8]AnVÕÉIOgeœ.·‰ºÄ{NmÙŠk¯åØJ·Ùñ¿ÀÞeÒßô/@hQ€SÃÃtåçdUïÞü:s¦»iC‰¿ÎšÅêoä·™ñÿ Üg"à³L¼(À>ư ñgàU£:¥EElKMeýðá\:eÚ>åMÑ™3ü0bÛž|²²±Ù›6!þ«ÕžP+DQ†Mˆç€qèì¾ZƱ+XÞ­[eÝ€:ÏáÅ‹ù:1‘#_|á®Úe Õ&„_ÅXW—Z% ›s±w§ ›ƒ‚ãÇY?t(ßÝ~»»¨°:ɹ¬,Ö¦¤°áÁ)r3­Ç9`*ðž#ò±NQ'EQ†ª(‘ØŽãJp0- väHš@£öí«lƒOE!gví"wÍrÒÓÉ]»Ö[‡È ÀûÀ[þ°yŠUÔiQ”¡*JðöÖÃë]×Ã[·¦ùM7Ѽšßt<¾·º¢¸pä¹ëÖ9EPÉÚ‚ç9ØÅPç—û¥(Ê¡*J40xhVÕç4hÙ’È.]h”@ã„9ކññÕ«bî©( Ož$Ïòöì!o÷nçÏEgÎTÕL°w“foûs&³‘¢ÐAU”àaì­G¥Ó¸ž¢Þº5! AHD§¶lqY8  #²kWŠòò(Îϧ(/Ï×»9íĽ¸À&DµTU‘¢pƒª(A@à~à ©µU‹?°¯Õ|d"Ãjcü) Q¥pvÜDXk‘GœÖb•^^ܺÍ@Š¢ ¨ŠŽ=¸©¿ãè[j”`+vߤt`³?¦º÷w¤(|€ª(° ¤41áÕG±o|²{JÊu6!òMxo­FŠ¢†P%h_îHpüÛû´o8ææùØ÷ÿ+;ÎYذØgBŸ×RâÈÂu†+Û&DœùI Ž8ú+ ù­ägHQH$¤($ R‰) ‰Dƒ…D¢AŠB"Ñ E!‘h¢H4HQH$¤($ R‰) ‰Dƒ…D¢AŠB"Ñ E!‘h¨ù´Ú’ʸä8´×$!#ï$ ²û$‘h¢H4HQH$¤($ R‰) ‰Dƒ…D¢AŠB"Ñðÿõ/ËáãIEND®B`‚arb-2.22.1/doc/source/_static/arbfilled.svg000066400000000000000000000111761417376376500205330ustar00rootroot00000000000000 image/svg+xml ζ(s) arb-2.22.1/doc/source/_static/arbtext.eps000066400000000000000000000501671417376376500202530ustar00rootroot00000000000000%!PS-Adobe-3.0 EPSF-3.0 %%Creator: cairo 1.13.1 (http://cairographics.org) %%CreationDate: Wed Jan 28 14:20:15 2015 %%Pages: 1 %%DocumentData: Clean7Bit %%LanguageLevel: 2 %%BoundingBox: 0 -1 813 349 %%EndComments %%BeginProlog save 50 dict begin /q { gsave } bind def /Q { grestore } bind def /cm { 6 array astore concat } bind def /w { setlinewidth } bind def /J { setlinecap } bind def /j { setlinejoin } bind def /M { setmiterlimit } bind def /d { setdash } bind def /m { moveto } bind def /l { lineto } bind def /c { curveto } bind def /h { closepath } bind def /re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto 0 exch rlineto 0 rlineto closepath } bind def /S { stroke } bind def /f { fill } bind def /f* { eofill } bind def /n { newpath } bind def /W { clip } bind def /W* { eoclip } bind def /BT { } bind def /ET { } bind def /pdfmark where { pop globaldict /?pdfmark /exec load put } { globaldict begin /?pdfmark /pop load def /pdfmark /cleartomark load def end } ifelse /BDC { mark 3 1 roll /BDC pdfmark } bind def /EMC { mark /EMC pdfmark } bind def /cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def /Tj { show currentpoint cairo_store_point } bind def /TJ { { dup type /stringtype eq { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse } forall currentpoint cairo_store_point } bind def /cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def /Tf { pop /cairo_font exch def /cairo_font_matrix where { pop cairo_selectfont } if } bind def /Td { matrix translate cairo_font_matrix matrix concatmatrix dup /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def /Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def /g { setgray } bind def /rg { setrgbcolor } bind def /d1 { setcachedevice } bind def %%EndProlog %%BeginSetup %%BeginResource: font CMUSerif-Bold 11 dict begin /FontType 42 def /FontName /CMUSerif-Bold def /PaintType 0 def /FontMatrix [ 1 0 0 1 0 0 ] def /FontBBox [ 0 0 0 0 ] def /Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for Encoding 40 /parenleft put Encoding 41 /parenright put /CharStrings 3 dict dup begin /.notdef 0 def /parenleft 1 def /parenright 2 def end readonly def /sfnts [ <000100000009008000030010637674200a280bb9000002d4000000706670676d83042d570000 034400000205676c796617bfa05f0000009c0000023868656164ed833cf30000054c00000036 68686561060403fc0000058400000024686d7478067600b6000005a80000000c6c6f63610000 0544000005b4000000106d617870012c0417000005c40000002070726570512791cb000005e4 000000de0005000a000a02ee02fd000300060009000c000f00f200b0002fb407060032042bb0 0832b00a2fb00c33b401060032042b01b0102fb000d6b4040d0032042bb00632b00410b2000e 102bb00f32b4030d0032042bb011d6b0361ab1040c8704b0042e05b00cc0b1070df904b00fc0 b106088705b0082e04b006c0b10e0df905b00ac0b00610b3050608132bb1060808b00410b305 040c132b05b00610b3090608132bb1060808b00710b309070f132b05b00a10b30b0a0e132bb1 0a0e08b00410b30b040c132b05b00a10b30d0a0e132bb10a0e08b00710b30d070f132b00b704 0506090b0d0e0f2e2e2e2e2e2e2e2e01b7050708090a0b0c0d2e2e2e2e2e2e2e2eb0401a0100 303137112111250901132109030301110a02e4fd580114feec230226feedfeed01130113f101 140a02f3fd0d6601140113fdaf01140167feec0114fec3feec0227000001006cff07017e02ee 0019002900b0142fb0042f01b01a2fb000d6b40a0e001f042bb20a000a2bb3000a06092bb012 32b01bd6003031371037363332151407061114171617301716151423222e0127266cb3391412 10a1262a5e0102120b37501e50fb010bb2360e0510a2fed1907381570304030e2958358d0000 00010040ff07015202ee0015002900b0142fb00a2f01b0162fb004d6b4100e001f042bb20410 0a2bb3000400092bb00832b017d60030311734373611102726353433321e0117161510070623 224010a1a011120b37501e50b3391412eb0510a2012f012ba310070e2958358db1fef5b23600 0000ff3dff5e000001bd028d02a300300000002100240028002f00720035006d00720080008e 0099003c0089007d0095008300610069005b004d006b005200920067002c001e00180040001c 00450033004a0065007400370058005d0078003a00470050002a007a0063005f00540026006f b0002cb000134bb0275058b04a7659b000233f18b0062b583d594bb02750587d5920d4b00113 2e182db0012c20dab00c2b2db0022c4b5258452359212db0032c691820b040505821b040592d b0042cb0062b582123217a58dd1bcd591b4b525858fd1bed591b2321b0052b58b046765958dd 1bcd595959182db0052c0d5c5a2db0062cb12201885058b020885c5c1bb000592db0072cb124 01885058b040885c5c1bb000592db0082c121120392f2db0092c207db0062b58c41bcd5920b0 0325492320b004264ab00050588a658a6120b0005058381b2121591b8a8a6120b0005258381b 21215959182db00a2cb0062b5821101b1021592db00b2c20d2b00c2b2db00c2c202fb0072b5c 582020472346616a2058206462381b2121591b21592db00d2c12112020392f208a20478a4661 238a208a234ab000505823b0005258b040381b21591b23b0005058b04065381b2159592db00e 2cb0062b583dd61821211b20d68a4b5258208a234920b0005558381b2121591b212159592db0 0f2c2320d6202fb0072b5c582320584b531b21b00159588ab0042649238a23208a498a236138 1b21212121591b2121212121592db0102c20dab0122b2db0112c20d2b0122b2db0122c202fb0 072b5c582020472346616a8a2047234623616a602058206462381b2121591b2121592db0132c 208a208a8720b003254a64238a07b02050583c1bc0592d000000000100000000b3331a58429c 5f0f3cf5001f03e800000000c65fa30800000000c65fa308fac6fe6f06ca045b000100080002 0001000000000001000003a9fecc00c8070afac6fe2206ca0001000000000000000000000000 0000000302f8000a01bf006c01bf00400000000000000148000001c400000238000100000003 00a50008009b000800020001000000140000010002d100030004b801ff85b0018d004bb00850 58b101018e59b146062b5821b010594bb014525821b080591db0062b5c5800b0062045b0032b 44b00b2045ba0006021400022bb0032b44b00a2045b20b49022bb0032b44b0092045b20a3402 2bb0032b44b0082045b209b5022bb0032b44b0072045b20820022bb0032b4401b00c2045b003 2b44b00e2045b20c6e022bb10346762b44b00d2045b20e0e022bb10346762b44b00f2045ba00 0c7fff00022bb10346762b44b0102045b20f2f022bb10346762b44b0112045b2101d022bb103 46762b44b0122045b21114022bb10346762b4459000000> ] def /f-0-0 currentdict end definefont pop %%EndResource %%BeginResource: font CMUSerif-Bold 11 dict begin /FontType 42 def /FontName /CMUSerif-Bold def /PaintType 0 def /FontMatrix [ 1 0 0 1 0 0 ] def /FontBBox [ 0 0 0 0 ] def /Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for Encoding 1 /uni03B6 put /CharStrings 2 dict dup begin /.notdef 0 def /uni03B6 1 def end readonly def /sfnts [ <000100000009008000030010637674200a280bb900000314000000706670676d83042d570000 038400000205676c7966b43722940000009c0000027868656164ed833cf30000058c00000036 68686561060403fb000005c400000024686d7478054a004a000005e8000000086c6f63610000 03c0000005f00000000c6d617870012b0417000005fc0000002070726570512791cb0000061c 000000de0005000a000a02ee02fd000300060009000c000f00f200b0002fb407060032042bb0 0832b00a2fb00c33b401060032042b01b0102fb000d6b4040d0032042bb00632b00410b2000e 102bb00f32b4030d0032042bb011d6b0361ab1040c8704b0042e05b00cc0b1070df904b00fc0 b106088705b0082e04b006c0b10e0df905b00ac0b00610b3050608132bb1060808b00410b305 040c132b05b00610b3090608132bb1060808b00710b309070f132b05b00a10b30b0a0e132bb1 0a0e08b00410b30b040c132b05b00a10b30d0a0e132bb10a0e08b00710b30d070f132b00b704 0506090b0d0e0f2e2e2e2e2e2e2e2e01b7050708090a0b0c0d2e2e2e2e2e2e2e2eb0401a0100 303137112111250901132109030301110a02e4fd580114feec230226feedfeed01130113f101 140a02f3fd0d6601140113fdaf01140167feec0114fec3feec02270000010040ff2b021202c1 003c008e00b23a02002bb427060012042bb02e2fb433060015042bb0072fb40c06000d042bb0 183201b03d2fb000d6b1220de9b00a20d611b10f10e9b02210b20037102bb12b0de9b2372b0a 2bb3003731092bb03ed6b10f221112b10c073939b03711b5181e2728053a241739b02b12b01b 3900b13a331112b02b39b107271112b100223939b00c11b205151e393939303137343e023706 2322263436333216171e0433323633321615140e02070615141e023b01321615140623222635 34373e0235342b012226401e37301f261331292a16192104010102050b0923ab0f16221c2b65 32b3283a3113086a8a72401e18200256409a167082ee366452371e083446201d15030f090a05 5c2218141d163a247f752234190c604c47552111230b01041a1d398fff3dff5e000001bd028d 02a300300000002100240028002f00720035006d00720080008e0099003c0089007d00950083 00610069005b004d006b005200920067002c001e00180040001c00450033004a006500740037 0058005d0078003a00470050002a007a0063005f00540026006fb0002cb000134bb0275058b0 4a7659b000233f18b0062b583d594bb02750587d5920d4b001132e182db0012c20dab00c2b2d b0022c4b5258452359212db0032c691820b040505821b040592db0042cb0062b582123217a58 dd1bcd591b4b525858fd1bed591b2321b0052b58b046765958dd1bcd595959182db0052c0d5c 5a2db0062cb12201885058b020885c5c1bb000592db0072cb12401885058b040885c5c1bb000 592db0082c121120392f2db0092c207db0062b58c41bcd5920b00325492320b004264ab00050 588a658a6120b0005058381b2121591b8a8a6120b0005258381b21215959182db00a2cb0062b 5821101b1021592db00b2c20d2b00c2b2db00c2c202fb0072b5c582020472346616a20582064 62381b2121591b21592db00d2c12112020392f208a20478a4661238a208a234ab000505823b0 005258b040381b21591b23b0005058b04065381b2159592db00e2cb0062b583dd61821211b20 d68a4b5258208a234920b0005558381b2121591b212159592db00f2c2320d6202fb0072b5c58 2320584b531b21b00159588ab0042649238a23208a498a2361381b21212121591b2121212121 592db0102c20dab0122b2db0112c20d2b0122b2db0122c202fb0072b5c582020472346616a8a 2047234623616a602058206462381b2121591b2121592db0132c208a208a8720b003254a6423 8a07b02050583c1bc0592d000000000100000000b333e3c33ff05f0f3cf5001f03e800000000 c65fa30800000000c65fa308fac6fe6f06ca045b0001000800020001000000000001000003a9 fecc00c8070afac6fe2206ca00010000000000000000000000000000000202f8000a02520040 00000000000001480000027800010000000200a50008009b0008000200010000001400000100 02d100030004b801ff85b0018d004bb0085058b101018e59b146062b5821b010594bb0145258 21b080591db0062b5c5800b0062045b0032b44b00b2045ba0006021400022bb0032b44b00a20 45b20b49022bb0032b44b0092045b20a34022bb0032b44b0082045b209b5022bb0032b44b007 2045b20820022bb0032b4401b00c2045b0032b44b00e2045b20c6e022bb10346762b44b00d20 45b20e0e022bb10346762b44b00f2045ba000c7fff00022bb10346762b44b0102045b20f2f02 2bb10346762b44b0112045b2101d022bb10346762b44b0122045b21114022bb10346762b4459 000000> ] def /f-0-1 currentdict end definefont pop %%EndResource %%BeginResource: font CMUSerif-BoldItalic 11 dict begin /FontType 42 def /FontName /CMUSerif-BoldItalic def /PaintType 0 def /FontMatrix [ 1 0 0 1 0 0 ] def /FontBBox [ 0 0 0 0 ] def /Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for Encoding 115 /s put /CharStrings 2 dict dup begin /.notdef 0 def /s 1 def end readonly def /sfnts [ <000100000009008000030010637674200bc30cab0000036c000000746670676d75042d570000 03e000000205676c7966a2aae2a50000009c000002d068656164eddc3791000005e800000036 68686561066404400000062000000024686d747804df005e00000644000000086c6f63610000 04140000064c0000000c6d617870012b048b00000658000000207072657056cdc1d200000678 0000010f0005000a000a02ee02fd000300060009000c000f00ee00b20a04002bb00c33b40105 0032042bb0002fb407050032042bb0083201b0102fb000d6b1040ae9b00632b00410b2000e10 2bb00f32b1030ae9b011d6b0361ab1040c8704b0042e05b00cc0b10715f904b00fc0b1060887 05b0082e04b006c0b10e15f905b00ac0b00610b3050608132bb1060808b00410b305040c132b 05b00610b3090608132bb1060808b00710b309070f132b05b00a10b30b0a0e132bb10a0e08b0 0410b30b040c132b05b00a10b30d0a0e132bb10a0e08b00710b30d070f132b00b7040506090b 0d0e0f2e2e2e2e2e2e2e2e01b7050708090a0b0c0d2e2e2e2e2e2e2e2eb0401a010030313711 2111250901132109030301110a02e4fd580114feec230226feedfeed01130113f101140a02f3 fd0d6601140113fdaf01140167feec0114fec3feec02270000010054fff501e501c8003b00e9 00b23901002bb10b07e9b20b390a2bb3000b03092bb21b02002bb12808e9b2281b0a2bb30028 21092b01b03c2fb016d6b12b0be9b02b10b00620d611b10010e9b0002fb10610e9b02b10b216 0e102bb1340be9b3170e240e2bb11e0de9b03dd6b0361ab1131087b0132eb010c0b12e0df9b0 31c0b01310b3111310132bb02e10b32f2e31132bb22f2e31208a208a23060e111239b2111310 11123900b5133110112e2f2e2e2e2e2e2e01b5133110112e2f2e2e2e2e2e2eb0401a01b11600 1112b103093939b1242b1112b30b1b2839241739b1340e1112b12126393900b1280b1112b116 3439393031373436333216151406071633323635342e02272e0135343e023332161514062322 26353437262322061514171e02171e0115140e02232226542a1e161b181a223b4c3f22283b0c 1d2f0f244f373d4928161318271d2a3a2f0a0b2437132138132c5c3f4a575a222d1a14122809 1f4220161d0b0b040a3227122e382532292124181125131a3619110b0c0b09060b372c17353c 2737ff3e000001bc029902a30030000000240025006e003a004e00600065006e00750079007d 0084008900950036003c00670038007f0070002a0082008b0032009000630069004c00560028 0086002e0092009c008d00970022002c005a00180050003f005c002000770052006c0058001e 004a0034b0002cb000134bb0205058b04a7659b000233f18b0062b583d594bb02050587d5920 d4b001132e182db0012c20dab00c2b2db0022c4b5258452359212db0032c691820b040505821 b040592db0042cb0062b582123217a58dd1bcd591b4b525858fd1bed591b2321b0052b58b046 765958dd1bcd595959182db0052c0d5c5a2db0062cb12201885058b020885c5c1bb000592db0 072cb12401885058b040885c5c1bb000592db0082c121120392f2db0092c207db0062b58c41b cd5920b00325492320b004264ab00050588a658a6120b0005058381b2121591b8a8a6120b000 5258381b21215959182db00a2cb0062b5821101b1021592db00b2c20d2b00c2b2db00c2c202f b0072b5c582020472346616a2058206462381b2121591b21592db00d2c12112020392f208a20 478a4661238a208a234ab000505823b0005258b040381b21591b23b0005058b04065381b2159 592db00e2cb0062b583dd61821211b20d68a4b5258208a234920b0005558381b2121591b2121 59592db00f2c2320d6202fb0072b5c582320584b531b21b00159588ab0042649238a23208a49 8a2361381b21212121591b2121212121592db0102c20dab0122b2db0112c20d2b0122b2db012 2c202fb0072b5c582020472346616a8a2047234623616a602058206462381b2121591b212159 2db0132c208a208a8720b003254a64238a07b02050583c1bc0592d000000000100000000b333 13bd62f55f0f3cf5001f03e800000000c65fa04b00000000c65fa04bfb53fe750694046d0003 00080002000100000000000100000399fecc00c806bffb53fe4f069400640019000000000000 000000000000000202f8000a01e700540000000000000144000002d000010000000200bf0008 00a00008000200010000001400000100032600030004b801ff85b0018d004bb0085058b10101 8e59b146062b5821b010594bb014525821b080591db0062b5c5800b0052045b0032b44b00820 45b20534022bb0032b44b0072045ba000801f400022bb0032b44b0062045b20720022bb0032b 4401b0092045b0032b44b00d2045b20945022bb10346762b44b00c2045b20d29022bb1034676 2b44b00b2045b20c17022bb10346762b44b00a2045b20b0e022bb10346762b44b00e2045ba00 097fff00022bb10346762b44b00f2045b20e4d022bb10346762b44b0102045b20f3a022bb103 46762b44b0112045b21028022bb10346762b44b0122045b2111f022bb10346762b44b0132045 b21216022bb10346762b44b0142045b21315022bb10346762b44590000> ] def /f-1-0 currentdict end definefont pop %%EndResource %%BeginResource: font CMUSansSerif-Bold 11 dict begin /FontType 42 def /FontName /CMUSansSerif-Bold def /PaintType 0 def /FontMatrix [ 1 0 0 1 0 0 ] def /FontBBox [ 0 0 0 0 ] def /Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for Encoding 65 /A put Encoding 98 /b put Encoding 114 /r put /CharStrings 4 dict dup begin /.notdef 0 def /A 1 def /r 2 def /b 3 def end readonly def /sfnts [ <0001000000090080000300106376742009c2095b0000051c000000606670676d69042d570000 057c00000205676c79665d85ff490000009c0000048068656164ee495d1b0000078400000036 6868656106c104b4000007bc00000024686d7478097a00ac000007e0000000106c6f63610000 0c44000007f0000000146d617870012e042c0000080400000020707265707c372bdd00000824 000000f60005000a000a02ee02fd000300060009000c000f00ee00b20a04002bb00c33b10108 e9b0002fb10708e9b0083201b0102fb000d6b4040f000b042bb00632b00410b2000e102bb00f 32b4030f000b042bb011d6b0361ab1040c8704b0042e05b00cc0b10714f904b00fc0b1060887 05b0082e04b006c0b10e14f905b00ac0b00610b3050608132bb1060808b00410b305040c132b 05b00610b3090608132bb1060808b00710b309070f132b05b00a10b30b0a0e132bb10a0e08b0 0410b30b040c132b05b00a10b30d0a0e132bb10a0e08b00710b30d070f132b00b7040506090b 0d0e0f2e2e2e2e2e2e2e2e01b7050708090a0b0c0d2e2e2e2e2e2e2e2eb0401a010030313711 2111250901132109030301110a02e4fd580114feec230226feedfeed01130113f101140a02f3 fd0d6601140113fdaf01140167feec0114fec3feec0227000002002a000002b202b60028002d 012700b22702002bb01133b20604002bb41d2927060d2bb02a33b11d0be9b01c3201b02e2fb0 2fd6b0361ab102038704b0022eb003c0b12117f9b02cc0b12c1887b1212c08b02c1005b018c0 b10a18f9b00dc0b30b0a0d132bb30c0a0d132bb02c10b3192c18132bb31a2c18132bb31b2c18 132bb31c2c18132bb02110b31d212c132b04b31e212c132bb31f212c132bb320212c132b05b3 29212c132bb02c10b32a2c18132bb220212c208a208a23060e111239b01f39b01e39b20b0a0d 208a208a23060e111239b00c39b21a2c18111239b01b39b0193900400f02030c0d2c0a0b1819 1a1b1e1f20212e2e2e2e2e2e2e2e2e2e2e2e2e2e2e01401302030c0d1c1d292a2c0a0b18191a 1b1e1f20212e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2eb0401a01003031373437133e013b 01321e0217131615142b01222e0727210e072b012237330227062a04d4081a1d5a1218100406 cf042535090e0d080a060b070f06fee3070f080b080b0c100b2526cce1660a0a1b070c025a17 1708190912fdb20c051b010705110b1d152b11122f161d0c0f0404ed0124282400000001003c 0000016401d50026002e00b22402002bb20f03002bb00433b1150ce901b0272fb000d6b11e0e e9b00a32b028d600b10f151112b00a393031371134363b0132171e01173e023b0132161d0114 070e01070e0107061d01140607062b0122263c1915211b0d0702011844270f010d0705062910 22320703060c0c102b1b122b01771d100d0810262128080a0c380b070505050c32210d19af15 0d0a06180002003cfff5020b02d200190034006100b21802002bb21202002bb12405e9b20404 002bb20a03002bb13205e901b0352fb000d6b11a12e9b00732b01a10b2002a102bb10e12e9b0 36d6b11a001112b01439b02a11b10a12393900b124181112b01439b03211b00e39b00a12b008 393031371134363b01321d013633321716140e022322270e012b012237171e0733323e033534 35342e032322073c131b2c2c3f4c8f240b2541462a3f320811132e2e8903040309060a090c0e 08202d150c01020a14281c2f2a2e027616182cf928872a8860321526100b6504040308040703 0402171c351f1d05031e23321b152300ff3dff5e000001ca02b10049000000140040004e0051 0056005f006c00880078007b00880089008e00360053006e007e0086007000740068008b0084 0080007200620076005b004b0082006a003b00430046003d00660058005d0064002b0032b000 2cb000134bb01a5058b04a7659b000233f18b0062b583d594bb01a50587d5920d4b001132e18 2db0012c20dab00c2b2db0022c4b5258452359212db0032c691820b040505821b040592db004 2cb0062b582123217a58dd1bcd591b4b525858fd1bed591b2321b0052b58b046765958dd1bcd 595959182db0052c0d5c5a2db0062cb12201885058b020885c5c1bb000592db0072cb1240188 5058b040885c5c1bb000592db0082c121120392f2db0092c207db0062b58c41bcd5920b00325 492320b004264ab00050588a658a6120b0005058381b2121591b8a8a6120b0005258381b2121 5959182db00a2cb0062b5821101b1021592db00b2c20d2b00c2b2db00c2c202fb0072b5c5820 20472346616a2058206462381b2121591b21592db00d2c12112020392f208a20478a4661238a 208a234ab000505823b0005258b040381b21591b23b0005058b04065381b2159592db00e2cb0 062b583dd61821211b20d68a4b5258208a234920b0005558381b2121591b212159592db00f2c 2320d6202fb0072b5c582320584b531b21b00159588ab0042649238a23208a498a2361381b21 212121591b2121212121592db0102c20dab0122b2db0112c20d2b0122b2db0122c202fb0072b 5c582020472346616a8a2047234623616a602058206462381b2121591b2121592db0132c208a 208a8720b003254a64238a07b02050583c1bc0592d000000000100000000b3336465f14e5f0f 3cf5001f03e800000000c65fb31400000000c65fb314facdfe48078904920001000800020001 000000000001000003a0feb000c807c8facdfe37078900010000000000000000000000000000 000402f8000a02dd002a0174003c0231003c0000000000000144000002f00000039000000480 00010000000400b4000900b4000800020001000000140000010002be00030004b801ff85b001 8d004bb0085058b101018e59b146062b5821b010594bb014525821b080591db0062b5c5800b0 052045b0032b44b0082045b2053e022bb0032b44b0072045b20815022bb0032b44b0062045b2 074b022bb0032b44b0092045b20574022bb0032b44b00a2045b2094a022bb0032b44b00b2045 b20a2f022bb0032b44b00c2045b20b20022bb0032b44b00d2045b20c13022bb0032b4401b00e 2045b0032b44b0102045b20e30022bb10346762b44b00f2045b21029022bb10346762b44b011 2045ba000e7fff00022bb10346762b44b0122045ba0011021500022bb10346762b44b0132045 b21263022bb10346762b4459000000> ] def /f-2-0 currentdict end definefont pop %%EndResource %%EndSetup %%Page: 1 1 %%BeginPageSetup %%PageBoundingBox: 0 -1 813 349 %%EndPageSetup q 0 -1 813 350 rectclip q 0 g BT 84.489223 0 0 91.540387 103.653328 149.367872 Tm /f-0-1 1 Tf <01>Tj /f-0-0 1 Tf [()101(\()]TJ /f-1-0 1 Tf [()123(s)]TJ /f-0-0 1 Tf (\))Tj ET 0.639216 0 0 rg 11.592215 w 0 J 0 j [] 0.0 d 4 M q 0.933351 0.0115746 0.0108031 -1 0 348.475006 cm 328.486 176.204 m 328.487 250.263 264.164 310.3 184.813 310.299 c 105.466 310.299 41.14 250.261 41.139 176.203 c 41.143 102.144 105.465 42.107 184.816 42.108 c 264.163 42.108 328.489 102.146 328.486 176.204 c h 328.486 176.204 m S Q 11.2 w q 1 0 0 -1 0 348.475006 cm 175.199 -0.008 m 175.199 80.465 l S Q q 1 0 0 -1 0 348.475006 cm 175.199 267.992 m 175.199 348.465 l S Q 11.200018 w q 1 0 0 -1 0 348.475006 cm 80.473 173.266 m 0 173.266 l S Q 11.2 w q 1 0 0 -1 0 348.475006 cm 348.473 173.266 m 268 173.266 l S Q 0 g BT 263.310797 0 0 231.685574 384.041751 97.7285 Tm /f-2-0 1 Tf [(Arb)]TJ ET Q Q showpage %%Trailer end restore %%EOF arb-2.22.1/doc/source/_static/arbtext.pdf000066400000000000000000000277501417376376500202370ustar00rootroot00000000000000%PDF-1.4 %Çì¢ 5 0 obj <> stream xœuR±N$1 Õµù —K±Æv'.ABW]LyÕÍ b‹…‚ßǙɰ{ˆÓÉ> /Contents 5 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 16 0 obj <> endobj 17 0 obj <> endobj 22 0 obj <>stream xœ];Â0 †÷œÂ7H› ¤*KY:€pÔqª 8QšÜž¤[~üŸü[öÃe`ŸAÞSÀ'epžm¢9, Fš<‹Võ˜÷nÍø6QÈþjâë Š€ÜÖßÌ›äCm“vc0Xš£AJ†']ÓèÎ9-ˆíßjF·+ÕIwê¬ Qªª?6­Ž“€KJÄy5º©<Óï—b¥ „øñ°S endstream endobj 10 0 obj <> endobj 23 0 obj <>stream xœ]O»à Üù ÿyH¢,é’¡UÕöÀ˜ˆ!2ôïHÒ¡ÃY:ß|–ÃxÙ%èñE ¬ciñkDM“cQ7`¦ƒ•‰³ B7ÞŸ@°Èîü®f’Ϧ-›zÏ 7´…O$ºªê;k{Alþ¤# íé¬û­¾ÿ©ähîpž\c$N¥h)’ 8¦ß/Á‡œ‚ â úÒS endstream endobj 8 0 obj <> endobj 24 0 obj <>stream xœ]O1ƒ0 Üó ÿ Vê‚XèÂЪjûà8(NÂÐß—èÐáN²ïN>Ë®¿öìÈGôø¢Ö±‰4û%"Á@£cQÕ`¦}*Œ“Bv7ÞŸ@°Ènó]O$Ÿõ¹lª-ƒÞÐ4RÔ<’h”jk[Alþ¤=0ØÝy9µJ­œý‡’£¹Ãqp‰‘8•¢¥H.à˜~¿r Vˆ/ò©S endstream endobj 12 0 obj <> endobj 25 0 obj <>stream xœ]O»à Üù þ’>² –tÉЪjûLÄPƒú÷’tèp'Ÿí³Î¬.ºDÙ=zý„D­CaöKÔ@G˜’¦¥Æé´©Êú­aýU…×'Í `W}So`öT;ÍêÑÞÀ”†¨p"8—ÂZIÍßè°F»mYÁyf"έ¬à<3].»*3—k»¯. ÷@T/1¦úFYâ9„ß§Á‡â¢ä ´œY endstream endobj 14 0 obj <> endobj 11 0 obj <> endobj 18 0 obj <>stream xœÕV]lU>wfvfvöoöZ»üÌt v¶‹[hÁݨ-i+q- 3RÁµ€-m i*ÅNR‚&&}ÑŸ¸ÛÖ€$Æ&bP0¦F}0>˜H bH@í®çÎ,ñÁðêMæÎý¾ûóÝsgîì€òoÏdÁmr-vOöÆ<,^ öMŒkÊšÀÇH|רàØÐÈq!½ çà|CÃÏzzañ¦}…þ…ãm70ß;H¶ìCBø¿øˆWퟬø1ex´¯Pñ£Œ)LŽS¨A=Ói #Þ¼t »•c£‡Ç+ñ/°ù±CcO4¾ö%êßDücyKy®ínŠ; ë‘Ña¬ ‚0‚ý18oA¼ Gá 8Ø»a<=ð: + r° Ú¡º`Æ¡,x&áØ yXG öÂh€Q &…x7mÌ[´k¦`FÐÜv¶Ì×êzR›wp0¨W³³²6Ý•ELC›¯˜šÕ½=©Sb[Ôi8†æt:Fx!ì–¦*{ 1\w”À±à°›Q8ðÌ?+a¡q‹pN°mëê7‰jy«-9g§ÙëˆgŠÿ°ô|!)\*Õ‹—sWã\†‡@†·ñòp‚…rW.ò+”LA7•óV‘Sv±ƒí8UñeJôàà˜½w¦×*jí”O=JZûE¹p)+Zût ³ü”  #ðTYó¡ÁJ²0²Áƒ\ªÈwL ! ‡«0¬‚/•¡Ê¨(ˆdª0ŠP]^…1„ÑÄhc­>P@á®q‹X­~Bn…̬$BVHQ9K• 6Ϫf(ÌÏ !wVÌRA†°š¢‘ì,ï‘ÑyÚRW‚'*4ùhp®(…n 42Wå>*7 Tœ+†C·}T™£¢:ãåx 'eL6ã‚ñ”Ñþ*-!"ŒVÔ™€FZ »ê€§F:T¥Qbj8/øD Ž4U9ï“d¿†î04WG`ýý­Q=ºÚO⺟çITá~^´H¢tÕàJ ¥'ñßHBá~_ ’‰/žÃ~¨t5Ÿ•®rì….KäEîÜk&2TÈZç•Bj7:5ŠèOÑX–&ç™­ÚÚÒœ]’Äh¢fiÍúš¥KF}ilžÙœˆ©gÖí!\,К_‘ÿ“¦[Â>õ½Ò•Ó‡_ÞÅ |x­µqÊ}Ïsè݃ÞK*Þ z/Å%ÌϪž· 2oüî­aÞ5Z[¢jcÃÆ ÍÙUI4êsê™w£ž![Á¯èG2$uV•\·béæt‹wvÞ‡ŸÈ²êb§†w]^"Üs#ܽkÿWMÀ_9Ö l®¯-—±_ÃzÄ‚Û{•ˆáˆEülÛ¹}àÐþÁôãÃýî7ŒœÆSz¯M¾^‡ë廈Ê» ù†ñW¼çöÍ™i.Òs÷FÚnÂJþÆ\Ú{V¾sÇïë¨xYØZ¹Rü ©/ÂÞ endstream endobj 9 0 obj <> endobj 19 0 obj <>stream xœåU]lU>wvvvvöÿ§eéÒ2³SÚÊìvév麵àFm›¶kùqVª°¶ÛRº©µ©$"1è&àObâÏ#ú`4áN»%1©Ñƒú !}0ê“’PR1& i×sg· ø¢ïÞdÎÜï»ß=çž³÷Ìœ >¾'žsˆ{Ñì™È*X¸@ºFf¦e©Åñ)?âS+ŒOœácOâÚ.Î:~ìÅ±ŠžŸE<{8Ÿ]:Óuý]G²ã0où ÀÂü7ž˜ž­Æû˜™c“#¹j¼ef&r³¢ñPÏtòñÜD¾ªO¢Ù\˜|~ºŠKl½0•/<ÑüÆ×¨ñÏåågðlŸqç¸ ° ¡â0Ûaíi8ï@¼ 'á-898`7<Cð&ŒC ØÝÐý‡iHOÃ,tB/ ÂV8#pöBLRˆR ÐæAöÏd)¨‡¨ é;²&w2+_§$ЊQ• N-F¹èÀÞ­f•µD„dšÔšÉÆ(e[U9¡ÿþ6F¾^ʆU…Z5öÌdÍ…lýY£®á§bTˆò F—_S@7¶¨ÑhR™uJŒú}r:£ö¨|’ùÝÈÔ²¥O•)ßÔOaP/æ‹9™M +J6\4ÑP±€RåtÞ°WAލü½™Ž3*Ç©MÖe¹WíÉ•uyôÙŠ ¦s±ÈZ.ʽŞœZ”‹ªNeÎi•˜#h&Ïîq›‘v,†%,/± ¸©O³¯z6Å”y¢ª¼X ®ÊúÀž°BIV/bB}jQ•‹}E5Ç6T¶°WŒzÙÏàÇsûXlâÿGEöRsGÝ› Ûˆbų¬lý£jÑFåA½+¼±ëˆ=eùpõøÊ&ýyu5"\cÌ}ƒ3>Þ炃l+÷ö"ÿ )¿LÉ9 â nr>kô°ŠS/^¦àNNgë±2Ã:PAî¦í1껯€ÀÓL,ÉÝs޾*°#’U "°_ªQ®BUgndÇ9ͰôÌ t!t»×¡‡…rž*Ã:ãE'¾}½õëÐÐ\ƒYÌÕ HÜ-n³ÀNðÀm /ÙHðTŠSg{‰˜˜PoœÂb‰w™«B‚òÞ9p{5êI”,Ò·H;ê Þy–§|«•: ›ë.O= † žµR±•§Â‚ávݵRi Þy« 4\ÑÙ¼•w4+£íë´ ÍÃhÉ;ïÜHKnSí¨¨‘v­Ó¨v15\æ­‚Ýár{Z«ƒ\¶ÚD»äpºÖš©#°­-åS|[ì$ Ø-⓸_Vt\½©rM«K«K$@¿‘ Äý¾â#AX¹ˆv|õ&j¾X½É5³ “)kœŸû¿cça®“­Ô,€ËÑ/µ Pƒ3[¼äÀ…³P‚ЬFÄuoÈ¢ÏðxoÐÖ2åÕ Íuc.¥IÚ<¤Úìݹhx">¿á´¥Ó4å»jhn±v6nHSÍOÃi0:Û}~ª¥ [3ª ‚*§oÎZÓN§1·äN.%¨‘¦dG{¢vCßž`“š ›³ 5Áî!ÂSlO¦vrÛ“‰4eRÛ67ÚØZ»Qá ᬻú‘§6²IË'æ[:ÛâÑâT¦!$sû3ïÖ^ºÕ1:”j“=r}Åc—¬Ã‘P°¾¶³ñÔ ‘äFç¡]½ûŸê |]}ú5¼yï“®{zuÅlÚ:|„J÷þ¯Óò¬ˤ\^³ˆy¨Ô‡€ëÇá ¯À£»÷íÉO‹=2ylÔT×±Ãÿëï‡Ë°\¾¨þ"Üüb áÿ±å_ü™úùvƒ^¼rÐÓõl¶üʘ«/ˆkoü.O ×ø¨Í> endobj 20 0 obj <>stream xœÅV]hW>wvvvgffw6›4‹q&“ŸÕ™ÝÕuM\M°Ml­ÁßY è6‰FI4Øh¨´ÛØ--R,EðAÚǼ³k±HÁKñ¡B‘’‡bßZÚ€Š¥*%IÏÝ]-´ôÍ sîý¾ûsî=sïì?¼.Ú¶#•†róþŠf÷Èd~ª‚=§H×ȉiM¾æû‰[øL˜:8yœOìÁ¹!Î}pâ•=ÿâïÆÇò£wnužÇ‘ìGBå{\6â–ñÉé—+z±‡%8:’¯æ{ 0™yŠ˜ü»¨gX;’Ÿ«®oMëÔѧ«þϱù©ccS»o|uõçqMÁ¥§Ñ~Éã>U,´ÂXÏÃ~ÃÑqxNÂ)x>„肃°^‡)X o»†30‡` ì†8¼ IøÎÃ{ð4ƒ{¡† †Aƒ—`;L€ M0 ujC68‘£`t7PÁ´7æÊÜÉœö=%j²!A‰¥ý@}f‚rÖàv»×Èé ê²5h´gÈÖiO.Ay‹¹ê†þªýcìF.†:{!v'3tê6mÚw"WžÈå0žÛòïMPÁršÉiÌ®ŽQÀ0Ëi)S=5Êk…CZ6• ¢¥dI¾Æ0uµöåÛ( Ù…±B^cƒu1]ÏÅ e´½‚XB©²:%¦èQ¶´›åíø,-E=æ°­i›¾üaÍÖF_¨„`:?ËŒ©µ‚¶¹Ð—7 ZÁ(§3XpÚƒJÜ#hÏè(gÚ8× ë1m®€e@§~\Í®êÚô²,hÚ\5¹¡Ùƒ;b:%9»€ê7 †Vè/yæPqa]‚*ì5„qÝ!¶6ÿcÖùÃûÝ sU-ÜDa†•m`Ô(xØ îŠÍæìHâ½r[ü® WÿÚ±¸M8 £ð<Ú8¦A{¼pŸ Ž0WWÞGþ ²ô%ïÁ õÙ!ïçœ>VqªàaŠlÇÁ¹eX™a¨[ë¥.óYêÕz‹î g–Gë½^òT±€“­«.~dÅ^Ît\}'úúWÔ ŒÐW_ƒB9Pƒ–A|} jL­5¨ ®¯ÁB%^ƒa„¡å5¨" Gk0‚P­{sn@âîr XDðAîBQâÁ¤¾5—ˆÒ¼I!uÉSyÓ„*) s/ÍS!My¥ŤÁ´ãB&4G;Þ7ÃS>馾YÇS÷€§ÁYGðθ©7ÉSaÖ Ô=pSi– JÉ-xU'½©äæ}ªéf´X£=%É-ª¾Nµ†»öìmN4FÂqqù&-ºL–y)ÝN®kM¯Ð[B­jcÇS!Ù'‹‚ÜiÕ¯íjïÄÛþ1ä[Àn¿«üñhÄG€'ÑÈÉúoÇ_[fy¶®{/.-=´ˆy¨¬–@ëÇáHà™­»vŒ;t ±éèÄhÿt~âÐT”ä ~Aþoó>ïÁ½¥Çˆj¸?A"¿ÀÎÊ{ûVÖ—Ö8ôâ•}Á®û°ÜÅþcÁ7û. >ìñwâ¸p–ŸÄXÞò~°ý Œû÷k endstream endobj 15 0 obj <> endobj 21 0 obj <>stream xœ­VëoW?wÞ;3»;û²×^¯=ãñsgvÝ®_YÕI¶4qqÌÃÄjÙM]’mlç¡8±RË„G!BP;‹(Uÿ„øŒ”;»Eý€ÌC(BT ªø"|ÀR¡"Œd›sg7nb„Z‰^íž{¿9çžÇ}Ì€ Üf>?;”¿©¿Gñâù¥Êrtòƒó«+fà—øþÏ-._Xº$d¿ˆÏ&8ñ•¯,6ô…›ìq¡2ÿ`êåv­„äØE$¤Ÿ ü Ä=—Vn4ôµÆ•kç+M~K•Ë$'¸¨±yµ²´ÐŒïÇ(ìåk¯®4í°çË×–¿>îÜEýuÄÿÜ?ºÿ%Œí7œSˆãP„ÏÁàE8 W`nÀ×PÞ‚7` fá*|^‡eX‹ð]ø6Vä:¼«ðL÷à2<ÏÁ$…E(ÁË0ä)¸bÓ´}¦DO­–)ØÇ“TrJGË>÷ZÙ|Ÿ’X.™¥Ä5ÿHu'K9wúté¤]¶²”w/%MZœ)Y´XÎRÁe¦–m}µt7õn9…z¥ÝÔýrʶ¨è”èäjÙP.ã|¢œ;“¥’ëu“uôn®ÏÍ¥(à4²ëõøTñ€RÜhÄ, eiÀ5_cN~…Ó˜”ï²M*ô¢0Sª.T+&IYV9UõÑébÕFtFʰpFÍ5ßóÓÑ]sˆÊÎ\É4Ÿ·'+—Í’9ÿJc ¦džÑµY5Ÿ¯NVìªYµ}w6›œQóc-.0€6!ßÓÑ­¤e¥Ì­*–¦0šš±Y¾Zصͭ¦sÛ,MϦ,JÊ¥*&4eWm³:Uµ+Ì aº,5Ø2D1îK€ ¢‡¨²Î®\>÷x&Ì4æbÕ5V¶SóvU¦æLi"µYβí‡gˆÿá…;ò¿»7.ßbÌMð6pko€œãÌ”ûž=á§dÿ;”|¦©2Sòy£ìM²ŠS7Sü4n–ÓX™¹PÑ0QÆD¸Ä‡L M¢çÁ2Ö@Tî·‹U°::„áÔTª{DÙ¦0äÉØ)yB! [B4Á¡Rž F B†CÃù ¾AF¶èX»'èkr"Õ7=9¾#Ðð¦')k"Ur•6½P|G¤ê&•Œº()1*8Y]ô˜#2:p@Ëä0£U£®©!¤Õ¯­5´‘ШdÚð¶ J- çš¼-ÊJ@Õôà#†Û <õôxÄŠôHÌ ð<‰¨Ü_wK$¾wÏæúöîïÝ'1û;‰«Ü?vƒ‹$Nb»·Q^Ø»‡:¿Ü»ÇõãÕ 5î'0YÒµ~«®IXÅô`¿thfØKkÛ´«˜¢C~™8ËÄå(¿éY­;ÔÝôÜäšg¹ u ‘&7=5¹Cƒ›˜u0æÔu&ñI½ÍM"l÷eÊ—LR˨§-7æõNÖÕ»|i2)ÖYǬ3L·†,;Q¶ŠD ´«@; 5tó§jè‚RÚV€b˜ãõ «jɶöTg—iåžl¤c éÁÌÿVz¼ì#ã±cä’ïäZc-‰¸Cºsr¿’q0>ÌõKá}¥=}&š4éwBïh TTI“ÃÒÞ_ä°¢)šnh½}¿ý󢪦d;ÓÚª´¢»5]LYŒh鄉µ¤õ° Ü'==þ]ïJ2Oþ}ƒZ®T-Ìãr Ã^Bß&´Ÿmq¯3´MÕ<Ø/œˆD©Z`ûdd Ãmí$­Ç8´¤I\ö“p(ÉFÞ7Ñ–°RA™#Éýa”EiÐèÎ˼¤ë†“Š:äËi#¨}Ö€¢êG4YE=oÛn'‚ª”Ľ4±ÿ§qïAŒ@jIa…×#n×ÜQ5ãõò";êÛݦrž¶ãaÌŽB8†,`ÜñÍD<5Z(€×“lù ¨¥Ê‡I¥ÉØp¾µ%âìîþaKÐÚ)çñ£#£#9Þî–'b)×=þ™ï÷h½ÏNfŽç•H,—»Å |@RzH1³ pj| c(“ãV[’îÎÀZfý\>Ñgh ‚À+‚Ì \kÇhWZä;í|*a³»ùGä¹Ãý{škÞÜq¼Øbá· ‘àÿo‡ßÿÕøC˜ûœ~‚MÀ/"&ý÷ØÃëûû(Ÿe±#¿l‡ p¸5 B Š#6– ðÜg_˜­\}uváú¥Åì§®]™÷#!oâ[åã6åIøî?A43ãþ…o©»!+0Á=gø£âõíêýýÎÙðÄÐÅÿ1¿>[?êñ[áÓò-á-ÔU-ø›76® endstream endobj 26 0 obj <>stream 2015-01-28T14:21:20+01:00 2015-01-28T14:21:20+01:00 cairo 1.13.1 (http://cairographics.org) Untitled endstream endobj 2 0 obj <>endobj xref 0 27 0000000000 65535 f 0000000695 00000 n 0000011395 00000 n 0000000636 00000 n 0000000476 00000 n 0000000015 00000 n 0000000457 00000 n 0000000760 00000 n 0000001514 00000 n 0000004238 00000 n 0000001125 00000 n 0000002570 00000 n 0000001896 00000 n 0000005969 00000 n 0000002306 00000 n 0000007819 00000 n 0000000801 00000 n 0000000831 00000 n 0000002782 00000 n 0000004445 00000 n 0000006199 00000 n 0000008047 00000 n 0000000894 00000 n 0000001286 00000 n 0000001667 00000 n 0000002061 00000 n 0000009953 00000 n trailer << /Size 27 /Root 1 0 R /Info 2 0 R /ID [<89F4D9C1E94E6B5AB61BAEFD60E54FD7><89F4D9C1E94E6B5AB61BAEFD60E54FD7>] >> startxref 11570 %%EOF arb-2.22.1/doc/source/_static/arbtext.png000066400000000000000000000177771417376376500202620ustar00rootroot00000000000000‰PNG  IHDRM•Üê¨2sBIT|dˆ pHYsNNB‹“ütEXtSoftwarewww.inkscape.org›î<|IDATxœíyØU•ÿ?'"@}QÀd7ìHØTP–‘¥EDÀ…M@qA@~‚Œ0ìPüÉ.8*aG0 {X†E²„Îüqª“~«»ß®ºÝUÕÝïù9ŽS.šmXV ÷¦¯ ŒéÒígnnîŽTgvéÞŽãT̈ÍXda`k`bòZ¾Äæßî&—FªO–ضã8]f`E3™roììÌ_mæp70 øM¤úbÕq''š±ÈG½nñ:0 x xàóõ'üQá`,æê¾D@;×?ŠT¸Þqœ ÑŒE> |X(ãew'¯©‘êóõ'LYóƒ”sû‡`ÕÝTç8·Ç"c€%¯OŸÈÐ.~©>‘±ßŽãTDß‹f2 ß 8‹tÇKØÚâd`r¤ú\»ûgÍýšX Øø&¤2Ì%ïçÇ¥…ÛqœÞ¡¯E3Ù8Xw˜ÓÞ®ÎnŠrþ‡CE³I_—vv>3Ì©ïg?T_ÉÓ†ã8ÅÓ—¢‹¬ œˆxZñ p&0)RÚV·D³žXduà`gZ>ßNNTÿÚ–ã8Ý¥¯D3‹‰Í7yZœ6 ø!pa¤úA§m!š5b‘µ±e…‰Ãœö<°c¤zw§í9ŽÓ9}³2ù–4~Íó-à'ÀÇ#Õó»!˜E©Þ©n|KEjÆÒÀm±È>åõÌqœVô…hÆ"[w+7ùøà|`•HõØHõíR;×"Õ›"Õõh^O}>à¼XäôXÄkÕ;N…ô¼hÆ"_þ€íOs#°V¤ºo¤:­ÜžuŸHõJàSÀ×€—›œò-`r,²X©sg=+š±È¨Xäà?iœŽ¿ ì©n©Þ_~ïŠ#R©ž¬-G¤Ù¸'Yu§dzR4c‘W‡5ùø1`ýHõÚr{U.I鯨ÒCše;b‘¨Ü^9ŽÓs¢‹,‹íÒùb“'Œ”3‘êÌHu_lZ>+õñ‡‹c‘Ëï™ãŒ\zJ4c‘U1G 5š||&°m'9—ýJ¤zao¶Îyd,ÒlDî8NôŒh&9˜×K¦>š ©©¾_~ÏzƒHõvZ¯sž‹l_r—gDÒ¢‹Œ.>žúè à‹‘êiå÷ÊX z–¬†ÿ­¢/É:ç&@œúh0)Y³ü^9ÎÈ¢'v%ërG¦¿|.R}¸‚.õ4ÉCæÌ¤žçõ!ýÊé_Dd[ìá¾<–*X¿Ux6ö{ú0pžª¾Y~;£rÑŒEvÃLyë™l©ÞQA—ú‚$ÃàϘ]=÷›ôc’¿ÓÿˆÈ5@Ö¥¢éÀƪúX]ê:•Šf,²)O»ª©žYA—úŠXd9lûåâ©®vÊëè4èˆy®.‰ù­gÓ0x®GBU!"Û×ç¼ìfUÝ¢ˆþEe[ò‡õ«i̳]0³©þ=Ù¸KAªñeàçÀQUô«—‘„¥m-pýëÀ}ÀÕg>íØ ä¥}àQ£’@PbÐ{9¿Äwb¿ÜNF"Õ»°:HiŽL–>F,"²¶÷D3aalÖd1§5K\3?V2»o¨*zþ l·K=Ó°)å{ô§¯‰T/ÞҜ›pŒTN6ìÒ½æ.«lê4çC×µ[*é)JÍÄ€÷ Ôᙘgä e÷gPˆTÅj Õ³ðÝ ºS9b%¾ÖåÛ.ü Ë÷túŒ*FšÇ7i÷ dšétÆ×°tŽzŽŒEÒF‡>òŽýD¤WÊA;PªhÆ";¤_›¸ú8’¤ý0ux p\Ý© Y«ÇTã ¼·Ó”=ÒpaÁm:u$£Ít$=JLS‰ñº^U_QÕû€©íîé;„FE‹fÚeçÆ~]Ë‘…Ed.Üg­ þÈÒe€¶+¹…ÑA¨þÞ¬Tr< 4Â(L4c‘Ï+¦w2 ª 1³äÇi\Ÿ áÛÀ#bKeq=æ’]ÏÀˆ&a 0tÓ¸Œ‘Ÿ¢ Ši~>õþ]ÌQ¼Dd ¹DDΫÞê¼…Däh™”8á´»ïzÀÍXº¢ù,ò¦,íwƒHupmêðÄ2Ú.‰Œ€IjßTõEÌ{3„ÏÊàלEŠæf©÷“ …­¡”|='"ÇÏ`9¢»ÃV¹‘ñ˜YòÀîªúF§LÊ'ì†?Ü$"éÑxQÜz¿b,²rImFòP[#àÒfkë¡StðÑæˆ¡ÑLŒo×M¾­ˆ¶Ä¬ÏÖ¯;´MmÝPDƈÈÑÀSÀ±uçµé‰U|¼süþ‘vѺNUï~,\ ¶Í´hnÒ5ƒa´2Ê|HUÿ§ÉñßaÓö< 4B(ªFÐ`ÞÔ±ÂDxx+šæ=)ѢͱÅú4Êðù¢?¶žþ½k=ËIÀ~X©Óo§ÐÆ"Õé±Èý MË™üºÈv‹$ …ašŽ(Uu–ˆ\pϱÀ¿RbvˆˆŒÁ'K 2×}V áµayî¹ f߸&ö÷´6+º8ZUèNï3õåCØ.¶O'¯ÕE°¿ç…±ºXoo$¯'€¿¨ê[Eô«(ÑÜ,õþmì›^ªª"r9C׿4Ì%Oªê›}˜¬‰ÖºUDÑ'Uý@DÎÀJ2œ "׫êSÝn'Å ÍBX½DDþÐ{˜}^+Î%L4Á¦è¥ˆ¦ˆ‰- wÞàÐáŠÂ‰muÞ3nn•ëúy,-ëÈ gDDæ¶vÂÄ{Ñ6—Ô¾QÝ×ïˆÈõØÆ…«U5íÃLQkšéÔœ;#ÕÐÈdVÎÆFmrÎ{˜!ïê­3áH`,øsn—ûYÏùIcht*‚´Ïæ’±ÈØ¦gö!ëˆW©jË)¸ª>Hóß,L(# $"[b5¡²†¬\Õ¬¶‘ˆŒ‘ƒ°ÚÅ´ßPظˆ,""?ÁfŒ×c0Ú æpÌìŒÅ$î‘t`:˜¢D3½×¼°Qf U­ªg©êþX-ð´pOÖWÕ«ê;­î#"‹cÓf€ Uõõbz ɽk£žÄê˜I³©Új·Y"²>a ´‰I3:yP–Z¿ý)C•užƒˆ¬ü8(ú÷®ÇaÚc°éw·Y¸ND.‘;½Y×E3¶áõò©Ãw»V$ÑÔ‹ZáîWÀ:ÉÎvÌÜâ¿ër÷šqMòïhŠ/_ü(Á RÒž DœžÂ–(Úq)¶¤B¡ôßW戅ˆ|¸—ÞYžù:ð‘ÚÙ ¸K:Ì)b¤¹"­þ·€vHž"“°r«ï;«ê·‡]¦¨­…*PF±·»°²`Ó‰ÂHjý-u¸ïFšì:WUÓ’Ô²+îÚ%ðÚ¬Ì×þ”> "§aKAé@íHaUàO"²Xè ŠÍUš+E4±¼Ë%_O6WÕÌ¿ü"² sG^SUuFŽk·‘KEäq™‘ü{i»²É½VòcÅv =’zÿ±¦gõ6ÙÖóêyŸ|y˜½>EÏË‚Ià±4Êâl&v.ð ,ÈöG+®æeEàj yø=_!õþ­2ꙋÈ'€½’·/ªê“9oSŸ·ø—mÿ[—¹[PŸ†¹;}ØQD¶VÕ[†¹Å_˜ëµsE´Ò?‹q¶U¡æ™UõVy‚°àdž"²ºöVý«ƒhžz—‡'ºÑ‘6üK¿»²U6I’×¼°'V¶:dÔ<«n6HoK#Ít Hh²p^¾‰­c¾ ì ˜`©52壉ȱoüŸ€õTõ8U=WUþû¶+¡[¿ÖÜÈCzôÜéR©t:;àšNJK÷Úh³‚yI7:Ò‚éØ g%U=y¸ô;5îTÕƒ°™áÍm~?™]æ¢åHóX‘QËÃB7L§ ¼{A@ZË3ðÆ1ó#“µÌ½“·v°{§~ªúj†vbnåÇSµ.­*I 9$yûÑ6·ªo+sÊÊoE~khÀ«-£í¡RϸŸÏx{Õ÷ò^×BÄè9Âö•_ˆ=ðBê*í)"G©júûÝLÃf;cô›Uõï¶w°·ª¾’÷BU}J¬`ào/æ¼|,bÿõ<µÍU`•Ùë_!|b4¼–÷¢Uì òhÆÓ7âƒÐYrq½àgYÏÜŽ¹Oðt†@½iÈoÚܧ¾­ÌÓÁ™ðÌèÎGË…ü|Þµ2&tØv.’\ÃÐù!Éͪ:-IÞ> ÍqX@èâ€k«à5líð×%l²Hs]ˆ`ÖPÕ™"²7¦y<»‰ÈašÃ£´ºçS!—%:: õ¢™%?s¥º¯Ï‘OÖ½¿K²?‚öÛ0ëE³ã<²fò€> ³ NÈ´¾F¯MÑ›ñ&–ê¶´ªQ`vU}ø—ŽÁ¶¿ffPD³&^¡kµ}®õÓÔ,#Íë¾þæ“ù‚ˆ\l­ªßMÖgÒÅÍÒÔ·5*ÙSì4bÎqƒvV*ú¿°é}%Iä½ÊŸ5TõŒ)y½Ì•×í”çäAÍ—:âcOœúõÁ,¿DWé6—vþ’r”eúœnk¤æÐµ$ ›¾Õ‚NFŠ$ÓúA´Œ;ØTUŸ®º#ÝBUeè@&+kå9¹åšæhxnvjëUFöc¨ñãÀQyo2:ßÓý`¼ˆ,Úp¦QÚÁTu†ˆl€E×krÊ®Ø÷¸]²s½°~@¶¥°éjÞZ?_bnjØ÷n¿çG3kµ" e¾L£ùrçb.!ƒŒ=Eä{=º8¸Ã¥¬^ålà’‡ÅEdɬ)i-Es›R^³qb+ Q/𩿾ON¦bÎÏ3¼ƒMKTu¶ˆ¼ÍÜ5³LeU}BD6¶À¦èa9dµ?°Ed‘dÍ¥õ¢9#««R¤z}–óê‰EÒé:¯–ðóéˆd´bwA½;{(ªúŒˆÜlpù"ØN¯¸Ó~t‰)@4 ‚ &š›\·fÒ–"¦çéHlÉÓµ$â_$J½°µì·ˆ, "‡ŠÈ™"²¬ª¾¯ªRÕ£TuCÌPáÙºKZ–ßH¨è¢óZÓ륅xv™@Íœ#+ƒ:z@Ö/[ZU4óÒO¢™ ”!š7b™‹7ŠÈI"²f€#zý7|¸‘æeض®o`nðCPÕ)Ì58žM{Ã’ú¶:Y—ÍÂâ©÷ýPƒ>DtnUÕnnß½ÛiÂÆeÕƒjÃãÀäª;Q0/^—Ù]© Ñœ')ÂîiÉzÑ¡ÉÛù°„ó{ŠÈTù½ˆœ."ß’áûòPÝ×MG‡"2ޡӴVkUµã7ex²× Ù½mÎí”´m_O§˜TJ“Ló/èà½0Úi—³&–K9gÝ3‰p×ÜÆ‹H+Û´í±Qé!À³"rƒˆ\!"`#· Égßi×gYš¹Kww£Lð0¤G™ÐÛ#ÍÐÐ~Øh³ˆ×©zŠ’ÃØo„–ÕÉ,šEV›ÊPó‹ÒvE$é:çç‰È¢À2X e~lj½<–’°mòúC÷¸_lœ|=«Ÿ’nã`ÙK1Z›²_‹Õ—™œ£^}´¿è}Êé$^¥»¯Pª™n³‰ˆ|2I®‚v;ÓsÈ¡…EŠf½ãÈgb‰J^„NÝ›E£O‘ݱ¤ô Ís¶^Œ6† ªz;p{‡ÝŒ’§ÑÙΓ,lšz?5j¿Å³’M! ^gà°ª;1À„î¦ËœzWÔ6Ê´ïbôÞ@mípHQ©$Zòv›d´ZÉô¿¶à$UYT[ ›¤ÞßRp{0h£Ì_ u w2Ñ·¢y3k [6;± Dd¬Ø4Oñ9 }ÎC†uÉø6ö3x3,.ŒØzéÔá[Šl3”@ýÀ¢TdBE3s~g!¢™7ݧOlvnˆÈ†"rˆ\/"/bª°5ž†hh2âÛË8¸MnghŸIÚPÌ€5´úaVÒ[˸µà6C õ !iTN6– ¼.óÚ~‘.Gé|Ãã ¦%ItüJ̤b;æ&’+°—ª6}¨êÀ/±}á§5;§CÎÆ"v?UÕÿ*àþiÒ•.§FªÓKh7„Aš×Ø$©iåtŸÐ„™E³¨@˜hÖ'v/|b’ŽÛ‘Nx}8LUÛùï<ÛCD®WÕK»Ñùf7øI7î9±•+ý\êð5Íέš@·P~âÊÀÚ×îÞž8Fh¦Î_³žX¤hÞý×o܇’ESU5‰”Ž%¾Þ œ•ÅBNUß‘í±$ösEäiUM/;ä")Ñ{*– ¿kVG£ùWÖ]y@È(ó à 9Ò¼ºBb0Zqr/9º„à߈!™U†Œ4ŸRÕiYO.lz™ykÚk›X$tÍ!U½MUwPÕ]Tõgy<7“}ã_Äþ/'v¡;?Ŷ{nÞ¡irvK½0R}¨é™ÒAè’²@U§2wwX^ÅfN÷ؘ0ƒ ?æ9¹hçöt Ô_-¸Í®£ªo«êþ˜gf§ìœˆw)ù‘±È§hÜÅ2©Œ¶ ÙíŽä “B~ê.¡Ú’kSI¡¢Ù“8]N÷€*BÝ ¤¢a÷ÈÉñ -ã¡ôîÔ"%UŽ‘sDäYÌúq†®×çáU½/äÂ"ó4ç©ÎŠEŽbh1÷y°ÊvŸ]tÕÉÿˆTŸmvr"STõŽ®÷$œócZY4+›‰È*ªZ´!t¿”º‡­Å§×ã»ÅÏUõ—¡—5Ò$R½ ¸-uøË±yR:]"¶©MzqûMÌî®çH Ž…€r/à‰ªÎ Ié“DíO™CH´þ}c Ýæõ‚ïß)ï¨ê÷;¹Ii¢™p8O»SâüU#ÖìOãÏ)‘jÑ¥CÙ(àš¿¨êµ]ïIçœ ü=ðÚô6×á)†÷\ én¡ëåelL¸X[UÏêôF¥Šfd¥m/I^ؽÌ~ *±ÈÀ¿§OÇÊ ÷*¯å<ÿew8õɆ…¯6ÌSæä2ZWAmÅE9Ïá2àùœ×\,ùTáôõ(¶Åv+íÒ.¸²Gš`&éø¯bOòíˆXdú`BÔ¦"2«ß4ž¡ów°‚`Ï«jhѬJH*“®Dëï[À4U ‰Ä—uyPoSËÚ®›&I#[ ê¤w¤= ü­UºˆŒÂLË·>‹9IÍ?Ls/`…§$¯›ψB¨J4Ä\>™úè6`b¤Z†sD‹œŽÕu¯çe`Ž˜;N&’ÝB‹Ô½f3°ÀÓŒ²¢*M˜S~á.Ìí¥ž "Õ}*èR_‹ì œ›:< Ø2RMg+8ŽÓ!U¬i©>‰åh¦G•{Ç"ß« K}Glûµ›%Uâ‚é8ÅPÙH³F,²¶h[;GíÕG,±íÓBcM”s"U7pœ‚¨l¤Y#R½øyê°ǶßI[€á4 æÀ7Ëï‘ãŒ*iœ½Ò—Ó¸¥r:6â¬lª™D¦Ç§OÊ÷ŬõgàZs°v¤úbù½rœ‘Cå#M€È”{O,m žÅ€c‘td¸L>…¥4Ô¿*1‰E¾Œ•ÝM æL`GLÇ)žžM€Èê~oOcbëhàôXäü~u|ï±È‘XQºtòú»Àî‘jÚ!ßqœèш¬"ÜÖ4ß[»7p{,²L©ª˜XdžXäÌ*$ý°™Ì§~—”¨b‘•b‘ßwÍLLNvˆ*ÚSì8#žÍ‘ê%Xøf{¨¿Ü‹\‹¬Pf¿ºM,269xعÉ)ïDª‡EuMÇé=/š‘ê=À:ÀíM>…y>‹ü2Y¬ÔÎuHèùfáu0o“ÓfÛD]0Pu§3úB4"Õ—1wë3h^ëd^à;ÀS±È±‰“RO‹ì<ü’Fã°ÿç%À§#Õ,…ŽãLOìÊK,òàx,XÔŠ`.æEª/uÐÖšÀ½©Ã«†–ÂÍgp7`?Ì'°·‡'n÷Žãô})š5’Ô£Ÿ1|™ÙÀd ®Î@é†hÆfªº)°/°Ãª>©^§ŸŽã”C_‹fXd;lä¹f›S߯òoÁ¶#>µù„Šf,²2æ<=Øs°ŽW°:)gFª³Úœë8NE „hÂÓ¯ÿFö½á¯aÁ¥)X¹''êKn´ÍXd^,5hµäµ:6í^!cf§ÇGª½^ÕqF<#š5W¢}€CUoó:V.¢VZ4=‚Ší,Dë0Ãñ4p!pž—¤pœþaàD³žd”¸;°+°lÅÝáË1Óå[Û- 8ŽÓ{ ´hÖH¦îa.J›kaîIeð¶þà&ßÉã8ý͈Í4±ÈG€ XD{C¬ÞrÚ£2„ç°=SûÉ>õvœÁbDŠf3b«»½°ròï¢XjÐ24nk<³¯{-y= <©¾QZ‡Ç©Í6t;¹Ýqœþ¦o¶Q:Žãô.šŽã89pÑtÇÉ‹¦ã8N\4Çqrà¢é8Ž“MÇqœ¸h:ŽãäÀEÓq'.šŽã89pÑtÇÉ‹¦ã8NÊò”ìg¡Ñþ©*:â8Nõ¸Ë‘ã8N|zî8Ž“MÇqœ¸h:ŽãäÀEÓq'.šŽã89ø?jcŒiû% ìIEND®B`‚arb-2.22.1/doc/source/_static/arbtext.svg000066400000000000000000000127001417376376500202520ustar00rootroot00000000000000 image/svg+xml ζ(s) Arb arb-2.22.1/doc/source/_static/arbwhite.png000066400000000000000000000065351417376376500204040ustar00rootroot00000000000000‰PNG  IHDRÃxOrFbKGDÿÿÿ ½§“ pHYsww¯’`(tIMEß %.4î‹¶ êIDATxÚí]iÕþî0,3 AP £Ôüˆ ƒT!hRq7X)1Qq‰KÄDMÊRâRRq©”–‰b\Q%BÅ=â‚[âŠJ\‘QA”eXôËwžÞ\ºß2Ó=3ýÞ÷U½z<¦û.眯ûnç@AAA„¢pAÇäŒóþë2ç\‹$#T#¦ñÿÑGRé8ÔH‚ 2‚È "ƒ ˆ ‚ 2‚È "ƒ ˆ ‚Ð6ÔJíÛ]dŸ&û\v>É4XiŸfçÜç’`úÐÙ¤t ¿À¡&ØÛ ¿¡ E®0Àƒæ9çVKÊ"Cg&@o‡Æ¨O©ª¯< `.€¹Î¹Å’¾ÐЗä’‘ÜÈòð5É/Øv¼MrÉí¥½:jt€sŠ Öx Àû–ÚçCû^`*€«½ët0@ûÞÀƨ+R×L34ŒÚƒŽäq$—xRIòv’“4…Ê+ù7É:’ãI^_¤þÕ$Ï+V· ´…‘|1Æ×œEr"Ée”Ùj’{‘œNòõ˜6­ y ɮҞ †‘¼?Æà>"ù ’Ý[Yv›{HÖ<–ä{1m\Br´4)´•'Üa`ëH^B²gËOÌÓd7’§‘\ÑÞ-$ÏF…ÖÎ .‹Yº…ä „êIÜí“dÉßŬTÝJ²NJ^)"yo„!=IrdÂu¥æMr[’èÇ‹$KÓB13I¾8¥úR@òL&ùø„ä(i\ˆ3š$—F³‘ä±)ÖÙ.Ñ1HŽ6øØLòi^å@›ûøŒä)×Ûn¡bHîHò¥ˆ9в!o$ƒI6Gqصêž@rŽ÷é™r}u6‰ö±>é¹M"ÔE<-Ÿ Ù·Âû}eÄ~É YDu“á¶À(žoíZÆú]±‘øRÚo&¡óÄÙ1|\MOG’=#ÞŠ÷‘”÷c•al°Ü¸‰äþU(‡+h—ËBªÇv!¹*0€_W±Wú.ãXþ¦ÚƒÔðÆ´ò¾CRx¾úx ¹ì¡g"—ßí(û^P`“í9ûÞ?E24U*2“ÝvsKõWÞ9ø½¡Äz›sëJ¸.¿Þ~”sîÕ2º1"ÆÀB\`_:çž³þ/0¹$‡{x4â¾¥ö½ ÉzçÜúòì  ”W-¶x¶2´ŒÃŽ-ι Ü“'ÃELsJhGw›ß_fûklɵàŠM²×X½¼ÿÿ¹ÝûEœo²åpËãûEÚ3§äy‘†I•tPîæ¶ž¼W¸®¹tº]̶Ãx½ÌA.Uî>žø~¹½¥*‘!m ±aÃËeÞç/IÆæi¶aÚös,€‡ÍÈç˜ïœ[\ ¿Ü^RU…ÎÌ(>/ñÚüÉê×ÎÀî[RÂ5u6·âA²Åûw±±út÷ØÞ{hðo’Ãsqs¿ÜõEê¸ Àã%¶ýrä’µ¹$ï÷–xß³¢XÇÏ/~Œ]·O°ìáVæ„2ïkôÚs^ ×÷³ì÷»éç¸ÇßžPëY^ aR¶æÚøÛ6ø ɽ˸o•÷vècx£Hþƒä‰Î¹Ïœs3s“lžòˆ]ö£uøy%>I¨¿ážÍÇ"C¶°4ø=0©‚s[\`;ÏX÷“ILrW’]cîÛì ÃúF¡À]Æ87¸w €[ìg¡¥Ü¼OC €ÏR"ÃJ™& H3ʶå6X^àÄ꼨Ãz$gÛ5 #þæÕøSÄßç›·ÞNÚuW ŽLãƒþ)åUÆÈàìHs—¥PÇnA|¡(œÜsrþôgø!ÙÃŽ`/ó½ã¬/SmßáŒ"múÐÊ??Á~žôIé®2Hˆ%žg¥TG’Ú›`E¾&9Ñ»¾É ý>2¢¼},üså\hùÖÞ$yh‘¶ìàÕ»O‚}¼ èS7YWöÈð¸§À…íTg¥˜ei²¶¼'¸f^±À\$‡Ú‘ìýJ„Mò¨4br|O–•M2\ï)q ÉІ$—D¬Ñ‚tÕ&X×SVîá –Ù7H÷õgYV6É0.mŸ†"õ$ù>ÉG L¤L¨®½­¼W‹ù=”YîÑ Çɲ²I†®N’i¸Y˜lÎ÷&²$ù›ˆëI~Jò™$Œ—ä¶`0"áþøþÏk«!-p%âO™›Óˆ-äÕµmù†çµ&æúŸ%Ô—ä‘i¼ùìa²¦œ½Bç&C˜­çøëêBòi[-zË–C»¹ç “jeƒííwm ý9¸”øOBvÈPg¯÷<ævÂ6žfag\+î½›äI)µëEÓ«'¹›,¥z àØÀ6“[…r8Àüª}ÿíñ²ê3„?F<w¯¢þ7©mIrº,£:Éà‚óú$ùn9•;aß{|!èûì$ƒ„ìEÉç£x¢’ìCrAÐç×I6È"DˆF’ÆñJ¡øD Ö=ÁBÃç?=S®o¨EÚð±šä®²!o${XÞŸ’r½Ó‚:û¤X×ÁÅü¡ÅѲ!jeåÓˆU¦Ó³N’S‚U#Z°‚ïIóBœÑì%ﯖF+Sd°8NWDôç’Ò¸PÌ€êIÞa@Ï“Ü#+d°7Ý ý¸# b •MŠs¼lþ¦Ô,’»tV2âÅe q‰–O…ÖÖ!A¢<6‘¼–äv… ¶dzÉíÝ@òiTh+!†’|4æI»Î—÷é(2ìMòÔˆÉ>ªÅm$w”&…$I16f ž_«¿‰äáål^µ– $·±è}Ƽ HòÉ$£q Bh„ŽäW ÂÑ?E.“fÑËß<ØÊm²°' gg]à×YÊ,AdhWRtp"€‰B..S{âKó‹ 5ÏrH "C‡£'rIÌ0¹ˆi`5€Œ œs%}‘¡SÏ-Œ4büÀ|›‰³l°¹T¾¯¸Àc–qT2K®È¥‘mô¾'ðïÏðr©{—hvÎQÒª ívjU(ÅÅ‘ADAAd‘ADAAd„6¢V"èP< àbïw‹D"‚ ‚ ‚ B§ÆÿMÆè1n\k¨IEND®B`‚arb-2.22.1/doc/source/_static/arbwhite.svg000066400000000000000000000111511417376376500204050ustar00rootroot00000000000000 image/svg+xml ζ(s) arb-2.22.1/doc/source/_static/banner.jpg000066400000000000000000002451751417376376500200450ustar00rootroot00000000000000ÿØÿàJFIFHHÿÛC       ÿÛC ÿÂÀÌÿÄ ÿÄÿÚ ú¥$’I$’I$ ‡Ð¢ä•¬Ä„›£{æ7`µ¦k4úï,ÏâI$’I$’Cs7Câˆ×3c÷×yBͼ™M<%¯ÆÏ£ŠaôÜ¢õN`ì×94 ÎË-ÖýƒO~º% WH×qO='å‹0Ü}gúÔ”%€tÍß]å 6òE4ð–Ã>Š)ƒŸÓr‹ôù¹¾vh9­–_­ûšýtJ®‘®â¾zKËa¸úÏõ¤´Ô¿3»(˯tŽ@CP¿'Ùv£¶^_7§¾—EâùD0T3'(¼mL¢ªk7ͧÐav•§LÇèxÜ—•æ!÷”Ñ;ðÔ’o©%âñ©¬s!tTÝj ”8„3|ÔöÉé(¤’I$’I$’I$’ZN˜$’I$˜Õ>åórâDØu)e!G¦hï¾sœÍËí‡u­ƒçŸ´?Âì–OI$’H^Vö[“¯Fhšöøæ¯}óÉ,ÄÉ.q«ÕbµU æ¶1üCgˆÝhEtKroJÉ‘s_÷ß-yß*Ÿ„WM­ˆ¾Ê‚1¤+Ñš&½¾9«ß|òK14KœjõX½M2G¹­ŒwÚb7z}Ü—À›Ó2d\×½÷Ë^A{ʧáÓkb4Zpß™;ÑwöòÜÌëÜQ(rí5£¨ÝÝ¢íÝz2‡WàùòÀ!Í” À_oV=Loº ¥B]. š@ùÎ¥©¥O«fp&‚S.™Þ± z¼I/¼g­ÖµÐÂú04,AAÓ ÏßÐk†ë}¦Ÿ4¹íd’I$’I$’I$–“¦I$’@„Í?­*R8ë?9›ó–U³ªÊh§Øà-Ò=Ѝe²:èMg¡£Ò QLŽÿoJݦ¤’I!ò.K ¯ÕýšHÄï̆H –¥ÕùÇUš·‚è˜-`C1&Õ´MO^Íÿ+]U®*×r¡¾«”ÙÔÍÅ­Ð{4.‘‰Þ%™ ‘W–¥õùÏUš³è¸Mp#}3&Õ´LÏ^Íÿ+]U®*×r­¡¾«“é:\W掔*×zWDd×?¹×8Æ,PFWýUvº‚´6ÏvoŸ+Ü¡&pžT)ÌÛH×&$dúô¶F¼:A¹.¬L]ŽÌ+›ê¡¯ê™Õç«Äš¼KÆ9zÊΊœ•ªÍN½šô¥¢2Õ_,œSžÔ’I$’I$’I$–“¦I$†w5ÄÜèúšäв¯ ¹üœØX5ì-ÉöÀ:¦:ys;<¯QÃéðšœfœ”Ia'mVé:˜ bI$K!Êt4Ýbºšh#³)G^Í*6ĺ>L6?KC-³Õ‘"4ÐÝ’è=–åzzaö­¤X…j§ ¢„>²J™Xâ´Ýfº–h#³)G^Í*ɺ°í¯J9’ÕD™DO,FwDZÛÔÑë|mˆ3=pÞ”@­­Φ ;½nWä Èn[·¥&Æ«õú²"Jõ.”œHÌ>”+ÌÑ/¬#Rç^Œuþ‘Ë#Ðcé=Vwœ ÑåØMŠˆ»rUfœÿ§v:K@çQ×Ú^{ãRóÖ³ÖÁë+º6¾¿’`°äÕ€}¿Õ‘pÝo}ñ$’I$’I$’KIÓUƒÚCž4\ŒfÜ>Ït,æˆ^‡&;UQÚúÃgŠÿ!ƒj#wC¤{èÛ%åžJ÷ø•(bÎ |rôíÍ[´&8ž+œi£cÊ¢½¦(ž?2c\ýQö<TU=Ç;ºm°vty|^oUÈà$6Ý!oÑ“ кs,—ÑmduûÑy]|yë^AœÍ™(:Šö˜’xìÑœsÕ‡XðuAU4›<íîç·ÀÏ¢Ìâóz¾I¶é ~ n…ÓÙ1)qÞK]½•×GžÓl|¯‘*'®­o¡ûjÏK!”×xÑ0&tÄÃjí:ä#vµ(kû—$ÆC]÷š]þl7M™˜—¬§GÛ,–Á3]¿;ûN›¢¦ûãSc÷Æûo†¯¬ú´lÁ<Ê:ùX¢åvú„£‰öê\Æ×µÒI$’I$’I$’ZN˜< Ns—´Z¥ÎhHY€×·ct¯¦Ôà¹]ÁýêÙŠúÁlŸÊK¤¨q†åµ ÓµÒùë¼ñ¾ÃYÙ€~GeÛ}L2ñ<ÿMj¤*TW-—;Î<1D|1ŒEsÅAn;fgÙº¦‹9›­{•†ÙbâuW¡r¶7uÒŒÁ#°ýoZ-bÏĤ̀3jœ*ÓW/—=Íü/H|0ŒMsåÁmû^cÙº¶‡;œ­{•Ùc"uW¡r¸7uÒLÖ‘Ø~¹®³ÐµÃþ$1ç—eðq¯ÕŽ“q¹Ž3Ý;ˆ3G©ˆÒóqæÃ°Hn—µÓ7yïz_=ÂBù¯·>0‡=¤ÈÛ3åÙ¬xÙ#•ï±ïjÔtïõ¬õ•žÈ]®¹Í_2n›IY–ÒÜ¡-­S@½5$’I$’I$’I$¤æØ‰óç³pµàxœ6ç{Ôyô¸gšÆl9CH”ÕJ7¨ŠyyÞ–¥‚‘Íe™¾¿Ï}KÕç‰;™—[¨„vlŽ7¤$>’npß>Sœ¡Nþ†ûó/° Ña{jÉóS±Ww9¡äPë¶!¸×Ïz΋DPFŸK”ÚŸ²*£,g€—$:—’ÎçìÔgÓ®!†ûó}+° ÒaºÿkÉsBùÁWw9¢äPêÅ6 ºÙ,_³¡Ð•¨Òå6‡¬Š!©©ðWW#ÔxQ¢ÄãµYóš Õ4}²ÖOEÖ¸îxu¬NSk€’¨š='µƒÖ(èÿEóî9×Û† NHžD)Ü„‡h–ºD¼Åì¾}®¤ëYëaõ¬t1>-€}¸/G“\öà“.Äì(UÒI \¥xÝY®Ä’I$’I$’I$’“b/Ÿälé/Árý:tiÎÓ£qöñzNAŽ/ܺ?=È\Óg ¼`™#/Ù²ÇÎ×Iâõ/|^¤’ñE]ÁÇ9ôoåplj £@–pnƒ$Òc2Õ†Ã-LïJè#ݰÏ»­¡6;FSšÚÌ×» FÈeõ\Âþ¦«ÉBwM<…­”׿:A+>Ó†ÈPD‰ £@–lvƒ&Âc2Õ†Ã5LçIèT°Ï{­¡SöœŸ4³š‚ì5C—Õó úˆb¯% Ý4ò—¶S_—ém«úŸ õKE2´ú÷ƒ{ 8îrM'K aë\¾™aY|Ö¿Š¼ ¶ë —´‰Âõþ´'ŸìùþnœÖIV¥gÚm(.¹Aß%Èm[“ ô# Ìc¢¤è ”T£â ƉÓ3—Ê?G6\æ¯ ˜‰*_+Pž²—®jI$’I$’I$“ã\a Nk=¥ 1k "G>¾õ¬&RQ“ÐÑ"fâU¦¹æjzKÅêI$’I!£ŸÛùì9‹´© 5¶~®=™aÊ úC‚Íê²YŽñ\âpÒìùnj̳üõ„m3ùPšl´Y^„õ®Ë.¸g@'!š•çíºTEÈ[?[̨õ }!ÑFõY,Çx„ ÒQRí9NibEê'Úgò¡tØ3 G²½)ë]šmp¾€JC ÔøïM†­c«tŽ3é\ök!³åßhGÒz^kµéxlmG ¤ÈÐ×ΙïC¹ïbØÃœìë ¬B9y•n:¼ÓÃ%¨_rÚ‹]×ÅANFUu/[P©ÒÈ~® Ù«C+%slz¬¯løû>If=—AÌϺ¾fÅg3uLå®  ²»¬Åï°4ØÖ¡ëOŽÞåv6¾*ꪒI$’I$’I$’?ÒCHô¼^3ت¾7‚„nr>~L˜`Ûû>àúí®ì¨¦½žôn“ÄïI$’KÔ’^x¨ ·C'm[¢ ¶\SÅ©¬½@ÿ±¨)MDU¨Ëí é(€¶Zhã%^•fON+ÙVÔÔxEsAGÙ‡KÁV‘íÊ!Šå…¼YÊšÛÔ{¯JjB­@2_`ðž’ˆ e§Ž25éVdôâ±}•-MAÇÄ×2…˜ô‘kÈ^¯ò¦kޝ?Cçý§'­ê9½ÞsO”ù<Ìgµ˜¾óoUîoA”[—éš`ž²CVÍïj•Ö=ñ.#}”ÊùFÜÕÝe®›Ïeð¶„x*•Yž5¿Ï›ŠêØ ðÐb®|õOKÙ-cù°¦è|¿K¥™4;tX•:Jž¹©$’I$’I$’VvbŒ–bI°º ’PÊ ‰T£{*ãÏÛbnm³rç‹_–k‘º_¾/RI$’I$¡…GJÅ,ÍŸHRÍ\Ï•ðõª„«RœP+ôƒÙ‚Œ°U–ZŒµ¨¯ÇôýÝq{šÙ}lùùHGN;*š·å;'h¼¼§¥†Fr#K7o>WÃÖª­Fq@ïÒf 2ÁVYj2ΦA¦è‡+‹ÜÖËk')éÅeTVÕ;'(¾¼‡ˆ\äÇ ÙävZ!W‹ôÞ‹¨Ñüðo ËuY-éìï`ä}C¡yÒ¸–£›pÒqÕóžÒ=škV¿¸«ÇMôo´Uƒè!u‚ʾ…›P{sÛuÇÌ>¥x!¶(œ©Y­sã<÷¦ò¦d~›1W眷Ah€?UöÜÀ±×HÖ#§¦é’I$’I$’I$#@?Cf+×ÜØV‚ææ ÅG‘;&S£ÞÔUh¨ÂiÝ%Z{q¾V§¥ï‰$’I$’9÷ê€g†í:òÉÊZÖY¥bOi]>Wk”ÑVÅå¥9ÿPÃô×%ÙÅ6‡Í9‹w'#æk¤ñ9%âõ$—Š*î =Ưù¹`—Ç>H†IX;몔l ‚ƒh !\K)Ô2'z–#­ƒÒÏÂÏfÆ…™æg:uÚÂ>Ù’»ö6Ê–_<§ìøçÉÉ+}jQ°$J  (…q,§QÈêX®´I/ =œNZi Ntëµd™ cÞÆÙV¯Åñç9Èl(j9Ÿz:NˆKœï’èsǶ¾ÅŠ×n²û‘:XøÌÆDÀƒ gg…šR¶éðΉÔèyn¡ ËiŠrÍ,[4DÏN¤ÑE×ô}!±9•Ý’V îx¦P˜} œ›rúþO™Ö—Êút°Y°W_­ÏëRI$’I$’I$’Gú8ngŒ³’¥gX Î+p aÎ/økc…”ÆgIÈ·ø±ÚWÊnmI/¶ ޼ïeºÇÊß_ç¾¥êóÄÈŽÌɬÔE;”Tž×ûåwB9Ô% \ðhAˆŽ0)¸.~¿j^M¢,äÄ´nÓ•”¥«rÍjKÓ¹aï¾Ëã¥ñ°z×ûågB=Ô% \èXB Š0)º*Ç^¸þK¡0ìÄ´NÓ•”¥«rÍjKÓ¹aï¾Íä¶™òŸ(ÏbºéñûSçòv¶"‰ØèªløÇ\Ü”¹7ŽàË.Ÿ Ðì“Áw-²ÔrÓ{¸ï@{_Ë-ipwà˜¸e§{jgv}7GlNl~µ®Žƒéù𹫔mfrñv+t4 }#šuŠ* Ä’I$’I$’I$’ÒtÀÙÐr`qÖç}Ì¢+Ú;Д6˜õ0š¬oÚ Í]Ô ¬ŸŸ§£"RÜÒE5¶¹þ{ïž/`­î`™emõ6?Y —Š:¯®ÏjµG°Ðð/yF‡W·£)™«VçÝ`:&¸»Öh•‹…[x½kÄkY%î¶[,^'?Æ·Õ⎫ë³Ú­QÁ,#üOÞQ¡Öd-èŠæjT¹Çw|ÿ¢k@‹½a¶ÉX¶U·‹Ö¼Fµ’P>ëe²Ä“æoÆøÊøå§’lNeŒ'±Ó²,ßC=šÞ_¾3k ËnAsŽèSÕè$_'è½’7ÔÐíy%³ÙBC1G0ØYªX°ˆ’öŠSÛÍ^‹Æ{çž¶cìñÑ ’µx3wó)¶,èÀ÷¨„µ%Ý'Zö‚§®ñ$’I$’I$’KIÓU¯í*gsu¼ÐÙâLk$1û¼¥ÓÙíçèù@šX:z|‰ŠZ.Ó–g¶?*Öfp\ÃSº~Þ­‰üñ‹Ï=ò?XÇGUõELWª‹Trc y5Æ>V§%}8qyk¸{c:nÎ ¯£¶Ð]‹ŸÜæx÷€› äµzZðš£\Ÿy®5æjáp&@qëyL£çº^R¢òðãEíKVÑn;p…ç«Åã}l^²?cíÕ„MXg£&——)Švˆ¾{µtÙñ3û I$’I$’I$’KIÓ$’C¿šc-ô5r%Yg‚*Œ˜Á}iÞYвOyåÅs2Óôlíþ|R®½’€5j¿EØFL“I/^%ç­Ø(É@<£Æ]çdEãÙˆw^ЖÔs^ŠÐsÂâ÷™Ü|)"ñŸä½ 3¹ÑhÉÛÒ‰+ióÝÒø½ñz—‰yëbö 2P(ñ—yÑ!y²PëÚ2‚z~m´<ð°îw)[ LÃNò>…šÝèt„mé´ùïFé<^ø½_˜ ­ŒM#y_zÖ'ÁšBØNÙ£ŽèC¸þs]Fb^‰™×Ix‡.í™à‚hjÎñÛì›É_3 »À¥Ñçö¦Çí_!(‰ÉÑ{Ž9yêñxÕçžøÏY £¢úð°,¢Æ0\®åªõUt½:95E$’I$’I$’I%¤é’I$1MëJ•Ž:ÏÎæ¼Áå“­lM_ç$ªiyQ@rÔ³¸O!vŠZ˜ŠDúÄ}»mI$’^$’^&Âêc%2 ˜0Rë§e…•³½ó)¨Õ]!%št|Ä ˜1;xî.š?KaÇúMY} W‰Fé¼^ø’I/=l>Ó(eXÌ¿&4Íç¹=F¦é ,Ò¢ÜB „¶e·ï³‡jkøöþ®°Æ‚+¤£tÞ/|I~^“¥w?ç]ÃØ-Î[ÜÌ×ÒS”N×=ªc.Þ–¾bœÇ¹ô½ëT¯Ìr1™OoÝ4.Sù³z`½Ý-ò‚ºN“Û¤c¦6NsUa%©2…x$ B¾à«t:Z¾ÄïI$ßk“=žó À ïÚl=ðlÈm¥t#®‘ŽÉyÖ?ÊÑ’Ô˜ˆ F$¾B¶à³t:Z¾Äï_—‘Õßeïté>UÖYS¡¶¥<Ýü8ëÙo:NAš!×p]hÈ}áR04“Yç™hYlài6½aýZç DÑÚ+âô´P‡êÝ?¼KÏW‹Ï÷ÆzÈÝ×-*q¨$6jÕŒæìúEuô#RI$’I$’I$´02I$’I$’PCèQRH›‹.÷M¾ùŠËX Iºí »Ë3ø’I$’I$“R©_Ñ (o¾ÿ4¥êæÜèû Üûn ›¨+§Ik9&` þI7DØQçÛZ’´²t.S…hgn„䋲Õ+Wô@‰3¤M÷äóLZ¶dM®°ƒŸcm×™º²õôú(³¹3@æOŸ¡ì(óŒm­IjY:iÁæ†vèNÂ\´vìyù¢.^·Œ1Ï÷ÂuˆiÄ*Æ:•¼ç¼$Ù>‚_+ÕMÚ|¤jó2¼ã1LE£€–ë7®-Ouf½Åx¿6Öt· \2 dK“})xñ/=I/M‰Ì…Ñ@êQÆ!”(­Ï¡èÛ>ÁZbI$’I$’I$’KÿÄ+!0 "#13%2@BÿÚýìr•5r•j{+"ùm­.övFöä¯aQz€{( €«¹YîwsæqÕfB‚b_©2ª|‰ògɨü¼vª×ôª9‘ÅÊ ŸV—{C;>ÆÛ’½…åKì .®ågºžX×>oPvd(&%úcŠ8A8nKå¯F5íFÜ'•µR×3²1s†ä¾rí}͘|妯×ä¢CAëf?\ê;?ØMŠ.+ê :õB¬—Ä¡ ð]˺—u®;ª„Õ÷˜oÿÃä5nY¶´ðóv *›ùGaÑÄn§ZüZúœÊ6éœVo…+Hømä''Æ7k@X·wÚŒ¥ÜòžSÎ{%i!›xÎ+‘›þ’Ô«þÌì§uogöñ#ý`DݰSþ°Â˜ß«¹GB䵺SŠà²ЦNIÊ,Z«J‹íFRîyO)ç=’´•MÜ_ÈÍÿIkTþÌì¦øÛÙÓ¸¡é`DݰSþ°Â˜ß«¹GB䵺SŠà²ЦNIÊ,Z«J±Î¢¸Ìíâ¶/by#©nÎI5Ô5ZÉLìCxíÈæ´ÑÖÌ7=P”Je2rª×nËܱð./“ÙÇ.gá<äcøJ£ÜnFÇçÙ9dè±ÉòXÌÏ?æäy0ÆIl!ÙÈÿðW.唳ÜþRüå‘T·]MIÍÈ#ÄèÇY›z´W5‹ kúƒ‘|¿2¾º€a‚ Ôƒq5ÜábÆÿðW.唳ÜþRüå‘T·]MHËÈ#ÅhÇ36õh®o@×õ"ù~E}u„¨7âG¹Â2Ř猪ñ´—sÔ\nŸâÀå0{‡×ÔPûG×yÙaF8u3ŽÖ‚[×i¦V®>z¥,‚ÔTp•GV»b@塈¼¯ì¸}7àY–ÏÃw á6ê^”Ɔ'EñøhëÇó=ÔÊ+Úí¹O ò„_g<;Ó¢†sõZqð—ä7žög¯§±"ª·`g…éË©:U¯’ÉòsðGvßó?ä‰/¥WëÉðW çÞàªR¥ÕBv¡Öš9B§Üë º¶Ìˆ«”— ñyÕrñ…ÂÊAÈbÛ^q ˜Å®ÿà®Ï÷R•.ªõ n´„ÑÊÍ<†æÀÉ«mdE\¤¸gˆËΫ—Œ.R VCØŠóˆ\À> Ç7a<Ž¡•V²˜¿§÷xY¯¹Èbð*«nt ,˜ŽïƒÛðÙAÔ±¢š°ÏTõE—sŠ™”‡ôtÉÆ“2?Ìu„ÛoICòŒrပ,îâÊàßuøõûíoͽNÂÍÚß”½`­cò?“Az'0E‚×oäÞxµgœ ê­†æÜ^J«¯ˆ5³^0VçF|SøÝvÆâܽ¯'ÿ3¹{ZåRã!4mŒ6qõD»lÓÕϧs†Þ2’Åù„ ¢Írë¼,o ξæUýßÿ3—÷µ®Põ.1ÂFØÃ3Ž>¨—lšz¹ôîp5lã),_˜J:,×.¾ñ™è«ÂÆðÌëîe_ßäðŽ¥meKö{°&ñÚÇɧ7°žÀò—¡»3{(>ñÕÔúwËC.èëNIáÜ$w+È%Fg[bSi5LÚM{%±üV}Ívœ._1Hà›Œ¡°ò¥œ«§ŽÕýºù…q£Åòä‡ÔI‚€!BÙœ„eß©ÔêxÂU\äxÐrømNSþg¦†uM²qxxS‹©áT±/÷¥žgô¢ÿòz=™¼ª‡Ên¬~óÆŠ¯7®Á5k¬þ%‰qcÕiÿ™ÿµé¡FÙ8¬<)ÅÔðŽ:P—ûÒÏ3úUøâ=ÌÞR‡Êll~óÆŠ¯7®Á5kþ'‰qcÕdœÏCšŸ*דÒÌW@ÆføºŸ»àô|œ­M0täõ°ÔÃ_€ý˜>%ô#ëÐÕua*¼«F>çF›ŠRhªñOCBîîÞ5§œ©¢á»žÆ"ÇJ›Z8átWTb4øšV+o0üsWó/‚Vño ›%/‰{¶Y’‘Épy]FœZC¼¸ÔüR˸"`S¯ÜCW9<–“ÌêÐŽSþ]v@=Qý©åekOˆè*Ô; ¶ØZOÀ(;¥×ãÂÝt~U«=¬‡¢¢Or§]ÄÅs"ú•þ´ÿϮȪ;êŸvV´øŽ‚¡Cºc-…¤üƒ±úa~àbå¯ÃË nÛŸ(=u=p“DfÞÆu5ai¯©{”¼Ô†Ü•Eõñ4<5òŸóPËŒ¯3  L÷2êZ­•¡ ªÒÏ+J¾à¿¿¿_ʉ.¥}ã³ÑOU¤•üë^;T¡‰˜ïúêiÿš†\ey˜…,4²ÜË©j¶V„‚«K,í*€¿¿¿_ʉ.¥}ã³ÑOU¤•üë^;T¡‰™/úêeM2ˆ+Ã×òñ55¡mÍu<=‹Ö¾Õô{¬4€t{•âæ/£Ö?ÔÿùgãÁ£ÒŒ«±€ÙGW+©ÔêxË—rî: FÊ=ÿ RôSkê}®Êë C<˜gÐ(bÒW^?zöþ—Pª< •YR¨Çª¥è*¿¨6´1qœ¦£™=ï™Ô#¥~×cÉÿÍCý)}ß$éc)^R×öÓœÛ?ÆCÉá‹#¥z±˜Ë®­M•÷ŒM %¬X:2ÚUÔÇr¦Ÿù¨aÿ¥+»ä,e+ÊZþÚs›gøÈy<"d~¯VCuÕ©²¾ñˆ¢”¢U‹Aù­ êñßÚ¦iš¬a§Ä¸_ãù3U­»sx+À´«£áŠól*ñ$¿ã¡]V•ù«bH( =WzttC,'Ô«*‚Û‚éM”Èp¯¹n¡"oW´ïƒ]2s{ܦ]¾ ú›ûxÌMþBi(K–Ql±€TR×E(mvÅ”øuxÀ+ìuÜ;¬é>îÅ^QX¬¥â«—‚£0KâZÉ‹…^s1òIB\°º‹eŒ¢–º)Ck¶*´§Ã©Šú)š<)LðÖž?C^9]ñž›<ï¡£bÕÆ}?Uz^M]¹;m}-~E|”oâœoY ‡Ê‰=>9ÏŒsãøÇ>;%!±ýÕ{hÅãòˆýC«WÅÍÉxÎy3%kè=¿ä8”:€x{ƒ™cöm,æ>_†<õ•ˆ Ì?[Œ ¸ì^SWÑ­ú>5ãKy].áý,à’ÖâÈ›P⿵k®ë¯°‡w½žF+³´æ ~†å„-ƒ>YÜ­'¼…ÜÞe1\’=im)àjµŸsǸ¿á{QüYPëºëì!Ýï?6 ìí9¨'_¡¹a `Ï–w+AÀ/!w9™lW$§OR[GŠx­gÜñî/ø^ÔDÿTÏ}†UÕÞ[ôÔ¼þ¥êÉ¿qߨ­ ŽEy¦®V¶/ÿ«Y‚)¶P4œò|¦l’¹ñ8¾OΊ9WWû]ÃÍMcÜn–üøGŒO#â'ôòŸáÈ$Y·‡¢ÿ/Îd¢k×k¼Džc.\YÓkiy-Å*ûüXßÓ?K¸W ¡ÙÝÕ–ŸÈñ ß2ñã²ÞpчÂÑN¨?‰—о]Kþµ’ì‰(¥×QŽÆ9§,rÔrüÆÍz~?z/Ë.ñ©‹«‹e]QCÍî§PjŒI>$¿¸ÝK©Ö²]‘%ºê1ÂŽiË\µ¿1€sfŸÆ|‹ò˼jbßWÊ:º¢‡šÝN¥UÚ|IqL·y·‹µñ…f×a©g*å¡êUuQuöTËü‹ ÒÓõï²kÔ!t¥æ»‰¿Jwìø@wáø›DKÑÃ?ps:=gµi.bôìClóòÜcyÓ6§2óêÍÆHÈkб¨Áu]Œï÷UNOY8³&’ý:—.£_K¦éyÆÑ\m\a€ÂpKÖÕ_+È#jòÿ¥Ä|z‰$ÔAJ͘¥cñä2§S¯×©rê7E.›¥çEqµq† Á/[T\¯ £–¾Êˆøõi¨4‚•—1JÇcÈeN§Pfqð®oÊÑGHZKâäIÝß!l^u½­Û¤Ý¢æò3?ºj}[ÉúULƒäâR…uÝÜÏæÈ±º¡ûAƒû:—]Æœ¥ÐQÝÞ*¹•Çðô2¸’)“N_ËÊ7bE8ÿÈL_í¥Ê¸7Ý©UâZ* °ÿuËûB]²ü(aÂU”:@Æ ìUÝÅܯ·ä×ò(5;v³N-›”L„3ø›³{-ÕöÕ¦‘9NAÍÂP8WWU«™FiÇ¿ÊÅÕCUlÖ*š÷âQ[óàC–ü8Cï.ã}ÑÚ4®Õ\ "视a^Üü˜Py#N®žüÕůêm®CøÝïdÊ.Ñ™5#RªWï.ã}ÑÚt®Õ\ ø­˜W³?&YôçñŠú|žü(W¿©¶¹8íï9”]¢#2j,F¥T¯ØÆøÒ¯ïGå|F_;UNkùšÒ‡¯ýz}†«œb¼Fºœ×)ð3}ÎÒªU “-!KžUTLŠ öUE©­‰ËU*¿Œº…,n?À&­©·“nIÇýHQ [×ù^š]4u/vPþ0†iMœäø²$ñ¼3˜Í¼eÑpE­8¹®4ÖÞ+R9›ð8ÞMjœ’>zxvò:-œaázSL¯ÞW á4g?ã†×Ìß%¹ü“~Ÿöäa(|µeîÈ}+y!SŸv}X8¬Ì` )p*ê”ñ;å~ë…}C8MÏøáµó ä¶èä›ô÷·# Uç§'‘úVóB§ÔÍ«™Œ.XÒž'c+öùXÜÁœ´·:iAÍr? *6ÛL_èBî`M£úÁû‘kv¹`!¶’†‚­”ueaöŠ[3â€2Ú#>G¾åñö=’ñ4áq=ÍüºÇ‰:.;1eÍù¹4u×Eê…þµ“'ùt›8þ^¹g?i_€ò¡©ìoÓ«ŸÓ‰ÌÉ5Õ¢®ôŒäðî%dâ4m™¯Á«”Ú\^L_¾ ÄALóªý×uS@yÏòulr±n Üv<èàéÏ32Muh«-u9<;­Y8k)rur»K‹Éƒc÷Ĉ(üê¿`Å ™q>2vnN{Y¥®|Í]Oe°±ªÜyK¯`ˆò\©rßVq õ‰º‚*®íU3e³µ.{j§°Î/9²+×à¾îXTºª†Î¡èeBÚuª 4KÿÁã]¹†ªÕÍu4ò:}›ø‘Ÿ|TÔ£ø=uÊr¸6éЪʱ|ÎG‹Vå¬ÿ†hÔ¾ïœJ´rXëã8–ûß‚´³Éħ’rQ_ǨêèyND13Žä[È=|x©œÅk¹ÂŽ”3!¯V¼ûA†¦ WíaÐÍ—w|âTþKH¯Œâ[òÇÖÖÌœHpz9%üz®‡”äƒxîE¼ƒ—ÇŠ˜­—8QÒƒÅÈk׫6Ði­”UúŒàxÿ2všXnÜ\ŽƒoT̼â˜XrÒ@'5Ë|¢Bá¸WXQcª‚*®íey2õ=”0lŠ)sO5ÇãŠú…í$ó†áUÜgñxŒ­ÀÃPÜ_p×ÿˆSf® \­ioÄ_«,zAÁ³H$nÁ´5$K^u+ðYUCוqüÎqÙ·I;§çÝÇ®€Uаe÷çÕîÍéÓU¯[øËÊþ7” rºäy5øåÌ÷èÈ7Çh÷eôî-:›á’ðñÜVnÕ‹J1/fÜìG0‚ Ù•“Ì!ìʸþe³v“v=/Ï¿X׫àÉïϫݛÒú­›Ç|Gñ¼ x{•ãÈò‹ñË™ú4c«ãßîÍéÝzµ6×’ðñ¼Vh¼Z³â^ݹÍ ƒ^VJ*¹Çd-._†usè>üÊÆú‹ì¯‰ÁëÍòÞ1+êŠ]qù¼ËFÞ¢¦q³¼Yh*Êî)}ͼž$wýG»‘ºÑ;À?†î2˜PñY[xª)Ëp»<øaÐX¨¿ÿÄA !1A"2Qaq #0B‘¡±ðÁÑá$3R@b‚Cñ4D’ÿÚ?ùà™q#ôÝe±øŸÑ‡è:=wþßz~S}Ÿ¦»¿×ðŒA­i~Úº{ú~û" ¨¤î›P{2öcÙCSYKþÛ•'KÕ ÏÁ[ï´u›5ûú“påq‡mú+ͼÐTûD~R¸ÞÝÒ¥Õ+zª:sQ+X­<¶‚SHb2'J5òî±Q'•…:ÃöJuCzµ9ŽoQò¶=H@½™{155”¿í¹RqL±mPÏÁ[ï”u›5ûúÜ8+Œ;oÑ^-æßSÏg”®7¶ô©oB©[ÕQÓš‰ZÕh¡å°šC‘:P¨Ï—u¦¦O+ 4u‡ì”ê:†õjsÞ¿%_eå9QAA.~ÿwöU,ÁÏu3~ÓQ*9´•oªÊž>êª^ßgôÿ ñï…,e©ÅJ£k}+×ñ)Œˆå;"RÑ4uk¸6o¡›g*'ýƒ-*çÂüÔÿ?Ùeð»— ÁE­‘OL˜*›DRý@ p¹ uB¨7¢7–ÃÔl¿R\¤ä4ø•K±°ÿ±Â ˜ð g¢d‘ÕVGD<­Ã®ã§ÞUmh 4ð;.iÿ¯¿Þ®×ëm]@Ž”s\;á~ÙCÚ ÁTVÊ™æÕUQ¦?@:û•L4þ*šŒÆ:DvªŒêÚÚêG„}éú>ÁÊÇ΢ܔƠjÒ´.Zt ª;Åu»hŸ‘èwTÜUKVÞUXÐ%_Ã÷iWzi¥’‘ÝFáEcœ Ðj<×&È0%]yÿNÂOÅRð}L›Ô<7ẄèaÝÃWÅ6ÛO‘€# ѧÂÓÔ*«trŽŠ¶˜Ó? »”Æ jÒ´.Zt ª;Åu»hß‘èwTÜUKXÞUXÐ/Å\"lŒ1¿v•x öšI)Õ»… E…ÃÞ¸jƒWÒ¹6PÑ€©(ªëÿüvïíøª^©“z—†ü7Qp;¸jø¦Û©áÙŒ@N>ž¡UÛb”tU”Æ™øU}–T/Òp´ë CÎak¼Ã÷•#‹JyBãp¨«4¹RJ*#©UDw$H0ª©Þ‰û)e+Séܬ¤'Ó‰U¢wo}²á8+€¸XÒ\[s«Óëý•W"pAUmk&!>¾1ÃBÈÕ%Y£i00—|ÚŒ·s»;¦p ‚ÙDŽu$C>ªº¼¾ëÉÎÍýUÖÓ5sCi¼ãp­Wªëe_²ÜXt|:. ©¬â‹¨ŠŸéãïÛâ«øz®¾˜ûž¿e|Í©¬rúgÅ2nM9üý>ì¢=>m¿ÌSB Å€¼(éNhRF…LôŸí½;*‹ž©ÎÅ\íb*ç˜ü®Á Ù‹:B¶RSÃâ Ô}ûþ]=|PÖsÝÚäàœ‚™ØW˜Ã™­GæMƒð£¥9¡I5Ÿí½;)îaÒйZÄUÏåù]¸VȶçHVÊJx|Aº¿ð©ëänÊÎb »¢{œ‚pS; õs5ª¾Ë(=QË«bª!8ÖΣ÷ùª ãjs´§'»’íC¢²Ü°í%TÆ%g1¨«Kºa0¿IO¦5\-Îná9¸*FŒíP•i¿ËBñ‚¨®´×ˆ÷8r¶_êlï —vú«}òšç9ÝTÃáÈWza«Xê›Røö?? ¡6=]Ц“²‰õ0©+ê‹t‘¿×ꤧ{ /m>°í·#lwéœ~ AhÆ=ËJ Bá Ó'UÿQÐÓy°q ÚùO gµOt¼ITï qÿT 9Y Ââãä¡’BÀ6ôßñ_ÃÞ"‚µ¦Ùq#£»û“¥’Èø@õ—ÓW|™µûµÿ—¦Ö²Šš†qXÐøøû°U ¶¢åAIRùÏ :zxŠÓìÜÖÕ/aÒÞ/‡Á“°ù–ï1M ¡tN‘S¥ÇU-{#SßÎ꣊ZÍSq4ïò£vžc‡½”þÑo§awŸñǹ3‹ä§?ê"¡QñM¶«¹aQUÈñª–|ýê> ¸R¹º·ñ£\t¸àª[ìuIJÉFZ¤‰Nt)äUÎÕ 2hM Ê"2§K…-{#UƳº©â–³`TÜM;ü«ù´ózöS™íð3>Ç œ_%9ÅD@P¨ø¦ÛUܰ¨ªäxÕK>~õ\)Òn­üh×.8*–û@ñ,²A¤‰Nt)äUîÕ ¯²™¿h"ì*ZŒ9Bá4Jº'_nÿÝLÌ㓈pÁQÔ¾Žeb¸6²-UÓè•6Ú¡Ò<çöPŒ*Š1;r®–·4êoTऌ9KŒª[„´®ËJ´ñc'o&©STÉLyÔOÙ[xäÊ©UtÕãTeUC¥ß<.©î1¡pcNp…qÔw¸˜pý•tu-9R3 F„á¬f3º†ZVj}Xð4Äù¿¦>ôÖK[noѼœyô¨èźú‡d÷Tö¦sECDæ*ë\U±ø¿VÜ6Ù ‡øiü¦?j­”ç°Ê³ñ¯ý;Tê:¨Áfqœ)¯ûÍu>îcEe!:Ú§l¬õýSó£'þJ:cÑ„. új-*ßQ-©¬?dm÷®š/a}EpÔíZµODÀ]Gíp·è‰s²zã=0¦…лKÆËmó”À†ÊIvTÕ"0«nÚUuû}-Ü©'ž£ý²PIÒÅÂvPöú‘“öUuio3ígú+ͽÔrŸE4%¾(Õ5Ú¦‘Þ­œhï%Fê9©n-ÕÝS×Õ[×!Y8ŒL<%EPÙÙ©ªµTI…S"ƒÎ˜†ÊIvTÕ"0«núUuû},Ü©'ž£y ÈbuA'K Øy-öú—*®·–¹ºûå^mŽÊhK|Qªk½M#¼%[8ÑÇÁQºd´·êˆî©îVÇuÈVN"lÃÂTU šš«UD˜U2*¾ÊW”ó茜·+E`;YT:Jž ·!HH;ª¦óžë‡®¦–` ›P‰˜¨©º‚ºÐh>Ô·¯Ç×ïQ*ê+r®Ö§4ëgUôž©ñeOL[¸MËz+uìS.Ð\‰6)•ÕTGÀì…MÄÆO Ÿ?¤;b«-†A˜ÔñÔR?|„úʉÿràjk]ÐCaÎsÓ¢®l´ŽÓ3HOŸ=?VÖê8E»ª—Q´†Vôü•¦¢ÁŠ(¤ËÛv\mr§7AKåoUm§1Qêp½9ôuâEÃ×6Vì©j]j“Swj–ã%ÅúßÓ°\Wdw´†UEUSj‘¤~¢¬lñ‰Ы jp¨ž[iìžÀe)¾•ºJ“Ç-OªoffÁk‘®†ŠöÆ5{Ûé÷¢Ø&š•§@8ÿÛ¿¼Œ>)Í,8?%³ÎTjGa9ÙSÌ# årÓ•W_%[´³¢c²† Ô³™áK®—™'”+-(©“˜>*ÿMÊ|@úÕ_mÍ©…O†CÔôú“ƒ£*‚ë5#² µßb¸3D½W1ôsbV"åTÌ%n ªÞª$ʧó¨ÔŽÂs²§œFÊå§*®ºJ·igDÖ†)e ©'2–#[/6_(VZQS!—lú›•,@úU~· ˜r§ˆÅ!ýTôú“ƒ˜U¾í5#² µß"¸3DW1ôsbV"Áʪ˜HÝAU½TI•WÙU·>$çce'ˆ`ªÓ¸*7ŠºmAK·rÿyL‹ì•r£1îv yäK¸Jè*¡öw•iw.sNîý6_¡“¡ÙUÑ>ßPêy;~‰­Ô0®ñ W{9ΦõAå§Cú¢¤¥݉‘–ŸQEÿ›,ÌÙs³Ô|àŽÉ4É=Z¥‚9†$ Ÿ‡mó¿Å¬¶ûC?Óîzª¾]K \ª¢ÊZ>±‡HÎ2®t­e²¢´?2a¹ü†¸* m=ÖšÜF‡áè«ì¼!›… YøcoßÞ¨8.¬Y “^ùí”ÈÛS#iÚ¸÷…ËèÛSß\ù?˜†~~åIi’äsуóW;oòÓªŠS[pUe™„öý½’P;–tYYYZ–¤ß¡Ó¤xöä}éíË/_O»ä¶yÊb•éÎÒγ ãTê—òÚ±£e,Â!¿U,®yÝY­¯˜4KJ)#m?˜« SÀÈ×õÌoþ?ÕM¸ð¸ŽÕ¾¦õMv¡‚§§ º­•,Ïùj¶\Åd\¹:ªzçÐTû•¦æ*!Ó•Y"‘Ù*›Î˜¥z{´…s¬Â¸Õ:¦N[z,hÙK0ˆoÕK+žwV[[iE3COÔ«% SÀÈ×õìoþ?Ô©¡×ÚŽu·ªkµÔôâA·U£²¥™ð?-V˘­‹–þªš½ô>åj¹ŠˆtåVH¤vJ«ì®ý ¦²{±ÕUçÆ®º‰¾…ꮟLʪ”°¶où~ª®O¯§0I¥T·SWÜCJ|ø1Õ±Q8d­\WlçÓŠ¶:ü?ˆ©¨*ûx+­—R’9iŽ™ú&³Õ?â´ÈΡóÉ…§;*§>”ê šà%o੪['•Ù?Å:™ñ…Op0ìå-ì–é`NqyÔ~¬'0;G,ƒ’o}û«Í®šÑC$Ô±‘0ÇS‘×ÑPq =öÞǺ0ÙA—É$Úao@¸î ³f>\~ˆ0K+§fÛ쿟û<*ÂÃê„–ú;›îT –wÕUÿäcyTÌ,h÷'*ëç#Þ/ÁRì?ÂW;XõR»äÏÎÂØðöýþÊ{t» ×ç+8j{·U“hj¹Ndv›Ô¾• $êr¥¤}T­V‹|vz}G̸BÐú™}¦Q¹è›¦/ W¿]ËÿQú”Z®”bf+½©¤æ±gPÈRÁÍÜuQÅŠ¦{©ž¦“Ú¯ºáË™nULº†QTÞuœ5=Ù*¶m W)ÌŽÒbÓº”èRNT”o«5ªÓAžŸQó.´>¢_i”nPÓ…«Š®åÿ¨þ«jºQ‰˜®ô¦“šÏ½gPÈRÁÍÜuQÅŠ¦‘ÔÏ i9ìÖ\ËpÒªeÕº*«²­fF°§‡K²:*êB¦§;±Vú·[ê ³6®T„hM9ðø¨cìWÛôm û ã «‡êýºÝ¤ö\?´Ó¡‡Ç¥Ê¶”ÐU¾œöéðLÝKª¢l¡WÙóÙTØË7fÈSÏÔ-ÏU–£KM?™¿3#3„ÖåTS‰Øcr˜ËAQŽáC_¨s£ûÕ¶àÚ¦äuQ8H0T‘éôíNŒ·êãì©]O,¶?-”÷Çá‡w¢š¢hMXrFßweg§öY¥=‰\G™ŽÔ«=!¦§l'âUÚîÚ¼={+ή¾].9' \!æ°É,£'÷•zàØåw6ã=”\5U ÄÊq ššj]Ùg=Qú€S÷Ý[<å=Ø•tŸ —¨äªËêœÍ^"…9Øj²Z£ g6^ªÓo’ë>§yµQ¶†z2wWçë¹€QôS7²»[„ƒ*ºôÔѲÜ'Eö‚H0 ”ÆtC7&eüèù)¼éîÀD«¤ø\½G*£èú§3Wˆ¡Ngv¬–¨íìæÉÕZ-ò]gÖï*µÑ¶†z2wW×ë¹;à}Íì®Öá %WP>‘úš6Qáû„è¾Ð@  ”Æt9PMÉ™A?6 ~J®Ê×TÛ•T)̤ÅûÊüÆ–u¤4Ò*®šýÜ…L¤z°»Ú)Ç«vWÚb¸;OGx¿¿š¼Òsa%TEÊ™Ñ*Á‡ep-^K¡+‚gÓPèýêC¥Ø\[’¨vب܈)…$AÊ{{^¦´ŸhÂö „/od>@º Õqc˜ÎkͲŒŸ½hçG©ªÿk5{SN©Ò:šBÃÕXî.†«A=U3õ`§§)ú¨Î†êÆ~ò?0ºãYÔGBzþ+^ùM8\ ù9ŽF~SÖ»šòÖî}²á{ªê² 7ÔÿDêªHhM<[47 *¡§RÍû)ó4öOvS¾«#N ¶yÊ•ÊGaª¹ÜÇáh i{”ÏçÉ«²x2 TQEF5»ªµRËvgʬv–QF i{'È®Rs./*2¦nT¬Ö0UÊØ¸Ußg~BŽ J¦‘Ð} èˆÔOÝY¦×TÞu+”ŽÃUs¹ÂÐÒ÷)_Ï“Wdàd:¨¢ŠˆkwUi¤–í 'ʬv–QF i{'ɲ¸É̸HTeLÜ©X0UÊÖÑT[}ù 85*šGSøÇDF ¢~êÏ6¸ðŠ©ì¸Vîhªy2tQ NÝ÷W D¢Vôw꯶ÁQ ¦aiV;ƒ­µÍw½p­S}¸Çö^2S5ôìœuaüì)Ù̉q?³ÖeW €W<²¸Á`ºµÿ§vêøÎ}ÛîTïËSˆO‰‹Q¥Q¦j 3œµQ×2]e$!ì÷W–Š£éý ]ÛPãNîߢ²Û!¬Žhßú®2¤4uMwÝ÷ƒ…AŸhŒUngѵJå$À'Ë«êÜz,ü€ Tо£Ã•5žž39*wzá6œ8`»*ÃFÇT¹Ž—ßiínöZ\jõþʵ—jsÊŠŒÀ¡½û«MšZé¤Vz8-Í«ù’e^¾ªiÃZ\Q—›Rçú¦9‘…,JFgb«m­“¢–‘ÔîQ#t;¢ª¥4’iíÙc« ˆªo:•Ê©øbÑ©ÙWzýŸz>¡¿Š´Y¤­:Eg¤†ÜÑê¿™&Uëꦜ1¥Åsyµªc9RĤfv*ºÚÙÊZGS¹1¢Fèzª¥4’iíÙc« ‘U=”Ï1H% ‡îÞÝFÙ‰´-ºP¿G¦¡ñýì„Bh´•Ä–óGS«±U1¿P\!y× 3gxÎÁ\ñYFGüššuD¸Î›nhU5pÓ95ÁÅãcªJ–p󲯔ŸENì&¹­YD4§D 1#b:~Dš_ÝFÑ+rÕv‰öÚž|~Sû+‡nñV“Jî¿Ñ_øj•ÚçnÇïþÇYª¤·Öÿ3 ázæ œösOåºþ&Ó€ícþn\?Lj+#o¢¦îÄŒ¸¨øZG UNû‡÷U7Nƒ9U4ßW׿Ò5‚ ª/rGåÇâÕBþ€®ãº^s_/…Ê¢ÍWÄ·I*³3±>ŠžÙ²•œgCK®Ê'ÖL9“7HôîÕÐ8§•Vs²©”RÄd)ĸ—9G‘Û+]£QÖõLöS7K¯*:äÛ¬qõ*¶òú†òÙ°Lv“”Éš›"Ê’0î‰ì©¤l¡KJ`r©¥‘iî¹nIVs¡øù 8ryÝV쪥±‰q.rŽ##•®Ï“­êžFS7K¯*:äÛ¬qõ*¶òú†òÙ°Lv“”Éš›"ÏU$aÝÙ…SHÙB’”ÀåSJ+"Óß²åt•fv‡ãä¨ìªwªÏzžÍ8‘½;¯áåú’¶ÜùƒÆ{öï¹>h½¡æ?.N>\]BʪÊÞ­ÝV‘°VçÐJqå=UºªÛï…K8Ó‡.'„INªG„(Ë~¦«EÃùu)›ÛªŠù|Å\¯f©¼¸ú&;IÊlá Û꽡¾«Úê½¥¾«Ú[꽡ž¨ÌÄÁp ©cÆå\¨}ª-ëÙP_MôÔuCj¡¿Ó¾ãÍøþÿU#'áË»à>hÝû ‡ïP×Ò>ä•¿Ÿß¹qMhîîÑö†OÅpÕÔò¡$î6\{TÚ¡c©q?¢á8ÄR:gvQñM R ÞF·úþŠøÁO=@Ž\üU\ALâKÊ® ÕJd?V~`\±'UUdùŸÃ•™ÃFUðî²æ|lwä©ÿ‡Öë/6Vƒ)Øwüÿ² ã;‡ W>–OYèwUwË}ù¤ÁáÔ0@ê›K4yK¾;£õt‡¬©w*é'6NXè?TÊWLí-VûK"ž†°ù ßÑ6Œ÷+Ù§j{t» ,Ò3[¶RÛd‡¡\É"ê™Yêµ¶Q²‘˜SD$§Bb*çIƒÏoÞ¨Û¢@SZ˜pVT»•t“',tªŽ‘Ó?KU¾ÒȆ§¡°ù ßÑ6Œ÷^ÈÐ;SÛ¥ØPÙf‘šÝ²–Ý$= æÉTÊÏù-m”)…4BAºt&"®t˜w=¿z£n‰L9j¨ìªô¾ºCÍ$¨à/!­®¶¶ÝA¥ÝNë†ìPKOíS·%Çlú.?©¡‚‘Ô,hÎ2O  ƒ& £ˆÉ+bŒuTâ:aì ·>§vô\gGìá”ý÷(VE R½’°e>¾‰ð5 ÊúJÅç Ž‰°Œü‘Âç¨áˆ= Z†—'±QÓûEsPƒ# ªÇ²¬ !IaAŽj{=<¸R49KsK™ ØQ ›²†, G©\7oKÌr§a¨‘´Ñ÷U·X­”zbò°`{×\ß1kÏÒI×à¨cûK„¨yõ<âÑÄ­VöÁÇ@¸Ö©³ÔTOÿ…伤HÃïV‰yßTRSº¡PÓ¶&éj–…=:š©iá!áa1ªC§¶ª*hé[¥«ˆjõG¤þÏø\Ïå5Å»ýŸî¸¾ó$T$øßûü— QÉp»´´y?^ßš¼RÇAE zõ?wù+ŒdÕp v +Lnš1ñüPSÞ­Œ/ï¸>…WRÔ[¦^ž½‘œ9>@‰ÏÕFÝlÆqߺ8'·½iMÜ(^tªúhªe|Ô®åMÙ[8˜G(Šc·ªE­Spîªq+³¨îª¢©£8wDùµu åªi$¨–TÃR‚ÝÊÊŒ¹\ÔéÚÞ¥:å ;¦Þ õTõ±Ëå*7s¬0ó.?P¬ßÐ+ÇÑQeŒÜªþ8‘îð±;ŠÄ§ÆÕâž}pvá¢ì§n¤fùQìVT£R‚ÝÊÊŒîW5:v·©N¹BÎé·ˆ=U=lrùJc¹Vy—ƒJ¶6ëExâú:,±›•_Ç9Û1*ŸTŠyöAÁÛ„Z‹²º‘›åG°R¦C­ØV¶ XU”òÁ¨wSÓà®5‚©Ûùú®$¯uδžÊ(ÈZ¸Z„SB²›ù…tpöê~^ªÙn¢‘þåŵ;~]æyÊ£¤@xÚ=êÁþÈQ ”ápÍ€Ô»º¦Ã©ID ª§d[¹VVSEÝUÞ`oE5ñ½“ V½!/n›\¾P©ôÂ2OÎñ;îþë€ÚÊ MkÇNžóþ]ÁõY©“¿è¯µ\ú¹e\ jÞïrà×—ÚZÒªZÙF—+½œAô°ôúÈœAëŒn¤² ®.~eÓÓòëÕ@Kmö‰ºã*ÊóSK¨ªš£Iq-ìU!”úÚª8WùÜ|ØŒvõÿ*ía¯µJKšK0¸¾:è AÙ§‚â¯âd44ônÇÃw…QÄW7jÔíýJ¦‚ºC’ì}êší{²‹pÔŸÓ ˆ•…”Ò‹ô©j|ªwçr©tMûJgœå®T·JªWe®ÊáÞ"Ž»Àÿ2árÁW$Žìßê¸ÃŠƒ³OÑzŸì«¸¾0K(Û÷”.•U;¹Ë[ÕɤޅPÜ&‰SÖ¶`‰YNù2‰XYM(¿J–¡çʧqûnU/‰¿iLóœµÊ–ëUJìµÙ\;ÄQ×xæ\,XÚ©dwfÿUÆT˜£~ˆ›Ôúüw°Ê6}å ¥UNîrÖçuri#¡T7¢ê©ë[0D¬§|TPåùP»˜í=”U/œèbâ» ¥öhúžªj<Ç+U/>qîTا„4. ¤…Õó;aðÿïô\U^ê’ÚAßr¸æ¬IQÈoFª6`eS3›RÆ«,zb ÊÔcuL\©(ÛMbodص#™råsâ@Ó¤á]ø¥Ò’#ÝUWÖTöÉÕå=Íou¬žˆ|c=SvÙM.–n—:Œ‚£§d`FÞ^+ypÞê¶Çi?a‡ÙÛ¥¾i?Ed,·ÛÙN«k•ÂfrNS÷vßY¬0°ÆÎŸQèUÊóIs·TÑÓ Èì`ãn½2­6gÚ)<þw/â-‘Ö±d} @$½Z®qÛå!ÃðU׊J¨‰š}åQ²íÊj;wƒ#·uSÀ31ıßUEÂ3Bs#”¨é†J“OdéšNŠÇÎ0g~ÃóNv£”ß“("ý*¢¨·ÊUMCöÕø'ƒÝrÜîOm«xðGø/b¸ÄÛr¦–®•âBÂ÷+o6Ô;c€=}Êñ_Uy—TÇ ì¦‰ª™;©ahOÉ6Ž'ù£‚þUòŒ&Ѻ.‡*7…Ÿ™”~•QV[ä ª¦¡ûjüÁî¹nw@§¶Õ¼e‘þ Øî1öÝø*iªéd‘îVî/l4¨vÄ€6õߢ»×U^e×1Ã{D)¡b¦cNÀ*XZ“òM£‰þhÿ$-P(Âm¢èr£qèQYù f6 šœéǪ–è Žê¯O¹U•Ë`¬º ÷T×·›\/¸ ûÏì#ÄRñ\¶Atc|žË†x“‡‹[o¥®nÛ«¤tÑU7‘ŒEÆ7ÃOÉí/á›$þqÍ÷ýWD —ÚY߯÷\çI´C*â]G>¨à*‹Äõòr¡Ø+}.†dõOÃw(x†V”pÐ\PcžàCOGÀø©4†cîÛïûþAó4åÝ{<^‰Ô4ïêÕ’ß1ÃÚ­¼A.ñÈB‡)|s9]-ö»`åC—¿âvø¨k᪽šI7aÏâ?eUp½=;#ãŽèà?Tþ£ê›e…YÑ©ÔøO` ØD,üý9Bw^Ï¢u ;úµEd·Ìpö«wÐK¼r¡àJFŸÎWK}®Ø9Peïø¾*ž¾ »Ñ¤—vþ#öU_ ÓÓ1¯|`±Ý?ªQõ M²ÀÎB¬èÔê|'°ì"=~R©)rì(!lc[—ÜŒ™cThR¢‹S•/ÐÇ…o”SŽsºžŸÎ}Yåö\et³ÙcP³[µ”иz‡@ ¤§’áPÚxûþžªš8¨`lMèMŰ0¹_¸†J—˜iÏÞŒL¦o6 «ÏñÀ¤¬’weÅBGt×—lÕOF鈨(©¡í“óBÊiU†5KM5t™Vû4T¾'îSZ_³TtN>d)ÔèZŸD}X89Eù?²ªa‚§ ©~§En’e£‹õ#¸\CÃÄU{m?}þõÃÕÒOd½Xp¸œ‡xŠàÖºÜ}±Ã~ßÝM=Exú^‹†¡f§@ñï_Ä[ãe¯ä3¶ÃÜ=~õÃôÆ¥Þñ)ш¤*šÿhªñôGà )²ŽÊB# êw©Ý\¾ÈÖÊ|¨ÃP× ¸®^áëýÓ…=6¨(Ýô{wÈÕßÀèªs‹ŽOÍÊ ©’µª7Fþ¡{#_¼e[î>Äí3*¾!tÿEI·¿û+¼þÉF÷¸QÕºžº×9\1PÛœÃ.᤻²­Öêƒ éÙ¢vfêWT5Lqºåü™Ý¹¬DV~vPMÂd­jÑ¿¨^È×x£*Ýrö'iUñê>Š“aëý•âc£{‡¢‚­Ô×g«†ªq³reÜ ·û*ÈÝnœÂzvF¨™º•ÕSTÅûŽ_Ì)ÑËšÇôEgæRÓˆ›âW:í-ÒÕ6g“tX©™ƒ¨¨~•Ø=aó;eS3-”ÅÝÕÒ©õÕ¡-¡¡PSóeåmŒCS¥VvZàçH>‘ßôRV—÷•îõ%kýžŸ¢žHmqk“ª¾ñ •o!§d\^rTlsöj†Ï6å0Õ@ü rIÐ|ೕÈÖwQ±¬Ù©Œ\„ÁƒÂŸuŠ/3Õtu>C•.ÊG€‰úÆŸ‚*G¾&ÓÞ<Ø?§Þ©ç»Ûí¬þR-ÙÙÞm=•-mD€ÅXÜÉAiäs›ÝTÓ É¾6hé•râéiÏÑ…Ãü}!œÍýBo Ô_ëd¸I´dþJŠßMl‹D]ÊŠhè$­wܬ®ÔéîU[yQmé•óóf-wRWRº9{™@ëõ[Wtø…bŒË鮌݇ŒrctÑšHÛˆ›=ýÓ:wk~äüðŸŽòYUYF|cdÛÖŸN“ù+¶¶NKör–Tc$©(æ¶»ôWØùô¯hî”:^ÝK….þÇj%ßh’«ª$º<<ô †èãš'1ÃpWßã¡y¤¤8 îO¹EÕÎÕŸÅPÚI'òB±ôGê|R;ÈUe]]úA²mëO‰‡Iü•ƒˆ›ZþKöz’T¸EÉ*J9m®Ä½ú.}+Ú=è´ÈÍK…oÇj˾Ñ%WO%ÍúÏ@¸nŽ9á,#pWqto4”‡¦{“îPÇ5kµgñT6†’Iü±ôGæÕUhnªÈW/9”1eRÓ?OiÛÌrâ{±—À<úG-*ÏI…ÌÒ0šŸœÿh—Ê:{ÏøB}[•uº>¬û=?EU<6˜u;ª¾_$­yÝ`ÈT4ŸòA¸ VÕQZ¦¨:¤TVLuQQ2?Ÿ” jtÚz*êàͤ~e[$`üWðöÛWSzVÑçßÿת¸pèß’ó÷©¢|,_®;ú‰;¢dúFÝ@'àÞŸÕk%¾#•©5Ê{{ë¶/Vî 3l'ržŠ×l§4Ô #r¸7Š'±]K1ú'뺽ŠyêqO÷ªÊÈë-2ÐÎpìlWpÄíºFvÊ‚:Yæ’:½¶Â±ðÕ]5þX±–·¦;å]ÅÓ]™†úçqðVú¿åQRINþ€‡üwÜ›&µ³ =¥ºÜ\H'°N8;¨ 9cé”i›PÏP¿èQuÔGOíþUO ^ør NøÉh9Î7ýü2¢ã[-‚dçT®íè?]Õ_[¯>Ý>ñû2a4ZUÖ„ó™=ÿª¢‰±ÆÖUÜUK@tõø.ã‹?Pv `þ_š©µÜ¸†¹ÕA‡NvôÇùê­\2(Ùªs“ù)択ÈVÇ9Ä{¢Ï 9c=ѦmC=Bÿ¡?š´ºˆïéßîÿ*~½ðÝHžHÉh9Î?_ñ•Ùlk˜ê™Ý³Ð~eUñõºóá-Óï?ºlÂh´«¥ ¹ì¿½ÕMkº5Wq]-Ó×à¸wŽ(9ÅÁØ$ƒù~j{Uψk]TtçlôÇïujá¡DÍSœŸÉO4P·=­Žsˆ÷GæÊòýÑjÑ©2ã…MK©Ú{ !¾'+ÅË ÒÕ3 L»§7°Tðêz§Ä,Â¥aª~žÝÓ*ØÀÎOY%OÐÅÑUTÃj‡Sº«õîJÙè5Ò•‹f Õ=,Õ‡Á°V¾ ß šÜÈl'²äc¯Ï 8O“ £Ÿ>ÍFÇS)ÏEMÃ;æg®u•˜§#ÜõNº´·SʸTŠ©‹ÛõñLèŽÉß#TÌ«,×HsîVkÍX­þ__n®™Un¡ Ã"®q¯Ö¦ó}¦åVWš:W?>"¸[†å¾Uû“þ‰»à÷U×~¸ó¨\Lìõw¾I-ªé¶sú{”|<Ê›K åw´nâì½Å=²ÔÓj¹5·RÕËPÌLvÎØÏ@02}=Ã܉ôú€kzªûkª#æ@påC}žÛVØ*†3·ùPËSFïh¦wô\sÅ´Ô|†¼—?÷ÑVð…e¾žw·{z_óÕ Ûd+|3P} ÎGdö5ò‰eYQ//—ÉT¼--Ò`+^ ­á{5‚Ý#(™ªm$êôÛ·Íp â ݾJZß ±ý¯QýU¶‘·ÌS»{ÕÚ¯ù½ÙÔ°ùZqûüS)c·Ã‡lƒ„ƒPèηª¯¶º¢>e9Õö{}c)ê†3·ùPËSFî}8Û¾Û.9âzØ)E3^KŸûè«ø>‚®† ÜÝ.{z_óÕ ÃÙ ßÔ“!ÈìžÆ¾Q!ì«*%åòá*—…eºLkÃAýöW³X-²2…š¦ÒN¯M»wü×Þ ¾[ŸMYá–/µê?¯em¤mÊsçnÞõsªþqvu4>Vœ`~ÿ›M¾;d$‚?1ɱë8\­])ù@cÌyTð6áWVé ¶gHSbÐ0‹U+7Qê”éjˆÛÊÿ¿ßeLÉ&Ø*š˜m‘dõWÛÛëwMÓ¦FÑcºÈú‡j•[¬­Œd…6‘²åµT• KXO—êM÷&Ç«©L§aêäÚ6Ÿ)O¥>©ÑÿØ„#yò&ÄÊZ†U5Çö½]q7:ŠZ}Z¡Õ¹ÆúGæLJmtRs-×Ót<,å“”àɱ̦¸Ô5øöcÊO U•Õ Ñlž¨´°Mò¸È\sÛìãÑI£?F0?EœýHÛªŽiM ÝOOz´Ð\¨+›GTÜÄö’×v?b¸®Jyi㤨§›PcHëŸ\…q¸q=¾GR—6HØÙ÷«¤͹'ñCˆèùñQT¸œc Øð÷*Úšû•kßK*vÈê=~ôK±â9YMs¾ÏU]ê'êöbøÇ›Nøªªÿh‰Þ͉wÚð?qý…CFËu\’³ÈGõVÙ¯wJÃ,¡nù#¸u\9¿Ù¤|-ÓP×ð{î|@ú{•ú„×]"§¥ñDãÛ'×ßîRIþ¨Ò0yëg Cç º cžSC6Î==êÓAr¡­UMÌonZîÇïõ\U%<ðÅGQN1pkHêzå\nf4ÿeÙæ9D2îcºþöU5ZF©”½w(·¹A›ä¨Ø¡€°{ʦ£ÔUMLVøýêýz}SÈ2Lu;¢ÒÁ2"ó¥½U®Ë“©ÝU ¹±ÐÖ'Ï…Mf««ñ?ÀßÏðRØ"ˆxFJšÒGÔp ZÁêšúYå+ÊÁG'SÑJà¤GþÄ%,$Ëe´žÑúìz=ÁCÕkåÄèC¶=s¿à?04I¾žžîŸÙ;,“õ:JÒW*,âc–œ‚§ô í¶}S_áŠ2ј÷>'gz|7~“Úäq«hp-Æž€oœ¾;|‚ Ö·ìî;à©ä–§HsÉÓ醃É>þØè²r©ê_MØÌaÃ~Û|FsŸ»ßèŒÎ–ŒQÌïÒßü°ßàr;§37§oßïÝòjZùt¯¥ÇC²7Πõé×ï÷©êd¨cAÀÆ>ð<#Ü:dõÎv[ç šY v¾g\ŒÛm¿ß·½=œí@õpß¶UÏu#‡²té-SŽøõÏ~§(¼?œ5:Q»ú.:n6íÛ}ýO.2ïÀØ ú½=V“ÝŽ¿ A‡²åDN&:šs=;ö#§T1pãâ9Ó·üöm¿aì –GǾFáEb9¾CüãüÿE=æCÀNÖìúÙöC\gÞjZƒß R'öp*;Éê‹2¡%…T·ÕfÃÝjíøŠÙõj¥ÄnZœ¸á;Ìr ïA¯”áƒ*Äœ¿…‰~s•cìÄo`ý³Þd<í`ŽÁ­ŸP†¸Ï¼Õµ¾:¤OìàTv#“ÕlÊ…Å…U·ÖiüEmÞ¡Râ'-N\pç9G„÷¦µòœ0eC£Ø“—ð¡Ñ"oÎr££ }˜€ ìg‡ò~_ªÒíõ™ÒzÕtÀñ½«ZÓ GîhòŸè¡²ê²d*—3wVÆ Ó.àí=”ÌõVk¶qõ^'ЧHlÂ<‡¿Óü ü*Ö¶¨l¦N¡Ôd¤üƒÂƒS‡Qfó)Ég‘ê}Ñœ·²‘âFà­K@Š|É[‚§†jŽÛ(D¡¾3¯p·¿ï”äðÒ¤ƒ=Šš¤ÞŠz6e~µšÿ÷[ÂÒjIž¤œþŽàÑÉ Ã]…oKþˤðdy 4|¹ç•ÿMñG&e¨´öWp™òäžüªÖÆÂæöVmù7ÊI(o2ýñÛ•¦Y|/°ýä’;fãr´»¦j™+d$OÞñ;¶1‡ñý™rQ$¬-«jØ¢±«vÓ…­éQjÕŒOZ…9tùݽÂ^ç¡Uìg…–ÊÝ쥉õ^´½k¥öròdoR­i‘ÚoukKt'Ÿ˜¤ú¯€†^YÁýÌþÂTöŸºŸ3ÙÝ:ÕMnüÉö+·ï¡vÆô×±ÿ)þ5«!ÁÑÆü8)líÈsé·Ÿæ©OåϧÕuT’nì­6ÏÜ*õkò´ e©lC0à•â­Lõ^Ö÷?Ùi‘™s‡•Iâ 3ÈØa%­OÓ«ê•Lò€^ÎÿPµI\†V;[ôTôèfÓ®HÁU®?MŸáê³9÷VÌú{Û , aç>¼ò§’y$Àå£9ÿ™Ul†µ±Èü“ûž1ÿã³óý9[QNz2!’˜ÄÈÉ죪÷(4§?ºÓ´Nñ9+Q’ >¬@oo›œ>_e'‰«Ìܽ¤~ Ku¬ÿÛxüÓ+·ï5¦Ã/e>ŠG#•-Äè£Âw¹8­GÿŽV9[QNz2!’˜ÄÈÉ죪÷(4§?ºÓ¼>Éäã’µ að´•axó|Üàñòû)ÐKºŽŒòIŒþáG…¸SÙìœ3ÝKUSéÎ?*±JfvSÊøŽÙŽöUgp<(^ÌŸâ\tÁ›a«‚xþî'·ºšzúKó4~i9ü+n¸à{5:ÎÙƒÇ9ƒ¨ÄÍDJ8w8•Å«RŸOÓÕgœŽÙ÷Td¥ªí}–€]ëõú­_Mu;…-?‡”8*oÞÍÃÔ+Ô~Ìe{ëáAOþ´•¬V}·67zñù©Åxb†6òÕœYoTFq蟨2è;oŒ¿øìüÿD¶áJS”qe2 ¨)—(4Ürå 6·²u†°ì‹’´XÅu_óŸèîu__o ?¢Óµ,ù\¤ƒžêž±f¡ÆU nµ®$ò”Ð@Ü9 Z±Ø«ºi‰K8*`œQ+Qÿã”¶áJS”q™‚™rƒMÇ.PÔk{ë aÙ%hÑŠ1õóŸèîueƒo ?¢Óµ-Ãk”oóÃÝSÖlT8Ê£­VµÄžRš‡!KR;•wM1)cÇL(•áÿüŸ—ê¨Û5ßôUlú­.öǥČޘ[a…Ž^ Ò¤[,û§ Ÿc•k>©“p´MXNÞ„‰îé¼°©¬gÊWŠ´®“þ..Ǻk‘òò{8UmoଉF×'·¦påærÕ§ø†zÃdœ„5ˆ,8VXÉ9V4ö¿‘ûsû v tŽºë´¢å¼'`§µÇ°þ‹Wðí‹•Œá›qëÙ;D·œ; ¶“Óåå4ŒáÙœWˆÈU=A³C“Ý^‘øêB2mö®6 mþjJÐéÍksæ#'袽׹‘Ù2^¬[eªn¥.áØªZ|›Ýk6bnŸ Z ‘·£"t±tŸÈRÑê3iZva=')a5TfÆí] ³nR×Ì¡ÊZ¢Iâ’ ërs·²¥bzígP–ç'ßÛðUçmˆÄŒýž1ÿã³óýZ¤áIÊŠ åG]U£¿º†»cᨹ‘÷RÎù8Z6•µ¿(ü·˜¸õ+ÅÓn–/À¦É±Û‚¡sxš1(Ü;¦å½–•®ÍMØ=•KQ^fø»û)dn×-J¦ÂTêD9+Qôé­Rp¤åEò£®ªÐßÝC]±ðÔ^È»÷RÌùxZ>•µ¿(ü·˜ˆoºñlÛ§‹ð)’ôݸ*7Œ)£ãºn[ÈZV»53´öU-Ey›âïì¤kdn×-J¦ÂTéèrV÷ÿ/ÕY®úSº ;…§[Ǫ–ˆZMöÍÒ¦û7¯híÕiÑç„òXpU;~…WŸ!uÝVa#}P¸.@%·/ß pËQߨ­B«´ùÌG·¢ÊÝŽB¯k ­Á ÁD‰‹_\ñÙG+dA¿ú”Éeb“ÝØQã²Ý”ñ”ïb¦Œ·–¯‹,)¶ÚþêR{´¨µYa8r³¬Ëq›xGÅÕÛaíû3€¨Ìiìkø`à*:¨u§0rܟ䥹¤Ù´ÐÀwø€¼@ÍHJà~_¢Ò#yqZDXªúÇæô^!ÝžëE éñì;+”£“æéòDwµPºæù$L-xRUÝæjˆ.– 1åòŒ\åIT8mW(’ã+G›Óè´kŽßÒy?³ÅÃ03óýj™n*0ªRßÉMˆ0)'û‘­»{÷Z&nI½ÿ(R5¬n~èWlõ%ÊñKüñ­Ü*– «c¨Ü©Ù´b …Fì´Ÿ¹¥VÔÙu»½Uç Z¯³r‘DÜ•¨°Aªd¸¨ ©Kw%60À¤œ“²5·o~ëCÒ É7¿å FµÝ÷B»g©.WŠ_ö±­Ü*vK «c¨Ü©Ù·í£Û ÈToKIûšU}M—»Õ^"V«ìÚw)MÉZßü¿UãM ©ÅÂ9oöÿ 96œªvò2¨_0…¶Ý¯½½Â0¼g¦|Ã<+ÿºŽBÓ•FÖå(êÄ@î‰p‡ôØ£rœLN-+]¦.×Þߘ&¿ãêdPZ©#Q¼=|#_Ùtd5ä|É®VQOç²ú9 s3Ù[«¼d)‹à*=AÍìQ½ ¼?‚š=Zr·9cÕŌ%½Ô·l5Ôrލþ´Qt€'¿Ñj´«2/úVãpþKC§ç|…jóÇшýì-Bô±Ëˆ¸Â¡â+È8Ïà¬C[W…¶leƒ<ýOÓñU%Ò«®:Ðû Be^™Àä#E®PÄø õ@,,,-ªX»YÕäë1V˜O/ŒÂÏÏôE¸ AʯNTåW„5ŠËËÎÆ¦D" NÓŸ~`СªÊ±ˆ#ZͰÆôÚ‹·¿+Äç–œµG. ¡p°¨¤Na…Û›Ù0‰‚wVzmž«r®³pOá@Õ¨±Nn”r«E“•9Uá b²ò󱩑‚Ó´çߘ4(k2´bû-fØ`éµn~W‰Ï™…g-QË‚´û……E xNaû›Ù0‰¯;«= =Vå^fàSûá@Õ¢}ÿËõR±²´Æåâm$è÷KÈîGû*v¶» ­Œ­'Uø;7ü¥M.Ç· uJŽŒ÷ôüSx;J©/MøU%ÜMÍyøPÆáئ»)ü(åPΫ\,Qj!6þä%c–S‘Nú!&TƒÔ)Û»‘Ý2ÙaÛÕv°•¹ äf„ÛÇ+ªøŽXT:¼£‡r«ÝdßÃÖ§éEð{£×œ á“8vp®Õø ,ú÷RÂå¦UØÒUî>ÑÞ¤ûÒãÑRÒ[ Äq7.^$­ð´þ¼2SZ–+ù bÊJ#꣰×öL>é¬Âc÷¬@&n ÒIˆ¾»½‰ÆbgüöR·„æäªñpªÀ§“kv…xä¨bu‡íjÓ*2”[óz«Ö›U˜ÕéÌ…5x—ÓõLNò•ZU§ÚÇD#p  vB*òŽÒ¤óa˜•DÜy¿d¥'7%W‰UO&Öí 8öòT0ºËöµiµNù½UëMªÌêôæBš¼KÎÓõLìå*´ª…¬pTm7 Ñ:dvC^CÚTž`§f$Q·hßòýTïHÞÅx¯Ln¯D†üíä'8Æïª¡s*gPw ç\®=Ú§q†N}V½ÂÜÜÞÎå 0r´¹·5Z|¯IÖ¨YìµÈ¼€®ÎZÍ_‰…4ã…Á9¸QÈæ¨m{¨¬…„Ë)–ŠzÝŽ =”¹<Žé–ࣇ-B íUu ®ØõEýYL%Mº»üþ‹Z…ƒÌÕ¿cðžåžUBr£ùyþ®M‹]Ÿí•^–ß?¯¯Õ|.Z¤‡ìö¦F#j¸ÇZ~ÆöPSmvà*·aÒÏPòånçŹÒ;Õ?N•’–±¹j¯§퀫iÌ÷QRcTPíìSHúV›(õáxˆf6)Âk2åZ,¨Ù±¨7yÜSyØÕ¦ÂÚþoTýA7ŽêÝÓ9É*gî(/Ñç꘤fTd°ª³åT¸æð£œLÜ·¦x[w&;<f?>Po Û~ÍNÔÖeÊ´Y*6tÚƒwÅ8Zl-¯É2ñÝ[ºg9%LýÅâ4yú¦)•,*¬ùU.9ª9ÄíÁ[zeîL9*Ä~| Þ1¿òýVª|C Y>Šk{Êñ]Z×^?•ÿÝG'IÙ „âf`­o…·ÒwcÂÕªžŽïe¯Cש¼wj2p Ñ&óaKËÀ^>iôZï(ÃÔÃ,+R‡¡dã±M+nåÑB2rà™3“g*E!ô+¯°írv¯Fæ}£UkâAUÔêŽkqü#Ä­ìW‡î H”÷x¢&Žœììá…«qX"7I”÷*º|Óó…Vƒ`åßé[©+çw©+n™•;w ØZÅaã ÕˆYÛ•cP”ðÃ…£Yø––Ióþ‘ zâÄþ½‚ø˜k÷áElÍò…roðenB×FXÕ;T1åʤ>¨Ü'yB‚0ÎJ’àˆ)¯™;#a倵vï¯ù¦¦Œ§B™–ZǺ­c )¡3Ž=T‘îåmV[äSµC\ªCêˆÝÂw”(# ä©.‚šù“²6~Q8 Xnúùú¦¦Œ§B™–ZǺ­c 9¡3Ž1Ê’=Ü­«KÝù~©Ö]ͰÅñ?Q¾¿ÝküegWwÍéø óØ­ןaSq&àª8jz~ï\P­Ã´º2¥„°º?e¢gxR3jðä‚.ü½q®!‰îÜå'ÊVµæ¶D8M)¥‚„HB› lJÓ‹pBê¶@§{TwzOéHº½PG²Õwiò‰™Ø¯ OèŒ/ìÿèV¯L¾Äîí+à¶É‹Üe¬MÕÓ™ôÂ×]µ‰•¤ý(†IT´(«y¥åÈÀ=Óøq³¦ÀßÚT˜ wÈ~P¦­<½Óôrg ­;N±BÓ^á–ö+ÄZà†]ËxËJ2êSo•V·‹•‰Mþ ZÈ˧j­J›B ÂÇ©SÝð³>C’· k“œ\¬C׌±M§Mìƒ\Î霮ˆ=—HµA)ouVƼe7•µ« ò)›Ê­J›B Âú•=ÐΖgÈrVâMrs‹•˜zñ–)´é£=k™Ý3•ѲªóðU[Lvñ”ÞVÔZ´Ñß’‰¦ZÞoP´ÍEÔµã-Z¼°=ÌžpV§¢´ç4yJÓzŸÐÔçý¨ HÔݦ¸Ží+U•ÒÙvÎÊõ' ËÀà­*›Û6S¼Y:R…v̳H]„בÝ=åü+‰Ù°©t™à/ôÛî¦Ñ°>êmKú¦ÕŸÿTÚÓê›^_ýSkÉÿª¹è¬oŒïGss7­R·Ä ÇóáÍKfqÛ‚±F+’ŽGp¼2_RÙ®þ=Gâ?Ýj•‹¦Ü~ûUM=Z0þ¡ZÅ&GU­¹ ^Œ­I‚µFÏ1ÆþçôB¶“+1¾o¯ÿ‰ÒaÄߟáÆþ£C¿iR9¾©ÛžÐà éóä&»sQî´æ“ N Á-¤&¼„ÉÓ%Xnì+7E\0ä÷W_±¹Z}¼Îîê[¯«  ‡×ºlêWò{-˜–n³¾HÂñUî  ÷v’ðñÜK—†Ø'ŽHÏ¿÷Z­&HçVœp­èv wÙ„jXj©FB{(™ÓnßájÁÐZê·ÕVÔŒÜ â2í¨O¸–fW@w„ËM{r§c%­SL,oV$d.üP«º Êm8Zpá…Ÿ ä(j1Š=­ìšä?$KLˆzrUÑ.[qÂ윬XÇO))í{Óª<©h¹K ‘”×o^ûáC•Ø I›œ+#cî¤Ò›è™^HŠkQˆ?º’®`ÆPänMå=¼#\¶ã…Ù9X±ŽžRSÚ÷§SyRÑr–)#)®Þ†¹Þ1™]ƒC–fç ÆˆØû©4¶ú&A$G ­F þêJ¸QƒC‘¹7•Tc*üŠÃ‹ß•á= ˆÍÙ~Ê:îaÜ;•«Ø6¬Ø+²cÀV>Ñåhõ¾"èöo+N„Í`«N+Ð~?>І­M؉Zä¨þT{ÃB§Æ"ƒw/‡F¿²ø”4Ò{¡§›O TYê¶m hþ!ÿDÖ5jnÃv¦Qè³qîTš£X×»»­iïžè´¨ jÙ÷^ˆ‡Jâ‡Ä; ¿IÎGñ5ˆ:Œkråï‰9ØkFqþ}U]@Y²K{vSÛÙp5Jñ:ñõ§VüOgÝý”Ú•‹$á¹ÝÜ›ø¦…±mÊ’¿¨Pº£§7…~l 2Q Ìž‰ìt‡„Ý<žèPhî¾Ý>­\+ZCdbž“«¿•á¨Îé%£éñV­:·âxöuÆïì¦Ô¬X9'=ÎîäÔж-¹RWöPº£¨u¨Íè—¦Iª[mfzÿdÍ>:6»ŠµÝ9ïè˜Ü1îV«?¢#ʼ7CmwN~÷öZDB<ÊW‰-b&ÃùªÍÃw­ZN0¦(Œ5iÌösìšÝÂqP  é}t£•%F±=¡©ò4-äöO O7tý—ÈÔ+õäÜîË`kU¼DÒÿUSb|¡ƵžËB”S€½Þ«Rº&‘ÎAêG ¨vþÍ/a 8+ágÉ–^[ÏëIlµýðá¤!5‹·9¤(aéý@yiþëTŸþ±ØT-ˆë‰fáþ°ÂvÁ’ª\žÕI&kCdÇzéúû˜âÞPñpÊiíN¨g.@ì 97„×eeeeeI0j½hØEžª¬"¼B0¦ ­á5˜S»hÂèòäØšß”-žéÀ#ÝØ&éV§ùcÊ~‰~–ÄU­9ó “ÆAü†ô“TØ}ŽC>êõ÷Ú;^ü7ÛýÖø‡ßL–«F\r…èG`›z4ËLwªcóÙ5È §G´î7œ¢[ ÀS»  _Ë“b ùBَ而/`›¤Ú›å)ú%øN[V´çÌ6Oð^ÒM_ˆ}Žvþ}ÕÛòZ;d~ì·Ä>údµZ2ã•ñÐŽÁ6ôi–˜ïT×ç²kNiÜo9Q)N⼡ü (ó»úÒë; Ä’õŸÑo`­»hÀZƒòì*µŸvvÂÏT)Šñ6ýMéážjv Ë<)16¨Ë¸”[•)^£Ñ‡ªîå<瀪×/Z~•»ÌîÊ8ÙööÂÝò+Ú³IÄiÓI1MhÖà‘E¨Œ)Ze)¬€¤àr®3¶…J˜ˆelй¨í8Ó¥.M%žÿÅÕ0¦ñ4‡†´+þ,uwc»ý½¿§^~·]ñê>bþÞ›qíüÿÝjôfÓÞyË}ÿÝŽÊ+S•YýÔ=Ê*¯QE#Tn=ž˜1Ùc(7Ñ1xgG:¥­ïFÿS죋kC§Åh–¥8‘ä…z\)¼îÊðF†_›Ò RV ;–¥ÿGT“ÝÊ´~c1WdÚÕeÛÜž0´úFõÏDX#hcUzæG-;Oò&Ü5jÜ4Øùr·©MuÙq@ݽš×»º Ecö8nE™à-»U—瀢«·Ì䀧óp‘ÇË•‹áœDÕ=û.ûËãfæUuú¦»xÏðìÀÛ1˜ÜªP ‹ÏÝ^Å|¼7%^Õ¦Õk:»}=;- ËáÄ/àŽÊís1t‡Ô-"®ÝÅY·$Q|<_š»©>?,kI¸.4µß0WQŒoÎå~ø¬Ý¾«Lóž£Ðx Ê©?VRåf^˜FO³ÊŽ~¬YYëÇ€y [†ÜDÅÄþ¿E^«íJ&tc<õöÎUzì¬Î›?c–EªYCTÓ¿ÑM<¡I¨HÎèê™q•VÌRü…jšŸÂGˆþb˜ç>Låia<ÛÕxŠ›b°xáËRÒ]Yûàù}•:3É˸ ¼0EÜeW ü¡1…@(3XXXDe©e SNÿE4ò….¡#;£ªdyÆU[1KË ÕuO„l1Q—>LåicfÿÎx^!¤Ø¬GZ–’ê®ßʩўO3¸ `‹¸Ê®C¾P˜Â†hc² /él¡]¬oüú¨ã œµ»ýO+UÉUÙw•¦i¯Ôí6»=²«N:5Ûc€›UÙ=—ˆ§6gé±KˆÛ´+ò¯\§ù»-Jø:ûßóc˶…B£bÞ˜íüžÕõðÁÑ®#¥v\Œâ>tÆÉ1óvQÇC•5Ð;'Ü'ö‘”B“À]0ÏÅú§«6C;+Vò¤ŠwöRºHµéÇ%Q¬÷”Æìn?‰u³tË¡<«,Ç'Pwnrßoò¾"®7ÚÅ̃'éôM¥ –î‰FÇ:<9Vƒ¢Å}ϘôáNÐLƒ2¹iú$Õì6XNGè¼G~xe;Z¢d²O&_ÉZU7ÎöÄ;-BÏF¥OäϺէéÇ•VÏV/ÉP»¶Á¬ãê¥mª·œè›–Ž~Š¡’fÈö`»ü²ÓôöRo¯í?°§7)ì>‰Í÷RFҬъ@µj/¢w7²Óùí·gâµ]<͉Ü(!Û8qUÀdú/j6¿ªˆÐ2U £»ö¡¤CN°³?¯`º ò¨F8 )Ý'`¢õ «¸S›”öæû©#i Õ¤ V¤ú.ÜÞËLcæ¶Ý‹UÓÌßhÞáAÛ•[ ‘’7è¼A©üDØ þª vÐ2U£»ö¡¤CJ¸±?sØ.°<§jŽŠwIØ(ƒ½BjÇí†Ñ…©Þlgez}ËR± Oåx7Cøzò;¿æiyÀWÞ*Á´wV~bOumþŠô™+•á­Û“â%P¦B«gê3¿ÌîËWÖ·”=–âó’› Þ›#쥶ػ©õ2î}À¢îȬ~Â(ŒpOÝ<†«3À_ ù“4Ö7ºøxãìÕ7†Ûz³¬XàÞ„”Í´<°48þ5šÁ¡ÒÆÜ’º/†MÝ.]îOóT¡±ü—IMFПҮZ›!—%¡ËÄ~"™Ì3Œû{-ñ߯ћÛ-?_e©JÊÞv7•áϳâ^0{}¶lÏ/F&’=V—+(íø£ƒœáx¯´GÁ Íw<*:ŒšQÞÍÅÃIBŸ^X÷‘1÷á|•[G§ÔòUZ­{[$­Á¾å.ïu<“ÇÈåMò»‚¨Y‚úVøú…ªè‚fWp‘§¶;Éh:*3uLj˽ûãÓ…¨é°c5$Ü­éùV…@n„¨žˆ.ûÅ;KµkÌÁÂÐéZ©q¬y_Çû-wÄ1ŽóÛ€v¯-÷aœ§ÓçŠMɨ~ë”»½ÔòÏ=×ú›åwiö+ÙwJßPµmJÂÈ$¶;Éh:*G›o .çžøôáj:l5I7+z~GU¡Q¡j'  ¾ñNÒíÙ˜8Z+Un69•ü~~‹\ñ N˜—žÜµi¯» à->˜oÏÝ3…›“Pý·îˆ†Æ«–r¯Ù´¸©¥2;q^Ñùʼn•½¾§ü(¢é·`LŒFÝÅkW9Ø;«Ra\—)|îÊÒ´©5KÅA¦6”&5@ó¹twùe©êŸø£ì£cì;„Ø™ú©lŒ¹[ÔñÃT×IîqÎà(ßÝE¿îaaa=ØOk¤]„#O!©÷:'!ªm^i†ÓÙ ½ÑäçøúŽ–Ëƒpù–™¸7§'²|aY5\v¼rµX–pç Þ)…”sî´vIØ¿¸W4ãfa§ª†­=># ÆáØ~¥hšÙ¹˜­ù¿ÿˆ*Ö’lÛNÊÅ™)ËZYù{ŽÊ* ²æù“*ÏñNÁÜÿ\ÿ`¢„–´ÌGð§‘ìì¾>7ðV·G1u™Áî>«K³`Äù1;²Ó'¹¨YËÜ@ƒÉx¤ÚÓn¹ñ;ƒßÛ?åPÕ¤xãþJ–ð«×1 ©Ô„òõ$캵bx‚[ôZּʯlT˜Ÿnøü~«QÓj_ª-¼aÙÁôüÖ™V³'11ùr¹ðúA1ç·sõTæ’ùÞ~Uo‘©Ÿ¼õ÷¦a<3¼Ï'Ù´qíø­5ןæ.Üßu ~¦ŽTÕúys{•wOžGolA 'Ͳ r>ˆRÜÝÞ¨Ö²ƒÛ>«J¯fçíýS"c wþV& Ýï…PrÏìµh&±Ø¦2ç{~ª¥Ë³Î4²ß'®®=•[õ^DÆŽ3Ï÷U4ÿƒ•ïвÍFyÄ››ž}зB)úeÎÿZ0þq…ÒWÞø ö—ñls«IæUþ†Ùáf÷ >áòš›Ì?º=J9³;üÍç…«ÖŽÓ©Î;ãþeFµqÉËŸÛû*³ô#þw(%?¸U‰ƒB·áGT³û-Z¼ÓìSs½¿URåË-Í?\ÿ\{*š…YZh˜Ã1Ǫ©Cà¤{Çâ¬3Pšq&̳<ûþ)·(G?F¾\GÅVŒ?œat•Æ·à+úWÅ1Ï­'˜}Wú,DÍÏ@9ü²uySaù‡÷CH©C6g™œðµz±Øku!ùÇ|Ì÷NÔkQ©á9sû<*³ô#nïÊ AáÛ#òµ{›GMªΙàI^Ñ þª(°¯Ý·cë9V¦õ*Õƒ#‘œá ü~&ÀóŸèžp›\ÊyZÞ ÚÑô£NŒÎíòvRIŽ«xì¬Y.NòS°CçvÈÆJ¥áÿ¿gù/‡lmÛátû¸XXN )föR6Y;'iîÌ¤ÑØ{­[KuFõb)ïÜU@ì¨s°gÿ£%xæù³£²VÆq…j“¾1ŒË“ôëíyn~ž‹N²3ià­BvÆÝ£’™¦>ÌòGßñGFŸªâܨ#‘‘í¨«GÈ?ƒ%¨bùœ¬j£´`ŸÉ>[sZÜOåÛóô+á$?#,'å>ùþxÇæ¬i÷CÆóž;€=ù_ ÇÕ3“Î1õÿõTõCFß/=ù=ǯø@CÐßè¬Á%Ç‘—>ŠÍy¡²ó.#ØqÕi×^Yxú•½»wg…©^/ò×ä¦i"ÕŒ<`œüqôú÷M®#²ëfrîOüïøð¾Ë¡ÔÏ zÝYLÂ<ãñçª:²ÛŽQ+½½1ÿŸËú¦Öm´Aòùy9ôãÛŸª…×+yHÎ3üÿüüU}Tvù(íE/ÊïÙ%¨¢ùœ¬j£´`”ùmÌAkpÇËþÅ ²]‘¹„ü§ß9ôçüÔúgA™‡çwð=ùF«TÏžHÇÕTõCFß/=ù=ýÿÂÄ= þŠÌ\yÎ <}=ÕšÓÃfC.#ØqÕi×gl™R··nìðµ+¥þX9þÊ=$Y±‡7áÝøãéõî™\EeÖÌåÜŸùýø_cÐêg…5q,†qqøóž9ÏÕ 0¶˜xôôú¦T–Ürõ]ì{cÿ?—õL­ -¶rqåäçÓn}Ê…×*®Æsøç¿òçÕWÕGi ;PËò»ö]² a)Û¦~ç/èä#Ç'ú*uD »tB65\µ•fl­BÞó±©ÅxOÃ…Îì}êšÁv„È Ï+P²+³kÇu¹êi0¬Î¬Î\P¥HåGDž÷™þVªô`¢Ý±„Æ:S«¥I7/ôËÿx”rS˜=QÁ{£µªiöze?V߯©êW•ß*ޤQvÃÿÄA!1"2AQa #0BqR‘¡3b±Á‚’Ñ$4@CrcáñS¢ðÿÚ?íí¼)‘aCÖk2ZØx€×<¬™ j^Û<ßkÑ2ç|Î3*«µã'6ÅxˆÎÔû¢NSèŒ(‹ÚéS1n·UFcAäÓ5°ñlÇ€ß}9+µwОOG"_‡%¿3n4ÒsE¨z #=9-¢¶ñ ú¯ÆbÙŠÕ²à{9+µJ4§ƒÄK£‘10î-ù›q¦“˜E¨z #=9)¸†­¼C>«ñ˜¶bµl¸öRU³0¨‰ø¬ÞëÕRìÑk†‰7>|á\*šŠ©¹®º$å´=ÖÎHd!—M¼”ż=ŵ0³ ²jVñ¢Á…‡³3$ØQa¶$8>gÑaÓL«‘[q"T8•F~É®òº‹Ϧ´ç^+€ã—Ñ„ˆðß—‚€1pa¹ÄNìFÁ OÊ2’†èŽ|Â4MF#Ýðü¡B„ÈÚ·d[5 hõ½ùÃ{|•ÌÕ€[ ’:¸’3À,F'Xíciœ­Sn¤Ø’<œÕÀ©>ÝV’·e§¯É\ÍdÃd$g€XŒV±Õ¶ej›u&đ修IðÖê´•»-)ÞȰ2_ôØÇ¬3ûhÖ4Xª›˜R⌙…5ðñÏsÿI椩*¦‹¬”ÅŠ¥Ö*N pö›ËŠý•L±@;Á²º‘u%M²pè¤öÉUøôaÛwqä¢G‹ ¡È™y¹©üU°æžSU9Þ®(;šs8…C÷‘•¨„o݃ Q4Ä{Töž"K<Ô9r’†eÁD²¶m¾î*.5γć¯4bcâMMS•ÓÓ 祽«) •7u‚ԶͬKó›€û6’¤û…q58gت\)r“ÄÔ‘C@íÙH]mu‚Ô·t\¬K³ãôShÙ9)>㚸šœ#ìU.¹IáL)4ïdm´2E¤)qT”"0É͸)±¼ãeãªÉ®…ká¶ýôüOÅ„6?3ñ¢‡©ŒÔ´Iÿ]p¿0¦ ²¸ð¦Â­0z)8‡z…7î›ÛªðÑÚÿÕ_Ätgp ± ¹ÍSî±ð°˜)û¦üC¤ÔÆå>çn(†¦ä¨s©‰Íj¡ÝÇ}ÜÖ²[.@¸uõM{sE²ÎãÕ»‚k¹"9©tTDp°dÀás%ðuj°ðËv¥Ç’!›hojMËMOú) Ô¼ÎX‡Ý¢t7*J›~ŠaRð¶¶™ÏE‚—ƒ&壪©ù© Ô¼ÎQÿwöEŽà©*mú+)<-­¦sÑ`¥¥Þɱáµâk^ÁêªZØ~º$óÝEÙ÷R* 4HæÛ)·,Õc‚lxFO†f,J§‘ŸüKqeì;PÃx(ºØît0Óš¤Ê†,S0Ñ;Â'OŠÖª¾ÉСÊ1£1Á±bÖ÷\—)ñèƒ_š›|&ã ‹ÃLŠÞ!7± ¦¿E3š.vAkò…Ô©ž(õŒA¢’«n‰·=2Töä×^ g4\ì‚Öå ©S‹'µlŘW iQpgÈfßDÞÄÕÕGD¼ƒî«r’3«Ýب +*Ú/¢h9Úšº©Ú? ˪­Ú$¡õ{»+*Ú/¢a t9:M歿‰²ÿî©*`Xªx9k¨qPâ8Íð»§{eöE‰ÍNoºc½´ÆÀ»Ì+o¯¬g_¼årÖv9©NÎñÆMt1"àBke»–‚ª>\”Ñl-§ÜŽÉ3PßFÕ`¢æÙ~0W‰öYøp£·Í°äÝ2U»‚«‡ Ñ&ä§¢÷Ñ-3hÖ´lœôSÚ’/u¤ªáÃD´Hd§¢÷Ñ-6ËF±£dç¢.MÅCÏPª’¡ß‰dõa ¨Ñ>J.îÇdǨÿñD y P<œÑÿšHø•75PÌfŒ7#ż}¡O«TŒ¹ú'LäT3§/6)Âñ~ƒ³H°SwÝI°êS©öPâ1ämÈ©¹Ç¢ª$R:,Éðý)ºf¾‡þZ&rSಲÉX Ð3Páü hŸc¢¡×Så9v=ôÍ|;?›DÎJ|VY+j?” ìtT:àªxpì9GÙSårefLq¡þ‡Ec'"=Ñl¬å (ÿiÿm w%5!Ír¹[AC—Ì>­ç<оHE®Ì-‡]»MôEžG榙ÿéö¢ìl¿”&þ[§G2.ITà`OóÄþ˽kôB+xøa¼»Y+QõW Ua„ÜLñM|ˆo9!0pdéõ*«4rñë¢H½Ή¸[FK%²ÏªÖÄ59Id²VWìSÇ‚‘ ]‰"þ<'3¢nËFK%f}V¶!©ÊK%’²¿b\FJD]KC—PT¦€…î'åPuÍ:Í[jõ’sÓP¸CšðF9}›B”¯Å4‚PZÇæ¤Èk]À¸d–Kun­Õ¸· Ý+" ¦û«f2[n»lîªX s˜ ÀNÉ‘*Pñøf—áò”×O#%3iÆÂ}÷[/tùˆà‰-…‡òó<ÐÕÕ?TÚá™”ØC‡†ϳš³Ñ9©lª;–ŠŸÕ8B›6¦ÉØ|DBóÈž0Dt…¤|9¦éÕŒ›ú©}7r³tf¦µmÄ+ÃV d«…}:æû¡Ù dÕ ¯¦î[-Ñš©jØ*!^°[%\v5Íãš 愚› ¦üPÀ᣺†ÑYi̪Ž"$if€êƒXÑ2™'kå2¤ÝÐTº¦† U±Åošš“ŒÏ%³î·Gh*Ü,º ‚"ÙSá63Ü'S½y'Ås@%b1u9­ŠC?tb›A#eÅÒå$"›Up‰i¦Ò²‡ˆ‰·»/æ ¯$H&Jþl+³†ó/CÙ¤™gH©Ee•XzgÕjó{î⃲pUC%…m9§Ãõ ! ¹[5×D³*ݘÑFy9­åž‰8jN ÅK—`¹H.º%™íEˆ ò s[Ë=*pÔ ±ÜT¹h*C&­iQ1q·aŠŠ|h¦nˆêжM^ˆÅ>ËÑF{g>CÑC…>!TÏT4˜§9Y¸ÜèÍf³íjÛ™ÍRÌÔþJª;©nd­\Èn³û£ÖË"Ò o¿þo&¦“è‹àŽiÉÁU‡2g0·|AŒÝa³¯Ÿ²ã§Ñ[0µQŇÔ*^jk²*MâŒQªa¦gŠmEgŸÃmÈh’¨è“Uôf³Ñ1’?š#B¥¹•¶ù jšÉg-ÓR–™*މ5_Fk=à¿åKs+iò@Õ?u’Î]š”‘A¡›ü>üñ?`¿3´uMj‰jšêSGº•ÓBoªY‚iÜw¯bÚ6£.ÌݸիqEüwX¥—T0²eÜy•þɾ¿²ksAB1;Üâ0Â+ÎÀèÅø¯‰!t^ó)ºeÑd÷Ó_ÁÖ*§qâ³—DøÍwxÆÒ=x*÷AþËmÔú•µ¸øEÇ‚‹Œ>sK}nÁmÄ—ºüVýVËÖËê órP8Æý•dMîSˆï`¤4f¹®ºeàYmÄû¯ÅoÕl½YÕlù,;ß²¨‰½Êq소×>Ä´‡¹;uƒ.}£D»žfWünP†8f‡EÐ(_ÃÚlÁ¬©Ëíú¢ò‹¹¯DК4?vjOŒów™éÚÑž‹ŸbZ&r dI¡RÁ~ ^g! Žetj°°ÐÙ!? †ºGF> Éó³ø…ŒÄî=¼ú øn6Œ“§i9¸Ù0µí JøÏf„Öº4MLö^hSÒjñôREMÊ–ø-ÁÁ;Qa³u°ßªß>Ë"²+iÀz­˜Ãú•m ÉaØ ˆ{‹šxd¶¹[O[³ö_€?¥_ߢ°-[&jþÊØoÕoŸe‘Y´à=VÌaýJ¶d°ÌE®q ð6[Ü­§­Éû+@Ò¯‡oÑX­“5#ÙC ÝÔµÕ˪­ûî¹UÊ©:‰Øˆ§iæe3à…\.Qy⇠ƒ!ƒÃ¿¸Çæw¢£š“DÉU:ïÑ&Ým]]Y[Àº°R`S{•䪆rñõ˜svùy¨˜8¬-4¶Þ’»È®–Òo  Ø­ÚçÍ8üÉ£€¹TäÞŠMkTH›*‡iµDòÎèB†ÊBXn¿4O™(‘ °²uó*ÉQ"káµô>-…–£øŒGn›–}S¨&N6‡²åÞ0è¬L7}‘…y:4gÒÆfQ8yÌp)ìL¶mM l´"Áw»4È­vÙeTGETäÞe\¹ßef¬¼—.ñ€E²ã ßda?y:4gÒÆfQvs {m›SH-Ã{ŽÒdV»`³eUÄŸÑU97™W.wÙY«.Ì‚¨è×8Xd¤¾î ›õr¨­{÷Y’Õ·!š’žLwñ‡ô·EoÍYuS+“tH\­¥Áw±@è¡Â.õEðe>\øŒ+%ͨD‡‘ñ¢Æ…·¿0¡ÅÄFÔ±×cP9é“¢R:'; §/‰ÆÎ@ì4ñ*p„œ «fäׯá¦[9¹§‚\íÐç™ð2|ö%‹‰ª-Ì:×P±˜\lšÆü¶*Mf ‚Ó!2¾%°ÃÌW€PãFCÙðlU1E]69 ú÷z¡ þá—˜ó9 cí>+XÜŸš„ÙsC„.¶êqN†Ø‚¦Û<ú ZËu@9Õ»UE4ôR†'áXªb‹*ªlrB%{½Pƒ†q—™ÈkiäV±¹?5 ²æ…]mTâ‹U Ö'ŸT Yn¨:·r ¨®§¢”1?0 ÆŒ—ÃAw}ÿ¨S+V2Ro´TP ؈¹ ‡Ìy'GŠé¹æeTtõU=]ZÁ_M¼jLœº+Ùf¶òØP†ìüzÙh£"µq[LFYÃIÕ8…¹Á¤'C, Ãw5]7ZÁ‚ɰµo"!”Êî™/N ‡å‡÷QbÿheD0ö£„–§ÖBi"°%1؆¶¶òðn‰„iˆª/¡C ‹‰µä×*p0°ÚçXLýTX/„*‚ìÀ½+ŸØª ©œOʬڜx'DRò„øØÖÉ€ÖK2¡ÃƒTXfÚ·\!ˆÃÃÚóþTÓÆ\—Ц2ð.‹¡bª‰èPÂââmyuÊœ ,6—Zr™ú¨ j ¥0/J–}r+VãS8&Ÿ•l¶§èƒj^PŸ6$CÌóL‡ ¨ÐÝjt1hwóþTÓÆ\—Ц2í„á´äè¯9}Ï$ìV ÍÎR §*”¸,‘{ÜÖÜ“ÁlZ,Á¢_@¶·Š»”ÍΉ½Hg¢ËšÚ> ôY¤«BRt0··ú¥uP„^:"Ñ ?ñL‹ s"yxÍøllX»EjfѲ˜ÕÆJðÝ?-v&“UÁR’nXé4Ï-™ªqI9À]×'Á¹Z¨œEhÔêNe?ø¦½·’…üF³î“îPÙ&j(D9¦üf˜qs½ÄÕÌôѴב;[ ˜_í?û§F òÛ¢x8b[fe¶÷NÁâ l0~+SàbØ•#.І<:[Ä)ŽÕÊÕDãú(°cF¤À9”ÿâx\D^óm¼”?â˜tŸr›³²Lý”fáè‚÷4ߌÓ>".bw æz ‚kc¶šò §ë¡Q ý§tê7Ënˆa á‰lm™–ÛÝ; ˆ°Áø­âŸ ÀÑÒ¤eÑRLJK2Çg_X#pÐʘž¥›ƒ÷RS*‘’ hÍÇŽ‚»ºnó‡˜è—¯¼rè©eܦsRj›•,ÒY ëâ—wê¶Ü9½ád®æR¿ÌCZ—–™äGúM¶Á2(”jòZ¸p*ˆD¬l› 2ç?j' .×|®(çü­¹M‹‘5.2,–KY†v©¬¬åÕSí'›BØ`½Éð.@[xˆcù”¡TóÐ ÖB¥¯4Mǘ±MÅEÄS¨îÍåè°Ñþ%á²yÛ2„@æÉ¢Ã’˜ïs™ ©¢ÖkYL³ša0!j¥[…ÁP°Ø( C…8æšÌSu.ë’«XÙsš,Ãiéýу‹ŽÚʘ8ߪÕ3ü¤=€s3Ík5¬¢YÍ9øhÎd&H»™ò£X6…Óñ%º˜¦á7܃Å=øhíÈ–¦W¿²s_ Ò²zL®ô9‡¨[ˆgù–øú­¼D1üÊPªyè­©lC«›KÌTlM1!ºŽìÞ^‹ ;âL€ž|ÉB%m“r—ÄÇ{œÈÜŽàÂÖkYL³šatZŠ©p¸*pgí¯4Ö⛩w\•ZÖËœÑfkOîŒ\vÒöM¼ïÕjØ?ÂCØ35¬Ö²™g4çá⽘E\Ü:#XÝ¡tüIf¦$ß3~%9Øhín² J™^þÉÁðjk]NÉé2»Ú™êÆ!‡ù•ŒÐhB‡Á|l¶~b¥¦Ak^6ŽZí¬¢;—M â#û-\<ÔÊ“TÊ¥¹hÿú¢ð„Üýù**ÕAÿãf^üÔ›rª&Kióðl³WzßAÍÝÖš›`NdxŸÿÄ)!1AQaq‘¡ ±ÁÑð0áñ@ÿÚ?!úÄZ¦ôE´1ÏGk…,1Y}ó­Ý s²<3’Ú¢£ÌÖÏ#Óª,Ï[Gþ ›¸•[ƒÛü?—‰Œˆm-Â[ˆ –]ê™}¶bS7þBD%„͉ï1«’Q¡–j5žéM9°Å‘ÕŸ©°ÅÌÆDö×lKp–•dEfîËÒ¿¢G³ö TIÒJ˜½åérJ¿¾±Ð˵šÏ t¦œØe#«?Ca‚7™Œˆ;ì§òó70•“0áÇæ6ƒ-¢„óS-¦A‡Êÿ°²…(tb É)üÇ3 dˆ“U¯Ó¨»•ñaÙR1Õ.ƒÏæîC8`£tæÖlèý,e“w6¤ï`;a¹ñÈ– òDbv¿þ•“iÕ­k÷†­h곈hƒ{ÌJmg5n6±\41ÖtJ®Y++ aÛMäJkU1s*òÂWÝ/ÓU[ÖÐè/[ÇÔ­4–>‹ ÷î` x—Í_ö¶a¹þL—A¥p´Û¢“ å(ú&dªE­›^‡ueøŒËn‡˜½‘åMq¾bó3@ó-ÆÁ+µ–>‹ ÷Îù1âYï1‘æCÿ£ÄŽt W E: dá¼u,è—+*Ôk¶xfò!ñ–êûQó²<©®7Ì^cv2Ül·Tþ^eŒ“y/@oþL Ûß"d*e("ªƒ{.’˜ËËY”t%K_ÐË€i™.4fn[s™¥Ç~á Y\/D¶˜ÅÎnÞì•¢˜m“£·™ÇNDшԿNeÆ´#„K߈Aª:9~RÛo0uPSž_î‘LÅö¼0V¹ËíèF›I©æ5QL3S$¡åñó‹ˆF{}¶¦Ãtm!]rù43°ÄR8j-"ÿÐSˆÐiÎýŸ‘4/Ò«ùmôÜ_¡;bá6ær„XŠ«C±ü%ÀA蟟Ñc[‹ÿ®Sqžº Ì0®ú¾Òêñª·/š‚ÂÅiOU=c¸Š¡›èâýôÅÂoÉÊMÃØþ܃³ƒ¶þ=¥üŽ—ø…hJruÐ@_{š¥óÙª·/¯…ˆÒ6žªd\±ŸËÏ¡(@6ÞF‡Aé,p`4H)ͺ"Õ0?u"r;';¡onVœR³òϸõ%vÞD^…$°´>`šQÔ”ç]™Nðèí1¤/ºY,Èj³ Ö$:¼øÒÅ7F1¬]¦³c£4^A5y¨JÈÈhGJe°&ª«•“ÀX±b‰Z%&°Š]­ÄÀ ÓIEÕšÕÜL‚ãò›à;Ö¼DZé¼OoÚ+¨s¯Úé*ǵÊÜ­—”—RÔ:0ÂårèW=¹•Ïc}cKâ;oF>oǬå¢YÖ B&è=2_~T1¯º ê ‚^Ì"‚ÆC]†öŸ 蘘cÚe;MæøbšûD©¸÷LÄf–"?[ËIJ¬„MT\¢ú¾ô9®ß 0G;TA¨#^PÚ_„™I‰†= {&û|1 }£TÜ}ˆÍ,Fêóùyª¯ · ém3p›WÌfç ÉÃ`ÐŽ+OïÿË0‚i²¾/Û§hÍ[NIÙ–h>è½&Ñw hË~YhDÙ¡ÖèíÍÖ¤o<±à±únejšnαo"ÒPw„mwá–k±¬Ñ3¥µ_Ü5Jž â¶WvgóFF²åƳ´¢÷wÄ-ØÎwN¦â(ÏH‰dUЗ=Y[â5bXfO'ñ+ L¼æŽÁšiƒrSˆèû Àïë÷ŸBôK6€=$»¹™†A‡&¬lŸ+dE&¢×Í"Õ97&ûæ¼p2ëHšÓ>Þ‚dF&&R´šñKÐK6€=»¹™´É8pBjÁËû`) ¾èÃ9¾ˆµpL §øÖ`6eó ­>³Adb5)JÒ/0Ò›ïÄ®²0Ö˜zOJH¨Â;+þõ„®Bf"ÏOyG¸^‰RuÉ/`©–îú¼ŽÝþÎÑ6›ˆÙˆ)þÒªÅ=`LìÆ›{Aâhç´`Èj;K&>Ñú£k¤¹´O ±Sn þZ%³®^õ9A’èwÍÚšÛ†N¬Æ/¸Ð t¶¢¹œ:3=#mq«s i 1º«¤¢âÅ‹¬ 4*Mžf6.Ðh‰’®¨F0èrâÑ @áŸjN¦¨ç¼Á´º_»1ª+’½>ûñ±p Ál"—»Õ(rÃÃUЊÖ¶÷ ¹ë`8ä@´Ò^O™b»7„ËäæFœ{ÁTÈṳ̈"Z•†&¼RÅÂ…°‹šˆïê”9a`ehKj ‰Ê¬÷a¸’[£´´ evo.2[ù¬Í8÷‚©‘ù™0"Z€ÄþÞf'¸aß0Óù€¤JŸÉfäC\ÐãÃ÷-²i¬4Öä°,ÚtæPT§Ü¿hp×öSy—‡wìźèLØ +䛟–iuô¦&ë}ãô\Î:„¶Èû³9¥8ƒ.[ ‰¥}¡Ùƒ?éŒ.Í¿á”qÿÉmÔ+Z0-Âόنϫ¦ÌÑ4—ÖwÏ\ïJQždmæàZba®Œ¦¶äåt ’ I®¿GC q¬µ–pººô˜Æ(Ø/§Î6½$©d\óBSÜhB޳Þ/ tX›.YzK)ÚLÓ2DÂ9Ô…‚P›«Üæ`ÒÈ¢dÔf;b ^R´gÒ5ûÌéé8”RæBSX%}Æ„(¹žñ.GAËKk/H…sSHAf‰Z¼êB”5›£Üæ`Ó¼]2j37±¯)L 3éÛ̺¤·cÌmFê*é_1+ˬÅRôc>eøö•Ã5Hhˆ2HPŽN%ϾžÑYCL‡Úyx1ÌSv•€œ1\öŒv«“$c.1oHó„Ê#'Ã4b<0ÚuŽqÑføœÍÅàZ¡¸*ÿ17Wƒv28 tõM`œ°ïå1è RL(¡Í¢7ABâèœf2öU§™–5$ØjÁ*êÕFâ©YÞ_¶‡m¦ K&ÇH@}"ÒL¸khÛxðY/˜þ=L;ŸIÅ|ÌK]JäZÄŠ‚ÖPÚ4à9—öòGÞ•Í3©ô+¤é)¦šÚ<ÇÂý é1MWvgRP1Rk÷õ³tún+Ä•¢)\‹VíIQ5^s&I@ÄIü¼ÆSDÈlÁ¡Yóó¯¼òÄŒXR@˜Žm:ü£kj¾½}°ø˜~°g;_2óMa­Õ£/úæhü‘@!³6Û§XÕ%I•J,‚(Y.à ך ÌôMÜraŒbú.CrÆU˜‰fª¾BĘâgÝ`°z„Ý®tÇüê<ªíó0Šì†î4%dUŒÑÎo‰¥™‚²¼ÌƒáFN–µ¤ºïÙò¾Ð{ T:º¨íÞ㸸œJd8‡ÖtØ‘4½_\ùÌÌB”˜Ø¶MeÛf˜ÓUø‚²Ï '.c“ÀN2¹¶i4ª´ Áº³;ùI{…§3~R†-8i!¤ûó1 Rc#»™e»f–"Ô~&9e²åÌsx%'kštÒh DyCƒuf&>²\¢–‘©Ìß•¤µ4Ò~?Ì8µÔžÛ €‰d/úJ±ß3c)ª`;ò|=¥ìk¤Áº6O`®—ùËΊJ7‰jñm}4ÌŽ`&Ï4Â(ÈM)šÙè¹Ìžäå”÷õM 0~HB/áf~é°˜à•“ÍuôÚæ•ÿ–Ýê_k7ï ¸W´•[Q«V,Að®´éŠ\ ™ö€Þ/Ó]F”ÁbW†ê~ɹ¢¬¤0?Åní9>O™ò™ž N‹°î+h82¼ÆŠÁ–…¸Í"¶’ÈÆÚß¹ôíZYPšèEjâ†@Små”ãÐ~S<À˜à Ž´2¼Æ Á—…¸‚e[’Íê>ïNÕ  •±!«ˆ~(} ©u8ô~Ì p4ÿŠZ„±{¡7Ý~<Œ¡„ªO˜ß+)ó(É™Jô—œøŒ)Ö¦1˜÷Q'x3õ™D4Qvq4f¹ô]é:þœ–ð€ÀpzhÃ)Ãh£æÕV:‘ÐÀBô]Ò6´Œõ,Ÿhmsg¼ËY_ÄÆx‹¬éh²ÿš UR´¯P*({õë1@¼À?*[¬Ê€ÁuÆ"x=„¤| E/•ñT¤köä3Á3.&_ÓÒH ¥_tE0„¾•føªV&‹Ðz“i”8ƒéè¢3UÖò>’ðË„ô`˜&dÄÜ0gôô–éWÝL"¦_J²øU )¢øô¤Úe == @t)#½o/’(2úz?æTœkùoª;{/ÿɧÄÊŒAýó¨±}î?öjp7ÖÙø¸}5©i DCFñ³Gæ[–ͬ+‡*éê[OG³©é›T1UÒz3ï²äK[!Ì;äþ¿i°sî–Öÿ:>äÃo[%p-*Û¬è%G“ÍÚ;Œ)4½ÿ5w²½Xc:yXbÑÜÌ3ÑEtÝuÓ0õïd¡· e¹v‚íS¼½jÃüE™Eê”ÇŠ;°¬ÚZÅzbSÒá0éØ1+U'8BÆ BXH÷ÅÞ¸J HE$éùjiÊáŠjÉI3J¬¦<¤r, v–±^˜”ã[ ´úw½Uœá t e#ßxRáj€!“§æÞæ]e›H4žƒ'àüÀy5SEz0¦íŸ¯@]±pü‡CX#e,fª Ædd•¯tÒu –ÐÁBhÊXÍ#4;¨C4!Z›+G™lêç]éHz‚\ÌÝ µwÖëÐà¸sCnò©’f‡ô>8 Á7IχV_EÈâ®ÌxŠ"G# N²–êxŽ\g»EdeAC0ú”Û¼Õ‚Íè|x& ÁÁ7IσV_œ§™ˆ{èðE9!‘ƒP$¥ºž#•"Lá÷`¨ÍL¨(a¯lÍ›^w‡cÁ¤ÊÂKž-eÍ›‡-Á~ù“¾>aéó« 0BÆ^ÃâV˜6OkG{ É·&Çydk¶;¥ÔÒãSrŠƒT: ]`h}0¸UÒ>[þb÷¶˜…ÂþBB5B½ú¯¼Mutìk>äµ/ì=á4f@˜¥{CØŸ–pðk¶û\‘jQâpf#üŠè!¨¼+UÍ!&éâ)‰°ṵG*’?Ui1ÛœW¨bqŸc,°ØÕˆ™Õ@غÍã¤ñê'âÁòüA~èݨ,8ÃÀÌi–l±Ì 0Bk&,é˜2¯Q5'éñ™ ÂäõŸ; BY;ÀMN°ŒÑÙæ6 ±p茫ÐfÔHxcL³eˆКɋm˜2¬j˜»¯µ,jfƒ ›Ö^Ä(K§x ©ÖY‘š¹žc`Ë„èÊ:W²_sFŸ^?GÉ÷òM7ô;ÛåŽ:¾ð·G1*‡gÇû|E´#Á?èÌS5rˆ9šù„±Ö—0:ÜPÊVë(à 4ÌWÑó›¬×«*5` QŒìû@ÞvªžÌ¼ÇûâT4À÷)ÖÃ38d’%rwÿMl|ls§‰`ÚçG¡ÒoN[ÝMþº=áiáó ÂAÒÀÑ̬uaí3´®[â(«_a*öz`Å£³3òO‚ˆ ýmMà.Ô]C+ú> ³“„î¤,ôœõ|2ëA³¬HÃ]gí¿Ü)Â")SÜ÷…–‡xºüÂhæ¤Ò†¸Ap›Jý ÍýÑ•8C¼”{fj¾d¬ÙÖ-Ðu„¼Ë>ß÷ ~ –Šžç¼ ´;Ç׿ G(…¤ &ñ«©´2– Õ‹´?A/F2î-:~‰)ýöÄñÃDÍuûe£Æ¢èY¬¹œ=1~¦Q•BÖÌÂó½f@…ƒžŒðO¡PlM7IZRV³,Úaö!Å : ýÈ™I@¸².¼Á&pÀUšŽsÌÚ—â€eÇoO~“±Þ†’™ªó´¹Û³Ùîë-”×+ïËA6ZÈN’®“¢&[ïÊÍ’ÆÛX@ý"Ṳ́ ×hÔ¶JÄ$TÃjˆð±æ/J1™k õö§ãeöb[Áœ£ ‚£sYr(h×ò†ýãíz³_.ŒlÌû3I¶fNQÊåJÄ$TÃe©sÌbP8Â^6AÝûSñòû1 -àÎŒ€ù Íw 7¡£V÷µêÍl»þædϳéÉÊ9\Ê‹qèoûiï-»´!~á¶"´¶gZ¹™-ÉûÓ̵€w™M„ÖtŽçR¶|:Vƒ¤\“bÞã¬VÚ@ôø›| b­MvKqe!EÄÚPžH•ñ‰vÿn’ÀíÓ•Œ»Y¢‹†Þ¨½rÀh»_õ%¥Ýþ¦0/)ç¤ýl…Þf4yHnßxÄP޳¤9žmM ™ÈýæCJÿ ¹c+é­F“£„¹÷reÁuUë°¸5š¸Ü4Òh–Ò¯'Ǫ£e8šï"'ú½jenÉÅzÀÍ£cã;u”袂«|µþ¨EK³¯"k ÚeÂv4vŠÿ´L4ñü>Ñnª‚ï£Ì̹ìšu«îÄkÓ;qonð>ØÙâS!V›™AÓæ 6"‹SB†'p×›8úTsà” 9ݹEt¿°JU!N7Wub;Gî›¶â¥ÿ˜_b²ÕÈšuæ/:Yñî@íÿS¥H$ <æàFó¹#VއHqÊ5h1=é¹ÕN»å4/ØÍc{pp+º¢ðï‡;!‘ºûøoKV#~Õ,4evö"¶ –ýR££êÏ3_Ù,Õï/·´Ã‡™Ô;þ’™àaÚXFnó÷o6p¸taý[Ý)=a¡’ÍK#%zÔb±÷€u/3_Ù,š;Æfíí1з:‡~]¦ÔËIm Ýæ7m=³¼/Ã…ðtatÐâÛ¬ 2Y¯KÆ08* úm푘pðtJ,ËuÕï78YjÛÊeâZO––E¼³\5ìDT7Œ°ŠËñt¦ŸlØš!ÿ%²ë7®ßŽÞ†´syøÚV44„}5•*p%Mï.=Cï¹c™cÌT^É@fJ ¥ Xêµ_ܹê0 íû|ÌÿæÃÜ˜× ®‚&›{Ë”˜íVn˜Cè¹€m/¡‹\5ä÷/XøZÆ-6È;o*m…7³q–ÞÑ·hMw¨ƒ…vn:ØyFñm]ÆqAEz¾©8*P)O—é<^ܨˆ€ë?˜d"$vÝN“ä¸áDáß‘ë#ž‘ æ¬×ñ,)H+ÈtØ@³Îˆ3Ì/¬IÁS•Ëžòü‰âÂåE³¯iüW!·å:CÈ1â˜;ò#÷šËH¬sÆÖjKšFÃh:ÝCGý„ <èQža}ÛIdécâ7íÂPT-Ìm¼øÓÞ)GOÝ&NƒHjÊÅ2Û ˆSƯ«ÝÐóéö¡ŒA¹Z³4â[ßæ` ÚznÝ…C#êÇ1à²ú&LþúC”ã)®Y™Ö9/ZØ'½Å~Ëì€d«¨“Ó@Ê»!¯yc·ªô`h—ká€f—™O0@®¤\µj±-ô€3Na曨䃲 sPè‹TUíÌ€VKÃYµH rw&ûH”¿yKdû‡à Õý«*Õø€Ýmqì"¨ZèÓÌ/‚Örõ[†¯=áií JÞ:)½ß!(Öæ¼u–¯$â°Ñíö% žo ë:QD¡‘Â^µuvu€Z˜¦×¸Â*u®¶ó+µ¤ ]KÜjøÓÞe] ụGÿ¢U€Íx9–=i%' ]Sg·ÚPíæñ¾³¥¤@"%ëWWhÝÓè0Ô?p¹f9¦ުǕôšikwBãÐ3=­¬0]  â>C†þÏói  ‡I¸©¤¤6”€†r´&»‰Sp€&ˆƒà©¹EEõ¨Ê˜@°[«MpÂlß(‚Ò²Ûm¡  éA^£ýß¶±ö®8‹´É~ÞŒ2”’a|ݘÚÑæò&Óp»GÝ4ÀUüÀü˜O Ȫ¹‹„gyEe`V7,jvV·Þ&‚ÄÊ\–sý»5àÐÈ~—èaU^— «šVðÂuìõé5Ó–°øíßÔ9´ÄŠIhõ­=¦® Uø™Î5nGq©cýíÒ"Ñ;G£dcm˜$%£Ö´ö”í\)Wâf Õ¹Ò:ÍÕ EП¾¹ƉâRl­6²»}ûL’ÄðêKP^­­Ìø¸«zZYúÙ[¬Ó¯Ð&9…¬<)ûš.!¾À¸»ìpJKàðõcrìøe`× ÒTlÙZ·†yz±‹i2UÀj̦Z:Mò4%ƒ³yEbØ8¼Ah²:öØã "Ú1•»¡¡Œh†Rtˆ°£T‡Rl†û'Eÿà\è7‹:±Ï´Jþô)ÿÉyèêžò¬3låÒnYk¸Ê¢™ŠZ_$¼}ìZ”DÑŠañ4¹MP¢š¸dïå?Sê6„Sp¥÷äBf›§æ[A—J¼F0Õ¬-—UüCû[±¡«üoï,cZ6™x£¨*V_,{Ô¥Otßiok)ÏCù‡ in\ûLÓ~ÒuW+óaÖv¤ëÒT© —Ý9ó"Ëà€ÖÇO¨m ¢»‘º5æ1]i Ë:VÓXô¬-—UüBËXÓS r—«{Çëõ–¬´QÔ+-½êuQ}¦&L9—ö~aó[—>Ó:ß´·W™QÛ.óJN½%cŠÙ}Ò™ÍrËà…ÖÇN¾¤²Êî7Ö&fdØ%¼ I¿WVF/‚™›™sEJ;Éu‡Ú"äÝ%ø%u‰BçaínxŸ‰píjÀly™[@癊0LíuVT%,»¼Jß:!A”~–Tcš_%½ÌX¢ö5`LZZ—ÿÂ\ ·¦7£ž:»\@ˉï¬ÃkDQ6TÀ™GÉ6šÀB¤RÝ|Du”c ¼=àjn°%ÝErü7¼åžÛ(¸ W¾MÃ;2÷`•¶ì±{ÜÊ¥k«Å5Úàݸ§í4Æ$†>{ëÞ ËXb>UÒQ·~{Ê­zœu©y1Ñ>IåþƒC½·ùLÏ€hoÈÉ[ë(¥ëªÝj¸âo0Ô¹FŽY®¥ULUÒQ¦øï˜ð)eÀ]õûE߉”µ†íˆh-Ñt{:CÃ.y¿çG¦‰ºˆ=W .Æv—L†­·e‹Þøš‰54+áf´ù·ø•”š† =ÝëÞwúÃR£»£RÛ½ë^ÈZõ8ëS"Ðcz†‡Ìò¯ B¡Ü4óðŒnhh^y+Ì E+ïWZíæ,5Ë4çžR©<Í,ÙF•ã¾fR3¸ÿȧì¢l7Èøš®J.g8Ûhx ׿¡·à“KéÃ1ì¼ô À®ñ’ÜgØì@T˜Ä¡D…1ƒ±é­’Ø;8~` ½˜ÛËŸø ¶Ë]X<¡pîͤ”F-Žô¼¿›d¹h•äŠ5%nFT¶º±úXÆ·•è‚ÑHÉø`-;í+ }‚UeÞU/‘4ÓüÿÿÚ ’I&­ÁÒI$OøÛ*#­½Næ¹Ï ­±5™)*˜‚cP2~‹¨Ù¶Ûm¶I%¶ x $“S]'!BrÝ5“S]&G 1¤z¶É3Š©pÍ¿ó&Ûm¶Ù$áÑxª¨_’O^–b…]±¬ª‰~6c㬸‹w;‰çS…Ò¹t2j½+m¶Ûd—c˜å¿¦ƒI#¶%nÕ1˜;–%(‹ÐSÒ=Át~àT<d±'û…å¶Ûm“ˆñT¨æâä$ìÕ¦3LßêlÌÚ/ZL?ìFf,QtOÿ<Ý!t¶Ûm¶TîªÖÕ­…ŽRİMÅá.tæ,¶/lÉ›°ÑÛp õAPý~­WýÁpµ‚Ûm¶Øœð®½c®ÃlùÀ&ξ¡}}EÔ-ƒï‘áAFp–Q™ï yqËÛm¶ÛB\ŽæVufŸÞ¥Ð«øfÏþ*O¾z‚ä󛃔S:®ÝD½¶Ûm@ lâÞ)€Ëñén½þ ë IÇ{ú¡L‘¬ Ôv#‰B1ÛÝf3Ûm´=°™›DL0áru*ì¼ØÿªŽ÷kWÚ1˜9 ì`çæÓdOÞ‡ÞÚÛm¶ßª[nÜ–XJ»ÿ·3Öb‘‚:³ò“4µ”K÷†ºŸˆ—²1 °Ûr«m¶Ûxuž¹(@ *} ³4ô9 w¡RõJJRŒk‹ÛþºßŸ5}K­¶Ûm¡þÅ\g£$ã¤uhCaÖO/@·eáÂAVÚGy4´U`P½u³.Áe¥yÿÛm·ë1Omy%€&—˜ìŽðù»@(¿ÌùŽÄ}¢3,u»nm JO“%9§Ûm¶Ôh™ÿöÜ0s6· >³8êQ6·¤jA¸P‹ûØ©é{œa®›m¶Û|Ç©ª ˜`1úV°XÿýxLþu³^%J};9%m¶ÛdÆ-Á’¨;ù)rœ àö3¦QbÓ’ž™Ž¦~š…֨ġÃe& ŸW–-¶Ûm’n˜!ÕFXA$C×]uwà öQ¯ºk÷–¤ãóußæý¿N›¶Ûm¶I2dÌA$…ä’W_µÞ¶óGK©WÓSS]ìæK#àö߆Ûm¶Ù$…Œ…<„’H0)‡¾Iqß|6™†‘<ìrÀEÝ‘—v(ÛÁëm¶Ûd’H|‘$’Ií8'Ù üSyèàÁ>g‘Ù@NþO•ÿM¶°i³ `í¶ÛmÿÄ)!1AQaq‘Á¡±Ñð 0áñ@ÿÚ?ÿ=, ‚à¬v%S|~ëÙˆŽ²ÆèÐV”5¤K÷çòÄÓÂ]3}°FÀçݽö¹¥i³X¸mô|1ä^ee9QË™OIÖ*Äy¼­r‹d¡ ÏžÌ6ó*€‹·ÓþÁ £éä ®Óõ£2¬³ ¦>¯í”y›J8/âïó-I^#À~ûôú%<Š<ùìÀ(þÙWªL]¿x !T}<‚ÂTÚ~„fU–a¢8§Óçø–Ðq(åòîqÔîgÇåÙƒ’Ç'Ft¢d…Aa%4Á¸Û]Ý<¸èãI*J?gþÇ2} ›ÔLQ>`}˜Âlr2µZæÎ=n¼8èeG±)= Ü,‡(gü¥`NÍeá™Z‘)qZJqÓ¬ üKˆ6\À °m(}Ãs’Ðuàz™¦ûͪe*ÞbWÆX)è.hâáñì#ňޖ¶rÌ}â)WFN»•?ó0œZ„´ØµêB•©m&Dá<Åÿ‘¡ãæP}Pœãi”IDì½9=‡¿~ÏSÖT‘°™Ò1r¡W¨f:ÌLcˆ\¬ Ö«Ü£ï*Æt÷hüÌñ]Sø(€×ˆ ª!ô„ÐGõF)ãú¡ôÛL²A‡eèìôfJ<[Ÿ˜õ=e3ƒ ‘#0%:„C™)-Sˆ¡{+Ü£ï)Jt6÷hö¹+ª_±DÑ5D3ˆMGTcž3çø™á™ô §Û~Nä^àx³çžŽ5QŠoòNÁª4TY™©pÕþý/Ÿ¬”s)ˆê µ7 »¨q°ô2Κòþ Ö®Ûé0!¥¶á2÷e/§ }zJñò }¥©öeù‰áSÑ‚—ÒaÂ¹ä™ ÈnI¡6Bo¤6~·™LGPM¬Þ2Þ¡FÓÐËö5åýEUU@Û˜’Ñ ûÎÛx§×¤ª=A¯´°>Ì¿2œjz0zL(W<“'Ù¬š“d×>ˆBéäèÆÈ”YôK!·þ={SÄg#gôýFØNÜ|K­vD¢±»kß×ÕÇGËRf=b£¡÷į̀”›:Bi–CPŠƒ2w„.,¥ãÚ*LSðÇã·ˆìÿ˜C –©–}{þê P;3, -" öm‹—=¼ ÐÅà9)z°‡8cA‘Ç}ÌhÛKuýÒ–Zñ\™˜GÀÙȹOFÖtä½ëˆâù„:óÓÌB^:%lï܈ÌP§Ü†Xnƒïÿ³f~׆}˜Êt\ Ÿ˜Éд%Rò¢²Ø”Zš-nõLLÀØÿsõüOŸ Al¢:¶dŒ2ƒoØ>bWIÐþ¹Z‰µì¯¸à<¯3y³æVlBÊí*T@bw„. š]|„ ‘RË /f •Ê"«e‘aënÁó4èDÔM¯YU¤Õæn sö% Î#ev„•*bw•ätB4º,0ùb¥–x“çøŒïÃÜþÔl:ŠO tiðÌ1®Ÿó¡Q”r¬¬®0Jëåñûѹ' `“æX΀Pã‡ÚPÊT÷ÄvÖjoˆûafa”Cj¨A¡1¸Éò%÷Ã+Ybd`¹B¥ÈÅYY\p•×Ëã·xu0N9Ã%ÌÂEž/WèJJßø‹išš2}ΰ›”-@j¨iê+“µÛ ,ÍŒ­e‰óüFµ)Òt\’X¶Ÿ³ÿbF–‘§âÈ„6[uÛ‡¾Ÿ7IJdzKSÆáÜĈæ^Qd,ìv[:3w U§ÔûÙ ôb„:Ù‰N„6d²1}=X¢.è`öl™n¦B¾žSè,ñ0ìüÊw|ÁŠð±}ˆR×N—Ò‘hØ)j2Yã5{ñæ-k!bÚÐHùv͸¢ðØ´.šëâ&ˆºØ¯Ž5¼(KÕÆ…–Ã"wší_Ĺ€º¸Lžú޵¼ZW„½]–=2rÄä[±€þõÔŠ³=KŽÐ×ׯ†bã²Ô7IuÜy¼åîÒ%rCfÔW¥ý?æ:.qKÆSAŠ[þ¥M%‹%¢\ÅÂá]¤kû‰WqV÷`Òãæý@uÇC$˜HÁ“E[ ƪ‡›U9°S¶13?HÓô…]"L7ú”–,–‰ps ΡO¿´«8 {Á¡ ÀK¡“õ“ `É£mÃÍU,ž&!*seëlbf~‘òüJT»=ξŸ‹íXE[i¿A7ˆô†mØoÜÏ›ŠÉ£>fLÙ™eqpPôsL AÀÆœ½û²v¹ªñ2®Õ&“d©–uãþNZXP²6ÝGj¯ S(¸tÊN }žÌ»ù7Èÿæag¤%FøÌ:Å*·–;\¿ëæ\½5°øs/æ…d ïŠy»AÀkÉÙ¤†³¿‚\k~郋jb¼Je6§ß˜Rž t·IÔ3ï `^²éÛƒòJg´ßºu›B]_ð‘ä˜ Rôã<˜Œçá|ý%ÐO˜±e5íˆg—ˆ×"Ãjî,ÈðÖ5J@âŒdÔxNÝ|2ˆ~óHÌ8Ýt`†S©‚s·4ýdæ,YM[a]ËÄjÈ°Š»„2èÇYw€*`?$ºj/ pùô€ÐH+à÷{ª8ˆ÷ žM £ ë}æ+K· ëÙú`’k¤–ÔKŠ#» À›¯¡Wô”©ÄåQ¿Ü´Ù0:t|0/ÉÜXS£Ï¤ThaïÑ‚02>IPy‡ Mßõ {CÐM™ F˜Ø²‹Eçóç˜y ˆvš„‰¸hlÃÀíûB˜NxŽƒ«Ö7BžVWÞ4æzNQøšªúÂÒ.±~ùˆ½ïˆ«Òù˜e“¸CŽÚp€d(GÒ=·¼ªÒhù`…%í•Á+”ì‚B:D~œ·Úу{&_ÇоɆ_1&Ó#2Ç@=¡Ò–÷”ZCNì£(E`•ÊVEQq‘Dx,÷Ù‡q+²gü}?Ä&™5`” ©Øoß~n!,Ôpt–2äÐ ñ G Í­GØ~ÿ”*ILMÙò|ÊS­N»b¨c°î<™•Ò˜oÕα7â£øúND·$³ÜK§÷á—J¼ 8OÝkþw#±œŽëõ û¢Wa‡ÜaH«å|–ñü†+wH&& biÿÕH:ó2—õ!mHõ0 aŸr?JØ÷ÌwKEe¾ƒ·,Àaâßâ {ÇXÑÿ2}„±—QL¦Q;ü–<<¨@c¤r¢Ÿh4¡œ„F0ñäÊ!Üœ„L%DuŒE‡h¨õååu?g1º’–žb‹ì–2ÊY”´& ü–<æøZƒ†:Eª)öƒJÈF#¯'ó(‡rrM1",b7+¢W¶WSöFÊOuù>&^a¶µ,êæ%µ>CÔ¿TP%.q¾x` >|ŒGÆñy¬}ê?~^CHþå'¹:0í5N«cæg¸Â±i{ô@íôPuô+ŽAw8`–Fnýˆ<žŸŸ'¼ep1{b uº ð 0mèK§û´ßÉ`û ¦?ö§æRÌeø%¥â—ÿ]ÌE¿Í¯‚»ÇwÍο֪·è0™E˜§æ +G‘3yÄ–#¤JÃÛeÄÇbY—eϛ☆ðpœ‰)%•ò±Ü¦9RÞ°«Ò¥T¡å‰IÜbÌè|Èôp«è§Ä ®°àR/Ú7hÃ=èžðñZïÌ>ÿ+š-¯1*Jy~Œ Wô&%8EòDä%Ø0Ó.Ÿ×ǬÍ;iç _“OYi’•Æ“¤2É…ni¦Ï8kÎc 6+ ÀóWê ÞtQƺ/¬5êWÌB­ÁÈao´éhù­f¸-k´4(sM®¢Ø×F®X…s ¿õŠkèB^&© h{‘U^ó¦='¾LHº¼ªä3€MøÒŒ÷J链 &Y äJ¾Îâ ÍîçÝg|Õ`ñ³}Šmü¿÷†Â ÀQ2Í&FÄ6ˆôaä£ï21]JSƒSx‘Vx”!¼|‡ÒT2¥ú#voÅ´þ_{ÀAˆ3ш[4ˆá± ¢-1(ûÏÒ±U+ƒ¡SHÇvE€” aÇÁø}# Ì gÉñ+Ý€ Ë™&‰@…l÷¯ƒiØ °Ó‹[ô©|W+G¼#Éœø†@WM°|Ð>Òè¶B)|Wµ…(§æT‘³p% Ö0Åu0Ëö ÇOÓyqe̦.,Io×]Óˆ[œ>¡ó¦a,ôç>B¥h§"Ïç=£RÝÊû w§Ûpª¿à XŸJ•õ©Èê:½ÜUsØRQ[¬'yjµ^Ïý°<0EAÃ‡Þ 5Æw~¥FaÛ·“©êñ©cY{Ì*%«º9p\ÈNðÎB3ž`ÑÁ¶”j¶XDÛG–  UìÿØôƒÃ Tœ8}à#ÐáÜCpø•1d·+“©êúK(zËÞ`,nÜd'xg!Ï0hŽê½ŠÔ6ôžé á4b]è¹µiŒ½x‡`T)­)ìÛë¾×ètõ‚—O1Š'½bÉx&È@>_HL`„nÔ¿4Jp.㸹T#òfÒßR\U–a† AkbPú~ÇO/0_¯ïݵ`Nç/\ýåÀf´nÆ# ôÍéþ³yˆöYÃiW_˜”.QI“ÓÄ]ú—ƒ5¥à abësP+OB-Ÿ‘*Ì"z™…†&qµ¥zÁ·š`ó}áú‚g«+^²Ë[VÅn'øTV\d¾<5ɲ3¨¥ÛWAªç¾¿½¡ÊAÓÆ~ñ-•{Á4~ñººi¨î,å-–¯\j9êl .Žç‡Œ®¢¾—òõyœý¾Q‚߯x«çþ! ø†Àû/ÍÆô=™^*e†*\»c àX÷þýC”ƒ¦ŒýâU ÷ƒèýãt'«ñ5ÔwLçI¯\j$в4îo]F4ý.ËÕæc.ýQ‚ߣ^ð!WÏüCðýŸ‰°eù¸Þ‡³+ÁL°ÁÅEq„*«œŸƒåîçS€&&\²âCQ »6ú«öú”@Õ#Áòþc¾Êü:&µ`Š¡Í~à›è®/ø=Yk&–܇aDLšéÄaBôŒ‚¼FôLê¶U¨B -6#–Ô©Ój6Êë¨ÿneþ Ò&ˆ-­ö#–ÇGûO¡uèÅç?ÆåüŠØ#IhðÝš¢]Â’Ý™¥åÒáRqÎiz\>}ƒÁXZ*Ψ½ÂV ±%×¥W§2†›7‚×Úh°è÷ãÕ§Þm»hõ‰z»Ð%µÑ¿VrÇ'õÚtM£õâ`Ñæ…¯´Z†jÈωÍ:ii{aqY~»ƒpWN,{báÊf‹˜ñ){>æ|» _Õ"‡’êûõ¨8”‡¹eß:âá´ã¾:œ&N†²ôú~"t!: ˆWdm†,¿¥Á¸+‚'?"áÊf‹‡ëx†s<]†'êCÉu}‚úÔ6 CÝRïŠW8¸!«ã¡û&N†²ôú~"t!: ˆ[†ØbÓ/è¦éËðzííæ#ÒBÕıÿ™)Ĉ!¶1é#î}\‡¬BÏÁ¦ Ç}ø&nC!7¦òôåè>õ0‚`z~öË#ž%ÌpÛ3yÛ¼DnÆà3´*ˆ ˆ½ÃŸ¶¡ô¸5:˜O$tï¡Ö_ů°t%Eª!6ª¨!2Jÿ]t2*»Úí¼°öøíGËOÄ6Jn]˼ûGzVœuzþcLà/¦ëÓ'ikžŠ<¬uùßÀ„Å[×W¼¢‹Ó¹Ï´àz@Ða§Uϯ`ûX³^Ä&Y2øÜ©+°êsœ„±X=á´ÓáæQÀaKfšò¢ l U P¤0€.Û mçèK—¼A¶m’h‡ÄIˆÊëC®ÈÈçWÇGž8ƒÌFüÆó½Rÿ0˰G›~Syo'G¹§®ãu+·Ìw"£ØG»˜"‰†Çém¸²þ—.x†Ù†RhH—jXvAy5|työëi·Þ$™ ú¥þeM²ƒÈ?qŠck)äïÜÓï­]¾b™í£î`Š&¥¶âËŒ´®ëÕåýt(‚‰ˆz&ØOˆq X6|ýÒ ¥‡¤F9’àZ°d‰ÊRÈÊÑëž.ÅÛèq*Ä"èX™üeI"úÇ©›·à†Þì6Å`}.¡a–Xb9RMÙqÒW€*"aDö”I1æÿØ Yÿc1¥DV- Šv€Á)ìÈmA¼W'2Õ'M¼t{L•}góÞfŒ<–tuQ£©NÆ¢guNÚ8:Hûù„¥Q÷jRͽz]¿°2/²+Œ† Êh¾ß7*mêq€hAeGV^¢C§É*‡>Œc¤|¶-_©õF©›ÇÜcÜ”-t7îý“PßfpvgÏ‚ ¥\œ=î,‰òW䆊“¤‡xt}PÏ& K°ß±˜ñO|=Œ±ÂÕiæ›Scx7+](žàMa¿ÝŒ¸†ì­:ìöL¤õiO´´Hm èAKw’Ÿrt+"¡Z+ö‹@ŽŽ“¹ÞSzKQ§£ÒàBNÙCÑ憎¦J'œ¶ž;K ½6%Xãn ö4§_yËm@²°ÐmÏX!.‰Xö•‹-®!øeˆ® ÁêÌœˆý ‰qM´c˜PÇ6Óëqé„ >¶'%r„Q•jévh骃T¶‘OQÍKŲ¬z’¬eA쨨â5ý™z*8÷–—0ÁmZ8jž‹ñ¡¸Þvä«–¬zÜ 9pzLÕîâwŸâ¿¡*f9N‘àls܃hy¸|{¡™µ ÀrJåðaBptÆ€]´t·ª–Ò/¨@yª—;eaê1åSìŒÖ ó_Ù™™Gþó§…µháO±c$<pçkµrÃޏõ€ràôíîâw‘ÿ,m†CÓ»ÿ'(M+©ÝØzmô:Âô²OǘeýNUt!ÜËTrº·A×Ö`ì¨;~ú÷™Â¹? ˜NK\#Y›Êw—Ä0^K¸3ŽÀÊ­Â\³ 0BW!ÐÇßyB”Ç¡ã,}Õ—¬xš¨ÿ}¡!5‡ÛÚ7wg\ü«îË›JÕF×ÃÃæ¤2 ž—@ù÷–@5¥= éå€A¡k¾ï0óÜ1Öe±–d 㱎±+^ì¢m§­f/ÖÅs`ûšó/SÙ¥dÐqÄ¿´Òö¡Ã|Ö. @E¶…§#]U—R•¾ó>Š[ÐÀT'=ž—Ö-û¬%sT;sXæ ÑKÎÌÿ0%ÐìaE¶ër°ž¸šá¾P³¬é.ÚÏ´Û§hKfЖ+ÁƒÕé:Ù~óë %ÁJ,¡\ÛjépZƒ„(·‹»ÍäÄ¥¹¢Ž_l‡êdmÁØùêáÇ¥ ô?½Ùζž°Gü¡Rô0…GI§³Òã ºÂVn¨:§|swã`¼ìÏó/âÐТÕâU©×\7ÃJÞ é.ÚÏ´Á#·NÐ;ó0Û¯HÁÛ…ø|úÂp®rQ°W*¤<Ãô¢Ó[luɉXP/E¾Ù™â=Òèì}¯Øo¡!C<÷»8Vé‚?\ðF§ŠcG޾±@:=º®ÇÝ¢Ð?­î¹a»â#­°+o™N9®gq-½kÁ˜Y0mêëàÐàî± FæœKPzÔ®ˆ¯·÷ñ D4!•n¦ T?ÀúÀ!°BFÐ>€k9Éóôô¯÷ܶ ”Q\XXzëÌwl w&ús Ö,Ô:³®nñÙ [-; ž`F”åÜs •w¯NŽæPª«âäp†r™¨,°à`[û4¹ÐoÖ ŒƒG€ðE Bd¨…M ôïx™ šȧ^ñïEf¶ % :FÌi–º’†žç‘·+Ä2¤Ëa·×æU®À#P"Y U¼t–Íæâ¢Ž!¨K©©yRÈð¼—eöŒ”g'¬Éô,ð•­]Z·Q¨­3¦Iö&˜žJ I\ Î[Q*SB•-ŠcÚ.Ãg R{´ÂW-ÅYa]S/HÒ[=cþ%D9¨úÇrŸR7åŸX+hX¥o¼iÓ€.@t˜º–>† =ÎëmÊæ  ŠL¶_\˜yö)¨[€Ýá<ÜTQɘjõ5/ `È{fJ3“\Àù¡g©X5uj»¨×P1Úí>ÄØ×ĺÐôzNRe*U©J–ÆeÀYY±g Ux^˜e¸«,<Ö^š%±ÓÖ?VØ&›—ÇOXìpÝÑ6·Øàv>í°]#̼Ð)ÔTgÇKtJÍu;?o.4eË]1„$ÿÝ`¨ZþÌq+\þ k PMJ0³®Þ8zûKKu¿Þ%ë_Cü A›n|„%ïµÏâ†kÑmœ`b\DT­¿ü:F b6U;Ô¢i÷ë¤~åõ”µQæ!fG«¥Ó–:?¼FË#AQ»ì+©}¦Gy̪Zµx¨ÊGŸ1ÜÒ!uˆ=ÐñÞ¯xÖf˨M½6¥¥©`Fñ¨°ÀåD(X¥ 2z¬æí@¥ ÒÐ#­Ýp+ŠZWhehh6¡±eò±Å€ ò¦òaPªÓh}2Ý‹`# q¤V hN éVÈ\DiÜ[ Ží«íŒ‹šL ]Šrdš)hDc>O¤#¤PBÛ ì–."`‡¬F,±”YRƒ\¬3 ^Ó ºRñ¨P¼\±PhôjêêW&R»zLˆ ¼–H&/Y¬µÛ8yÒSƧ³f³÷ô“IO {¡âùßn¯Y"«Á°–›Q`Fá‘Jœ7VB-Àç'8î‚–ƒK@f[jØœZâÒºðÆ P0v¡±e*Ö[Á˜ ØÏ+- ­ep¤ÀèÅ8¶@rÐF©â´Ñä*Ý-Ò…ÀV«0dÛ¶¯¨VEÍ:ÕÜWÆI¢ )H¡bÙ°ªÀ`´€• QMÙô%O"5¡–2‹*43A•/i…Ý)} C¼—,À9Q­ÕÔÉq•ªð*îÉ!|¼0Õ‚Úr¨ë)Zg²?êˆXú_Ä6ò¯÷¡wއu‡UfYƒT„ºïÞ*·RèŒ=ßÍt3·­S1óNþ`ˆQû(¦ya30‚z§G¡µãX4z™ô4_Ú>øü3Qï6‰ŽA½ÃR¨çâ oRŠ]œ®ný ³]‹”´ûø&Ub¿po¼_ÞT{@}\BÙ®%zcñð2þÑ÷Чá˜xî&)Ï P:/ˆ,=¾65ú‰G‘vaòéáãã¤)¢IE˜D¹CJG"F`¿íÇMt‰‘ÕâQHânÈKŒª>Èøo³/Oo‡ûúãgø}æ¯~ˆ¦?ñZ–1—6MùQãFòöŽja7€vÿŸþ!ÏI?c?讹×cö¹×þ»·»O›ªˆÌŽ;þˆz´î”˜D|,áê@`5VŸžóu›¿Ðz)nL åu,¯oÔt·|þXï*j€ãK¬u½ÌØYÒ§ÈûÑ3´ÀhŽ”ÑÚº€Ë‹sè¹T­"ë2ý–á!DÂÒ gRÊöý@Îл¾,wšŽtÇÌÐYÒ§ÉóDâùðhŠ´ã´.j.mÏ¢ý=ÓØ%h¸gYŒ2©Úè÷ìéíÜ!¯j‘‹w—Ò^3-Þc4й̺yû$ é>N̼ ä Õ0S2úw›åœ1)•”Ö9"®Ž±¹D9cÊ ::ŸoZøýz1Ƨteøi6f¡7ô +ìýD±O#úPÃ1>?ì7€[½Þÿh]‚àâÅ&8Èó 9[0.!”TÆ ™~v_Äy!ªô7ù—Ó=WA‚.¥ ¸ÉÓë™km¿£Æf/¤“< îÍ1±Q¬3o;õUUwêWyų§wØÿä§E룛.vµÇk€"‹ÞÇo0u¾ðêtÂC6WÔo:“Dn(3–ÄÄ Ùuaɳ¦K+w*”yVF3‘| Q&:ê’·"R¼E†ãé\TÃÙÓ #™\gRüêMÒÔ¹)ZZ•°°Ýžíy•â<«#̾ŸÔ u%n,E*¥qaéé\z0TÌ´Ã$) 0„;>xyríâ\¸¤™%9&v„õ°â«áÇs¤N4œz è3bI†k¬?ôY®û/‘¤1ËŒ£¤Ô•LÎHaBüΙyi|¦PYCp^ÐÏú9´‡=?Ù‹QZpíã/«côÐWcèw•æfvÝË)’PVDââEzº(Þ7àšî}á#EÒi#ÀÙáØÇ¼ll¯Ì¦€Àq«±àšØ.ÓHaÓŠJËß+J»˜¯_¨ô ”Ĭ|ؘd¢V0}á=ÙP;¼¹alòÿ~Ó>~ËúF#沺8|tñ3ºŽD}ÓP‚ÙÉ1å1¥¬LðÌ©”cÑ?JY.S³*ÆxŒ”LlxmûŒ Þeسµú_´Êß¶þ‘s+]]>:x™°‡ ¯.é¨al䘲˜ÚÖ:Ìý’µ•>†±o-Áh8eÊ.X,÷öðÀ9¿ÃÉäqðÄå”ꨅsBãà ‡ èõ„n]MјLýçQ'M:ËcÁ ™žÏî2Ò<ácÓqcMOŽV°äÁrGC:Y€GÍ¥#TEƒšªs}È  ó€ö‚õÿσSëÄ0ö®é¼ïdZù¼ÍðÜS7ÆzAE¼A°øÌ³l1ñ:ÈR m9!ÓÃþÃÚÕƒOU®Ì@ýÞ;A§É©oìE n%ž1ÄÙ,³Dp>¬IèÕ|œÿFðÖ‹œ” Â7LL,}ù=Ò¦Hö2”*ˆEtÆkƒ¤ÑåýF äω@xû„r…#sÄàûrÕº¨ï˜ê~èvrˆ{@Š3oA›íèšTc) "!„Q™Öåpt…í§Wõ.U²¨ñ÷ƒ Fæqõ¹nÝ@+}.¥“î†ç˜„= E¿ 4LÒמ‰Ù#±ü~£¢9 µìË!>ò¤8÷×ÄK!9¦1â] eïÌ[øˆpa„e„îR]¿ÉB Á™˜Qó÷ô|Ï£õ®b»š\U.óNP8’ÆÈSœ…3ʘ³ ”ð² ñCM†,éÿKˆÞ\ù®g¢Acq¢°ëjâíï@½6É㤦x4"õuÔ¶ ›¼Ôuw{KØ@+<¬T5¿" † |JaX»ž§ˆÈКy?d5òeLE$Í÷•´æ (X*ƒ(ÅÜ$±&µ”ä{™à‚n h£s—»çÒ¥Þ—èzå©R¬J€Š´çûqFÕ®a`¬‹0Më6?fj¸d½C#¾b}ièØš†ŽÎ½Èƒ©§¼Yô‹ÙÜ”—èzà€¨Æ¬JV‚Rÿn(åjQ:ȳPàˆ³bö~óUÀeêó äô, „ÃGg^äQÖcñfTCS.eº¶ó<íââ…¥rs̸˜a&êK[˜D³_Ž_;”£ –ÎîÛrÒpz­¤«²ÆZ1 ["2˜$ðj2G/yÆoÌÃWá’U2E¶,ä†Ü¡p(4Ç—©‚ö“äÛ™vìÆŠ1 ?æq]0ub Ó¡Jª¶tŒHznH›yæÅu9FËézíÜ"Í¡izé·Ÿò.!ì1+]npXSX6½"”† (Òå#ÙÇ>Åëp¬³PnRz)Ä‚Cÿ»”Ù=åèMÑœKáP ëÑ}÷˜â86õcæÁ¸ê¥Ý&>‘ G8”vFoú–ÒF xoÞ$¹å¯Éè6FQ/…@k¯Aø®áÈ$á·«¶ Äe.ó¤$NäœK9‘œòK # »·0lœðÔ†Ükàyö?J™ƒ)UưÿYt°äš–ç°AvÓ [,>¹fg |’”o0C©–—ëþ™ópM0®ÉK˜…fU7+ >šd‘UE;AÅܲ x_EÆ”le艋&â]PjÚ6ðÆí÷AiÃ+þTÁ•‹½ËÁyÈ\få«frõx%+Ìý¥ÉÑú“m‡> Pìü²ØÛWÞ+¯ÂLý¬%'¸æª>eFÜ0t"!VáIR½RâÒœ‘lðÊv(ô%B\Œµ]ìWphå·â!Lâ…f÷ðìs[ߘBLº—a–ý¹”Cq|“δa¼ýŒüú…±—!ïé cÕ\å }+Ô£¡èU”aŽÓrÕp…XáóÓõüÅþFºÄ?‡Ü‹)| ô~“ î´dŒ´FBë‚%¿óí]x>Ð"ˆ–LM3!…¢6ÒÞeÀoÜf—õG™b³ä?äCtìÛ¤aiõ–¬Âû#^øR¿ÝüLó!*--SP`7:Íf=KÜ »lc+Øýæ 03”†ñ-¢™”e†­%F0%•ï2ÌĨ´µÑs¬ÓpRÄw»l4cû§Þ`Ô#Lå!¼KèÚ#3*,³´n¤¬Æ¤ŠE"ãõ ÚM=¿™Š ø5ó);ÍÌܰoÃl¨ÿ• 'Yøc^ZŠ÷¼yPèè„Éx¥Y³˜ÕO¦Ný8]Nß °Žãñ ˆÔÌtJewܽÿï;ëý†jØk¨þGç•Îÿ}Ïo*þ×*nרŸ‰Hq ý’:½ ßhðCÌŠ¶Ì€àúóèœÅ ¸RQ/íQûúoªE`™ áñÓqA@8W=Ö%k®¸:ûÑú ÿxöâhÄÔ5ÿ ù‡âZúH@7)|pŽ_G,Vóâ N]V(GQÊ5ƒÜ²9QpÎ ˜al2Œz ýB Ê/ŠË,Ìb£˜§jpN¢:‹ÔrF`Ä·Ù!tÎ €0¶Dþx„’Γgäî@4½“8c›VÄ1ÂržÐhà³£ÔŠltÎcip^j™e»‹f¢«ìÆâ«Ç‰›ÎW¼C–øœ—âŸÄ/8^Sž§9A‡çñåÔ€|báÎà­ûÞäýŸ©­Â½’Ãá§æ.–6b°}ñ–…®£Cî@[’½øÌ Êâ›ÁjøÌ&á=ÝÉØø2÷bj”Å^–‰X01´­¿ó9ôc¨ŒA¶!8">šÔìQøa€Þsg’î¨Ì.B•¡×©ç0Ò(è”§=áΠ­@š‡ü,#ä‰|^ܹ—bY…‹É€â‚úgÝWûóÐðzr2{æ ¡‰„?d]Y»be-:8à12ÿi¨`˜jPY2=-ñ{rä³Ì.ÞLì‹èeŸr_ïÌcCÁéØyb ˜CöE\ݱ2Ôº8Ø™½ÄÔ,3&¥“"}ó4Rêôþ¸ñ|NÄc·ˆøPÅôâ-Fl¾ÄÈÐþññ¾²þî÷st_)eÆ=³)ƒ8M°³›c·ó˜TGÎgxãxÍŠz µ¹¤cô¦Tfþqâ×)Pª´=ºö²Ë`QomcÆ”¾8÷qó€‹à`{娋4€én~Ÿx:Î3"=̾aˆâ᣻o/Â|FtBœ#Ç>:ÂÓªÏÌ òe%'xcþ@®Ú<-þ`r ÊCmKŦ(…¨GÏ‚' ®Ûï©M­ƒ…©·’îIR¯ýÑPùOÄùoãÔê•ÍCp@ÑËÒYP:±µ²¬ÇUÇáªiˆ½Åq® !Wñˆõ胳S6%‘g§®P¨trôƒ4‡¬ml«1Qqø@ªš"'qTiÂÉšøÿ±¥¢¸ø2ÆUñüÊuÊøàüÊ ÜäÞÜ¿CàÊGîu—ü?1Ëà‰î!òÌ] …M+>†Q×ó2×B96Â:Ž¡Ǫ%Äv$àz fúa¸Ïâw[9ßêóâ ¾ÉßcEýb®f{cë!÷p}-ö#ÐÔì?Ò' 8µ‡ñ/lu£Ädô;Ãúeà̪SÿÈxÍ6åŶðÖÊ©–ìêöí+ÔT «s…ÊÄÀÖ?؈¿1:uj ;Q¼ñ,gÃõ*#\ÅŒ@‰`ÿïŠwûGÕúOŸ~&h<@¦%BØE‹GpM¬‡ÒY–æoA£è’ÿ©Ö`~øVÝ2…²'$„G-qÔ!‹œ£#€ñ˜• a.b?‚l`L>šÄ»˜º ý%$Bn‡Y€ûáÛtËÓ$NHEŽ^ÈêGÐ2±"3LÃÇ—ßRºt{j :S¤?Ÿ´/Rn]cºaZP†A Ú*K¨ŽÎYS`ô^ o¸‹´:JˆK®å—ÿcst=øpJ·@}¿\{GµÎÚqš‡½ËThÂçý7Pé/‘§ç‹ÄÃÍyT†n€»Ñâ>ö0ïÖNȘëˆåíôëím8zK!i”ÊÎÝeØ’{Lýñ‘ûÕæ¿È¾žöþÜ*Ü}&h¿!¢ £rü`Ëõ¸Ý°"ÞŒpJys\G‘ H‰JŒÈ›äwbÆK4ªP©f-çÝüÊßW¯a·év™Ë X¦¥E3 ·£,P.ø ……‘6Èî&ÅŒ—ûÌ«”ãê¸ ±«Îêþ cg«qì6Ê¢œ ^e¸eL’¦™Ë K‰ƒ*ø~e«#+/NOÇÖUCâ ¦+örã—Þ`DªÜ±Ò¨{?lg©[¹r÷×ÒZ>5¦Y3“ûºýûA#ÄJˆÍc2¬-ÃSô­;.á ¦5Ë 0¼F#€CS:À×÷iˆpCÁ·ÌI)wìj;9`¬¸¹«þxjz2û½—«÷âoR>é¯=+ÄdÁePuîÁ«Ä³·/˜= ¸Âa‹{ké 8wh} ¥†ÆJX^Škï14õ¾óÞ!‘\Á Œ¤ “ü°bõC`l–§ýèý&h–¼¥=e ˜åýDÂA!A0·Ã+é%üdøÔéw›WÚe¹Z-k«‰FG ýzŸ·&Tn%êbCnçR²RCL2–õôŒrî¢c ‘br¾’QÆO‰Óg6¯´Õ䯹5®·R¤Aú½_âS£à„ʃÍÁPN¦ †\êBJH`*ãÜËšãÎökÛíÒ_¢æP4ÏÑ(Qe‡·0 À9N£ùzš!‚X¦ù”òx>«,A£5$Àëñ:ó,‹DÊ(zÜLL¡'DË4=< feÏ0ï¿ÈöbÌ-ÂÒ“cËÂuμZw`’§ae[E÷/z䊜Ñ•éneʪ˜-tÞŒÀ¡Û(ê{J‹1ïSÿ„FÀ{_ìƒAПÍÇ1/—ÄyËùšÊÙ“²îQ®æBù~ÐEJ$X@^æU°â21,d«<±(8ÒŠœd6{ùôB ˜îïb‹ÆQÙ¡…dù†d`™OºN!ƒ¹ö2öÜXÓ«2á+¢•ÝßTÉ‹q–;£ô‰Ú²V‘ìJ,Àõ™Ræ¹ï,ˆR£² ¸Fò‹ô<9{c˜JZ®ßBhZTVdÁþ¯â6¦µ þ*˜çX<ÿ’м³@0öXméýø¹©0¨!H4<¸ðDŒu¸"W3!{Ó0ªl¡¹„@‰©Ú#§%ÏÒeÀ…¨š¦w–V;¿¨Ãt:›¥óƒ²žçÊN»=` ùû>ïÖYy6…ûKKST(œuúÇ’«-{Cc9¼õ–iæp‘o¢æy]{u‡ Qg^ä ñÛÔ?n‰M9ý;K$­)Ðâg^j:OÄ£M@Z½Èš%Òµä¼éòÌ£t^CMBcƒÐÙèµp ³G˜Û£/ÚcY'÷x´í‡õ3¶u9=¿$öÉíÞ[KWl@úAñƒ–N3¸¸í{óí«¼ïØÜuPÐ`ñRµ²»zY«“6¸áèµp ³E˜Û£3ôŲH´í‡õö›×Ôäöü‘< Û¼––®ØÎ Añš\ ²:ÌZ ¸äÿ>Ð;ÎýÂAWõ¨`Px©ZÙÌô;÷&mpÔpëÊój"± %â+ÔöËÓ“+à NŠ'Œ@-¼Yvܺ¬–5G+âU 0à‰f§lBôrõ–êb»ìœy¸j±'9ãÐYˆÓÓ{Öæ2ÚcŠá–U {T­fµlöërÀQZYë]ŠÏuÖýEĸ'2:ˆ6s ]øœÞtÔèC*éþêpâ×S·¼§˜gyÃ*7L {è¿h+¤äzMØy·ö!qàúüÅn·´rh#ŽálʉàœÈ Q:‰—f.¾ßäçÓ¦£' ¾:{ÅVN§nçNa–Ãp? PaKßC·Ÿ´!ÎÓÔzO©ò0°è>Ÿ<Ån¿Ø£0Çpå*Ð(#†Ãë-ÊöeÜJ ØÙù=èãÓ-¢ É-ËlK0‹J'dG» €ˆÑ™””vÄF£õŒpJÑ£lÉ(´Cm‹ú„˜BøÊP¡˜"ÙkùÔÌJ Ô<‚htÞ;¾Óeßw÷Ä EWý±éV]k“¼PAÙ€(]Uøƒë%izÆá%á`ÁÞLßÒ2'@U{9eËqÀ3à‘%¡¯¬øÛ••¾?1ÊØ[ë¨û"ÈMkñ.å`rœëy€ÎŠ{õ7|TÊ`Ð!½yzFÒE¢Î%y©À%~ïþR$ bt‘í/B‘%ýys<³D¸½³Ûà˜H½ƒ‘{÷%1ÆŸ¬¦¬í:3«Gîs/OˆSùµ‹A<]åÛ8¾ŒD´é 1—ªå¯B¥À„£]®?p* Ãtõ¨µ*Ò=¥È))/äË™å|AÅíž×à+%=ƒ‘f}à€ ãOÖRVvbóaùœéËÓÇâ"© œAtË+Ñœ{ËÂ$W«¶¼q—þ‰v¸ýÊj¢ Ãz³|ó¥ÄB0å–Ölâ¶ó]à ]LÔ¶¶ô•˜%)ÝrèJ$Cá"Ó€mŽ‹PŸu&y˜»tˆ1UQH¹pD>‹Ò6ÜmC1ëpAw¶]¼ŒC°¯Y~hqÄÁj%úÿîüÎä½qœ,ôSòvñ*Tî:­ÝÒŠ6#¥Kàüþà'Äã>íüÃz–0Ølû 'C¦Æ:k´±Ìð/ÞÉ…èÄäòûkžñhƒk®NØÜÜåí›ÎUzcvqbU¡÷çÿl@n¦ûJŽÙÉ.K†º~òÒCòävûF ± ëªÜ¼³Pì•õ†žô`íî2ãle¡¢Q¨ãçü˜Í;zŠmg£ÅÁëaÌ—aªÙ»ŒI‚Öv×^éô€ARw£Æ¥®X‰¶%3ü1¸R7ÚTVg$Í* &ºb±gnZÈíöÔBEY®ŒqÖî^z€ìg<9¾ÐSÞŒ]½Î$Ûøˆ ½?¢_ý–õº<_XoÑW— Ui»Ü©òÖv×^ée¡Üä55›ÖÛ™‡ª.s Äwl&v^‡_ÁÕ” Ì"[TY`²sÄp\{‹  À^eß·bs¦…˜­è"†£·¯‰Cè%¨6Åf}ˆgQËe‹½ø÷eE·¡¯˜úTHªqq2;fÒ"HÊ_æYÕîÇ*ßg÷(ÚÉ‹ÛÿÀ6™9—y㿉L"ÓfNþÒÂ8lhÉ˺‹›Pl¢ÜÜ6¢­.C¼[4#SB…Ô–XuÞ$æ' zÞ1*S¢_™h´Wc®âVjwÛåï(L«^_ø:"Žk}e-ã~Z|u–ŽÀ™& jïIï k‹™«ÂÑ[.ô6V#µ];Éä7¾`ÐÁÒÈ ©6¥ •8êjZ3Ýà¶úÖ¥ »Úþ’•}Ì;s%#>-ÚêD*‡ TÓ©ô”'%WPPýn˜x¦Ô̓…WÃ;?Sf5½y¼‘¡‘¥jš«+Þ¥§/«‚;|›ó.?ð莆úÊ‹->%šå&I… jªïIïˆS™«ÂXVÏgމ¥8FÑä<ó4”@t²àñfZ”.QÇSRÅ`¶lo Öo­jR»½¯Þ¢*0înfL²R3âÑ÷.¦& ¢¨8]©Æ>’ˆäªëJ†áêÕŠmLÐh8U^ÌìNDPÖòç$c¤iZª à*Þé9ê÷ð}¦ó“˜ìõf¬ËyacxT™ephùÛ€`›ÌKæ-‚2xâ X%|<¼ôÔ!D±i.cßm×ü„)€âEˆÂ¨drîNŸž‘Kì׿/Ò&T/GѶ0Ú „Û+ÄêS~‚å÷™Ì ½þf•;—ÿÂU ²ùÏyÓXØ9ïíˆTªúý1j‚Ð@Ù°jý³ÖxJ¼Jn€·óõ”Ôh ¦Å,/Z¸›ø,»j²^Ž âS:õ ü°ºË×—ËÿD=/?×ïÇZéÿÝn+» ´Ý–ôÃ`¬Ë«°³aIDÙ£+Ș˜!DÖî: g€éÌr±åçg´;.Á¬§ qj­¶Ff0þ?ÈÈrp³b:)3e.aìmpQwv*ªÎ¼±è÷^®ë@’ÊuâX“!eÒ穌Ök%ÂܬÓ@ƒL­±ÅbÄÔà/ÊÞ Fþæ2¥¸¼¢eDZ0ÝA@Ye.º)Îó]cÈ,IL&š½µå¸ó†ÀD”Ó“¢$ZAyojô ´9 Òù£û·‘š¹ô/|1ë_߈²žíl|Vã°³Bšl^DÄÚÈt…œwÀ¨¥Ú_G>ÞÑ(Ä«àS…¸µVÕ”g0ßãüˆNnކФLÙJ\ ® ÆÅAMènœÊžŠõwZˆ`wq-…YÍ]©sŒ˜Íg’ó2}q,í@ƒJVصX¸P c€»ïo<&þçë µî6„Y 7P")YK®ŠóšëÔ0Âc•Úò)‚"\êšà ¦!„à/q]‹€ØN–#݃ýy&0—¥çãѺæ\ngMt~Þ~:À¤Ï1*瘩ÎeÙ~˜7éäZËpuwè{ô€#rÒ=Ý,ZØeYP«+D©+‹Ôõ]¾&èºó)‚f)ÉK–²½8Ø›™zR0ÇÕ•y¨LqÛY|»®ÑÂ!_hõÿÎÿÄ)!1AQaq‘¡±ÁÑð 0áñ@ÿÚ?ÿ;n™kAjZ%|ÊXè‚…[}A‘ 7ÀÛ Á¾7¢ñmmÆêí* "\'…ÓÁÀ­5:l–1êáUA€Â7qÐz@¸Fåʸq"EV'î̳ѵ‘ÿN,‚Ó¸† «XW¤Ž¥ÜRýOdõÈýgé3ňx¹\qÒ:ŸÅ[L—HÎ`Ý@ËÕýæFðD¸#b*BΚŠÃÄ;„GIÓR¯ÌvÝÕ¥"üSP DzR  ´šd‚Õ&9Rì %=g^C¿ 3ôŽX‚b\®qƒÒ:“KòÀ  é5Bn¡dj >º?dtlq!gcµ‡ˆ'`pˆèšjUùŒÛº´ ^øjQä”ŸÆ “H¥GT‰‘8ƒA Xlèâ©9NhÃÐE)´¥Éfò¸²dîbxщzqŠDÈŒqBòF-˜§¾hVfƧQŠ¢‘Ú*G¬Ê)GuÒDt׽ߗ‰ˆ&%°üõF°Uò¨m22ô컓¨ûÎGXWVœ^“í¬«,ª€Q€Ûs¸“D¶Ñ¤NãÄhÙp«ï#vÞ,•F”Eízú„‚c'ÔªÛÿ€‚WaÖ¹ñ:aþÚAbÌX¥ùúE¦ª‹»¢.·š–76X oJçÜ«¹1Â÷a0îÔ!ÁÅñ+^A¿ÄÇþˆ¶ŸÄx>hª˜Âªz–˜8:_Úf!§8l•Ó \ÍýLé#2êYÙ“üºLƒ®w‹Ìî”ï0Š#4•ªÈú•0û7ò¨K÷™U[ëx…ÛÏ)š£'¸€V^O¼~  ›–T[EÈóÄ£Šà©Jû«¾A `=ü—/i-Vh$VÇz”¸|\d^åLmgót¦\±y”܃3¤ÈënñyòæSH.ùd}Jk×BÎCêçâMG iù+ÄgngTdðÅ&´Í¹>.$…PoRåàòx%W@¸Ì1J+«¾AÀ[9.^ÒlNAålo¨KŸKŒ[Ü©¬þaŇ gKÀ°Aü2éŽ F`4Õ Áá~“_&e¥ÂÛèGŒFG—Žá4†S«þúBr÷N. Å^€l /‰lÐU¶ícïdÀ(ˆžåC®í³Jq ”ÞÃ.ó/ uÀç=Sô‹j»<}&š³¾ZªþÈšâ*è2zwó6\OVY-„€Tð$º8ÇÌ×£0—‘jö°e¼-Úžë+Oßül}C#(ÞS¼M˜ë¬² º[\›·ä¼Lì†}7Ò"e™Z”QKP¼Qò%y@0)ý‚Þ¥ôŒ%?Ïð#¨VEµ’ö¹aIiâ,(õ)iŽª˜˜Ì|f(†²Í´Éfê-¥™Nñ6c¬"eÚtÕ ÎZ#‰0Ÿ„ŽÈµÄE‚s©ÀF gÄ2–îž§ü•††§ì˜¥lz¼;=0”ŠcÊr=V¥uE¦’ÿÈÑàtƒmcãü%¦˜K¿na„0Ø|Ä[ù¤K u?\%[ì¨ SdÉãx£ZPh÷,ª4‹jê¯]cBûáU£ÍרE@RÝO´Á¬¥dM¥†ø½^£íÑ eQjËŽMf(Y·š=ÃÓUp°Òí’®+»6.¹Q{·‚pgš¸Õx¨ªM2ÚV‘¼L¹B8¯…JÊÊÒ…_zJ–Ä;(ågygÎW x›„BCX`u«øÿjYUyލ¨ÕRàöz NjܿPõTwD®-6«B¾!¡ö”€ ª¿i˜ˆÉBÊê/@aœ` _Jþ.T GW÷#˜Ku]ýjµâ Á·bZÀ›0Ájà ê >W®T²‹Ž6ˆÕ²àvmZÇi~¡ê¡ÝÀôØ- ê.–¡ªŠ@ ÕûkÔX Aq’ô¦à¾#ðñ(Ô?ˆçfM黺ôÂU¯ »öÔeáj‰ÿf„|?Â1X0•ZÁM#~ Atš:ýÔönJJgi‹|(þƒ÷™¥™N·Æ5hæTÚ¹J0:¼¶öl…‰|Çs¸Ú µ7‚‘Xé.7•+R»£>Ì| ÙÓ±Š1àj-ò7ñ]MǤñ© ‹¢ô¤l /ü o7ˆe0IlúnáûK¢Mo¸“Ôƒl•Åó—¥c¤ØÓR€u?Ø{®SI…7xDpPePc»ñ­ªû2«E¨êJË¥ô³>-A×*>Óø]©FŃTäæ-(:ìG˜âx’ùåÐó)ã„^Ú³?H8[ƒ5Œ •bµIƒô¨OG6pûA§uE—®µO¼Ãdu‹2|@k’ÜÙOGÍb]–©²0Ðôn£„•¹Jî]DI§‚SfP«¢¸ „´à fÔ•˜9;æP'ä%Y°ýä‚fþúÓé5¥EôÌH)~elˆ'kêYC¡U¹N‘!8JCJF¡ ë,Ì嫳§?¯4©¸¸ú°Ò™Ž‚*ƒ4'<ò«1ëÆV`ž¯ôm•šÇ0o;¸qP©|'ó ¶üq5}°Öˆ#’^ÛÙà §Hê<1ÐÏ9£5|*óÖ¡ÊÈ8‡.Nž#¶)©ØUÛ¦'Ù)¸÷Íaµ2Æ;Œ€Ý¦æyì]¦·b«ìÔþ­°S8ààæf[w#jUï4_ÌÌõ6×ÿºxÔæ-M½og 2øÜÜxc3r3*Uç§íý¤!cN§OèÔкÔ7n˜ÉUƒ¥OblŽ’cGH5?¬Ë‘/'&änŒ:ÀÞ¡¦^¶–_}¼ :8i±ìw‹YF¶â\ž רîlèT‰Ñùi"¼cu9Z<‰bn,È5ÂøÑÈŒR%g2ˆSïö­ze—H3Gܤ™xâtÀ¾!ÐK—K§xþE‹ZLŒAEeÚ±óÎIYhá(¡Àµ~¢2öù”’"‚¨Kê^Ó˜sJ«Î’”óر*㉜+F)VPFT½† ÊÛâÚJ3¢}c3õ¸Ur<-AÇD HÜý…c@B`Õ‰`ôËÖ¥.°n«ï••,m?¼g…á $yÒÑ,æT=§´¦¢mžžz…›ù`co¾e]µ”C(´BëHf5u¤3@kÕ¶“–õÞt+¯ßL5Ö?žŽìÒjT¨$è"Ô@æoÔ¯4nÇ¢¿iÛÔ]牕1O] Š»ÜÛù¡ׄÏ O§ïŒá‘ºç˜eR–}È¢ë*ízM@a5p†bB"VÁ×§‰TÉËŒÔ=ö,5˜HFÖÓñWvh5*º#wµ™¿RœÕjÅ£¿ýG¨,7œ:!cGVÐ#¹z~Ü€Ø: ÝËè?tG ™®MÈ#KQ_H›@fQZ^.å,°˜£0Ð,I^ ØoÓÄ«d–ÎP „< R5ð ñ½}½×0ÈXDMI°¥hqëõ(MXìÜ{&B®¥ƒqpªðB`Êî¯Ù¥øå[‰º„á)}SGæéf# `!HÚHË»=| ™Årî+¤Jm¤¦¹Ñ0w¨jK"Û?ä®PÞ¢ÀË[3•yϘÝÐmýˆæ¯?ÂÆHÛ1¦Oˆªx€ã3ù ×UÅèpÇêj÷=»;zˆêLÉ·©«X­ÇÌ·G³ú§X~VU|P¬¤'b‚ e𢶵~#·8–¨-Ü{~ Gaìij•ʸ”„¶Nó\7­DÒNß d­4Bn0{Ö0KwŠ@8EÄ<ÚÆ˜ÆlŠ6¼M]¡aŸ j`ÔÛùAÖ)r°…+9ÐÒû`D |ïüP²8™šƒÂ‘º¶ëÔs”ŒÔar¼½F+R¡Ãa‚×ò;e?~;©Û¡ÔÑøÀüAµj’üÆOˆÔæ-tDhàñæ&ФuZù(iõ"à#áÜ–†’»>‘8ZB² p±z¶ëÔÔyÞi#•åê0Z”Ô–1óƒ+ùžÙ§É‰ ºo/¤ˆ º8™7ž"ÃˆÔæÕ“"ƒ¶Ç2ÍP#¨ÌEy#ª1ä¶Óļ1]Àšäd `Ș qf̓‡t4€æw+F^€î&’†MÙø_‰m¨ØŽÃ òGkUô\•Ob;¦\&~%õi\h5 > E9‰ì0Ç Q‹Ãÿn ,ý˜è*A±1€›®}¥û•’Ô‡èñu¡ ŸUÀØâú ÁíËcêE­K4rD;æ.@Ôæ@69Œ^’ˆ‡†#CZvàMÄŒì¼î8e¥ª1ë7ÍJÕN™ˆ î þ²»êÊ­Um áŸÄ(òþÁdÜsæT+j€wh`¨C­Ÿ«1ï‰tk)"F2­¥—m&¦æŠz•ƒ2¡Ÿ9{8ê¨ÍÍmŠrL<ð ~°£æá”B§’ ˜5©þc•!´ Øö㡲 þö’›Êþ’ØqZaîPÕq{ÚØpB*e¸8aì>g\J“1­»þ´Ñp*X~4üJZèÅÉ3bu)ñwâ¦Ý¢‡W‹oî%Ò1œŒÔ‰pˆÂ\ÊGYqMå56–åÚ+µ’! #‚6×µ°à€*€®Ð–—±ùqCÆ—wõ(5~´µ,J&}Ä®®ŒTÎHúš™î?U¾.á:Ú9*Œ[yó餣«aKVæPi™°¬„Ôæ §µä³C{gÅ›ÍIH2=Ììzza%_HéòL(ÇžaczÍõÖZIwjº ÚÔ^‰ÿ%ëGLÆ5îÃö˜ë >)öa!3ù©mªš'€]0ƒÉ_:T¿h\("â 7—Öm—TEž#9Úæ!•®%qq«LOaphíÌ$ʦlEmÜ¡ìClì:aD¾®ñ°Äˆøžàf/o¯Þ ZõÎäºZÁcB‘-GEKr+ýG §­ ¬JµF3p„0¤ŠŒAàE+IT º^((w̹.4ví1ûë˜Ôg²í†oŽ z*XM¦2¡¸è}’»¯ôÌk$ck†Ÿè5”;áoª _÷´–µez#€,6Å´u-ƒx½|²’É ƒyŽ΢õCÓÁ1/ZJ‹5b#Fÿ±—^#^iˆ%Â*¼FÕC0@ò–òÚ/Ä1Íá•V!&†D£ZáÍñüË𲏡2ƤU.Ä¡j‘v9òÊKàžö´Qà†ÜÊDg$Ä,_úÆH©Yľïp í€F‡ˆÌõƒX §×ôFÈF1ŒwnÛaæ!#a2m¾¦ˆ 0_qfOVs[J¨Æ@U=Ëpÿ¢Ð²oTø¸,ÿ¶ ¨:‚+je` }?&uEh¡õ‚VžõŸuZ[DKU®5Š)¸U¥ÁÝf]xœ1‚Su•qZe€¾%ÔÄ[Œ³ þHâš2´u ÍK<ÇæjÚµM²Ê«RŸOÉQ èh;ËKLÇ>ª“q9¼ÔATV¸Ö#”¤®àЗ'z¥×d«9 ”ž£2]ÄmEšqËâ;1¸ÇÈÛ_Áä‚“FåÇ()†¦Ñ;dðÿéî'e¡×#µ~¦Nˆ¨À!Öü˜¤ÔãMŸ¨”ô`>ãæi¯XM_q¦ìztCA¬&Ñó¯ßéš' {· Þ„-Ò…A"òDÞ+¤˜ÒÕÄ·h²ÚE3l¡,ÝQ”WQƒçé—ÿ »F—Ä´›Ÿ­Ôn¡´ñÔeYãïáÑ‹„lš“Ž[Q·ó6è€&¨SPv y@Vë/«K§0EB"RèÀT¥uøŽ‰ñ’þ“ LŸÄ!h¤qÈrv¦q !yg1¯± ÕçcÄ|ëÂÃðéQ¤lš“*ßH[‚*¿µ£¾\‚XÊv>²•MÈ£ ´ÝØÜ´äpÂc%ñÿ±ëª‹êxPòQJZF–¼…FÔH¦í»C"CA°lÑ(y ×SM(Íi2}±–ô¾àu?çâL[õÃþ ôM }MãˆX;Ò  c!ÔApü0™¸Xà<¦GÄ#Õ hÖyDDlÝ ®g\z)ÆJìµ!i±zuˆ½¦“ 87“JmUG7ÿ% õ%–À݃BíUëBà jÙÔ@öqâ)SÏ9žÖñ?ë ÏOò¨‰²'C|0—bIWGTÚ6mÝÕSÑ Š¬`1‡A!Í\`* rúD”CµÃ1¹óßQ¼˜ãø4 0Ö‰ö”ÅLˆÄ1ÛÕ ß>aÕ¶çzÆ’¢¨¢4!‰ì4æyQÌD!wõTV®*W-æV€yÂg\îª:<0á$Ù”ô„w\E4dÃ}¿ˆZ¤.¦%É* Ù)±16!Bþ4wüió­·0;‡ZJʬ¡Fy eÈò£ŸC}CHe±Q¦à2¬+r Bé5Uƒƒ0áD‚2š‚$+­écŸ‡Äd¡¢7!£ûï*VÃêòߨ¹pe†´[* WX–"ÜFisq}g²Õ…Ó8!ˆuq«GQQ®ðTP³[°7$‹/íQ‚´ü±+Ÿ,p¤áyΰ ÆBªa‘MEK'm΢Eš.«¼®ÔlÉjŠö°i|Bl˜@ Js—ÒR °(¸´tLÐ Þ¿ø‰BÍû+]T"Û ~ý±ÊBÑe¿|KŽ¡®Í77á iuJ ÷Š«_ANRõ:Á¡bÖ–þâvë ƒO0NÖ(ZÞˆ ›MF1TTª{¢ãTÁ‹=Â3¿úŠJ ¹¹ôéê,b†ð k7Ó•4Z rð2ÌŽ›/CžÛ ÓµÀ¼öÌqÓpx`pÜjôëP#cK*–ôý†"ɧ4 ñr¹Z?„¤Ò ~%VÝÉ*ÃE™aM`Í©þ̺¹ú?ögÔzƒ¶ßK*È\§‰·„}âËU²½`ªTîbâ5¼.Ê‘JÖÂà'xèøcÖ"@XTcÃ40+ç†`m¥•©†ªVš<­!0WjïË4Q–Ë-ÃOöY{{ôögZz‚¶ßë*È\«R…ÜujÝå¬Uó1ÙáöTŠV¶K–]ã£ášr‚&ÃYœ‚øÑïšÑž•?¦ð3Jo¹ø™÷¯íCgÕŽhÅšvšUÑ qÐ8yÐ~X[Aù2ý*f8spØí3Û¹‡]M†ƒÐ‹0¡žªÛô¹JÞŸIå˜2]á‚áb™€Œ°ùzF^ÂWH —„S_söŒ0;r¼Sv3rà ÐÛ‡îSÁ¹2»¨dÙqw^CV\`Hy yÞ9§Ó±·°ª™Qºƒ‹'û¼[ãa7¶>1³öËl¯ÿÃ4F¶7CÖ#’dC ¿ãØBPK"°ì•_êä#åa-½q½4Ú²œ˜{6¬öCú%~f[KxbÄ îu °«‚öxXsUÞZph–qc]D£Apç©D$mF!)kwÂ÷â6ä3þ‡ÏBí€Rù²+ÿM¥ %c7Ï÷ïsu¸ªØF¯ê¹4y–Ô%RJ.äMdT cî*#¢åѨGXÕÖ¨Fj$ÅñYvÂ!EÐjMî6c 4„©ú%²ÚfF%Rn¾¿ykÀº‚T …¶>ÕýAïT\Ñæ_PT•(]ȚŨq~17fjÇ<ƒT#1xÁ`¥—h2QP4“Ù²F´¨…OÑ3È÷?´‚²üLwड{×ÄŸfVƒ=^ðåCofÐ@e~T8üŸë–:©Ø0+ˆßÅŸae`r¯ ÿ³Sê_¬É]l”ÁÌ™A‰jŒ¿ðLˆÒ*ZQ/!IPÚí•`{LyôJÑqk-%E̵e©¥à ¿y¾½ï)•AÒ(Ò+ƒÓÑøŸq³;g­EAö'%µÁûeËCÁ4ÉŒG|„y€|÷J5*ŸõÁiŠ‘6) ¨¤¥ÊÔʵ_1‰•Úr+þwÍÁ­äþ1Á¥½+gÚMôðó(.nŠbâ"n¯aFÂÜ+O%ߨ±U’ßû1c rØ„¸æ|k5‚‹¯–uA0e–cüÃ: e¬™3Tªâ§Öa]GÎvÄ…T³’¬]âa<Æ5/‚!kÅ~óP?_Ò\"8~Q­«o„ì&Ií ê@Œ‘V€þ„WûµÚüàô ­*ªDU?2ã!ÊŒrJ/$´Ä¨Zé,Š«†èÓ1rÛRÌ:J±ñOªæb_W^ûÍPýrÇÑ«^ŒUíð5wTQ#•E ´lô"#îÕOkð{‡@6´¢©Lüȯ Œ Ù¨Ay%¸Nei/ŠÖ}ópÕš_ˆŽ]iÓ/-íâ!ÉHtª›£ö9õ6"~Ðüƹš—ÎÒÕôTÂ|‘Ôé>Ohoзæ[ `:õe0àO—/â9Ù3}ËaÑ({.¡¦°¸´1ä²Ô™kKpz1®YF \–mNÁî÷ˆ°:`M>—å‰Ç½šín£²Ï¨Ä:;˜Õ ë‘åD ÀƒÐòÂ&c~fS}.ê—†Ìñm—åûFȲññ-D€ÖÄ ¥£ˆ¸ DÐ\ýj©´-£ C^ó>Rêñ‰pıªÁ‹º¿1Ôy\¼TzgZÓGF$@µÕ¬·³Åh"ËÜ••QºûÅ"Ãb¬¿/†pÌbŒ#1ŒíGÖvg ™·O0•kTД೻ -ÌÓùPÞ; ³z˜×”ÙÆÖ0Í€çx/å1o0‚Ó,!Üól<^8=jý%ØßG韬UMwE`ê m÷Ê·6±ôXÄÂÄ­é7–ÉüÕ%›Û6s¤ãïV¯×bÜ Išée'y,Ä Ø/¡¦\©õ¸°_‘0z•S‘’Â4B@©?Ž-æZe„+xvæØÈ'â=oô—­ý?¦eø×tY‡(u÷ˆ z>‹8X•§ yùšU¦Õ &µ›9Ò`ì«‚úä0op4}&p=ŸªKŠ{ƒø†¯pû ˆŸˆZ&R  ™!,2FˆH$£áhPÒ],øn;í1à«.Ùí¢²vÄß/0å\ëW±åPìE$þÚÍ à „ª»òï3¶¯üG†Ìó1Ò–0ôH»…aQoÞû_÷m8d³{æS i6hdé0}ï­ßby̾« ´ùþ`‰TÞ ª—+A«1†ßÜ Xeåe¾PPá¦Guú9bŽÀ=<}‚UšPçË*AwC~å!ƒÁþЄBÛ²ž3ÓÔîøV”L—ÞÔZ5 r¥Ád°ØÞÐÞùúÌvÃ&+2} Y;6÷M¸š½·xÔÊîêjÓJûFf­ÎKjt¶{8€\ ø$€˜6²X ªYNWˆíïx:•„–ç¨ …À^±©jåEóô7€™äÆBõkÎ54ÒиNT¬²ÜjÓø6ãp HYâj/’!l=¦Hj4z† AjÙ–Û,l•Ö§*¥<µ—Ìòã‹‹5û_8ÑeUh—Àu0µ~s}•á¸cX]ò°øØ3Á*|”´˜jî÷–5`Ì1¤Ž¸¤s=³ÔZehÒ¾@Jçh-i¥Çž¨ƒ[æò\{8¸.,Ì÷ÛÑ÷‡®Ÿˆh{bÊ€9gqûå—ƒ{†¶RÚ_åøë±kC£C •}«žØ F¸®<»–E-SŠ™û¨Êù~&$ ×Ú¾L1@›R·æÕ¯ñ§ð¬QBøFÛ’Ž uaèBC“• ]ëá6˜Dv65z‰³Ž0ŒÚ¾â÷ €ßýf<T¥0â$[‚· ð†(Zù¶fÏržÀL/¸:£—b$¬i ÿ̹¡ìÕè˜Î±  ­Ü³ÚPå¥ÂÅÌšC)…5m¹¯Ö*zŠó¹}¡\È—pÏÖ£½lµà¸Èe9r*ïÉXÛe•ì%¨ z¿Ðtk11a¡o(.ª»<‰24w&Œ1øH2ðʵMt…- ­o=AàŒ‡C%jï U¬¹~Ưd-_e2ðŸf^U ‡ê cÀÁ]¶û£ñ óì¼,Ö‡V´UÁŒ¨¸™–'dŰÂ)Hè‰VåFñ´@Ê w±.;œbü»`@´”Žkˆì×üÄ«,ð0`º î}ÂBtNE ðòi¹5æÞ„r¬Yâ-ÓHÑÕm›ä!|C¥©jöŒRNçòeœËÈûKÊ©áÈLLppW+h|¥^}÷€oIZ ­9EÇPôðá6F©ã $Žl%ˆV¥rxç È:¸;Ø–±ÕÓëò‚ÒR9®#³_ð`¶¬B©!… Úgþ·…7/ä;ð /:ùé´@u6Á B— S¼u„"=3?l®`’ÛRŵmÀe­ç…ó!o£B²+/P‘%ܘåP´h8u*éЮ²åõkìC4I j²Øiç˜0+Whã§jKÛ®„ µ  p€2Öo­…Á9»¨8È©§B‚À6õ+Ž:Å¥JšBÛAdbãÆ@¢b‰h‰àŸ¤±´™—W»P`»tJ –™ â&ñ‚ÃÔB²‹@¦‚`RÆE(D¶J¯ÐËC’Û -£c@±,Õj0E¯bÏ…¸Í(kâ#…Yí¸Âª YÀmwo—:>åÖXõU²µµÖJ­‚´57òÍ (5”_#rîØÇ0Õ˜Õb×·ŒsÔ%YJhq- ´Õf¾Ô·‰K­%p¥0ÈI0F¬&)tt<™àb\b®uœpÕËã!ó ÕC¨:­ïò –z„e\Kü\`’òÊ/–2¦ú£MFHMe¯F¬]«Z[šŠ_úÿÿÙarb-2.22.1/doc/source/_static/default.css000066400000000000000000000005161417376376500202200ustar00rootroot00000000000000@import url("classic.css"); div .toctree-wrapper { column-count: 2; } div .toctree-wrapper > ul { margin: 0; } ul .toctree-l1 { margin: 0; -webkit-column-break-inside: avoid; page-break-inside: avoid; break-inside: avoid-column; } div.body { min-width: 450px; max-width: 100%; } li p { margin: 0.2em; } arb-2.22.1/doc/source/acb.rst000066400000000000000000001412551417376376500157210ustar00rootroot00000000000000.. _acb: **acb.h** -- complex numbers =============================================================================== An :type:`acb_t` represents a complex number with error bounds. An :type:`acb_t` consists of a pair of real number balls of type :type:`arb_struct`, representing the real and imaginary part with separate error bounds. An :type:`acb_t` thus represents a rectangle `[m_1-r_1, m_1+r_1] + [m_2-r_2, m_2+r_2] i` in the complex plane. This is used instead of a disk or square representation (consisting of a complex floating-point midpoint with a single radius), since it allows implementing many operations more conveniently by splitting into ball operations on the real and imaginary parts. It also allows tracking when complex numbers have an exact (for example exactly zero) real part and an inexact imaginary part, or vice versa. The interface for the :type:`acb_t` type is slightly less developed than that for the :type:`arb_t` type. In many cases, the user can easily perform missing operations by directly manipulating the real and imaginary parts. Types, macros and constants ------------------------------------------------------------------------------- .. type:: acb_struct .. type:: acb_t An *acb_struct* consists of a pair of *arb_struct*:s. An *acb_t* is defined as an array of length one of type *acb_struct*, permitting an *acb_t* to be passed by reference. .. type:: acb_ptr Alias for ``acb_struct *``, used for vectors of numbers. .. type:: acb_srcptr Alias for ``const acb_struct *``, used for vectors of numbers when passed as constant input to functions. .. macro:: acb_realref(x) Macro returning a pointer to the real part of *x* as an *arb_t*. .. macro:: acb_imagref(x) Macro returning a pointer to the imaginary part of *x* as an *arb_t*. Memory management ------------------------------------------------------------------------------- .. function:: void acb_init(acb_t x) Initializes the variable *x* for use, and sets its value to zero. .. function:: void acb_clear(acb_t x) Clears the variable *x*, freeing or recycling its allocated memory. .. function:: acb_ptr _acb_vec_init(slong n) Returns a pointer to an array of *n* initialized *acb_struct*:s. .. function:: void _acb_vec_clear(acb_ptr v, slong n) Clears an array of *n* initialized *acb_struct*:s. .. function:: slong acb_allocated_bytes(const acb_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(acb_struct)`` to get the size of the object as a whole. .. function:: slong _acb_vec_allocated_bytes(acb_srcptr vec, slong len) Returns the total number of bytes allocated for this vector, i.e. the space taken up by the vector itself plus the sum of the internal heap allocation sizes for all its member elements. .. function:: double _acb_vec_estimate_allocated_bytes(slong len, slong prec) Estimates the number of bytes that need to be allocated for a vector of *len* elements with *prec* bits of precision, including the space for internal limb data. See comments for :func:`_arb_vec_estimate_allocated_bytes`. Basic manipulation ------------------------------------------------------------------------------- .. function:: void acb_zero(acb_t z) .. function:: void acb_one(acb_t z) .. function:: void acb_onei(acb_t z) Sets *z* respectively to 0, 1, `i = \sqrt{-1}`. .. function:: void acb_set(acb_t z, const acb_t x) .. function:: void acb_set_ui(acb_t z, ulong x) .. function:: void acb_set_si(acb_t z, slong x) .. function:: void acb_set_d(acb_t z, double x) .. function:: void acb_set_fmpz(acb_t z, const fmpz_t x) .. function:: void acb_set_arb(acb_t z, const arb_t c) Sets *z* to the value of *x*. .. function:: void acb_set_si_si(acb_t z, slong x, slong y) .. function:: void acb_set_d_d(acb_t z, double x, double y) .. function:: void acb_set_fmpz_fmpz(acb_t z, const fmpz_t x, const fmpz_t y) .. function:: void acb_set_arb_arb(acb_t z, const arb_t x, const arb_t y) Sets the real and imaginary part of *z* to the values *x* and *y* respectively .. function:: void acb_set_fmpq(acb_t z, const fmpq_t x, slong prec) .. function:: void acb_set_round(acb_t z, const acb_t x, slong prec) .. function:: void acb_set_round_fmpz(acb_t z, const fmpz_t x, slong prec) .. function:: void acb_set_round_arb(acb_t z, const arb_t x, slong prec) Sets *z* to *x*, rounded to *prec* bits. .. function:: void acb_swap(acb_t z, acb_t x) Swaps *z* and *x* efficiently. .. function:: void acb_add_error_arf(acb_t x, const arf_t err) .. function:: void acb_add_error_mag(acb_t x, const mag_t err) .. function:: void acb_add_error_arb(acb_t x, const arb_t err) Adds *err* to the error bounds of both the real and imaginary parts of *x*, modifying *x* in-place. .. function:: void acb_get_mid(acb_t m, const acb_t x) Sets *m* to the midpoint of *x*. Input and output ------------------------------------------------------------------------------- The *acb_print...* functions print to standard output, while *acb_fprint...* functions print to the stream *file*. .. function:: void acb_print(const acb_t x) .. function:: void acb_fprint(FILE * file, const acb_t x) Prints the internal representation of *x*. .. function:: void acb_printd(const acb_t x, slong digits) .. function:: void acb_fprintd(FILE * file, const acb_t x, slong digits) Prints *x* in decimal. The printed value of the radius is not adjusted to compensate for the fact that the binary-to-decimal conversion of both the midpoint and the radius introduces additional error. .. function:: void acb_printn(const acb_t x, slong digits, ulong flags) .. function:: void acb_fprintn(FILE * file, const acb_t x, slong digits, ulong flags) Prints a nice decimal representation of *x*, using the format of :func:`arb_get_str` (or the corresponding :func:`arb_printn`) for the real and imaginary parts. By default, the output shows the midpoint of both the real and imaginary parts with a guaranteed error of at most one unit in the last decimal place. In addition, explicit error bounds are printed so that the displayed decimal interval is guaranteed to enclose *x*. Any flags understood by :func:`arb_get_str` can be passed via *flags* to control the format of the real and imaginary parts. Random number generation ------------------------------------------------------------------------------- .. function:: void acb_randtest(acb_t z, flint_rand_t state, slong prec, slong mag_bits) Generates a random complex number by generating separate random real and imaginary parts. .. function:: void acb_randtest_special(acb_t z, flint_rand_t state, slong prec, slong mag_bits) Generates a random complex number by generating separate random real and imaginary parts. Also generates NaNs and infinities. .. function:: void acb_randtest_precise(acb_t z, flint_rand_t state, slong prec, slong mag_bits) Generates a random complex number with precise real and imaginary parts. .. function:: void acb_randtest_param(acb_t z, flint_rand_t state, slong prec, slong mag_bits) Generates a random complex number, with very high probability of generating integers and half-integers. Precision and comparisons ------------------------------------------------------------------------------- .. function:: int acb_is_zero(const acb_t z) Returns nonzero iff *z* is zero. .. function:: int acb_is_one(const acb_t z) Returns nonzero iff *z* is exactly 1. .. function:: int acb_is_finite(const acb_t z) Returns nonzero iff *z* certainly is finite. .. function:: int acb_is_exact(const acb_t z) Returns nonzero iff *z* is exact. .. function:: int acb_is_int(const acb_t z) Returns nonzero iff *z* is an exact integer. .. function:: int acb_is_int_2exp_si(const acb_t x, slong e) Returns nonzero iff *z* exactly equals `n 2^e` for some integer *n*. .. function:: int acb_equal(const acb_t x, const acb_t y) Returns nonzero iff *x* and *y* are identical as sets, i.e. if the real and imaginary parts are equal as balls. Note that this is not the same thing as testing whether both *x* and *y* certainly represent the same complex number, unless either *x* or *y* is exact (and neither contains NaN). To test whether both operands *might* represent the same mathematical quantity, use :func:`acb_overlaps` or :func:`acb_contains`, depending on the circumstance. .. function:: int acb_equal_si(const acb_t x, slong y) Returns nonzero iff *x* is equal to the integer *y*. .. function:: int acb_eq(const acb_t x, const acb_t y) Returns nonzero iff *x* and *y* are certainly equal, as determined by testing that :func:`arb_eq` holds for both the real and imaginary parts. .. function:: int acb_ne(const acb_t x, const acb_t y) Returns nonzero iff *x* and *y* are certainly not equal, as determined by testing that :func:`arb_ne` holds for either the real or imaginary parts. .. function:: int acb_overlaps(const acb_t x, const acb_t y) Returns nonzero iff *x* and *y* have some point in common. .. function:: void acb_union(acb_t z, const acb_t x, const acb_t y, slong prec) Sets *z* to a complex interval containing both *x* and *y*. .. function:: void acb_get_abs_ubound_arf(arf_t u, const acb_t z, slong prec) Sets *u* to an upper bound for the absolute value of *z*, computed using a working precision of *prec* bits. .. function:: void acb_get_abs_lbound_arf(arf_t u, const acb_t z, slong prec) Sets *u* to a lower bound for the absolute value of *z*, computed using a working precision of *prec* bits. .. function:: void acb_get_rad_ubound_arf(arf_t u, const acb_t z, slong prec) Sets *u* to an upper bound for the error radius of *z* (the value is currently not computed tightly). .. function:: void acb_get_mag(mag_t u, const acb_t x) Sets *u* to an upper bound for the absolute value of *x*. .. function:: void acb_get_mag_lower(mag_t u, const acb_t x) Sets *u* to a lower bound for the absolute value of *x*. .. function:: int acb_contains_fmpq(const acb_t x, const fmpq_t y) .. function:: int acb_contains_fmpz(const acb_t x, const fmpz_t y) .. function:: int acb_contains(const acb_t x, const acb_t y) Returns nonzero iff *y* is contained in *x*. .. function:: int acb_contains_zero(const acb_t x) Returns nonzero iff zero is contained in *x*. .. function:: int acb_contains_int(const acb_t x) Returns nonzero iff the complex interval represented by *x* contains an integer. .. function:: int acb_contains_interior(const acb_t x, const acb_t y) Tests if *y* is contained in the interior of *x*. This predicate always evaluates to false if *x* and *y* are both real-valued, since an imaginary part of 0 is not considered contained in the interior of the point interval 0. More generally, the same problem occurs for intervals with an exact real or imaginary part. Such intervals must be handled specially by the user where a different interpretation is intended. .. function:: slong acb_rel_error_bits(const acb_t x) Returns the effective relative error of *x* measured in bits. This is computed as if calling :func:`arb_rel_error_bits` on the real ball whose midpoint is the larger out of the real and imaginary midpoints of *x*, and whose radius is the larger out of the real and imaginary radiuses of *x*. .. function:: slong acb_rel_accuracy_bits(const acb_t x) Returns the effective relative accuracy of *x* measured in bits, equal to the negative of the return value from :func:`acb_rel_error_bits`. .. function:: slong acb_rel_one_accuracy_bits(const acb_t x) Given a ball with midpoint *m* and radius *r*, returns an approximation of the relative accuracy of `[\max(1,|m|) \pm r]` measured in bits. .. function:: slong acb_bits(const acb_t x) Returns the maximum of *arb_bits* applied to the real and imaginary parts of *x*, i.e. the minimum precision sufficient to represent *x* exactly. .. function:: void acb_indeterminate(acb_t x) Sets *x* to `[\operatorname{NaN} \pm \infty] + [\operatorname{NaN} \pm \infty]i`, representing an indeterminate result. .. function:: void acb_trim(acb_t y, const acb_t x) Sets *y* to a a copy of *x* with both the real and imaginary parts trimmed (see :func:`arb_trim`). .. function:: int acb_is_real(const acb_t x) Returns nonzero iff the imaginary part of *x* is zero. It does not test whether the real part of *x* also is finite. .. function:: int acb_get_unique_fmpz(fmpz_t z, const acb_t x) If *x* contains a unique integer, sets *z* to that value and returns nonzero. Otherwise (if *x* represents no integers or more than one integer), returns zero. Complex parts ------------------------------------------------------------------------------- .. function:: void acb_get_real(arb_t re, const acb_t z) Sets *re* to the real part of *z*. .. function:: void acb_get_imag(arb_t im, const acb_t z) Sets *im* to the imaginary part of *z*. .. function:: void acb_arg(arb_t r, const acb_t z, slong prec) Sets *r* to a real interval containing the complex argument (phase) of *z*. We define the complex argument have a discontinuity on `(-\infty,0]`, with the special value `\operatorname{arg}(0) = 0`, and `\operatorname{arg}(a+0i) = \pi` for `a < 0`. Equivalently, if `z = a+bi`, the argument is given by `\operatorname{atan2}(b,a)` (see :func:`arb_atan2`). .. function:: void acb_abs(arb_t r, const acb_t z, slong prec) Sets *r* to the absolute value of *z*. .. function:: void acb_sgn(acb_t r, const acb_t z, slong prec) Sets *r* to the complex sign of *z*, defined as 0 if *z* is exactly zero and the projection onto the unit circle `z / |z| = \exp(i \arg(z))` otherwise. .. function:: void acb_csgn(arb_t r, const acb_t z) Sets *r* to the extension of the real sign function taking the value 1 for *z* strictly in the right half plane, -1 for *z* strictly in the left half plane, and the sign of the imaginary part when *z* is on the imaginary axis. Equivalently, `\operatorname{csgn}(z) = z / \sqrt{z^2}` except that the value is 0 when *z* is exactly zero. Arithmetic ------------------------------------------------------------------------------- .. function:: void acb_neg(acb_t z, const acb_t x) .. function:: void acb_neg_round(acb_t z, const acb_t x, slong prec) Sets *z* to the negation of *x*. .. function:: void acb_conj(acb_t z, const acb_t x) Sets *z* to the complex conjugate of *x*. .. function:: void acb_add_ui(acb_t z, const acb_t x, ulong y, slong prec) .. function:: void acb_add_si(acb_t z, const acb_t x, slong y, slong prec) .. function:: void acb_add_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) .. function:: void acb_add_arb(acb_t z, const acb_t x, const arb_t y, slong prec) .. function:: void acb_add(acb_t z, const acb_t x, const acb_t y, slong prec) Sets *z* to the sum of *x* and *y*. .. function:: void acb_sub_ui(acb_t z, const acb_t x, ulong y, slong prec) .. function:: void acb_sub_si(acb_t z, const acb_t x, slong y, slong prec) .. function:: void acb_sub_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) .. function:: void acb_sub_arb(acb_t z, const acb_t x, const arb_t y, slong prec) .. function:: void acb_sub(acb_t z, const acb_t x, const acb_t y, slong prec) Sets *z* to the difference of *x* and *y*. .. function:: void acb_mul_onei(acb_t z, const acb_t x) Sets *z* to *x* multiplied by the imaginary unit. .. function:: void acb_div_onei(acb_t z, const acb_t x) Sets *z* to *x* divided by the imaginary unit. .. function:: void acb_mul_ui(acb_t z, const acb_t x, ulong y, slong prec) .. function:: void acb_mul_si(acb_t z, const acb_t x, slong y, slong prec) .. function:: void acb_mul_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) .. function:: void acb_mul_arb(acb_t z, const acb_t x, const arb_t y, slong prec) Sets *z* to the product of *x* and *y*. .. function:: void acb_mul(acb_t z, const acb_t x, const acb_t y, slong prec) Sets *z* to the product of *x* and *y*. If at least one part of *x* or *y* is zero, the operations is reduced to two real multiplications. If *x* and *y* are the same pointers, they are assumed to represent the same mathematical quantity and the squaring formula is used. .. function:: void acb_mul_2exp_si(acb_t z, const acb_t x, slong e) .. function:: void acb_mul_2exp_fmpz(acb_t z, const acb_t x, const fmpz_t e) Sets *z* to *x* multiplied by `2^e`, without rounding. .. function:: void acb_sqr(acb_t z, const acb_t x, slong prec) Sets *z* to *x* squared. .. function:: void acb_cube(acb_t z, const acb_t x, slong prec) Sets *z* to *x* cubed, computed efficiently using two real squarings, two real multiplications, and scalar operations. .. function:: void acb_addmul(acb_t z, const acb_t x, const acb_t y, slong prec) .. function:: void acb_addmul_ui(acb_t z, const acb_t x, ulong y, slong prec) .. function:: void acb_addmul_si(acb_t z, const acb_t x, slong y, slong prec) .. function:: void acb_addmul_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) .. function:: void acb_addmul_arb(acb_t z, const acb_t x, const arb_t y, slong prec) Sets *z* to *z* plus the product of *x* and *y*. .. function:: void acb_submul(acb_t z, const acb_t x, const acb_t y, slong prec) .. function:: void acb_submul_ui(acb_t z, const acb_t x, ulong y, slong prec) .. function:: void acb_submul_si(acb_t z, const acb_t x, slong y, slong prec) .. function:: void acb_submul_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) .. function:: void acb_submul_arb(acb_t z, const acb_t x, const arb_t y, slong prec) Sets *z* to *z* minus the product of *x* and *y*. .. function:: void acb_inv(acb_t z, const acb_t x, slong prec) Sets *z* to the multiplicative inverse of *x*. .. function:: void acb_div_ui(acb_t z, const acb_t x, ulong y, slong prec) .. function:: void acb_div_si(acb_t z, const acb_t x, slong y, slong prec) .. function:: void acb_div_fmpz(acb_t z, const acb_t x, const fmpz_t y, slong prec) .. function:: void acb_div_arb(acb_t z, const acb_t x, const arb_t y, slong prec) .. function:: void acb_div(acb_t z, const acb_t x, const acb_t y, slong prec) Sets *z* to the quotient of *x* and *y*. Dot product ------------------------------------------------------------------------------- .. function:: void acb_dot_precise(acb_t res, const acb_t s, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) void acb_dot_simple(acb_t res, const acb_t s, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) void acb_dot(acb_t res, const acb_t s, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) Computes the dot product of the vectors *x* and *y*, setting *res* to `s + (-1)^{subtract} \sum_{i=0}^{len-1} x_i y_i`. The initial term *s* is optional and can be omitted by passing *NULL* (equivalently, `s = 0`). The parameter *subtract* must be 0 or 1. The length *len* is allowed to be negative, which is equivalent to a length of zero. The parameters *xstep* or *ystep* specify a step length for traversing subsequences of the vectors *x* and *y*; either can be negative to step in the reverse direction starting from the initial pointer. Aliasing is allowed between *res* and *s* but not between *res* and the entries of *x* and *y*. The default version determines the optimal precision for each term and performs all internal calculations using mpn arithmetic with minimal overhead. This is the preferred way to compute a dot product; it is generally much faster and more precise than a simple loop. The *simple* version performs fused multiply-add operations in a simple loop. This can be used for testing purposes and is also used as a fallback by the default version when the exponents are out of range for the optimized code. The *precise* version computes the dot product exactly up to the final rounding. This can be extremely slow and is only intended for testing. .. function:: void acb_approx_dot(acb_t res, const acb_t s, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) Computes an approximate dot product *without error bounds*. The radii of the inputs are ignored (only the midpoints are read) and only the midpoint of the output is written. .. function:: void acb_dot_ui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) void acb_dot_si(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const slong * y, slong ystep, slong len, slong prec) void acb_dot_uiui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) void acb_dot_siui(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) void acb_dot_fmpz(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, const fmpz * y, slong ystep, slong len, slong prec) Equivalent to :func:`acb_dot`, but with integers in the array *y*. The *uiui* and *siui* versions take an array of double-limb integers as input; the *siui* version assumes that these represent signed integers in two's complement form. Mathematical constants ------------------------------------------------------------------------------- .. function:: void acb_const_pi(acb_t y, slong prec) Sets *y* to the constant `\pi`. Powers and roots ------------------------------------------------------------------------------- .. function:: void acb_sqrt(acb_t r, const acb_t z, slong prec) Sets *r* to the square root of *z*. If either the real or imaginary part is exactly zero, only a single real square root is needed. Generally, we use the formula `\sqrt{a+bi} = u/2 + ib/u, u = \sqrt{2(|a+bi|+a)}`, requiring two real square root extractions. .. function:: void acb_sqrt_analytic(acb_t r, const acb_t z, int analytic, slong prec) Computes the square root. If *analytic* is set, gives a NaN-containing result if *z* touches the branch cut. .. function:: void acb_rsqrt(acb_t r, const acb_t z, slong prec) Sets *r* to the reciprocal square root of *z*. If either the real or imaginary part is exactly zero, only a single real reciprocal square root is needed. Generally, we use the formula `1/\sqrt{a+bi} = ((a+r) - bi)/v, r = |a+bi|, v = \sqrt{r |a+bi+r|^2}`, requiring one real square root and one real reciprocal square root. .. function:: void acb_rsqrt_analytic(acb_t r, const acb_t z, int analytic, slong prec) Computes the reciprocal square root. If *analytic* is set, gives a NaN-containing result if *z* touches the branch cut. .. function:: void acb_quadratic_roots_fmpz(acb_t r1, acb_t r2, const fmpz_t a, const fmpz_t b, const fmpz_t c, slong prec) Sets *r1* and *r2* to the roots of the quadratic polynomial `ax^2 + bx + c`. Requires that *a* is nonzero. This function is implemented so that both roots are computed accurately even when direct use of the quadratic formula would lose accuracy. .. function:: void acb_root_ui(acb_t r, const acb_t z, ulong k, slong prec) Sets *r* to the principal *k*-th root of *z*. .. function:: void acb_pow_fmpz(acb_t y, const acb_t b, const fmpz_t e, slong prec) .. function:: void acb_pow_ui(acb_t y, const acb_t b, ulong e, slong prec) .. function:: void acb_pow_si(acb_t y, const acb_t b, slong e, slong prec) Sets `y = b^e` using binary exponentiation (with an initial division if `e < 0`). Note that these functions can get slow if the exponent is extremely large (in such cases :func:`acb_pow` may be superior). .. function:: void acb_pow_arb(acb_t z, const acb_t x, const arb_t y, slong prec) .. function:: void acb_pow(acb_t z, const acb_t x, const acb_t y, slong prec) Sets `z = x^y`, computed using binary exponentiation if `y` if a small exact integer, as `z = (x^{1/2})^{2y}` if `y` is a small exact half-integer, and generally as `z = \exp(y \log x)`. .. function:: void acb_pow_analytic(acb_t r, const acb_t x, const acb_t y, int analytic, slong prec) Computes the power `x^y`. If *analytic* is set, gives a NaN-containing result if *x* touches the branch cut (unless *y* is an integer). .. function:: void acb_unit_root(acb_t res, ulong order, slong prec) Sets *res* to `\exp(\frac{2i\pi}{\mathrm{order}})` to precision *prec*. Exponentials and logarithms ------------------------------------------------------------------------------- .. function:: void acb_exp(acb_t y, const acb_t z, slong prec) Sets *y* to the exponential function of *z*, computed as `\exp(a+bi) = \exp(a) \left( \cos(b) + \sin(b) i \right)`. .. function:: void acb_exp_pi_i(acb_t y, const acb_t z, slong prec) Sets *y* to `\exp(\pi i z)`. .. function:: void acb_exp_invexp(acb_t s, acb_t t, const acb_t z, slong prec) Sets `s = \exp(z)` and `t = \exp(-z)`. .. function:: void acb_expm1(acb_t res, const acb_t z, slong prec) Sets *res* to `\exp(z)-1`, using a more accurate method when `z \approx 0`. .. function:: void acb_log(acb_t y, const acb_t z, slong prec) Sets *y* to the principal branch of the natural logarithm of *z*, computed as `\log(a+bi) = \frac{1}{2} \log(a^2 + b^2) + i \operatorname{arg}(a+bi)`. .. function:: void acb_log_analytic(acb_t r, const acb_t z, int analytic, slong prec) Computes the natural logarithm. If *analytic* is set, gives a NaN-containing result if *z* touches the branch cut. .. function:: void acb_log1p(acb_t z, const acb_t x, slong prec) Sets `z = \log(1+x)`, computed accurately when `x \approx 0`. Trigonometric functions ------------------------------------------------------------------------------- .. function:: void acb_sin(acb_t s, const acb_t z, slong prec) .. function:: void acb_cos(acb_t c, const acb_t z, slong prec) .. function:: void acb_sin_cos(acb_t s, acb_t c, const acb_t z, slong prec) Sets `s = \sin(z)`, `c = \cos(z)`, evaluated as `\sin(a+bi) = \sin(a)\cosh(b) + i \cos(a)\sinh(b)`, `\cos(a+bi) = \cos(a)\cosh(b) - i \sin(a)\sinh(b)`. .. function:: void acb_tan(acb_t s, const acb_t z, slong prec) Sets `s = \tan(z) = \sin(z) / \cos(z)`. For large imaginary parts, the function is evaluated in a numerically stable way as `\pm i` plus a decreasing exponential factor. .. function:: void acb_cot(acb_t s, const acb_t z, slong prec) Sets `s = \cot(z) = \cos(z) / \sin(z)`. For large imaginary parts, the function is evaluated in a numerically stable way as `\pm i` plus a decreasing exponential factor. .. function:: void acb_sin_pi(acb_t s, const acb_t z, slong prec) .. function:: void acb_cos_pi(acb_t s, const acb_t z, slong prec) .. function:: void acb_sin_cos_pi(acb_t s, acb_t c, const acb_t z, slong prec) Sets `s = \sin(\pi z)`, `c = \cos(\pi z)`, evaluating the trigonometric factors of the real and imaginary part accurately via :func:`arb_sin_cos_pi`. .. function:: void acb_tan_pi(acb_t s, const acb_t z, slong prec) Sets `s = \tan(\pi z)`. Uses the same algorithm as :func:`acb_tan`, but evaluates the sine and cosine accurately via :func:`arb_sin_cos_pi`. .. function:: void acb_cot_pi(acb_t s, const acb_t z, slong prec) Sets `s = \cot(\pi z)`. Uses the same algorithm as :func:`acb_cot`, but evaluates the sine and cosine accurately via :func:`arb_sin_cos_pi`. .. function:: void acb_sec(acb_t res, const acb_t z, slong prec) Computes `\sec(z) = 1 / \cos(z)`. .. function:: void acb_csc(acb_t res, const acb_t z, slong prec) Computes `\csc(x) = 1 / \sin(z)`. .. function:: void acb_csc_pi(acb_t res, const acb_t z, slong prec) Computes `\csc(\pi x) = 1 / \sin(\pi z)`. Evaluates the sine accurately via :func:`acb_sin_pi`. .. function:: void acb_sinc(acb_t s, const acb_t z, slong prec) Sets `s = \operatorname{sinc}(x) = \sin(z) / z`. .. function:: void acb_sinc_pi(acb_t s, const acb_t z, slong prec) Sets `s = \operatorname{sinc}(\pi x) = \sin(\pi z) / (\pi z)`. Inverse trigonometric functions ------------------------------------------------------------------------------- .. function:: void acb_asin(acb_t res, const acb_t z, slong prec) Sets *res* to `\operatorname{asin}(z) = -i \log(iz + \sqrt{1-z^2})`. .. function:: void acb_acos(acb_t res, const acb_t z, slong prec) Sets *res* to `\operatorname{acos}(z) = \tfrac{1}{2} \pi - \operatorname{asin}(z)`. .. function:: void acb_atan(acb_t res, const acb_t z, slong prec) Sets *res* to `\operatorname{atan}(z) = \tfrac{1}{2} i (\log(1-iz)-\log(1+iz))`. Hyperbolic functions ------------------------------------------------------------------------------- .. function:: void acb_sinh(acb_t s, const acb_t z, slong prec) .. function:: void acb_cosh(acb_t c, const acb_t z, slong prec) .. function:: void acb_sinh_cosh(acb_t s, acb_t c, const acb_t z, slong prec) .. function:: void acb_tanh(acb_t s, const acb_t z, slong prec) .. function:: void acb_coth(acb_t s, const acb_t z, slong prec) Respectively computes `\sinh(z) = -i\sin(iz)`, `\cosh(z) = \cos(iz)`, `\tanh(z) = -i\tan(iz)`, `\coth(z) = i\cot(iz)`. .. function:: void acb_sech(acb_t res, const acb_t z, slong prec) Computes `\operatorname{sech}(z) = 1 / \cosh(z)`. .. function:: void acb_csch(acb_t res, const acb_t z, slong prec) Computes `\operatorname{csch}(z) = 1 / \sinh(z)`. Inverse hyperbolic functions ------------------------------------------------------------------------------- .. function:: void acb_asinh(acb_t res, const acb_t z, slong prec) Sets *res* to `\operatorname{asinh}(z) = -i \operatorname{asin}(iz)`. .. function:: void acb_acosh(acb_t res, const acb_t z, slong prec) Sets *res* to `\operatorname{acosh}(z) = \log(z + \sqrt{z+1} \sqrt{z-1})`. .. function:: void acb_atanh(acb_t res, const acb_t z, slong prec) Sets *res* to `\operatorname{atanh}(z) = -i \operatorname{atan}(iz)`. Lambert W function ------------------------------------------------------------------------------- .. function:: void acb_lambertw_asymp(acb_t res, const acb_t z, const fmpz_t k, slong L, slong M, slong prec) Sets *res* to the Lambert W function `W_k(z)` computed using *L* and *M* terms in the bivariate series giving the asymptotic expansion at zero or infinity. This algorithm is valid everywhere, but the error bound is only finite when `|\log(z)|` is sufficiently large. .. function:: int acb_lambertw_check_branch(const acb_t w, const fmpz_t k, slong prec) Tests if *w* definitely lies in the image of the branch `W_k(z)`. This function is used internally to verify that a computed approximation of the Lambert W function lies on the intended branch. Note that this will necessarily evaluate to false for points exactly on (or overlapping) the branch cuts, where a different algorithm has to be used. .. function:: void acb_lambertw_bound_deriv(mag_t res, const acb_t z, const acb_t ez1, const fmpz_t k) Sets *res* to an upper bound for `|W_k'(z)|`. The input *ez1* should contain the precomputed value of `ez+1`. Along the real line, the directional derivative of `W_k(z)` is understood to be taken. As a result, the user must handle the branch cut discontinuity separately when using this function to bound perturbations in the value of `W_k(z)`. .. function:: void acb_lambertw(acb_t res, const acb_t z, const fmpz_t k, int flags, slong prec) Sets *res* to the Lambert W function `W_k(z)` where the index *k* selects the branch (with `k = 0` giving the principal branch). The placement of branch cuts follows [CGHJK1996]_. If *flags* is nonzero, nonstandard branch cuts are used. If *flags* is set to *ACB_LAMBERTW_LEFT*, computes `W_{\mathrm{left}|k}(z)` which corresponds to `W_k(z)` in the upper half plane and `W_{k+1}(z)` in the lower half plane, connected continuously to the left of the branch points. In other words, the branch cut on `(-\infty,0)` is rotated counterclockwise to `(0,+\infty)`. (For `k = -1` and `k = 0`, there is also a branch cut on `(-1/e,0)`, continuous from below instead of from above to maintain counterclockwise continuity.) If *flags* is set to *ACB_LAMBERTW_MIDDLE*, computes `W_{\mathrm{middle}}(z)` which corresponds to `W_{-1}(z)` in the upper half plane and `W_{1}(z)` in the lower half plane, connected continuously through `(-1/e,0)` with branch cuts on `(-\infty,-1/e)` and `(0,+\infty)`. `W_{\mathrm{middle}}(z)` extends the real analytic function `W_{-1}(x)` defined on `(-1/e,0)` to a complex analytic function, whereas the standard branch `W_{-1}(z)` has a branch cut along the real segment. The algorithm used to compute the Lambert W function is described in [Joh2017b]_. Rising factorials ------------------------------------------------------------------------------- .. function:: void acb_rising_ui(acb_t z, const acb_t x, ulong n, slong prec) void acb_rising(acb_t z, const acb_t x, const acb_t n, slong prec) Computes the rising factorial `z = x (x+1) (x+2) \cdots (x+n-1)`. These functions are aliases for :func:`acb_hypgeom_rising_ui` and :func:`acb_hypgeom_rising`. .. function :: void acb_rising2_ui(acb_t u, acb_t v, const acb_t x, ulong n, slong prec) Letting `u(x) = x (x+1) (x+2) \cdots (x+n-1)`, simultaneously compute `u(x)` and `v(x) = u'(x)`. This function is a wrapper of :func:`acb_hypgeom_rising_ui_jet`. .. function :: void acb_rising_ui_get_mag(mag_t bound, const acb_t x, ulong n) Computes an upper bound for the absolute value of the rising factorial `z = x (x+1) (x+2) \cdots (x+n-1)`. Not currently optimized for large *n*. Gamma function ------------------------------------------------------------------------------- .. function:: void acb_gamma(acb_t y, const acb_t x, slong prec) Computes the gamma function `y = \Gamma(x)`. This is an alias for :func:`acb_hypgeom_gamma`. .. function:: void acb_rgamma(acb_t y, const acb_t x, slong prec) Computes the reciprocal gamma function `y = 1/\Gamma(x)`, avoiding division by zero at the poles of the gamma function. This is an alias for :func:`acb_hypgeom_rgamma`. .. function:: void acb_lgamma(acb_t y, const acb_t x, slong prec) Computes the logarithmic gamma function `y = \log \Gamma(x)`. This is an alias for :func:`acb_hypgeom_lgamma`. The branch cut of the logarithmic gamma function is placed on the negative half-axis, which means that `\log \Gamma(z) + \log z = \log \Gamma(z+1)` holds for all `z`, whereas `\log \Gamma(z) \ne \log(\Gamma(z))` in general. In the left half plane, the reflection formula with correct branch structure is evaluated via :func:`acb_log_sin_pi`. .. function:: void acb_digamma(acb_t y, const acb_t x, slong prec) Computes the digamma function `y = \psi(x) = (\log \Gamma(x))' = \Gamma'(x) / \Gamma(x)`. .. function:: void acb_log_sin_pi(acb_t res, const acb_t z, slong prec) Computes the logarithmic sine function defined by .. math :: S(z) = \log(\pi) - \log \Gamma(z) + \log \Gamma(1-z) which is equal to .. math :: S(z) = \int_{1/2}^z \pi \cot(\pi t) dt where the path of integration goes through the upper half plane if `0 < \arg(z) \le \pi` and through the lower half plane if `-\pi < \arg(z) \le 0`. Equivalently, .. math :: S(z) = \log(\sin(\pi(z-n))) \mp n \pi i, \quad n = \lfloor \operatorname{re}(z) \rfloor where the negative sign is taken if `0 < \arg(z) \le \pi` and the positive sign is taken otherwise (if the interval `\arg(z)` does not certainly satisfy either condition, the union of both cases is computed). After subtracting *n*, we have `0 \le \operatorname{re}(z) < 1`. In this strip, we use use `S(z) = \log(\sin(\pi(z)))` if the imaginary part of *z* is small. Otherwise, we use `S(z) = i \pi (z-1/2) + \log((1+e^{-2i\pi z})/2)` in the lower half-plane and the conjugated expression in the upper half-plane to avoid exponent overflow. The function is evaluated at the midpoint and the propagated error is computed from `S'(z)` to get a continuous change when `z` is non-real and `n` spans more than one possible integer value. .. function:: void acb_polygamma(acb_t res, const acb_t s, const acb_t z, slong prec) Sets *res* to the value of the generalized polygamma function `\psi(s,z)`. If *s* is a nonnegative order, this is simply the *s*-order derivative of the digamma function. If `s = 0`, this function simply calls the digamma function internally. For integers `s \ge 1`, it calls the Hurwitz zeta function. Note that for small integers `s \ge 1`, it can be faster to use :func:`acb_poly_digamma_series` and read off the coefficients. The generalization to other values of *s* is due to Espinosa and Moll [EM2004]_: .. math :: \psi(s,z) = \frac{\zeta'(s+1,z) + (\gamma + \psi(-s)) \zeta(s+1,z)}{\Gamma(-s)} .. function:: void acb_barnes_g(acb_t res, const acb_t z, slong prec) .. function:: void acb_log_barnes_g(acb_t res, const acb_t z, slong prec) Computes Barnes *G*-function or the logarithmic Barnes *G*-function, respectively. The logarithmic version has branch cuts on the negative real axis and is continuous elsewhere in the complex plane, in analogy with the logarithmic gamma function. The functional equation .. math :: \log G(z+1) = \log \Gamma(z) + \log G(z). holds for all *z*. For small integers, we directly use the recurrence relation `G(z+1) = \Gamma(z) G(z)` together with the initial value `G(1) = 1`. For general *z*, we use the formula .. math :: \log G(z) = (z-1) \log \Gamma(z) - \zeta'(-1,z) + \zeta'(-1). Zeta function ------------------------------------------------------------------------------- .. function:: void acb_zeta(acb_t z, const acb_t s, slong prec) Sets *z* to the value of the Riemann zeta function `\zeta(s)`. Note: for computing derivatives with respect to `s`, use :func:`acb_poly_zeta_series` or related methods. This is a wrapper of :func:`acb_dirichlet_zeta`. .. function:: void acb_hurwitz_zeta(acb_t z, const acb_t s, const acb_t a, slong prec) Sets *z* to the value of the Hurwitz zeta function `\zeta(s, a)`. Note: for computing derivatives with respect to `s`, use :func:`acb_poly_zeta_series` or related methods. This is a wrapper of :func:`acb_dirichlet_hurwitz`. .. function:: void acb_bernoulli_poly_ui(acb_t res, ulong n, const acb_t x, slong prec) Sets *res* to the value of the Bernoulli polynomial `B_n(x)`. Warning: this function is only fast if either *n* or *x* is a small integer. This function reads Bernoulli numbers from the global cache if they are already cached, but does not automatically extend the cache by itself. Polylogarithms ------------------------------------------------------------------------------- .. function:: void acb_polylog(acb_t w, const acb_t s, const acb_t z, slong prec) .. function:: void acb_polylog_si(acb_t w, slong s, const acb_t z, slong prec) Sets *w* to the polylogarithm `\operatorname{Li}_s(z)`. Arithmetic-geometric mean ------------------------------------------------------------------------------- See :ref:`algorithms_agm` for implementation details. .. function:: void acb_agm1(acb_t m, const acb_t z, slong prec) Sets *m* to the arithmetic-geometric mean `M(z) = \operatorname{agm}(1,z)`, defined such that the function is continuous in the complex plane except for a branch cut along the negative half axis (where it is continuous from above). This corresponds to always choosing an "optimal" branch for the square root in the arithmetic-geometric mean iteration. .. function:: void acb_agm1_cpx(acb_ptr m, const acb_t z, slong len, slong prec) Sets the coefficients in the array *m* to the power series expansion of the arithmetic-geometric mean at the point *z* truncated to length *len*, i.e. `M(z+x) \in \mathbb{C}[[x]]`. .. function:: void acb_agm(acb_t m, const acb_t x, const acb_t y, slong prec) Sets *m* to the arithmetic-geometric mean of *x* and *y*. The square roots in the AGM iteration are chosen so as to form the "optimal" AGM sequence. This gives a well-defined function of *x* and *y* except when `x / y` is a negative real number, in which case there are two optimal AGM sequences. In that case, an arbitrary but consistent choice is made (if a decision cannot be made due to inexact arithmetic, the union of both choices is returned). Other special functions ------------------------------------------------------------------------------- .. function:: void acb_chebyshev_t_ui(acb_t a, ulong n, const acb_t x, slong prec) .. function:: void acb_chebyshev_u_ui(acb_t a, ulong n, const acb_t x, slong prec) Evaluates the Chebyshev polynomial of the first kind `a = T_n(x)` or the Chebyshev polynomial of the second kind `a = U_n(x)`. .. function:: void acb_chebyshev_t2_ui(acb_t a, acb_t b, ulong n, const acb_t x, slong prec) .. function:: void acb_chebyshev_u2_ui(acb_t a, acb_t b, ulong n, const acb_t x, slong prec) Simultaneously evaluates `a = T_n(x), b = T_{n-1}(x)` or `a = U_n(x), b = U_{n-1}(x)`. Aliasing between *a*, *b* and *x* is not permitted. Piecewise real functions ------------------------------------------------------------------------------- The following methods extend common piecewise real functions to piecewise complex analytic functions, useful together with the :ref:`acb_calc.h ` module. If *analytic* is set, evaluation on a discontinuity or non-analytic point gives a NaN result. .. function:: void acb_real_abs(acb_t res, const acb_t z, int analytic, slong prec) The absolute value is extended to `+z` in the right half plane and `-z` in the left half plane, with a discontinuity on the vertical line `\operatorname{Re}(z) = 0`. .. function:: void acb_real_sgn(acb_t res, const acb_t z, int analytic, slong prec) The sign function is extended to `+1` in the right half plane and `-1` in the left half plane, with a discontinuity on the vertical line `\operatorname{Re}(z) = 0`. If *analytic* is not set, this is effectively the same function as :func:`acb_csgn`. .. function:: void acb_real_heaviside(acb_t res, const acb_t z, int analytic, slong prec) The Heaviside step function (or unit step function) is extended to `+1` in the right half plane and `0` in the left half plane, with a discontinuity on the vertical line `\operatorname{Re}(z) = 0`. .. function:: void acb_real_floor(acb_t res, const acb_t z, int analytic, slong prec) The floor function is extended to a piecewise constant function equal to `n` in the strips with real part `(n,n+1)`, with discontinuities on the vertical lines `\operatorname{Re}(z) = n`. .. function:: void acb_real_ceil(acb_t res, const acb_t z, int analytic, slong prec) The ceiling function is extended to a piecewise constant function equal to `n+1` in the strips with real part `(n,n+1)`, with discontinuities on the vertical lines `\operatorname{Re}(z) = n`. .. function:: void acb_real_max(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec) The real function `\max(x,y)` is extended to a piecewise analytic function of two variables by returning `x` when `\operatorname{Re}(x) \ge \operatorname{Re}(y)` and returning `y` when `\operatorname{Re}(x) < \operatorname{Re}(y)`, with discontinuities where `\operatorname{Re}(x) = \operatorname{Re}(y)`. .. function:: void acb_real_min(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec) The real function `\min(x,y)` is extended to a piecewise analytic function of two variables by returning `x` when `\operatorname{Re}(x) \le \operatorname{Re}(y)` and returning `y` when `\operatorname{Re}(x) > \operatorname{Re}(y)`, with discontinuities where `\operatorname{Re}(x) = \operatorname{Re}(y)`. .. function:: void acb_real_sqrtpos(acb_t res, const acb_t z, int analytic, slong prec) Extends the real square root function on `[0,+\infty)` to the usual complex square root on the cut plane. Like :func:`arb_sqrtpos`, only the nonnegative part of *z* is considered if *z* is purely real and *analytic* is not set. This is useful for integrating `\sqrt{f(x)}` where it is known that `f(x) \ge 0`: unlike :func:`acb_sqrt_analytic`, no spurious imaginary terms `[\pm \varepsilon] i` are created when the balls computed for `f(x)` straddle zero. Vector functions ------------------------------------------------------------------------------- .. function:: void _acb_vec_zero(acb_ptr A, slong n) Sets all entries in *vec* to zero. .. function:: int _acb_vec_is_zero(acb_srcptr vec, slong len) Returns nonzero iff all entries in *x* are zero. .. function:: int _acb_vec_is_real(acb_srcptr v, slong len) Returns nonzero iff all entries in *x* have zero imaginary part. .. function:: void _acb_vec_set(acb_ptr res, acb_srcptr vec, slong len) Sets *res* to a copy of *vec*. .. function:: void _acb_vec_set_round(acb_ptr res, acb_srcptr vec, slong len, slong prec) Sets *res* to a copy of *vec*, rounding each entry to *prec* bits. .. function:: void _acb_vec_swap(acb_ptr vec1, acb_ptr vec2, slong len) Swaps the entries of *vec1* and *vec2*. .. function:: void _acb_vec_neg(acb_ptr res, acb_srcptr vec, slong len) .. function:: void _acb_vec_add(acb_ptr res, acb_srcptr vec1, acb_srcptr vec2, slong len, slong prec) .. function:: void _acb_vec_sub(acb_ptr res, acb_srcptr vec1, acb_srcptr vec2, slong len, slong prec) .. function:: void _acb_vec_scalar_submul(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) .. function:: void _acb_vec_scalar_addmul(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) .. function:: void _acb_vec_scalar_mul(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) .. function:: void _acb_vec_scalar_mul_ui(acb_ptr res, acb_srcptr vec, slong len, ulong c, slong prec) .. function:: void _acb_vec_scalar_mul_2exp_si(acb_ptr res, acb_srcptr vec, slong len, slong c) .. function:: void _acb_vec_scalar_mul_onei(acb_ptr res, acb_srcptr vec, slong len) .. function:: void _acb_vec_scalar_div_ui(acb_ptr res, acb_srcptr vec, slong len, ulong c, slong prec) .. function:: void _acb_vec_scalar_div(acb_ptr res, acb_srcptr vec, slong len, const acb_t c, slong prec) .. function:: void _acb_vec_scalar_mul_arb(acb_ptr res, acb_srcptr vec, slong len, const arb_t c, slong prec) .. function:: void _acb_vec_scalar_div_arb(acb_ptr res, acb_srcptr vec, slong len, const arb_t c, slong prec) .. function:: void _acb_vec_scalar_mul_fmpz(acb_ptr res, acb_srcptr vec, slong len, const fmpz_t c, slong prec) .. function:: void _acb_vec_scalar_div_fmpz(acb_ptr res, acb_srcptr vec, slong len, const fmpz_t c, slong prec) Performs the respective scalar operation elementwise. .. function:: slong _acb_vec_bits(acb_srcptr vec, slong len) Returns the maximum of :func:`arb_bits` for all entries in *vec*. .. function:: void _acb_vec_set_powers(acb_ptr xs, const acb_t x, slong len, slong prec) Sets *xs* to the powers `1, x, x^2, \ldots, x^{len-1}`. .. function:: void _acb_vec_unit_roots(acb_ptr z, slong order, slong len, slong prec) Sets *z* to the powers `1,z,z^2,\dots z^{\mathrm{len}-1}` where `z=\exp(\frac{2i\pi}{\mathrm{order}})` to precision *prec*. *order* can be taken negative. In order to avoid precision loss, this function does not simply compute powers of a primitive root. .. function:: void _acb_vec_add_error_arf_vec(acb_ptr res, arf_srcptr err, slong len) .. function:: void _acb_vec_add_error_mag_vec(acb_ptr res, mag_srcptr err, slong len) Adds the magnitude of each entry in *err* to the radius of the corresponding entry in *res*. .. function:: void _acb_vec_indeterminate(acb_ptr vec, slong len) Applies :func:`acb_indeterminate` elementwise. .. function:: void _acb_vec_trim(acb_ptr res, acb_srcptr vec, slong len) Applies :func:`acb_trim` elementwise. .. function:: int _acb_vec_get_unique_fmpz_vec(fmpz * res, acb_srcptr vec, slong len) Calls :func:`acb_get_unique_fmpz` elementwise and returns nonzero if all entries can be rounded uniquely to integers. If any entry in *vec* cannot be rounded uniquely to an integer, returns zero. .. function:: void _acb_vec_sort_pretty(acb_ptr vec, slong len) Sorts the vector of complex numbers based on the real and imaginary parts. This is intended to reveal structure when printing a set of complex numbers, not to apply an order relation in a rigorous way. arb-2.22.1/doc/source/acb_calc.rst000066400000000000000000000427511417376376500167040ustar00rootroot00000000000000.. _acb-calc: **acb_calc.h** -- calculus with complex-valued functions =============================================================================== This module provides functions for operations of calculus over the complex numbers (intended to include root-finding, integration, and so on). The numerical integration code is described in [Joh2018a]_. Types, macros and constants ------------------------------------------------------------------------------- .. type:: acb_calc_func_t Typedef for a pointer to a function with signature:: int func(acb_ptr out, const acb_t inp, void * param, slong order, slong prec) implementing a univariate complex function `f(z)`. The *param* argument may be used to pass through additional parameters to the function. The return value is reserved for future use as an error code. It can be assumed that *out* and *inp* are not aliased. When called with *order* = 0, *func* should write to *out* the value of `f(z)` at the point *inp*, evaluated at a precision of *prec* bits. In this case, *f* can be an arbitrary complex function, which may have branch cuts or even be non-holomorphic. When called with *order* = *n* for `n \ge 1`, *func* should write to *out* the first *n* coefficients in the Taylor series expansion of `f(z)` at the point *inp*, evaluated at a precision of *prec* bits. In this case, the implementation of *func* must verify that *f* is holomorphic on the complex interval defined by *z*, and set the coefficients in *out* to non-finite values otherwise. For algorithms that do not rely on derivatives, *func* will always get called with *order* = 0 or *order* = 1, in which case the user only needs to implement evaluation of the direct function value `f(z)` (without derivatives). With *order* = 1, *func* must verify holomorphicity (unlike the *order* = 0 case). If *f* is built from field operations and meromorphic functions, then no special action is necessary when *order* is positive since division by zero or evaluation of builtin functions at poles automatically produces infinite enclosures. However, manual action is needed for bounded functions with branch cuts. For example, when evaluating `\sqrt{z}`, the output must be set to an non-finite value if `z` overlaps with the branch cut `[-\infty,0]`. The easiest way to accomplish this is to use versions of basic functions (sqrt, log, pow, etc.) that test holomorphicity of their arguments individually. Some functions with branch cut detection are available as builtins: see :func:`acb_sqrt_analytic`, :func:`acb_rsqrt_analytic`, :func:`acb_log_analytic`, :func:`acb_pow_analytic`. It is not difficult to write custom functions of this type, using the following pattern:: /* Square root function on C with detection of the branch cut. */ void sqrt_analytic(acb_t res, const acb_t z, int analytic, slong prec) { if (analytic && arb_contains_zero(acb_imagref(z)) && arb_contains_nonpositive(acb_realref(z)))) { acb_indeterminate(res); } else { acb_sqrt(res, z, prec); } } The built-in methods :func:`acb_real_abs`, :func:`acb_real_sgn`, :func:`acb_real_heaviside`, :func:`acb_real_floor`, :func:`acb_real_ceil`, :func:`acb_real_max`, :func:`acb_real_min` provide piecewise holomorphic functions that are useful for integrating piecewise-defined real functions. For example, here we define a piecewise holomorphic extension of the function `f(z) = \sqrt{\lfloor z \rfloor}` (for simplicity, without implementing derivatives):: int func(acb_ptr out, const acb_t inp, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* derivatives not implemented */ acb_real_floor(out, inp, order != 0, prec); acb_sqrt_analytic(out, out, order != 0, prec); return 0; } (Here, :func:`acb_real_sqrtpos` may be slightly better if it is known that *z* will be nonnegative on the path.) See the demo program ``examples/integrals.c`` for more examples. Integration ------------------------------------------------------------------------------- .. function:: int acb_calc_integrate(acb_t res, acb_calc_func_t func, void * param, const acb_t a, const acb_t b, slong rel_goal, const mag_t abs_tol, const acb_calc_integrate_opt_t options, slong prec) Computes a rigorous enclosure of the integral .. math :: I = \int_a^b f(t) dt where *f* is specified by (*func*, *param*), following a straight-line path between the complex numbers *a* and *b*. For finite results, *a*, *b* must be finite and *f* must be bounded on the path of integration. To compute improper integrals, the user should therefore truncate the path of integration manually (or make a regularizing change of variables, if possible). Returns *ARB_CALC_SUCCESS* if the integration converged to the target accuracy on all subintervals, and returns *ARB_CALC_NO_CONVERGENCE* otherwise. By default, the integrand *func* will only be called with *order* = 0 or *order* = 1; that is, derivatives are not required. - The integrand will be called with *order* = 0 to evaluate *f* normally on the integration path (either at a single point or on a subinterval). In this case, *f* is treated as a pointwise defined function and can have arbitrary discontinuities. - The integrand will be called with *order* = 1 to evaluate *f* on a domain surrounding a segment of the integration path for the purpose of bounding the error of a quadrature formula. In this case, *func* must verify that *f* is holomorphic on this domain (and output a non-finite value if it is not). The integration algorithm combines direct interval enclosures, Gauss-Legendre quadrature where *f* is holomorphic, and adaptive subdivision. This strategy supports integrands with discontinuities while providing exponential convergence for typical piecewise holomorphic integrands. The following parameters control accuracy: - *rel_goal* - relative accuracy goal as a number of bits, i.e. target a relative error less than `\varepsilon_{rel} = 2^{-r}` where *r* = *rel_goal* (note the sign: *rel_goal* should be nonnegative). - *abs_tol* - absolute accuracy goal as a :type:`mag_t` describing the error tolerance, i.e. target an absolute error less than `\varepsilon_{abs}` = *abs_tol*. - *prec* - working precision. This is the working precision used to evaluate the integrand and manipulate interval endpoints. As currently implemented, the algorithm does not attempt to adjust the working precision by itself, and adaptive control of the working precision must be handled by the user. For typical usage, set *rel_goal* = *prec* and *abs_tol* = `2^{-prec}`. It usually only makes sense to have *rel_goal* between 0 and *prec*. The algorithm attempts to achieve an error of `\max(\varepsilon_{abs}, M \varepsilon_{rel})` on each subinterval, where *M* is the magnitude of the integral. These parameters are only guidelines; the cumulative error may be larger than both the prescribed absolute and relative error goals, depending on the number of subdivisions, cancellation between segments of the integral, and numerical errors in the evaluation of the integrand. To compute tiny integrals with high relative accuracy, one should set `\varepsilon_{abs} \approx M \varepsilon_{rel}` where *M* is a known estimate of the magnitude. Setting `\varepsilon_{abs}` to 0 is also allowed, forcing use of a relative instead of an absolute tolerance goal. This can be handy for exponentially small or large functions of unknown magnitude. It is recommended to avoid setting `\varepsilon_{abs}` very small if possible since the algorithm might need many extra subdivisions to estimate *M* automatically; if the approximate magnitude can be estimated by some external means (for example if a midpoint-width or endpoint-width estimate is known to be accurate), providing an appropriate `\varepsilon_{abs} \approx M \varepsilon_{rel}` will be more efficient. If the integral has very large magnitude, setting the absolute tolerance to a corresponding large value is recommended for best performance, but it is not necessary for convergence since the absolute tolerance is increased automatically during the execution of the algorithm if the partial integrals are found to have larger error. Additional options for the integration can be provided via the *options* parameter (documented below). To use all defaults, *NULL* can be passed for *options*. Options for integration ............................................................................... .. type:: acb_calc_integrate_opt_struct .. type:: acb_calc_integrate_opt_t This structure contains several fields, explained below. An *acb_calc_integrate_opt_t* is defined as an array of *acb_calc_integrate_opt_struct* of length 1, permitting it to be passed by reference. An *acb_calc_integrate_opt_t* must be initialized before use, which sets all fields to 0 or *NULL*. For fields that have not been set to other values, the integration algorithm will choose defaults automatically (based on the precision and accuracy goals). This structure will most likely be extended in the future to accommodate more options. .. member:: slong deg_limit Maximum quadrature degree for each subinterval. If a zero or negative value is provided, the limit is set to a default value which currently equals `0.5 \cdot \min(prec, rel\_goal) + 60` for Gauss-Legendre quadrature. A higher quadrature degree can be beneficial for functions that are holomorphic on a large domain around the integration path and yet behave irregularly, such as oscillatory entire functions. The drawback of increasing the degree is that the precomputation time for quadrature nodes increases. .. member:: slong eval_limit Maximum number of function evaluations. If a zero or negative value is provided, the limit is set to a default value which currently equals `1000 \cdot prec + prec^2`. This is the main parameter used to limit the amount of work before aborting due to possible slow convergence or non-convergence. A lower limit allows aborting faster. A higher limit may be needed for integrands with many discontinuities or many singularities close to the integration path. This limit is only taken as a rough guideline, and the actual number of function evaluations may be slightly higher depending on the actual subdivisions. .. member:: slong depth_limit Maximum search depth for adaptive subdivision. Technically, this is not the limit on the local bisection depth but the limit on the number of simultaneously queued subintervals. If a zero or negative value is provided, the limit is set to the default value `2 \cdot \text{prec}`. Warning: memory usage may increase in proportion to this limit. .. member:: int use_heap By default (if set to 0), new subintervals generated by adaptive bisection will be appended to the top of a stack. If set to 1, a binary heap will be used to maintain a priority queue where the subintervals with larger error have higher priority. This sometimes gives better results in case of convergence failure, but can lead to a much larger array of subintervals (requiring a higher *depth_limit*) when many global bisections are needed. .. member:: int verbose If set to 1, some information about the overall integration process is printed to standard output. If set to 2, information about each subinterval is printed. .. function:: void acb_calc_integrate_opt_init(acb_calc_integrate_opt_t options) Initializes *options* for use, setting all fields to 0 indicating default values. Local integration algorithms ------------------------------------------------------------------------------- .. function:: int acb_calc_integrate_gl_auto_deg(acb_t res, slong * num_eval, acb_calc_func_t func, void * param, const acb_t a, const acb_t b, const mag_t tol, slong deg_limit, int flags, slong prec) Attempts to compute `I = \int_a^b f(t) dt` using a single application of Gauss-Legendre quadrature with automatic determination of the quadrature degree so that the error is smaller than *tol*. Returns *ARB_CALC_SUCCESS* if the integral has been evaluated successfully or *ARB_CALC_NO_CONVERGENCE* if the tolerance could not be met. The total number of function evaluations is written to *num_eval*. For the interval `[-1,1]`, the error of the *n*-point Gauss-Legendre rule is bounded by .. math :: \left| I - \sum_{k=0}^{n-1} w_k f(x_k) \right| \le \frac{64 M}{15 (\rho-1) \rho^{2n-1}} if `f` is holomorphic with `|f(z)| \le M` inside the ellipse *E* with foci `\pm 1` and semiaxes `X` and `Y = \sqrt{X^2 - 1}` such that `\rho = X + Y` with `\rho > 1` [Tre2008]_. For an arbitrary interval, we use `\int_a^b f(t) dt = \int_{-1}^1 g(t) dt` where `g(t) = \Delta f(\Delta t + m)`, `\Delta = \tfrac{1}{2}(b-a)`, `m = \tfrac{1}{2}(a+b)`. With `I = [\pm X] + [\pm Y]i`, this means that we evaluate `\Delta f(\Delta I + m)` to get the bound `M`. (An improvement would be to reduce the wrapping effect of rotating the ellipse when the path is not rectilinear). We search for an `X` that makes the error small by trying steps `2^{2^k}`. Larger `X` will give smaller `1 / \rho^{2n-1}` but larger `M`. If we try successive larger values of `k`, we can abort when `M = \infty` since this either means that we have hit a singularity or a branch cut or that overestimation in the evaluation of `f` is becoming too severe. Integration (old) ------------------------------------------------------------------------------- .. function:: void acb_calc_cauchy_bound(arb_t bound, acb_calc_func_t func, void * param, const acb_t x, const arb_t radius, slong maxdepth, slong prec) Sets *bound* to a ball containing the value of the integral .. math :: C(x,r) = \frac{1}{2 \pi r} \oint_{|z-x| = r} |f(z)| dz = \int_0^1 |f(x+re^{2\pi i t})| dt where *f* is specified by (*func*, *param*) and *r* is given by *radius*. The integral is computed using a simple step sum. The integration range is subdivided until the order of magnitude of *b* can be determined (i.e. its error bound is smaller than its midpoint), or until the step length has been cut in half *maxdepth* times. This function is currently implemented completely naively, and repeatedly subdivides the whole integration range instead of performing adaptive subdivisions. .. function:: int acb_calc_integrate_taylor(acb_t res, acb_calc_func_t func, void * param, const acb_t a, const acb_t b, const arf_t inner_radius, const arf_t outer_radius, slong accuracy_goal, slong prec) Computes the integral .. math :: I = \int_a^b f(t) dt where *f* is specified by (*func*, *param*), following a straight-line path between the complex numbers *a* and *b* which both must be finite. The integral is approximated by piecewise centered Taylor polynomials. Rigorous truncation error bounds are calculated using the Cauchy integral formula. More precisely, if the Taylor series of *f* centered at the point *m* is `f(m+x) = \sum_{n=0}^{\infty} a_n x^n`, then .. math :: \int f(m+x) = \left( \sum_{n=0}^{N-1} a_n \frac{x^{n+1}}{n+1} \right) + \left( \sum_{n=N}^{\infty} a_n \frac{x^{n+1}}{n+1} \right). For sufficiently small *x*, the second series converges and its absolute value is bounded by .. math :: \sum_{n=N}^{\infty} \frac{C(m,R)}{R^n} \frac{|x|^{n+1}}{N+1} = \frac{C(m,R) R x}{(R-x)(N+1)} \left( \frac{x}{R} \right)^N. It is required that any singularities of *f* are isolated from the path of integration by a distance strictly greater than the positive value *outer_radius* (which is the integration radius used for the Cauchy bound). Taylor series step lengths are chosen so as not to exceed *inner_radius*, which must be strictly smaller than *outer_radius* for convergence. A smaller *inner_radius* gives more rapid convergence of each Taylor series but means that more series might have to be used. A reasonable choice might be to set *inner_radius* to half the value of *outer_radius*, giving roughly one accurate bit per term. The truncation point of each Taylor series is chosen so that the absolute truncation error is roughly `2^{-p}` where *p* is given by *accuracy_goal* (in the future, this might change to a relative accuracy). Arithmetic operations and function evaluations are performed at a precision of *prec* bits. Note that due to accumulation of numerical errors, both values may have to be set higher (and the endpoints may have to be computed more accurately) to achieve a desired accuracy. This function chooses the evaluation points uniformly rather than implementing adaptive subdivision. arb-2.22.1/doc/source/acb_dft.rst000066400000000000000000000235421417376376500165540ustar00rootroot00000000000000.. _acb-dft: **acb_dft.h** -- Discrete Fourier transform =================================================================================== *Warning: the interfaces in this module are experimental and may change without notice.* All functions support aliasing. Let *G* be a finite abelian group, and `\chi` a character of *G*. For any map `f:G\to\mathbb C`, the discrete fourier transform `\hat f:\hat G\to \mathbb C` is defined by .. math:: \hat f(\chi) = \sum_{x\in G}\overline{\chi(x)}f(x) Note that by the inversion formula .. math:: \widehat{\hat f}(\chi) = \#G\times f(\chi^{-1}) it is straightforward to recover `f` from its DFT `\hat f`. Main DFT functions ------------------------------------------------------------------------------- If `G=\mathbb Z/n\mathbb Z`, we compute the DFT according to the usual convention .. math:: w_x = \sum_{y\bmod n} v_y e^{-\frac{2i \pi}nxy} .. function:: void acb_dft(acb_ptr w, acb_srcptr v, slong n, slong prec) Set *w* to the DFT of *v* of length *len*, using an automatic choice of algorithm. .. function:: void acb_dft_inverse(acb_ptr w, acb_srcptr v, slong n, slong prec) Compute the inverse DFT of *v* into *w*. If several computations are to be done on the same group, the FFT scheme should be reused. .. type:: acb_dft_pre_struct .. type:: acb_dft_pre_t Stores a fast DFT scheme on :math:`\mathbb Z/n\mathbb Z` as a recursive decomposition into simpler DFT with some tables of roots of unity. An *acb_dft_pre_t* is defined as an array of *acb_dft_pre_struct* of length 1, permitting it to be passed by reference. .. function:: void acb_dft_precomp_init(acb_dft_pre_t pre, slong len, slong prec) Initializes the fast DFT scheme of length *len*, using an automatic choice of algorithms depending on the factorization of *len*. The length *len* is stored as *pre->n*. .. function:: void acb_dft_precomp_clear(acb_dft_pre_t pre) Clears *pre*. .. function:: void acb_dft_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec) Computes the DFT of the sequence *v* into *w* by applying the precomputed scheme *pre*. Both *v* and *w* must have length *pre->n*. .. function:: void acb_dft_inverse_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec) Compute the inverse DFT of *v* into *w*. DFT on products ------------------------------------------------------------------------------- A finite abelian group is isomorphic to a product of cyclic components .. math:: G = \bigoplus_{i=1}^r \mathbb Z/n_i\mathbb Z Characters are product of component characters and the DFT reads .. math:: \hat f(x_1,\dots x_r) = \sum_{y_1\dots y_r} f(y_1,\dots y_r) e^{-2i \pi \sum\frac{x_i y_i}{n_i}} We assume that `f` is given by a vector of length `\prod n_i` corresponding to a lexicographic ordering of the values `y_1,\dots y_r`, and the computation returns the same indexing for values of `\hat f`. .. function:: void acb_dirichlet_dft_prod(acb_ptr w, acb_srcptr v, slong * cyc, slong num, slong prec) Computes the DFT on the group product of *num* cyclic components of sizes *cyc*. Assume the entries of *v* are indexed according to lexicographic ordering of the cyclic components. .. type:: acb_dft_prod_struct .. type:: acb_dft_prod_t Stores a fast DFT scheme on a product of cyclic groups. An *acb_dft_prod_t* is defined as an array of *acb_dft_prod_struct* of length 1, permitting it to be passed by reference. .. function:: void acb_dft_prod_init(acb_dft_prod_t t, slong * cyc, slong num, slong prec) Stores in *t* a DFT scheme for the product of *num* cyclic components whose sizes are given in the array *cyc*. .. function:: void acb_dft_prod_clear(acb_dft_prod_t t) Clears *t*. .. function:: void acb_dirichlet_dft_prod_precomp(acb_ptr w, acb_srcptr v, const acb_dft_prod_t prod, slong prec) Sets *w* to the DFT of *v*. Assume the entries are lexicographically ordered according to the product of cyclic groups initialized in *t*. Convolution ------------------------------------------------------------------------------- For functions `f` and `g` on `G` we consider the convolution .. math:: (f \star g)(x) = \sum_{y\in G} f(x-y)g(y) .. function:: void acb_dft_convol_naive(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) .. function:: void acb_dft_convol_rad2(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) .. function:: void acb_dft_convol(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec) Sets *w* to the convolution of *f* and *g* of length *len*. The *naive* version simply uses the definition. The *rad2* version embeds the sequence into a power of 2 length and uses the formula .. math:: \widehat{f \star g}(\chi) = \hat f(\chi)\hat g(\chi) to compute it using three radix 2 FFT. The default version uses radix 2 FFT unless *len* is a product of small primes where a non padded FFT is faster. FFT algorithms ------------------------------------------------------------------------------- Fast Fourier transform techniques allow to compute efficiently all values `\hat f(\chi)` by reusing common computations. Specifically, if `H\triangleleft G` is a subgroup of size `M` and index `[G:H]=m`, then writing `f_x(h)=f(xh)` the translate of `f` by representatives `x` of `G/H`, one has a decomposition .. math:: \hat f(\chi) = \sum_{x\in G/H} \overline{\chi(x)} \hat{f_x}(\chi_{H}) so that the DFT on `G` can be computed using `m` DFT on `H` (of appropriate translates of `f`), then `M` DFT on `G/H`, one for each restriction `\chi_{H}`. This decomposition can be done recursively. Naive algorithm ............................................................................... .. function:: void acb_dft_naive(acb_ptr w, acb_srcptr v, slong n, slong prec) Computes the DFT of *v* into *w*, where *v* and *w* have size *n*, using the naive `O(n^2)` algorithm. .. type:: acb_dft_naive_struct .. type:: acb_dft_naive_t .. function:: void acb_dft_naive_init(acb_dft_naive_t t, slong len, slong prec) .. function:: void acb_dft_naive_clear(acb_dft_naive_t t) Stores a table of roots of unity in *t*. The length *len* is stored as *t->n*. .. function:: void acb_dft_naive_precomp(acb_ptr w, acb_srcptr v, const acb_dft_naive_t t, slong prec) Sets *w* to the DFT of *v* of size *t->n*, using the naive algorithm data *t*. CRT decomposition ............................................................................... .. function:: void acb_dft_crt(acb_ptr w, acb_srcptr v, slong n, slong prec) Computes the DFT of *v* into *w*, where *v* and *w* have size *len*, using CRT to express `\mathbb Z/n\mathbb Z` as a product of cyclic groups. .. type:: acb_dft_crt_struct .. type:: acb_dft_crt_t .. function:: void acb_dft_crt_init(acb_dft_crt_t t, slong len, slong prec) .. function:: void acb_dft_crt_clear(acb_dft_crt_t t) Initialize a CRT decomposition of `\mathbb Z/n\mathbb Z` as a direct product of cyclic groups. The length *len* is stored as *t->n*. .. function:: void acb_dft_crt_precomp(acb_ptr w, acb_srcptr v, const acb_dft_crt_t t, slong prec) Sets *w* to the DFT of *v* of size *t->n*, using the CRT decomposition scheme *t*. Cooley-Tukey decomposition ............................................................................... .. function:: void acb_dft_cyc(acb_ptr w, acb_srcptr v, slong n, slong prec) Computes the DFT of *v* into *w*, where *v* and *w* have size *n*, using each prime factor of `m` of `n` to decompose with the subgroup `H=m\mathbb Z/n\mathbb Z`. .. type:: acb_dft_cyc_struct .. type:: acb_dft_cyc_t .. function:: void acb_dft_cyc_init(acb_dft_cyc_t t, slong len, slong prec) .. function:: void acb_dft_cyc_clear(acb_dft_cyc_t t) Initialize a decomposition of `\mathbb Z/n\mathbb Z` into cyclic subgroups. The length *len* is stored as *t->n*. .. function:: void acb_dft_cyc_precomp(acb_ptr w, acb_srcptr v, const acb_dft_cyc_t t, slong prec) Sets *w* to the DFT of *v* of size *t->n*, using the cyclic decomposition scheme *t*. Radix 2 decomposition ............................................................................... .. function:: void acb_dft_rad2(acb_ptr w, acb_srcptr v, int e, slong prec) Computes the DFT of *v* into *w*, where *v* and *w* have size `2^e`, using a radix 2 FFT. .. function:: void acb_dft_inverse_rad2(acb_ptr w, acb_srcptr v, int e, slong prec) Computes the inverse DFT of *v* into *w*, where *v* and *w* have size `2^e`, using a radix 2 FFT. .. type:: acb_dft_rad2_struct .. type:: acb_dft_rad2_t .. function:: void acb_dft_rad2_init(acb_dft_rad2_t t, int e, slong prec) .. function:: void acb_dft_rad2_clear(acb_dft_rad2_t t) Initialize and clear a radix 2 FFT of size `2^e`, stored as *t->n*. .. function:: void acb_dft_rad2_precomp(acb_ptr w, acb_srcptr v, const acb_dft_rad2_t t, slong prec) Sets *w* to the DFT of *v* of size *t->n*, using the precomputed radix 2 scheme *t*. Bluestein transform ............................................................................... .. function:: void acb_dft_bluestein(acb_ptr w, acb_srcptr v, slong n, slong prec) Computes the DFT of *v* into *w*, where *v* and *w* have size *n*, by conversion to a radix 2 one using Bluestein's convolution trick. .. type:: acb_dft_bluestein_struct .. type:: acb_dft_bluestein_t Stores a Bluestein scheme for some length *n* : that is a :type:`acb_dft_rad2_t` of size `2^e \geq 2n-1` and a size *n* array of convolution factors. .. function:: void acb_dft_bluestein_init(acb_dft_bluestein_t t, slong len, slong prec) .. function:: void acb_dft_bluestein_clear(acb_dft_bluestein_t t) Initialize and clear a Bluestein scheme to compute DFT of size *len*. .. function:: void acb_dft_bluestein_precomp(acb_ptr w, acb_srcptr v, const acb_dft_bluestein_t t, slong prec) Sets *w* to the DFT of *v* of size *t->n*, using the precomputed Bluestein scheme *t*. arb-2.22.1/doc/source/acb_dirichlet.rst000066400000000000000000001137611417376376500177510ustar00rootroot00000000000000.. _acb-dirichlet: **acb_dirichlet.h** -- Dirichlet L-functions, Riemann zeta and related functions =================================================================================== This module allows working with values of Dirichlet characters, Dirichlet L-functions, and related functions. A Dirichlet L-function is the analytic continuation of an L-series .. math :: L(s,\chi) = \sum_{k=1}^\infty \frac{\chi(k)}{k^s} where `\chi(k)` is a Dirichlet character. The trivial character `\chi(k) = 1` gives the Riemann zeta function. Working with Dirichlet characters is documented in :ref:`dirichlet`. The code in other modules for computing the Riemann zeta function, Hurwitz zeta function and polylogarithm will possibly be migrated to this module in the future. Roots of unity ------------------------------------------------------------------------------- .. type:: acb_dirichlet_roots_struct .. type:: acb_dirichlet_roots_t .. function:: void acb_dirichlet_roots_init(acb_dirichlet_roots_t roots, ulong n, slong num, slong prec) Initializes *roots* with precomputed data for fast evaluation of roots of unity `e^{2\pi i k/n}` of a fixed order *n*. The precomputation is optimized for *num* evaluations. For very small *num*, only the single root `e^{2\pi i/n}` will be precomputed, which can then be raised to a power. For small *prec* and large *n*, this method might even skip precomputing this single root if it estimates that evaluating roots of unity from scratch will be faster than powering. If *num* is large enough, the whole set of roots in the first quadrant will be precomputed at once. However, this is automatically avoided for large *n* if too much memory would be used. For intermediate *num*, baby-step giant-step tables are computed. .. function:: void acb_dirichlet_roots_clear(acb_dirichlet_roots_t roots) Clears the structure. .. function:: void acb_dirichlet_root(acb_t res, const acb_dirichlet_roots_t roots, ulong k, slong prec) Computes `e^{2\pi i k/n}`. Truncated L-series and power sums ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_powsum_term(acb_ptr res, arb_t log_prev, ulong * prev, const acb_t s, ulong k, int integer, int critical_line, slong len, slong prec) Sets *res* to `k^{-(s+x)}` as a power series in *x* truncated to length *len*. The flags *integer* and *critical_line* respectively specify optimizing for *s* being an integer or having real part 1/2. On input *log_prev* should contain the natural logarithm of the integer at *prev*. If *prev* is close to *k*, this can be used to speed up computations. If `\log(k)` is computed internally by this function, then *log_prev* is overwritten by this value, and the integer at *prev* is overwritten by *k*, allowing *log_prev* to be recycled for the next term when evaluating a power sum. .. function:: void acb_dirichlet_powsum_sieved(acb_ptr res, const acb_t s, ulong n, slong len, slong prec) Sets *res* to `\sum_{k=1}^n k^{-(s+x)}` as a power series in *x* truncated to length *len*. This function stores a table of powers that have already been calculated, computing `(ij)^r` as `i^r j^r` whenever `k = ij` is composite. As a further optimization, it groups all even `k` and evaluates the sum as a polynomial in `2^{-(s+x)}`. This scheme requires about `n / \log n` powers, `n / 2` multiplications, and temporary storage of `n / 6` power series. Due to the extra power series multiplications, it is only faster than the naive algorithm when *len* is small. .. function:: void acb_dirichlet_powsum_smooth(acb_ptr res, const acb_t s, ulong n, slong len, slong prec) Sets *res* to `\sum_{k=1}^n k^{-(s+x)}` as a power series in *x* truncated to length *len*. This function performs partial sieving by adding multiples of 5-smooth *k* into separate buckets. Asymptotically, this requires computing 4/15 of the powers, which is slower than *sieved*, but only requires logarithmic extra space. It is also faster for large *len*, since most power series multiplications are traded for additions. A slightly bigger gain for larger *n* could be achieved by using more small prime factors, at the expense of space. Riemann zeta function ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_zeta(acb_t res, const acb_t s, slong prec) Computes `\zeta(s)` using an automatic choice of algorithm. .. function:: void acb_dirichlet_zeta_jet(acb_t res, const acb_t s, int deflate, slong len, slong prec) Computes the first *len* terms of the Taylor series of the Riemann zeta function at *s*. If *deflate* is nonzero, computes the deflated function `\zeta(s) - 1/(s-1)` instead. .. function:: void acb_dirichlet_zeta_bound(mag_t res, const acb_t s) Computes an upper bound for `|\zeta(s)|` quickly. On the critical strip (and slightly outside of it), formula (43.3) in [Rad1973]_ is used. To the right, evaluating at the real part of *s* gives a trivial bound. To the left, the functional equation is used. .. function:: void acb_dirichlet_zeta_deriv_bound(mag_t der1, mag_t der2, const acb_t s) Sets *der1* to a bound for `|\zeta'(s)|` and *der2* to a bound for `|\zeta''(s)|`. These bounds are mainly intended for use in the critical strip and will not be tight. .. function:: void acb_dirichlet_eta(acb_t res, const acb_t s, slong prec) Sets *res* to the Dirichlet eta function `\eta(s) = \sum_{k=1}^{\infty} (-1)^{k+1} / k^s = (1-2^{1-s}) \zeta(s)`, also known as the alternating zeta function. Note that the alternating character `\{1,-1\}` is not itself a Dirichlet character. .. function:: void acb_dirichlet_xi(acb_t res, const acb_t s, slong prec) Sets *res* to the Riemann xi function `\xi(s) = \frac{1}{2} s (s-1) \pi^{-s/2} \Gamma(\frac{1}{2} s) \zeta(s)`. The functional equation for xi is `\xi(1-s) = \xi(s)`. Riemann-Siegel formula ------------------------------------------------------------------------------- The Riemann-Siegel (RS) formula is implemented closely following J. Arias de Reyna [Ari2011]_. For `s = \sigma + it` with `t > 0`, the expansion takes the form .. math :: \zeta(s) = \mathcal{R}(s) + X(s) \overline{\mathcal{R}}(1-s), \quad X(s) = \pi^{s-1/2} \frac{\Gamma((1-s)/2)}{\Gamma(s/2)} where .. math :: \mathcal{R}(s) = \sum_{k=1}^N \frac{1}{k^s} + (-1)^{N-1} U a^{-\sigma} \left[ \sum_{k=0}^K \frac{C_k(p)}{a^k} + RS_K \right] .. math :: U = \exp\left(-i\left[ \frac{t}{2} \log\left(\frac{t}{2\pi}\right)-\frac{t}{2}-\frac{\pi}{8} \right]\right), \quad a = \sqrt{\frac{t}{2\pi}}, \quad N = \lfloor a \rfloor, \quad p = 1-2(a-N). The coefficients `C_k(p)` in the asymptotic part of the expansion are expressed in terms of certain auxiliary coefficients `d_j^{(k)}` and `F^{(j)}(p)`. Because of artificial discontinuities, *s* should be exact inside the evaluation. .. function:: void acb_dirichlet_zeta_rs_f_coeffs(acb_ptr f, const arb_t p, slong n, slong prec) Computes the coefficients `F^{(j)}(p)` for `0 \le j < n`. Uses power series division. This method breaks down when `p = \pm 1/2` (which is not problem if *s* is an exact floating-point number). .. function:: void acb_dirichlet_zeta_rs_d_coeffs(arb_ptr d, const arb_t sigma, slong k, slong prec) Computes the coefficients `d_j^{(k)}` for `0 \le j \le \lfloor 3k/2 \rfloor + 1`. On input, the array *d* must contain the coefficients for `d_j^{(k-1)}` unless `k = 0`, and these coefficients will be updated in-place. .. function:: void acb_dirichlet_zeta_rs_bound(mag_t err, const acb_t s, slong K) Bounds the error term `RS_K` following Theorem 4.2 in Arias de Reyna. .. function:: void acb_dirichlet_zeta_rs_r(acb_t res, const acb_t s, slong K, slong prec) Computes `\mathcal{R}(s)` in the upper half plane. Uses precisely *K* asymptotic terms in the RS formula if this input parameter is positive; otherwise chooses the number of terms automatically based on *s* and the precision. .. function:: void acb_dirichlet_zeta_rs(acb_t res, const acb_t s, slong K, slong prec) Computes `\zeta(s)` using the Riemann-Siegel formula. Uses precisely *K* asymptotic terms in the RS formula if this input parameter is positive; otherwise chooses the number of terms automatically based on *s* and the precision. .. function:: void acb_dirichlet_zeta_jet_rs(acb_t res, const acb_t s, slong len, slong prec) Computes the first *len* terms of the Taylor series of the Riemann zeta function at *s* using the Riemann Siegel formula. This function currently only supports *len* = 1 or *len* = 2. A finite difference is used to compute the first derivative. Hurwitz zeta function ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_hurwitz(acb_t res, const acb_t s, const acb_t a, slong prec) Computes the Hurwitz zeta function `\zeta(s, a)`. This function automatically delegates to the code for the Riemann zeta function when `a = 1`. Some other special cases may also be handled by direct formulas. In general, Euler-Maclaurin summation is used. Hurwitz zeta function precomputation ------------------------------------------------------------------------------- .. type:: acb_dirichlet_hurwitz_precomp_struct .. type:: acb_dirichlet_hurwitz_precomp_t .. function:: void acb_dirichlet_hurwitz_precomp_init(acb_dirichlet_hurwitz_precomp_t pre, const acb_t s, int deflate, ulong A, ulong K, ulong N, slong prec) Precomputes a grid of Taylor polynomials for fast evaluation of `\zeta(s,a)` on `a \in (0,1]` with fixed *s*. *A* is the initial shift to apply to *a*, *K* is the number of Taylor terms, *N* is the number of grid points. The precomputation requires *NK* evaluations of the Hurwitz zeta function, and each subsequent evaluation requires *2K* simple arithmetic operations (polynomial evaluation) plus *A* powers. As *K* grows, the error is at most `O(1/(2AN)^K)`. This function can be called with *A* set to zero, in which case no Taylor series precomputation is performed. This means that evaluation will be identical to calling :func:`acb_dirichlet_hurwitz` directly. Otherwise, we require that *A*, *K* and *N* are all positive. For a finite error bound, we require `K+\operatorname{re}(s) > 1`. To avoid an initial "bump" that steals precision and slows convergence, *AN* should be at least roughly as large as `|s|`, e.g. it is a good idea to have at least `AN > 0.5 |s|`. If *deflate* is set, the deflated Hurwitz zeta function is used, removing the pole at `s = 1`. .. function:: void acb_dirichlet_hurwitz_precomp_init_num(acb_dirichlet_hurwitz_precomp_t pre, const acb_t s, int deflate, double num_eval, slong prec) Initializes *pre*, choosing the parameters *A*, *K*, and *N* automatically to minimize the cost of *num_eval* evaluations of the Hurwitz zeta function at argument *s* to precision *prec*. .. function:: void acb_dirichlet_hurwitz_precomp_clear(acb_dirichlet_hurwitz_precomp_t pre) Clears the precomputed data. .. function:: void acb_dirichlet_hurwitz_precomp_choose_param(ulong * A, ulong * K, ulong * N, const acb_t s, double num_eval, slong prec) Chooses precomputation parameters *A*, *K* and *N* to minimize the cost of *num_eval* evaluations of the Hurwitz zeta function at argument *s* to precision *prec*. If it is estimated that evaluating each Hurwitz zeta function from scratch would be better than performing a precomputation, *A*, *K* and *N* are all set to 0. .. function:: void acb_dirichlet_hurwitz_precomp_bound(mag_t res, const acb_t s, ulong A, ulong K, ulong N) Computes an upper bound for the truncation error (not accounting for roundoff error) when evaluating `\zeta(s,a)` with precomputation parameters *A*, *K*, *N*, assuming that `0 < a \le 1`. For details, see :ref:`algorithms_hurwitz`. .. function:: void acb_dirichlet_hurwitz_precomp_eval(acb_t res, const acb_dirichlet_hurwitz_precomp_t pre, ulong p, ulong q, slong prec) Evaluates `\zeta(s,p/q)` using precomputed data, assuming that `0 < p/q \le 1`. Stieltjes constants ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_stieltjes(acb_t res, const fmpz_t n, const acb_t a, slong prec) Given a nonnegative integer *n*, sets *res* to the generalized Stieltjes constant `\gamma_n(a)` which is the coefficient in the Laurent series of the Hurwitz zeta function at the pole .. math :: \zeta(s,a) = \frac{1}{s-1} + \sum_{n=0}^\infty \frac{(-1)^n}{n!} \gamma_n(a) (s-1)^n. With `a = 1`, this gives the ordinary Stieltjes constants for the Riemann zeta function. This function uses an integral representation to permit fast computation for extremely large *n* [JB2018]_. If *n* is moderate and the precision is high enough, it falls back to evaluating the Hurwitz zeta function of a power series and reading off the last coefficient. Note that for computing a range of values `\gamma_0(a), \ldots, \gamma_n(a)`, it is generally more efficient to evaluate the Hurwitz zeta function series expansion once at `s = 1` than to call this function repeatedly, unless *n* is extremely large (at least several hundred). Dirichlet character evaluation ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_chi(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, ulong n, slong prec) Sets *res* to `\chi(n)`, the value of the Dirichlet character *chi* at the integer *n*. .. function:: void acb_dirichlet_chi_vec(acb_ptr v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv, slong prec) Compute the *nv* first Dirichlet values. .. function:: void acb_dirichlet_pairing(acb_t res, const dirichlet_group_t G, ulong m, ulong n, slong prec) .. function:: void acb_dirichlet_pairing_char(acb_t res, const dirichlet_group_t G, const dirichlet_char_t a, const dirichlet_char_t b, slong prec) Sets *res* to the value of the Dirichlet pairing `\chi(m,n)` at numbers `m` and `n`. The second form takes two characters as input. Dirichlet character Gauss, Jacobi and theta sums ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_gauss_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) .. function:: void acb_dirichlet_gauss_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) .. function:: void acb_dirichlet_gauss_sum_order2(acb_t res, const dirichlet_char_t chi, slong prec) .. function:: void acb_dirichlet_gauss_sum_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) .. function:: void acb_dirichlet_gauss_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) .. function:: void acb_dirichlet_gauss_sum_ui(acb_t res, const dirichlet_group_t G, ulong a, slong prec) Sets *res* to the Gauss sum .. math:: G_q(a) = \sum_{x \bmod q} \chi_q(a, x) e^{\frac{2i\pi x}q} - the *naive* version computes the sum as defined. - the *factor* version writes it as a product of local Gauss sums by chinese remainder theorem. - the *order2* version assumes *chi* is real and primitive and returns `i^p\sqrt q` where `p` is the parity of `\chi`. - the *theta* version assumes that *chi* is primitive to obtain the Gauss sum by functional equation of the theta series at `t=1`. An abort will be raised if the theta series vanishes at `t=1`. Only 4 exceptional characters of conductor 300 and 600 are known to have this particularity, and none with primepower modulus. - the default version automatically combines the above methods. - the *ui* version only takes the Conrey number *a* as parameter. .. function:: void acb_dirichlet_jacobi_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) .. function:: void acb_dirichlet_jacobi_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) .. function:: void acb_dirichlet_jacobi_sum_gauss(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) .. function:: void acb_dirichlet_jacobi_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) .. function:: void acb_dirichlet_jacobi_sum_ui(acb_t res, const dirichlet_group_t G, ulong a, ulong b, slong prec) Computes the Jacobi sum .. math:: J_q(a,b) = \sum_{x \bmod q} \chi_q(a, x)\chi_q(b, 1-x) - the *naive* version computes the sum as defined. - the *factor* version writes it as a product of local Jacobi sums - the *gauss* version assumes `ab` is primitive and uses the formula `J_q(a,b)G_q(ab) = G_q(a)G_q(b)` - the default version automatically combines the above methods. - the *ui* version only takes the Conrey numbers *a* and *b* as parameters. .. function:: void acb_dirichlet_chi_theta_arb(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t t, slong prec) .. function:: void acb_dirichlet_ui_theta_arb(acb_t res, const dirichlet_group_t G, ulong a, const arb_t t, slong prec) Compute the theta series `\Theta_q(a,t)` for real argument `t>0`. Beware that if `t<1` the functional equation .. math:: t \theta(a,t) = \epsilon(\chi) \theta\left(\frac1a, \frac1t\right) should be used, which is not done automatically (to avoid recomputing the Gauss sum). We call *theta series* of a Dirichlet character the quadratic series .. math:: \Theta_q(a) = \sum_{n\geq 0} \chi_q(a, n) n^p x^{n^2} where `p` is the parity of the character `\chi_q(a,\cdot)`. For `\Re(t)>0` we write `x(t)=\exp(-\frac{\pi}{N}t^2)` and define .. math:: \Theta_q(a,t) = \sum_{n\geq 0} \chi_q(a, n) x(t)^{n^2}. .. function:: ulong acb_dirichlet_theta_length(ulong q, const arb_t t, slong prec) Compute the number of terms to be summed in the theta series of argument *t* so that the tail is less than `2^{-\mathrm{prec}}`. .. function:: void acb_dirichlet_qseries_powers_naive(acb_t res, const arb_t x, int p, const ulong * a, const acb_dirichlet_powers_t z, slong len, slong prec) .. function:: void acb_dirichlet_qseries_powers_smallorder(acb_t res, const arb_t x, int p, const ulong * a, const acb_dirichlet_powers_t z, slong len, slong prec) Compute the series `\sum n^p z^{a_n} x^{n^2}` for exponent list *a*, precomputed powers *z* and parity *p* (being 0 or 1). The *naive* version sums the series as defined, while the *smallorder* variant evaluates the series on the quotient ring by a cyclotomic polynomial before evaluating at the root of unity, ignoring its argument *z*. Discrete Fourier transforms ------------------------------------------------------------------------------- If `f` is a function `\mathbb Z/q\mathbb Z\to \mathbb C`, its discrete Fourier transform is the function defined on Dirichlet characters mod `q` by .. math:: \hat f(\chi) = \sum_{x\mod q}\overline{\chi(x)}f(x) See the :ref:`acb-dft` module. Here we take advantage of the Conrey isomorphism `G \to \hat G` to consider the Fourier transform on Conrey labels as .. math:: g(a) = \sum_{b\bmod q}\overline{\chi_q(a,b)}f(b) .. function:: void acb_dirichlet_dft_conrey(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec) Compute the DFT of *v* using Conrey indices. This function assumes *v* and *w* are vectors of size *G->phi_q*, whose values correspond to a lexicographic ordering of Conrey logs (as obtained using :func:`dirichlet_char_next` or by :func:`dirichlet_char_index`). For example, if `q=15`, the Conrey elements are stored in following order ======= ============= ===================== index log = [e,f] number = 7^e 11^f ======= ============= ===================== 0 [0, 0] 1 1 [0, 1] 7 2 [0, 2] 4 3 [0, 3] 13 4 [0, 4] 1 5 [1, 0] 11 6 [1, 1] 2 7 [1, 2] 14 8 [1, 3] 8 9 [1, 4] 11 ======= ============= ===================== .. function:: void acb_dirichlet_dft(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec) Compute the DFT of *v* using Conrey numbers. This function assumes *v* and *w* are vectors of size *G->q*. All values at index not coprime to *G->q* are ignored. Dirichlet L-functions ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_root_number_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) .. function:: void acb_dirichlet_root_number(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) Sets *res* to the root number `\epsilon(\chi)` for a primitive character *chi*, which appears in the functional equation (where `p` is the parity of `\chi`): .. math:: \left(\frac{q}{\pi}\right)^{\frac{s+p}2}\Gamma\left(\frac{s+p}2\right) L(s, \chi) = \epsilon(\chi) \left(\frac{q}{\pi}\right)^{\frac{1-s+p}2}\Gamma\left(\frac{1-s+p}2\right) L(1 - s, \overline\chi) - The *theta* variant uses the evaluation at `t=1` of the Theta series. - The default version computes it via the gauss sum. .. function:: void acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, const acb_dirichlet_hurwitz_precomp_t precomp, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) Computes `L(s,\chi)` using decomposition in terms of the Hurwitz zeta function .. math:: L(s,\chi) = q^{-s}\sum_{k=1}^q \chi(k) \,\zeta\!\left(s,\frac kq\right). If `s = 1` and `\chi` is non-principal, the deflated Hurwitz zeta function is used to avoid poles. If *precomp* is *NULL*, each Hurwitz zeta function value is computed directly. If a pre-initialized *precomp* object is provided, this will be used instead to evaluate the Hurwitz zeta function. .. function:: void acb_dirichlet_l_euler_product(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) .. function:: void _acb_dirichlet_euler_product_real_ui(arb_t res, ulong s, const signed char * chi, int mod, int reciprocal, slong prec) Computes `L(s,\chi)` directly using the Euler product. This is efficient if *s* has large positive real part. As implemented, this function only gives a finite result if `\operatorname{re}(s) \ge 2`. An error bound is computed via :func:`mag_hurwitz_zeta_uiui`. If *s* is complex, replace it with its real part. Since .. math :: \frac{1}{L(s,\chi)} = \prod_{p} \left(1 - \frac{\chi(p)}{p^s}\right) = \sum_{k=1}^{\infty} \frac{\mu(k)\chi(k)}{k^s} and the truncated product gives all smooth-index terms in the series, we have .. math :: \left|\prod_{p < N} \left(1 - \frac{\chi(p)}{p^s}\right) - \frac{1}{L(s,\chi)}\right| \le \sum_{k=N}^{\infty} \frac{1}{k^s} = \zeta(s,N). The underscore version specialized for integer *s* assumes that `\chi` is a real Dirichlet character given by the explicit list *chi* of character values at 0, 1, ..., *mod* - 1. If *reciprocal* is set, it computes `1 / L(s,\chi)` (this is faster if the reciprocal can be used directly). .. function:: void acb_dirichlet_l(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) Computes `L(s,\chi)` using a default choice of algorithm. .. function:: void acb_dirichlet_l_fmpq(acb_t res, const fmpq_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) void acb_dirichlet_l_fmpq_afe(acb_t res, const fmpq_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) Computes `L(s,\chi)` where *s* is a rational number. The *afe* version uses the approximate functional equation; the default version chooses an algorithm automatically. .. function:: void acb_dirichlet_l_vec_hurwitz(acb_ptr res, const acb_t s, const acb_dirichlet_hurwitz_precomp_t precomp, const dirichlet_group_t G, slong prec) Compute all values `L(s,\chi)` for `\chi` mod `q`, using the Hurwitz zeta function and a discrete Fourier transform. The output *res* is assumed to have length *G->phi_q* and values are stored by lexicographically ordered Conrey logs. See :func:`acb_dirichlet_dft_conrey`. If *precomp* is *NULL*, each Hurwitz zeta function value is computed directly. If a pre-initialized *precomp* object is provided, this will be used instead to evaluate the Hurwitz zeta function. .. function:: void acb_dirichlet_l_jet(acb_ptr res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec) Computes the Taylor expansion of `L(s,\chi)` to length *len*, i.e. `L(s), L'(s), \ldots, L^{(len-1)}(s) / (len-1)!`. If *deflate* is set, computes the expansion of .. math :: L(s,\chi) - \frac{\sum_{k=1}^q \chi(k)}{(s-1)q} instead. If *chi* is a principal character, then this has the effect of subtracting the pole with residue `\sum_{k=1}^q \chi(k) = \phi(q) / q` that is located at `s = 1`. In particular, when evaluated at `s = 1`, this gives the regular part of the Laurent expansion. When *chi* is non-principal, *deflate* has no effect. .. function:: void _acb_dirichlet_l_series(acb_ptr res, acb_srcptr s, slong slen, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec) .. function:: void acb_dirichlet_l_series(acb_poly_t res, const acb_poly_t s, const dirichlet_group_t G, const dirichlet_char_t chi, int deflate, slong len, slong prec) Sets *res* to the power series `L(s,\chi)` where *s* is a given power series, truncating the result to length *len*. See :func:`acb_dirichlet_l_jet` for the meaning of the *deflate* flag. Hardy Z-functions ------------------------------------------------------------------------------- For convenience, setting both *G* and *chi* to *NULL* in the following methods selects the Riemann zeta function. Currently, these methods require *chi* to be a primitive character. .. function:: void acb_dirichlet_hardy_theta(acb_ptr res, const acb_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) Computes the phase function used to construct the Z-function. We have .. math :: \theta(t) = -\frac{t}{2} \log(\pi/q) - \frac{i \log(\epsilon)}{2} + \frac{\log \Gamma((s+\delta)/2) - \log \Gamma((1-s+\delta)/2)}{2i} where `s = 1/2+it`, `\delta` is the parity of *chi*, and `\epsilon` is the root number as computed by :func:`acb_dirichlet_root_number`. The first *len* terms in the Taylor expansion are written to the output. .. function:: void acb_dirichlet_hardy_z(acb_t res, const acb_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) Computes the Hardy Z-function, also known as the Riemann-Siegel Z-function `Z(t) = e^{i \theta(t)} L(1/2+it)`, which is real-valued for real *t*. The first *len* terms in the Taylor expansion are written to the output. .. function:: void _acb_dirichlet_hardy_theta_series(acb_ptr res, acb_srcptr t, slong tlen, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) .. function:: void acb_dirichlet_hardy_theta_series(acb_poly_t res, const acb_poly_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) Sets *res* to the power series `\theta(t)` where *t* is a given power series, truncating the result to length *len*. .. function:: void _acb_dirichlet_hardy_z_series(acb_ptr res, acb_srcptr t, slong tlen, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) .. function:: void acb_dirichlet_hardy_z_series(acb_poly_t res, const acb_poly_t t, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, slong prec) Sets *res* to the power series `Z(t)` where *t* is a given power series, truncating the result to length *len*. Gram points ------------------------------------------------------------------------------- .. function:: void acb_dirichlet_gram_point(arb_t res, const fmpz_t n, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) Sets *res* to the *n*-th Gram point `g_n`, defined as the unique solution in `[7, \infty)` of `\theta(g_n) = \pi n`. Currently only the Gram points corresponding to the Riemann zeta function are supported and *G* and *chi* must both be set to *NULL*. Requires `n \ge -1`. Riemann zeta function zeros ------------------------------------------------------------------------------- The following functions for counting and isolating zeros of the Riemann zeta function use the ideas from the implementation of Turing's method in mpmath [Joh2018b]_ by Juan Arias de Reyna, described in [Ari2012]_. .. function:: ulong acb_dirichlet_turing_method_bound(const fmpz_t p) Computes an upper bound *B* for the minimum number of consecutive good Gram blocks sufficient to count nontrivial zeros of the Riemann zeta function using Turing's method [Tur1953]_ as updated by [Leh1970]_, [Bre1979]_, and [Tru2011]_. Let `N(T)` denote the number of zeros (counted according to their multiplicities) of `\zeta(s)` in the region `0 < \operatorname{Im}(s) \le T`. If at least *B* consecutive Gram blocks with union `[g_n, g_p)` satisfy Rosser's rule, then `N(g_n) \le n + 1` and `N(g_p) \ge p + 1`. .. function:: int _acb_dirichlet_definite_hardy_z(arb_t res, const arf_t t, slong * pprec) Sets *res* to the Hardy Z-function `Z(t)`. The initial precision (* *pprec*) is increased as necessary to determine the sign of `Z(t)`. The sign is returned. .. function:: void _acb_dirichlet_isolate_gram_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) Uses Gram's law to compute an interval `(a, b)` that contains the *n*-th zero of the Hardy Z-function and no other zero. Requires `1 \le n \le 126`. .. function:: void _acb_dirichlet_isolate_rosser_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) Uses Rosser's rule to compute an interval `(a, b)` that contains the *n*-th zero of the Hardy Z-function and no other zero. Requires `1 \le n \le 13999526`. .. function:: void _acb_dirichlet_isolate_turing_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) Computes an interval `(a, b)` that contains the *n*-th zero of the Hardy Z-function and no other zero, following Turing's method. Requires `n \ge 2`. .. function:: void acb_dirichlet_isolate_hardy_z_zero(arf_t a, arf_t b, const fmpz_t n) Computes an interval `(a, b)` that contains the *n*-th zero of the Hardy Z-function and contains no other zero, using the most appropriate underscore version of this function. Requires `n \ge 1`. .. function:: void _acb_dirichlet_refine_hardy_z_zero(arb_t res, const arf_t a, const arf_t b, slong prec) Sets *res* to the unique zero of the Hardy Z-function in the interval `(a, b)`. .. function:: void acb_dirichlet_hardy_z_zero(arb_t res, const fmpz_t n, slong prec) Sets *res* to the *n*-th zero of the Hardy Z-function, requiring `n \ge 1`. .. function:: void acb_dirichlet_hardy_z_zeros(arb_ptr res, const fmpz_t n, slong len, slong prec) Sets the entries of *res* to *len* consecutive zeros of the Hardy Z-function, beginning with the *n*-th zero. Requires positive *n*. .. function:: void acb_dirichlet_zeta_zero(acb_t res, const fmpz_t n, slong prec) Sets *res* to the *n*-th nontrivial zero of `\zeta(s)`, requiring `n \ge 1`. .. function:: void acb_dirichlet_zeta_zeros(acb_ptr res, const fmpz_t n, slong len, slong prec) Sets the entries of *res* to *len* consecutive nontrivial zeros of `\zeta(s)` beginning with the *n*-th zero. Requires positive *n*. .. function:: void _acb_dirichlet_exact_zeta_nzeros(fmpz_t res, const arf_t t) .. function:: void acb_dirichlet_zeta_nzeros(arb_t res, const arb_t t, slong prec) Compute the number of zeros (counted according to their multiplicities) of `\zeta(s)` in the region `0 < \operatorname{Im}(s) \le t`. .. function:: void acb_dirichlet_backlund_s(arb_t res, const arb_t t, slong prec) Compute `S(t) = \frac{1}{\pi}\operatorname{arg}\zeta(\frac{1}{2} + it)` where the argument is defined by continuous variation of `s` in `\zeta(s)` starting at `s = 2`, then vertically to `s = 2 + it`, then horizontally to `s = \frac{1}{2} + it`. In particular `\operatorname{arg}` in this context is not the principal value of the argument, and it cannot be computed directly by :func:`acb_arg`. In practice `S(t)` is computed as `S(t) = N(t) - \frac{1}{\pi}\theta(t) - 1` where `N(t)` is :func:`acb_dirichlet_zeta_nzeros` and `\theta(t)` is :func:`acb_dirichlet_hardy_theta`. .. function:: void acb_dirichlet_backlund_s_bound(mag_t res, const arb_t t) Compute an upper bound for `|S(t)|` quickly. Theorem 1 and the bounds in (1.2) in [Tru2014]_ are used. .. function:: void acb_dirichlet_zeta_nzeros_gram(fmpz_t res, const fmpz_t n) Compute `N(g_n)`. That is, compute the number of zeros (counted according to their multiplicities) of `\zeta(s)` in the region `0 < \operatorname{Im}(s) \le g_n` where `g_n` is the *n*-th Gram point. Requires `n \ge -1`. .. function:: slong acb_dirichlet_backlund_s_gram(const fmpz_t n) Compute `S(g_n)` where `g_n` is the *n*-th Gram point. Requires `n \ge -1`. Riemann zeta function zeros (Platt's method) ------------------------------------------------------------------------------- The following functions related to the Riemann zeta function use the ideas and formulas described by David J. Platt in [Pla2017]_. .. function:: void acb_dirichlet_platt_scaled_lambda(arb_t res, const arb_t t, slong prec) Compute `\Lambda(t) e^{\pi t/4}` where .. math :: \Lambda(t) = \pi^{-\frac{it}{2}} \Gamma\left(\frac{\frac{1}{2}+it}{2}\right) \zeta\left(\frac{1}{2} + it\right) is defined in the beginning of section 3 of [Pla2017]_. As explained in [Pla2011]_ this function has the same zeros as `\zeta(1/2 + it)` and is real-valued by the functional equation, and the exponential factor is designed to counteract the decay of the gamma factor as `t` increases. .. function:: void acb_dirichlet_platt_scaled_lambda_vec(arb_ptr res, const fmpz_t T, slong A, slong B, slong prec) .. function:: void acb_dirichlet_platt_multieval(arb_ptr res, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec) .. function:: void acb_dirichlet_platt_multieval_threaded(arb_ptr res, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma, slong prec) Compute :func:`acb_dirichlet_platt_scaled_lambda` at `N=AB` points on a grid, following the notation of [Pla2017]_. The first point on the grid is `T - B/2` and the distance between grid points is `1/A`. The product `N=AB` must be an even integer. The multieval versions evaluate the function at all points on the grid simultaneously using discrete Fourier transforms, and they require the four additional tuning parameters *h*, *J*, *K*, and *sigma*. The *threaded* multieval version splits the computation over the number of threads returned by *flint_get_num_threads()*, while the default multieval version chooses whether to use multithreading automatically. .. function:: void acb_dirichlet_platt_ws_interpolation(arb_t res, arf_t deriv, const arb_t t0, arb_srcptr p, const fmpz_t T, slong A, slong B, slong Ns_max, const arb_t H, slong sigma, slong prec) Compute :func:`acb_dirichlet_platt_scaled_lambda` at *t0* by Gaussian-windowed Whittaker-Shannon interpolation of points evaluated by :func:`acb_dirichlet_platt_scaled_lambda_vec`. The derivative is also approximated if the output parameter *deriv* is not *NULL*. *Ns_max* defines the maximum number of supporting points to be used in the interpolation on either side of *t0*. *H* is the standard deviation of the Gaussian window centered on *t0* to be applied before the interpolation. *sigma* is an odd positive integer tuning parameter `\sigma \in 2\mathbb{Z}_{>0}+1` used in computing error bounds. .. function:: slong _acb_dirichlet_platt_local_hardy_z_zeros(arb_ptr res, const fmpz_t n, slong len, const fmpz_t T, slong A, slong B, const arb_t h, slong J, slong K, slong sigma_grid, slong Ns_max, const arb_t H, slong sigma_interp, slong prec) .. function:: slong acb_dirichlet_platt_local_hardy_z_zeros(arb_ptr res, const fmpz_t n, slong len, slong prec) .. function:: slong acb_dirichlet_platt_hardy_z_zeros(arb_ptr res, const fmpz_t n, slong len, slong prec) Sets at most the first *len* entries of *res* to consecutive zeros of the Hardy Z-function starting with the *n*-th zero. The number of obtained consecutive zeros is returned. The first two function variants each make a single call to Platt's grid evaluation of the scaled Lambda function, whereas the third variant performs as many evaluations as necessary to obtain *len* consecutive zeros. The final several parameters of the underscored local variant have the same meanings as in the functions :func:`acb_dirichlet_platt_multieval` and :func:`acb_dirichlet_platt_ws_interpolation`. The non-underscored variants currently expect `10^4 \leq n \leq 10^{23}`. The user has the option of multi-threading through *flint_set_num_threads(numthreads)*. .. function:: slong acb_dirichlet_platt_zeta_zeros(acb_ptr res, const fmpz_t n, slong len, slong prec) Sets at most the first *len* entries of *res* to consecutive zeros of the Riemann zeta function starting with the *n*-th zero. The number of obtained consecutive zeros is returned. It currently expects `10^4 \leq n \leq 10^{23}`. The user has the option of multi-threading through *flint_set_num_threads(numthreads)*. arb-2.22.1/doc/source/acb_elliptic.rst000066400000000000000000000353321417376376500176040ustar00rootroot00000000000000.. _acb-elliptic: **acb_elliptic.h** -- elliptic integrals and functions of complex variables =============================================================================== This module supports computation of elliptic (doubly periodic) functions, and their inverses, elliptic integrals. See :ref:`acb_modular.h ` for the closely related modular forms and Jacobi theta functions. Warning: incomplete elliptic integrals have very complicated branch structure when extended to complex variables. For some functions in this module, branch cuts may be artifacts of the evaluation algorithm rather than having a natural mathematical justification. The user should, accordingly, watch out for edge cases where the functions implemented here may differ from other systems or literature. There may also exist points where a function should be well-defined but the implemented algorithm fails to produce a finite result due to artificial internal singularities. Complete elliptic integrals ------------------------------------------------------------------------------- .. function:: void acb_elliptic_k(acb_t res, const acb_t m, slong prec) Computes the complete elliptic integral of the first kind .. math :: K(m) = \int_0^{\pi/2} \frac{dt}{\sqrt{1-m \sin^2 t}} = \int_0^1 \frac{dt}{\left(\sqrt{1-t^2}\right)\left(\sqrt{1-mt^2}\right)} using the arithmetic-geometric mean: `K(m) = \pi / (2 M(\sqrt{1-m}))`. .. function:: void acb_elliptic_k_jet(acb_ptr res, const acb_t m, slong len, slong prec) Sets the coefficients in the array *res* to the power series expansion of the complete elliptic integral of the first kind at the point *m* truncated to length *len*, i.e. `K(m+x) \in \mathbb{C}[[x]]`. .. function:: void _acb_elliptic_k_series(acb_ptr res, acb_srcptr m, slong mlen, slong len, slong prec) .. function:: void acb_elliptic_k_series(acb_poly_t res, const acb_poly_t m, slong len, slong prec) Sets *res* to the complete elliptic integral of the first kind of the power series *m*, truncated to length *len*. .. function:: void acb_elliptic_e(acb_t res, const acb_t m, slong prec) Computes the complete elliptic integral of the second kind .. math :: E(m) = \int_0^{\pi/2} \sqrt{1-m \sin^2 t} \, dt = \int_0^1 \frac{\sqrt{1-mt^2}}{\sqrt{1-t^2}} \, dt using `E(m) = (1-m)(2m K'(m) + K(m))` (where the prime denotes a derivative, not a complementary integral). .. function:: void acb_elliptic_pi(acb_t res, const acb_t n, const acb_t m, slong prec) Evaluates the complete elliptic integral of the third kind .. math :: \Pi(n, m) = \int_0^{\pi/2} \frac{dt}{(1-n \sin^2 t) \sqrt{1-m \sin^2 t}} = \int_0^1 \frac{dt}{(1-nt^2) \sqrt{1-t^2} \sqrt{1-mt^2}}. This implementation currently uses the same algorithm as the corresponding incomplete integral. It is therefore less efficient than the implementations of the first two complete elliptic integrals which use the AGM. Legendre incomplete elliptic integrals ------------------------------------------------------------------------------- .. function:: void acb_elliptic_f(acb_t res, const acb_t phi, const acb_t m, int pi, slong prec) Evaluates the Legendre incomplete elliptic integral of the first kind, given by .. math :: F(\phi,m) = \int_0^{\phi} \frac{dt}{\sqrt{1-m \sin^2 t}} = \int_0^{\sin \phi} \frac{dt}{\left(\sqrt{1-t^2}\right)\left(\sqrt{1-mt^2}\right)} on the standard strip `-\pi/2 \le \operatorname{Re}(\phi) \le \pi/2`. Outside this strip, the function extends quasiperiodically as .. math :: F(\phi + n \pi, m) = 2 n K(m) + F(\phi,m), n \in \mathbb{Z}. Inside the standard strip, the function is computed via the symmetric integral `R_F`. If the flag *pi* is set to 1, the variable `\phi` is replaced by `\pi \phi`, changing the quasiperiod to 1. The function reduces to a complete elliptic integral of the first kind when `\phi = \frac{\pi}{2}`; that is, `F\left(\frac{\pi}{2}, m\right) = K(m)`. .. function:: void acb_elliptic_e_inc(acb_t res, const acb_t phi, const acb_t m, int pi, slong prec) Evaluates the Legendre incomplete elliptic integral of the second kind, given by .. math :: E(\phi,m) = \int_0^{\phi} \sqrt{1-m \sin^2 t} \, dt = \int_0^{\sin \phi} \frac{\sqrt{1-mt^2}}{\sqrt{1-t^2}} \, dt on the standard strip `-\pi/2 \le \operatorname{Re}(\phi) \le \pi/2`. Outside this strip, the function extends quasiperiodically as .. math :: E(\phi + n \pi, m) = 2 n E(m) + E(\phi,m), n \in \mathbb{Z}. Inside the standard strip, the function is computed via the symmetric integrals `R_F` and `R_D`. If the flag *pi* is set to 1, the variable `\phi` is replaced by `\pi \phi`, changing the quasiperiod to 1. The function reduces to a complete elliptic integral of the second kind when `\phi = \frac{\pi}{2}`; that is, `E\left(\frac{\pi}{2}, m\right) = E(m)`. .. function:: void acb_elliptic_pi_inc(acb_t res, const acb_t n, const acb_t phi, const acb_t m, int pi, slong prec) Evaluates the Legendre incomplete elliptic integral of the third kind, given by .. math :: \Pi(n, \phi, m) = \int_0^{\phi} \frac{dt}{(1-n \sin^2 t) \sqrt{1-m \sin^2 t}} = \int_0^{\sin \phi} \frac{dt}{(1-nt^2) \sqrt{1-t^2} \sqrt{1-mt^2}} on the standard strip `-\pi/2 \le \operatorname{Re}(\phi) \le \pi/2`. Outside this strip, the function extends quasiperiodically as .. math :: \Pi(n, \phi + k \pi, m) = 2 k \Pi(n,m) + \Pi(n,\phi,m), k \in \mathbb{Z}. Inside the standard strip, the function is computed via the symmetric integrals `R_F` and `R_J`. If the flag *pi* is set to 1, the variable `\phi` is replaced by `\pi \phi`, changing the quasiperiod to 1. The function reduces to a complete elliptic integral of the third kind when `\phi = \frac{\pi}{2}`; that is, `\Pi\left(n, \frac{\pi}{2}, m\right) = \Pi(n, m)`. Carlson symmetric elliptic integrals ------------------------------------------------------------------------------- Carlson symmetric forms are the preferred form of incomplete elliptic integrals, due to their neat properties and relatively simple computation based on duplication theorems. There are five named functions: `R_F, R_G, R_J`, and `R_C`, `R_D` which are special cases of `R_F` and `R_J` respectively. We largely follow the definitions and algorithms in [Car1995]_ and chapter 19 in [NIST2012]_. .. function:: void acb_elliptic_rf(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec) Evaluates the Carlson symmetric elliptic integral of the first kind .. math :: R_F(x,y,z) = \frac{1}{2} \int_0^{\infty} \frac{dt}{\sqrt{(t+x)(t+y)(t+z)}} where the square root extends continuously from positive infinity. The integral is well-defined for `x,y,z \notin (-\infty,0)`, and with at most one of `x,y,z` being zero. When some parameters are negative real numbers, the function is still defined by analytic continuation. In general, one or more duplication steps are applied until `x,y,z` are close enough to use a multivariate Taylor series. The special case `R_C(x, y) = R_F(x, y, y) = \frac{1}{2} \int_0^{\infty} (t+x)^{-1/2} (t+y)^{-1} dt` may be computed by setting *y* and *z* to the same variable. (This case is not yet handled specially, but might be optimized in the future.) The *flags* parameter is reserved for future use and currently does nothing. Passing 0 results in default behavior. .. function:: void acb_elliptic_rg(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec) Evaluates the Carlson symmetric elliptic integral of the second kind .. math :: R_G(x,y,z) = \frac{1}{4} \int_0^{\infty} \frac{t}{\sqrt{(t+x)(t+y)(t+z)}} \left( \frac{x}{t+x} + \frac{y}{t+y} + \frac{z}{t+z}\right) dt where the square root is taken continuously as in `R_F`. The evaluation is done by expressing `R_G` in terms of `R_F` and `R_D`. There are no restrictions on the variables. .. function:: void acb_elliptic_rj(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec) .. function:: void acb_elliptic_rj_carlson(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec) .. function:: void acb_elliptic_rj_integration(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec) Evaluates the Carlson symmetric elliptic integral of the third kind .. math :: R_J(x,y,z,p) = \frac{3}{2} \int_0^{\infty} \frac{dt}{(t+p)\sqrt{(t+x)(t+y)(t+z)}} where the square root is taken continuously as in `R_F`. Three versions of this function are available: the *carlson* version applies one or more duplication steps until `x,y,z,p` are close enough to use a multivariate Taylor series. The duplication algorithm is not correct for all possible combinations of complex variables, since the square roots taken during the computation can introduce spurious branch cuts. According to [Car1995]_, a sufficient (but not necessary) condition for correctness is that *x*, *y*, *z* have nonnegative real part and that *p* has positive real part. In other cases, the algorithm *might* still be correct, but no attempt is made to check this; it is up to the user to verify that the duplication algorithm is appropriate for the given parameters before calling this function. The *integration* algorithm uses explicit numerical integration to translate the parameters to the right half-plane. This is reliable but can be slow. The default method uses the *carlson* algorithm when it is certain to be correct, and otherwise falls back to the slow *integration* algorithm. The special case `R_D(x, y, z) = R_J(x, y, z, z)` may be computed by setting *z* and *p* to the same variable. This case is handled specially to avoid redundant arithmetic operations. In this case, the *carlson* algorithm is correct for all *x*, *y* and *z*. The *flags* parameter is reserved for future use and currently does nothing. Passing 0 results in default behavior. .. function:: void acb_elliptic_rc1(acb_t res, const acb_t x, slong prec) This helper function computes the special case `R_C(1, 1+x) = \operatorname{atan}(\sqrt{x})/\sqrt{x} = {}_2F_1(1,1/2,3/2,-x)`, which is needed in the evaluation of `R_J`. Weierstrass elliptic functions ------------------------------------------------------------------------------- Elliptic functions may be defined on a general lattice `\Lambda = \{m 2\omega_1 + n 2\omega_2\ : m, n \in \mathbb{Z}\}` with half-periods `\omega_1, \omega_2`. We simplify by setting `2\omega_1 = 1, 2\omega_2 = \tau` with `\operatorname{im}(\tau) > 0`. To evaluate the functions on a general lattice, it is enough to make a linear change of variables. The main reference is chapter 23 in [NIST2012]_. .. function:: void acb_elliptic_p(acb_t res, const acb_t z, const acb_t tau, slong prec) Computes Weierstrass's elliptic function .. math :: \wp(z, \tau) = \frac{1}{z^2} + \sum_{n^2+m^2 \ne 0} \left[ \frac{1}{(z+m+n\tau)^2} - \frac{1}{(m+n\tau)^2} \right] which satisfies `\wp(z, \tau) = \wp(z + 1, \tau) = \wp(z + \tau, \tau)`. To evaluate the function efficiently, we use the formula .. math :: \wp(z, \tau) = \pi^2 \theta_2^2(0,\tau) \theta_3^2(0,\tau) \frac{\theta_4^2(z,\tau)}{\theta_1^2(z,\tau)} - \frac{\pi^2}{3} \left[ \theta_2^4(0,\tau) + \theta_3^4(0,\tau)\right]. .. function:: void acb_elliptic_p_prime(acb_t res, const acb_t z, const acb_t tau, slong prec) Computes the derivative `\wp'(z, \tau)` of Weierstrass's elliptic function `\wp(z, \tau)`. .. function:: void acb_elliptic_p_jet(acb_ptr res, const acb_t z, const acb_t tau, slong len, slong prec) Computes the formal power series `\wp(z + x, \tau) \in \mathbb{C}[[x]]`, truncated to length *len*. In particular, with *len* = 2, simultaneously computes `\wp(z, \tau), \wp'(z, \tau)` which together generate the field of elliptic functions with periods 1 and `\tau`. .. function:: void _acb_elliptic_p_series(acb_ptr res, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec) .. function:: void acb_elliptic_p_series(acb_poly_t res, const acb_poly_t z, const acb_t tau, slong len, slong prec) Sets *res* to the Weierstrass elliptic function of the power series *z*, with periods 1 and *tau*, truncated to length *len*. .. function:: void acb_elliptic_invariants(acb_t g2, acb_t g3, const acb_t tau, slong prec) Computes the lattice invariants `g_2, g_3`. The Weierstrass elliptic function satisfies the differential equation `[\wp'(z, \tau)]^2 = 4 [\wp(z,\tau)]^3 - g_2 \wp(z,\tau) - g_3`. Up to constant factors, the lattice invariants are the first two Eisenstein series (see :func:`acb_modular_eisenstein`). .. function:: void acb_elliptic_roots(acb_t e1, acb_t e2, acb_t e3, const acb_t tau, slong prec) Computes the lattice roots `e_1, e_2, e_3`, which are the roots of the polynomial `4z^3 - g_2 z - g_3`. .. function:: void acb_elliptic_inv_p(acb_t res, const acb_t z, const acb_t tau, slong prec) Computes the inverse of the Weierstrass elliptic function, which satisfies `\wp(\wp^{-1}(z, \tau), \tau) = z`. This function is given by the elliptic integral .. math :: \wp^{-1}(z, \tau) = \frac{1}{2} \int_z^{\infty} \frac{dt}{\sqrt{(t-e_1)(t-e_2)(t-e_3)}} = R_F(z-e_1,z-e_2,z-e_3). .. function:: void acb_elliptic_zeta(acb_t res, const acb_t z, const acb_t tau, slong prec) Computes the Weierstrass zeta function .. math :: \zeta(z, \tau) = \frac{1}{z} + \sum_{n^2+m^2 \ne 0} \left[ \frac{1}{z-m-n\tau} + \frac{1}{m+n\tau} + \frac{z}{(m+n\tau)^2} \right] which is quasiperiodic with `\zeta(z + 1, \tau) = \zeta(z, \tau) + \zeta(1/2, \tau)` and `\zeta(z + \tau, \tau) = \zeta(z, \tau) + \zeta(\tau/2, \tau)`. .. function:: void acb_elliptic_sigma(acb_t res, const acb_t z, const acb_t tau, slong prec) Computes the Weierstrass sigma function .. math :: \sigma(z, \tau) = z \prod_{n^2+m^2 \ne 0} \left[ \left(1-\frac{z}{m+n\tau}\right) \exp\left(\frac{z}{m+n\tau} + \frac{z^2}{2(m+n\tau)^2} \right) \right] which is quasiperiodic with `\sigma(z + 1, \tau) = -e^{2 \zeta(1/2, \tau) (z+1/2)} \sigma(z, \tau)` and `\sigma(z + \tau, \tau) = -e^{2 \zeta(\tau/2, \tau) (z+\tau/2)} \sigma(z, \tau)`. arb-2.22.1/doc/source/acb_hypgeom.rst000066400000000000000000001617461417376376500174600ustar00rootroot00000000000000.. _acb-hypgeom: **acb_hypgeom.h** -- hypergeometric functions of complex variables ================================================================================== The generalized hypergeometric function is formally defined by .. math :: {}_pF_q(a_1,\ldots,a_p;b_1,\ldots,b_q;z) = \sum_{k=0}^\infty \frac{(a_1)_k\dots(a_p)_k}{(b_1)_k\dots(b_q)_k} \frac {z^k} {k!}. It can be interpreted using analytic continuation or regularization when the sum does not converge. In a looser sense, we understand "hypergeometric functions" to be linear combinations of generalized hypergeometric functions with prefactors that are products of exponentials, powers, and gamma functions. Rising factorials ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_rising_ui_forward(acb_t res, const acb_t x, ulong n, slong prec) void acb_hypgeom_rising_ui_bs(acb_t res, const acb_t x, ulong n, slong prec) void acb_hypgeom_rising_ui_rs(acb_t res, const acb_t x, ulong n, ulong m, slong prec) void acb_hypgeom_rising_ui_rec(acb_t res, const acb_t x, ulong n, slong prec) void acb_hypgeom_rising_ui(acb_t res, const acb_t x, ulong n, slong prec) void acb_hypgeom_rising(acb_t res, const acb_t x, const acb_t n, slong prec) Computes the rising factorial `(x)_n`. The *forward* version uses the forward recurrence. The *bs* version uses binary splitting. The *rs* version uses rectangular splitting. It takes an extra tuning parameter *m* which can be set to zero to choose automatically. The *rec* version chooses an algorithm automatically, avoiding use of the gamma function (so that it can be used in the computation of the gamma function). The default versions (*rising_ui* and *rising_ui*) choose an algorithm automatically and may additionally fall back on the gamma function. .. function:: void acb_hypgeom_rising_ui_jet_powsum(acb_ptr res, const acb_t x, ulong n, slong len, slong prec) void acb_hypgeom_rising_ui_jet_bs(acb_ptr res, const acb_t x, ulong n, slong len, slong prec) void acb_hypgeom_rising_ui_jet_rs(acb_ptr res, const acb_t x, ulong n, ulong m, slong len, slong prec) void acb_hypgeom_rising_ui_jet(acb_ptr res, const acb_t x, ulong n, slong len, slong prec) Computes the jet of the rising factorial `(x)_n`, truncated to length *len*. In other words, constructs the polynomial `(X + x)_n \in \mathbb{R}[X]`, truncated if `\operatorname{len} < n + 1` (and zero-extended if `\operatorname{len} > n + 1`). The *powsum* version computes the sequence of powers of *x* and forms integral linear combinations of these. The *bs* version uses binary splitting. The *rs* version uses rectangular splitting. It takes an extra tuning parameter *m* which can be set to zero to choose automatically. The default version chooses an algorithm automatically. .. function:: void acb_hypgeom_log_rising_ui(acb_ptr res, const acb_t x, ulong n, slong prec) Computes the log-rising factorial `\log \, (x)_n = \sum_{k=0}^{n-1} \log(x+k)`. This first computes the ordinary rising factorial and then determines the branch correction `2 \pi i m` with respect to the principal logarithm. The correction is computed using Hare's algorithm in floating-point arithmetic if this is safe; otherwise, a direct computation of `\sum_{k=0}^{n-1} \arg(x+k)` is used as a fallback. .. function:: void acb_hypgeom_log_rising_ui_jet(acb_ptr res, const acb_t x, ulong n, slong len, slong prec) Computes the jet of the log-rising factorial `\log \, (x)_n`, truncated to length *len*. Gamma function ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_gamma_stirling_sum_horner(acb_t s, const acb_t z, slong N, slong prec) void acb_hypgeom_gamma_stirling_sum_improved(acb_t s, const acb_t z, slong N, slong K, slong prec) Sets *res* to the final sum in the Stirling series for the gamma function truncated before the term with index *N*, i.e. computes `\sum_{n=1}^{N-1} B_{2n} / (2n(2n-1) z^{2n-1})`. The *horner* version uses Horner scheme with gradual precision adjustments. The *improved* version uses rectangular splitting for the low-index terms and reexpands the high-index terms as hypergeometric polynomials, using a splitting parameter *K* (which can be set to 0 to use a default value). .. function:: void acb_hypgeom_gamma_stirling(acb_t res, const acb_t x, int reciprocal, slong prec) Sets *res* to the gamma function of *x* computed using the Stirling series together with argument reduction. If *reciprocal* is set, the reciprocal gamma function is computed instead. .. function:: int acb_hypgeom_gamma_taylor(acb_t res, const acb_t x, int reciprocal, slong prec) Attempts to compute the gamma function of *x* using Taylor series together with argument reduction. This is only supported if *x* and *prec* are both small enough. If successful, returns 1; otherwise, does nothing and returns 0. If *reciprocal* is set, the reciprocal gamma function is computed instead. .. function:: void acb_hypgeom_gamma(acb_t res, const acb_t x, slong prec) Sets *res* to the gamma function of *x* computed using a default algorithm choice. .. function:: void acb_hypgeom_rgamma(acb_t res, const acb_t x, slong prec) Sets *res* to the reciprocal gamma function of *x* computed using a default algorithm choice. .. function:: void acb_hypgeom_lgamma(acb_t res, const acb_t x, slong prec) Sets *res* to the principal branch of the log-gamma function of *x* computed using a default algorithm choice. Convergent series ------------------------------------------------------------------------------- In this section, we define .. math :: T(k) = \frac{\prod_{i=0}^{p-1} (a_i)_k}{\prod_{i=0}^{q-1} (b_i)_k} z^k and .. math :: {}_pf_{q}(a_0,\ldots,a_{p-1}; b_0 \ldots b_{q-1}; z) = {}_{p+1}F_{q}(a_0,\ldots,a_{p-1},1; b_0 \ldots b_{q-1}; z) = \sum_{k=0}^{\infty} T(k) For the conventional generalized hypergeometric function `{}_pF_{q}`, compute `{}_pf_{q+1}` with the explicit parameter `b_q = 1`, or remove a 1 from the `a_i` parameters if there is one. .. function:: void acb_hypgeom_pfq_bound_factor(mag_t C, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, ulong n) Computes a factor *C* such that `\left|\sum_{k=n}^{\infty} T(k)\right| \le C |T(n)|`. See :ref:`algorithms_hypergeometric_convergent`. As currently implemented, the bound becomes infinite when `n` is too small, even if the series converges. .. function:: slong acb_hypgeom_pfq_choose_n(acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong prec) Heuristically attempts to choose a number of terms *n* to sum of a hypergeometric series at a working precision of *prec* bits. Uses double precision arithmetic internally. As currently implemented, it can fail to produce a good result if the parameters are extremely large or extremely close to nonpositive integers. Numerical cancellation is assumed to be significant, so truncation is done when the current term is *prec* bits smaller than the largest encountered term. This function will also attempt to pick a reasonable truncation point for divergent series. .. function:: void acb_hypgeom_pfq_sum_forward(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) .. function:: void acb_hypgeom_pfq_sum_rs(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) .. function:: void acb_hypgeom_pfq_sum_bs(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) .. function:: void acb_hypgeom_pfq_sum_fme(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) .. function:: void acb_hypgeom_pfq_sum(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) Computes `s = \sum_{k=0}^{n-1} T(k)` and `t = T(n)`. Does not allow aliasing between input and output variables. We require `n \ge 0`. The *forward* version computes the sum using forward recurrence. The *bs* version computes the sum using binary splitting. The *rs* version computes the sum in reverse order using rectangular splitting. It only computes a magnitude bound for the value of *t*. The *fme* version uses fast multipoint evaluation. The default version automatically chooses an algorithm depending on the inputs. .. function:: void acb_hypgeom_pfq_sum_bs_invz(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t w, slong n, slong prec) .. function:: void acb_hypgeom_pfq_sum_invz(acb_t s, acb_t t, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, const acb_t w, slong n, slong prec) Like :func:`acb_hypgeom_pfq_sum`, but taking advantage of `w = 1/z` possibly having few bits. .. function:: void acb_hypgeom_pfq_direct(acb_t res, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) Computes .. math :: {}_pf_{q}(z) = \sum_{k=0}^{\infty} T(k) = \sum_{k=0}^{n-1} T(k) + \varepsilon directly from the defining series, including a rigorous bound for the truncation error `\varepsilon` in the output. If `n < 0`, this function chooses a number of terms automatically using :func:`acb_hypgeom_pfq_choose_n`. .. function:: void acb_hypgeom_pfq_series_sum_forward(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) .. function:: void acb_hypgeom_pfq_series_sum_bs(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) .. function:: void acb_hypgeom_pfq_series_sum_rs(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) .. function:: void acb_hypgeom_pfq_series_sum(acb_poly_t s, acb_poly_t t, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) Computes `s = \sum_{k=0}^{n-1} T(k)` and `t = T(n)` given parameters and argument that are power series. Does not allow aliasing between input and output variables. We require `n \ge 0` and that *len* is positive. If *regularized* is set, the regularized sum is computed, avoiding division by zero at the poles of the gamma function. The *forward*, *bs*, *rs* and default versions use forward recurrence, binary splitting, rectangular splitting, and an automatic algorithm choice. .. function:: void acb_hypgeom_pfq_series_direct(acb_poly_t res, const acb_poly_struct * a, slong p, const acb_poly_struct * b, slong q, const acb_poly_t z, int regularized, slong n, slong len, slong prec) Computes `{}_pf_{q}(z)` directly using the defining series, given parameters and argument that are power series. The result is a power series of length *len*. We require that *len* is positive. An error bound is computed automatically as a function of the number of terms *n*. If `n < 0`, the number of terms is chosen automatically. If *regularized* is set, the regularized hypergeometric function is computed instead. Asymptotic series ------------------------------------------------------------------------------- `U(a,b,z)` is the confluent hypergeometric function of the second kind with the principal branch cut, and `U^{*} = z^a U(a,b,z)`. For details about how error bounds are computed, see :ref:`algorithms_hypergeometric_asymptotic_confluent`. .. function:: void acb_hypgeom_u_asymp(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong n, slong prec) Sets *res* to `U^{*}(a,b,z)` computed using *n* terms of the asymptotic series, with a rigorous bound for the error included in the output. We require `n \ge 0`. .. function:: int acb_hypgeom_u_use_asymp(const acb_t z, slong prec) Heuristically determines whether the asymptotic series can be used to evaluate `U(a,b,z)` to *prec* accurate bits (assuming that *a* and *b* are small). Generalized hypergeometric function ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_pfq(acb_poly_t res, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, int regularized, slong prec) Computes the generalized hypergeometric function `{}_pF_{q}(z)`, or the regularized version if *regularized* is set. This function automatically delegates to a specialized implementation when the order (*p*, *q*) is one of (0,0), (1,0), (0,1), (1,1), (2,1). Otherwise, it falls back to direct summation. While this is a top-level function meant to take care of special cases automatically, it does not generally perform the optimization of deleting parameters that appear in both *a* and *b*. This can be done ahead of time by the user in applications where duplicate parameters are likely to occur. Confluent hypergeometric functions ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_u_1f1_series(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t z, slong len, slong prec) Computes `U(a,b,z)` as a power series truncated to length *len*, given `a, b, z \in \mathbb{C}[[x]]`. If `b[0] \in \mathbb{Z}`, it computes one extra derivative and removes the singularity (it is then assumed that `b[1] \ne 0`). As currently implemented, the output is indeterminate if `b` is nonexact and contains an integer. .. function:: void acb_hypgeom_u_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec) Computes `U(a,b,z)` as a sum of two convergent hypergeometric series. If `b \in \mathbb{Z}`, it computes the limit value via :func:`acb_hypgeom_u_1f1_series`. As currently implemented, the output is indeterminate if `b` is nonexact and contains an integer. .. function:: void acb_hypgeom_u(acb_t res, const acb_t a, const acb_t b, const acb_t z, slong prec) Computes `U(a,b,z)` using an automatic algorithm choice. The function :func:`acb_hypgeom_u_asymp` is used if `a` or `a-b+1` is a nonpositive integer (in which case the asymptotic series terminates), or if *z* is sufficiently large. Otherwise :func:`acb_hypgeom_u_1f1` is used. .. function:: void acb_hypgeom_m_asymp(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_m(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) Computes the confluent hypergeometric function `M(a,b,z) = {}_1F_1(a,b,z)`, or `\mathbf{M}(a,b,z) = \frac{1}{\Gamma(b)} {}_1F_1(a,b,z)` if *regularized* is set. .. function:: void acb_hypgeom_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) Alias for :func:`acb_hypgeom_m`. .. function:: void acb_hypgeom_0f1_asymp(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_0f1_direct(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_0f1(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec) Computes the confluent hypergeometric function `{}_0F_1(a,z)`, or `\frac{1}{\Gamma(a)} {}_0F_1(a,z)` if *regularized* is set, using asymptotic expansions, direct summation, or an automatic algorithm choice. The *asymp* version uses the asymptotic expansions of Bessel functions, together with the connection formulas .. math :: \frac{{}_0F_1(a,z)}{\Gamma(a)} = (-z)^{(1-a)/2} J_{a-1}(2 \sqrt{-z}) = z^{(1-a)/2} I_{a-1}(2 \sqrt{z}). The Bessel-*J* function is used in the left half-plane and the Bessel-*I* function is used in the right half-plane, to avoid loss of accuracy due to evaluating the square root on the branch cut. Error functions and Fresnel integrals ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_erf_propagated_error(mag_t re, mag_t im, const acb_t z) Sets *re* and *im* to upper bounds for the error in the real and imaginary part resulting from approximating the error function of *z* by the error function evaluated at the midpoint of *z*. Uses the first derivative. .. function:: void acb_hypgeom_erf_1f1a(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_erf_1f1b(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_erf_asymp(acb_t res, const acb_t z, int complementary, slong prec, slong prec2) Computes the error function respectively using .. math :: \operatorname{erf}(z) &= \frac{2z}{\sqrt{\pi}} {}_1F_1(\tfrac{1}{2}, \tfrac{3}{2}, -z^2) \operatorname{erf}(z) &= \frac{2z e^{-z^2}}{\sqrt{\pi}} {}_1F_1(1, \tfrac{3}{2}, z^2) \operatorname{erf}(z) &= \frac{z}{\sqrt{z^2}} \left(1 - \frac{e^{-z^2}}{\sqrt{\pi}} U(\tfrac{1}{2}, \tfrac{1}{2}, z^2)\right) = \frac{z}{\sqrt{z^2}} - \frac{e^{-z^2}}{z \sqrt{\pi}} U^{*}(\tfrac{1}{2}, \tfrac{1}{2}, z^2). The *asymp* version takes a second precision to use for the *U* term. It also takes an extra flag *complementary*, computing the complementary error function if set. .. function:: void acb_hypgeom_erf(acb_t res, const acb_t z, slong prec) Computes the error function using an automatic algorithm choice. If *z* is too small to use the asymptotic expansion, a working precision sufficient to circumvent cancellation in the hypergeometric series is determined automatically, and a bound for the propagated error is computed with :func:`acb_hypgeom_erf_propagated_error`. .. function:: void _acb_hypgeom_erf_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_erf_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the error function of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_erfc(acb_t res, const acb_t z, slong prec) Computes the complementary error function `\operatorname{erfc}(z) = 1 - \operatorname{erf}(z)`. This function avoids catastrophic cancellation for large positive *z*. .. function:: void _acb_hypgeom_erfc_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_erfc_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the complementary error function of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_erfi(acb_t res, const acb_t z, slong prec) Computes the imaginary error function `\operatorname{erfi}(z) = -i\operatorname{erf}(iz)`. This is a trivial wrapper of :func:`acb_hypgeom_erf`. .. function:: void _acb_hypgeom_erfi_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_erfi_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the imaginary error function of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_fresnel(acb_t res1, acb_t res2, const acb_t z, int normalized, slong prec) Sets *res1* to the Fresnel sine integral `S(z)` and *res2* to the Fresnel cosine integral `C(z)`. Optionally, just a single function can be computed by passing *NULL* as the other output variable. The definition `S(z) = \int_0^z \sin(t^2) dt` is used if *normalized* is 0, and `S(z) = \int_0^z \sin(\tfrac{1}{2} \pi t^2) dt` is used if *normalized* is 1 (the latter is the Abramowitz & Stegun convention). `C(z)` is defined analogously. .. function:: void _acb_hypgeom_fresnel_series(acb_ptr res1, acb_ptr res2, acb_srcptr z, slong zlen, int normalized, slong len, slong prec) .. function:: void acb_hypgeom_fresnel_series(acb_poly_t res1, acb_poly_t res2, const acb_poly_t z, int normalized, slong len, slong prec) Sets *res1* to the Fresnel sine integral and *res2* to the Fresnel cosine integral of the power series *z*, truncated to length *len*. Optionally, just a single function can be computed by passing *NULL* as the other output variable. Bessel functions ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_bessel_j_asymp(acb_t res, const acb_t nu, const acb_t z, slong prec) Computes the Bessel function of the first kind via :func:`acb_hypgeom_u_asymp`. For all complex `\nu, z`, we have .. math :: J_{\nu}(z) = \frac{z^{\nu}}{2^{\nu} e^{iz} \Gamma(\nu+1)} {}_1F_1(\nu+\tfrac{1}{2}, 2\nu+1, 2iz) = A_{+} B_{+} + A_{-} B_{-} where .. math :: A_{\pm} = z^{\nu} (z^2)^{-\tfrac{1}{2}-\nu} (\mp i z)^{\tfrac{1}{2}+\nu} (2 \pi)^{-1/2} = (\pm iz)^{-1/2-\nu} z^{\nu} (2 \pi)^{-1/2} .. math :: B_{\pm} = e^{\pm i z} U^{*}(\nu+\tfrac{1}{2}, 2\nu+1, \mp 2iz). Nicer representations of the factors `A_{\pm}` can be given depending conditionally on the parameters. If `\nu + \tfrac{1}{2} = n \in \mathbb{Z}`, we have `A_{\pm} = (\pm i)^{n} (2 \pi z)^{-1/2}`. And if `\operatorname{Re}(z) > 0`, we have `A_{\pm} = \exp(\mp i [(2\nu+1)/4] \pi) (2 \pi z)^{-1/2}`. .. function:: void acb_hypgeom_bessel_j_0f1(acb_t res, const acb_t nu, const acb_t z, slong prec) Computes the Bessel function of the first kind from .. math :: J_{\nu}(z) = \frac{1}{\Gamma(\nu+1)} \left(\frac{z}{2}\right)^{\nu} {}_0F_1\left(\nu+1, -\frac{z^2}{4}\right). .. function:: void acb_hypgeom_bessel_j(acb_t res, const acb_t nu, const acb_t z, slong prec) Computes the Bessel function of the first kind `J_{\nu}(z)` using an automatic algorithm choice. .. function:: void acb_hypgeom_bessel_y(acb_t res, const acb_t nu, const acb_t z, slong prec) Computes the Bessel function of the second kind `Y_{\nu}(z)` from the formula .. math :: Y_{\nu}(z) = \frac{\cos(\nu \pi) J_{\nu}(z) - J_{-\nu}(z)}{\sin(\nu \pi)} unless `\nu = n` is an integer in which case the limit value .. math :: Y_n(z) = -\frac{2}{\pi} \left( i^n K_n(iz) + \left[\log(iz)-\log(z)\right] J_n(z) \right) is computed. As currently implemented, the output is indeterminate if `\nu` is nonexact and contains an integer. .. function:: void acb_hypgeom_bessel_jy(acb_t res1, acb_t res2, const acb_t nu, const acb_t z, slong prec) Sets *res1* to `J_{\nu}(z)` and *res2* to `Y_{\nu}(z)`, computed simultaneously. From these values, the user can easily construct the Bessel functions of the third kind (Hankel functions) `H_{\nu}^{(1)}(z), H_{\nu}^{(2)}(z) = J_{\nu}(z) \pm i Y_{\nu}(z)`. Modified Bessel functions ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_bessel_i_asymp(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) .. function:: void acb_hypgeom_bessel_i_0f1(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) .. function:: void acb_hypgeom_bessel_i(acb_t res, const acb_t nu, const acb_t z, slong prec) .. function:: void acb_hypgeom_bessel_i_scaled(acb_t res, const acb_t nu, const acb_t z, slong prec) Computes the modified Bessel function of the first kind `I_{\nu}(z) = z^{\nu} (iz)^{-\nu} J_{\nu}(iz)` respectively using asymptotic series (see :func:`acb_hypgeom_bessel_j_asymp`), the convergent series .. math :: I_{\nu}(z) = \frac{1}{\Gamma(\nu+1)} \left(\frac{z}{2}\right)^{\nu} {}_0F_1\left(\nu+1, \frac{z^2}{4}\right), or an automatic algorithm choice. The *scaled* version computes the function `e^{-z} I_{\nu}(z)`. The *asymp* and *0f1* functions implement both variants and allow choosing with a flag. .. function:: void acb_hypgeom_bessel_k_asymp(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) Computes the modified Bessel function of the second kind via via :func:`acb_hypgeom_u_asymp`. For all `\nu` and all `z \ne 0`, we have .. math :: K_{\nu}(z) = \left(\frac{2z}{\pi}\right)^{-1/2} e^{-z} U^{*}(\nu+\tfrac{1}{2}, 2\nu+1, 2z). If *scaled* is set, computes the function `e^{z} K_{\nu}(z)`. .. function:: void acb_hypgeom_bessel_k_0f1_series(acb_poly_t res, const acb_poly_t nu, const acb_poly_t z, int scaled, slong len, slong prec) Computes the modified Bessel function of the second kind `K_{\nu}(z)` as a power series truncated to length *len*, given `\nu, z \in \mathbb{C}[[x]]`. Uses the formula .. math :: K_{\nu}(z) = \frac{1}{2} \frac{\pi}{\sin(\pi \nu)} \left[ \left(\frac{z}{2}\right)^{-\nu} {}_0{\widetilde F}_1\left(1-\nu, \frac{z^2}{4}\right) - \left(\frac{z}{2}\right)^{\nu} {}_0{\widetilde F}_1\left(1+\nu, \frac{z^2}{4}\right) \right]. If `\nu[0] \in \mathbb{Z}`, it computes one extra derivative and removes the singularity (it is then assumed that `\nu[1] \ne 0`). As currently implemented, the output is indeterminate if `\nu[0]` is nonexact and contains an integer. If *scaled* is set, computes the function `e^{z} K_{\nu}(z)`. .. function:: void acb_hypgeom_bessel_k_0f1(acb_t res, const acb_t nu, const acb_t z, int scaled, slong prec) Computes the modified Bessel function of the second kind from .. math :: K_{\nu}(z) = \frac{1}{2} \left[ \left(\frac{z}{2}\right)^{-\nu} \Gamma(\nu) {}_0F_1\left(1-\nu, \frac{z^2}{4}\right) - \left(\frac{z}{2}\right)^{\nu} \frac{\pi}{\nu \sin(\pi \nu) \Gamma(\nu)} {}_0F_1\left(\nu+1, \frac{z^2}{4}\right) \right] if `\nu \notin \mathbb{Z}`. If `\nu \in \mathbb{Z}`, it computes the limit value via :func:`acb_hypgeom_bessel_k_0f1_series`. As currently implemented, the output is indeterminate if `\nu` is nonexact and contains an integer. If *scaled* is set, computes the function `e^{z} K_{\nu}(z)`. .. function:: void acb_hypgeom_bessel_k(acb_t res, const acb_t nu, const acb_t z, slong prec) Computes the modified Bessel function of the second kind `K_{\nu}(z)` using an automatic algorithm choice. .. function:: void acb_hypgeom_bessel_k_scaled(acb_t res, const acb_t nu, const acb_t z, slong prec) Computes the function `e^{z} K_{\nu}(z)`. Airy functions ------------------------------------------------------------------------------- The Airy functions are linearly independent solutions of the differential equation `y'' - zy = 0`. All solutions are entire functions. The standard solutions are denoted `\operatorname{Ai}(z), \operatorname{Bi}(z)`. For negative *z*, both functions are oscillatory. For positive *z*, the first function decreases exponentially while the second increases exponentially. The Airy functions can be expressed in terms of Bessel functions of fractional order, but this is inconvenient since such formulas only hold piecewise (due to the Stokes phenomenon). Computation of the Airy functions can also be optimized more than Bessel functions in general. We therefore provide a dedicated interface for evaluating Airy functions. The following methods optionally compute `(\operatorname{Ai}(z), \operatorname{Ai}'(z), \operatorname{Bi}(z), \operatorname{Bi}'(z))` simultaneously. Any of the four function values can be omitted by passing *NULL* for the unwanted output variables, speeding up the evaluation. .. function:: void acb_hypgeom_airy_direct(acb_t ai, acb_t ai_prime, acb_t bi, acb_t bi_prime, const acb_t z, slong n, slong prec) Computes the Airy functions using direct series expansions truncated at *n* terms. Error bounds are included in the output. .. function:: void acb_hypgeom_airy_asymp(acb_t ai, acb_t ai_prime, acb_t bi, acb_t bi_prime, const acb_t z, slong n, slong prec) Computes the Airy functions using asymptotic expansions truncated at *n* terms. Error bounds are included in the output. For details about how the error bounds are computed, see :ref:`algorithms_hypergeometric_asymptotic_airy`. .. function:: void acb_hypgeom_airy_bound(mag_t ai, mag_t ai_prime, mag_t bi, mag_t bi_prime, const acb_t z) Computes bounds for the Airy functions using first-order asymptotic expansions together with error bounds. This function uses some shortcuts to make it slightly faster than calling :func:`acb_hypgeom_airy_asymp` with `n = 1`. .. function:: void acb_hypgeom_airy(acb_t ai, acb_t ai_prime, acb_t bi, acb_t bi_prime, const acb_t z, slong prec) Computes Airy functions using an automatic algorithm choice. We use :func:`acb_hypgeom_airy_asymp` whenever this gives full accuracy and :func:`acb_hypgeom_airy_direct` otherwise. In the latter case, we first use hardware double precision arithmetic to determine an accurate estimate of the working precision needed to compute the Airy functions accurately for given *z*. This estimate is obtained by comparing the leading-order asymptotic estimate of the Airy functions with the magnitude of the largest term in the power series. The estimate is generic in the sense that it does not take into account vanishing near the roots of the functions. We subsequently evaluate the power series at the midpoint of *z* and bound the propagated error using derivatives. Derivatives are bounded using :func:`acb_hypgeom_airy_bound`. .. function:: void acb_hypgeom_airy_jet(acb_ptr ai, acb_ptr bi, const acb_t z, slong len, slong prec) Writes to *ai* and *bi* the respective Taylor expansions of the Airy functions at the point *z*, truncated to length *len*. Either of the outputs can be *NULL* to avoid computing that function. The variable *z* is not allowed to be aliased with the outputs. To simplify the implementation, this method does not compute the series expansions of the primed versions directly; these are easily obtained by computing one extra coefficient and differentiating the output with :func:`_acb_poly_derivative`. .. function:: void _acb_hypgeom_airy_series(acb_ptr ai, acb_ptr ai_prime, acb_ptr bi, acb_ptr bi_prime, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_airy_series(acb_poly_t ai, acb_poly_t ai_prime, acb_poly_t bi, acb_poly_t bi_prime, const acb_poly_t z, slong len, slong prec) Computes the Airy functions evaluated at the power series *z*, truncated to length *len*. As with the other Airy methods, any of the outputs can be *NULL*. Coulomb wave functions ------------------------------------------------------------------------------- Coulomb wave functions are solutions of the Coulomb wave equation .. math :: y'' + \left(1 - \frac{2 \eta}{z} - \frac{\ell(\ell+1)}{z^2}\right) y = 0 which is the radial Schrödinger equation for a charged particle in a Coulomb potential `1/z`, where `\ell` is the orbital angular momentum and `\eta` is the Sommerfeld parameter. The standard solutions are named `F_{\ell}(\eta,z)` (regular at the origin `z = 0`) and `G_{\ell}(\eta,z)` (irregular at the origin). The irregular solutions `H^{\pm}_{\ell}(\eta,z) = G_{\ell}(\eta,z) \pm i F_{\ell}(\eta,z)` are also used. Coulomb wave functions are special cases of confluent hypergeometric functions. The normalization constants and connection formulas are discussed in [DYF1999]_, [Gas2018]_, [Mic2007]_ and chapter 33 in [NIST2012]_. In this implementation, we define the analytic continuations of all the functions so that the branch cut with respect to *z* is placed on the negative real axis. Precise definitions are given in http://fungrim.org/topic/Coulomb_wave_functions/ The following methods optionally compute `F_{\ell}(\eta,z), G_{\ell}(\eta,z), H^{+}_{\ell}(\eta,z), H^{-}_{\ell}(\eta,z)` simultaneously. Any of the four function values can be omitted by passing *NULL* for the unwanted output variables. The redundant functions `H^{\pm}` are provided explicitly since taking the linear combination of *F* and *G* suffers from cancellation in parts of the complex plane. .. function:: void acb_hypgeom_coulomb(acb_t F, acb_t G, acb_t Hpos, acb_t Hneg, const acb_t l, const acb_t eta, const acb_t z, slong prec) Writes to *F*, *G*, *Hpos*, *Hneg* the values of the respective Coulomb wave functions. Any of the outputs can be *NULL*. .. function:: void acb_hypgeom_coulomb_jet(acb_ptr F, acb_ptr G, acb_ptr Hpos, acb_ptr Hneg, const acb_t l, const acb_t eta, const acb_t z, slong len, slong prec) Writes to *F*, *G*, *Hpos*, *Hneg* the respective Taylor expansions of the Coulomb wave functions at the point *z*, truncated to length *len*. Any of the outputs can be *NULL*. .. function:: void _acb_hypgeom_coulomb_series(acb_ptr F, acb_ptr G, acb_ptr Hpos, acb_ptr Hneg, const acb_t l, const acb_t eta, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_coulomb_series(acb_poly_t F, acb_poly_t G, acb_poly_t Hpos, acb_poly_t Hneg, const acb_t l, const acb_t eta, const acb_poly_t z, slong len, slong prec) Computes the Coulomb wave functions evaluated at the power series *z*, truncated to length *len*. Any of the outputs can be *NULL*. Incomplete gamma and beta functions ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_gamma_upper_asymp(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_gamma_upper_1f1a(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_gamma_upper_1f1b(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_gamma_upper_singular(acb_t res, slong s, const acb_t z, int regularized, slong prec) .. function:: void acb_hypgeom_gamma_upper(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) If *regularized* is 0, computes the upper incomplete gamma function `\Gamma(s,z)`. If *regularized* is 1, computes the regularized upper incomplete gamma function `Q(s,z) = \Gamma(s,z) / \Gamma(s)`. If *regularized* is 2, computes the generalized exponential integral `z^{-s} \Gamma(s,z) = E_{1-s}(z)` instead (this option is mainly intended for internal use; :func:`acb_hypgeom_expint` is the intended interface for computing the exponential integral). The different methods respectively implement the formulas .. math :: \Gamma(s,z) = e^{-z} U(1-s,1-s,z) .. math :: \Gamma(s,z) = \Gamma(s) - \frac{z^s}{s} {}_1F_1(s, s+1, -z) .. math :: \Gamma(s,z) = \Gamma(s) - \frac{z^s e^{-z}}{s} {}_1F_1(1, s+1, z) .. math :: \Gamma(s,z) = \frac{(-1)^n}{n!} (\psi(n+1) - \log(z)) + \frac{(-1)^n}{(n+1)!} z \, {}_2F_2(1,1,2,2+n,-z) - z^{-n} \sum_{k=0}^{n-1} \frac{(-z)^k}{(k-n) k!}, \quad n = -s \in \mathbb{Z}_{\ge 0} and an automatic algorithm choice. The automatic version also handles other special input such as `z = 0` and `s = 1, 2, 3`. The *singular* version evaluates the finite sum directly and therefore assumes that *s* is not too large. .. function:: void _acb_hypgeom_gamma_upper_series(acb_ptr res, const acb_t s, acb_srcptr z, slong zlen, int regularized, slong n, slong prec) .. function:: void acb_hypgeom_gamma_upper_series(acb_poly_t res, const acb_t s, const acb_poly_t z, int regularized, slong n, slong prec) Sets *res* to an upper incomplete gamma function where *s* is a constant and *z* is a power series, truncated to length *n*. The *regularized* argument has the same interpretation as in :func:`acb_hypgeom_gamma_upper`. .. function:: void acb_hypgeom_gamma_lower(acb_t res, const acb_t s, const acb_t z, int regularized, slong prec) If *regularized* is 0, computes the lower incomplete gamma function `\gamma(s,z) = \frac{z^s}{s} {}_1F_1(s, s+1, -z)`. If *regularized* is 1, computes the regularized lower incomplete gamma function `P(s,z) = \gamma(s,z) / \Gamma(s)`. If *regularized* is 2, computes a further regularized lower incomplete gamma function `\gamma^{*}(s,z) = z^{-s} P(s,z)`. .. function:: void _acb_hypgeom_gamma_lower_series(acb_ptr res, const acb_t s, acb_srcptr z, slong zlen, int regularized, slong n, slong prec) .. function:: void acb_hypgeom_gamma_lower_series(acb_poly_t res, const acb_t s, const acb_poly_t z, int regularized, slong n, slong prec) Sets *res* to an lower incomplete gamma function where *s* is a constant and *z* is a power series, truncated to length *n*. The *regularized* argument has the same interpretation as in :func:`acb_hypgeom_gamma_lower`. .. function:: void acb_hypgeom_beta_lower(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) Computes the (lower) incomplete beta function, defined by `B(a,b;z) = \int_0^z t^{a-1} (1-t)^{b-1}`, optionally the regularized incomplete beta function `I(a,b;z) = B(a,b;z) / B(a,b;1)`. In general, the integral must be interpreted using analytic continuation. The precise definitions for all parameter values are .. math :: B(a,b;z) = \frac{z^a}{a} {}_2F_1(a, 1-b, a+1, z) .. math :: I(a,b;z) = \frac{\Gamma(a+b)}{\Gamma(b)} z^a {}_2{\widetilde F}_1(a, 1-b, a+1, z). Note that both functions with this definition are undefined for nonpositive integer *a*, and *I* is undefined for nonpositive integer `a + b`. .. function:: void _acb_hypgeom_beta_lower_series(acb_ptr res, const acb_t a, const acb_t b, acb_srcptr z, slong zlen, int regularized, slong n, slong prec) .. function:: void acb_hypgeom_beta_lower_series(acb_poly_t res, const acb_t a, const acb_t b, const acb_poly_t z, int regularized, slong n, slong prec) Sets *res* to the lower incomplete beta function `B(a,b;z)` (optionally the regularized version `I(a,b;z)`) where *a* and *b* are constants and *z* is a power series, truncating the result to length *n*. The underscore method requires positive lengths and does not support aliasing. Exponential and trigonometric integrals ------------------------------------------------------------------------------- The branch cut conventions of the following functions match Mathematica. .. function:: void acb_hypgeom_expint(acb_t res, const acb_t s, const acb_t z, slong prec) Computes the generalized exponential integral `E_s(z)`. This is a trivial wrapper of :func:`acb_hypgeom_gamma_upper`. .. function:: void acb_hypgeom_ei_asymp(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_ei_2f2(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_ei(acb_t res, const acb_t z, slong prec) Computes the exponential integral `\operatorname{Ei}(z)`, respectively using .. math :: \operatorname{Ei}(z) = -e^z U(1,1,-z) - \log(-z) + \frac{1}{2} \left(\log(z) - \log\left(\frac{1}{z}\right) \right) .. math :: \operatorname{Ei}(z) = z {}_2F_2(1, 1; 2, 2; z) + \gamma + \frac{1}{2} \left(\log(z) - \log\left(\frac{1}{z}\right) \right) and an automatic algorithm choice. .. function:: void _acb_hypgeom_ei_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_ei_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the exponential integral of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_si_asymp(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_si_1f2(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_si(acb_t res, const acb_t z, slong prec) Computes the sine integral `\operatorname{Si}(z)`, respectively using .. math :: \operatorname{Si}(z) = \frac{i}{2} \left[ e^{iz} U(1,1,-iz) - e^{-iz} U(1,1,iz) + \log(-iz) - \log(iz) \right] .. math :: \operatorname{Si}(z) = z {}_1F_2(\tfrac{1}{2}; \tfrac{3}{2}, \tfrac{3}{2}; -\tfrac{z^2}{4}) and an automatic algorithm choice. .. function:: void _acb_hypgeom_si_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_si_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the sine integral of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_ci_asymp(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_ci_2f3(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_ci(acb_t res, const acb_t z, slong prec) Computes the cosine integral `\operatorname{Ci}(z)`, respectively using .. math :: \operatorname{Ci}(z) = \log(z) - \frac{1}{2} \left[ e^{iz} U(1,1,-iz) + e^{-iz} U(1,1,iz) + \log(-iz) + \log(iz) \right] .. math :: \operatorname{Ci}(z) = -\tfrac{z^2}{4} {}_2F_3(1, 1; 2, 2, \tfrac{3}{2}; -\tfrac{z^2}{4}) + \log(z) + \gamma and an automatic algorithm choice. .. function:: void _acb_hypgeom_ci_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_ci_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the cosine integral of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_shi(acb_t res, const acb_t z, slong prec) Computes the hyperbolic sine integral `\operatorname{Shi}(z) = -i \operatorname{Si}(iz)`. This is a trivial wrapper of :func:`acb_hypgeom_si`. .. function:: void _acb_hypgeom_shi_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_shi_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the hyperbolic sine integral of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_chi_asymp(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_chi_2f3(acb_t res, const acb_t z, slong prec) .. function:: void acb_hypgeom_chi(acb_t res, const acb_t z, slong prec) Computes the hyperbolic cosine integral `\operatorname{Chi}(z)`, respectively using .. math :: \operatorname{Chi}(z) = -\frac{1}{2} \left[ e^{z} U(1,1,-z) + e^{-z} U(1,1,z) + \log(-z) - \log(z) \right] .. math :: \operatorname{Chi}(z) = \tfrac{z^2}{4} {}_2F_3(1, 1; 2, 2, \tfrac{3}{2}; \tfrac{z^2}{4}) + \log(z) + \gamma and an automatic algorithm choice. .. function:: void _acb_hypgeom_chi_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_hypgeom_chi_series(acb_poly_t res, const acb_poly_t z, slong len, slong prec) Computes the hyperbolic cosine integral of the power series *z*, truncated to length *len*. .. function:: void acb_hypgeom_li(acb_t res, const acb_t z, int offset, slong prec) If *offset* is zero, computes the logarithmic integral `\operatorname{li}(z) = \operatorname{Ei}(\log(z))`. If *offset* is nonzero, computes the offset logarithmic integral `\operatorname{Li}(z) = \operatorname{li}(z) - \operatorname{li}(2)`. .. function:: void _acb_hypgeom_li_series(acb_ptr res, acb_srcptr z, slong zlen, int offset, slong len, slong prec) .. function:: void acb_hypgeom_li_series(acb_poly_t res, const acb_poly_t z, int offset, slong len, slong prec) Computes the logarithmic integral (optionally the offset version) of the power series *z*, truncated to length *len*. Gauss hypergeometric function ------------------------------------------------------------------------------- The following methods compute the Gauss hypergeometric function .. math :: F(z) = {}_2F_1(a,b,c,z) = \sum_{k=0}^{\infty} \frac{(a)_k (b)_k}{(c)_k} \frac{z^k}{k!} or the regularized version `\operatorname{\mathbf{F}}(z) = \operatorname{\mathbf{F}}(a,b,c,z) = {}_2F_1(a,b,c,z) / \Gamma(c)` if the flag *regularized* is set. .. function:: void acb_hypgeom_2f1_continuation(acb_t res0, acb_t res1, const acb_t a, const acb_t b, const acb_t c, const acb_t z0, const acb_t z1, const acb_t f0, const acb_t f1, slong prec) Given `F(z_0), F'(z_0)` in *f0*, *f1*, sets *res0* and *res1* to `F(z_1), F'(z_1)` by integrating the hypergeometric differential equation along a straight-line path. The evaluation points should be well-isolated from the singular points 0 and 1. .. function:: void acb_hypgeom_2f1_series_direct(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t c, const acb_poly_t z, int regularized, slong len, slong prec) Computes `F(z)` of the given power series truncated to length *len*, using direct summation of the hypergeometric series. .. function:: void acb_hypgeom_2f1_direct(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, slong prec) Computes `F(z)` using direct summation of the hypergeometric series. .. function:: void acb_hypgeom_2f1_transform(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int flags, int which, slong prec) .. function:: void acb_hypgeom_2f1_transform_limit(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec) Computes `F(z)` using an argument transformation determined by the flag *which*. Legal values are 1 for `z/(z-1)`, 2 for `1/z`, 3 for `1/(1-z)`, 4 for `1-z`, and 5 for `1-1/z`. The *transform_limit* version assumes that *which* is not 1. If *which* is 2 or 3, it assumes that `b-a` represents an exact integer. If *which* is 4 or 5, it assumes that `c-a-b` represents an exact integer. In these cases, it computes the correct limit value. See :func:`acb_hypgeom_2f1` for the meaning of *flags*. .. function:: void acb_hypgeom_2f1_corner(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, slong prec) Computes `F(z)` near the corner cases `\exp(\pm \pi i \sqrt{3})` by analytic continuation. .. function:: int acb_hypgeom_2f1_choose(const acb_t z) Chooses a method to compute the function based on the location of *z* in the complex plane. If the return value is 0, direct summation should be used. If the return value is 1 to 5, the transformation with this index in :func:`acb_hypgeom_2f1_transform` should be used. If the return value is 6, the corner case algorithm should be used. .. function:: void acb_hypgeom_2f1(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int flags, slong prec) Computes `F(z)` or `\operatorname{\mathbf{F}}(z)` using an automatic algorithm choice. The following bit fields can be set in *flags*: - *ACB_HYPGEOM_2F1_REGULARIZED* - computes the regularized hypergeometric function `\operatorname{\mathbf{F}}(z)`. Setting *flags* to 1 is the same as just toggling this option. - *ACB_HYPGEOM_2F1_AB* - `a-b` is an integer. - *ACB_HYPGEOM_2F1_ABC* - `a+b-c` is an integer. - *ACB_HYPGEOM_2F1_AC* - `a-c` is an integer. - *ACB_HYPGEOM_2F1_BC* - `b-c` is an integer. The last four flags can be set to indicate that the respective parameter differences are known to represent exact integers, even if the input intervals are inexact. This allows the correct limits to be evaluated when applying transformation formulas. For example, to evaluate `{}_2F_1(\sqrt{2}, 1/2, \sqrt{2}+3/2, 9/10)`, the *ABC* flag should be set. If not set, the result will be an indeterminate interval due to internally dividing by an interval containing zero. If the parameters are exact floating-point numbers (including exact integers or half-integers), then the limits are computed automatically, and setting these flags is unnecessary. Currently, only the *AB* and *ABC* flags are used this way; the *AC* and *BC* flags might be used in the future. Orthogonal polynomials and functions ------------------------------------------------------------------------------- .. function:: void acb_hypgeom_chebyshev_t(acb_t res, const acb_t n, const acb_t z, slong prec) .. function:: void acb_hypgeom_chebyshev_u(acb_t res, const acb_t n, const acb_t z, slong prec) Computes the Chebyshev polynomial (or Chebyshev function) of first or second kind .. math :: T_n(z) = {}_2F_1\left(-n,n,\frac{1}{2},\frac{1-z}{2}\right) .. math :: U_n(z) = (n+1) {}_2F_1\left(-n,n+2,\frac{3}{2},\frac{1-z}{2}\right). The hypergeometric series definitions are only used for computation near the point 1. In general, trigonometric representations are used. For word-size integer *n*, :func:`acb_chebyshev_t_ui` and :func:`acb_chebyshev_u_ui` are called. .. function:: void acb_hypgeom_jacobi_p(acb_t res, const acb_t n, const acb_t a, const acb_t b, const acb_t z, slong prec) Computes the Jacobi polynomial (or Jacobi function) .. math :: P_n^{(a,b)}(z)=\frac{(a+1)_n}{\Gamma(n+1)} {}_2F_1\left(-n,n+a+b+1,a+1,\frac{1-z}{2}\right). For nonnegative integer *n*, this is a polynomial in *a*, *b* and *z*, even when the parameters are such that the hypergeometric series is undefined. In such cases, the polynomial is evaluated using direct methods. .. function:: void acb_hypgeom_gegenbauer_c(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) Computes the Gegenbauer polynomial (or Gegenbauer function) .. math :: C_n^{m}(z)=\frac{(2m)_n}{\Gamma(n+1)} {}_2F_1\left(-n,2m+n,m+\frac{1}{2},\frac{1-z}{2}\right). For nonnegative integer *n*, this is a polynomial in *m* and *z*, even when the parameters are such that the hypergeometric series is undefined. In such cases, the polynomial is evaluated using direct methods. .. function:: void acb_hypgeom_laguerre_l(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) Computes the Laguerre polynomial (or Laguerre function) .. math :: L_n^{m}(z)=\frac{(m+1)_n}{\Gamma(n+1)} {}_1F_1\left(-n,m+1,z\right). For nonnegative integer *n*, this is a polynomial in *m* and *z*, even when the parameters are such that the hypergeometric series is undefined. In such cases, the polynomial is evaluated using direct methods. There are at least two incompatible ways to define the Laguerre function when *n* is a negative integer. One possibility when `m = 0` is to define `L_{-n}^0(z) = e^z L_{n-1}^0(-z)`. Another possibility is to cover this case with the recurrence relation `L_{n-1}^m(z) + L_n^{m-1}(z) = L_n^m(z)`. Currently, we leave this case undefined (returning indeterminate). .. function:: void acb_hypgeom_hermite_h(acb_t res, const acb_t n, const acb_t z, slong prec) Computes the Hermite polynomial (or Hermite function) .. math :: H_n(z) = 2^n \sqrt{\pi} \left( \frac{1}{\Gamma((1-n)/2)} {}_1F_1\left(-\frac{n}{2},\frac{1}{2},z^2\right) - \frac{2z}{\Gamma(-n/2)} {}_1F_1\left(\frac{1-n}{2},\frac{3}{2},z^2\right)\right). .. function:: void acb_hypgeom_legendre_p(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec) Sets *res* to the associated Legendre function of the first kind evaluated for degree *n*, order *m*, and argument *z*. When *m* is zero, this reduces to the Legendre polynomial `P_n(z)`. Many different branch cut conventions appear in the literature. If *type* is 0, the version .. math :: P_n^m(z) = \frac{(1+z)^{m/2}}{(1-z)^{m/2}} \mathbf{F}\left(-n, n+1, 1-m, \frac{1-z}{2}\right) is computed, and if *type* is 1, the alternative version .. math :: {\mathcal P}_n^m(z) = \frac{(z+1)^{m/2}}{(z-1)^{m/2}} \mathbf{F}\left(-n, n+1, 1-m, \frac{1-z}{2}\right). is computed. Type 0 and type 1 respectively correspond to type 2 and type 3 in *Mathematica* and *mpmath*. .. function:: void acb_hypgeom_legendre_q(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec) Sets *res* to the associated Legendre function of the second kind evaluated for degree *n*, order *m*, and argument *z*. When *m* is zero, this reduces to the Legendre function `Q_n(z)`. Many different branch cut conventions appear in the literature. If *type* is 0, the version .. math :: Q_n^m(z) = \frac{\pi}{2 \sin(\pi m)} \left( \cos(\pi m) P_n^m(z) - \frac{\Gamma(1+m+n)}{\Gamma(1-m+n)} P_n^{-m}(z)\right) is computed, and if *type* is 1, the alternative version .. math :: \mathcal{Q}_n^m(z) = \frac{\pi}{2 \sin(\pi m)} e^{\pi i m} \left( \mathcal{P}_n^m(z) - \frac{\Gamma(1+m+n)}{\Gamma(1-m+n)} \mathcal{P}_n^{-m}(z)\right) is computed. Type 0 and type 1 respectively correspond to type 2 and type 3 in *Mathematica* and *mpmath*. When *m* is an integer, either expression is interpreted as a limit. We make use of the connection formulas [WQ3a]_, [WQ3b]_ and [WQ3c]_ to allow computing the function even in the limiting case. (The formula [WQ3d]_ would be useful, but is incorrect in the lower half plane.) .. [WQ3a] http://functions.wolfram.com/07.11.26.0033.01 .. [WQ3b] http://functions.wolfram.com/07.12.27.0014.01 .. [WQ3c] http://functions.wolfram.com/07.12.26.0003.01 .. [WQ3d] http://functions.wolfram.com/07.12.26.0088.01 .. function:: void acb_hypgeom_legendre_p_uiui_rec(acb_t res, ulong n, ulong m, const acb_t z, slong prec) For nonnegative integer *n* and *m*, uses recurrence relations to evaluate `(1-z^2)^{-m/2} P_n^m(z)` which is a polynomial in *z*. .. function:: void acb_hypgeom_spherical_y(acb_t res, slong n, slong m, const acb_t theta, const acb_t phi, slong prec) Computes the spherical harmonic of degree *n*, order *m*, latitude angle *theta*, and longitude angle *phi*, normalized such that .. math :: Y_n^m(\theta, \phi) = \sqrt{\frac{2n+1}{4\pi} \frac{(n-m)!}{(n+m)!}} e^{im\phi} P_n^m(\cos(\theta)). The definition is extended to negative *m* and *n* by symmetry. This function is a polynomial in `\cos(\theta)` and `\sin(\theta)`. We evaluate it using :func:`acb_hypgeom_legendre_p_uiui_rec`. Dilogarithm ------------------------------------------------------------------------------- The dilogarithm function is given by `\operatorname{Li}_2(z) = -\int_0^z \frac{\log(1-t)}{t} dt = z {}_3F_2(1,1,1,2,2,z)`. .. function :: void acb_hypgeom_dilog_bernoulli(acb_t res, const acb_t z, slong prec) Computes the dilogarithm using a series expansion in `w = \log(z)`, with rate of convergence `|w/(2\pi)|^n`. This provides good convergence near `z = e^{\pm i \pi / 3}`, where hypergeometric series expansions fail. Since the coefficients involve Bernoulli numbers, this method should only be used at moderate precision. .. function:: void acb_hypgeom_dilog_zero_taylor(acb_t res, const acb_t z, slong prec) Computes the dilogarithm for *z* close to 0 using the hypergeometric series (effective only when `|z| \ll 1`). .. function:: void acb_hypgeom_dilog_zero(acb_t res, const acb_t z, slong prec) Computes the dilogarithm for *z* close to 0, using the bit-burst algorithm instead of the hypergeometric series directly at very high precision. .. function:: void acb_hypgeom_dilog_transform(acb_t res, const acb_t z, int algorithm, slong prec) Computes the dilogarithm by applying one of the transformations `1/z`, `1-z`, `z/(z-1)`, `1/(1-z)`, indexed by *algorithm* from 1 to 4, and calling :func:`acb_hypgeom_dilog_zero` with the reduced variable. Alternatively, for *algorithm* between 5 and 7, starts from the respective point `\pm i`, `(1\pm i)/2`, `(1\pm i)/2` (with the sign chosen according to the midpoint of *z*) and computes the dilogarithm by the bit-burst method. .. function:: void acb_hypgeom_dilog_continuation(acb_t res, const acb_t a, const acb_t z, slong prec) Computes `\operatorname{Li}_2(z) - \operatorname{Li}_2(a)` using Taylor expansion at *a*. Binary splitting is used. Both *a* and *z* should be well isolated from the points 0 and 1, except that *a* may be exactly 0. If the straight line path from *a* to *b* crosses the branch cut, this method provides continuous analytic continuation instead of computing the principal branch. .. function:: void acb_hypgeom_dilog_bitburst(acb_t res, acb_t z0, const acb_t z, slong prec) Sets *z0* to a point with short bit expansion close to *z* and sets *res* to `\operatorname{Li}_2(z) - \operatorname{Li}_2(z_0)`, computed using the bit-burst algorithm. .. function:: void acb_hypgeom_dilog(acb_t res, const acb_t z, slong prec) Computes the dilogarithm using a default algorithm choice. arb-2.22.1/doc/source/acb_mat.rst000066400000000000000000001042271417376376500165600ustar00rootroot00000000000000.. _acb-mat: **acb_mat.h** -- matrices over the complex numbers =============================================================================== An :type:`acb_mat_t` represents a dense matrix over the complex numbers, implemented as an array of entries of type :type:`acb_struct`. The dimension (number of rows and columns) of a matrix is fixed at initialization, and the user must ensure that inputs and outputs to an operation have compatible dimensions. The number of rows or columns in a matrix can be zero. .. note:: Methods prefixed with *acb_mat_approx* treat all input entries as floating-point numbers (ignoring the radii of the balls) and compute floating-point output (balls with zero radius) representing approximate solutions *without error bounds*. All other methods compute rigorous error bounds. The *approx* methods are typically useful for computing initial values or preconditioners for rigorous solvers. Some users may also find *approx* methods useful for doing ordinary numerical linear algebra in applications where error bounds are not needed. Types, macros and constants ------------------------------------------------------------------------------- .. type:: acb_mat_struct .. type:: acb_mat_t Contains a pointer to a flat array of the entries (entries), an array of pointers to the start of each row (rows), and the number of rows (r) and columns (c). An *acb_mat_t* is defined as an array of length one of type *acb_mat_struct*, permitting an *acb_mat_t* to be passed by reference. .. macro:: acb_mat_entry(mat, i, j) Macro giving a pointer to the entry at row *i* and column *j*. .. macro:: acb_mat_nrows(mat) Returns the number of rows of the matrix. .. macro:: acb_mat_ncols(mat) Returns the number of columns of the matrix. Memory management ------------------------------------------------------------------------------- .. function:: void acb_mat_init(acb_mat_t mat, slong r, slong c) Initializes the matrix, setting it to the zero matrix with *r* rows and *c* columns. .. function:: void acb_mat_clear(acb_mat_t mat) Clears the matrix, deallocating all entries. .. function:: slong acb_mat_allocated_bytes(const acb_mat_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(acb_mat_struct)`` to get the size of the object as a whole. .. function:: void acb_mat_window_init(acb_mat_t window, const acb_mat_t mat, slong r1, slong c1, slong r2, slong c2) Initializes *window* to a window matrix into the submatrix of *mat* starting at the corner at row *r1* and column *c1* (inclusive) and ending at row *r2* and column *c2* (exclusive). .. function:: void acb_mat_window_clear(acb_mat_t window) Frees the window matrix. Conversions ------------------------------------------------------------------------------- .. function:: void acb_mat_set(acb_mat_t dest, const acb_mat_t src) .. function:: void acb_mat_set_fmpz_mat(acb_mat_t dest, const fmpz_mat_t src) .. function:: void acb_mat_set_round_fmpz_mat(acb_mat_t dest, const fmpz_mat_t src, slong prec) .. function:: void acb_mat_set_fmpq_mat(acb_mat_t dest, const fmpq_mat_t src, slong prec) .. function:: void acb_mat_set_arb_mat(acb_mat_t dest, const arb_mat_t src) .. function:: void acb_mat_set_round_arb_mat(acb_mat_t dest, const arb_mat_t src, slong prec) Sets *dest* to *src*. The operands must have identical dimensions. Random generation ------------------------------------------------------------------------------- .. function:: void acb_mat_randtest(acb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits) Sets *mat* to a random matrix with up to *prec* bits of precision and with exponents of width up to *mag_bits*. .. function:: void acb_mat_randtest_eig(acb_mat_t mat, flint_rand_t state, acb_srcptr E, slong prec) Sets *mat* to a random matrix with the prescribed eigenvalues supplied as the vector *E*. The output matrix is required to be square. We generate a random unitary matrix via a matrix exponential, and then evaluate an inverse Schur decomposition. Input and output ------------------------------------------------------------------------------- .. function:: void acb_mat_printd(const acb_mat_t mat, slong digits) Prints each entry in the matrix with the specified number of decimal digits. .. function:: void acb_mat_fprintd(FILE * file, const acb_mat_t mat, slong digits) Prints each entry in the matrix with the specified number of decimal digits to the stream *file*. Comparisons ------------------------------------------------------------------------------- Predicate methods return 1 if the property certainly holds and 0 otherwise. .. function:: int acb_mat_equal(const acb_mat_t mat1, const acb_mat_t mat2) Returns whether the matrices have the same dimensions and identical intervals as entries. .. function:: int acb_mat_overlaps(const acb_mat_t mat1, const acb_mat_t mat2) Returns whether the matrices have the same dimensions and each entry in *mat1* overlaps with the corresponding entry in *mat2*. .. function:: int acb_mat_contains(const acb_mat_t mat1, const acb_mat_t mat2) .. function:: int acb_mat_contains_fmpz_mat(const acb_mat_t mat1, const fmpz_mat_t mat2) .. function:: int acb_mat_contains_fmpq_mat(const acb_mat_t mat1, const fmpq_mat_t mat2) Returns whether the matrices have the same dimensions and each entry in *mat2* is contained in the corresponding entry in *mat1*. .. function:: int acb_mat_eq(const acb_mat_t mat1, const acb_mat_t mat2) Returns whether *mat1* and *mat2* certainly represent the same matrix. .. function:: int acb_mat_ne(const acb_mat_t mat1, const acb_mat_t mat2) Returns whether *mat1* and *mat2* certainly do not represent the same matrix. .. function:: int acb_mat_is_real(const acb_mat_t mat) Returns whether all entries in *mat* have zero imaginary part. .. function:: int acb_mat_is_empty(const acb_mat_t mat) Returns whether the number of rows or the number of columns in *mat* is zero. .. function:: int acb_mat_is_square(const acb_mat_t mat) Returns whether the number of rows is equal to the number of columns in *mat*. .. function:: int acb_mat_is_exact(const acb_mat_t mat) Returns whether all entries in *mat* have zero radius. .. function:: int acb_mat_is_zero(const acb_mat_t mat) Returns whether all entries in *mat* are exactly zero. .. function:: int acb_mat_is_finite(const acb_mat_t mat) Returns whether all entries in *mat* are finite. .. function:: int acb_mat_is_triu(const acb_mat_t mat) Returns whether *mat* is upper triangular; that is, all entries below the main diagonal are exactly zero. .. function:: int acb_mat_is_tril(const acb_mat_t mat) Returns whether *mat* is lower triangular; that is, all entries above the main diagonal are exactly zero. .. function:: int acb_mat_is_diag(const acb_mat_t mat) Returns whether *mat* is a diagonal matrix; that is, all entries off the main diagonal are exactly zero. Special matrices ------------------------------------------------------------------------------- .. function:: void acb_mat_zero(acb_mat_t mat) Sets all entries in mat to zero. .. function:: void acb_mat_one(acb_mat_t mat) Sets the entries on the main diagonal to ones, and all other entries to zero. .. function:: void acb_mat_ones(acb_mat_t mat) Sets all entries in the matrix to ones. .. function:: void acb_mat_indeterminate(acb_mat_t mat) Sets all entries in the matrix to indeterminate (NaN). .. function:: void acb_mat_dft(acb_mat_t mat, int type, slong prec) Sets *mat* to the DFT (discrete Fourier transform) matrix of order *n* where *n* is the smallest dimension of *mat* (if *mat* is not square, the matrix is extended periodically along the larger dimension). Here, we use the normalized DFT matrix .. math :: A_{j,k} = \frac{\omega^{jk}}{\sqrt{n}}, \quad \omega = e^{-2\pi i/n}. The *type* parameter is currently ignored and should be set to 0. In the future, it might be used to select a different convention. Transpose ------------------------------------------------------------------------------- .. function:: void acb_mat_transpose(acb_mat_t dest, const acb_mat_t src) Sets *dest* to the exact transpose *src*. The operands must have compatible dimensions. Aliasing is allowed. .. function:: void acb_mat_conjugate_transpose(acb_mat_t dest, const acb_mat_t src) Sets *dest* to the conjugate transpose of *src*. The operands must have compatible dimensions. Aliasing is allowed. .. function:: void acb_mat_conjugate(acb_mat_t dest, const acb_mat_t src) Sets *dest* to the elementwise complex conjugate of *src*. Norms ------------------------------------------------------------------------------- .. function:: void acb_mat_bound_inf_norm(mag_t b, const acb_mat_t A) Sets *b* to an upper bound for the infinity norm (i.e. the largest absolute value row sum) of *A*. .. function:: void acb_mat_frobenius_norm(acb_t res, const acb_mat_t A, slong prec) Sets *res* to the Frobenius norm (i.e. the square root of the sum of squares of entries) of *A*. .. function:: void acb_mat_bound_frobenius_norm(mag_t res, const acb_mat_t A) Sets *res* to an upper bound for the Frobenius norm of *A*. Arithmetic ------------------------------------------------------------------------------- .. function:: void acb_mat_neg(acb_mat_t dest, const acb_mat_t src) Sets *dest* to the exact negation of *src*. The operands must have the same dimensions. .. function:: void acb_mat_add(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) Sets res to the sum of *mat1* and *mat2*. The operands must have the same dimensions. .. function:: void acb_mat_sub(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) Sets *res* to the difference of *mat1* and *mat2*. The operands must have the same dimensions. .. function:: void acb_mat_mul_classical(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) .. function:: void acb_mat_mul_threaded(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) .. function:: void acb_mat_mul_reorder(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) .. function:: void acb_mat_mul(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) Sets *res* to the matrix product of *mat1* and *mat2*. The operands must have compatible dimensions for matrix multiplication. The *classical* version performs matrix multiplication in the trivial way. The *threaded* version performs classical multiplication but splits the computation over the number of threads returned by *flint_get_num_threads()*. The *reorder* version reorders the data and performs one to four real matrix multiplications via :func:`arb_mat_mul`. The default version chooses an algorithm automatically. .. function:: void acb_mat_mul_entrywise(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) Sets *res* to the entrywise product of *mat1* and *mat2*. The operands must have the same dimensions. .. function:: void acb_mat_sqr_classical(acb_mat_t res, const acb_mat_t mat, slong prec) .. function:: void acb_mat_sqr(acb_mat_t res, const acb_mat_t mat, slong prec) Sets *res* to the matrix square of *mat*. The operands must both be square with the same dimensions. .. function:: void acb_mat_pow_ui(acb_mat_t res, const acb_mat_t mat, ulong exp, slong prec) Sets *res* to *mat* raised to the power *exp*. Requires that *mat* is a square matrix. .. function:: void acb_mat_approx_mul(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec) Approximate matrix multiplication. The input radii are ignored and the output matrix is set to an approximate floating-point result. For performance reasons, the radii in the output matrix will *not* necessarily be written (zeroed), but will remain zero if they are already zeroed in *res* before calling this function. Scalar arithmetic ------------------------------------------------------------------------------- .. function:: void acb_mat_scalar_mul_2exp_si(acb_mat_t B, const acb_mat_t A, slong c) Sets *B* to *A* multiplied by `2^c`. .. function:: void acb_mat_scalar_addmul_si(acb_mat_t B, const acb_mat_t A, slong c, slong prec) .. function:: void acb_mat_scalar_addmul_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec) .. function:: void acb_mat_scalar_addmul_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec) .. function:: void acb_mat_scalar_addmul_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec) Sets *B* to `B + A \times c`. .. function:: void acb_mat_scalar_mul_si(acb_mat_t B, const acb_mat_t A, slong c, slong prec) .. function:: void acb_mat_scalar_mul_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec) .. function:: void acb_mat_scalar_mul_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec) .. function:: void acb_mat_scalar_mul_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec) Sets *B* to `A \times c`. .. function:: void acb_mat_scalar_div_si(acb_mat_t B, const acb_mat_t A, slong c, slong prec) .. function:: void acb_mat_scalar_div_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec) .. function:: void acb_mat_scalar_div_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec) .. function:: void acb_mat_scalar_div_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec) Sets *B* to `A / c`. Gaussian elimination and solving ------------------------------------------------------------------------------- .. function:: int acb_mat_lu_classical(slong * perm, acb_mat_t LU, const acb_mat_t A, slong prec) .. function:: int acb_mat_lu_recursive(slong * perm, acb_mat_t LU, const acb_mat_t A, slong prec) .. function:: int acb_mat_lu(slong * perm, acb_mat_t LU, const acb_mat_t A, slong prec) Given an `n \times n` matrix `A`, computes an LU decomposition `PLU = A` using Gaussian elimination with partial pivoting. The input and output matrices can be the same, performing the decomposition in-place. Entry `i` in the permutation vector perm is set to the row index in the input matrix corresponding to row `i` in the output matrix. The algorithm succeeds and returns nonzero if it can find `n` invertible (i.e. not containing zero) pivot entries. This guarantees that the matrix is invertible. The algorithm fails and returns zero, leaving the entries in `P` and `LU` undefined, if it cannot find `n` invertible pivot elements. In this case, either the matrix is singular, the input matrix was computed to insufficient precision, or the LU decomposition was attempted at insufficient precision. The *classical* version uses Gaussian elimination directly while the *recursive* version performs the computation in a block recursive way to benefit from fast matrix multiplication. The default version chooses an algorithm automatically. .. function:: void acb_mat_solve_tril_classical(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) .. function:: void acb_mat_solve_tril_recursive(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) .. function:: void acb_mat_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) .. function:: void acb_mat_solve_triu_classical(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) .. function:: void acb_mat_solve_triu_recursive(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) .. function:: void acb_mat_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) Solves the lower triangular system `LX = B` or the upper triangular system `UX = B`, respectively. If *unit* is set, the main diagonal of *L* or *U* is taken to consist of all ones, and in that case the actual entries on the diagonal are not read at all and can contain other data. The *classical* versions perform the computations iteratively while the *recursive* versions perform the computations in a block recursive way to benefit from fast matrix multiplication. The default versions choose an algorithm automatically. .. function:: void acb_mat_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t LU, const acb_mat_t B, slong prec) Solves `AX = B` given the precomputed nonsingular LU decomposition `A = PLU`. The matrices `X` and `B` are allowed to be aliased with each other, but `X` is not allowed to be aliased with `LU`. .. function:: int acb_mat_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) .. function:: int acb_mat_solve_lu(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) .. function:: int acb_mat_solve_precond(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) Solves `AX = B` where `A` is a nonsingular `n \times n` matrix and `X` and `B` are `n \times m` matrices. If `m > 0` and `A` cannot be inverted numerically (indicating either that `A` is singular or that the precision is insufficient), the values in the output matrix are left undefined and zero is returned. A nonzero return value guarantees that `A` is invertible and that the exact solution matrix is contained in the output. Three algorithms are provided: * The *lu* version performs LU decomposition directly in ball arithmetic. This is fast, but the bounds typically blow up exponentially with *n*, even if the system is well-conditioned. This algorithm is usually the best choice at very high precision. * The *precond* version computes an approximate inverse to precondition the system. This is usually several times slower than direct LU decomposition, but the bounds do not blow up with *n* if the system is well-conditioned. This algorithm is usually the best choice for large systems at low to moderate precision. * The default version selects between *lu* and *precomp* automatically. The automatic choice should be reasonable most of the time, but users may benefit from trying either *lu* or *precond* in specific applications. For example, the *lu* solver often performs better for ill-conditioned systems where use of very high precision is unavoidable. .. function:: int acb_mat_inv(acb_mat_t X, const acb_mat_t A, slong prec) Sets `X = A^{-1}` where `A` is a square matrix, computed by solving the system `AX = I`. If `A` cannot be inverted numerically (indicating either that `A` is singular or that the precision is insufficient), the values in the output matrix are left undefined and zero is returned. A nonzero return value guarantees that the matrix is invertible and that the exact inverse is contained in the output. .. function:: void acb_mat_det_lu(acb_t det, const acb_mat_t A, slong prec) .. function:: void acb_mat_det_precond(acb_t det, const acb_mat_t A, slong prec) .. function:: void acb_mat_det(acb_t det, const acb_mat_t A, slong prec) Sets *det* to the determinant of the matrix *A*. The *lu* version uses Gaussian elimination with partial pivoting. If at some point an invertible pivot element cannot be found, the elimination is stopped and the magnitude of the determinant of the remaining submatrix is bounded using Hadamard's inequality. The *precond* version computes an approximate LU factorization of *A* and multiplies by the inverse *L* and *U* martices as preconditioners to obtain a matrix close to the identity matrix [Rum2010]_. An enclosure for this determinant is computed using Gershgorin circles. This is about four times slower than direct Gaussian elimination, but much more numerically stable. The default version automatically selects between the *lu* and *precond* versions and additionally handles small or triangular matrices by direct formulas. .. function:: void acb_mat_approx_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec) .. function:: void acb_mat_approx_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec) .. function:: int acb_mat_approx_lu(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec) .. function:: void acb_mat_approx_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t A, const acb_mat_t B, slong prec) .. function:: int acb_mat_approx_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec) .. function:: int acb_mat_approx_inv(acb_mat_t X, const acb_mat_t A, slong prec) These methods perform approximate solving *without any error control*. The radii in the input matrices are ignored, the computations are done numerically with floating-point arithmetic (using ordinary Gaussian elimination and triangular solving, accelerated through the use of block recursive strategies for large matrices), and the output matrices are set to the approximate floating-point results with zeroed error bounds. Characteristic polynomial and companion matrix ------------------------------------------------------------------------------- .. function:: void _acb_mat_charpoly(acb_ptr poly, const acb_mat_t mat, slong prec) .. function:: void acb_mat_charpoly(acb_poly_t poly, const acb_mat_t mat, slong prec) Sets *poly* to the characteristic polynomial of *mat* which must be a square matrix. If the matrix has *n* rows, the underscore method requires space for `n + 1` output coefficients. Employs a division-free algorithm using `O(n^4)` operations. .. function:: void _acb_mat_companion(acb_mat_t mat, acb_srcptr poly, slong prec) .. function:: void acb_mat_companion(acb_mat_t mat, const acb_poly_t poly, slong prec) Sets the *n* by *n* matrix *mat* to the companion matrix of the polynomial *poly* which must have degree *n*. The underscore method reads `n + 1` input coefficients. Special functions ------------------------------------------------------------------------------- .. function:: void acb_mat_exp_taylor_sum(acb_mat_t S, const acb_mat_t A, slong N, slong prec) Sets *S* to the truncated exponential Taylor series `S = \sum_{k=0}^{N-1} A^k / k!`. See :func:`arb_mat_exp_taylor_sum` for implementation notes. .. function:: void acb_mat_exp(acb_mat_t B, const acb_mat_t A, slong prec) Sets *B* to the exponential of the matrix *A*, defined by the Taylor series .. math :: \exp(A) = \sum_{k=0}^{\infty} \frac{A^k}{k!}. The function is evaluated as `\exp(A/2^r)^{2^r}`, where `r` is chosen to give rapid convergence of the Taylor series. Error bounds are computed as for :func:`arb_mat_exp`. .. function:: void acb_mat_trace(acb_t trace, const acb_mat_t mat, slong prec) Sets *trace* to the trace of the matrix, i.e. the sum of entries on the main diagonal of *mat*. The matrix is required to be square. .. function:: void _acb_mat_diag_prod(acb_t res, const acb_mat_t mat, slong a, slong b, slong prec) .. function:: void acb_mat_diag_prod(acb_t res, const acb_mat_t mat, slong prec) Sets *res* to the product of the entries on the main diagonal of *mat*. The underscore method computes the product of the entries between index *a* inclusive and *b* exclusive (the indices must be in range). Component and error operations ------------------------------------------------------------------------------- .. function:: void acb_mat_get_mid(acb_mat_t B, const acb_mat_t A) Sets the entries of *B* to the exact midpoints of the entries of *A*. .. function:: void acb_mat_add_error_mag(acb_mat_t mat, const mag_t err) Adds *err* in-place to the radii of the entries of *mat*. .. _acb-mat-eigenvalues: Eigenvalues and eigenvectors ------------------------------------------------------------------------------- The functions in this section are experimental. There are classes of matrices where the algorithms fail to converge even as *prec* is increased, or for which the error bounds are much worse than necessary. In some cases, it can help to manually precondition the matrix *A* by applying a similarity transformation `T^{-1} A T`. * If *A* is badly scaled, take `T` to be a matrix such that the entries of `T^{-1} A T` are more uniform (this is known as balancing). * Simply taking `T` to be a random invertible matrix can help if an algorithm fails to converge despite `A` being well-scaled. (This can be the case when dealing with multiple eigenvalues.) .. function:: int acb_mat_approx_eig_qr(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, const mag_t tol, slong maxiter, slong prec) Computes floating-point approximations of all the *n* eigenvalues (and optionally eigenvectors) of the given *n* by *n* matrix *A*. The approximations of the eigenvalues are written to the vector *E*, in no particular order. If *L* is not *NULL*, approximations of the corresponding left eigenvectors are written to the rows of *L*. If *R* is not *NULL*, approximations of the corresponding right eigenvectors are written to the columns of *R*. The parameters *tol* and *maxiter* can be used to control the target numerical error and the maximum number of iterations allowed before giving up. Passing *NULL* and 0 respectively results in default values being used. Uses the implicitly shifted QR algorithm with reduction to Hessenberg form. No guarantees are made about the accuracy of the output. A nonzero return value indicates that the QR iteration converged numerically, but this is only a heuristic termination test and does not imply any statement whatsoever about error bounds. The output may also be accurate even if this function returns zero. .. function:: void acb_mat_eig_global_enclosure(mag_t eps, const acb_mat_t A, acb_srcptr E, const acb_mat_t R, slong prec) Given an *n* by *n* matrix *A*, a length-*n* vector *E* containing approximations of the eigenvalues of *A*, and an *n* by *n* matrix *R* containing approximations of the corresponding right eigenvectors, computes a rigorous bound `\varepsilon` such that every eigenvalue `\lambda` of *A* satisfies `|\lambda - \hat \lambda_k| \le \varepsilon` for some `\hat \lambda_k` in *E*. In other words, the union of the balls `B_k = \{z : |z - \hat \lambda_k| \le \varepsilon\}` is guaranteed to be an enclosure of all eigenvalues of *A*. Note that there is no guarantee that each ball `B_k` can be identified with a single eigenvalue: it is possible that some balls contain several eigenvalues while other balls contain no eigenvalues. In other words, this method is not powerful enough to compute isolating balls for the individual eigenvalues (or even for clusters of eigenvalues other than the whole spectrum). Nevertheless, in practice the balls `B_k` will represent eigenvalues one-to-one with high probability if the given approximations are good. The output can be used to certify that all eigenvalues of *A* lie in some region of the complex plane (such as a specific half-plane, strip, disk, or annulus) without the need to certify the individual eigenvalues. The output is easily converted into lower or upper bounds for the absolute values or real or imaginary parts of the spectrum, and with high probability these bounds will be tight. Using :func:`acb_add_error_mag` and :func:`acb_union`, the output can also be converted to a single :type:`acb_t` enclosing the whole spectrum of *A* in a rectangle, but note that to test whether a condition holds for all eigenvalues of *A*, it is typically better to iterate over the individual balls `B_k`. This function implements the fast algorithm in Theorem 1 in [Miy2010]_ which extends the Bauer-Fike theorem. Approximations *E* and *R* can, for instance, be computed using :func:`acb_mat_approx_eig_qr`. No assumptions are made about the structure of *A* or the quality of the given approximations. .. function:: void acb_mat_eig_enclosure_rump(acb_t lambda, acb_mat_t J, acb_mat_t R, const acb_mat_t A, const acb_t lambda_approx, const acb_mat_t R_approx, slong prec) Given an *n* by *n* matrix *A* and an approximate eigenvalue-eigenvector pair *lambda_approx* and *R_approx* (where *R_approx* is an *n* by 1 matrix), computes an enclosure *lambda* guaranteed to contain at least one of the eigenvalues of *A*, along with an enclosure *R* for a corresponding right eigenvector. More generally, this function can handle clustered (or repeated) eigenvalues. If *R_approx* is an *n* by *k* matrix containing approximate eigenvectors for a presumed cluster of *k* eigenvalues near *lambda_approx*, this function computes an enclosure *lambda* guaranteed to contain at least *k* eigenvalues of *A* along with a matrix *R* guaranteed to contain a basis for the *k*-dimensional invariant subspace associated with these eigenvalues. Note that for multiple eigenvalues, determining the individual eigenvectors is an ill-posed problem; describing an enclosure of the invariant subspace is the best we can hope for. For `k = 1`, it is guaranteed that `AR - R \lambda` contains the zero matrix. For `k > 2`, this cannot generally be guaranteed (in particular, *A* might not diagonalizable). In this case, we can still compute an approximately diagonal *k* by *k* interval matrix `J \approx \lambda I` such that `AR - RJ` is guaranteed to contain the zero matrix. This matrix has the property that the Jordan canonical form of (any exact matrix contained in) *A* has a *k* by *k* submatrix equal to the Jordan canonical form of (some exact matrix contained in) *J*. The output *J* is optional (the user can pass *NULL* to omit it). The algorithm follows section 13.4 in [Rum2010]_, corresponding to the ``verifyeig()`` routine in INTLAB. The initial approximations can, for instance, be computed using :func:`acb_mat_approx_eig_qr`. No assumptions are made about the structure of *A* or the quality of the given approximations. .. function:: int acb_mat_eig_simple_rump(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) .. function:: int acb_mat_eig_simple_vdhoeven_mourrain(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) .. function:: int acb_mat_eig_simple(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) Computes all the eigenvalues (and optionally corresponding eigenvectors) of the given *n* by *n* matrix *A*. Attempts to prove that *A* has *n* simple (isolated) eigenvalues, returning 1 if successful and 0 otherwise. On success, isolating complex intervals for the eigenvalues are written to the vector *E*, in no particular order. If *L* is not *NULL*, enclosures of the corresponding left eigenvectors are written to the rows of *L*. If *R* is not *NULL*, enclosures of the corresponding right eigenvectors are written to the columns of *R*. The left eigenvectors are normalized so that `L = R^{-1}`. This produces a diagonalization `LAR = D` where *D* is the diagonal matrix with the entries in *E* on the diagonal. The user supplies approximations *E_approx* and *R_approx* of the eigenvalues and the right eigenvectors. The initial approximations can, for instance, be computed using :func:`acb_mat_approx_eig_qr`. No assumptions are made about the structure of *A* or the quality of the given approximations. Two algorithms are implemented: * The *rump* version calls :func:`acb_mat_eig_enclosure_rump` repeatedly to certify eigenvalue-eigenvector pairs one by one. The iteration is stopped to return non-success if a new eigenvalue overlaps with previously computed one. Finally, *L* is computed by a matrix inversion. This has complexity `O(n^4)`. * The *vdhoeven_mourrain* version uses the algorithm in [HM2017]_ to certify all eigenvalues and eigenvectors in one step. This has complexity `O(n^3)`. The default version currently uses *vdhoeven_mourrain*. By design, these functions terminate instead of attempting to compute eigenvalue clusters if some eigenvalues cannot be isolated. To compute all eigenvalues of a matrix allowing for overlap, :func:`acb_mat_eig_multiple_rump` may be used as a fallback, or :func:`acb_mat_eig_multiple` may be used in the first place. .. function:: int acb_mat_eig_multiple_rump(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) .. function:: int acb_mat_eig_multiple(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec) Computes all the eigenvalues of the given *n* by *n* matrix *A*. On success, the output vector *E* contains *n* complex intervals, each representing one eigenvalue of *A* with the correct multiplicities in case of overlap. The output intervals are either disjoint or identical, and identical intervals are guaranteed to be grouped consecutively. Each complete run of *k* identical intervals thus represents a cluster of exactly *k* eigenvalues which could not be separated from each other at the current precision, but which could be isolated from the other `n - k` eigenvalues of the matrix. The user supplies approximations *E_approx* and *R_approx* of the eigenvalues and the right eigenvectors. The initial approximations can, for instance, be computed using :func:`acb_mat_approx_eig_qr`. No assumptions are made about the structure of *A* or the quality of the given approximations. The *rump* algorithm groups approximate eigenvalues that are close and calls :func:`acb_mat_eig_enclosure_rump` repeatedly to validate each cluster. The complexity is `O(m n^3)` for *m* clusters. The default version, as currently implemented, first attempts to call :func:`acb_mat_eig_simple_vdhoeven_mourrain` hoping that the eigenvalues are actually simple. It then uses the *rump* algorithm as a fallback. arb-2.22.1/doc/source/acb_modular.rst000066400000000000000000000566671417376376500174600ustar00rootroot00000000000000.. _acb-modular: **acb_modular.h** -- modular forms of complex variables =============================================================================== This module provides methods for numerical evaluation of modular forms and Jacobi theta functions. See :ref:`acb_elliptic.h ` for the closely related elliptic functions and integrals. In the context of this module, *tau* or `\tau` always denotes an element of the complex upper half-plane `\mathbb{H} = \{z \in \mathbb{C} : \operatorname{Im}(z) > 0\}`. We also often use the variable `q`, variously defined as `q = e^{2 \pi i \tau}` (usually in relation to modular forms) or `q = e^{\pi i \tau}` (usually in relation to theta functions) and satisfying `|q| < 1`. We will clarify the local meaning of `q` every time such a quantity appears as a function of `\tau`. As usual, the numerical functions in this module compute strict error bounds: if *tau* is represented by an :type:`acb_t` whose content overlaps with the real line (or lies in the lower half-plane), and *tau* is passed to a function defined only on `\mathbb{H}`, then the output will have an infinite radius. The analogous behavior holds for functions requiring `|q| < 1`. The modular group ------------------------------------------------------------------------------- .. type:: psl2z_struct .. type:: psl2z_t Represents an element of the modular group `\text{PSL}(2, \mathbb{Z})`, namely an integer matrix .. math :: \begin{pmatrix} a & b \\ c & d \end{pmatrix} with `ad-bc = 1`, and with signs canonicalized such that `c \ge 0`, and `d > 0` if `c = 0`. The struct members *a*, *b*, *c*, *d* are of type *fmpz*. .. function:: void psl2z_init(psl2z_t g) Initializes *g* and set it to the identity element. .. function:: void psl2z_clear(psl2z_t g) Clears *g*. .. function:: void psl2z_swap(psl2z_t f, psl2z_t g) Swaps *f* and *g* efficiently. .. function:: void psl2z_set(psl2z_t f, const psl2z_t g) Sets *f* to a copy of *g*. .. function:: void psl2z_one(psl2z_t g) Sets *g* to the identity element. .. function:: int psl2z_is_one(const psl2z_t g) Returns nonzero iff *g* is the identity element. .. function:: void psl2z_print(const psl2z_t g) Prints *g* to standard output. .. function:: void psl2z_fprint(FILE * file, const psl2z_t g) Prints *g* to the stream *file*. .. function:: int psl2z_equal(const psl2z_t f, const psl2z_t g) Returns nonzero iff *f* and *g* are equal. .. function:: void psl2z_mul(psl2z_t h, const psl2z_t f, const psl2z_t g) Sets *h* to the product of *f* and *g*, namely the matrix product with the signs canonicalized. .. function:: void psl2z_inv(psl2z_t h, const psl2z_t g) Sets *h* to the inverse of *g*. .. function:: int psl2z_is_correct(const psl2z_t g) Returns nonzero iff *g* contains correct data, i.e. satisfying `ad-bc = 1`, `c \ge 0`, and `d > 0` if `c = 0`. .. function:: void psl2z_randtest(psl2z_t g, flint_rand_t state, slong bits) Sets *g* to a random element of `\text{PSL}(2, \mathbb{Z})` with entries of bit length at most *bits* (or 1, if *bits* is not positive). We first generate *a* and *d*, compute their Bezout coefficients, divide by the GCD, and then correct the signs. Modular transformations ------------------------------------------------------------------------------- .. function:: void acb_modular_transform(acb_t w, const psl2z_t g, const acb_t z, slong prec) Applies the modular transformation *g* to the complex number *z*, evaluating .. math :: w = g z = \frac{az+b}{cz+d}. .. function:: void acb_modular_fundamental_domain_approx_d(psl2z_t g, double x, double y, double one_minus_eps) .. function:: void acb_modular_fundamental_domain_approx_arf(psl2z_t g, const arf_t x, const arf_t y, const arf_t one_minus_eps, slong prec) Attempts to determine a modular transformation *g* that maps the complex number `x+yi` to the fundamental domain or just slightly outside the fundamental domain, where the target tolerance (not a strict bound) is specified by *one_minus_eps*. The inputs are assumed to be finite numbers, with *y* positive. Uses floating-point iteration, repeatedly applying either the transformation `z \gets z + b` or `z \gets -1/z`. The iteration is terminated if `|x| \le 1/2` and `x^2 + y^2 \ge 1 - \varepsilon` where `1 - \varepsilon` is passed as *one_minus_eps*. It is also terminated if too many steps have been taken without convergence, or if the numbers end up too large or too small for the working precision. The algorithm can fail to produce a satisfactory transformation. The output *g* is always set to *some* correct modular transformation, but it is up to the user to verify a posteriori that *g* maps `x+yi` close enough to the fundamental domain. .. function:: void acb_modular_fundamental_domain_approx(acb_t w, psl2z_t g, const acb_t z, const arf_t one_minus_eps, slong prec) Attempts to determine a modular transformation *g* that maps the complex number `z` to the fundamental domain or just slightly outside the fundamental domain, where the target tolerance (not a strict bound) is specified by *one_minus_eps*. It also computes the transformed value `w = gz`. This function first tries to use :func:`acb_modular_fundamental_domain_approx_d` and checks if the result is acceptable. If this fails, it calls :func:`acb_modular_fundamental_domain_approx_arf` with higher precision. Finally, `w = gz` is evaluated by a single application of *g*. The algorithm can fail to produce a satisfactory transformation. The output *g* is always set to *some* correct modular transformation, but it is up to the user to verify a posteriori that `w` is close enough to the fundamental domain. .. function:: int acb_modular_is_in_fundamental_domain(const acb_t z, const arf_t tol, slong prec) Returns nonzero if it is certainly true that `|z| \ge 1 - \varepsilon` and `|\operatorname{Re}(z)| \le 1/2 + \varepsilon` where `\varepsilon` is specified by *tol*. Returns zero if this is false or cannot be determined. Addition sequences ------------------------------------------------------------------------------- .. function:: void acb_modular_fill_addseq(slong * tab, slong len) Builds a near-optimal addition sequence for a sequence of integers which is assumed to be reasonably dense. As input, the caller should set each entry in *tab* to `-1` if that index is to be part of the addition sequence, and to 0 otherwise. On output, entry *i* in *tab* will either be zero (if the number is not part of the sequence), or a value *j* such that both *j* and `i - j` are also marked. The first two entries in *tab* are ignored (the number 1 is always assumed to be part of the sequence). Jacobi theta functions ------------------------------------------------------------------------------- Unfortunately, there are many inconsistent notational variations for Jacobi theta functions in the literature. Unless otherwise noted, we use the functions .. math :: \theta_1(z,\tau) = -i \sum_{n=-\infty}^{\infty} (-1)^n \exp(\pi i [(n + 1/2)^2 \tau + (2n + 1) z]) = 2 q_{1/4} \sum_{n=0}^{\infty} (-1)^n q^{n(n+1)} \sin((2n+1) \pi z) .. math :: \theta_2(z,\tau) = \sum_{n=-\infty}^{\infty} \exp(\pi i [(n + 1/2)^2 \tau + (2n + 1) z]) = 2 q_{1/4} \sum_{n=0}^{\infty} q^{n(n+1)} \cos((2n+1) \pi z) .. math :: \theta_3(z,\tau) = \sum_{n=-\infty}^{\infty} \exp(\pi i [n^2 \tau + 2n z]) = 1 + 2 \sum_{n=1}^{\infty} q^{n^2} \cos(2n \pi z) .. math :: \theta_4(z,\tau) = \sum_{n=-\infty}^{\infty} (-1)^n \exp(\pi i [n^2 \tau + 2n z]) = 1 + 2 \sum_{n=1}^{\infty} (-1)^n q^{n^2} \cos(2n \pi z) where `q = \exp(\pi i \tau)` and `q_{1/4} = \exp(\pi i \tau / 4)`. Note that many authors write `q_{1/4}` as `q^{1/4}`, but the principal fourth root `(q)^{1/4} = \exp(\frac{1}{4} \log q)` differs from `q_{1/4}` in general and some formulas are only correct if one reads "`q^{1/4} = \exp(\pi i \tau / 4)`". To avoid confusion, we only write `q^k` when `k` is an integer. .. function:: void acb_modular_theta_transform(int * R, int * S, int * C, const psl2z_t g) We wish to write a theta function with quasiperiod `\tau` in terms of a theta function with quasiperiod `\tau' = g \tau`, given some `g = (a, b; c, d) \in \text{PSL}(2, \mathbb{Z})`. For `i = 0, 1, 2, 3`, this function computes integers `R_i` and `S_i` (*R* and *S* should be arrays of length 4) and `C \in \{0, 1\}` such that .. math :: \theta_{1+i}(z,\tau) = \exp(\pi i R_i / 4) \cdot A \cdot B \cdot \theta_{1+S_i}(z',\tau') where `z' = z, A = B = 1` if `C = 0`, and .. math :: z' = \frac{-z}{c \tau + d}, \quad A = \sqrt{\frac{i}{c \tau + d}}, \quad B = \exp\left(-\pi i c \frac{z^2}{c \tau + d}\right) if `C = 1`. Note that `A` is well-defined with the principal branch of the square root since `A^2 = i/(c \tau + d)` lies in the right half-plane. Firstly, if `c = 0`, we have `\theta_i(z, \tau) = \exp(-\pi i b / 4) \theta_i(z, \tau+b)` for `i = 1, 2`, whereas `\theta_3` and `\theta_4` remain unchanged when `b` is even and swap places with each other when `b` is odd. In this case we set `C = 0`. For an arbitrary `g` with `c > 0`, we set `C = 1`. The general transformations are given by Rademacher [Rad1973]_. We need the function `\theta_{m,n}(z,\tau)` defined for `m, n \in \mathbb{Z}` by (beware of the typos in [Rad1973]_) .. math :: \theta_{0,0}(z,\tau) = \theta_3(z,\tau), \quad \theta_{0,1}(z,\tau) = \theta_4(z,\tau) .. math :: \theta_{1,0}(z,\tau) = \theta_2(z,\tau), \quad \theta_{1,1}(z,\tau) = i \theta_1(z,\tau) .. math :: \theta_{m+2,n}(z,\tau) = (-1)^n \theta_{m,n}(z,\tau) .. math :: \theta_{m,n+2}(z,\tau) = \theta_{m,n}(z,\tau). Then we may write .. math :: \theta_1(z,\tau) &= \varepsilon_1 A B \theta_1(z', \tau') \theta_2(z,\tau) &= \varepsilon_2 A B \theta_{1-c,1+a}(z', \tau') \theta_3(z,\tau) &= \varepsilon_3 A B \theta_{1+d-c,1-b+a}(z', \tau') \theta_4(z,\tau) &= \varepsilon_4 A B \theta_{1+d,1-b}(z', \tau') where `\varepsilon_i` is an 8th root of unity. Specifically, if we denote the 24th root of unity in the transformation formula of the Dedekind eta function by `\varepsilon(a,b,c,d) = \exp(\pi i R(a,b,c,d) / 12)` (see :func:`acb_modular_epsilon_arg`), then: .. math :: \varepsilon_1(a,b,c,d) &= \exp(\pi i [R(-d,b,c,-a) + 1] / 4) \varepsilon_2(a,b,c,d) &= \exp(\pi i [-R(a,b,c,d) + (5+(2-c)a)] / 4) \varepsilon_3(a,b,c,d) &= \exp(\pi i [-R(a,b,c,d) + (4+(c-d-2)(b-a))] / 4) \varepsilon_4(a,b,c,d) &= \exp(\pi i [-R(a,b,c,d) + (3-(2+d)b)] / 4) These formulas are easily derived from the formulas in [Rad1973]_ (Rademacher has the transformed/untransformed variables exchanged, and his "`\varepsilon`" differs from ours by a constant offset in the phase). .. function:: void acb_modular_addseq_theta(slong * exponents, slong * aindex, slong * bindex, slong num) Constructs an addition sequence for the first *num* squares and triangular numbers interleaved (excluding zero), i.e. 1, 2, 4, 6, 9, 12, 16, 20, 25, 30 etc. .. function:: void acb_modular_theta_sum(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t w, int w_is_unit, const acb_t q, slong len, slong prec) Simultaneously computes the first *len* coefficients of each of the formal power series .. math :: \theta_1(z+x,\tau) / q_{1/4} \in \mathbb{C}[[x]] \theta_2(z+x,\tau) / q_{1/4} \in \mathbb{C}[[x]] \theta_3(z+x,\tau) \in \mathbb{C}[[x]] \theta_4(z+x,\tau) \in \mathbb{C}[[x]] given `w = \exp(\pi i z)` and `q = \exp(\pi i \tau)`, by summing a finite truncation of the respective theta function series. In particular, with *len* equal to 1, computes the respective value of the theta function at the point *z*. We require *len* to be positive. If *w_is_unit* is nonzero, *w* is assumed to lie on the unit circle, i.e. *z* is assumed to be real. Note that the factor `q_{1/4}` is removed from `\theta_1` and `\theta_2`. To get the true theta function values, the user has to multiply this factor back. This convention avoids unnecessary computations, since the user can compute `q_{1/4} = \exp(\pi i \tau / 4)` followed by `q = (q_{1/4})^4`, and in many cases when computing products or quotients of theta functions, the factor `q_{1/4}` can be eliminated entirely. This function is intended for `|q| \ll 1`. It can be called with any `q`, but will return useless intervals if convergence is not rapid. For general evaluation of theta functions, the user should only call this function after applying a suitable modular transformation. We consider the sums together, alternatingly updating `(\theta_1, \theta_2)` or `(\theta_3, \theta_4)`. For `k = 0, 1, 2, \ldots`, the powers of `q` are `\lfloor (k+2)^2 / 4 \rfloor = 1, 2, 4, 6, 9` etc. and the powers of `w` are `\pm (k+2) = \pm 2, \pm 3, \pm 4, \ldots` etc. The scheme is illustrated by the following table: .. math :: \begin{array}{llll} & \theta_1, \theta_2 & q^0 & (w^1 \pm w^{-1}) \\ k = 0 & \theta_3, \theta_4 & q^1 & (w^2 \pm w^{-2}) \\ k = 1 & \theta_1, \theta_2 & q^2 & (w^3 \pm w^{-3}) \\ k = 2 & \theta_3, \theta_4 & q^4 & (w^4 \pm w^{-4}) \\ k = 3 & \theta_1, \theta_2 & q^6 & (w^5 \pm w^{-5}) \\ k = 4 & \theta_3, \theta_4 & q^9 & (w^6 \pm w^{-6}) \\ k = 5 & \theta_1, \theta_2 & q^{12} & (w^7 \pm w^{-7}) \\ \end{array} For some integer `N \ge 1`, the summation is stopped just before term `k = N`. Let `Q = |q|`, `W = \max(|w|,|w^{-1}|)`, `E = \lfloor (N+2)^2 / 4 \rfloor` and `F = \lfloor (N+1)/2 \rfloor + 1`. The error of the zeroth derivative can be bounded as .. math :: 2 Q^E W^{N+2} \left[ 1 + Q^F W + Q^{2F} W^2 + \ldots \right] = \frac{2 Q^E W^{N+2}}{1 - Q^F W} provided that the denominator is positive (otherwise we set the error bound to infinity). When *len* is greater than 1, consider the derivative of order *r*. The term of index *k* and order *r* picks up a factor of magnitude `(k+2)^r` from differentiation of `w^{k+2}` (it also picks up a factor `\pi^r`, but we omit this until we rescale the coefficients at the end of the computation). Thus we have the error bound .. math :: 2 Q^E W^{N+2} (N+2)^r \left[ 1 + Q^F W \frac{(N+3)^r}{(N+2)^r} + Q^{2F} W^2 \frac{(N+4)^r}{(N+2)^r} + \ldots \right] which by the inequality `(1 + m/(N+2))^r \le \exp(mr/(N+2))` can be bounded as .. math :: \frac{2 Q^E W^{N+2} (N+2)^r}{1 - Q^F W \exp(r/(N+2))}, again valid when the denominator is positive. To actually evaluate the series, we write the even cosine terms as `w^{2n} + w^{-2n}`, the odd cosine terms as `w (w^{2n} + w^{-2n-2})`, and the sine terms as `w (w^{2n} - w^{-2n-2})`. This way we only need even powers of `w` and `w^{-1}`. The implementation is not yet optimized for real `z`, in which case further work can be saved. This function does not permit aliasing between input and output arguments. .. function:: void acb_modular_theta_const_sum_basecase(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong N, slong prec) .. function:: void acb_modular_theta_const_sum_rs(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong N, slong prec) Computes the truncated theta constant sums `\theta_2 = \sum_{k(k+1) < N} q^{k(k+1)}`, `\theta_3 = \sum_{k^2 < N} q^{k^2}`, `\theta_4 = \sum_{k^2 < N} (-1)^k q^{k^2}`. The *basecase* version uses a short addition sequence. The *rs* version uses rectangular splitting. The algorithms are described in [EHJ2016]_. .. function:: void acb_modular_theta_const_sum(acb_t theta2, acb_t theta3, acb_t theta4, const acb_t q, slong prec) Computes the respective theta constants by direct summation (without applying modular transformations). This function selects an appropriate *N*, calls either :func:`acb_modular_theta_const_sum_basecase` or :func:`acb_modular_theta_const_sum_rs` or depending on *N*, and adds a bound for the truncation error. .. function:: void acb_modular_theta_notransform(acb_t theta1, acb_t theta2, acb_t theta3, acb_t theta4, const acb_t z, const acb_t tau, slong prec) Evaluates the Jacobi theta functions `\theta_i(z,\tau)`, `i = 1, 2, 3, 4` simultaneously. This function does not move `\tau` to the fundamental domain. This is generally worse than :func:`acb_modular_theta`, but can be slightly better for moderate input. .. function:: void acb_modular_theta(acb_t theta1, acb_t theta2, acb_t theta3, acb_t theta4, const acb_t z, const acb_t tau, slong prec) Evaluates the Jacobi theta functions `\theta_i(z,\tau)`, `i = 1, 2, 3, 4` simultaneously. This function moves `\tau` to the fundamental domain and then also reduces `z` modulo `\tau` before calling :func:`acb_modular_theta_sum`. .. function:: void acb_modular_theta_jet_notransform(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t z, const acb_t tau, slong len, slong prec) .. function:: void acb_modular_theta_jet(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, const acb_t z, const acb_t tau, slong len, slong prec) Evaluates the Jacobi theta functions along with their derivatives with respect to *z*, writing the first *len* coefficients in the power series `\theta_i(z+x,\tau) \in \mathbb{C}[[x]]` to each respective output variable. The *notransform* version does not move `\tau` to the fundamental domain or reduce `z` during the computation. .. function:: void _acb_modular_theta_series(acb_ptr theta1, acb_ptr theta2, acb_ptr theta3, acb_ptr theta4, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec) .. function:: void acb_modular_theta_series(acb_poly_t theta1, acb_poly_t theta2, acb_poly_t theta3, acb_poly_t theta4, const acb_poly_t z, const acb_t tau, slong len, slong prec) Evaluates the respective Jacobi theta functions of the power series *z*, truncated to length *len*. Either of the output variables can be *NULL*. Dedekind eta function ------------------------------------------------------------------------------- .. function:: void acb_modular_addseq_eta(slong * exponents, slong * aindex, slong * bindex, slong num) Constructs an addition sequence for the first *num* generalized pentagonal numbers (excluding zero), i.e. 1, 2, 5, 7, 12, 15, 22, 26, 35, 40 etc. .. function:: void acb_modular_eta_sum(acb_t eta, const acb_t q, slong prec) Evaluates the Dedekind eta function without the leading 24th root, i.e. .. math :: \exp(-\pi i \tau/12) \eta(\tau) = \sum_{n=-\infty}^{\infty} (-1)^n q^{(3n^2-n)/2} given `q = \exp(2 \pi i \tau)`, by summing the defining series. This function is intended for `|q| \ll 1`. It can be called with any `q`, but will return useless intervals if convergence is not rapid. For general evaluation of the eta function, the user should only call this function after applying a suitable modular transformation. The series is evaluated using either a short addition sequence or rectangular splitting, depending on the number of terms. The algorithms are described in [EHJ2016]_. .. function:: int acb_modular_epsilon_arg(const psl2z_t g) Given `g = (a, b; c, d)`, computes an integer `R` such that `\varepsilon(a,b,c,d) = \exp(\pi i R / 12)` is the 24th root of unity in the transformation formula for the Dedekind eta function, .. math :: \eta\left(\frac{a\tau+b}{c\tau+d}\right) = \varepsilon (a,b,c,d) \sqrt{c\tau+d} \eta(\tau). .. function:: void acb_modular_eta(acb_t r, const acb_t tau, slong prec) Computes the Dedekind eta function `\eta(\tau)` given `\tau` in the upper half-plane. This function applies the functional equation to move `\tau` to the fundamental domain before calling :func:`acb_modular_eta_sum`. Modular forms ------------------------------------------------------------------------------- .. function:: void acb_modular_j(acb_t r, const acb_t tau, slong prec) Computes Klein's j-invariant `j(\tau)` given `\tau` in the upper half-plane. The function is normalized so that `j(i) = 1728`. We first move `\tau` to the fundamental domain, which does not change the value of the function. Then we use the formula `j(\tau) = 32 (\theta_2^8+\theta_3^8+\theta_4^8)^3 / (\theta_2 \theta_3 \theta_4)^8` where `\theta_i = \theta_i(0,\tau)`. .. function:: void acb_modular_lambda(acb_t r, const acb_t tau, slong prec) Computes the lambda function `\lambda(\tau) = \theta_2^4(0,\tau) / \theta_3^4(0,\tau)`, which is invariant under modular transformations `(a, b; c, d)` where `a, d` are odd and `b, c` are even. .. function:: void acb_modular_delta(acb_t r, const acb_t tau, slong prec) Computes the modular discriminant `\Delta(\tau) = \eta(\tau)^{24}`, which transforms as .. math :: \Delta\left(\frac{a\tau+b}{c\tau+d}\right) = (c\tau+d)^{12} \Delta(\tau). The modular discriminant is sometimes defined with an extra factor `(2\pi)^{12}`, which we omit in this implementation. .. function:: void acb_modular_eisenstein(acb_ptr r, const acb_t tau, slong len, slong prec) Computes simultaneously the first *len* entries in the sequence of Eisenstein series `G_4(\tau), G_6(\tau), G_8(\tau), \ldots`, defined by .. math :: G_{2k}(\tau) = \sum_{m^2 + n^2 \ne 0} \frac{1}{(m+n\tau )^{2k}} and satisfying .. math :: G_{2k} \left(\frac{a\tau+b}{c\tau+d}\right) = (c\tau+d)^{2k} G_{2k}(\tau). We first evaluate `G_4(\tau)` and `G_6(\tau)` on the fundamental domain using theta functions, and then compute the Eisenstein series of higher index using a recurrence relation. Elliptic integrals and functions ------------------------------------------------------------------------------- See the :ref:`acb_elliptic.h ` module for elliptic integrals and functions. The following wrappers are available for backwards compatibility. .. function:: void acb_modular_elliptic_k(acb_t w, const acb_t m, slong prec) .. function:: void acb_modular_elliptic_k_cpx(acb_ptr w, const acb_t m, slong len, slong prec) .. function:: void acb_modular_elliptic_e(acb_t w, const acb_t m, slong prec) .. function:: void acb_modular_elliptic_p(acb_t wp, const acb_t z, const acb_t tau, slong prec) .. function:: void acb_modular_elliptic_p_zpx(acb_ptr wp, const acb_t z, const acb_t tau, slong len, slong prec) Class polynomials ------------------------------------------------------------------------------- .. function:: void acb_modular_hilbert_class_poly(fmpz_poly_t res, slong D) Sets *res* to the Hilbert class polynomial of discriminant *D*, defined as .. math :: H_D(x) = \prod_{(a,b,c)} \left(x - j\left(\frac{-b+\sqrt{D}}{2a}\right)\right) where `(a,b,c)` ranges over the primitive reduced positive definite binary quadratic forms of discriminant `b^2 - 4ac = D`. The Hilbert class polynomial is only defined if `D < 0` and *D* is congruent to 0 or 1 mod 4. If some other value of *D* is passed as input, *res* is set to the zero polynomial. arb-2.22.1/doc/source/acb_poly.rst000066400000000000000000001577221417376376500167720ustar00rootroot00000000000000.. _acb-poly: **acb_poly.h** -- polynomials over the complex numbers =============================================================================== An :type:`acb_poly_t` represents a polynomial over the complex numbers, implemented as an array of coefficients of type :type:`acb_struct`. Most functions are provided in two versions: an underscore method which operates directly on pre-allocated arrays of coefficients and generally has some restrictions (such as requiring the lengths to be nonzero and not supporting aliasing of the input and output arrays), and a non-underscore method which performs automatic memory management and handles degenerate cases. Types, macros and constants ------------------------------------------------------------------------------- .. type:: acb_poly_struct .. type:: acb_poly_t Contains a pointer to an array of coefficients (coeffs), the used length (length), and the allocated size of the array (alloc). An *acb_poly_t* is defined as an array of length one of type *acb_poly_struct*, permitting an *acb_poly_t* to be passed by reference. Memory management ------------------------------------------------------------------------------- .. function:: void acb_poly_init(acb_poly_t poly) Initializes the polynomial for use, setting it to the zero polynomial. .. function:: void acb_poly_clear(acb_poly_t poly) Clears the polynomial, deallocating all coefficients and the coefficient array. .. function:: void acb_poly_fit_length(acb_poly_t poly, slong len) Makes sure that the coefficient array of the polynomial contains at least *len* initialized coefficients. .. function:: void _acb_poly_set_length(acb_poly_t poly, slong len) Directly changes the length of the polynomial, without allocating or deallocating coefficients. The value should not exceed the allocation length. .. function:: void _acb_poly_normalise(acb_poly_t poly) Strips any trailing coefficients which are identical to zero. .. function:: void acb_poly_swap(acb_poly_t poly1, acb_poly_t poly2) Swaps *poly1* and *poly2* efficiently. .. function:: slong acb_poly_allocated_bytes(const acb_poly_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(acb_poly_struct)`` to get the size of the object as a whole. Basic properties and manipulation ------------------------------------------------------------------------------- .. function:: slong acb_poly_length(const acb_poly_t poly) Returns the length of *poly*, i.e. zero if *poly* is identically zero, and otherwise one more than the index of the highest term that is not identically zero. .. function:: slong acb_poly_degree(const acb_poly_t poly) Returns the degree of *poly*, defined as one less than its length. Note that if one or several leading coefficients are balls containing zero, this value can be larger than the true degree of the exact polynomial represented by *poly*, so the return value of this function is effectively an upper bound. .. function:: int acb_poly_is_zero(const acb_poly_t poly) .. function:: int acb_poly_is_one(const acb_poly_t poly) .. function:: int acb_poly_is_x(const acb_poly_t poly) Returns 1 if *poly* is exactly the polynomial 0, 1 or *x* respectively. Returns 0 otherwise. .. function:: void acb_poly_zero(acb_poly_t poly) Sets *poly* to the zero polynomial. .. function:: void acb_poly_one(acb_poly_t poly) Sets *poly* to the constant polynomial 1. .. function:: void acb_poly_set(acb_poly_t dest, const acb_poly_t src) Sets *dest* to a copy of *src*. .. function:: void acb_poly_set_round(acb_poly_t dest, const acb_poly_t src, slong prec) Sets *dest* to a copy of *src*, rounded to *prec* bits. .. function:: void acb_poly_set_trunc(acb_poly_t dest, const acb_poly_t src, slong n) .. function:: void acb_poly_set_trunc_round(acb_poly_t dest, const acb_poly_t src, slong n, slong prec) Sets *dest* to a copy of *src*, truncated to length *n* and rounded to *prec* bits. .. function:: void acb_poly_set_coeff_si(acb_poly_t poly, slong n, slong c) .. function:: void acb_poly_set_coeff_acb(acb_poly_t poly, slong n, const acb_t c) Sets the coefficient with index *n* in *poly* to the value *c*. We require that *n* is nonnegative. .. function:: void acb_poly_get_coeff_acb(acb_t v, const acb_poly_t poly, slong n) Sets *v* to the value of the coefficient with index *n* in *poly*. We require that *n* is nonnegative. .. macro:: acb_poly_get_coeff_ptr(poly, n) Given `n \ge 0`, returns a pointer to coefficient *n* of *poly*, or *NULL* if *n* exceeds the length of *poly*. .. function:: void _acb_poly_shift_right(acb_ptr res, acb_srcptr poly, slong len, slong n) .. function:: void acb_poly_shift_right(acb_poly_t res, const acb_poly_t poly, slong n) Sets *res* to *poly* divided by `x^n`, throwing away the lower coefficients. We require that *n* is nonnegative. .. function:: void _acb_poly_shift_left(acb_ptr res, acb_srcptr poly, slong len, slong n) .. function:: void acb_poly_shift_left(acb_poly_t res, const acb_poly_t poly, slong n) Sets *res* to *poly* multiplied by `x^n`. We require that *n* is nonnegative. .. function:: void acb_poly_truncate(acb_poly_t poly, slong n) Truncates *poly* to have length at most *n*, i.e. degree strictly smaller than *n*. We require that *n* is nonnegative. .. function:: slong acb_poly_valuation(const acb_poly_t poly) Returns the degree of the lowest term that is not exactly zero in *poly*. Returns -1 if *poly* is the zero polynomial. Input and output ------------------------------------------------------------------------------- .. function:: void acb_poly_printd(const acb_poly_t poly, slong digits) Prints the polynomial as an array of coefficients, printing each coefficient using *acb_printd*. .. function:: void acb_poly_fprintd(FILE * file, const acb_poly_t poly, slong digits) Prints the polynomial as an array of coefficients to the stream *file*, printing each coefficient using *acb_fprintd*. Random generation ------------------------------------------------------------------------------- .. function:: void acb_poly_randtest(acb_poly_t poly, flint_rand_t state, slong len, slong prec, slong mag_bits) Creates a random polynomial with length at most *len*. Comparisons ------------------------------------------------------------------------------- .. function:: int acb_poly_equal(const acb_poly_t A, const acb_poly_t B) Returns nonzero iff *A* and *B* are identical as interval polynomials. .. function:: int acb_poly_contains(const acb_poly_t poly1, const acb_poly_t poly2) .. function:: int acb_poly_contains_fmpz_poly(const acb_poly_t poly1, const fmpz_poly_t poly2) .. function:: int acb_poly_contains_fmpq_poly(const acb_poly_t poly1, const fmpq_poly_t poly2) Returns nonzero iff *poly2* is contained in *poly1*. .. function:: int _acb_poly_overlaps(acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2) .. function:: int acb_poly_overlaps(const acb_poly_t poly1, const acb_poly_t poly2) Returns nonzero iff *poly1* overlaps with *poly2*. The underscore function requires that *len1* ist at least as large as *len2*. .. function:: int acb_poly_get_unique_fmpz_poly(fmpz_poly_t z, const acb_poly_t x) If *x* contains a unique integer polynomial, sets *z* to that value and returns nonzero. Otherwise (if *x* represents no integers or more than one integer), returns zero, possibly partially modifying *z*. .. function:: int acb_poly_is_real(const acb_poly_t poly) Returns nonzero iff all coefficients in *poly* have zero imaginary part. Conversions ------------------------------------------------------------------------------- .. function:: void acb_poly_set_fmpz_poly(acb_poly_t poly, const fmpz_poly_t re, slong prec) .. function:: void acb_poly_set2_fmpz_poly(acb_poly_t poly, const fmpz_poly_t re, const fmpz_poly_t im, slong prec) .. function:: void acb_poly_set_arb_poly(acb_poly_t poly, const arb_poly_t re) .. function:: void acb_poly_set2_arb_poly(acb_poly_t poly, const arb_poly_t re, const arb_poly_t im) .. function:: void acb_poly_set_fmpq_poly(acb_poly_t poly, const fmpq_poly_t re, slong prec) .. function:: void acb_poly_set2_fmpq_poly(acb_poly_t poly, const fmpq_poly_t re, const fmpq_poly_t im, slong prec) Sets *poly* to the given real part *re* plus the imaginary part *im*, both rounded to *prec* bits. .. function:: void acb_poly_set_acb(acb_poly_t poly, const acb_t src) .. function:: void acb_poly_set_si(acb_poly_t poly, slong src) Sets *poly* to *src*. Bounds ------------------------------------------------------------------------------- .. function:: void _acb_poly_majorant(arb_ptr res, acb_srcptr poly, slong len, slong prec) .. function:: void acb_poly_majorant(arb_poly_t res, const acb_poly_t poly, slong prec) Sets *res* to an exact real polynomial whose coefficients are upper bounds for the absolute values of the coefficients in *poly*, rounded to *prec* bits. Arithmetic ------------------------------------------------------------------------------- .. function:: void _acb_poly_add(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) Sets *{C, max(lenA, lenB)}* to the sum of *{A, lenA}* and *{B, lenB}*. Allows aliasing of the input and output operands. .. function:: void acb_poly_add(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong prec) .. function:: void acb_poly_add_si(acb_poly_t C, const acb_poly_t A, slong B, slong prec) Sets *C* to the sum of *A* and *B*. .. function:: void _acb_poly_sub(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) Sets *{C, max(lenA, lenB)}* to the difference of *{A, lenA}* and *{B, lenB}*. Allows aliasing of the input and output operands. .. function:: void acb_poly_sub(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong prec) Sets *C* to the difference of *A* and *B*. .. function:: void acb_poly_add_series(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong len, slong prec) Sets *C* to the sum of *A* and *B*, truncated to length *len*. .. function:: void acb_poly_sub_series(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong len, slong prec) Sets *C* to the difference of *A* and *B*, truncated to length *len*. .. function:: void acb_poly_neg(acb_poly_t C, const acb_poly_t A) Sets *C* to the negation of *A*. .. function:: void acb_poly_scalar_mul_2exp_si(acb_poly_t C, const acb_poly_t A, slong c) Sets *C* to *A* multiplied by `2^c`. .. function:: void acb_poly_scalar_mul(acb_poly_t C, const acb_poly_t A, const acb_t c, slong prec) Sets *C* to *A* multiplied by *c*. .. function:: void acb_poly_scalar_div(acb_poly_t C, const acb_poly_t A, const acb_t c, slong prec) Sets *C* to *A* divided by *c*. .. function:: void _acb_poly_mullow_classical(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong n, slong prec) .. function:: void _acb_poly_mullow_transpose(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong n, slong prec) .. function:: void _acb_poly_mullow_transpose_gauss(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong n, slong prec) .. function:: void _acb_poly_mullow(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong n, slong prec) Sets *{C, n}* to the product of *{A, lenA}* and *{B, lenB}*, truncated to length *n*. The output is not allowed to be aliased with either of the inputs. We require `\mathrm{lenA} \ge \mathrm{lenB} > 0`, `n > 0`, `\mathrm{lenA} + \mathrm{lenB} - 1 \ge n`. The *classical* version uses a plain loop. The *transpose* version evaluates the product using four real polynomial multiplications (via :func:`_arb_poly_mullow`). The *transpose_gauss* version evaluates the product using three real polynomial multiplications. This is almost always faster than *transpose*, but has worse numerical stability when the coefficients vary in magnitude. The default function :func:`_acb_poly_mullow` automatically switches been *classical* and *transpose* multiplication. If the input pointers are identical (and the lengths are the same), they are assumed to represent the same polynomial, and its square is computed. .. function:: void acb_poly_mullow_classical(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong n, slong prec) .. function:: void acb_poly_mullow_transpose(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong n, slong prec) .. function:: void acb_poly_mullow_transpose_gauss(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong n, slong prec) .. function:: void acb_poly_mullow(acb_poly_t C, const acb_poly_t A, const acb_poly_t B, slong n, slong prec) Sets *C* to the product of *A* and *B*, truncated to length *n*. If the same variable is passed for *A* and *B*, sets *C* to the square of *A* truncated to length *n*. .. function:: void _acb_poly_mul(acb_ptr C, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) Sets *{C, lenA + lenB - 1}* to the product of *{A, lenA}* and *{B, lenB}*. The output is not allowed to be aliased with either of the inputs. We require `\mathrm{lenA} \ge \mathrm{lenB} > 0`. This function is implemented as a simple wrapper for :func:`_acb_poly_mullow`. If the input pointers are identical (and the lengths are the same), they are assumed to represent the same polynomial, and its square is computed. .. function:: void acb_poly_mul(acb_poly_t C, const acb_poly_t A1, const acb_poly_t B2, slong prec) Sets *C* to the product of *A* and *B*. If the same variable is passed for *A* and *B*, sets *C* to the square of *A*. .. function:: void _acb_poly_inv_series(acb_ptr Qinv, acb_srcptr Q, slong Qlen, slong len, slong prec) Sets *{Qinv, len}* to the power series inverse of *{Q, Qlen}*. Uses Newton iteration. .. function:: void acb_poly_inv_series(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec) Sets *Qinv* to the power series inverse of *Q*. .. function:: void _acb_poly_div_series(acb_ptr Q, acb_srcptr A, slong Alen, acb_srcptr B, slong Blen, slong n, slong prec) Sets *{Q, n}* to the power series quotient of *{A, Alen}* by *{B, Blen}*. Uses Newton iteration followed by multiplication. .. function:: void acb_poly_div_series(acb_poly_t Q, const acb_poly_t A, const acb_poly_t B, slong n, slong prec) Sets *Q* to the power series quotient *A* divided by *B*, truncated to length *n*. .. function:: void _acb_poly_div(acb_ptr Q, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) .. function:: void _acb_poly_rem(acb_ptr R, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) .. function:: void _acb_poly_divrem(acb_ptr Q, acb_ptr R, acb_srcptr A, slong lenA, acb_srcptr B, slong lenB, slong prec) .. function:: int acb_poly_divrem(acb_poly_t Q, acb_poly_t R, const acb_poly_t A, const acb_poly_t B, slong prec) Performs polynomial division with remainder, computing a quotient `Q` and a remainder `R` such that `A = BQ + R`. The implementation reverses the inputs and performs power series division. If the leading coefficient of `B` contains zero (or if `B` is identically zero), returns 0 indicating failure without modifying the outputs. Otherwise returns nonzero. .. function:: void _acb_poly_div_root(acb_ptr Q, acb_t R, acb_srcptr A, slong len, const acb_t c, slong prec) Divides `A` by the polynomial `x - c`, computing the quotient `Q` as well as the remainder `R = f(c)`. Composition ------------------------------------------------------------------------------- .. function:: void _acb_poly_taylor_shift_horner(acb_ptr g, const acb_t c, slong n, slong prec) .. function:: void acb_poly_taylor_shift_horner(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) .. function:: void _acb_poly_taylor_shift_divconquer(acb_ptr g, const acb_t c, slong n, slong prec) .. function:: void acb_poly_taylor_shift_divconquer(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) .. function:: void _acb_poly_taylor_shift_convolution(acb_ptr g, const acb_t c, slong n, slong prec) .. function:: void acb_poly_taylor_shift_convolution(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) .. function:: void _acb_poly_taylor_shift(acb_ptr g, const acb_t c, slong n, slong prec) .. function:: void acb_poly_taylor_shift(acb_poly_t g, const acb_poly_t f, const acb_t c, slong prec) Sets *g* to the Taylor shift `f(x+c)`, computed respectively using an optimized form of Horner's rule, divide-and-conquer, a single convolution, and an automatic choice between the three algorithms. The underscore methods act in-place on *g* = *f* which has length *n*. .. function:: void _acb_poly_compose_horner(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) .. function:: void acb_poly_compose_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) .. function:: void _acb_poly_compose_divconquer(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) .. function:: void acb_poly_compose_divconquer(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) .. function:: void _acb_poly_compose(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong prec) .. function:: void acb_poly_compose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong prec) Sets *res* to the composition `h(x) = f(g(x))` where `f` is given by *poly1* and `g` is given by *poly2*, respectively using Horner's rule, divide-and-conquer, and an automatic choice between the two algorithms. The default algorithm also handles special-form input `g = ax^n + c` efficiently by performing a Taylor shift followed by a rescaling. The underscore methods do not support aliasing of the output with either input polynomial. .. function:: void _acb_poly_compose_series_horner(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) .. function:: void acb_poly_compose_series_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) .. function:: void _acb_poly_compose_series_brent_kung(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) .. function:: void acb_poly_compose_series_brent_kung(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) .. function:: void _acb_poly_compose_series(acb_ptr res, acb_srcptr poly1, slong len1, acb_srcptr poly2, slong len2, slong n, slong prec) .. function:: void acb_poly_compose_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, slong n, slong prec) Sets *res* to the power series composition `h(x) = f(g(x))` truncated to order `O(x^n)` where `f` is given by *poly1* and `g` is given by *poly2*, respectively using Horner's rule, the Brent-Kung baby step-giant step algorithm, and an automatic choice between the two algorithms. The default algorithm also handles special-form input `g = ax^n` efficiently. We require that the constant term in `g(x)` is exactly zero. The underscore methods do not support aliasing of the output with either input polynomial. .. function:: void _acb_poly_revert_series_lagrange(acb_ptr h, acb_srcptr f, slong flen, slong n, slong prec) .. function:: void acb_poly_revert_series_lagrange(acb_poly_t h, const acb_poly_t f, slong n, slong prec) .. function:: void _acb_poly_revert_series_newton(acb_ptr h, acb_srcptr f, slong flen, slong n, slong prec) .. function:: void acb_poly_revert_series_newton(acb_poly_t h, const acb_poly_t f, slong n, slong prec) .. function:: void _acb_poly_revert_series_lagrange_fast(acb_ptr h, acb_srcptr f, slong flen, slong n, slong prec) .. function:: void acb_poly_revert_series_lagrange_fast(acb_poly_t h, const acb_poly_t f, slong n, slong prec) .. function:: void _acb_poly_revert_series(acb_ptr h, acb_srcptr f, slong flen, slong n, slong prec) .. function:: void acb_poly_revert_series(acb_poly_t h, const acb_poly_t f, slong n, slong prec) Sets `h` to the power series reversion of `f`, i.e. the expansion of the compositional inverse function `f^{-1}(x)`, truncated to order `O(x^n)`, using respectively Lagrange inversion, Newton iteration, fast Lagrange inversion, and a default algorithm choice. We require that the constant term in `f` is exactly zero and that the linear term is nonzero. The underscore methods assume that *flen* is at least 2, and do not support aliasing. Evaluation ------------------------------------------------------------------------------- .. function:: void _acb_poly_evaluate_horner(acb_t y, acb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void acb_poly_evaluate_horner(acb_t y, const acb_poly_t f, const acb_t x, slong prec) .. function:: void _acb_poly_evaluate_rectangular(acb_t y, acb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void acb_poly_evaluate_rectangular(acb_t y, const acb_poly_t f, const acb_t x, slong prec) .. function:: void _acb_poly_evaluate(acb_t y, acb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void acb_poly_evaluate(acb_t y, const acb_poly_t f, const acb_t x, slong prec) Sets `y = f(x)`, evaluated respectively using Horner's rule, rectangular splitting, and an automatic algorithm choice. .. function:: void _acb_poly_evaluate2_horner(acb_t y, acb_t z, acb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void acb_poly_evaluate2_horner(acb_t y, acb_t z, const acb_poly_t f, const acb_t x, slong prec) .. function:: void _acb_poly_evaluate2_rectangular(acb_t y, acb_t z, acb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void acb_poly_evaluate2_rectangular(acb_t y, acb_t z, const acb_poly_t f, const acb_t x, slong prec) .. function:: void _acb_poly_evaluate2(acb_t y, acb_t z, acb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void acb_poly_evaluate2(acb_t y, acb_t z, const acb_poly_t f, const acb_t x, slong prec) Sets `y = f(x), z = f'(x)`, evaluated respectively using Horner's rule, rectangular splitting, and an automatic algorithm choice. When Horner's rule is used, the only advantage of evaluating the function and its derivative simultaneously is that one does not have to generate the derivative polynomial explicitly. With the rectangular splitting algorithm, the powers can be reused, making simultaneous evaluation slightly faster. Product trees ------------------------------------------------------------------------------- .. function:: void _acb_poly_product_roots(acb_ptr poly, acb_srcptr xs, slong n, slong prec) .. function:: void acb_poly_product_roots(acb_poly_t poly, acb_srcptr xs, slong n, slong prec) Generates the polynomial `(x-x_0)(x-x_1)\cdots(x-x_{n-1})`. .. function:: acb_ptr * _acb_poly_tree_alloc(slong len) Returns an initialized data structured capable of representing a remainder tree (product tree) of *len* roots. .. function:: void _acb_poly_tree_free(acb_ptr * tree, slong len) Deallocates a tree structure as allocated using *_acb_poly_tree_alloc*. .. function:: void _acb_poly_tree_build(acb_ptr * tree, acb_srcptr roots, slong len, slong prec) Constructs a product tree from a given array of *len* roots. The tree structure must be pre-allocated to the specified length using :func:`_acb_poly_tree_alloc`. Multipoint evaluation ------------------------------------------------------------------------------- .. function:: void _acb_poly_evaluate_vec_iter(acb_ptr ys, acb_srcptr poly, slong plen, acb_srcptr xs, slong n, slong prec) .. function:: void acb_poly_evaluate_vec_iter(acb_ptr ys, const acb_poly_t poly, acb_srcptr xs, slong n, slong prec) Evaluates the polynomial simultaneously at *n* given points, calling :func:`_acb_poly_evaluate` repeatedly. .. function:: void _acb_poly_evaluate_vec_fast_precomp(acb_ptr vs, acb_srcptr poly, slong plen, acb_ptr * tree, slong len, slong prec) .. function:: void _acb_poly_evaluate_vec_fast(acb_ptr ys, acb_srcptr poly, slong plen, acb_srcptr xs, slong n, slong prec) .. function:: void acb_poly_evaluate_vec_fast(acb_ptr ys, const acb_poly_t poly, acb_srcptr xs, slong n, slong prec) Evaluates the polynomial simultaneously at *n* given points, using fast multipoint evaluation. Interpolation ------------------------------------------------------------------------------- .. function:: void _acb_poly_interpolate_newton(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) .. function:: void acb_poly_interpolate_newton(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) Recovers the unique polynomial of length at most *n* that interpolates the given *x* and *y* values. This implementation first interpolates in the Newton basis and then converts back to the monomial basis. .. function:: void _acb_poly_interpolate_barycentric(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) .. function:: void acb_poly_interpolate_barycentric(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) Recovers the unique polynomial of length at most *n* that interpolates the given *x* and *y* values. This implementation uses the barycentric form of Lagrange interpolation. .. function:: void _acb_poly_interpolation_weights(acb_ptr w, acb_ptr * tree, slong len, slong prec) .. function:: void _acb_poly_interpolate_fast_precomp(acb_ptr poly, acb_srcptr ys, acb_ptr * tree, acb_srcptr weights, slong len, slong prec) .. function:: void _acb_poly_interpolate_fast(acb_ptr poly, acb_srcptr xs, acb_srcptr ys, slong len, slong prec) .. function:: void acb_poly_interpolate_fast(acb_poly_t poly, acb_srcptr xs, acb_srcptr ys, slong n, slong prec) Recovers the unique polynomial of length at most *n* that interpolates the given *x* and *y* values, using fast Lagrange interpolation. The precomp function takes a precomputed product tree over the *x* values and a vector of interpolation weights as additional inputs. Differentiation ------------------------------------------------------------------------------- .. function:: void _acb_poly_derivative(acb_ptr res, acb_srcptr poly, slong len, slong prec) Sets *{res, len - 1}* to the derivative of *{poly, len}*. Allows aliasing of the input and output. .. function:: void acb_poly_derivative(acb_poly_t res, const acb_poly_t poly, slong prec) Sets *res* to the derivative of *poly*. .. function:: void _acb_poly_integral(acb_ptr res, acb_srcptr poly, slong len, slong prec) Sets *{res, len}* to the integral of *{poly, len - 1}*. Allows aliasing of the input and output. .. function:: void acb_poly_integral(acb_poly_t res, const acb_poly_t poly, slong prec) Sets *res* to the integral of *poly*. Transforms ------------------------------------------------------------------------------- .. function:: void _acb_poly_borel_transform(acb_ptr res, acb_srcptr poly, slong len, slong prec) .. function:: void acb_poly_borel_transform(acb_poly_t res, const acb_poly_t poly, slong prec) Computes the Borel transform of the input polynomial, mapping `\sum_k a_k x^k` to `\sum_k (a_k / k!) x^k`. The underscore method allows aliasing. .. function:: void _acb_poly_inv_borel_transform(acb_ptr res, acb_srcptr poly, slong len, slong prec) .. function:: void acb_poly_inv_borel_transform(acb_poly_t res, const acb_poly_t poly, slong prec) Computes the inverse Borel transform of the input polynomial, mapping `\sum_k a_k x^k` to `\sum_k a_k k! x^k`. The underscore method allows aliasing. .. function:: void _acb_poly_binomial_transform_basecase(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec) .. function:: void acb_poly_binomial_transform_basecase(acb_poly_t b, const acb_poly_t a, slong len, slong prec) .. function:: void _acb_poly_binomial_transform_convolution(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec) .. function:: void acb_poly_binomial_transform_convolution(acb_poly_t b, const acb_poly_t a, slong len, slong prec) .. function:: void _acb_poly_binomial_transform(acb_ptr b, acb_srcptr a, slong alen, slong len, slong prec) .. function:: void acb_poly_binomial_transform(acb_poly_t b, const acb_poly_t a, slong len, slong prec) Computes the binomial transform of the input polynomial, truncating the output to length *len*. See :func:`arb_poly_binomial_transform` for details. The underscore methods do not support aliasing, and assume that the lengths are nonzero. .. function:: void _acb_poly_graeffe_transform(acb_ptr b, acb_srcptr a, slong len, slong prec) .. function:: void acb_poly_graeffe_transform(acb_poly_t b, acb_poly_t a, slong prec) Computes the Graeffe transform of input polynomial, which is of length *len*. See :func:`arb_poly_graeffe_transform` for details. The underscore method assumes that *a* and *b* are initialized, *a* is of length *len*, and *b* is of length at least *len*. Both methods allow aliasing. Elementary functions ------------------------------------------------------------------------------- .. function:: void _acb_poly_pow_ui_trunc_binexp(acb_ptr res, acb_srcptr f, slong flen, ulong exp, slong len, slong prec) Sets *{res, len}* to *{f, flen}* raised to the power *exp*, truncated to length *len*. Requires that *len* is no longer than the length of the power as computed without truncation (i.e. no zero-padding is performed). Does not support aliasing of the input and output, and requires that *flen* and *len* are positive. Uses binary exponentiation. .. function:: void acb_poly_pow_ui_trunc_binexp(acb_poly_t res, const acb_poly_t poly, ulong exp, slong len, slong prec) Sets *res* to *poly* raised to the power *exp*, truncated to length *len*. Uses binary exponentiation. .. function:: void _acb_poly_pow_ui(acb_ptr res, acb_srcptr f, slong flen, ulong exp, slong prec) Sets *res* to *{f, flen}* raised to the power *exp*. Does not support aliasing of the input and output, and requires that *flen* is positive. .. function:: void acb_poly_pow_ui(acb_poly_t res, const acb_poly_t poly, ulong exp, slong prec) Sets *res* to *poly* raised to the power *exp*. .. function:: void _acb_poly_pow_series(acb_ptr h, acb_srcptr f, slong flen, acb_srcptr g, slong glen, slong len, slong prec) Sets *{h, len}* to the power series `f(x)^{g(x)} = \exp(g(x) \log f(x))` truncated to length *len*. This function detects special cases such as *g* being an exact small integer or `\pm 1/2`, and computes such powers more efficiently. This function does not support aliasing of the output with either of the input operands. It requires that all lengths are positive, and assumes that *flen* and *glen* do not exceed *len*. .. function:: void acb_poly_pow_series(acb_poly_t h, const acb_poly_t f, const acb_poly_t g, slong len, slong prec) Sets *h* to the power series `f(x)^{g(x)} = \exp(g(x) \log f(x))` truncated to length *len*. This function detects special cases such as *g* being an exact small integer or `\pm 1/2`, and computes such powers more efficiently. .. function:: void _acb_poly_pow_acb_series(acb_ptr h, acb_srcptr f, slong flen, const acb_t g, slong len, slong prec) Sets *{h, len}* to the power series `f(x)^g = \exp(g \log f(x))` truncated to length *len*. This function detects special cases such as *g* being an exact small integer or `\pm 1/2`, and computes such powers more efficiently. This function does not support aliasing of the output with either of the input operands. It requires that all lengths are positive, and assumes that *flen* does not exceed *len*. .. function:: void acb_poly_pow_acb_series(acb_poly_t h, const acb_poly_t f, const acb_t g, slong len, slong prec) Sets *h* to the power series `f(x)^g = \exp(g \log f(x))` truncated to length *len*. .. function:: void _acb_poly_sqrt_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sqrt_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) Sets *g* to the power series square root of *h*, truncated to length *n*. Uses division-free Newton iteration for the reciprocal square root, followed by a multiplication. The underscore method does not support aliasing of the input and output arrays. It requires that *hlen* and *n* are greater than zero. .. function:: void _acb_poly_rsqrt_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_rsqrt_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) Sets *g* to the reciprocal power series square root of *h*, truncated to length *n*. Uses division-free Newton iteration. The underscore method does not support aliasing of the input and output arrays. It requires that *hlen* and *n* are greater than zero. .. function:: void _acb_poly_log_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec) .. function:: void acb_poly_log_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) Sets *res* to the power series logarithm of *f*, truncated to length *n*. Uses the formula `\log(f(x)) = \int f'(x) / f(x) dx`, adding the logarithm of the constant term in *f* as the constant of integration. The underscore method supports aliasing of the input and output arrays. It requires that *flen* and *n* are greater than zero. .. function:: void _acb_poly_log1p_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec) .. function:: void acb_poly_log1p_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) Computes the power series `\log(1+f)`, with better accuracy when the constant term of *f* is small. .. function:: void _acb_poly_atan_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec) .. function:: void acb_poly_atan_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec) Sets *res* the power series inverse tangent of *f*, truncated to length *n*. Uses the formula .. math :: \tan^{-1}(f(x)) = \int f'(x) / (1+f(x)^2) dx, adding the function of the constant term in *f* as the constant of integration. The underscore method supports aliasing of the input and output arrays. It requires that *flen* and *n* are greater than zero. .. function:: void _acb_poly_exp_series_basecase(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_exp_series_basecase(acb_poly_t f, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_exp_series(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_exp_series(acb_poly_t f, const acb_poly_t h, slong n, slong prec) Sets `f` to the power series exponential of `h`, truncated to length `n`. The basecase version uses a simple recurrence for the coefficients, requiring `O(nm)` operations where `m` is the length of `h`. The main implementation uses Newton iteration, starting from a small number of terms given by the basecase algorithm. The complexity is `O(M(n))`. Redundant operations in the Newton iteration are avoided by using the scheme described in [HZ2004]_. The underscore methods support aliasing and allow the input to be shorter than the output, but require the lengths to be nonzero. .. function:: void _acb_poly_exp_pi_i_series(acb_ptr f, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_exp_pi_i_series(acb_poly_t f, const acb_poly_t h, slong n, slong prec) Sets *f* to the power series `\exp(\pi i h)` truncated to length *n*. The underscore method supports aliasing and allows the input to be shorter than the output, but requires the lengths to be nonzero. .. function:: void _acb_poly_sin_cos_series_basecase(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec, int times_pi) .. function:: void acb_poly_sin_cos_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec, int times_pi) .. function:: void _acb_poly_sin_cos_series_tangent(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec, int times_pi) .. function:: void acb_poly_sin_cos_series_tangent(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec, int times_pi) .. function:: void _acb_poly_sin_cos_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sin_cos_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) Sets *s* and *c* to the power series sine and cosine of *h*, computed simultaneously. The *basecase* version uses a simple recurrence for the coefficients, requiring `O(nm)` operations where `m` is the length of `h`. The *tangent* version uses the tangent half-angle formulas to compute the sine and cosine via :func:`_acb_poly_tan_series`. This requires `O(M(n))` operations. When `h = h_0 + h_1` where the constant term `h_0` is nonzero, the evaluation is done as `\sin(h_0 + h_1) = \cos(h_0) \sin(h_1) + \sin(h_0) \cos(h_1)`, `\cos(h_0 + h_1) = \cos(h_0) \cos(h_1) - \sin(h_0) \sin(h_1)`, to improve accuracy and avoid dividing by zero at the poles of the tangent function. The default version automatically selects between the *basecase* and *tangent* algorithms depending on the input. The *basecase* and *tangent* versions take a flag *times_pi* specifying that the input is to be multiplied by `\pi`. The underscore methods support aliasing and require the lengths to be nonzero. .. function:: void _acb_poly_sin_series(acb_ptr s, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sin_series(acb_poly_t s, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_cos_series(acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_cos_series(acb_poly_t c, const acb_poly_t h, slong n, slong prec) Respectively evaluates the power series sine or cosine. These functions simply wrap :func:`_acb_poly_sin_cos_series`. The underscore methods support aliasing and require the lengths to be nonzero. .. function:: void _acb_poly_tan_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) .. function:: void acb_poly_tan_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec) Sets *g* to the power series tangent of *h*. For small *n* takes the quotient of the sine and cosine as computed using the basecase algorithm. For large *n*, uses Newton iteration to invert the inverse tangent series. The complexity is `O(M(n))`. The underscore version does not support aliasing, and requires the lengths to be nonzero. .. function:: void _acb_poly_sin_cos_pi_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sin_cos_pi_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_sin_pi_series(acb_ptr s, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sin_pi_series(acb_poly_t s, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_cos_pi_series(acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_cos_pi_series(acb_poly_t c, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_cot_pi_series(acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_cot_pi_series(acb_poly_t c, const acb_poly_t h, slong n, slong prec) Compute the respective trigonometric functions of the input multiplied by `\pi`. .. function:: void _acb_poly_sinh_cosh_series_basecase(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sinh_cosh_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_sinh_cosh_series_exponential(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sinh_cosh_series_exponential(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_sinh_cosh_series(acb_ptr s, acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sinh_cosh_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_sinh_series(acb_ptr s, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sinh_series(acb_poly_t s, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_cosh_series(acb_ptr c, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_cosh_series(acb_poly_t c, const acb_poly_t h, slong n, slong prec) Sets *s* and *c* respectively to the hyperbolic sine and cosine of the power series *h*, truncated to length *n*. The implementations mirror those for sine and cosine, except that the *exponential* version computes both functions using the exponential function instead of the hyperbolic tangent. .. function:: void _acb_poly_sinc_series(acb_ptr s, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_sinc_series(acb_poly_t s, const acb_poly_t h, slong n, slong prec) Sets *s* to the sinc function of the power series *h*, truncated to length *n*. Lambert W function ------------------------------------------------------------------------------- .. function:: void _acb_poly_lambertw_series(acb_ptr res, acb_srcptr z, slong zlen, const fmpz_t k, int flags, slong len, slong prec) .. function:: void acb_poly_lambertw_series(acb_poly_t res, const acb_poly_t z, const fmpz_t k, int flags, slong len, slong prec) Sets *res* to branch *k* of the Lambert W function of the power series *z*. The argument *flags* is reserved for future use. The underscore method allows aliasing, but assumes that the lengths are nonzero. Gamma function ------------------------------------------------------------------------------- .. function:: void _acb_poly_gamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_gamma_series(acb_poly_t res, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_rgamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_rgamma_series(acb_poly_t res, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_lgamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_lgamma_series(acb_poly_t res, const acb_poly_t h, slong n, slong prec) .. function:: void _acb_poly_digamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong n, slong prec) .. function:: void acb_poly_digamma_series(acb_poly_t res, const acb_poly_t h, slong n, slong prec) Sets *res* to the series expansion of `\Gamma(h(x))`, `1/\Gamma(h(x))`, or `\log \Gamma(h(x))`, `\psi(h(x))`, truncated to length *n*. These functions first generate the Taylor series at the constant term of *h*, and then call :func:`_acb_poly_compose_series`. The Taylor coefficients are generated using Stirling's series. The underscore methods support aliasing of the input and output arrays, and require that *hlen* and *n* are greater than zero. .. function:: void _acb_poly_rising_ui_series(acb_ptr res, acb_srcptr f, slong flen, ulong r, slong trunc, slong prec) .. function:: void acb_poly_rising_ui_series(acb_poly_t res, const acb_poly_t f, ulong r, slong trunc, slong prec) Sets *res* to the rising factorial `(f) (f+1) (f+2) \cdots (f+r-1)`, truncated to length *trunc*. The underscore method assumes that *flen*, *r* and *trunc* are at least 1, and does not support aliasing. Uses binary splitting. Power sums ------------------------------------------------------------------------------- .. function:: void _acb_poly_powsum_series_naive(acb_ptr z, const acb_t s, const acb_t a, const acb_t q, slong n, slong len, slong prec) .. function:: void _acb_poly_powsum_series_naive_threaded(acb_ptr z, const acb_t s, const acb_t a, const acb_t q, slong n, slong len, slong prec) Computes .. math :: z = S(s,a,n) = \sum_{k=0}^{n-1} \frac{q^k}{(k+a)^{s+t}} as a power series in `t` truncated to length *len*. This function evaluates the sum naively term by term. The *threaded* version splits the computation over the number of threads returned by *flint_get_num_threads()*. .. function:: void _acb_poly_powsum_one_series_sieved(acb_ptr z, const acb_t s, slong n, slong len, slong prec) Computes .. math :: z = S(s,1,n) \sum_{k=1}^n \frac{1}{k^{s+t}} as a power series in `t` truncated to length *len*. This function stores a table of powers that have already been calculated, computing `(ij)^r` as `i^r j^r` whenever `k = ij` is composite. As a further optimization, it groups all even `k` and evaluates the sum as a polynomial in `2^{-(s+t)}`. This scheme requires about `n / \log n` powers, `n / 2` multiplications, and temporary storage of `n / 6` power series. Due to the extra power series multiplications, it is only faster than the naive algorithm when *len* is small. Zeta function ------------------------------------------------------------------------------- .. function:: void _acb_poly_zeta_em_choose_param(mag_t bound, ulong * N, ulong * M, const acb_t s, const acb_t a, slong d, slong target, slong prec) Chooses *N* and *M* for Euler-Maclaurin summation of the Hurwitz zeta function, using a default algorithm. .. function:: void _acb_poly_zeta_em_bound1(mag_t bound, const acb_t s, const acb_t a, slong N, slong M, slong d, slong wp) .. function:: void _acb_poly_zeta_em_bound(arb_ptr vec, const acb_t s, const acb_t a, ulong N, ulong M, slong d, slong wp) Compute bounds for Euler-Maclaurin evaluation of the Hurwitz zeta function or its power series, using the formulas in [Joh2013]_. .. function:: void _acb_poly_zeta_em_tail_naive(acb_ptr z, const acb_t s, const acb_t Na, acb_srcptr Nasx, slong M, slong len, slong prec) .. function:: void _acb_poly_zeta_em_tail_bsplit(acb_ptr z, const acb_t s, const acb_t Na, acb_srcptr Nasx, slong M, slong len, slong prec) Evaluates the tail in the Euler-Maclaurin sum for the Hurwitz zeta function, respectively using the naive recurrence and binary splitting. .. function:: void _acb_poly_zeta_em_sum(acb_ptr z, const acb_t s, const acb_t a, int deflate, ulong N, ulong M, slong d, slong prec) Evaluates the truncated Euler-Maclaurin sum of order `N, M` for the length-*d* truncated Taylor series of the Hurwitz zeta function `\zeta(s,a)` at `s`, using a working precision of *prec* bits. With `a = 1`, this gives the usual Riemann zeta function. If *deflate* is nonzero, `\zeta(s,a) - 1/(s-1)` is evaluated (which permits series expansion at `s = 1`). .. function:: void _acb_poly_zeta_cpx_series(acb_ptr z, const acb_t s, const acb_t a, int deflate, slong d, slong prec) Computes the series expansion of `\zeta(s+x,a)` (or `\zeta(s+x,a) - 1/(s+x-1)` if *deflate* is nonzero) to order *d*. This function wraps :func:`_acb_poly_zeta_em_sum`, automatically choosing default values for `N, M` using :func:`_acb_poly_zeta_em_choose_param` to target an absolute truncation error of `2^{-\operatorname{prec}}`. .. function:: void _acb_poly_zeta_series(acb_ptr res, acb_srcptr h, slong hlen, const acb_t a, int deflate, slong len, slong prec) .. function:: void acb_poly_zeta_series(acb_poly_t res, const acb_poly_t f, const acb_t a, int deflate, slong n, slong prec) Sets *res* to the Hurwitz zeta function `\zeta(s,a)` where `s` a power series and `a` is a constant, truncated to length *n*. To evaluate the usual Riemann zeta function, set `a = 1`. If *deflate* is nonzero, evaluates `\zeta(s,a) + 1/(1-s)`, which is well-defined as a limit when the constant term of `s` is 1. In particular, expanding `\zeta(s,a) + 1/(1-s)` with `s = 1+x` gives the Stieltjes constants .. math :: \sum_{k=0}^{n-1} \frac{(-1)^k}{k!} \gamma_k(a) x^k`. If `a = 1`, this implementation uses the reflection formula if the midpoint of the constant term of `s` is negative. Other special functions ------------------------------------------------------------------------------- .. function:: void _acb_poly_polylog_cpx_small(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec) .. function:: void _acb_poly_polylog_cpx_zeta(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec) .. function:: void _acb_poly_polylog_cpx(acb_ptr w, const acb_t s, const acb_t z, slong len, slong prec) Sets *w* to the Taylor series with respect to *x* of the polylogarithm `\operatorname{Li}_{s+x}(z)`, where *s* and *z* are given complex constants. The output is computed to length *len* which must be positive. Aliasing between *w* and *s* or *z* is not permitted. The *small* version uses the standard power series expansion with respect to *z*, convergent when `|z| < 1`. The *zeta* version evaluates the polylogarithm as a sum of two Hurwitz zeta functions. The default version automatically delegates to the *small* version when *z* is close to zero, and the *zeta* version otherwise. For further details, see :ref:`algorithms_polylogarithms`. .. function:: void _acb_poly_polylog_series(acb_ptr w, acb_srcptr s, slong slen, const acb_t z, slong len, slong prec) .. function:: void acb_poly_polylog_series(acb_poly_t w, const acb_poly_t s, const acb_t z, slong len, slong prec) Sets *w* to the polylogarithm `\operatorname{Li}_{s}(z)` where *s* is a given power series, truncating the output to length *len*. The underscore method requires all lengths to be positive and supports aliasing between all inputs and outputs. .. function:: void _acb_poly_erf_series(acb_ptr res, acb_srcptr z, slong zlen, slong n, slong prec) .. function:: void acb_poly_erf_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec) Sets *res* to the error function of the power series *z*, truncated to length *n*. These methods are provided for backwards compatibility. See :func:`acb_hypgeom_erf_series`, :func:`acb_hypgeom_erfc_series`, :func:`acb_hypgeom_erfi_series`. .. function:: void _acb_poly_agm1_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_poly_agm1_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec) Sets *res* to the arithmetic-geometric mean of 1 and the power series *z*, truncated to length *n*. See the :ref:`acb_elliptic.h ` module for power series of elliptic functions. The following wrappers are available for backwards compatibility. .. function:: void _acb_poly_elliptic_k_series(acb_ptr res, acb_srcptr z, slong zlen, slong len, slong prec) .. function:: void acb_poly_elliptic_k_series(acb_poly_t res, const acb_poly_t z, slong n, slong prec) .. function:: void _acb_poly_elliptic_p_series(acb_ptr res, acb_srcptr z, slong zlen, const acb_t tau, slong len, slong prec) .. function:: void acb_poly_elliptic_p_series(acb_poly_t res, const acb_poly_t z, const acb_t tau, slong n, slong prec) Root-finding ------------------------------------------------------------------------------- .. function:: void _acb_poly_root_bound_fujiwara(mag_t bound, acb_srcptr poly, slong len) .. function:: void acb_poly_root_bound_fujiwara(mag_t bound, acb_poly_t poly) Sets *bound* to an upper bound for the magnitude of all the complex roots of *poly*. Uses Fujiwara's bound .. math :: 2 \max \left\{\left|\frac{a_{n-1}}{a_n}\right|, \left|\frac{a_{n-2}}{a_n}\right|^{1/2}, \cdots, \left|\frac{a_1}{a_n}\right|^{1/(n-1)}, \left|\frac{a_0}{2a_n}\right|^{1/n} \right\} where `a_0, \ldots, a_n` are the coefficients of *poly*. .. function:: void _acb_poly_root_inclusion(acb_t r, const acb_t m, acb_srcptr poly, acb_srcptr polyder, slong len, slong prec) Given any complex number `m`, and a nonconstant polynomial `f` and its derivative `f'`, sets *r* to a complex interval centered on `m` that is guaranteed to contain at least one root of `f`. Such an interval is obtained by taking a ball of radius `|f(m)/f'(m)| n` where `n` is the degree of `f`. Proof: assume that the distance to the nearest root exceeds `r = |f(m)/f'(m)| n`. Then .. math :: \left|\frac{f'(m)}{f(m)}\right| = \left|\sum_i \frac{1}{m-\zeta_i}\right| \le \sum_i \frac{1}{|m-\zeta_i|} < \frac{n}{r} = \left|\frac{f'(m)}{f(m)}\right| which is a contradiction (see [Kob2010]_). .. function:: slong _acb_poly_validate_roots(acb_ptr roots, acb_srcptr poly, slong len, slong prec) Given a list of approximate roots of the input polynomial, this function sets a rigorous bounding interval for each root, and determines which roots are isolated from all the other roots. It then rearranges the list of roots so that the isolated roots are at the front of the list, and returns the count of isolated roots. If the return value equals the degree of the polynomial, then all roots have been found. If the return value is smaller, all the remaining output intervals are guaranteed to contain roots, but it is possible that not all of the polynomial's roots are contained among them. .. function:: void _acb_poly_refine_roots_durand_kerner(acb_ptr roots, acb_srcptr poly, slong len, slong prec) Refines the given roots simultaneously using a single iteration of the Durand-Kerner method. The radius of each root is set to an approximation of the correction, giving a rough estimate of its error (not a rigorous bound). .. function:: slong _acb_poly_find_roots(acb_ptr roots, acb_srcptr poly, acb_srcptr initial, slong len, slong maxiter, slong prec) .. function:: slong acb_poly_find_roots(acb_ptr roots, const acb_poly_t poly, acb_srcptr initial, slong maxiter, slong prec) Attempts to compute all the roots of the given nonzero polynomial *poly* using a working precision of *prec* bits. If *n* denotes the degree of *poly*, the function writes *n* approximate roots with rigorous error bounds to the preallocated array *roots*, and returns the number of roots that are isolated. If the return value equals the degree of the polynomial, then all roots have been found. If the return value is smaller, all the output intervals are guaranteed to contain roots, but it is possible that not all of the polynomial's roots are contained among them. The roots are computed numerically by performing several steps with the Durand-Kerner method and terminating if the estimated accuracy of the roots approaches the working precision or if the number of steps exceeds *maxiter*, which can be set to zero in order to use a default value. Finally, the approximate roots are validated rigorously. Initial values for the iteration can be provided as the array *initial*. If *initial* is set to *NULL*, default values `(0.4+0.9i)^k` are used. The polynomial is assumed to be squarefree. If there are repeated roots, the iteration is likely to find them (with low numerical accuracy), but the error bounds will not converge as the precision increases. .. function:: int _acb_poly_validate_real_roots(acb_srcptr roots, acb_srcptr poly, slong len, slong prec) .. function:: int acb_poly_validate_real_roots(acb_srcptr roots, const acb_poly_t poly, slong prec) Given a strictly real polynomial *poly* (of length *len*) and isolating intervals for all its complex roots, determines if all the real roots are separated from the non-real roots. If this function returns nonzero, every root enclosure that touches the real axis (as tested by applying :func:`arb_contains_zero` to the imaginary part) corresponds to a real root (its imaginary part can be set to zero), and every other root enclosure corresponds to a non-real root (with known sign for the imaginary part). If this function returns zero, then the signs of the imaginary parts are not known for certain, based on the accuracy of the inputs and the working precision *prec*. arb-2.22.1/doc/source/agm.rst000066400000000000000000000103321417376376500157270ustar00rootroot00000000000000.. _algorithms_agm: Algorithms for the arithmetic-geometric mean =============================================================================== With complex variables, it is convenient to work with the univariate function `M(z) = \operatorname{agm}(1,z)`. The general case is given by `\operatorname{agm}(a,b) = a M(1,b/a)`. Functional equation ------------------------------------------------------------------------------ If the real part of *z* initially is not completely nonnegative, we apply the functional equation `M(z) = (z+1) M(u) / 2` where `u = \sqrt{z} / (z+1)`. Note that *u* has nonnegative real part, absent rounding error. It is not a problem for correctness if rounding makes the interval contain negative points, as this just inflates the final result. For the derivative, the functional equation becomes `M'(z) = [M(u) - (z-1) M'(u) / ((1+z) \sqrt{z})] / 2`. AGM iteration ------------------------------------------------------------------------------ Once *z* is in the right half plane, we can apply the AGM iteration (`2a_{n+1} = a_n + b_n, b_{n+1}^2 = a_n b_n`) directly. The correct square root is given by `\sqrt{a} \sqrt{b}`, which is computed as `\sqrt{ab}, i \sqrt{-ab}, -i \sqrt{-ab}, \sqrt{a} \sqrt{b}` respectively if both *a* and *b* have positive real part, nonnegative imaginary part, nonpositive imaginary part, or otherwise. The iteration should be terminated when `a_n` and `b_n` are close enough. For positive real variables, we can simply take lower and upper bounds to get a correct enclosure at this point. For complex variables, it is shown in [Dup2006]_, p. 87 that, for *z* with nonnegative real part, `|M(z) - a_n| \le |a_n - b_n|`, giving a convenient error bound. Rather than running the AGM iteration until `a_n` and `b_n` agree to `p` bits, it is slightly more efficient to iterate until they agree to about `p/10` bits and finish with a series expansion. With `z = (a-b)/(a+b)`, we have .. math :: \operatorname{agm}(a,b) = \frac{(a+b) \pi}{4 K(z^2)}, valid at least when `|z| < 1` and `a, b` have nonnegative real part, and .. math :: \frac{\pi}{4 K(z^2)} = \tfrac{1}{2} - \tfrac{1}{8} z^2 - \tfrac{5}{128} z^4 - \tfrac{11}{512} z^6 - \tfrac{469}{32768} z^8 + \ldots where the tail is bounded by `\sum_{k=10}^{\infty} |z|^k/64`. First derivative ------------------------------------------------------------------------------ Assuming that *z* is exact and that `|\arg(z)| \le 3 \pi / 4`, we compute `(M(z), M'(z))` simultaneously using a finite difference. The basic inequality we need is `|M(z)| \le \max(1, |z|)`, which is an immediate consequence of the AGM iteration. By Cauchy's integral formula, `|M^{(k)}(z) / k!| \le C D^k` where `C = \max(1, |z| + r)` and `D = 1/r`, for any `0 < r < |z|` (we choose *r* to be of the order `|z| / 4`). Taylor expansion now gives .. math :: \left|\frac{M(z+h) - M(z)}{h} - M'(z)\right| \le \frac{C D^2 h}{1 - D h} \left|\frac{M(z+h) - M(z-h)}{2h} - M'(z)\right| \le \frac{C D^3 h^2}{1 - D h} \left|\frac{M(z+h) + M(z-h)}{2} - M(z)\right| \le \frac{C D^2 h^2}{1 - D h} assuming that *h* is chosen so that it satisfies `h D < 1`. The forward finite difference would require two function evaluations at doubled precision. We use the central difference as it only requires 1.5 times the precision. When *z* is not exact, we evaluate at the midpoint as above and bound the propagated error using derivatives. Again by Cauchy's integral formula, we have .. math :: |M'(z+\varepsilon)| \le \frac{\max(1, |z|+|\varepsilon|+r)}{r} |M''(z+\varepsilon)| \le \frac{2 \max(1, |z|+|\varepsilon|+r)}{r^2} assuming that the circle centered on *z* with radius `|\varepsilon| + r` does not cross the negative half axis. We choose *r* of order `|z| / 2` and verify that all assumptions hold. Higher derivatives ------------------------------------------------------------------------------- The function `W(z) = 1 / M(z)` is D-finite. The coefficients of `W(z+x) = \sum_{k=0}^{\infty} c_k x^k` satisfy .. math :: -2 z (z^2-1) c_2 = (3z^2-1) c_1 + z c_0, .. math :: -(k+2)(k+3) z (z^2-1) c_{k+3} = (k+2)^2 (3z^2-1) c_{k+2} + (3k(k+3)+7)z c_{k+1} + (k+1)^2 c_{k} in general, and .. math :: -(k+2)^2 c_{k+2} = (3k(k+3)+7) c_{k+1} + (k+1)^2 c_{k} when `z = 1`. arb-2.22.1/doc/source/arb.rst000066400000000000000000002314771417376376500157460ustar00rootroot00000000000000.. _arb: **arb.h** -- real numbers =============================================================================== An :type:`arb_t` represents a ball over the real numbers, that is, an interval `[m \pm r] \equiv [m-r, m+r]` where the midpoint `m` and the radius `r` are (extended) real numbers and `r` is nonnegative (possibly infinite). The result of an (approximate) operation done on :type:`arb_t` variables is a ball which contains the result of the (mathematically exact) operation applied to any choice of points in the input balls. In general, the output ball is not the smallest possible. The precision parameter passed to each function roughly indicates the precision to which calculations on the midpoint are carried out (operations on the radius are always done using a fixed, small precision.) For arithmetic operations, the precision parameter currently simply specifies the precision of the corresponding :type:`arf_t` operation. In the future, the arithmetic might be made faster by incorporating sloppy rounding (typically equivalent to a loss of 1-2 bits of effective working precision) when the result is known to be inexact (while still propagating errors rigorously, of course). Arithmetic operations done on exact input with exactly representable output are always guaranteed to produce exact output. For more complex operations, the precision parameter indicates a minimum working precision (algorithms might allocate extra internal precision to attempt to produce an output accurate to the requested number of bits, especially when the required precision can be estimated easily, but this is not generally required). If the precision is increased and the inputs either are exact or are computed with increased accuracy as well, the output should converge proportionally, absent any bugs. The general intended strategy for using ball arithmetic is to add a few guard bits, and then repeat the calculation as necessary with an exponentially increasing number of guard bits (Ziv's strategy) until the result is exact enough for one's purposes (typically the first attempt will be successful). The following balls with an infinite or NaN component are permitted, and may be returned as output from functions. * The ball `[+\infty \pm c]`, where `c` is finite, represents the point at positive infinity. Such a ball can always be replaced by `[+\infty \pm 0]` while preserving mathematical correctness (this is currently not done automatically by the library). * The ball `[-\infty \pm c]`, where `c` is finite, represents the point at negative infinity. Such a ball can always be replaced by `[-\infty \pm 0]` while preserving mathematical correctness (this is currently not done automatically by the library). * The ball `[c \pm \infty]`, where `c` is finite or infinite, represents the whole extended real line `[-\infty,+\infty]`. Such a ball can always be replaced by `[0 \pm \infty]` while preserving mathematical correctness (this is currently not done automatically by the library). Note that there is no way to represent a half-infinite interval such as `[0,\infty]`. * The ball `[\operatorname{NaN} \pm c]`, where `c` is finite or infinite, represents an indeterminate value (the value could be any extended real number, or it could represent a function being evaluated outside its domain of definition, for example where the result would be complex). Such an indeterminate ball can always be replaced by `[\operatorname{NaN} \pm \infty]` while preserving mathematical correctness (this is currently not done automatically by the library). Types, macros and constants ------------------------------------------------------------------------------- .. type:: arb_struct .. type:: arb_t An :type:`arb_struct` consists of an :type:`arf_struct` (the midpoint) and a :type:`mag_struct` (the radius). An :type:`arb_t` is defined as an array of length one of type :type:`arb_struct`, permitting an :type:`arb_t` to be passed by reference. .. type:: arb_ptr Alias for ``arb_struct *``, used for vectors of numbers. .. type:: arb_srcptr Alias for ``const arb_struct *``, used for vectors of numbers when passed as constant input to functions. .. macro:: arb_midref(x) Macro returning a pointer to the midpoint of *x* as an :type:`arf_t`. .. macro:: arb_radref(x) Macro returning a pointer to the radius of *x* as a :type:`mag_t`. Memory management ------------------------------------------------------------------------------- .. function:: void arb_init(arb_t x) Initializes the variable *x* for use. Its midpoint and radius are both set to zero. .. function:: void arb_clear(arb_t x) Clears the variable *x*, freeing or recycling its allocated memory. .. function:: arb_ptr _arb_vec_init(slong n) Returns a pointer to an array of *n* initialized :type:`arb_struct` entries. .. function:: void _arb_vec_clear(arb_ptr v, slong n) Clears an array of *n* initialized :type:`arb_struct` entries. .. function:: void arb_swap(arb_t x, arb_t y) Swaps *x* and *y* efficiently. .. function:: slong arb_allocated_bytes(const arb_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(arb_struct)`` to get the size of the object as a whole. .. function:: slong _arb_vec_allocated_bytes(arb_srcptr vec, slong len) Returns the total number of bytes allocated for this vector, i.e. the space taken up by the vector itself plus the sum of the internal heap allocation sizes for all its member elements. .. function:: double _arb_vec_estimate_allocated_bytes(slong len, slong prec) Estimates the number of bytes that need to be allocated for a vector of *len* elements with *prec* bits of precision, including the space for internal limb data. This function returns a *double* to avoid overflow issues when both *len* and *prec* are large. This is only an approximation of the physical memory that will be used by an actual vector. In practice, the space varies with the content of the numbers; for example, zeros and small integers require no internal heap allocation even if the precision is huge. The estimate assumes that exponents will not be bignums. The actual amount may also be higher or lower due to overhead in the memory allocator or overcommitment by the operating system. Assignment and rounding ------------------------------------------------------------------------------- .. function:: void arb_set(arb_t y, const arb_t x) .. function:: void arb_set_arf(arb_t y, const arf_t x) .. function:: void arb_set_si(arb_t y, slong x) .. function:: void arb_set_ui(arb_t y, ulong x) .. function:: void arb_set_d(arb_t y, double x) .. function:: void arb_set_fmpz(arb_t y, const fmpz_t x) Sets *y* to the value of *x* without rounding. .. function:: void arb_set_fmpz_2exp(arb_t y, const fmpz_t x, const fmpz_t e) Sets *y* to `x \cdot 2^e`. .. function:: void arb_set_round(arb_t y, const arb_t x, slong prec) .. function:: void arb_set_round_fmpz(arb_t y, const fmpz_t x, slong prec) Sets *y* to the value of *x*, rounded to *prec* bits in the direction towards zero. .. function:: void arb_set_round_fmpz_2exp(arb_t y, const fmpz_t x, const fmpz_t e, slong prec) Sets *y* to `x \cdot 2^e`, rounded to *prec* bits in the direction towards zero. .. function:: void arb_set_fmpq(arb_t y, const fmpq_t x, slong prec) Sets *y* to the rational number *x*, rounded to *prec* bits in the direction towards zero. .. function:: int arb_set_str(arb_t res, const char * inp, slong prec) Sets *res* to the value specified by the human-readable string *inp*. The input may be a decimal floating-point literal, such as "25", "0.001", "7e+141" or "-31.4159e-1", and may also consist of two such literals separated by the symbol "+/-" and optionally enclosed in brackets, e.g. "[3.25 +/- 0.0001]", or simply "[+/- 10]" with an implicit zero midpoint. The output is rounded to *prec* bits, and if the binary-to-decimal conversion is inexact, the resulting error is added to the radius. The symbols "inf" and "nan" are recognized (a nan midpoint results in an indeterminate interval, with infinite radius). Returns 0 if successful and nonzero if unsuccessful. If unsuccessful, the result is set to an indeterminate interval. .. function:: char * arb_get_str(const arb_t x, slong n, ulong flags) Returns a nice human-readable representation of *x*, with at most *n* digits of the midpoint printed. With default flags, the output can be parsed back with :func:`arb_set_str`, and this is guaranteed to produce an interval containing the original interval *x*. By default, the output is rounded so that the value given for the midpoint is correct up to 1 ulp (unit in the last decimal place). If *ARB_STR_MORE* is added to *flags*, more (possibly incorrect) digits may be printed. If *ARB_STR_NO_RADIUS* is added to *flags*, the radius is not included in the output. Unless *ARB_STR_MORE* is set, the output is rounded so that the midpoint is correct to 1 ulp. As a special case, if there are no significant digits after rounding, the result will be shown as ``0e+n``, meaning that the result is between ``-1e+n`` and ``1e+n`` (following the contract that the output is correct to within one unit in the only shown digit). By adding a multiple *m* of *ARB_STR_CONDENSE* to *flags*, strings of more than three times *m* consecutive digits are condensed, only printing the leading and trailing *m* digits along with brackets indicating the number of digits omitted (useful when computing values to extremely high precision). Assignment of special values ------------------------------------------------------------------------------- .. function:: void arb_zero(arb_t x) Sets *x* to zero. .. function:: void arb_one(arb_t f) Sets *x* to the exact integer 1. .. function:: void arb_pos_inf(arb_t x) Sets *x* to positive infinity, with a zero radius. .. function:: void arb_neg_inf(arb_t x) Sets *x* to negative infinity, with a zero radius. .. function:: void arb_zero_pm_inf(arb_t x) Sets *x* to `[0 \pm \infty]`, representing the whole extended real line. .. function:: void arb_indeterminate(arb_t x) Sets *x* to `[\operatorname{NaN} \pm \infty]`, representing an indeterminate result. .. function:: void arb_zero_pm_one(arb_t x) Sets *x* to the interval `[0 \pm 1]`. .. function:: void arb_unit_interval(arb_t x) Sets *x* to the interval `[0, 1]`. Input and output ------------------------------------------------------------------------------- The *arb_print...* functions print to standard output, while *arb_fprint...* functions print to the stream *file*. .. function:: void arb_print(const arb_t x) .. function:: void arb_fprint(FILE * file, const arb_t x) Prints the internal representation of *x*. .. function:: void arb_printd(const arb_t x, slong digits) .. function:: void arb_fprintd(FILE * file, const arb_t x, slong digits) Prints *x* in decimal. The printed value of the radius is not adjusted to compensate for the fact that the binary-to-decimal conversion of both the midpoint and the radius introduces additional error. .. function:: void arb_printn(const arb_t x, slong digits, ulong flags) .. function:: void arb_fprintn(FILE * file, const arb_t x, slong digits, ulong flags) Prints a nice decimal representation of *x*. By default, the output shows the midpoint with a guaranteed error of at most one unit in the last decimal place. In addition, an explicit error bound is printed so that the displayed decimal interval is guaranteed to enclose *x*. See :func:`arb_get_str` for details. .. function:: char * arb_dump_str(const arb_t x) Returns a serialized representation of *x* as a null-terminated ASCII string that can be read by :func:`arb_load_str`. The format consists of four hexadecimal integers representing the midpoint mantissa, midpoint exponent, radius mantissa and radius exponent (with special values to indicate zero, infinity and NaN values), separated by single spaces. The returned string needs to be deallocated with *flint_free*. .. function:: int arb_load_str(arb_t x, const char * str) Sets *x* to the serialized representation given in *str*. Returns a nonzero value if *str* is not formatted correctly (see :func:`arb_dump_str`). .. function:: int arb_dump_file(FILE * stream, const arb_t x) Writes a serialized ASCII representation of *x* to *stream* in a form that can be read by :func:`arb_load_file`. Returns a nonzero value if the data could not be written. .. function:: int arb_load_file(arb_t x, FILE * stream) Reads *x* from a serialized ASCII representation in *stream*. Returns a nonzero value if the data is not formatted correctly or the read failed. Note that the data is assumed to be delimited by a whitespace or end-of-file, i.e., when writing multiple values with :func:`arb_dump_file` make sure to insert a whitespace to separate consecutive values. It is possible to serialize and deserialize a vector as follows (warning: without error handling): .. code-block:: c fp = fopen("data.txt", "w"); for (i = 0; i < n; i++) { arb_dump_file(fp, vec + i); fprintf(fp, "\n"); // or any whitespace character } fclose(fp); fp = fopen("data.txt", "r"); for (i = 0; i < n; i++) { arb_load_file(vec + i, fp); } fclose(fp); Random number generation ------------------------------------------------------------------------------- .. function:: void arb_randtest(arb_t x, flint_rand_t state, slong prec, slong mag_bits) Generates a random ball. The midpoint and radius will both be finite. .. function:: void arb_randtest_exact(arb_t x, flint_rand_t state, slong prec, slong mag_bits) Generates a random number with zero radius. .. function:: void arb_randtest_precise(arb_t x, flint_rand_t state, slong prec, slong mag_bits) Generates a random number with radius around `2^{-\text{prec}}` the magnitude of the midpoint. .. function:: void arb_randtest_wide(arb_t x, flint_rand_t state, slong prec, slong mag_bits) Generates a random number with midpoint and radius chosen independently, possibly giving a very large interval. .. function:: void arb_randtest_special(arb_t x, flint_rand_t state, slong prec, slong mag_bits) Generates a random interval, possibly having NaN or an infinity as the midpoint and possibly having an infinite radius. .. function:: void arb_get_rand_fmpq(fmpq_t q, flint_rand_t state, const arb_t x, slong bits) Sets *q* to a random rational number from the interval represented by *x*. A denominator is chosen by multiplying the binary denominator of *x* by a random integer up to *bits* bits. The outcome is undefined if the midpoint or radius of *x* is non-finite, or if the exponent of the midpoint or radius is so large or small that representing the endpoints as exact rational numbers would cause overflows. .. function:: void arb_urandom(arb_t x, flint_rand_t state, slong prec, arf_rnd_t rnd) Sets *x* to a uniformly distributed random number in the interval `[0, 1]`. The method uses rounding from integers to floats, hence the radius might not be `0`. Radius and interval operations ------------------------------------------------------------------------------- .. function:: void arb_get_mid_arb(arb_t m, const arb_t x) Sets *m* to the midpoint of *x*. .. function:: void arb_get_rad_arb(arb_t r, const arb_t x) Sets *r* to the radius of *x*. .. function:: void arb_add_error_arf(arb_t x, const arf_t err) .. function:: void arb_add_error_mag(arb_t x, const mag_t err) .. function:: void arb_add_error(arb_t x, const arb_t err) Adds the absolute value of *err* to the radius of *x* (the operation is done in-place). .. function:: void arb_add_error_2exp_si(arb_t x, slong e) .. function:: void arb_add_error_2exp_fmpz(arb_t x, const fmpz_t e) Adds `2^e` to the radius of *x*. .. function:: void arb_union(arb_t z, const arb_t x, const arb_t y, slong prec) Sets *z* to a ball containing both *x* and *y*. .. function:: int arb_intersection(arb_t z, const arb_t x, const arb_t y, slong prec) If *x* and *y* overlap according to :func:`arb_overlaps`, then *z* is set to a ball containing the intersection of *x* and *y* and a nonzero value is returned. Otherwise zero is returned and the value of *z* is undefined. If *x* or *y* contains NaN, the result is NaN. .. function:: void arb_nonnegative_part(arb_t res, const arb_t x) Sets *res* to the intersection of *x* with `[0,\infty]`. If *x* is nonnegative, an exact copy is made. If *x* is finite and contains negative numbers, an interval of the form `[r/2 \pm r/2]` is produced, which certainly contains no negative points. In the special case when *x* is strictly negative, *res* is set to zero. .. function:: void arb_get_abs_ubound_arf(arf_t u, const arb_t x, slong prec) Sets *u* to the upper bound for the absolute value of *x*, rounded up to *prec* bits. If *x* contains NaN, the result is NaN. .. function:: void arb_get_abs_lbound_arf(arf_t u, const arb_t x, slong prec) Sets *u* to the lower bound for the absolute value of *x*, rounded down to *prec* bits. If *x* contains NaN, the result is NaN. .. function:: void arb_get_ubound_arf(arf_t u, const arb_t x, slong prec) Sets *u* to the upper bound for the value of *x*, rounded up to *prec* bits. If *x* contains NaN, the result is NaN. .. function:: void arb_get_lbound_arf(arf_t u, const arb_t x, slong prec) Sets *u* to the lower bound for the value of *x*, rounded down to *prec* bits. If *x* contains NaN, the result is NaN. .. function:: void arb_get_mag(mag_t z, const arb_t x) Sets *z* to an upper bound for the absolute value of *x*. If *x* contains NaN, the result is positive infinity. .. function:: void arb_get_mag_lower(mag_t z, const arb_t x) Sets *z* to a lower bound for the absolute value of *x*. If *x* contains NaN, the result is zero. .. function:: void arb_get_mag_lower_nonnegative(mag_t z, const arb_t x) Sets *z* to a lower bound for the signed value of *x*, or zero if *x* overlaps with the negative half-axis. If *x* contains NaN, the result is zero. .. function:: void arb_get_interval_fmpz_2exp(fmpz_t a, fmpz_t b, fmpz_t exp, const arb_t x) Computes the exact interval represented by *x*, in the form of an integer interval multiplied by a power of two, i.e. `x = [a, b] \times 2^{\text{exp}}`. The result is normalized by removing common trailing zeros from *a* and *b*. This method aborts if *x* is infinite or NaN, or if the difference between the exponents of the midpoint and the radius is so large that allocating memory for the result fails. Warning: this method will allocate a huge amount of memory to store the result if the exponent difference is huge. Memory allocation could succeed even if the required space is far larger than the physical memory available on the machine, resulting in swapping. It is recommended to check that the midpoint and radius of *x* both are within a reasonable range before calling this method. .. function:: void arb_set_interval_mag(arb_t x, const mag_t a, const mag_t b, slong prec) .. function:: void arb_set_interval_arf(arb_t x, const arf_t a, const arf_t b, slong prec) .. function:: void arb_set_interval_mpfr(arb_t x, const mpfr_t a, const mpfr_t b, slong prec) Sets *x* to a ball containing the interval `[a, b]`. We require that `a \le b`. .. function:: void arb_set_interval_neg_pos_mag(arb_t x, const mag_t a, const mag_t b, slong prec) Sets *x* to a ball containing the interval `[-a, b]`. .. function:: void arb_get_interval_arf(arf_t a, arf_t b, const arb_t x, slong prec) .. function:: void arb_get_interval_mpfr(mpfr_t a, mpfr_t b, const arb_t x) Constructs an interval `[a, b]` containing the ball *x*. The MPFR version uses the precision of the output variables. .. function:: slong arb_rel_error_bits(const arb_t x) Returns the effective relative error of *x* measured in bits, defined as the difference between the position of the top bit in the radius and the top bit in the midpoint, plus one. The result is clamped between plus/minus *ARF_PREC_EXACT*. .. function:: slong arb_rel_accuracy_bits(const arb_t x) Returns the effective relative accuracy of *x* measured in bits, equal to the negative of the return value from :func:`arb_rel_error_bits`. .. function:: slong arb_rel_one_accuracy_bits(const arb_t x) Given a ball with midpoint *m* and radius *r*, returns an approximation of the relative accuracy of `[\max(1,|m|) \pm r]` measured in bits. .. function:: slong arb_bits(const arb_t x) Returns the number of bits needed to represent the absolute value of the mantissa of the midpoint of *x*, i.e. the minimum precision sufficient to represent *x* exactly. Returns 0 if the midpoint of *x* is a special value. .. function:: void arb_trim(arb_t y, const arb_t x) Sets *y* to a trimmed copy of *x*: rounds *x* to a number of bits equal to the accuracy of *x* (as indicated by its radius), plus a few guard bits. The resulting ball is guaranteed to contain *x*, but is more economical if *x* has less than full accuracy. .. function:: int arb_get_unique_fmpz(fmpz_t z, const arb_t x) If *x* contains a unique integer, sets *z* to that value and returns nonzero. Otherwise (if *x* represents no integers or more than one integer), returns zero. This method aborts if there is a unique integer but that integer is so large that allocating memory for the result fails. Warning: this method will allocate a huge amount of memory to store the result if there is a unique integer and that integer is huge. Memory allocation could succeed even if the required space is far larger than the physical memory available on the machine, resulting in swapping. It is recommended to check that the midpoint of *x* is within a reasonable range before calling this method. .. function:: void arb_floor(arb_t y, const arb_t x, slong prec) .. function:: void arb_ceil(arb_t y, const arb_t x, slong prec) Sets *y* to a ball containing `\lfloor x \rfloor` and `\lceil x \rceil` respectively, with the midpoint of *y* rounded to at most *prec* bits. .. function:: void arb_get_fmpz_mid_rad_10exp(fmpz_t mid, fmpz_t rad, fmpz_t exp, const arb_t x, slong n) Assuming that *x* is finite and not exactly zero, computes integers *mid*, *rad*, *exp* such that `x \in [m-r, m+r] \times 10^e` and such that the larger out of *mid* and *rad* has at least *n* digits plus a few guard digits. If *x* is infinite or exactly zero, the outputs are all set to zero. .. function:: int arb_can_round_arf(const arb_t x, slong prec, arf_rnd_t rnd) .. function:: int arb_can_round_mpfr(const arb_t x, slong prec, mpfr_rnd_t rnd) Returns nonzero if rounding the midpoint of *x* to *prec* bits in the direction *rnd* is guaranteed to give the unique correctly rounded floating-point approximation for the real number represented by *x*. In other words, if this function returns nonzero, applying :func:`arf_set_round`, or :func:`arf_get_mpfr`, or :func:`arf_get_d` to the midpoint of *x* is guaranteed to return a correctly rounded *arf_t*, *mpfr_t* (provided that *prec* is the precision of the output variable), or *double* (provided that *prec* is 53). Moreover, :func:`arf_get_mpfr` is guaranteed to return the correct ternary value according to MPFR semantics. Note that the *mpfr* version of this function takes an MPFR rounding mode symbol as input, while the *arf* version takes an *arf* rounding mode symbol. Otherwise, the functions are identical. This function may perform a fast, inexact test; that is, it may return zero in some cases even when correct rounding actually is possible. To be conservative, zero is returned when *x* is non-finite, even if it is an "exact" infinity. Comparisons ------------------------------------------------------------------------------- .. function:: int arb_is_zero(const arb_t x) Returns nonzero iff the midpoint and radius of *x* are both zero. .. function:: int arb_is_nonzero(const arb_t x) Returns nonzero iff zero is not contained in the interval represented by *x*. .. function:: int arb_is_one(const arb_t f) Returns nonzero iff *x* is exactly 1. .. function:: int arb_is_finite(const arb_t x) Returns nonzero iff the midpoint and radius of *x* are both finite floating-point numbers, i.e. not infinities or NaN. .. function:: int arb_is_exact(const arb_t x) Returns nonzero iff the radius of *x* is zero. .. function:: int arb_is_int(const arb_t x) Returns nonzero iff *x* is an exact integer. .. function:: int arb_is_int_2exp_si(const arb_t x, slong e) Returns nonzero iff *x* exactly equals `n 2^e` for some integer *n*. .. function:: int arb_equal(const arb_t x, const arb_t y) Returns nonzero iff *x* and *y* are equal as balls, i.e. have both the same midpoint and radius. Note that this is not the same thing as testing whether both *x* and *y* certainly represent the same real number, unless either *x* or *y* is exact (and neither contains NaN). To test whether both operands *might* represent the same mathematical quantity, use :func:`arb_overlaps` or :func:`arb_contains`, depending on the circumstance. .. function:: int arb_equal_si(const arb_t x, slong y) Returns nonzero iff *x* is equal to the integer *y*. .. function:: int arb_is_positive(const arb_t x) .. function:: int arb_is_nonnegative(const arb_t x) .. function:: int arb_is_negative(const arb_t x) .. function:: int arb_is_nonpositive(const arb_t x) Returns nonzero iff all points *p* in the interval represented by *x* satisfy, respectively, `p > 0`, `p \ge 0`, `p < 0`, `p \le 0`. If *x* contains NaN, returns zero. .. function:: int arb_overlaps(const arb_t x, const arb_t y) Returns nonzero iff *x* and *y* have some point in common. If either *x* or *y* contains NaN, this function always returns nonzero (as a NaN could be anything, it could in particular contain any number that is included in the other operand). .. function:: int arb_contains_arf(const arb_t x, const arf_t y) .. function:: int arb_contains_fmpq(const arb_t x, const fmpq_t y) .. function:: int arb_contains_fmpz(const arb_t x, const fmpz_t y) .. function:: int arb_contains_si(const arb_t x, slong y) .. function:: int arb_contains_mpfr(const arb_t x, const mpfr_t y) .. function:: int arb_contains(const arb_t x, const arb_t y) Returns nonzero iff the given number (or ball) *y* is contained in the interval represented by *x*. If *x* contains NaN, this function always returns nonzero (as it could represent anything, and in particular could represent all the points included in *y*). If *y* contains NaN and *x* does not, it always returns zero. .. function:: int arb_contains_int(const arb_t x) Returns nonzero iff the interval represented by *x* contains an integer. .. function:: int arb_contains_zero(const arb_t x) .. function:: int arb_contains_negative(const arb_t x) .. function:: int arb_contains_nonpositive(const arb_t x) .. function:: int arb_contains_positive(const arb_t x) .. function:: int arb_contains_nonnegative(const arb_t x) Returns nonzero iff there is any point *p* in the interval represented by *x* satisfying, respectively, `p = 0`, `p < 0`, `p \le 0`, `p > 0`, `p \ge 0`. If *x* contains NaN, returns nonzero. .. function:: int arb_contains_interior(const arb_t x, const arb_t y) Tests if *y* is contained in the interior of *x*; that is, contained in *x* and not touching either endpoint. .. function:: int arb_eq(const arb_t x, const arb_t y) .. function:: int arb_ne(const arb_t x, const arb_t y) .. function:: int arb_lt(const arb_t x, const arb_t y) .. function:: int arb_le(const arb_t x, const arb_t y) .. function:: int arb_gt(const arb_t x, const arb_t y) .. function:: int arb_ge(const arb_t x, const arb_t y) Respectively performs the comparison `x = y`, `x \ne y`, `x < y`, `x \le y`, `x > y`, `x \ge y` in a mathematically meaningful way. If the comparison `t \, (\operatorname{op}) \, u` holds for all `t \in x` and all `u \in y`, returns 1. Otherwise, returns 0. The balls *x* and *y* are viewed as subintervals of the extended real line. Note that balls that are formally different can compare as equal under this definition: for example, `[-\infty \pm 3] = [-\infty \pm 0]`. Also `[-\infty] \le [\infty \pm \infty]`. The output is always 0 if either input has NaN as midpoint. Arithmetic ------------------------------------------------------------------------------- .. function:: void arb_neg(arb_t y, const arb_t x) .. function:: void arb_neg_round(arb_t y, const arb_t x, slong prec) Sets *y* to the negation of *x*. .. function:: void arb_abs(arb_t y, const arb_t x) Sets *y* to the absolute value of *x*. No attempt is made to improve the interval represented by *x* if it contains zero. .. function:: void arb_sgn(arb_t y, const arb_t x) Sets *y* to the sign function of *x*. The result is `[0 \pm 1]` if *x* contains both zero and nonzero numbers. .. function:: int arb_sgn_nonzero(const arb_t x) Returns 1 if *x* is strictly positive, -1 if *x* is strictly negative, and 0 if *x* is zero or a ball containing zero so that its sign is not determined. .. function:: void arb_min(arb_t z, const arb_t x, const arb_t y, slong prec) .. function:: void arb_max(arb_t z, const arb_t x, const arb_t y, slong prec) Sets *z* respectively to the minimum and the maximum of *x* and *y*. .. function:: void arb_add(arb_t z, const arb_t x, const arb_t y, slong prec) .. function:: void arb_add_arf(arb_t z, const arb_t x, const arf_t y, slong prec) .. function:: void arb_add_ui(arb_t z, const arb_t x, ulong y, slong prec) .. function:: void arb_add_si(arb_t z, const arb_t x, slong y, slong prec) .. function:: void arb_add_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) Sets `z = x + y`, rounded to *prec* bits. The precision can be *ARF_PREC_EXACT* provided that the result fits in memory. .. function:: void arb_add_fmpz_2exp(arb_t z, const arb_t x, const fmpz_t m, const fmpz_t e, slong prec) Sets `z = x + m \cdot 2^e`, rounded to *prec* bits. The precision can be *ARF_PREC_EXACT* provided that the result fits in memory. .. function:: void arb_sub(arb_t z, const arb_t x, const arb_t y, slong prec) .. function:: void arb_sub_arf(arb_t z, const arb_t x, const arf_t y, slong prec) .. function:: void arb_sub_ui(arb_t z, const arb_t x, ulong y, slong prec) .. function:: void arb_sub_si(arb_t z, const arb_t x, slong y, slong prec) .. function:: void arb_sub_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) Sets `z = x - y`, rounded to *prec* bits. The precision can be *ARF_PREC_EXACT* provided that the result fits in memory. .. function:: void arb_mul(arb_t z, const arb_t x, const arb_t y, slong prec) .. function:: void arb_mul_arf(arb_t z, const arb_t x, const arf_t y, slong prec) .. function:: void arb_mul_si(arb_t z, const arb_t x, slong y, slong prec) .. function:: void arb_mul_ui(arb_t z, const arb_t x, ulong y, slong prec) .. function:: void arb_mul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) Sets `z = x \cdot y`, rounded to *prec* bits. The precision can be *ARF_PREC_EXACT* provided that the result fits in memory. .. function:: void arb_mul_2exp_si(arb_t y, const arb_t x, slong e) .. function:: void arb_mul_2exp_fmpz(arb_t y, const arb_t x, const fmpz_t e) Sets *y* to *x* multiplied by `2^e`. .. function:: void arb_addmul(arb_t z, const arb_t x, const arb_t y, slong prec) .. function:: void arb_addmul_arf(arb_t z, const arb_t x, const arf_t y, slong prec) .. function:: void arb_addmul_si(arb_t z, const arb_t x, slong y, slong prec) .. function:: void arb_addmul_ui(arb_t z, const arb_t x, ulong y, slong prec) .. function:: void arb_addmul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) Sets `z = z + x \cdot y`, rounded to prec bits. The precision can be *ARF_PREC_EXACT* provided that the result fits in memory. .. function:: void arb_submul(arb_t z, const arb_t x, const arb_t y, slong prec) .. function:: void arb_submul_arf(arb_t z, const arb_t x, const arf_t y, slong prec) .. function:: void arb_submul_si(arb_t z, const arb_t x, slong y, slong prec) .. function:: void arb_submul_ui(arb_t z, const arb_t x, ulong y, slong prec) .. function:: void arb_submul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) Sets `z = z - x \cdot y`, rounded to prec bits. The precision can be *ARF_PREC_EXACT* provided that the result fits in memory. .. function:: void arb_fma(arb_t res, const arb_t x, const arb_t y, const arb_t z, slong prec) void arb_fma_arf(arb_t res, const arb_t x, const arf_t y, const arb_t z, slong prec) void arb_fma_si(arb_t res, const arb_t x, slong y, const arb_t z, slong prec) void arb_fma_ui(arb_t res, const arb_t x, ulong y, const arb_t z, slong prec) void arb_fma_fmpz(arb_t res, const arb_t x, const fmpz_t y, const arb_t z, slong prec) Sets *res* to `x \cdot y + z`. This is equivalent to an *addmul* except that *res* and *z* can be separate variables. .. function:: void arb_inv(arb_t z, const arb_t x, slong prec) Sets *z* to `1 / x`. .. function:: void arb_div(arb_t z, const arb_t x, const arb_t y, slong prec) .. function:: void arb_div_arf(arb_t z, const arb_t x, const arf_t y, slong prec) .. function:: void arb_div_si(arb_t z, const arb_t x, slong y, slong prec) .. function:: void arb_div_ui(arb_t z, const arb_t x, ulong y, slong prec) .. function:: void arb_div_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) .. function:: void arb_fmpz_div_fmpz(arb_t z, const fmpz_t x, const fmpz_t y, slong prec) .. function:: void arb_ui_div(arb_t z, ulong x, const arb_t y, slong prec) Sets `z = x / y`, rounded to *prec* bits. If *y* contains zero, *z* is set to `0 \pm \infty`. Otherwise, error propagation uses the rule .. math :: \left| \frac{x}{y} - \frac{x+\xi_1 a}{y+\xi_2 b} \right| = \left|\frac{x \xi_2 b - y \xi_1 a}{y (y+\xi_2 b)}\right| \le \frac{|xb|+|ya|}{|y| (|y|-b)} where `-1 \le \xi_1, \xi_2 \le 1`, and where the triangle inequality has been applied to the numerator and the reverse triangle inequality has been applied to the denominator. .. function:: void arb_div_2expm1_ui(arb_t z, const arb_t x, ulong n, slong prec) Sets `z = x / (2^n - 1)`, rounded to *prec* bits. Dot product ------------------------------------------------------------------------------- .. function:: void arb_dot_precise(arb_t res, const arb_t s, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) void arb_dot_simple(arb_t res, const arb_t s, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) void arb_dot(arb_t res, const arb_t s, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) Computes the dot product of the vectors *x* and *y*, setting *res* to `s + (-1)^{subtract} \sum_{i=0}^{len-1} x_i y_i`. The initial term *s* is optional and can be omitted by passing *NULL* (equivalently, `s = 0`). The parameter *subtract* must be 0 or 1. The length *len* is allowed to be negative, which is equivalent to a length of zero. The parameters *xstep* or *ystep* specify a step length for traversing subsequences of the vectors *x* and *y*; either can be negative to step in the reverse direction starting from the initial pointer. Aliasing is allowed between *res* and *s* but not between *res* and the entries of *x* and *y*. The default version determines the optimal precision for each term and performs all internal calculations using mpn arithmetic with minimal overhead. This is the preferred way to compute a dot product; it is generally much faster and more precise than a simple loop. The *simple* version performs fused multiply-add operations in a simple loop. This can be used for testing purposes and is also used as a fallback by the default version when the exponents are out of range for the optimized code. The *precise* version computes the dot product exactly up to the final rounding. This can be extremely slow and is only intended for testing. .. function:: void arb_approx_dot(arb_t res, const arb_t s, int subtract, arb_srcptr x, slong xstep, arb_srcptr y, slong ystep, slong len, slong prec) Computes an approximate dot product *without error bounds*. The radii of the inputs are ignored (only the midpoints are read) and only the midpoint of the output is written. .. function:: void arb_dot_ui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) void arb_dot_si(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const slong * y, slong ystep, slong len, slong prec) void arb_dot_uiui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) void arb_dot_siui(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const ulong * y, slong ystep, slong len, slong prec) void arb_dot_fmpz(arb_t res, const arb_t initial, int subtract, arb_srcptr x, slong xstep, const fmpz * y, slong ystep, slong len, slong prec) Equivalent to :func:`arb_dot`, but with integers in the array *y*. The *uiui* and *siui* versions take an array of double-limb integers as input; the *siui* version assumes that these represent signed integers in two's complement form. Powers and roots ------------------------------------------------------------------------------- .. function:: void arb_sqrt(arb_t z, const arb_t x, slong prec) .. function:: void arb_sqrt_arf(arb_t z, const arf_t x, slong prec) .. function:: void arb_sqrt_fmpz(arb_t z, const fmpz_t x, slong prec) .. function:: void arb_sqrt_ui(arb_t z, ulong x, slong prec) Sets *z* to the square root of *x*, rounded to *prec* bits. If `x = m \pm x` where `m \ge r \ge 0`, the propagated error is bounded by `\sqrt{m} - \sqrt{m-r} = \sqrt{m} (1 - \sqrt{1 - r/m}) \le \sqrt{m} (r/m + (r/m)^2)/2`. .. function:: void arb_sqrtpos(arb_t z, const arb_t x, slong prec) Sets *z* to the square root of *x*, assuming that *x* represents a nonnegative number (i.e. discarding any negative numbers in the input interval). .. function:: void arb_hypot(arb_t z, const arb_t x, const arb_t y, slong prec) Sets *z* to `\sqrt{x^2 + y^2}`. .. function:: void arb_rsqrt(arb_t z, const arb_t x, slong prec) .. function:: void arb_rsqrt_ui(arb_t z, ulong x, slong prec) Sets *z* to the reciprocal square root of *x*, rounded to *prec* bits. At high precision, this is faster than computing a square root. .. function:: void arb_sqrt1pm1(arb_t z, const arb_t x, slong prec) Sets `z = \sqrt{1+x}-1`, computed accurately when `x \approx 0`. .. function:: void arb_root_ui(arb_t z, const arb_t x, ulong k, slong prec) Sets *z* to the *k*-th root of *x*, rounded to *prec* bits. This function selects between different algorithms. For large *k*, it evaluates `\exp(\log(x)/k)`. For small *k*, it uses :func:`arf_root` at the midpoint and computes a propagated error bound as follows: if input interval is `[m-r, m+r]` with `r \le m`, the error is largest at `m-r` where it satisfies .. math :: m^{1/k} - (m-r)^{1/k} = m^{1/k} [1 - (1-r/m)^{1/k}] = m^{1/k} [1 - \exp(\log(1-r/m)/k)] \le m^{1/k} \min(1, -\log(1-r/m)/k) = m^{1/k} \min(1, \log(1+r/(m-r))/k). This is evaluated using :func:`mag_log1p`. .. function:: void arb_root(arb_t z, const arb_t x, ulong k, slong prec) Alias for :func:`arb_root_ui`, provided for backwards compatibility. .. function:: void arb_sqr(arb_t y, const arb_t x, slong prec) Sets *y* to be the square of *x*. .. function:: void arb_pow_fmpz_binexp(arb_t y, const arb_t b, const fmpz_t e, slong prec) .. function:: void arb_pow_fmpz(arb_t y, const arb_t b, const fmpz_t e, slong prec) .. function:: void arb_pow_ui(arb_t y, const arb_t b, ulong e, slong prec) .. function:: void arb_ui_pow_ui(arb_t y, ulong b, ulong e, slong prec) .. function:: void arb_si_pow_ui(arb_t y, slong b, ulong e, slong prec) Sets `y = b^e` using binary exponentiation (with an initial division if `e < 0`). Provided that *b* and *e* are small enough and the exponent is positive, the exact power can be computed by setting the precision to *ARF_PREC_EXACT*. Note that these functions can get slow if the exponent is extremely large (in such cases :func:`arb_pow` may be superior). .. function:: void arb_pow_fmpq(arb_t y, const arb_t x, const fmpq_t a, slong prec) Sets `y = b^e`, computed as `y = (b^{1/q})^p` if the denominator of `e = p/q` is small, and generally as `y = \exp(e \log b)`. Note that this function can get slow if the exponent is extremely large (in such cases :func:`arb_pow` may be superior). .. function:: void arb_pow(arb_t z, const arb_t x, const arb_t y, slong prec) Sets `z = x^y`, computed using binary exponentiation if `y` is a small exact integer, as `z = (x^{1/2})^{2y}` if `y` is a small exact half-integer, and generally as `z = \exp(y \log x)`. Exponentials and logarithms ------------------------------------------------------------------------------- .. function:: void arb_log_ui(arb_t z, ulong x, slong prec) .. function:: void arb_log_fmpz(arb_t z, const fmpz_t x, slong prec) .. function:: void arb_log_arf(arb_t z, const arf_t x, slong prec) .. function:: void arb_log(arb_t z, const arb_t x, slong prec) Sets `z = \log(x)`. At low to medium precision (up to about 4096 bits), :func:`arb_log_arf` uses table-based argument reduction and fast Taylor series evaluation via :func:`_arb_atan_taylor_rs`. At high precision, it falls back to MPFR. The function :func:`arb_log` simply calls :func:`arb_log_arf` with the midpoint as input, and separately adds the propagated error. .. function:: void arb_log_ui_from_prev(arb_t log_k1, ulong k1, arb_t log_k0, ulong k0, slong prec) Computes `\log(k_1)`, given `\log(k_0)` where `k_0 < k_1`. At high precision, this function uses the formula `\log(k_1) = \log(k_0) + 2 \operatorname{atanh}((k_1-k_0)/(k_1+k_0))`, evaluating the inverse hyperbolic tangent using binary splitting (for best efficiency, `k_0` should be large and `k_1 - k_0` should be small). Otherwise, it ignores `\log(k_0)` and evaluates the logarithm the usual way. .. function:: void arb_log1p(arb_t z, const arb_t x, slong prec) Sets `z = \log(1+x)`, computed accurately when `x \approx 0`. .. function:: void arb_log_base_ui(arb_t res, const arb_t x, ulong b, slong prec) Sets *res* to `\log_b(x)`. The result is computed exactly when possible. .. function:: void arb_log_hypot(arb_t res, const arb_t x, const arb_t y, slong prec) Sets *res* to `\log(\sqrt{x^2+y^2})`. .. function:: void arb_exp(arb_t z, const arb_t x, slong prec) Sets `z = \exp(x)`. Error propagation is done using the following rule: assuming `x = m \pm r`, the error is largest at `m + r`, and we have `\exp(m+r) - \exp(m) = \exp(m) (\exp(r)-1) \le r \exp(m+r)`. .. function:: void arb_expm1(arb_t z, const arb_t x, slong prec) Sets `z = \exp(x)-1`, using a more accurate method when `x \approx 0`. .. function:: void arb_exp_invexp(arb_t z, arb_t w, const arb_t x, slong prec) Sets `z = \exp(x)` and `w = \exp(-x)`. The second exponential is computed from the first using a division, but propagated error bounds are computed separately. Trigonometric functions ------------------------------------------------------------------------------- .. function:: void arb_sin(arb_t s, const arb_t x, slong prec) .. function:: void arb_cos(arb_t c, const arb_t x, slong prec) .. function:: void arb_sin_cos(arb_t s, arb_t c, const arb_t x, slong prec) Sets `s = \sin(x)`, `c = \cos(x)`. .. function:: void arb_sin_pi(arb_t s, const arb_t x, slong prec) .. function:: void arb_cos_pi(arb_t c, const arb_t x, slong prec) .. function:: void arb_sin_cos_pi(arb_t s, arb_t c, const arb_t x, slong prec) Sets `s = \sin(\pi x)`, `c = \cos(\pi x)`. .. function:: void arb_tan(arb_t y, const arb_t x, slong prec) Sets `y = \tan(x) = \sin(x) / \cos(y)`. .. function:: void arb_cot(arb_t y, const arb_t x, slong prec) Sets `y = \cot(x) = \cos(x) / \sin(y)`. .. function:: void arb_sin_cos_pi_fmpq(arb_t s, arb_t c, const fmpq_t x, slong prec) .. function:: void arb_sin_pi_fmpq(arb_t s, const fmpq_t x, slong prec) .. function:: void arb_cos_pi_fmpq(arb_t c, const fmpq_t x, slong prec) Sets `s = \sin(\pi x)`, `c = \cos(\pi x)` where `x` is a rational number (whose numerator and denominator are assumed to be reduced). We first use trigonometric symmetries to reduce the argument to the octant `[0, 1/4]`. Then we either multiply by a numerical approximation of `\pi` and evaluate the trigonometric function the usual way, or we use algebraic methods, depending on which is estimated to be faster. Since the argument has been reduced to the first octant, the first of these two methods gives full accuracy even if the original argument is close to some root other the origin. .. function:: void arb_tan_pi(arb_t y, const arb_t x, slong prec) Sets `y = \tan(\pi x)`. .. function:: void arb_cot_pi(arb_t y, const arb_t x, slong prec) Sets `y = \cot(\pi x)`. .. function:: void arb_sec(arb_t res, const arb_t x, slong prec) Computes `\sec(x) = 1 / \cos(x)`. .. function:: void arb_csc(arb_t res, const arb_t x, slong prec) Computes `\csc(x) = 1 / \sin(x)`. .. function:: void arb_csc_pi(arb_t res, const arb_t x, slong prec) Computes `\csc(\pi x) = 1 / \sin(\pi x)`. .. function:: void arb_sinc(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{sinc}(x) = \sin(x) / x`. .. function:: void arb_sinc_pi(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{sinc}(\pi x) = \sin(\pi x) / (\pi x)`. Inverse trigonometric functions ------------------------------------------------------------------------------- .. function:: void arb_atan_arf(arb_t z, const arf_t x, slong prec) .. function:: void arb_atan(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{atan}(x)`. At low to medium precision (up to about 4096 bits), :func:`arb_atan_arf` uses table-based argument reduction and fast Taylor series evaluation via :func:`_arb_atan_taylor_rs`. At high precision, it falls back to MPFR. The function :func:`arb_atan` simply calls :func:`arb_atan_arf` with the midpoint as input, and separately adds the propagated error. The function :func:`arb_atan_arf` uses lookup tables if possible, and otherwise falls back to :func:`arb_atan_arf_bb`. .. function:: void arb_atan2(arb_t z, const arb_t b, const arb_t a, slong prec) Sets *r* to an the argument (phase) of the complex number `a + bi`, with the branch cut discontinuity on `(-\infty,0]`. We define `\operatorname{atan2}(0,0) = 0`, and for `a < 0`, `\operatorname{atan2}(0,a) = \pi`. .. function:: void arb_asin(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{asin}(x) = \operatorname{atan}(x / \sqrt{1-x^2})`. If `x` is not contained in the domain `[-1,1]`, the result is an indeterminate interval. .. function:: void arb_acos(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{acos}(x) = \pi/2 - \operatorname{asin}(x)`. If `x` is not contained in the domain `[-1,1]`, the result is an indeterminate interval. Hyperbolic functions ------------------------------------------------------------------------------- .. function:: void arb_sinh(arb_t s, const arb_t x, slong prec) .. function:: void arb_cosh(arb_t c, const arb_t x, slong prec) .. function:: void arb_sinh_cosh(arb_t s, arb_t c, const arb_t x, slong prec) Sets `s = \sinh(x)`, `c = \cosh(x)`. If the midpoint of `x` is close to zero and the hyperbolic sine is to be computed, evaluates `(e^{2x}\pm1) / (2e^x)` via :func:`arb_expm1` to avoid loss of accuracy. Otherwise evaluates `(e^x \pm e^{-x}) / 2`. .. function:: void arb_tanh(arb_t y, const arb_t x, slong prec) Sets `y = \tanh(x) = \sinh(x) / \cosh(x)`, evaluated via :func:`arb_expm1` as `\tanh(x) = (e^{2x} - 1) / (e^{2x} + 1)` if `|x|` is small, and as `\tanh(\pm x) = 1 - 2 e^{\mp 2x} / (1 + e^{\mp 2x})` if `|x|` is large. .. function:: void arb_coth(arb_t y, const arb_t x, slong prec) Sets `y = \coth(x) = \cosh(x) / \sinh(x)`, evaluated using the same strategy as :func:`arb_tanh`. .. function:: void arb_sech(arb_t res, const arb_t x, slong prec) Computes `\operatorname{sech}(x) = 1 / \cosh(x)`. .. function:: void arb_csch(arb_t res, const arb_t x, slong prec) Computes `\operatorname{csch}(x) = 1 / \sinh(x)`. Inverse hyperbolic functions ------------------------------------------------------------------------------- .. function:: void arb_atanh(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{atanh}(x)`. .. function:: void arb_asinh(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{asinh}(x)`. .. function:: void arb_acosh(arb_t z, const arb_t x, slong prec) Sets `z = \operatorname{acosh}(x)`. If `x < 1`, the result is an indeterminate interval. Constants ------------------------------------------------------------------------------- The following functions cache the computed values to speed up repeated calls at the same or lower precision. For further implementation details, see :ref:`algorithms_constants`. .. function:: void arb_const_pi(arb_t z, slong prec) Computes `\pi`. .. function:: void arb_const_sqrt_pi(arb_t z, slong prec) Computes `\sqrt{\pi}`. .. function:: void arb_const_log_sqrt2pi(arb_t z, slong prec) Computes `\log \sqrt{2 \pi}`. .. function:: void arb_const_log2(arb_t z, slong prec) Computes `\log(2)`. .. function:: void arb_const_log10(arb_t z, slong prec) Computes `\log(10)`. .. function:: void arb_const_euler(arb_t z, slong prec) Computes Euler's constant `\gamma = \lim_{k \rightarrow \infty} (H_k - \log k)` where `H_k = 1 + 1/2 + \ldots + 1/k`. .. function:: void arb_const_catalan(arb_t z, slong prec) Computes Catalan's constant `C = \sum_{n=0}^{\infty} (-1)^n / (2n+1)^2`. .. function:: void arb_const_e(arb_t z, slong prec) Computes `e = \exp(1)`. .. function:: void arb_const_khinchin(arb_t z, slong prec) Computes Khinchin's constant `K_0`. .. function:: void arb_const_glaisher(arb_t z, slong prec) Computes the Glaisher-Kinkelin constant `A = \exp(1/12 - \zeta'(-1))`. .. function:: void arb_const_apery(arb_t z, slong prec) Computes Apery's constant `\zeta(3)`. Lambert W function ------------------------------------------------------------------------------- .. function:: void arb_lambertw(arb_t res, const arb_t x, int flags, slong prec) Computes the Lambert W function, which solves the equation `w e^w = x`. The Lambert W function has infinitely many complex branches `W_k(x)`, two of which are real on a part of the real line. The principal branch `W_0(x)` is selected by setting *flags* to 0, and the `W_{-1}` branch is selected by setting *flags* to 1. The principal branch is real-valued for `x \ge -1/e` (taking values in `[-1,+\infty)`) and the `W_{-1}` branch is real-valued for `-1/e \le x < 0` and takes values in `(-\infty,-1]`. Elsewhere, the Lambert W function is complex and :func:`acb_lambertw` should be used. The implementation first computes a floating-point approximation heuristically and then computes a rigorously certified enclosure around this approximation. Some asymptotic cases are handled specially. The algorithm used to compute the Lambert W function is described in [Joh2017b]_, which follows the main ideas in [CGHJK1996]_. Gamma function and factorials ------------------------------------------------------------------------------- .. function:: void arb_rising_ui(arb_t z, const arb_t x, ulong n, slong prec) void arb_rising(arb_t z, const arb_t x, const arb_t n, slong prec) Computes the rising factorial `z = x (x+1) (x+2) \cdots (x+n-1)`. These functions are aliases for :func:`arb_hypgeom_rising_ui` and :func:`arb_hypgeom_rising`. .. function:: void arb_rising_fmpq_ui(arb_t z, const fmpq_t x, ulong n, slong prec) Computes the rising factorial `z = x (x+1) (x+2) \cdots (x+n-1)` using binary splitting. If the denominator or numerator of *x* is large compared to *prec*, it is more efficient to convert *x* to an approximation and use :func:`arb_rising_ui`. .. function :: void arb_rising2_ui(arb_t u, arb_t v, const arb_t x, ulong n, slong prec) Letting `u(x) = x (x+1) (x+2) \cdots (x+n-1)`, simultaneously compute `u(x)` and `v(x) = u'(x)`. This function is a wrapper of :func:`arb_hypgeom_rising_ui_jet`. .. function:: void arb_fac_ui(arb_t z, ulong n, slong prec) Computes the factorial `z = n!` via the gamma function. .. function:: void arb_doublefac_ui(arb_t z, ulong n, slong prec) Computes the double factorial `z = n!!` via the gamma function. .. function:: void arb_bin_ui(arb_t z, const arb_t n, ulong k, slong prec) .. function:: void arb_bin_uiui(arb_t z, ulong n, ulong k, slong prec) Computes the binomial coefficient `z = {n \choose k}`, via the rising factorial as `{n \choose k} = (n-k+1)_k / k!`. .. function:: void arb_gamma(arb_t z, const arb_t x, slong prec) void arb_gamma_fmpq(arb_t z, const fmpq_t x, slong prec) void arb_gamma_fmpz(arb_t z, const fmpz_t x, slong prec) Computes the gamma function `z = \Gamma(x)`. These functions are aliases for :func:`arb_hypgeom_gamma`, :func:`arb_hypgeom_gamma_fmpq`, :func:`arb_hypgeom_gamma_fmpz`. .. function:: void arb_lgamma(arb_t z, const arb_t x, slong prec) Computes the logarithmic gamma function `z = \log \Gamma(x)`. The complex branch structure is assumed, so if `x \le 0`, the result is an indeterminate interval. This function is an alias for :func:`arb_hypgeom_lgamma`. .. function:: void arb_rgamma(arb_t z, const arb_t x, slong prec) Computes the reciprocal gamma function `z = 1/\Gamma(x)`, avoiding division by zero at the poles of the gamma function. This function is an alias for :func:`arb_hypgeom_rgamma`. .. function:: void arb_digamma(arb_t y, const arb_t x, slong prec) Computes the digamma function `z = \psi(x) = (\log \Gamma(x))' = \Gamma'(x) / \Gamma(x)`. Zeta function ------------------------------------------------------------------------------- .. function:: void arb_zeta_ui_vec_borwein(arb_ptr z, ulong start, slong num, ulong step, slong prec) Evaluates `\zeta(s)` at `\mathrm{num}` consecutive integers *s* beginning with *start* and proceeding in increments of *step*. Uses Borwein's formula ([Bor2000]_, [GS2003]_), implemented to support fast multi-evaluation (but also works well for a single *s*). Requires `\mathrm{start} \ge 2`. For efficiency, the largest *s* should be at most about as large as *prec*. Arguments approaching *LONG_MAX* will cause overflows. One should therefore only use this function for *s* up to about *prec*, and then switch to the Euler product. The algorithm for single *s* is basically identical to the one used in MPFR (see [MPFR2012]_ for a detailed description). In particular, we evaluate the sum backwards to avoid storing more than one `d_k` coefficient, and use integer arithmetic throughout since it is convenient and the terms turn out to be slightly larger than `2^\mathrm{prec}`. The only numerical error in the main loop comes from the division by `k^s`, which adds less than 1 unit of error per term. For fast multi-evaluation, we repeatedly divide by `k^{\mathrm{step}}`. Each division reduces the input error and adds at most 1 unit of additional rounding error, so by induction, the error per term is always smaller than 2 units. .. function:: void arb_zeta_ui_asymp(arb_t x, ulong s, slong prec) .. function:: void arb_zeta_ui_euler_product(arb_t z, ulong s, slong prec) Computes `\zeta(s)` using the Euler product. This is fast only if *s* is large compared to the precision. Both methods are trivial wrappers for :func:`_acb_dirichlet_euler_product_real_ui`. .. function:: void arb_zeta_ui_bernoulli(arb_t x, ulong s, slong prec) Computes `\zeta(s)` for even *s* via the corresponding Bernoulli number. .. function:: void arb_zeta_ui_borwein_bsplit(arb_t x, ulong s, slong prec) Computes `\zeta(s)` for arbitrary `s \ge 2` using a binary splitting implementation of Borwein's algorithm. This has quasilinear complexity with respect to the precision (assuming that `s` is fixed). .. function:: void arb_zeta_ui_vec(arb_ptr x, ulong start, slong num, slong prec) .. function:: void arb_zeta_ui_vec_even(arb_ptr x, ulong start, slong num, slong prec) .. function:: void arb_zeta_ui_vec_odd(arb_ptr x, ulong start, slong num, slong prec) Computes `\zeta(s)` at *num* consecutive integers (respectively *num* even or *num* odd integers) beginning with `s = \mathrm{start} \ge 2`, automatically choosing an appropriate algorithm. .. function:: void arb_zeta_ui(arb_t x, ulong s, slong prec) Computes `\zeta(s)` for nonnegative integer `s \ne 1`, automatically choosing an appropriate algorithm. This function is intended for numerical evaluation of isolated zeta values; for multi-evaluation, the vector versions are more efficient. .. function:: void arb_zeta(arb_t z, const arb_t s, slong prec) Sets *z* to the value of the Riemann zeta function `\zeta(s)`. For computing derivatives with respect to `s`, use :func:`arb_poly_zeta_series`. .. function:: void arb_hurwitz_zeta(arb_t z, const arb_t s, const arb_t a, slong prec) Sets *z* to the value of the Hurwitz zeta function `\zeta(s,a)`. For computing derivatives with respect to `s`, use :func:`arb_poly_zeta_series`. Bernoulli numbers and polynomials ------------------------------------------------------------------------------- .. function:: void arb_bernoulli_ui(arb_t b, ulong n, slong prec) .. function:: void arb_bernoulli_fmpz(arb_t b, const fmpz_t n, slong prec) Sets `b` to the numerical value of the Bernoulli number `B_n` approximated to *prec* bits. The internal precision is increased automatically to give an accurate result. Note that, with huge *fmpz* input, the output will have a huge exponent and evaluation will accordingly be slower. A single division from the exact fraction of `B_n` is used if this value is in the global cache or the exact numerator roughly is larger than *prec* bits. Otherwise, the Riemann zeta function is used (see :func:`arb_bernoulli_ui_zeta`). This function reads `B_n` from the global cache if the number is already cached, but does not automatically extend the cache by itself. .. function:: void arb_bernoulli_ui_zeta(arb_t b, ulong n, slong prec) Sets `b` to the numerical value of `B_n` accurate to *prec* bits, computed using the formula `B_{2n} = (-1)^{n+1} 2 (2n)! \zeta(2n) / (2 \pi)^n`. To avoid potential infinite recursion, we explicitly call the Euler product implementation of the zeta function. This method will only give high accuracy if the precision is small enough compared to `n` for the Euler product to converge rapidly. .. function:: void arb_bernoulli_poly_ui(arb_t res, ulong n, const arb_t x, slong prec) Sets *res* to the value of the Bernoulli polynomial `B_n(x)`. Warning: this function is only fast if either *n* or *x* is a small integer. This function reads Bernoulli numbers from the global cache if they are already cached, but does not automatically extend the cache by itself. .. function:: void arb_power_sum_vec(arb_ptr res, const arb_t a, const arb_t b, slong len, slong prec) For *n* from 0 to *len* - 1, sets entry *n* in the output vector *res* to .. math :: S_n(a,b) = \frac{1}{n+1}\left(B_{n+1}(b) - B_{n+1}(a)\right) where `B_n(x)` is a Bernoulli polynomial. If *a* and *b* are integers and `b \ge a`, this is equivalent to .. math :: S_n(a,b) = \sum_{k=a}^{b-1} k^n. The computation uses the generating function for Bernoulli polynomials. Polylogarithms ------------------------------------------------------------------------------- .. function:: void arb_polylog(arb_t w, const arb_t s, const arb_t z, slong prec) .. function:: void arb_polylog_si(arb_t w, slong s, const arb_t z, slong prec) Sets *w* to the polylogarithm `\operatorname{Li}_s(z)`. Other special functions ------------------------------------------------------------------------------- .. function:: void arb_fib_fmpz(arb_t z, const fmpz_t n, slong prec) .. function:: void arb_fib_ui(arb_t z, ulong n, slong prec) Computes the Fibonacci number `F_n`. Uses the binary squaring algorithm described in [Tak2000]_. Provided that *n* is small enough, an exact Fibonacci number can be computed by setting the precision to *ARF_PREC_EXACT*. .. function:: void arb_agm(arb_t z, const arb_t x, const arb_t y, slong prec) Sets *z* to the arithmetic-geometric mean of *x* and *y*. .. function:: void arb_chebyshev_t_ui(arb_t a, ulong n, const arb_t x, slong prec) .. function:: void arb_chebyshev_u_ui(arb_t a, ulong n, const arb_t x, slong prec) Evaluates the Chebyshev polynomial of the first kind `a = T_n(x)` or the Chebyshev polynomial of the second kind `a = U_n(x)`. .. function:: void arb_chebyshev_t2_ui(arb_t a, arb_t b, ulong n, const arb_t x, slong prec) .. function:: void arb_chebyshev_u2_ui(arb_t a, arb_t b, ulong n, const arb_t x, slong prec) Simultaneously evaluates `a = T_n(x), b = T_{n-1}(x)` or `a = U_n(x), b = U_{n-1}(x)`. Aliasing between *a*, *b* and *x* is not permitted. .. function:: void arb_bell_sum_bsplit(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, slong prec) .. function:: void arb_bell_sum_taylor(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, slong prec) Helper functions for Bell numbers, evaluating the sum `\sum_{k=a}^{b-1} k^n / k!`. If *mmag* is non-NULL, it may be used to indicate that the target error tolerance should be `2^{mmag - prec}`. .. function:: void arb_bell_fmpz(arb_t res, const fmpz_t n, slong prec) .. function:: void arb_bell_ui(arb_t res, ulong n, slong prec) Sets *res* to the Bell number `B_n`. If the number is too large to fit exactly in *prec* bits, a numerical approximation is computed efficiently. The algorithm to compute Bell numbers, including error analysis, is described in detail in [Joh2015]_. .. function:: void arb_euler_number_fmpz(arb_t res, const fmpz_t n, slong prec) void arb_euler_number_ui(arb_t res, ulong n, slong prec) Sets *res* to the Euler number `E_n`, which is defined by the exponential generating function `1 / \cosh(x)`. The result will be exact if `E_n` is exactly representable at the requested precision. .. function:: void arb_fmpz_euler_number_ui_multi_mod(fmpz_t res, ulong n, double alpha) void arb_fmpz_euler_number_ui(fmpz_t res, ulong n) Computes the Euler number `E_n` as an exact integer. The default algorithm uses a table lookup, the Dirichlet beta function or a hybrid modular algorithm depending on the size of *n*. The *multi_mod* algorithm accepts a tuning parameter *alpha* which can be set to a negative value to use defaults. .. function:: void arb_partitions_fmpz(arb_t res, const fmpz_t n, slong prec) .. function:: void arb_partitions_ui(arb_t res, ulong n, slong prec) Sets *res* to the partition function `p(n)`. When *n* is large and `\log_2 p(n)` is more than twice *prec*, the leading term in the Hardy-Ramanujan asymptotic series is used together with an error bound. Otherwise, the exact value is computed and rounded. .. function:: void arb_primorial_nth_ui(arb_t res, ulong n, slong prec) Sets *res* to the *nth* primorial, defined as the product of the first *n* prime numbers. The running time is quasilinear in *n*. .. function:: void arb_primorial_ui(arb_t res, ulong n, slong prec) Sets *res* to the primorial defined as the product of the positive integers up to and including *n*. The running time is quasilinear in *n*. Internals for computing elementary functions ------------------------------------------------------------------------------- .. function:: void _arb_atan_taylor_naive(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int alternating) .. function:: void _arb_atan_taylor_rs(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int alternating) Computes an approximation of `y = \sum_{k=0}^{N-1} x^{2k+1} / (2k+1)` (if *alternating* is 0) or `y = \sum_{k=0}^{N-1} (-1)^k x^{2k+1} / (2k+1)` (if *alternating* is 1). Used internally for computing arctangents and logarithms. The *naive* version uses the forward recurrence, and the *rs* version uses a division-avoiding rectangular splitting scheme. Requires `N \le 255`, `0 \le x \le 1/16`, and *xn* positive. The input *x* and output *y* are fixed-point numbers with *xn* fractional limbs. A bound for the ulp error is written to *error*. .. function:: void _arb_exp_taylor_naive(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N) .. function:: void _arb_exp_taylor_rs(mp_ptr y, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N) Computes an approximation of `y = \sum_{k=0}^{N-1} x^k / k!`. Used internally for computing exponentials. The *naive* version uses the forward recurrence, and the *rs* version uses a division-avoiding rectangular splitting scheme. Requires `N \le 287`, `0 \le x \le 1/16`, and *xn* positive. The input *x* is a fixed-point number with *xn* fractional limbs, and the output *y* is a fixed-point number with *xn* fractional limbs plus one extra limb for the integer part of the result. A bound for the ulp error is written to *error*. .. function:: void _arb_sin_cos_taylor_naive(mp_ptr ysin, mp_ptr ycos, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N) .. function:: void _arb_sin_cos_taylor_rs(mp_ptr ysin, mp_ptr ycos, mp_limb_t * error, mp_srcptr x, mp_size_t xn, ulong N, int sinonly, int alternating) Computes approximations of `y_s = \sum_{k=0}^{N-1} (-1)^k x^{2k+1} / (2k+1)!` and `y_c = \sum_{k=0}^{N-1} (-1)^k x^{2k} / (2k)!`. Used internally for computing sines and cosines. The *naive* version uses the forward recurrence, and the *rs* version uses a division-avoiding rectangular splitting scheme. Requires `N \le 143`, `0 \le x \le 1/16`, and *xn* positive. The input *x* and outputs *ysin*, *ycos* are fixed-point numbers with *xn* fractional limbs. A bound for the ulp error is written to *error*. If *sinonly* is 1, only the sine is computed; if *sinonly* is 0 both the sine and cosine are computed. To compute sin and cos, *alternating* should be 1. If *alternating* is 0, the hyperbolic sine is computed (this is currently only intended to be used together with *sinonly*). .. function:: int _arb_get_mpn_fixed_mod_log2(mp_ptr w, fmpz_t q, mp_limb_t * error, const arf_t x, mp_size_t wn) Attempts to write `w = x - q \log(2)` with `0 \le w < \log(2)`, where *w* is a fixed-point number with *wn* limbs and ulp error *error*. Returns success. .. function:: int _arb_get_mpn_fixed_mod_pi4(mp_ptr w, fmpz_t q, int * octant, mp_limb_t * error, const arf_t x, mp_size_t wn) Attempts to write `w = |x| - q \pi/4` with `0 \le w < \pi/4`, where *w* is a fixed-point number with *wn* limbs and ulp error *error*. Returns success. The value of *q* mod 8 is written to *octant*. The output variable *q* can be NULL, in which case the full value of *q* is not stored. .. function:: slong _arb_exp_taylor_bound(slong mag, slong prec) Returns *n* such that `\left|\sum_{k=n}^{\infty} x^k / k!\right| \le 2^{-\mathrm{prec}}`, assuming `|x| \le 2^{\mathrm{mag}} \le 1/4`. .. function:: void arb_exp_arf_bb(arb_t z, const arf_t x, slong prec, int m1) Computes the exponential function using the bit-burst algorithm. If *m1* is nonzero, the exponential function minus one is computed accurately. Aborts if *x* is extremely small or large (where another algorithm should be used). For large *x*, repeated halving is used. In fact, we always do argument reduction until `|x|` is smaller than about `2^{-d}` where `d \approx 16` to speed up convergence. If `|x| \approx 2^m`, we thus need about `m+d` squarings. Computing `\log(2)` costs roughly 100-200 multiplications, so is not usually worth the effort at very high precision. However, this function could be improved by using `\log(2)` based reduction at precision low enough that the value can be assumed to be cached. .. function:: void _arb_exp_sum_bs_simple(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) .. function:: void _arb_exp_sum_bs_powtab(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) Computes *T*, *Q* and *Qexp* such that `T / (Q 2^{\text{Qexp}}) = \sum_{k=1}^N (x/2^r)^k/k!` using binary splitting. Note that the sum is taken to *N* inclusive and omits the constant term. The *powtab* version precomputes a table of powers of *x*, resulting in slightly higher memory usage but better speed. For best efficiency, *N* should have many trailing zero bits. .. function:: void arb_exp_arf_rs_generic(arb_t res, const arf_t x, slong prec, int minus_one) Computes the exponential function using a generic version of the rectangular splitting strategy, intended for intermediate precision. .. function:: void _arb_atan_sum_bs_simple(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) .. function:: void _arb_atan_sum_bs_powtab(fmpz_t T, fmpz_t Q, flint_bitcnt_t * Qexp, const fmpz_t x, flint_bitcnt_t r, slong N) Computes *T*, *Q* and *Qexp* such that `T / (Q 2^{\text{Qexp}}) = \sum_{k=1}^N (-1)^k (x/2^r)^{2k} / (2k+1)` using binary splitting. Note that the sum is taken to *N* inclusive, omits the linear term, and requires a final multiplication by `(x/2^r)` to give the true series for atan. The *powtab* version precomputes a table of powers of *x*, resulting in slightly higher memory usage but better speed. For best efficiency, *N* should have many trailing zero bits. .. function:: void arb_atan_arf_bb(arb_t z, const arf_t x, slong prec) Computes the arctangent of *x*. Initially, the argument-halving formula .. math :: \operatorname{atan}(x) = 2 \operatorname{atan}\left(\frac{x}{1+\sqrt{1+x^2}}\right) is applied up to 8 times to get a small argument. Then a version of the bit-burst algorithm is used. The functional equation .. math :: \operatorname{atan}(x) = \operatorname{atan}(p/q) + \operatorname{atan}(w), \quad w = \frac{qx-p}{px+q}, \quad p = \lfloor qx \rfloor is applied repeatedly instead of integrating a differential equation for the arctangent, as this appears to be more efficient. .. function:: void arb_sin_cos_arf_generic(arb_t s, arb_t c, const arf_t x, slong prec) Computes the sine and cosine of *x* using a generic strategy. This function gets called internally by the main sin and cos functions when the precision for argument reduction or series evaluation based on lookup tables is exhausted. This function first performs a cheap test to see if `|x| < \pi / 2 - \varepsilon`. If the test fails, it uses `\pi` to reduce the argument to the first octant, and then evaluates the sin and cos functions recursively (this call cannot result in infinite recursion). If no argument reduction is needed, this function uses a generic version of the rectangular splitting algorithm if the precision is not too high, and otherwise invokes the asymptotically fast bit-burst algorithm. .. function:: void arb_sin_cos_arf_bb(arb_t s, arb_t c, const arf_t x, slong prec) Computes the sine and cosine of *x* using the bit-burst algorithm. It is required that `|x| < \pi / 2` (this is not checked). .. function:: void arb_sin_cos_wide(arb_t s, arb_t c, const arb_t x, slong prec) Computes an accurate enclosure (with both endpoints optimal to within about `2^{-30}` as afforded by the radius format) of the range of sine and cosine on a given wide interval. The computation is done by evaluating the sine and cosine at the interval endpoints and determining whether peaks of -1 or 1 occur between the endpoints. The interval is then converted back to a ball. The internal computations are done with doubles, using a simple floating-point algorithm to approximate the sine and cosine. It is easy to see that the cumulative errors in this algorithm add up to less than `2^{-30}`, with the dominant source of error being a single approximate reduction by `\pi/2`. This reduction is done safely using doubles up to a magnitude of about `2^{20}`. For larger arguments, a slower reduction using :type:`arb_t` arithmetic is done as a preprocessing step. .. function:: void arb_sin_cos_generic(arb_t s, arb_t c, const arb_t x, slong prec) Computes the sine and cosine of *x* by taking care of various special cases and computing the propagated error before calling :func:`arb_sin_cos_arf_generic`. This is used as a fallback inside :func:`arb_sin_cos` to take care of all cases without a fast path in that function. Vector functions ------------------------------------------------------------------------------- .. function:: void _arb_vec_zero(arb_ptr vec, slong n) Sets all entries in *vec* to zero. .. function:: int _arb_vec_is_zero(arb_srcptr vec, slong len) Returns nonzero iff all entries in *x* are zero. .. function:: int _arb_vec_is_finite(arb_srcptr x, slong len) Returns nonzero iff all entries in *x* certainly are finite. .. function:: void _arb_vec_set(arb_ptr res, arb_srcptr vec, slong len) Sets *res* to a copy of *vec*. .. function:: void _arb_vec_set_round(arb_ptr res, arb_srcptr vec, slong len, slong prec) Sets *res* to a copy of *vec*, rounding each entry to *prec* bits. .. function:: void _arb_vec_swap(arb_ptr vec1, arb_ptr vec2, slong len) Swaps the entries of *vec1* and *vec2*. .. function:: void _arb_vec_neg(arb_ptr B, arb_srcptr A, slong n) .. function:: void _arb_vec_sub(arb_ptr C, arb_srcptr A, arb_srcptr B, slong n, slong prec) .. function:: void _arb_vec_add(arb_ptr C, arb_srcptr A, arb_srcptr B, slong n, slong prec) .. function:: void _arb_vec_scalar_mul(arb_ptr res, arb_srcptr vec, slong len, const arb_t c, slong prec) .. function:: void _arb_vec_scalar_div(arb_ptr res, arb_srcptr vec, slong len, const arb_t c, slong prec) .. function:: void _arb_vec_scalar_mul_fmpz(arb_ptr res, arb_srcptr vec, slong len, const fmpz_t c, slong prec) .. function:: void _arb_vec_scalar_mul_2exp_si(arb_ptr res, arb_srcptr src, slong len, slong c) .. function:: void _arb_vec_scalar_addmul(arb_ptr res, arb_srcptr vec, slong len, const arb_t c, slong prec) Performs the respective scalar operation elementwise. .. function:: void _arb_vec_get_mag(mag_t bound, arb_srcptr vec, slong len, slong prec) Sets *bound* to an upper bound for the entries in *vec*. .. function:: slong _arb_vec_bits(arb_srcptr x, slong len) Returns the maximum of :func:`arb_bits` for all entries in *vec*. .. function:: void _arb_vec_set_powers(arb_ptr xs, const arb_t x, slong len, slong prec) Sets *xs* to the powers `1, x, x^2, \ldots, x^{len-1}`. .. function:: void _arb_vec_add_error_arf_vec(arb_ptr res, arf_srcptr err, slong len) .. function:: void _arb_vec_add_error_mag_vec(arb_ptr res, mag_srcptr err, slong len) Adds the magnitude of each entry in *err* to the radius of the corresponding entry in *res*. .. function:: void _arb_vec_indeterminate(arb_ptr vec, slong len) Applies :func:`arb_indeterminate` elementwise. .. function:: void _arb_vec_trim(arb_ptr res, arb_srcptr vec, slong len) Applies :func:`arb_trim` elementwise. .. function:: int _arb_vec_get_unique_fmpz_vec(fmpz * res, arb_srcptr vec, slong len) Calls :func:`arb_get_unique_fmpz` elementwise and returns nonzero if all entries can be rounded uniquely to integers. If any entry in *vec* cannot be rounded uniquely to an integer, returns zero. arb-2.22.1/doc/source/arb_calc.rst000066400000000000000000000244661417376376500167260ustar00rootroot00000000000000.. _arb-calc: **arb_calc.h** -- calculus with real-valued functions =============================================================================== This module provides functions for operations of calculus over the real numbers (intended to include root-finding, optimization, integration, and so on). It is planned that the module will include two types of algorithms: * Interval algorithms that give provably correct results. An example would be numerical integration on an interval by dividing the interval into small balls and evaluating the function on each ball, giving rigorous upper and lower bounds. * Conventional numerical algorithms that use heuristics to estimate the accuracy of a result, without guaranteeing that it is correct. An example would be numerical integration based on pointwise evaluation, where the error is estimated by comparing the results with two different sets of evaluation points. Ball arithmetic then still tracks the accuracy of the function evaluations. Any algorithms of the second kind will be clearly marked as such. Types, macros and constants ------------------------------------------------------------------------------- .. type:: arb_calc_func_t Typedef for a pointer to a function with signature:: int func(arb_ptr out, const arb_t inp, void * param, slong order, slong prec) implementing a univariate real function `f(x)`. When called, *func* should write to *out* the first *order* coefficients in the Taylor series expansion of `f(x)` at the point *inp*, evaluated at a precision of *prec* bits. The *param* argument may be used to pass through additional parameters to the function. The return value is reserved for future use as an error code. It can be assumed that *out* and *inp* are not aliased and that *order* is positive. .. macro:: ARB_CALC_SUCCESS Return value indicating that an operation is successful. .. macro:: ARB_CALC_IMPRECISE_INPUT Return value indicating that the input to a function probably needs to be computed more accurately. .. macro:: ARB_CALC_NO_CONVERGENCE Return value indicating that an algorithm has failed to convergence, possibly due to the problem not having a solution, the algorithm not being applicable, or the precision being insufficient Debugging ------------------------------------------------------------------------------- .. var:: int arb_calc_verbose If set, enables printing information about the calculation to standard output. Subdivision-based root finding ------------------------------------------------------------------------------- .. type:: arf_interval_struct .. type:: arf_interval_t An :type:`arf_interval_struct` consists of a pair of :type:`arf_struct`, representing an interval used for subdivision-based root-finding. An :type:`arf_interval_t` is defined as an array of length one of type :type:`arf_interval_struct`, permitting an :type:`arf_interval_t` to be passed by reference. .. type:: arf_interval_ptr Alias for ``arf_interval_struct *``, used for vectors of intervals. .. type:: arf_interval_srcptr Alias for ``const arf_interval_struct *``, used for vectors of intervals. .. function:: void arf_interval_init(arf_interval_t v) .. function:: void arf_interval_clear(arf_interval_t v) .. function:: arf_interval_ptr _arf_interval_vec_init(slong n) .. function:: void _arf_interval_vec_clear(arf_interval_ptr v, slong n) .. function:: void arf_interval_set(arf_interval_t v, const arf_interval_t u) .. function:: void arf_interval_swap(arf_interval_t v, arf_interval_t u) .. function:: void arf_interval_get_arb(arb_t x, const arf_interval_t v, slong prec) .. function:: void arf_interval_printd(const arf_interval_t v, slong n) Helper functions for endpoint-based intervals. .. function:: void arf_interval_fprintd(FILE * file, const arf_interval_t v, slong n) Helper functions for endpoint-based intervals. .. function:: slong arb_calc_isolate_roots(arf_interval_ptr * found, int ** flags, arb_calc_func_t func, void * param, const arf_interval_t interval, slong maxdepth, slong maxeval, slong maxfound, slong prec) Rigorously isolates single roots of a real analytic function on the interior of an interval. This routine writes an array of *n* interesting subintervals of *interval* to *found* and corresponding flags to *flags*, returning the integer *n*. The output has the following properties: * The function has no roots on *interval* outside of the output subintervals. * Subintervals are sorted in increasing order (with no overlap except possibly starting and ending with the same point). * Subintervals with a flag of 1 contain exactly one (single) root. * Subintervals with any other flag may or may not contain roots. If no flags other than 1 occur, all roots of the function on *interval* have been isolated. If there are output subintervals on which the existence or nonexistence of roots could not be determined, the user may attempt further searches on those subintervals (possibly with increased precision and/or increased bounds for the breaking criteria). Note that roots of multiplicity higher than one and roots located exactly at endpoints cannot be isolated by the algorithm. The following breaking criteria are implemented: * At most *maxdepth* recursive subdivisions are attempted. The smallest details that can be distinguished are therefore about `2^{-\text{maxdepth}}` times the width of *interval*. A typical, reasonable value might be between 20 and 50. * If the total number of tested subintervals exceeds *maxeval*, the algorithm is terminated and any untested subintervals are added to the output. The total number of calls to *func* is thereby restricted to a small multiple of *maxeval* (the actual count can be slightly higher depending on implementation details). A typical, reasonable value might be between 100 and 100000. * The algorithm terminates if *maxfound* roots have been isolated. In particular, setting *maxfound* to 1 can be used to locate just one root of the function even if there are numerous roots. To try to find all roots, *LONG_MAX* may be passed. The argument *prec* denotes the precision used to evaluate the function. It is possibly also used for some other arithmetic operations performed internally by the algorithm. Note that it probably does not make sense for *maxdepth* to exceed *prec*. Warning: it is assumed that subdivision points of *interval* can be represented exactly as floating-point numbers in memory. Do not pass `1 \pm 2^{-10^{100}}` as input. .. function:: int arb_calc_refine_root_bisect(arf_interval_t r, arb_calc_func_t func, void * param, const arf_interval_t start, slong iter, slong prec) Given an interval *start* known to contain a single root of *func*, refines it using *iter* bisection steps. The algorithm can return a failure code if the sign of the function at an evaluation point is ambiguous. The output *r* is set to a valid isolating interval (possibly just *start*) even if the algorithm fails. Newton-based root finding ------------------------------------------------------------------------------- .. function:: void arb_calc_newton_conv_factor(arf_t conv_factor, arb_calc_func_t func, void * param, const arb_t conv_region, slong prec) Given an interval `I` specified by *conv_region*, evaluates a bound for `C = \sup_{t,u \in I} \frac{1}{2} |f''(t)| / |f'(u)|`, where `f` is the function specified by *func* and *param*. The bound is obtained by evaluating `f'(I)` and `f''(I)` directly. If `f` is ill-conditioned, `I` may need to be extremely precise in order to get an effective, finite bound for *C*. .. function:: int arb_calc_newton_step(arb_t xnew, arb_calc_func_t func, void * param, const arb_t x, const arb_t conv_region, const arf_t conv_factor, slong prec) Performs a single step with an interval version of Newton's method. The input consists of the function `f` specified by *func* and *param*, a ball `x = [m-r, m+r]` known to contain a single root of `f`, a ball `I` (*conv_region*) containing `x` with an associated bound (*conv_factor*) for `C = \sup_{t,u \in I} \frac{1}{2} |f''(t)| / |f'(u)|`, and a working precision *prec*. The Newton update consists of setting `x' = [m'-r', m'+r']` where `m' = m - f(m) / f'(m)` and `r' = C r^2`. The expression `m - f(m) / f'(m)` is evaluated using ball arithmetic at a working precision of *prec* bits, and the rounding error during this evaluation is accounted for in the output. We now check that `x' \in I` and `r' < r`. If both conditions are satisfied, we set *xnew* to `x'` and return *ARB_CALC_SUCCESS*. If either condition fails, we set *xnew* to `x` and return *ARB_CALC_NO_CONVERGENCE*, indicating that no progress is made. .. function:: int arb_calc_refine_root_newton(arb_t r, arb_calc_func_t func, void * param, const arb_t start, const arb_t conv_region, const arf_t conv_factor, slong eval_extra_prec, slong prec) Refines a precise estimate of a single root of a function to high precision by performing several Newton steps, using nearly optimally chosen doubling precision steps. The inputs are defined as for *arb_calc_newton_step*, except for the precision parameters: *prec* is the target accuracy and *eval_extra_prec* is the estimated number of guard bits that need to be added to evaluate the function accurately close to the root (for example, if the function is a polynomial with large coefficients of alternating signs and Horner's rule is used to evaluate it, the extra precision should typically be approximately the bit size of the coefficients). This function returns *ARB_CALC_SUCCESS* if all attempted Newton steps are successful (note that this does not guarantee that the computed root is accurate to *prec* bits, which has to be verified by the user), only that it is more accurate than the starting ball. On failure, *ARB_CALC_IMPRECISE_INPUT* or *ARB_CALC_NO_CONVERGENCE* may be returned. In this case, *r* is set to a ball for the root which is valid but likely does have full accuracy (it can possibly just be equal to the starting ball). arb-2.22.1/doc/source/arb_fmpz_poly.rst000066400000000000000000000142511417376376500200320ustar00rootroot00000000000000.. _arb_fmpz_poly: **arb_fmpz_poly.h** -- extra methods for integer polynomials ========================================================================================= This module provides methods for FLINT polynomials with integer and rational coefficients (:type:`fmpz_poly_t`) and (:type:`fmpq_poly_t`) requiring use of Arb real or complex numbers. Some methods output real or complex numbers while others use real and complex numbers internally to produce an exact result. This module also contains some useful helper functions not specifically related to real and complex numbers. Note that methods that combine Arb *polynomials* and FLINT polynomials are found in the respective Arb polynomial modules, such as :func:`arb_poly_set_fmpz_poly` and :func:`arb_poly_get_unique_fmpz_poly`. Evaluation ------------------------------------------------------------------------------- .. function:: void _arb_fmpz_poly_evaluate_arb_horner(arb_t res, const fmpz * poly, slong len, const arb_t x, slong prec) .. function:: void arb_fmpz_poly_evaluate_arb_horner(arb_t res, const fmpz_poly_t poly, const arb_t x, slong prec) .. function:: void _arb_fmpz_poly_evaluate_arb_rectangular(arb_t res, const fmpz * poly, slong len, const arb_t x, slong prec) .. function:: void arb_fmpz_poly_evaluate_arb_rectangular(arb_t res, const fmpz_poly_t poly, const arb_t x, slong prec) .. function:: void _arb_fmpz_poly_evaluate_arb(arb_t res, const fmpz * poly, slong len, const arb_t x, slong prec) .. function:: void arb_fmpz_poly_evaluate_arb(arb_t res, const fmpz_poly_t poly, const arb_t x, slong prec) .. function:: void _arb_fmpz_poly_evaluate_acb_horner(acb_t res, const fmpz * poly, slong len, const acb_t x, slong prec) .. function:: void arb_fmpz_poly_evaluate_acb_horner(acb_t res, const fmpz_poly_t poly, const acb_t x, slong prec) .. function:: void _arb_fmpz_poly_evaluate_acb_rectangular(acb_t res, const fmpz * poly, slong len, const acb_t x, slong prec) .. function:: void arb_fmpz_poly_evaluate_acb_rectangular(acb_t res, const fmpz_poly_t poly, const acb_t x, slong prec) .. function:: void _arb_fmpz_poly_evaluate_acb(acb_t res, const fmpz * poly, slong len, const acb_t x, slong prec) .. function:: void arb_fmpz_poly_evaluate_acb(acb_t res, const fmpz_poly_t poly, const acb_t x, slong prec) Evaluates *poly* (given by a polynomial object or an array with *len* coefficients) at the given real or complex number, respectively using Horner's rule, rectangular splitting, or a default algorithm choice. Utility methods ------------------------------------------------------------------------------- .. function:: ulong arb_fmpz_poly_deflation(const fmpz_poly_t poly) Finds the maximal exponent by which *poly* can be deflated. .. function:: void arb_fmpz_poly_deflate(fmpz_poly_t res, const fmpz_poly_t poly, ulong deflation) Sets *res* to a copy of *poly* deflated by the exponent *deflation*. Polynomial roots ------------------------------------------------------------------------------- .. function:: void arb_fmpz_poly_complex_roots(acb_ptr roots, const fmpz_poly_t poly, int flags, slong prec) Writes to *roots* all the real and complex roots of the polynomial *poly*, computed to at least *prec* accurate bits. The root enclosures are guaranteed to be disjoint, so that all roots are isolated. The real roots are written first in ascending order (with the imaginary parts set exactly to zero). The following nonreal roots are written in arbitrary order, but with conjugate pairs grouped together (the root in the upper plane leading the root in the lower plane). The input polynomial *must* be squarefree. For a general polynomial, compute the squarefree part `f / \gcd(f,f')` or do a full squarefree factorization to obtain the multiplicities of the roots:: fmpz_poly_factor_t fac; fmpz_poly_factor_init(fac); fmpz_poly_factor_squarefree(fac, poly); for (i = 0; i < fac->num; i++) { deg = fmpz_poly_degree(fac->p + i); flint_printf("%wd roots of multiplicity %wd\n", deg, fac->exp[i]); roots = _acb_vec_init(deg); arb_fmpz_poly_complex_roots(roots, fac->p + i, 0, prec); _acb_vec_clear(roots, deg); } fmpz_poly_factor_clear(fac); All roots are refined to a relative accuracy of at least *prec* bits. The output values will generally have higher actual precision, depending on the precision needed for isolation and the precision used internally by the algorithm. This implementation should be adequate for general use, but it is not currently competitive with state-of-the-art isolation methods for finding real roots alone. The following *flags* are supported: * *ARB_FMPZ_POLY_ROOTS_VERBOSE* Special polynomials ------------------------------------------------------------------------------- Note: see also the methods available in FLINT (e.g. for cyclotomic polynomials). .. function:: void arb_fmpz_poly_cos_minpoly(fmpz_poly_t res, ulong n) Sets *res* to the monic minimal polynomial of `2 \cos(2 \pi / n)`. This is a wrapper of FLINT's *fmpz_poly_cos_minpoly*, provided here for backward compatibility. .. function:: void arb_fmpz_poly_gauss_period_minpoly(fmpz_poly_t res, ulong q, ulong n) Sets *res* to the minimal polynomial of the Gaussian periods `\sum_{a \in H} \zeta^a` where `\zeta = \exp(2 \pi i / q)` and *H* are the cosets of the subgroups of order `d = (q - 1) / n` of `(\mathbb{Z}/q\mathbb{Z})^{\times}`. The resulting polynomial has degree *n*. When `d = 1`, the result is the cyclotomic polynomial `\Phi_q`. The implementation assumes that *q* is prime, and that *n* is a divisor of `q - 1` such that *n* is coprime with *d*. If any condition is not met, *res* is set to the zero polynomial. This method provides a fast (in practice) way to construct finite field extensions of prescribed degree. If *q* satisfies the conditions stated above and `(q-1)/f` additionally is coprime with *n*, where *f* is the multiplicative order of *p* mod *q*, then the Gaussian period minimal polynomial is irreducible over `\operatorname{GF}(p)` [CP2005]_. arb-2.22.1/doc/source/arb_fpwrap.rst000066400000000000000000000725301417376376500173160ustar00rootroot00000000000000.. _arb_fpwrap: **arb_fpwrap.h** -- floating-point wrappers of Arb mathematical functions ========================================================================================= This module provides wrappers of Arb functions intended users who want accurate floating-point mathematical functions without necessarily caring about ball arithmetic. The wrappers take floating-point input, give floating-point output, and automatically increase the internal working precision to ensure that the output is accurate (in the rare case of failure, they output NaN along with an error code). **Warning:** This module is experimental (as of Arb 2.21). It has not been extensively tested, and interfaces may change in the future. Supported types: * ``double`` and ``complex_double`` (53-bit precision) Limitations: * The wrappers currently only handle finite input and points where function value is finite. For example, they do not know that `\log(0) = -\infty` or that `\exp(-\infty) = 0`. Singular input or output result in ``FPWRAP_UNABLE`` and a NaN output value. Evaluation of limit values may be implemented in the future for some functions. * The wrappers currently treat ``-0.0`` as ``+0.0``. Users who need to distinguish signs of zero, e.g. on branch cuts, currently need to do so manually. * When requesting *correct rounding*, the wrappers can fail to converge in asymptotic or exact cases (where special algorithms are required). * If the value is computed accurately internally but is too small to represent as a floating-point number, the result will be ``-0.0`` or ``+0.0`` (on underflow) or ``-Inf`` or ``+Inf`` (on overflow). Since the underflowed or overflowed result is the best possible floating-point approximation of the true value, this outcome is considered correct and the flag ``FPWRAP_SUCCESS`` is returned. In the future, return status flags may be added to indicate that underflow or overflow has occurred. * Different rounding modes are not yet implemented. Option and return flags ------------------------------------------------------------------------------- Functions return an ``int`` flag indicating the status. .. macro:: FPWRAP_SUCCESS Indicates an accurate result. (Up to inevitable underflow or overflow in the final conversion to a floating-point result; see above.) This flag has the numerical value 0. .. macro:: FPWRAP_UNABLE Indicates failure (unable to achieve to target accuracy, possibly because of a singularity). The output is set to NaN. This flag has the numerical value 1. Functions take a *flags* parameter specifying optional rounding and termination behavior. This can be set to 0 to use defaults. .. macro:: FPWRAP_ACCURATE_PARTS For complex output, compute both real and imaginary parts to full relative accuracy. By default (if this flag is not set), complex results are computed to at least 53-bit accuracy as a whole, but if either the real or imaginary part is much smaller than the other, that part can have a large relative error. Setting this flag can result in slower evaluation or failure to converge in some cases. This flag has the numerical value 1. .. macro:: FPWRAP_CORRECT_ROUNDING Guarantees *correct rounding*. By default (if this flag is not set), real results are accurate up to the rounding of the last bit, but the last bit is not guaranteed to be rounded optimally. Setting this flag can result in slower evaluation or failure to converge in some cases. Correct rounding automatically applies to both real and imaginary parts of complex numbers, so it is unnecessary to set both this flag and *FPWRAP_ACCURATE_PARTS*. This flag has the numerical value 2. .. macro:: FPWRAP_WORK_LIMIT Multiplied by an integer, specifies the maximum working precision to use before giving up. With ``n * FPWRAP_WORK_LIMIT`` added to *flags*, `n` levels of precision will be used. The default `n = 0` is equivalent to `n = 8`, which for ``double`` means trying with a working precision of 64, 128, 256, 512, 1024, 2048, 4096, 8192 bits. With ``flags = 2 * FPWRAP_WORK_LIMIT``, we only try 64 and 128 bits, and with ``flags = 16 * FPWRAP_WORK_LIMIT`` we go up to 2097152 bits. This flag has the numerical value 65536. Types ------------------------------------------------------------------------------- Outputs are passed by reference so that we can return status flags and so that the interface is uniform for functions with multiple outputs. .. type:: complex_double A struct of two ``double`` components (``real`` and ``imag``), used to represent a machine-precision complex number. We use this custom type instead of the complex types defined in ```` since Arb does not depend on C99. Users should easily be able to convert to the C99 complex type since the layout in memory is identical. Functions ------------------------------------------------------------------------------- Elementary functions ............................................................................... .. function:: int arb_fpwrap_double_exp(double * res, double x, int flags) int arb_fpwrap_cdouble_exp(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_expm1(double * res, double x, int flags) int arb_fpwrap_cdouble_expm1(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_log(double * res, double x, int flags) int arb_fpwrap_cdouble_log(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_log1p(double * res, double x, int flags) int arb_fpwrap_cdouble_log1p(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_pow(double * res, double x, double y, int flags) int arb_fpwrap_cdouble_pow(complex_double * res, complex_double x, complex_double y, int flags) .. function:: int arb_fpwrap_double_sqrt(double * res, double x, int flags) int arb_fpwrap_cdouble_sqrt(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_rsqrt(double * res, double x, int flags) int arb_fpwrap_cdouble_rsqrt(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_cbrt(double * res, double x, int flags) int arb_fpwrap_cdouble_cbrt(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_sin(double * res, double x, int flags) int arb_fpwrap_cdouble_sin(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_cos(double * res, double x, int flags) int arb_fpwrap_cdouble_cos(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_tan(double * res, double x, int flags) int arb_fpwrap_cdouble_tan(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_cot(double * res, double x, int flags) int arb_fpwrap_cdouble_cot(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_sec(double * res, double x, int flags) int arb_fpwrap_cdouble_sec(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_csc(double * res, double x, int flags) int arb_fpwrap_cdouble_csc(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_sinc(double * res, double x, int flags) int arb_fpwrap_cdouble_sinc(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_sin_pi(double * res, double x, int flags) int arb_fpwrap_cdouble_sin_pi(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_cos_pi(double * res, double x, int flags) int arb_fpwrap_cdouble_cos_pi(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_tan_pi(double * res, double x, int flags) int arb_fpwrap_cdouble_tan_pi(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_cot_pi(double * res, double x, int flags) int arb_fpwrap_cdouble_cot_pi(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_sinc_pi(double * res, double x, int flags) int arb_fpwrap_cdouble_sinc_pi(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_asin(double * res, double x, int flags) int arb_fpwrap_cdouble_asin(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_acos(double * res, double x, int flags) int arb_fpwrap_cdouble_acos(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_atan(double * res, double x, int flags) int arb_fpwrap_cdouble_atan(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_atan2(double * res, double x1, double x2, int flags) .. function:: int arb_fpwrap_double_asinh(double * res, double x, int flags) int arb_fpwrap_cdouble_asinh(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_acosh(double * res, double x, int flags) int arb_fpwrap_cdouble_acosh(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_atanh(double * res, double x, int flags) int arb_fpwrap_cdouble_atanh(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_lambertw(double * res, double x, slong branch, int flags) int arb_fpwrap_cdouble_lambertw(complex_double * res, complex_double x, slong branch, int flags) Gamma, zeta and related functions ............................................................................... .. function:: int arb_fpwrap_double_rising(double * res, double x, double n, int flags) int arb_fpwrap_cdouble_rising(complex_double * res, complex_double x, complex_double n, int flags) Rising factorial. .. function:: int arb_fpwrap_double_gamma(double * res, double x, int flags) int arb_fpwrap_cdouble_gamma(complex_double * res, complex_double x, int flags) Gamma function. .. function:: int arb_fpwrap_double_rgamma(double * res, double x, int flags) int arb_fpwrap_cdouble_rgamma(complex_double * res, complex_double x, int flags) Reciprocal gamma function. .. function:: int arb_fpwrap_double_lgamma(double * res, double x, int flags) int arb_fpwrap_cdouble_lgamma(complex_double * res, complex_double x, int flags) Log-gamma function. .. function:: int arb_fpwrap_double_digamma(double * res, double x, int flags) int arb_fpwrap_cdouble_digamma(complex_double * res, complex_double x, int flags) Digamma function. .. function:: int arb_fpwrap_double_zeta(double * res, double x, int flags) int arb_fpwrap_cdouble_zeta(complex_double * res, complex_double x, int flags) Riemann zeta function. .. function:: int arb_fpwrap_double_hurwitz_zeta(double * res, double s, double z, int flags) int arb_fpwrap_cdouble_hurwitz_zeta(complex_double * res, complex_double s, complex_double z, int flags) Hurwitz zeta function. .. function:: int arb_fpwrap_double_barnes_g(double * res, double x, int flags) int arb_fpwrap_cdouble_barnes_g(complex_double * res, complex_double x, int flags) Barnes G-function. .. function:: int arb_fpwrap_double_log_barnes_g(double * res, double x, int flags) int arb_fpwrap_cdouble_log_barnes_g(complex_double * res, complex_double x, int flags) Logarithmic Barnes G-function. .. function:: int arb_fpwrap_double_polygamma(double * res, double s, double z, int flags) int arb_fpwrap_cdouble_polygamma(complex_double * res, complex_double s, complex_double z, int flags) Polygamma function. .. function:: int arb_fpwrap_double_polylog(double * res, double s, double z, int flags) int arb_fpwrap_cdouble_polylog(complex_double * res, complex_double s, complex_double z, int flags) Polylogarithm. .. function:: int arb_fpwrap_cdouble_dirichlet_eta(complex_double * res, complex_double s, int flags) .. function:: int arb_fpwrap_cdouble_riemann_xi(complex_double * res, complex_double s, int flags) .. function:: int arb_fpwrap_cdouble_hardy_theta(complex_double * res, complex_double z, int flags) .. function:: int arb_fpwrap_cdouble_hardy_z(complex_double * res, complex_double z, int flags) .. function:: int arb_fpwrap_cdouble_zeta_zero(complex_double * res, ulong n, int flags) Error functions and exponential integrals ............................................................................... .. function:: int arb_fpwrap_double_erf(double * res, double x, int flags) int arb_fpwrap_cdouble_erf(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_erfc(double * res, double x, int flags) int arb_fpwrap_cdouble_erfc(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_erfi(double * res, double x, int flags) int arb_fpwrap_cdouble_erfi(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_erfinv(double * res, double x, int flags) .. function:: int arb_fpwrap_double_erfcinv(double * res, double x, int flags) .. function:: int arb_fpwrap_double_fresnel_s(double * res, double x, int normalized, int flags) int arb_fpwrap_cdouble_fresnel_s(complex_double * res, complex_double x, int normalized, int flags) .. function:: int arb_fpwrap_double_fresnel_c(double * res, double x, int normalized, int flags) int arb_fpwrap_cdouble_fresnel_c(complex_double * res, complex_double x, int normalized, int flags) .. function:: int arb_fpwrap_double_gamma_upper(double * res, double s, double z, int regularized, int flags) int arb_fpwrap_cdouble_gamma_upper(complex_double * res, complex_double s, complex_double z, int regularized, int flags) .. function:: int arb_fpwrap_double_gamma_lower(double * res, double s, double z, int regularized, int flags) int arb_fpwrap_cdouble_gamma_lower(complex_double * res, complex_double s, complex_double z, int regularized, int flags) .. function:: int arb_fpwrap_double_beta_lower(double * res, double a, double b, double z, int regularized, int flags) int arb_fpwrap_cdouble_beta_lower(complex_double * res, complex_double a, complex_double b, complex_double z, int regularized, int flags) .. function:: int arb_fpwrap_double_exp_integral_e(double * res, double s, double z, int flags) int arb_fpwrap_cdouble_exp_integral_e(complex_double * res, complex_double s, complex_double z, int flags) .. function:: int arb_fpwrap_double_exp_integral_ei(double * res, double x, int flags) int arb_fpwrap_cdouble_exp_integral_ei(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_sin_integral(double * res, double x, int flags) int arb_fpwrap_cdouble_sin_integral(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_cos_integral(double * res, double x, int flags) int arb_fpwrap_cdouble_cos_integral(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_sinh_integral(double * res, double x, int flags) int arb_fpwrap_cdouble_sinh_integral(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_cosh_integral(double * res, double x, int flags) int arb_fpwrap_cdouble_cosh_integral(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_log_integral(double * res, double x, int offset, int flags) int arb_fpwrap_cdouble_log_integral(complex_double * res, complex_double x, int offset, int flags) Bessel, Airy and Coulomb functions ............................................................................... .. function:: int arb_fpwrap_double_bessel_j(double * res, double nu, double x, int flags) int arb_fpwrap_cdouble_bessel_j(complex_double * res, complex_double nu, complex_double x, int flags) .. function:: int arb_fpwrap_double_bessel_y(double * res, double nu, double x, int flags) int arb_fpwrap_cdouble_bessel_y(complex_double * res, complex_double nu, complex_double x, int flags) .. function:: int arb_fpwrap_double_bessel_i(double * res, double nu, double x, int flags) int arb_fpwrap_cdouble_bessel_i(complex_double * res, complex_double nu, complex_double x, int flags) .. function:: int arb_fpwrap_double_bessel_k(double * res, double nu, double x, int flags) int arb_fpwrap_cdouble_bessel_k(complex_double * res, complex_double nu, complex_double x, int flags) .. function:: int arb_fpwrap_double_bessel_k_scaled(double * res, double nu, double x, int flags) int arb_fpwrap_cdouble_bessel_k_scaled(complex_double * res, complex_double nu, complex_double x, int flags) .. function:: int arb_fpwrap_double_airy_ai(double * res, double x, int flags) int arb_fpwrap_cdouble_airy_ai(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_airy_ai_prime(double * res, double x, int flags) int arb_fpwrap_cdouble_airy_ai_prime(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_airy_bi(double * res, double x, int flags) int arb_fpwrap_cdouble_airy_bi(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_airy_bi_prime(double * res, double x, int flags) int arb_fpwrap_cdouble_airy_bi_prime(complex_double * res, complex_double x, int flags) .. function:: int arb_fpwrap_double_airy_ai_zero(double * res, ulong n, int flags) .. function:: int arb_fpwrap_double_airy_ai_prime_zero(double * res, ulong n, int flags) .. function:: int arb_fpwrap_double_airy_bi_zero(double * res, ulong n, int flags) .. function:: int arb_fpwrap_double_airy_bi_prime_zero(double * res, ulong n, int flags) .. function:: int arb_fpwrap_double_coulomb_f(double * res, double l, double eta, double x, int flags) int arb_fpwrap_cdouble_coulomb_f(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags) .. function:: int arb_fpwrap_double_coulomb_g(double * res, double l, double eta, double x, int flags) int arb_fpwrap_cdouble_coulomb_g(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags) .. function:: int arb_fpwrap_cdouble_coulomb_hpos(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags) int arb_fpwrap_cdouble_coulomb_hneg(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags) Orthogonal polynomials ............................................................................... .. function:: int arb_fpwrap_double_chebyshev_t(double * res, double n, double x, int flags) int arb_fpwrap_cdouble_chebyshev_t(complex_double * res, complex_double n, complex_double x, int flags) .. function:: int arb_fpwrap_double_chebyshev_u(double * res, double n, double x, int flags) int arb_fpwrap_cdouble_chebyshev_u(complex_double * res, complex_double n, complex_double x, int flags) .. function:: int arb_fpwrap_double_jacobi_p(double * res, double n, double a, double b, double x, int flags) int arb_fpwrap_cdouble_jacobi_p(complex_double * res, complex_double n, complex_double a, complex_double b, complex_double x, int flags) .. function:: int arb_fpwrap_double_gegenbauer_c(double * res, double n, double m, double x, int flags) int arb_fpwrap_cdouble_gegenbauer_c(complex_double * res, complex_double n, complex_double m, complex_double x, int flags) .. function:: int arb_fpwrap_double_laguerre_l(double * res, double n, double m, double x, int flags) int arb_fpwrap_cdouble_laguerre_l(complex_double * res, complex_double n, complex_double m, complex_double x, int flags) .. function:: int arb_fpwrap_double_hermite_h(double * res, double n, double x, int flags) int arb_fpwrap_cdouble_hermite_h(complex_double * res, complex_double n, complex_double x, int flags) .. function:: int arb_fpwrap_double_legendre_p(double * res, double n, double m, double x, int type, int flags) int arb_fpwrap_cdouble_legendre_p(complex_double * res, complex_double n, complex_double m, complex_double x, int type, int flags) .. function:: int arb_fpwrap_double_legendre_q(double * res, double n, double m, double x, int type, int flags) int arb_fpwrap_cdouble_legendre_q(complex_double * res, complex_double n, complex_double m, complex_double x, int type, int flags) .. function:: int arb_fpwrap_double_legendre_root(double * res1, double * res2, ulong n, ulong k, int flags) Sets *res1* to the index *k* root of the Legendre polynomial `P_n(x)`, and simultaneously sets *res2* to the corresponding weight for Gauss-Legendre quadrature. .. function:: int arb_fpwrap_cdouble_spherical_y(complex_double * res, slong n, slong m, complex_double x1, complex_double x2, int flags) Hypergeometric functions ............................................................................... .. function:: int arb_fpwrap_double_hypgeom_0f1(double * res, double a, double x, int regularized, int flags) int arb_fpwrap_cdouble_hypgeom_0f1(complex_double * res, complex_double a, complex_double x, int regularized, int flags) .. function:: int arb_fpwrap_double_hypgeom_1f1(double * res, double a, double b, double x, int regularized, int flags) int arb_fpwrap_cdouble_hypgeom_1f1(complex_double * res, complex_double a, complex_double b, complex_double x, int regularized, int flags) .. function:: int arb_fpwrap_double_hypgeom_u(double * res, double a, double b, double x, int flags) int arb_fpwrap_cdouble_hypgeom_u(complex_double * res, complex_double a, complex_double b, complex_double x, int flags) .. function:: int arb_fpwrap_double_hypgeom_2f1(double * res, double a, double b, double c, double x, int regularized, int flags) int arb_fpwrap_cdouble_hypgeom_2f1(complex_double * res, complex_double a, complex_double b, complex_double c, complex_double x, int regularized, int flags) .. function:: int arb_fpwrap_double_hypgeom_pfq(double * res, const double * a, slong p, const double * b, slong q, double z, int regularized, int flags) int arb_fpwrap_cdouble_hypgeom_pfq(complex_double * res, const complex_double * a, slong p, const complex_double * b, slong q, complex_double z, int regularized, int flags) Elliptic integrals, elliptic functions and modular forms ............................................................................... .. function:: int arb_fpwrap_double_agm(double * res, double x, double y, int flags) int arb_fpwrap_cdouble_agm(complex_double * res, complex_double x, complex_double y, int flags) Arithmetic-geometric mean. .. function:: int arb_fpwrap_cdouble_elliptic_k(complex_double * res, complex_double m, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_e(complex_double * res, complex_double m, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_pi(complex_double * res, complex_double n, complex_double m, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_f(complex_double * res, complex_double phi, complex_double m, int pi, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_e_inc(complex_double * res, complex_double phi, complex_double m, int pi, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_pi_inc(complex_double * res, complex_double n, complex_double phi, complex_double m, int pi, int flags) Complete and incomplete elliptic integrals. .. function:: int arb_fpwrap_cdouble_elliptic_rf(complex_double * res, complex_double x, complex_double y, complex_double z, int option, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_rg(complex_double * res, complex_double x, complex_double y, complex_double z, int option, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_rj(complex_double * res, complex_double x, complex_double y, complex_double z, complex_double w, int option, int flags) Carlson symmetric elliptic integrals. .. function:: int arb_fpwrap_cdouble_elliptic_p(complex_double * res, complex_double z, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_p_prime(complex_double * res, complex_double z, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_inv_p(complex_double * res, complex_double z, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_zeta(complex_double * res, complex_double z, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_elliptic_sigma(complex_double * res, complex_double z, complex_double tau, int flags) Weierstrass elliptic functions. .. function:: int arb_fpwrap_cdouble_jacobi_theta_1(complex_double * res, complex_double z, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_jacobi_theta_2(complex_double * res, complex_double z, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_jacobi_theta_3(complex_double * res, complex_double z, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_jacobi_theta_4(complex_double * res, complex_double z, complex_double tau, int flags) Jacobi theta functions. .. function:: int arb_fpwrap_cdouble_dedekind_eta(complex_double * res, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_modular_j(complex_double * res, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_modular_lambda(complex_double * res, complex_double tau, int flags) .. function:: int arb_fpwrap_cdouble_modular_delta(complex_double * res, complex_double tau, int flags) Calling from C ------------------------------------------------------------------------------- The program ``examples/fpwrap.c`` provides a usage example:: #include "arb_fpwrap.h" int main() { double x, y; complex_double cx, cy; int flags = 0; /* default options */ x = 2.0; cx.real = 0.5; cx.imag = 123.0; arb_fpwrap_double_zeta(&y, x, flags); arb_fpwrap_cdouble_zeta(&cy, cx, flags); printf("zeta(%g) = %.16g\n", x, y); printf("zeta(%g + %gi) = %.16g + %.16gi\n", cx.real, cx.imag, cy.real, cy.imag); flint_cleanup(); return 0; } .. highlight:: text This should print:: > build/examples/fpwrap zeta(2) = 1.644934066848226 zeta(0.5 + 123i) = 0.006252861175594465 + 0.08206030514520983i Note that this program does not check the return flag to perform error handling. Interfacing from Python ------------------------------------------------------------------------------- .. highlight:: python This illustrates how to call functions from Python using ``ctypes``:: import ctypes import ctypes.util libarb_path = ctypes.util.find_library('arb') libarb = ctypes.CDLL(libarb_path) class _complex_double(ctypes.Structure): _fields_ = [('real', ctypes.c_double), ('imag', ctypes.c_double)] def wrap_double_fun(fun): def f(x): y = ctypes.c_double() if fun(ctypes.byref(y), ctypes.c_double(x), 0): raise ValueError(f"unable to evaluate function accurately at {x}") return y.value return f def wrap_cdouble_fun(fun): def f(x): x = complex(x) cx = _complex_double() cy = _complex_double() cx.real = x.real cx.imag = x.imag if fun(ctypes.byref(cy), cx, 0): raise ValueError(f"unable to evaluate function accurately at {x}") return complex(cy.real, cy.imag) return f zeta = wrap_double_fun(libarb.arb_fpwrap_double_zeta) czeta = wrap_cdouble_fun(libarb.arb_fpwrap_cdouble_zeta) print(zeta(2.0)) print(czeta(0.5+1e9j)) print(zeta(1.0)) # pole, where wrapper throws exception .. highlight:: text This should print:: 1.6449340668482264 (-2.761748029838061-1.6775122409894598j) Traceback (most recent call last): ... ValueError: unable to evaluate function accurately at 1.0 Interfacing from Julia ------------------------------------------------------------------------------- .. highlight:: julia This illustrates how to call functions from Julia using ``ccall``:: using Libdl dlopen("/home/fredrik/src/arb/libarb.so") function zeta(x::Float64) cy = Ref{Float64}() if Bool(ccall((:arb_fpwrap_double_zeta, :libarb), Cint, (Ptr{Float64}, Float64, Cint), cy, x, 0)) error("unable to evaluate accurately at ", x) end return cy[] end function zeta(x::Complex{Float64}) cy = Ref{Complex{Float64}}() if Bool(ccall((:arb_fpwrap_cdouble_zeta, :libarb), Cint, (Ptr{Complex{Float64}}, Complex{Float64}, Cint), cy, x, 0)) error("unable to evaluate accurately at ", x) end return cy[] end println(zeta(2.0)) println(zeta(0.5 + 1e9im)) println(zeta(1.0)) # pole, where wrapper throws exception .. highlight:: text This should print:: 1.6449340668482264 -2.761748029838061 - 1.6775122409894598im ERROR: unable to evaluate accurately at 1.0 Stacktrace: ... .. highlight:: c arb-2.22.1/doc/source/arb_hypgeom.rst000066400000000000000000001044331417376376500174650ustar00rootroot00000000000000.. _arb-hypgeom: **arb_hypgeom.h** -- hypergeometric functions of real variables ================================================================================== See :ref:`acb-hypgeom` for the general implementation of hypergeometric functions. For convenience, this module provides versions of the same functions for real variables represented using :type:`arb_t` and :type:`arb_poly_t`. Most methods are simple wrappers around the complex versions, but some of the functions in this module have been further optimized specifically for real variables. This module also provides certain functions exclusive to real variables, such as functions for computing real roots of common special functions. Rising factorials ------------------------------------------------------------------------------- .. function:: void _arb_hypgeom_rising_coeffs_1(ulong * c, ulong k, slong n) void _arb_hypgeom_rising_coeffs_2(ulong * c, ulong k, slong n) void _arb_hypgeom_rising_coeffs_fmpz(fmpz * c, ulong k, slong n) Sets *c* to the coefficients of the rising factorial polynomial `(X+k)_n`. The *1* and *2* versions respectively compute single-word and double-word coefficients, without checking for overflow, while the *fmpz* version allows arbitrarily large coefficients. These functions are mostly intended for internal use; the *fmpz* version does not use an asymptotically fast algorithm. The degree *n* must be at least 2. .. function:: void arb_hypgeom_rising_ui_forward(arb_t res, const arb_t x, ulong n, slong prec) void arb_hypgeom_rising_ui_bs(arb_t res, const arb_t x, ulong n, slong prec) void arb_hypgeom_rising_ui_rs(arb_t res, const arb_t x, ulong n, ulong m, slong prec) void arb_hypgeom_rising_ui_rec(arb_t res, const arb_t x, ulong n, slong prec) void arb_hypgeom_rising_ui(arb_t res, const arb_t x, ulong n, slong prec) void arb_hypgeom_rising(arb_t res, const arb_t x, const arb_t n, slong prec) Computes the rising factorial `(x)_n`. The *forward* version uses the forward recurrence. The *bs* version uses binary splitting. The *rs* version uses rectangular splitting. It takes an extra tuning parameter *m* which can be set to zero to choose automatically. The *rec* version chooses an algorithm automatically, avoiding use of the gamma function (so that it can be used in the computation of the gamma function). The default versions (*rising_ui* and *rising_ui*) choose an algorithm automatically and may additionally fall back on the gamma function. .. function:: void arb_hypgeom_rising_ui_jet_powsum(arb_ptr res, const arb_t x, ulong n, slong len, slong prec) void arb_hypgeom_rising_ui_jet_bs(arb_ptr res, const arb_t x, ulong n, slong len, slong prec) void arb_hypgeom_rising_ui_jet_rs(arb_ptr res, const arb_t x, ulong n, ulong m, slong len, slong prec) void arb_hypgeom_rising_ui_jet(arb_ptr res, const arb_t x, ulong n, slong len, slong prec) Computes the jet of the rising factorial `(x)_n`, truncated to length *len*. In other words, constructs the polynomial `(X + x)_n \in \mathbb{R}[X]`, truncated if `\operatorname{len} < n + 1` (and zero-extended if `\operatorname{len} > n + 1`). The *powsum* version computes the sequence of powers of *x* and forms integral linear combinations of these. The *bs* version uses binary splitting. The *rs* version uses rectangular splitting. It takes an extra tuning parameter *m* which can be set to zero to choose automatically. The default version chooses an algorithm automatically. Gamma function ------------------------------------------------------------------------------- .. function:: void _arb_hypgeom_gamma_stirling_term_bounds(slong * bound, const mag_t zinv, slong N) For `1 \le n < N`, sets *bound* to an exponent bounding the *n*-th term in the Stirling series for the gamma function, given a precomputed upper bound for `|z|^{-1}`. This function is intended for internal use and does not check for underflow or underflow in the exponents. .. function:: void arb_hypgeom_gamma_stirling_sum_horner(arb_t res, const arb_t z, slong N, slong prec) void arb_hypgeom_gamma_stirling_sum_improved(arb_t res, const arb_t z, slong N, slong K, slong prec) Sets *res* to the final sum in the Stirling series for the gamma function truncated before the term with index *N*, i.e. computes `\sum_{n=1}^{N-1} B_{2n} / (2n(2n-1) z^{2n-1})`. The *horner* version uses Horner scheme with gradual precision adjustments. The *improved* version uses rectangular splitting for the low-index terms and reexpands the high-index terms as hypergeometric polynomials, using a splitting parameter *K* (which can be set to 0 to use a default value). .. function:: void arb_hypgeom_gamma_stirling(arb_t res, const arb_t x, int reciprocal, slong prec) Sets *res* to the gamma function of *x* computed using the Stirling series together with argument reduction. If *reciprocal* is set, the reciprocal gamma function is computed instead. .. function:: int arb_hypgeom_gamma_taylor(arb_t res, const arb_t x, int reciprocal, slong prec) Attempts to compute the gamma function of *x* using Taylor series together with argument reduction. This is only supported if *x* and *prec* are both small enough. If successful, returns 1; otherwise, does nothing and returns 0. If *reciprocal* is set, the reciprocal gamma function is computed instead. .. function:: void arb_hypgeom_gamma(arb_t res, const arb_t x, slong prec) void arb_hypgeom_gamma_fmpq(arb_t res, const fmpq_t x, slong prec) void arb_hypgeom_gamma_fmpz(arb_t res, const fmpz_t x, slong prec) Sets *res* to the gamma function of *x* computed using a default algorithm choice. .. function:: void arb_hypgeom_rgamma(arb_t res, const arb_t x, slong prec) Sets *res* to the reciprocal gamma function of *x* computed using a default algorithm choice. .. function:: void arb_hypgeom_lgamma(arb_t res, const arb_t x, slong prec) Sets *res* to the log-gamma function of *x* computed using a default algorithm choice. Binomial coefficients ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_central_bin_ui(arb_t res, ulong n, slong prec) Computes the central binomial coefficient `{2n \choose n}`. Generalized hypergeometric function ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_pfq(arb_t res, arb_srcptr a, slong p, arb_srcptr b, slong q, const arb_t z, int regularized, slong prec) Computes the generalized hypergeometric function `{}_pF_{q}(z)`, or the regularized version if *regularized* is set. Confluent hypergeometric functions ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_0f1(arb_t res, const arb_t a, const arb_t z, int regularized, slong prec) Computes the confluent hypergeometric limit function `{}_0F_1(a,z)`, or `\frac{1}{\Gamma(a)} {}_0F_1(a,z)` if *regularized* is set. .. function:: void arb_hypgeom_m(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) Computes the confluent hypergeometric function `M(a,b,z) = {}_1F_1(a,b,z)`, or `\mathbf{M}(a,b,z) = \frac{1}{\Gamma(b)} {}_1F_1(a,b,z)` if *regularized* is set. .. function:: void arb_hypgeom_1f1(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) Alias for :func:`arb_hypgeom_m`. .. function:: void arb_hypgeom_1f1_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) Computes the confluent hypergeometric function using numerical integration of the representation .. math :: {}_1F_1(a,b,z) = \frac{\Gamma(b)}{\Gamma(a) \Gamma(b-a)} \int_0^1 e^{zt} t^{a-1} (1-t)^{b-a-1} dt. This algorithm can be useful if the parameters are large. This will currently only return a finite enclosure if `a \ge 1` and `b - a \ge 1`. .. function:: void arb_hypgeom_u(arb_t res, const arb_t a, const arb_t b, const arb_t z, slong prec) Computes the confluent hypergeometric function `U(a,b,z)`. .. function:: void arb_hypgeom_u_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) Computes the confluent hypergeometric function `U(a,b,z)` using numerical integration of the representation .. math :: U(a,b,z) = \frac{1}{\Gamma(a)} \int_0^{\infty} e^{-zt} t^{a-1} (1+t)^{b-a-1} dt. This algorithm can be useful if the parameters are large. This will currently only return a finite enclosure if `a \ge 1` and `z > 0`. Gauss hypergeometric function ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_2f1(arb_t res, const arb_t a, const arb_t b, const arb_t c, const arb_t z, int regularized, slong prec) Computes the Gauss hypergeometric function `{}_2F_1(a,b,c,z)`, or `\mathbf{F}(a,b,c,z) = \frac{1}{\Gamma(c)} {}_2F_1(a,b,c,z)` if *regularized* is set. Additional evaluation flags can be passed via the *regularized* argument; see :func:`acb_hypgeom_2f1` for documentation. .. function:: void arb_hypgeom_2f1_integration(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) Computes the Gauss hypergeometric function using numerical integration of the representation .. math :: {}_2F_1(a,b,c,z) = \frac{\Gamma(a)}{\Gamma(b) \Gamma(c-b)} \int_0^1 t^{b-1} (1-t)^{c-b-1} (1-zt)^{-a} dt. This algorithm can be useful if the parameters are large. This will currently only return a finite enclosure if `b \ge 1` and `c - b \ge 1` and `z < 1`, possibly with *a* and *b* exchanged. Error functions and Fresnel integrals ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_erf(arb_t res, const arb_t z, slong prec) Computes the error function `\operatorname{erf}(z)`. .. function:: void _arb_hypgeom_erf_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_erf_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the error function of the power series *z*, truncated to length *len*. .. function:: void arb_hypgeom_erfc(arb_t res, const arb_t z, slong prec) Computes the complementary error function `\operatorname{erfc}(z) = 1 - \operatorname{erf}(z)`. This function avoids catastrophic cancellation for large positive *z*. .. function:: void _arb_hypgeom_erfc_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_erfc_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the complementary error function of the power series *z*, truncated to length *len*. .. function:: void arb_hypgeom_erfi(arb_t res, const arb_t z, slong prec) Computes the imaginary error function `\operatorname{erfi}(z) = -i\operatorname{erf}(iz)`. .. function:: void _arb_hypgeom_erfi_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_erfi_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the imaginary error function of the power series *z*, truncated to length *len*. .. function:: void arb_hypgeom_erfinv(arb_t res, const arb_t z, slong prec) void arb_hypgeom_erfcinv(arb_t res, const arb_t z, slong prec) Computes the inverse error function `\operatorname{erf}^{-1}(z)` or inverse complementary error function `\operatorname{erfc}^{-1}(z)`. .. function:: void arb_hypgeom_fresnel(arb_t res1, arb_t res2, const arb_t z, int normalized, slong prec) Sets *res1* to the Fresnel sine integral `S(z)` and *res2* to the Fresnel cosine integral `C(z)`. Optionally, just a single function can be computed by passing *NULL* as the other output variable. The definition `S(z) = \int_0^z \sin(t^2) dt` is used if *normalized* is 0, and `S(z) = \int_0^z \sin(\tfrac{1}{2} \pi t^2) dt` is used if *normalized* is 1 (the latter is the Abramowitz & Stegun convention). `C(z)` is defined analogously. .. function:: void _arb_hypgeom_fresnel_series(arb_ptr res1, arb_ptr res2, arb_srcptr z, slong zlen, int normalized, slong len, slong prec) void arb_hypgeom_fresnel_series(arb_poly_t res1, arb_poly_t res2, const arb_poly_t z, int normalized, slong len, slong prec) Sets *res1* to the Fresnel sine integral and *res2* to the Fresnel cosine integral of the power series *z*, truncated to length *len*. Optionally, just a single function can be computed by passing *NULL* as the other output variable. Incomplete gamma and beta functions ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_gamma_upper(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec) If *regularized* is 0, computes the upper incomplete gamma function `\Gamma(s,z)`. If *regularized* is 1, computes the regularized upper incomplete gamma function `Q(s,z) = \Gamma(s,z) / \Gamma(s)`. If *regularized* is 2, computes the generalized exponential integral `z^{-s} \Gamma(s,z) = E_{1-s}(z)` instead (this option is mainly intended for internal use; :func:`arb_hypgeom_expint` is the intended interface for computing the exponential integral). .. function:: void arb_hypgeom_gamma_upper_integration(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec) Computes the upper incomplete gamma function using numerical integration. .. function:: void _arb_hypgeom_gamma_upper_series(arb_ptr res, const arb_t s, arb_srcptr z, slong zlen, int regularized, slong n, slong prec) void arb_hypgeom_gamma_upper_series(arb_poly_t res, const arb_t s, const arb_poly_t z, int regularized, slong n, slong prec) Sets *res* to an upper incomplete gamma function where *s* is a constant and *z* is a power series, truncated to length *n*. The *regularized* argument has the same interpretation as in :func:`arb_hypgeom_gamma_upper`. .. function:: void arb_hypgeom_gamma_lower(arb_t res, const arb_t s, const arb_t z, int regularized, slong prec) If *regularized* is 0, computes the lower incomplete gamma function `\gamma(s,z) = \frac{z^s}{s} {}_1F_1(s, s+1, -z)`. If *regularized* is 1, computes the regularized lower incomplete gamma function `P(s,z) = \gamma(s,z) / \Gamma(s)`. If *regularized* is 2, computes a further regularized lower incomplete gamma function `\gamma^{*}(s,z) = z^{-s} P(s,z)`. .. function:: void _arb_hypgeom_gamma_lower_series(arb_ptr res, const arb_t s, arb_srcptr z, slong zlen, int regularized, slong n, slong prec) void arb_hypgeom_gamma_lower_series(arb_poly_t res, const arb_t s, const arb_poly_t z, int regularized, slong n, slong prec) Sets *res* to an lower incomplete gamma function where *s* is a constant and *z* is a power series, truncated to length *n*. The *regularized* argument has the same interpretation as in :func:`arb_hypgeom_gamma_lower`. .. function:: void arb_hypgeom_beta_lower(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) Computes the (lower) incomplete beta function, defined by `B(a,b;z) = \int_0^z t^{a-1} (1-t)^{b-1}`, optionally the regularized incomplete beta function `I(a,b;z) = B(a,b;z) / B(a,b;1)`. .. function:: void _arb_hypgeom_beta_lower_series(arb_ptr res, const arb_t a, const arb_t b, arb_srcptr z, slong zlen, int regularized, slong n, slong prec) void arb_hypgeom_beta_lower_series(arb_poly_t res, const arb_t a, const arb_t b, const arb_poly_t z, int regularized, slong n, slong prec) Sets *res* to the lower incomplete beta function `B(a,b;z)` (optionally the regularized version `I(a,b;z)`) where *a* and *b* are constants and *z* is a power series, truncating the result to length *n*. The underscore method requires positive lengths and does not support aliasing. Internal evaluation functions ................................................................................ .. function:: void _arb_hypgeom_gamma_lower_sum_rs_1(arb_t res, ulong p, ulong q, const arb_t z, slong N, slong prec) Computes `\sum_{k=0}^{N-1} z^k / (a)_k` where `a = p/q` using rectangular splitting. It is assumed that `p + qN` fits in a limb. .. function:: void _arb_hypgeom_gamma_upper_sum_rs_1(arb_t res, ulong p, ulong q, const arb_t z, slong N, slong prec) Computes `\sum_{k=0}^{N-1} (a)_k / z^k` where `a = p/q` using rectangular splitting. It is assumed that `p + qN` fits in a limb. .. function:: slong _arb_hypgeom_gamma_upper_fmpq_inf_choose_N(mag_t err, const fmpq_t a, const arb_t z, const mag_t abs_tol) Returns number of terms *N* and sets *err* to the truncation error for evaluating `\Gamma(a,z)` using the asymptotic series at infinity, targeting an absolute tolerance of *abs_tol*. The error may be set to *err* if the tolerance cannot be achieved. Assumes that *z* is positive. .. function:: void _arb_hypgeom_gamma_upper_fmpq_inf_bsplit(arb_t res, const fmpq_t a, const arb_t z, slong N, slong prec) Sets *res* to the approximation of `\Gamma(a,z)` obtained by truncating the asymptotic series at infinity before term *N*. The truncation error bound has to be added separately. .. function:: slong _arb_hypgeom_gamma_lower_fmpq_0_choose_N(mag_t err, const fmpq_t a, const arb_t z, const mag_t abs_tol) Returns number of terms *N* and sets *err* to the truncation error for evaluating `\gamma(a,z)` using the Taylor series at zero, targeting an absolute tolerance of *abs_tol*. Assumes that *z* is positive. .. function:: void _arb_hypgeom_gamma_lower_fmpq_0_bsplit(arb_t res, const fmpq_t a, const arb_t z, slong N, slong prec) Sets *res* to the approximation of `\gamma(a,z)` obtained by truncating the Taylor series at zero before term *N*. The truncation error bound has to be added separately. .. function:: slong _arb_hypgeom_gamma_upper_singular_si_choose_N(mag_t err, slong n, const arb_t z, const mag_t abs_tol) Returns number of terms *N* and sets *err* to the truncation error for evaluating `\Gamma(-n,z)` using the Taylor series at zero, targeting an absolute tolerance of *abs_tol*. .. function:: void _arb_hypgeom_gamma_upper_singular_si_bsplit(arb_t res, slong n, const arb_t z, slong N, slong prec) Sets *res* to the approximation of `\Gamma(-n,z)` obtained by truncating the Taylor series at zero before term *N*. The truncation error bound has to be added separately. .. function:: void _arb_gamma_upper_fmpq_step_bsplit(arb_t Gz1, const fmpq_t a, const arb_t z0, const arb_t z1, const arb_t Gz0, const arb_t expmz0, const mag_t abs_tol, slong prec) Given *Gz0* and *expmz0* representing the values `\Gamma(a,z_0)` and `\exp(-z_0)`, computes `\Gamma(a,z_1)` using the Taylor series at `z_0` evaluated using binary splitting, targeting an absolute error of *abs_tol*. Assumes that `z_0` and `z_1` are positive. Exponential and trigonometric integrals ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_expint(arb_t res, const arb_t s, const arb_t z, slong prec) Computes the generalized exponential integral `E_s(z)`. .. function:: void arb_hypgeom_ei(arb_t res, const arb_t z, slong prec) Computes the exponential integral `\operatorname{Ei}(z)`. .. function:: void _arb_hypgeom_ei_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_ei_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the exponential integral of the power series *z*, truncated to length *len*. .. function:: void _arb_hypgeom_si_asymp(arb_t res, const arb_t z, slong N, slong prec) void _arb_hypgeom_si_1f2(arb_t res, const arb_t z, slong N, slong wp, slong prec) void arb_hypgeom_si(arb_t res, const arb_t z, slong prec) Computes the sine integral `\operatorname{Si}(z)`. .. function:: void _arb_hypgeom_si_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_si_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the sine integral of the power series *z*, truncated to length *len*. .. function:: void _arb_hypgeom_ci_asymp(arb_t res, const arb_t z, slong N, slong prec) void _arb_hypgeom_ci_2f3(arb_t res, const arb_t z, slong N, slong wp, slong prec) void arb_hypgeom_ci(arb_t res, const arb_t z, slong prec) Computes the cosine integral `\operatorname{Ci}(z)`. The result is indeterminate if `z < 0` since the value of the function would be complex. .. function:: void _arb_hypgeom_ci_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_ci_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the cosine integral of the power series *z*, truncated to length *len*. .. function:: void arb_hypgeom_shi(arb_t res, const arb_t z, slong prec) Computes the hyperbolic sine integral `\operatorname{Shi}(z) = -i \operatorname{Si}(iz)`. .. function:: void _arb_hypgeom_shi_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_shi_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the hyperbolic sine integral of the power series *z*, truncated to length *len*. .. function:: void arb_hypgeom_chi(arb_t res, const arb_t z, slong prec) Computes the hyperbolic cosine integral `\operatorname{Chi}(z)`. The result is indeterminate if `z < 0` since the value of the function would be complex. .. function:: void _arb_hypgeom_chi_series(arb_ptr res, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_chi_series(arb_poly_t res, const arb_poly_t z, slong len, slong prec) Computes the hyperbolic cosine integral of the power series *z*, truncated to length *len*. .. function:: void arb_hypgeom_li(arb_t res, const arb_t z, int offset, slong prec) If *offset* is zero, computes the logarithmic integral `\operatorname{li}(z) = \operatorname{Ei}(\log(z))`. If *offset* is nonzero, computes the offset logarithmic integral `\operatorname{Li}(z) = \operatorname{li}(z) - \operatorname{li}(2)`. The result is indeterminate if `z < 0` since the value of the function would be complex. .. function:: void _arb_hypgeom_li_series(arb_ptr res, arb_srcptr z, slong zlen, int offset, slong len, slong prec) void arb_hypgeom_li_series(arb_poly_t res, const arb_poly_t z, int offset, slong len, slong prec) Computes the logarithmic integral (optionally the offset version) of the power series *z*, truncated to length *len*. Bessel functions ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_bessel_j(arb_t res, const arb_t nu, const arb_t z, slong prec) Computes the Bessel function of the first kind `J_{\nu}(z)`. .. function:: void arb_hypgeom_bessel_y(arb_t res, const arb_t nu, const arb_t z, slong prec) Computes the Bessel function of the second kind `Y_{\nu}(z)`. .. function:: void arb_hypgeom_bessel_jy(arb_t res1, arb_t res2, const arb_t nu, const arb_t z, slong prec) Sets *res1* to `J_{\nu}(z)` and *res2* to `Y_{\nu}(z)`, computed simultaneously. .. function:: void arb_hypgeom_bessel_i(arb_t res, const arb_t nu, const arb_t z, slong prec) Computes the modified Bessel function of the first kind `I_{\nu}(z) = z^{\nu} (iz)^{-\nu} J_{\nu}(iz)`. .. function:: void arb_hypgeom_bessel_i_scaled(arb_t res, const arb_t nu, const arb_t z, slong prec) Computes the function `e^{-z} I_{\nu}(z)`. .. function:: void arb_hypgeom_bessel_k(arb_t res, const arb_t nu, const arb_t z, slong prec) Computes the modified Bessel function of the second kind `K_{\nu}(z)`. .. function:: void arb_hypgeom_bessel_k_scaled(arb_t res, const arb_t nu, const arb_t z, slong prec) Computes the function `e^{z} K_{\nu}(z)`. .. function:: void arb_hypgeom_bessel_i_integration(arb_t res, const arb_t nu, const arb_t z, int scaled, slong prec) void arb_hypgeom_bessel_k_integration(arb_t res, const arb_t nu, const arb_t z, int scaled, slong prec) Computes the modified Bessel functions using numerical integration. Airy functions ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_airy(arb_t ai, arb_t ai_prime, arb_t bi, arb_t bi_prime, const arb_t z, slong prec) Computes the Airy functions `(\operatorname{Ai}(z), \operatorname{Ai}'(z), \operatorname{Bi}(z), \operatorname{Bi}'(z))` simultaneously. Any of the four function values can be omitted by passing *NULL* for the unwanted output variables, speeding up the evaluation. .. function:: void arb_hypgeom_airy_jet(arb_ptr ai, arb_ptr bi, const arb_t z, slong len, slong prec) Writes to *ai* and *bi* the respective Taylor expansions of the Airy functions at the point *z*, truncated to length *len*. Either of the outputs can be *NULL* to avoid computing that function. The variable *z* is not allowed to be aliased with the outputs. To simplify the implementation, this method does not compute the series expansions of the primed versions directly; these are easily obtained by computing one extra coefficient and differentiating the output with :func:`_arb_poly_derivative`. .. function:: void _arb_hypgeom_airy_series(arb_ptr ai, arb_ptr ai_prime, arb_ptr bi, arb_ptr bi_prime, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_airy_series(arb_poly_t ai, arb_poly_t ai_prime, arb_poly_t bi, arb_poly_t bi_prime, const arb_poly_t z, slong len, slong prec) Computes the Airy functions evaluated at the power series *z*, truncated to length *len*. As with the other Airy methods, any of the outputs can be *NULL*. .. function:: void arb_hypgeom_airy_zero(arb_t a, arb_t a_prime, arb_t b, arb_t b_prime, const fmpz_t n, slong prec) Computes the *n*-th real zero `a_n`, `a'_n`, `b_n`, or `b'_n` for the respective Airy function or Airy function derivative. Any combination of the four output variables can be *NULL*. The zeros are indexed by increasing magnitude, starting with `n = 1` to follow the convention in the literature. An index *n* that is not positive is invalid input. The implementation uses asymptotic expansions for the zeros [PS1991]_ together with the interval Newton method for refinement. Coulomb wave functions ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_coulomb(arb_t F, arb_t G, const arb_t l, const arb_t eta, const arb_t z, slong prec) Writes to *F*, *G* the values of the respective Coulomb wave functions `F_{\ell}(\eta,z)` and `G_{\ell}(\eta,z)`. Either of the outputs can be *NULL*. .. function:: void arb_hypgeom_coulomb_jet(arb_ptr F, arb_ptr G, const arb_t l, const arb_t eta, const arb_t z, slong len, slong prec) Writes to *F*, *G* the respective Taylor expansions of the Coulomb wave functions at the point *z*, truncated to length *len*. Either of the outputs can be *NULL*. .. function:: void _arb_hypgeom_coulomb_series(arb_ptr F, arb_ptr G, const arb_t l, const arb_t eta, arb_srcptr z, slong zlen, slong len, slong prec) void arb_hypgeom_coulomb_series(arb_poly_t F, arb_poly_t G, const arb_t l, const arb_t eta, const arb_poly_t z, slong len, slong prec) Computes the Coulomb wave functions evaluated at the power series *z*, truncated to length *len*. Either of the outputs can be *NULL*. Orthogonal polynomials and functions ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_chebyshev_t(arb_t res, const arb_t nu, const arb_t z, slong prec) void arb_hypgeom_chebyshev_u(arb_t res, const arb_t nu, const arb_t z, slong prec) void arb_hypgeom_jacobi_p(arb_t res, const arb_t n, const arb_t a, const arb_t b, const arb_t z, slong prec) void arb_hypgeom_gegenbauer_c(arb_t res, const arb_t n, const arb_t m, const arb_t z, slong prec) void arb_hypgeom_laguerre_l(arb_t res, const arb_t n, const arb_t m, const arb_t z, slong prec) void arb_hypgeom_hermite_h(arb_t res, const arb_t nu, const arb_t z, slong prec) Computes Chebyshev, Jacobi, Gegenbauer, Laguerre or Hermite polynomials, or their extensions to non-integer orders. .. function:: void arb_hypgeom_legendre_p(arb_t res, const arb_t n, const arb_t m, const arb_t z, int type, slong prec) void arb_hypgeom_legendre_q(arb_t res, const arb_t n, const arb_t m, const arb_t z, int type, slong prec) Computes Legendre functions of the first and second kind. See :func:`acb_hypgeom_legendre_p` and :func:`acb_hypgeom_legendre_q` for definitions. .. function:: void arb_hypgeom_legendre_p_ui_deriv_bound(mag_t dp, mag_t dp2, ulong n, const arb_t x, const arb_t x2sub1) Sets *dp* to an upper bound for `P'_n(x)` and *dp2* to an upper bound for `P''_n(x)` given *x* assumed to represent a real number with `|x| \le 1`. The variable *x2sub1* must contain the precomputed value `1-x^2` (or `x^2-1`). This method is used internally to bound the propagated error for Legendre polynomials. .. function:: void arb_hypgeom_legendre_p_ui_zero(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong K, slong prec) void arb_hypgeom_legendre_p_ui_one(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong K, slong prec) void arb_hypgeom_legendre_p_ui_asymp(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong K, slong prec) void arb_hypgeom_legendre_p_rec(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong prec) void arb_hypgeom_legendre_p_ui(arb_t res, arb_t res_prime, ulong n, const arb_t x, slong prec) Evaluates the ordinary Legendre polynomial `P_n(x)`. If *res_prime* is non-NULL, simultaneously evaluates the derivative `P'_n(x)`. The overall algorithm is described in [JM2018]_. The versions *zero*, *one* respectively use the hypergeometric series expansions at `x = 0` and `x = 1` while the *asymp* version uses an asymptotic series on `(-1,1)` intended for large *n*. The parameter *K* specifies the exact number of expansion terms to use (if the series expansion truncated at this point does not give the exact polynomial, an error bound is computed automatically). The asymptotic expansion with error bounds is given in [Bog2012]_. The *rec* version uses the forward recurrence implemented using fixed-point arithmetic; it is only intended for the interval `(-1,1)`, moderate *n* and modest precision. The default version attempts to choose the best algorithm automatically. It also estimates the amount of cancellation in the hypergeometric series and increases the working precision to compensate, bounding the propagated error using derivative bounds. .. function:: void arb_hypgeom_legendre_p_ui_root(arb_t res, arb_t weight, ulong n, ulong k, slong prec) Sets *res* to the *k*-th root of the Legendre polynomial `P_n(x)`. We index the roots in decreasing order .. math :: 1 > x_0 > x_1 > \ldots > x_{n-1} > -1 (which corresponds to ordering the roots of `P_n(\cos(\theta))` in order of increasing `\theta`). If *weight* is non-NULL, it is set to the weight corresponding to the node `x_k` for Gaussian quadrature on `[-1,1]`. Note that only `\lceil n / 2 \rceil` roots need to be computed, since the remaining roots are given by `x_k = -x_{n-1-k}`. We compute an enclosing interval using an asymptotic approximation followed by some number of Newton iterations, using the error bounds given in [Pet1999]_. If very high precision is requested, the root is subsequently refined using interval Newton steps with doubling working precision. Dilogarithm ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_dilog(arb_t res, const arb_t z, slong prec) Computes the dilogarithm `\operatorname{Li}_2(z)`. Hypergeometric sums ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_sum_fmpq_arb_forward(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) void arb_hypgeom_sum_fmpq_arb_rs(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) void arb_hypgeom_sum_fmpq_arb(arb_t res, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) Sets *res* to the finite hypergeometric sum `\sum_{n=0}^{N-1} (\textbf{a})_n z^n / (\textbf{b})_n` where `\textbf{x}_n = (x_1)_n (x_2)_n \cdots`, given vectors of rational parameters *a* (of length *alen*) and *b* (of length *blen*). If *reciprocal* is set, replace `z` by `1 / z`. The *forward* version uses the forward recurrence, optimized by delaying divisions, the *rs* version uses rectangular splitting, and the default version uses an automatic algorithm choice. .. function:: void arb_hypgeom_sum_fmpq_imag_arb_forward(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) void arb_hypgeom_sum_fmpq_imag_arb_rs(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) void arb_hypgeom_sum_fmpq_imag_arb_bs(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) void arb_hypgeom_sum_fmpq_imag_arb(arb_t res1, arb_t res2, const fmpq * a, slong alen, const fmpq * b, slong blen, const arb_t z, int reciprocal, slong N, slong prec) Sets *res1* and *res2* to the real and imaginary part of the finite hypergeometric sum `\sum_{n=0}^{N-1} (\textbf{a})_n (i z)^n / (\textbf{b})_n`. If *reciprocal* is set, replace `z` by `1 / z`. arb-2.22.1/doc/source/arb_mat.rst000066400000000000000000001011761417376376500165770ustar00rootroot00000000000000.. _arb-mat: **arb_mat.h** -- matrices over the real numbers =============================================================================== An :type:`arb_mat_t` represents a dense matrix over the real numbers, implemented as an array of entries of type :type:`arb_struct`. The dimension (number of rows and columns) of a matrix is fixed at initialization, and the user must ensure that inputs and outputs to an operation have compatible dimensions. The number of rows or columns in a matrix can be zero. .. note:: Methods prefixed with *arb_mat_approx* treat all input entries as floating-point numbers (ignoring the radii of the balls) and compute floating-point output (balls with zero radius) representing approximate solutions *without error bounds*. All other methods compute rigorous error bounds. The *approx* methods are typically useful for computing initial values or preconditioners for rigorous solvers. Some users may also find *approx* methods useful for doing ordinary numerical linear algebra in applications where error bounds are not needed. Types, macros and constants ------------------------------------------------------------------------------- .. type:: arb_mat_struct .. type:: arb_mat_t Contains a pointer to a flat array of the entries (entries), an array of pointers to the start of each row (rows), and the number of rows (r) and columns (c). An *arb_mat_t* is defined as an array of length one of type *arb_mat_struct*, permitting an *arb_mat_t* to be passed by reference. .. macro:: arb_mat_entry(mat, i, j) Macro giving a pointer to the entry at row *i* and column *j*. .. macro:: arb_mat_nrows(mat) Returns the number of rows of the matrix. .. macro:: arb_mat_ncols(mat) Returns the number of columns of the matrix. Memory management ------------------------------------------------------------------------------- .. function:: void arb_mat_init(arb_mat_t mat, slong r, slong c) Initializes the matrix, setting it to the zero matrix with *r* rows and *c* columns. .. function:: void arb_mat_clear(arb_mat_t mat) Clears the matrix, deallocating all entries. .. function:: slong arb_mat_allocated_bytes(const arb_mat_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(arb_mat_struct)`` to get the size of the object as a whole. .. function:: void arb_mat_window_init(arb_mat_t window, const arb_mat_t mat, slong r1, slong c1, slong r2, slong c2) Initializes *window* to a window matrix into the submatrix of *mat* starting at the corner at row *r1* and column *c1* (inclusive) and ending at row *r2* and column *c2* (exclusive). .. function:: void arb_mat_window_clear(arb_mat_t window) Frees the window matrix. Conversions ------------------------------------------------------------------------------- .. function:: void arb_mat_set(arb_mat_t dest, const arb_mat_t src) .. function:: void arb_mat_set_fmpz_mat(arb_mat_t dest, const fmpz_mat_t src) .. function:: void arb_mat_set_round_fmpz_mat(arb_mat_t dest, const fmpz_mat_t src, slong prec) .. function:: void arb_mat_set_fmpq_mat(arb_mat_t dest, const fmpq_mat_t src, slong prec) Sets *dest* to *src*. The operands must have identical dimensions. Random generation ------------------------------------------------------------------------------- .. function:: void arb_mat_randtest(arb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits) Sets *mat* to a random matrix with up to *prec* bits of precision and with exponents of width up to *mag_bits*. Input and output ------------------------------------------------------------------------------- .. function:: void arb_mat_printd(const arb_mat_t mat, slong digits) Prints each entry in the matrix with the specified number of decimal digits. .. function:: void arb_mat_fprintd(FILE * file, const arb_mat_t mat, slong digits) Prints each entry in the matrix with the specified number of decimal digits to the stream *file*. Comparisons ------------------------------------------------------------------------------- Predicate methods return 1 if the property certainly holds and 0 otherwise. .. function:: int arb_mat_equal(const arb_mat_t mat1, const arb_mat_t mat2) Returns whether the matrices have the same dimensions and identical intervals as entries. .. function:: int arb_mat_overlaps(const arb_mat_t mat1, const arb_mat_t mat2) Returns whether the matrices have the same dimensions and each entry in *mat1* overlaps with the corresponding entry in *mat2*. .. function:: int arb_mat_contains(const arb_mat_t mat1, const arb_mat_t mat2) .. function:: int arb_mat_contains_fmpz_mat(const arb_mat_t mat1, const fmpz_mat_t mat2) .. function:: int arb_mat_contains_fmpq_mat(const arb_mat_t mat1, const fmpq_mat_t mat2) Returns whether the matrices have the same dimensions and each entry in *mat2* is contained in the corresponding entry in *mat1*. .. function:: int arb_mat_eq(const arb_mat_t mat1, const arb_mat_t mat2) Returns whether *mat1* and *mat2* certainly represent the same matrix. .. function:: int arb_mat_ne(const arb_mat_t mat1, const arb_mat_t mat2) Returns whether *mat1* and *mat2* certainly do not represent the same matrix. .. function:: int arb_mat_is_empty(const arb_mat_t mat) Returns whether the number of rows or the number of columns in *mat* is zero. .. function:: int arb_mat_is_square(const arb_mat_t mat) Returns whether the number of rows is equal to the number of columns in *mat*. .. function:: int arb_mat_is_exact(const arb_mat_t mat) Returns whether all entries in *mat* have zero radius. .. function:: int arb_mat_is_zero(const arb_mat_t mat) Returns whether all entries in *mat* are exactly zero. .. function:: int arb_mat_is_finite(const arb_mat_t mat) Returns whether all entries in *mat* are finite. .. function:: int arb_mat_is_triu(const arb_mat_t mat) Returns whether *mat* is upper triangular; that is, all entries below the main diagonal are exactly zero. .. function:: int arb_mat_is_tril(const arb_mat_t mat) Returns whether *mat* is lower triangular; that is, all entries above the main diagonal are exactly zero. .. function:: int arb_mat_is_diag(const arb_mat_t mat) Returns whether *mat* is a diagonal matrix; that is, all entries off the main diagonal are exactly zero. Special matrices ------------------------------------------------------------------------------- .. function:: void arb_mat_zero(arb_mat_t mat) Sets all entries in mat to zero. .. function:: void arb_mat_one(arb_mat_t mat) Sets the entries on the main diagonal to ones, and all other entries to zero. .. function:: void arb_mat_ones(arb_mat_t mat) Sets all entries in the matrix to ones. .. function:: void arb_mat_indeterminate(arb_mat_t mat) Sets all entries in the matrix to indeterminate (NaN). .. function:: void arb_mat_hilbert(arb_mat_t mat, slong prec) Sets *mat* to the Hilbert matrix, which has entries `A_{j,k} = 1/(j+k+1)`. .. function:: void arb_mat_pascal(arb_mat_t mat, int triangular, slong prec) Sets *mat* to a Pascal matrix, whose entries are binomial coefficients. If *triangular* is 0, constructs a full symmetric matrix with the rows of Pascal's triangle as successive antidiagonals. If *triangular* is 1, constructs the upper triangular matrix with the rows of Pascal's triangle as columns, and if *triangular* is -1, constructs the lower triangular matrix with the rows of Pascal's triangle as rows. The entries are computed using recurrence relations. When the dimensions get large, some precision loss is possible; in that case, the user may wish to create the matrix at slightly higher precision and then round it to the final precision. .. function:: void arb_mat_stirling(arb_mat_t mat, int kind, slong prec) Sets *mat* to a Stirling matrix, whose entries are Stirling numbers. If *kind* is 0, the entries are set to the unsigned Stirling numbers of the first kind. If *kind* is 1, the entries are set to the signed Stirling numbers of the first kind. If *kind* is 2, the entries are set to the Stirling numbers of the second kind. The entries are computed using recurrence relations. When the dimensions get large, some precision loss is possible; in that case, the user may wish to create the matrix at slightly higher precision and then round it to the final precision. .. function:: void arb_mat_dct(arb_mat_t mat, int type, slong prec) Sets *mat* to the DCT (discrete cosine transform) matrix of order *n* where *n* is the smallest dimension of *mat* (if *mat* is not square, the matrix is extended periodically along the larger dimension). There are many different conventions for defining DCT matrices; here, we use the normalized "DCT-II" transform matrix .. math :: A_{j,k} = \sqrt{\frac{2}{n}} \cos\left(\frac{\pi j}{n} \left(k+\frac{1}{2}\right)\right) which satisfies `A^{-1} = A^T`. The *type* parameter is currently ignored and should be set to 0. In the future, it might be used to select a different convention. Transpose ------------------------------------------------------------------------------- .. function:: void arb_mat_transpose(arb_mat_t dest, const arb_mat_t src) Sets *dest* to the exact transpose *src*. The operands must have compatible dimensions. Aliasing is allowed. Norms ------------------------------------------------------------------------------- .. function:: void arb_mat_bound_inf_norm(mag_t b, const arb_mat_t A) Sets *b* to an upper bound for the infinity norm (i.e. the largest absolute value row sum) of *A*. .. function:: void arb_mat_frobenius_norm(arb_t res, const arb_mat_t A, slong prec) Sets *res* to the Frobenius norm (i.e. the square root of the sum of squares of entries) of *A*. .. function:: void arb_mat_bound_frobenius_norm(mag_t res, const arb_mat_t A) Sets *res* to an upper bound for the Frobenius norm of *A*. Arithmetic ------------------------------------------------------------------------------- .. function:: void arb_mat_neg(arb_mat_t dest, const arb_mat_t src) Sets *dest* to the exact negation of *src*. The operands must have the same dimensions. .. function:: void arb_mat_add(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec) Sets res to the sum of *mat1* and *mat2*. The operands must have the same dimensions. .. function:: void arb_mat_sub(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec) Sets *res* to the difference of *mat1* and *mat2*. The operands must have the same dimensions. .. function:: void arb_mat_mul_classical(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) .. function:: void arb_mat_mul_threaded(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) .. function:: void arb_mat_mul_block(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) .. function:: void arb_mat_mul(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec) Sets *res* to the matrix product of *mat1* and *mat2*. The operands must have compatible dimensions for matrix multiplication. The *classical* version performs matrix multiplication in the trivial way. The *block* version decomposes the input matrices into one or several blocks of uniformly scaled matrices and multiplies large blocks via *fmpz_mat_mul*. It also invokes :func:`_arb_mat_addmul_rad_mag_fast` for the radius matrix multiplications. The *threaded* version performs classical multiplication but splits the computation over the number of threads returned by *flint_get_num_threads()*. The default version chooses an algorithm automatically. .. function:: void arb_mat_mul_entrywise(arb_mat_t C, const arb_mat_t A, const arb_mat_t B, slong prec) Sets *C* to the entrywise product of *A* and *B*. The operands must have the same dimensions. .. function:: void arb_mat_sqr_classical(arb_mat_t B, const arb_mat_t A, slong prec) .. function:: void arb_mat_sqr(arb_mat_t res, const arb_mat_t mat, slong prec) Sets *res* to the matrix square of *mat*. The operands must both be square with the same dimensions. .. function:: void arb_mat_pow_ui(arb_mat_t res, const arb_mat_t mat, ulong exp, slong prec) Sets *res* to *mat* raised to the power *exp*. Requires that *mat* is a square matrix. .. function:: void _arb_mat_addmul_rad_mag_fast(arb_mat_t C, mag_srcptr A, mag_srcptr B, slong ar, slong ac, slong bc) Helper function for matrix multiplication. Adds to the radii of *C* the matrix product of the matrices represented by *A* and *B*, where *A* is a linear array of coefficients in row-major order and *B* is a linear array of coefficients in column-major order. This function assumes that all exponents are small and is unsafe for general use. .. function:: void arb_mat_approx_mul(arb_mat_t res, const arb_mat_t mat1, const arb_mat_t mat2, slong prec) Approximate matrix multiplication. The input radii are ignored and the output matrix is set to an approximate floating-point result. The radii in the output matrix will *not* necessarily be zeroed. Scalar arithmetic ------------------------------------------------------------------------------- .. function:: void arb_mat_scalar_mul_2exp_si(arb_mat_t B, const arb_mat_t A, slong c) Sets *B* to *A* multiplied by `2^c`. .. function:: void arb_mat_scalar_addmul_si(arb_mat_t B, const arb_mat_t A, slong c, slong prec) .. function:: void arb_mat_scalar_addmul_fmpz(arb_mat_t B, const arb_mat_t A, const fmpz_t c, slong prec) .. function:: void arb_mat_scalar_addmul_arb(arb_mat_t B, const arb_mat_t A, const arb_t c, slong prec) Sets *B* to `B + A \times c`. .. function:: void arb_mat_scalar_mul_si(arb_mat_t B, const arb_mat_t A, slong c, slong prec) .. function:: void arb_mat_scalar_mul_fmpz(arb_mat_t B, const arb_mat_t A, const fmpz_t c, slong prec) .. function:: void arb_mat_scalar_mul_arb(arb_mat_t B, const arb_mat_t A, const arb_t c, slong prec) Sets *B* to `A \times c`. .. function:: void arb_mat_scalar_div_si(arb_mat_t B, const arb_mat_t A, slong c, slong prec) .. function:: void arb_mat_scalar_div_fmpz(arb_mat_t B, const arb_mat_t A, const fmpz_t c, slong prec) .. function:: void arb_mat_scalar_div_arb(arb_mat_t B, const arb_mat_t A, const arb_t c, slong prec) Sets *B* to `A / c`. Gaussian elimination and solving ------------------------------------------------------------------------------- .. function:: int arb_mat_lu_classical(slong * perm, arb_mat_t LU, const arb_mat_t A, slong prec) .. function:: int arb_mat_lu_recursive(slong * perm, arb_mat_t LU, const arb_mat_t A, slong prec) .. function:: int arb_mat_lu(slong * perm, arb_mat_t LU, const arb_mat_t A, slong prec) Given an `n \times n` matrix `A`, computes an LU decomposition `PLU = A` using Gaussian elimination with partial pivoting. The input and output matrices can be the same, performing the decomposition in-place. Entry `i` in the permutation vector perm is set to the row index in the input matrix corresponding to row `i` in the output matrix. The algorithm succeeds and returns nonzero if it can find `n` invertible (i.e. not containing zero) pivot entries. This guarantees that the matrix is invertible. The algorithm fails and returns zero, leaving the entries in `P` and `LU` undefined, if it cannot find `n` invertible pivot elements. In this case, either the matrix is singular, the input matrix was computed to insufficient precision, or the LU decomposition was attempted at insufficient precision. The *classical* version uses Gaussian elimination directly while the *recursive* version performs the computation in a block recursive way to benefit from fast matrix multiplication. The default version chooses an algorithm automatically. .. function:: void arb_mat_solve_tril_classical(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) .. function:: void arb_mat_solve_tril_recursive(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) .. function:: void arb_mat_solve_tril(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) .. function:: void arb_mat_solve_triu_classical(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) .. function:: void arb_mat_solve_triu_recursive(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) .. function:: void arb_mat_solve_triu(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) Solves the lower triangular system `LX = B` or the upper triangular system `UX = B`, respectively. If *unit* is set, the main diagonal of *L* or *U* is taken to consist of all ones, and in that case the actual entries on the diagonal are not read at all and can contain other data. The *classical* versions perform the computations iteratively while the *recursive* versions perform the computations in a block recursive way to benefit from fast matrix multiplication. The default versions choose an algorithm automatically. .. function:: void arb_mat_solve_lu_precomp(arb_mat_t X, const slong * perm, const arb_mat_t LU, const arb_mat_t B, slong prec) Solves `AX = B` given the precomputed nonsingular LU decomposition `A = PLU`. The matrices `X` and `B` are allowed to be aliased with each other, but `X` is not allowed to be aliased with `LU`. .. function:: int arb_mat_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) .. function:: int arb_mat_solve_lu(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) .. function:: int arb_mat_solve_precond(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) Solves `AX = B` where `A` is a nonsingular `n \times n` matrix and `X` and `B` are `n \times m` matrices. If `m > 0` and `A` cannot be inverted numerically (indicating either that `A` is singular or that the precision is insufficient), the values in the output matrix are left undefined and zero is returned. A nonzero return value guarantees that `A` is invertible and that the exact solution matrix is contained in the output. Three algorithms are provided: * The *lu* version performs LU decomposition directly in ball arithmetic. This is fast, but the bounds typically blow up exponentially with *n*, even if the system is well-conditioned. This algorithm is usually the best choice at very high precision. * The *precond* version computes an approximate inverse to precondition the system [HS1967]_. This is usually several times slower than direct LU decomposition, but the bounds do not blow up with *n* if the system is well-conditioned. This algorithm is usually the best choice for large systems at low to moderate precision. * The default version selects between *lu* and *precomp* automatically. The automatic choice should be reasonable most of the time, but users may benefit from trying either *lu* or *precond* in specific applications. For example, the *lu* solver often performs better for ill-conditioned systems where use of very high precision is unavoidable. .. function:: int arb_mat_solve_preapprox(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, const arb_mat_t R, const arb_mat_t T, slong prec) Solves `AX = B` where `A` is a nonsingular `n \times n` matrix and `X` and `B` are `n \times m` matrices, given an approximation `R` of the matrix inverse of `A`, and given the approximation `T` of the solution `X`. If `m > 0` and `A` cannot be inverted numerically (indicating either that `A` is singular or that the precision is insufficient, or that `R` is not a close enough approximation of the inverse of `A`), the values in the output matrix are left undefined and zero is returned. A nonzero return value guarantees that `A` is invertible and that the exact solution matrix is contained in the output. .. function:: int arb_mat_inv(arb_mat_t X, const arb_mat_t A, slong prec) Sets `X = A^{-1}` where `A` is a square matrix, computed by solving the system `AX = I`. If `A` cannot be inverted numerically (indicating either that `A` is singular or that the precision is insufficient), the values in the output matrix are left undefined and zero is returned. A nonzero return value guarantees that the matrix is invertible and that the exact inverse is contained in the output. .. function:: void arb_mat_det_lu(arb_t det, const arb_mat_t A, slong prec) .. function:: void arb_mat_det_precond(arb_t det, const arb_mat_t A, slong prec) .. function:: void arb_mat_det(arb_t det, const arb_mat_t A, slong prec) Sets *det* to the determinant of the matrix *A*. The *lu* version uses Gaussian elimination with partial pivoting. If at some point an invertible pivot element cannot be found, the elimination is stopped and the magnitude of the determinant of the remaining submatrix is bounded using Hadamard's inequality. The *precond* version computes an approximate LU factorization of *A* and multiplies by the inverse *L* and *U* martices as preconditioners to obtain a matrix close to the identity matrix [Rum2010]_. An enclosure for this determinant is computed using Gershgorin circles. This is about four times slower than direct Gaussian elimination, but much more numerically stable. The default version automatically selects between the *lu* and *precond* versions and additionally handles small or triangular matrices by direct formulas. .. function:: void arb_mat_approx_solve_triu(arb_mat_t X, const arb_mat_t U, const arb_mat_t B, int unit, slong prec) .. function:: void arb_mat_approx_solve_tril(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, int unit, slong prec) .. function:: int arb_mat_approx_lu(slong * P, arb_mat_t LU, const arb_mat_t A, slong prec) .. function:: void arb_mat_approx_solve_lu_precomp(arb_mat_t X, const slong * perm, const arb_mat_t A, const arb_mat_t B, slong prec) .. function:: int arb_mat_approx_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) .. function:: int arb_mat_approx_inv(arb_mat_t X, const arb_mat_t A, slong prec) These methods perform approximate solving *without any error control*. The radii in the input matrices are ignored, the computations are done numerically with floating-point arithmetic (using ordinary Gaussian elimination and triangular solving, accelerated through the use of block recursive strategies for large matrices), and the output matrices are set to the approximate floating-point results with zeroed error bounds. Approximate solutions are useful for computing preconditioning matrices for certified solutions. Some users may also find these methods useful for doing ordinary numerical linear algebra in applications where error bounds are not needed. Cholesky decomposition and solving ------------------------------------------------------------------------------- .. function:: int _arb_mat_cholesky_banachiewicz(arb_mat_t A, slong prec) .. function:: int arb_mat_cho(arb_mat_t L, const arb_mat_t A, slong prec) Computes the Cholesky decomposition of *A*, returning nonzero iff the symmetric matrix defined by the lower triangular part of *A* is certainly positive definite. If a nonzero value is returned, then *L* is set to the lower triangular matrix such that `A = L * L^T`. If zero is returned, then either the matrix is not symmetric positive definite, the input matrix was computed to insufficient precision, or the decomposition was attempted at insufficient precision. The underscore method computes *L* from *A* in-place, leaving the strict upper triangular region undefined. .. function:: void arb_mat_solve_cho_precomp(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, slong prec) Solves `AX = B` given the precomputed Cholesky decomposition `A = L L^T`. The matrices *X* and *B* are allowed to be aliased with each other, but *X* is not allowed to be aliased with *L*. .. function:: int arb_mat_spd_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec) Solves `AX = B` where *A* is a symmetric positive definite matrix and *X* and *B* are `n \times m` matrices, using Cholesky decomposition. If `m > 0` and *A* cannot be factored using Cholesky decomposition (indicating either that *A* is not symmetric positive definite or that the precision is insufficient), the values in the output matrix are left undefined and zero is returned. A nonzero return value guarantees that the symmetric matrix defined through the lower triangular part of *A* is invertible and that the exact solution matrix is contained in the output. .. function:: void arb_mat_inv_cho_precomp(arb_mat_t X, const arb_mat_t L, slong prec) Sets `X = A^{-1}` where `A` is a symmetric positive definite matrix whose Cholesky decomposition *L* has been computed with :func:`arb_mat_cho`. The inverse is calculated using the method of [Kri2013]_ which is more efficient than solving `AX = I` with :func:`arb_mat_solve_cho_precomp`. .. function:: int arb_mat_spd_inv(arb_mat_t X, const arb_mat_t A, slong prec) Sets `X = A^{-1}` where *A* is a symmetric positive definite matrix. It is calculated using the method of [Kri2013]_ which computes fewer intermediate results than solving `AX = I` with :func:`arb_mat_spd_solve`. If *A* cannot be factored using Cholesky decomposition (indicating either that *A* is not symmetric positive definite or that the precision is insufficient), the values in the output matrix are left undefined and zero is returned. A nonzero return value guarantees that the symmetric matrix defined through the lower triangular part of *A* is invertible and that the exact inverse is contained in the output. .. function:: int _arb_mat_ldl_inplace(arb_mat_t A, slong prec) .. function:: int _arb_mat_ldl_golub_and_van_loan(arb_mat_t A, slong prec) .. function:: int arb_mat_ldl(arb_mat_t res, const arb_mat_t A, slong prec) Computes the `LDL^T` decomposition of *A*, returning nonzero iff the symmetric matrix defined by the lower triangular part of *A* is certainly positive definite. If a nonzero value is returned, then *res* is set to a lower triangular matrix that encodes the `L * D * L^T` decomposition of *A*. In particular, `L` is a lower triangular matrix with ones on its diagonal and whose strictly lower triangular region is the same as that of *res*. `D` is a diagonal matrix with the same diagonal as that of *res*. If zero is returned, then either the matrix is not symmetric positive definite, the input matrix was computed to insufficient precision, or the decomposition was attempted at insufficient precision. The underscore methods compute *res* from *A* in-place, leaving the strict upper triangular region undefined. The default method uses algorithm 4.1.2 from [GVL1996]_. .. function:: void arb_mat_solve_ldl_precomp(arb_mat_t X, const arb_mat_t L, const arb_mat_t B, slong prec) Solves `AX = B` given the precomputed `A = LDL^T` decomposition encoded by *L*. The matrices *X* and *B* are allowed to be aliased with each other, but *X* is not allowed to be aliased with *L*. .. function:: void arb_mat_inv_ldl_precomp(arb_mat_t X, const arb_mat_t L, slong prec) Sets `X = A^{-1}` where `A` is a symmetric positive definite matrix whose `LDL^T` decomposition encoded by *L* has been computed with :func:`arb_mat_ldl`. The inverse is calculated using the method of [Kri2013]_ which is more efficient than solving `AX = I` with :func:`arb_mat_solve_ldl_precomp`. Characteristic polynomial and companion matrix ------------------------------------------------------------------------------- .. function:: void _arb_mat_charpoly(arb_ptr poly, const arb_mat_t mat, slong prec) .. function:: void arb_mat_charpoly(arb_poly_t poly, const arb_mat_t mat, slong prec) Sets *poly* to the characteristic polynomial of *mat* which must be a square matrix. If the matrix has *n* rows, the underscore method requires space for `n + 1` output coefficients. Employs a division-free algorithm using `O(n^4)` operations. .. function:: void _arb_mat_companion(arb_mat_t mat, arb_srcptr poly, slong prec) .. function:: void arb_mat_companion(arb_mat_t mat, const arb_poly_t poly, slong prec) Sets the *n* by *n* matrix *mat* to the companion matrix of the polynomial *poly* which must have degree *n*. The underscore method reads `n + 1` input coefficients. Special functions ------------------------------------------------------------------------------- .. function:: void arb_mat_exp_taylor_sum(arb_mat_t S, const arb_mat_t A, slong N, slong prec) Sets *S* to the truncated exponential Taylor series `S = \sum_{k=0}^{N-1} A^k / k!`. Uses rectangular splitting to compute the sum using `O(\sqrt{N})` matrix multiplications. The recurrence relation for factorials is used to get scalars that are small integers instead of full factorials. As in [Joh2014b]_, all divisions are postponed to the end by computing partial factorials of length `O(\sqrt{N})`. The scalars could be reduced by doing more divisions, but this appears to be slower in most cases. .. function:: void arb_mat_exp(arb_mat_t B, const arb_mat_t A, slong prec) Sets *B* to the exponential of the matrix *A*, defined by the Taylor series .. math :: \exp(A) = \sum_{k=0}^{\infty} \frac{A^k}{k!}. The function is evaluated as `\exp(A/2^r)^{2^r}`, where `r` is chosen to give rapid convergence. The elementwise error when truncating the Taylor series after *N* terms is bounded by the error in the infinity norm, for which we have .. math :: \left\|\exp(2^{-r}A) - \sum_{k=0}^{N-1} \frac{\left(2^{-r} A\right)^k}{k!} \right\|_{\infty} = \left\|\sum_{k=N}^{\infty} \frac{\left(2^{-r} A\right)^k}{k!}\right\|_{\infty} \le \sum_{k=N}^{\infty} \frac{(2^{-r} \|A\|_{\infty})^k}{k!}. We bound the sum on the right using :func:`mag_exp_tail`. Truncation error is not added to entries whose values are determined by the sparsity structure of `A`. .. function:: void arb_mat_trace(arb_t trace, const arb_mat_t mat, slong prec) Sets *trace* to the trace of the matrix, i.e. the sum of entries on the main diagonal of *mat*. The matrix is required to be square. .. function:: void _arb_mat_diag_prod(arb_t res, const arb_mat_t mat, slong a, slong b, slong prec) .. function:: void arb_mat_diag_prod(arb_t res, const arb_mat_t mat, slong prec) Sets *res* to the product of the entries on the main diagonal of *mat*. The underscore method computes the product of the entries between index *a* inclusive and *b* exclusive (the indices must be in range). Sparsity structure ------------------------------------------------------------------------------- .. function:: void arb_mat_entrywise_is_zero(fmpz_mat_t dest, const arb_mat_t src) Sets each entry of *dest* to indicate whether the corresponding entry of *src* is certainly zero. If the entry of *src* at row `i` and column `j` is zero according to :func:`arb_is_zero` then the entry of *dest* at that row and column is set to one, otherwise that entry of *dest* is set to zero. .. function:: void arb_mat_entrywise_not_is_zero(fmpz_mat_t dest, const arb_mat_t src) Sets each entry of *dest* to indicate whether the corresponding entry of *src* is not certainly zero. This the complement of :func:`arb_mat_entrywise_is_zero`. .. function:: slong arb_mat_count_is_zero(const arb_mat_t mat) Returns the number of entries of *mat* that are certainly zero according to :func:`arb_is_zero`. .. function:: slong arb_mat_count_not_is_zero(const arb_mat_t mat) Returns the number of entries of *mat* that are not certainly zero. Component and error operations ------------------------------------------------------------------------------- .. function:: void arb_mat_get_mid(arb_mat_t B, const arb_mat_t A) Sets the entries of *B* to the exact midpoints of the entries of *A*. .. function:: void arb_mat_add_error_mag(arb_mat_t mat, const mag_t err) Adds *err* in-place to the radii of the entries of *mat*. Eigenvalues and eigenvectors ------------------------------------------------------------------------------- To compute eigenvalues and eigenvectors, one can convert to an :type:`acb_mat_t` and use the functions in :ref:`acb_mat.h: Eigenvalues and eigenvectors`. In the future dedicated methods for real matrices will be added here. arb-2.22.1/doc/source/arb_poly.rst000066400000000000000000001530661417376376500170060ustar00rootroot00000000000000.. _arb-poly: **arb_poly.h** -- polynomials over the real numbers =============================================================================== An :type:`arb_poly_t` represents a polynomial over the real numbers, implemented as an array of coefficients of type :type:`arb_struct`. Most functions are provided in two versions: an underscore method which operates directly on pre-allocated arrays of coefficients and generally has some restrictions (such as requiring the lengths to be nonzero and not supporting aliasing of the input and output arrays), and a non-underscore method which performs automatic memory management and handles degenerate cases. Types, macros and constants ------------------------------------------------------------------------------- .. type:: arb_poly_struct .. type:: arb_poly_t Contains a pointer to an array of coefficients (coeffs), the used length (length), and the allocated size of the array (alloc). An *arb_poly_t* is defined as an array of length one of type *arb_poly_struct*, permitting an *arb_poly_t* to be passed by reference. Memory management ------------------------------------------------------------------------------- .. function:: void arb_poly_init(arb_poly_t poly) Initializes the polynomial for use, setting it to the zero polynomial. .. function:: void arb_poly_clear(arb_poly_t poly) Clears the polynomial, deallocating all coefficients and the coefficient array. .. function:: void arb_poly_fit_length(arb_poly_t poly, slong len) Makes sure that the coefficient array of the polynomial contains at least *len* initialized coefficients. .. function:: void _arb_poly_set_length(arb_poly_t poly, slong len) Directly changes the length of the polynomial, without allocating or deallocating coefficients. The value should not exceed the allocation length. .. function:: void _arb_poly_normalise(arb_poly_t poly) Strips any trailing coefficients which are identical to zero. .. function:: slong arb_poly_allocated_bytes(const arb_poly_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(arb_poly_struct)`` to get the size of the object as a whole. Basic manipulation ------------------------------------------------------------------------------- .. function:: slong arb_poly_length(const arb_poly_t poly) Returns the length of *poly*, i.e. zero if *poly* is identically zero, and otherwise one more than the index of the highest term that is not identically zero. .. function:: slong arb_poly_degree(const arb_poly_t poly) Returns the degree of *poly*, defined as one less than its length. Note that if one or several leading coefficients are balls containing zero, this value can be larger than the true degree of the exact polynomial represented by *poly*, so the return value of this function is effectively an upper bound. .. function:: int arb_poly_is_zero(const arb_poly_t poly) .. function:: int arb_poly_is_one(const arb_poly_t poly) .. function:: int arb_poly_is_x(const arb_poly_t poly) Returns 1 if *poly* is exactly the polynomial 0, 1 or *x* respectively. Returns 0 otherwise. .. function:: void arb_poly_zero(arb_poly_t poly) .. function:: void arb_poly_one(arb_poly_t poly) Sets *poly* to the constant 0 respectively 1. .. function:: void arb_poly_set(arb_poly_t dest, const arb_poly_t src) Sets *dest* to a copy of *src*. .. function:: void arb_poly_set_round(arb_poly_t dest, const arb_poly_t src, slong prec) Sets *dest* to a copy of *src*, rounded to *prec* bits. .. function:: void arb_poly_set_trunc(arb_poly_t dest, const arb_poly_t src, slong n) .. function:: void arb_poly_set_trunc_round(arb_poly_t dest, const arb_poly_t src, slong n, slong prec) Sets *dest* to a copy of *src*, truncated to length *n* and rounded to *prec* bits. .. function:: void arb_poly_set_coeff_si(arb_poly_t poly, slong n, slong c) .. function:: void arb_poly_set_coeff_arb(arb_poly_t poly, slong n, const arb_t c) Sets the coefficient with index *n* in *poly* to the value *c*. We require that *n* is nonnegative. .. function:: void arb_poly_get_coeff_arb(arb_t v, const arb_poly_t poly, slong n) Sets *v* to the value of the coefficient with index *n* in *poly*. We require that *n* is nonnegative. .. macro:: arb_poly_get_coeff_ptr(poly, n) Given `n \ge 0`, returns a pointer to coefficient *n* of *poly*, or *NULL* if *n* exceeds the length of *poly*. .. function:: void _arb_poly_shift_right(arb_ptr res, arb_srcptr poly, slong len, slong n) .. function:: void arb_poly_shift_right(arb_poly_t res, const arb_poly_t poly, slong n) Sets *res* to *poly* divided by `x^n`, throwing away the lower coefficients. We require that *n* is nonnegative. .. function:: void _arb_poly_shift_left(arb_ptr res, arb_srcptr poly, slong len, slong n) .. function:: void arb_poly_shift_left(arb_poly_t res, const arb_poly_t poly, slong n) Sets *res* to *poly* multiplied by `x^n`. We require that *n* is nonnegative. .. function:: void arb_poly_truncate(arb_poly_t poly, slong n) Truncates *poly* to have length at most *n*, i.e. degree strictly smaller than *n*. We require that *n* is nonnegative. .. function:: slong arb_poly_valuation(const arb_poly_t poly) Returns the degree of the lowest term that is not exactly zero in *poly*. Returns -1 if *poly* is the zero polynomial. Conversions ------------------------------------------------------------------------------- .. function:: void arb_poly_set_fmpz_poly(arb_poly_t poly, const fmpz_poly_t src, slong prec) .. function:: void arb_poly_set_fmpq_poly(arb_poly_t poly, const fmpq_poly_t src, slong prec) .. function:: void arb_poly_set_si(arb_poly_t poly, slong src) Sets *poly* to *src*, rounding the coefficients to *prec* bits. Input and output ------------------------------------------------------------------------------- .. function:: void arb_poly_printd(const arb_poly_t poly, slong digits) Prints the polynomial as an array of coefficients, printing each coefficient using *arb_printd*. .. function:: void arb_poly_fprintd(FILE * file, const arb_poly_t poly, slong digits) Prints the polynomial as an array of coefficients to the stream *file*, printing each coefficient using *arb_fprintd*. Random generation ------------------------------------------------------------------------------- .. function:: void arb_poly_randtest(arb_poly_t poly, flint_rand_t state, slong len, slong prec, slong mag_bits) Creates a random polynomial with length at most *len*. Comparisons ------------------------------------------------------------------------------- .. function:: int arb_poly_contains(const arb_poly_t poly1, const arb_poly_t poly2) .. function:: int arb_poly_contains_fmpz_poly(const arb_poly_t poly1, const fmpz_poly_t poly2) .. function:: int arb_poly_contains_fmpq_poly(const arb_poly_t poly1, const fmpq_poly_t poly2) Returns nonzero iff *poly1* contains *poly2*. .. function:: int arb_poly_equal(const arb_poly_t A, const arb_poly_t B) Returns nonzero iff *A* and *B* are equal as polynomial balls, i.e. all coefficients have equal midpoint and radius. .. function:: int _arb_poly_overlaps(arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2) .. function:: int arb_poly_overlaps(const arb_poly_t poly1, const arb_poly_t poly2) Returns nonzero iff *poly1* overlaps with *poly2*. The underscore function requires that *len1* ist at least as large as *len2*. .. function:: int arb_poly_get_unique_fmpz_poly(fmpz_poly_t z, const arb_poly_t x) If *x* contains a unique integer polynomial, sets *z* to that value and returns nonzero. Otherwise (if *x* represents no integers or more than one integer), returns zero, possibly partially modifying *z*. Bounds ------------------------------------------------------------------------------- .. function:: void _arb_poly_majorant(arb_ptr res, arb_srcptr poly, slong len, slong prec) .. function:: void arb_poly_majorant(arb_poly_t res, const arb_poly_t poly, slong prec) Sets *res* to an exact real polynomial whose coefficients are upper bounds for the absolute values of the coefficients in *poly*, rounded to *prec* bits. Arithmetic ------------------------------------------------------------------------------- .. function:: void _arb_poly_add(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) Sets *{C, max(lenA, lenB)}* to the sum of *{A, lenA}* and *{B, lenB}*. Allows aliasing of the input and output operands. .. function:: void arb_poly_add(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong prec) .. function:: void arb_poly_add_si(arb_poly_t C, const arb_poly_t A, slong B, slong prec) Sets *C* to the sum of *A* and *B*. .. function:: void _arb_poly_sub(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) Sets *{C, max(lenA, lenB)}* to the difference of *{A, lenA}* and *{B, lenB}*. Allows aliasing of the input and output operands. .. function:: void arb_poly_sub(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong prec) Sets *C* to the difference of *A* and *B*. .. function:: void arb_poly_add_series(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong len, slong prec) Sets *C* to the sum of *A* and *B*, truncated to length *len*. .. function:: void arb_poly_sub_series(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong len, slong prec) Sets *C* to the difference of *A* and *B*, truncated to length *len*. .. function:: void arb_poly_neg(arb_poly_t C, const arb_poly_t A) Sets *C* to the negation of *A*. .. function:: void arb_poly_scalar_mul_2exp_si(arb_poly_t C, const arb_poly_t A, slong c) Sets *C* to *A* multiplied by `2^c`. .. function:: void arb_poly_scalar_mul(arb_poly_t C, const arb_poly_t A, const arb_t c, slong prec) Sets *C* to *A* multiplied by *c*. .. function:: void arb_poly_scalar_div(arb_poly_t C, const arb_poly_t A, const arb_t c, slong prec) Sets *C* to *A* divided by *c*. .. function:: void _arb_poly_mullow_classical(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong n, slong prec) .. function:: void _arb_poly_mullow_block(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong n, slong prec) .. function:: void _arb_poly_mullow(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong n, slong prec) Sets *{C, n}* to the product of *{A, lenA}* and *{B, lenB}*, truncated to length *n*. The output is not allowed to be aliased with either of the inputs. We require `\mathrm{lenA} \ge \mathrm{lenB} > 0`, `n > 0`, `\mathrm{lenA} + \mathrm{lenB} - 1 \ge n`. The *classical* version uses a plain loop. This has good numerical stability but gets slow for large *n*. The *block* version decomposes the product into several subproducts which are computed exactly over the integers. It first attempts to find an integer `c` such that `A(2^c x)` and `B(2^c x)` have slowly varying coefficients, to reduce the number of blocks. The scaling factor `c` is chosen in a quick, heuristic way by picking the first and last nonzero terms in each polynomial. If the indices in `A` are `a_2, a_1` and the log-2 magnitudes are `e_2, e_1`, and the indices in `B` are `b_2, b_1` with corresponding magnitudes `f_2, f_1`, then we compute `c` as the weighted arithmetic mean of the slopes, rounded to the nearest integer: .. math :: c = \left\lfloor \frac{(e_2 - e_1) + (f_2 + f_1)}{(a_2 - a_1) + (b_2 - b_1)} + \frac{1}{2} \right \rfloor. This strategy is used because it is simple. It is not optimal in all cases, but will typically give good performance when multiplying two power series with a similar decay rate. The default algorithm chooses the *classical* algorithm for short polynomials and the *block* algorithm for long polynomials. If the input pointers are identical (and the lengths are the same), they are assumed to represent the same polynomial, and its square is computed. .. function:: void arb_poly_mullow_classical(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong n, slong prec) .. function:: void arb_poly_mullow_ztrunc(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong n, slong prec) .. function:: void arb_poly_mullow_block(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong n, slong prec) .. function:: void arb_poly_mullow(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong n, slong prec) Sets *C* to the product of *A* and *B*, truncated to length *n*. If the same variable is passed for *A* and *B*, sets *C* to the square of *A* truncated to length *n*. .. function:: void _arb_poly_mul(arb_ptr C, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) Sets *{C, lenA + lenB - 1}* to the product of *{A, lenA}* and *{B, lenB}*. The output is not allowed to be aliased with either of the inputs. We require `\mathrm{lenA} \ge \mathrm{lenB} > 0`. This function is implemented as a simple wrapper for :func:`_arb_poly_mullow`. If the input pointers are identical (and the lengths are the same), they are assumed to represent the same polynomial, and its square is computed. .. function:: void arb_poly_mul(arb_poly_t C, const arb_poly_t A, const arb_poly_t B, slong prec) Sets *C* to the product of *A* and *B*. If the same variable is passed for *A* and *B*, sets *C* to the square of *A*. .. function:: void _arb_poly_inv_series(arb_ptr Q, arb_srcptr A, slong Alen, slong len, slong prec) Sets *{Q, len}* to the power series inverse of *{A, Alen}*. Uses Newton iteration. .. function:: void arb_poly_inv_series(arb_poly_t Q, const arb_poly_t A, slong n, slong prec) Sets *Q* to the power series inverse of *A*, truncated to length *n*. .. function:: void _arb_poly_div_series(arb_ptr Q, arb_srcptr A, slong Alen, arb_srcptr B, slong Blen, slong n, slong prec) Sets *{Q, n}* to the power series quotient of *{A, Alen}* by *{B, Blen}*. Uses Newton iteration followed by multiplication. .. function:: void arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, slong n, slong prec) Sets *Q* to the power series quotient *A* divided by *B*, truncated to length *n*. .. function:: void _arb_poly_div(arb_ptr Q, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) .. function:: void _arb_poly_rem(arb_ptr R, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) .. function:: void _arb_poly_divrem(arb_ptr Q, arb_ptr R, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) .. function:: int arb_poly_divrem(arb_poly_t Q, arb_poly_t R, const arb_poly_t A, const arb_poly_t B, slong prec) Performs polynomial division with remainder, computing a quotient `Q` and a remainder `R` such that `A = BQ + R`. The implementation reverses the inputs and performs power series division. If the leading coefficient of `B` contains zero (or if `B` is identically zero), returns 0 indicating failure without modifying the outputs. Otherwise returns nonzero. .. function:: void _arb_poly_div_root(arb_ptr Q, arb_t R, arb_srcptr A, slong len, const arb_t c, slong prec) Divides `A` by the polynomial `x - c`, computing the quotient `Q` as well as the remainder `R = f(c)`. Composition ------------------------------------------------------------------------------- .. function:: void _arb_poly_taylor_shift_horner(arb_ptr g, const arb_t c, slong n, slong prec) .. function:: void arb_poly_taylor_shift_horner(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) .. function:: void _arb_poly_taylor_shift_divconquer(arb_ptr g, const arb_t c, slong n, slong prec) .. function:: void arb_poly_taylor_shift_divconquer(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) .. function:: void _arb_poly_taylor_shift_convolution(arb_ptr g, const arb_t c, slong n, slong prec) .. function:: void arb_poly_taylor_shift_convolution(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) .. function:: void _arb_poly_taylor_shift(arb_ptr g, const arb_t c, slong n, slong prec) .. function:: void arb_poly_taylor_shift(arb_poly_t g, const arb_poly_t f, const arb_t c, slong prec) Sets *g* to the Taylor shift `f(x+c)`, computed respectively using an optimized form of Horner's rule, divide-and-conquer, a single convolution, and an automatic choice between the three algorithms. The underscore methods act in-place on *g* = *f* which has length *n*. .. function:: void _arb_poly_compose_horner(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) .. function:: void arb_poly_compose_horner(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) .. function:: void _arb_poly_compose_divconquer(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) .. function:: void arb_poly_compose_divconquer(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) .. function:: void _arb_poly_compose(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong prec) .. function:: void arb_poly_compose(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) Sets *res* to the composition `h(x) = f(g(x))` where `f` is given by *poly1* and `g` is given by *poly2*, respectively using Horner's rule, divide-and-conquer, and an automatic choice between the two algorithms. The default algorithm also handles special-form input `g = ax^n + c` efficiently by performing a Taylor shift followed by a rescaling. The underscore methods do not support aliasing of the output with either input polynomial. .. function:: void _arb_poly_compose_series_horner(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) .. function:: void arb_poly_compose_series_horner(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) .. function:: void _arb_poly_compose_series_brent_kung(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) .. function:: void arb_poly_compose_series_brent_kung(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) .. function:: void _arb_poly_compose_series(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) .. function:: void arb_poly_compose_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) Sets *res* to the power series composition `h(x) = f(g(x))` truncated to order `O(x^n)` where `f` is given by *poly1* and `g` is given by *poly2*, respectively using Horner's rule, the Brent-Kung baby step-giant step algorithm, and an automatic choice between the two algorithms. The default algorithm also handles special-form input `g = ax^n` efficiently. We require that the constant term in `g(x)` is exactly zero. The underscore methods do not support aliasing of the output with either input polynomial. .. function:: void _arb_poly_revert_series_lagrange(arb_ptr h, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_revert_series_lagrange(arb_poly_t h, const arb_poly_t f, slong n, slong prec) .. function:: void _arb_poly_revert_series_newton(arb_ptr h, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_revert_series_newton(arb_poly_t h, const arb_poly_t f, slong n, slong prec) .. function:: void _arb_poly_revert_series_lagrange_fast(arb_ptr h, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_revert_series_lagrange_fast(arb_poly_t h, const arb_poly_t f, slong n, slong prec) .. function:: void _arb_poly_revert_series(arb_ptr h, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_revert_series(arb_poly_t h, const arb_poly_t f, slong n, slong prec) Sets `h` to the power series reversion of `f`, i.e. the expansion of the compositional inverse function `f^{-1}(x)`, truncated to order `O(x^n)`, using respectively Lagrange inversion, Newton iteration, fast Lagrange inversion, and a default algorithm choice. We require that the constant term in `f` is exactly zero and that the linear term is nonzero. The underscore methods assume that *flen* is at least 2, and do not support aliasing. Evaluation ------------------------------------------------------------------------------- .. function:: void _arb_poly_evaluate_horner(arb_t y, arb_srcptr f, slong len, const arb_t x, slong prec) .. function:: void arb_poly_evaluate_horner(arb_t y, const arb_poly_t f, const arb_t x, slong prec) .. function:: void _arb_poly_evaluate_rectangular(arb_t y, arb_srcptr f, slong len, const arb_t x, slong prec) .. function:: void arb_poly_evaluate_rectangular(arb_t y, const arb_poly_t f, const arb_t x, slong prec) .. function:: void _arb_poly_evaluate(arb_t y, arb_srcptr f, slong len, const arb_t x, slong prec) .. function:: void arb_poly_evaluate(arb_t y, const arb_poly_t f, const arb_t x, slong prec) Sets `y = f(x)`, evaluated respectively using Horner's rule, rectangular splitting, and an automatic algorithm choice. .. function:: void _arb_poly_evaluate_acb_horner(acb_t y, arb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void arb_poly_evaluate_acb_horner(acb_t y, const arb_poly_t f, const acb_t x, slong prec) .. function:: void _arb_poly_evaluate_acb_rectangular(acb_t y, arb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void arb_poly_evaluate_acb_rectangular(acb_t y, const arb_poly_t f, const acb_t x, slong prec) .. function:: void _arb_poly_evaluate_acb(acb_t y, arb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void arb_poly_evaluate_acb(acb_t y, const arb_poly_t f, const acb_t x, slong prec) Sets `y = f(x)` where `x` is a complex number, evaluating the polynomial respectively using Horner's rule, rectangular splitting, and an automatic algorithm choice. .. function:: void _arb_poly_evaluate2_horner(arb_t y, arb_t z, arb_srcptr f, slong len, const arb_t x, slong prec) .. function:: void arb_poly_evaluate2_horner(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, slong prec) .. function:: void _arb_poly_evaluate2_rectangular(arb_t y, arb_t z, arb_srcptr f, slong len, const arb_t x, slong prec) .. function:: void arb_poly_evaluate2_rectangular(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, slong prec) .. function:: void _arb_poly_evaluate2(arb_t y, arb_t z, arb_srcptr f, slong len, const arb_t x, slong prec) .. function:: void arb_poly_evaluate2(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, slong prec) Sets `y = f(x), z = f'(x)`, evaluated respectively using Horner's rule, rectangular splitting, and an automatic algorithm choice. When Horner's rule is used, the only advantage of evaluating the function and its derivative simultaneously is that one does not have to generate the derivative polynomial explicitly. With the rectangular splitting algorithm, the powers can be reused, making simultaneous evaluation slightly faster. .. function:: void _arb_poly_evaluate2_acb_horner(acb_t y, acb_t z, arb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void arb_poly_evaluate2_acb_horner(acb_t y, acb_t z, const arb_poly_t f, const acb_t x, slong prec) .. function:: void _arb_poly_evaluate2_acb_rectangular(acb_t y, acb_t z, arb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void arb_poly_evaluate2_acb_rectangular(acb_t y, acb_t z, const arb_poly_t f, const acb_t x, slong prec) .. function:: void _arb_poly_evaluate2_acb(acb_t y, acb_t z, arb_srcptr f, slong len, const acb_t x, slong prec) .. function:: void arb_poly_evaluate2_acb(acb_t y, acb_t z, const arb_poly_t f, const acb_t x, slong prec) Sets `y = f(x), z = f'(x)`, evaluated respectively using Horner's rule, rectangular splitting, and an automatic algorithm choice. Product trees ------------------------------------------------------------------------------- .. function:: void _arb_poly_product_roots(arb_ptr poly, arb_srcptr xs, slong n, slong prec) .. function:: void arb_poly_product_roots(arb_poly_t poly, arb_srcptr xs, slong n, slong prec) Generates the polynomial `(x-x_0)(x-x_1)\cdots(x-x_{n-1})`. .. function:: void _arb_poly_product_roots_complex(arb_ptr poly, arb_srcptr r, slong rn, acb_srcptr c, slong cn, slong prec) .. function:: void arb_poly_product_roots_complex(arb_poly_t poly, arb_srcptr r, slong rn, acb_srcptr c, slong cn, slong prec) Generates the polynomial .. math :: \left(\prod_{i=0}^{rn-1} (x-r_i)\right) \left(\prod_{i=0}^{cn-1} (x-c_i)(x-\bar{c_i})\right) having *rn* real roots given by the array *r* and having `2cn` complex roots in conjugate pairs given by the length-*cn* array *c*. Either *rn* or *cn* or both may be zero. Note that only one representative from each complex conjugate pair is supplied (unless a pair is supposed to be repeated with higher multiplicity). To construct a polynomial from complex roots where the conjugate pairs have not been distinguished, use :func:`acb_poly_product_roots` instead. .. function:: arb_ptr * _arb_poly_tree_alloc(slong len) Returns an initialized data structured capable of representing a remainder tree (product tree) of *len* roots. .. function:: void _arb_poly_tree_free(arb_ptr * tree, slong len) Deallocates a tree structure as allocated using *_arb_poly_tree_alloc*. .. function:: void _arb_poly_tree_build(arb_ptr * tree, arb_srcptr roots, slong len, slong prec) Constructs a product tree from a given array of *len* roots. The tree structure must be pre-allocated to the specified length using :func:`_arb_poly_tree_alloc`. Multipoint evaluation ------------------------------------------------------------------------------- .. function:: void _arb_poly_evaluate_vec_iter(arb_ptr ys, arb_srcptr poly, slong plen, arb_srcptr xs, slong n, slong prec) .. function:: void arb_poly_evaluate_vec_iter(arb_ptr ys, const arb_poly_t poly, arb_srcptr xs, slong n, slong prec) Evaluates the polynomial simultaneously at *n* given points, calling :func:`_arb_poly_evaluate` repeatedly. .. function:: void _arb_poly_evaluate_vec_fast_precomp(arb_ptr vs, arb_srcptr poly, slong plen, arb_ptr * tree, slong len, slong prec) .. function:: void _arb_poly_evaluate_vec_fast(arb_ptr ys, arb_srcptr poly, slong plen, arb_srcptr xs, slong n, slong prec) .. function:: void arb_poly_evaluate_vec_fast(arb_ptr ys, const arb_poly_t poly, arb_srcptr xs, slong n, slong prec) Evaluates the polynomial simultaneously at *n* given points, using fast multipoint evaluation. Interpolation ------------------------------------------------------------------------------- .. function:: void _arb_poly_interpolate_newton(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) .. function:: void arb_poly_interpolate_newton(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) Recovers the unique polynomial of length at most *n* that interpolates the given *x* and *y* values. This implementation first interpolates in the Newton basis and then converts back to the monomial basis. .. function:: void _arb_poly_interpolate_barycentric(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) .. function:: void arb_poly_interpolate_barycentric(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) Recovers the unique polynomial of length at most *n* that interpolates the given *x* and *y* values. This implementation uses the barycentric form of Lagrange interpolation. .. function:: void _arb_poly_interpolation_weights(arb_ptr w, arb_ptr * tree, slong len, slong prec) .. function:: void _arb_poly_interpolate_fast_precomp(arb_ptr poly, arb_srcptr ys, arb_ptr * tree, arb_srcptr weights, slong len, slong prec) .. function:: void _arb_poly_interpolate_fast(arb_ptr poly, arb_srcptr xs, arb_srcptr ys, slong len, slong prec) .. function:: void arb_poly_interpolate_fast(arb_poly_t poly, arb_srcptr xs, arb_srcptr ys, slong n, slong prec) Recovers the unique polynomial of length at most *n* that interpolates the given *x* and *y* values, using fast Lagrange interpolation. The precomp function takes a precomputed product tree over the *x* values and a vector of interpolation weights as additional inputs. Differentiation ------------------------------------------------------------------------------- .. function:: void _arb_poly_derivative(arb_ptr res, arb_srcptr poly, slong len, slong prec) Sets *{res, len - 1}* to the derivative of *{poly, len}*. Allows aliasing of the input and output. .. function:: void arb_poly_derivative(arb_poly_t res, const arb_poly_t poly, slong prec) Sets *res* to the derivative of *poly*. .. function:: void _arb_poly_integral(arb_ptr res, arb_srcptr poly, slong len, slong prec) Sets *{res, len}* to the integral of *{poly, len - 1}*. Allows aliasing of the input and output. .. function:: void arb_poly_integral(arb_poly_t res, const arb_poly_t poly, slong prec) Sets *res* to the integral of *poly*. Transforms ------------------------------------------------------------------------------- .. function:: void _arb_poly_borel_transform(arb_ptr res, arb_srcptr poly, slong len, slong prec) .. function:: void arb_poly_borel_transform(arb_poly_t res, const arb_poly_t poly, slong prec) Computes the Borel transform of the input polynomial, mapping `\sum_k a_k x^k` to `\sum_k (a_k / k!) x^k`. The underscore method allows aliasing. .. function:: void _arb_poly_inv_borel_transform(arb_ptr res, arb_srcptr poly, slong len, slong prec) .. function:: void arb_poly_inv_borel_transform(arb_poly_t res, const arb_poly_t poly, slong prec) Computes the inverse Borel transform of the input polynomial, mapping `\sum_k a_k x^k` to `\sum_k a_k k! x^k`. The underscore method allows aliasing. .. function:: void _arb_poly_binomial_transform_basecase(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec) .. function:: void arb_poly_binomial_transform_basecase(arb_poly_t b, const arb_poly_t a, slong len, slong prec) .. function:: void _arb_poly_binomial_transform_convolution(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec) .. function:: void arb_poly_binomial_transform_convolution(arb_poly_t b, const arb_poly_t a, slong len, slong prec) .. function:: void _arb_poly_binomial_transform(arb_ptr b, arb_srcptr a, slong alen, slong len, slong prec) .. function:: void arb_poly_binomial_transform(arb_poly_t b, const arb_poly_t a, slong len, slong prec) Computes the binomial transform of the input polynomial, truncating the output to length *len*. The binomial transform maps the coefficients `a_k` in the input polynomial to the coefficients `b_k` in the output polynomial via `b_n = \sum_{k=0}^n (-1)^k {n \choose k} a_k`. The binomial transform is equivalent to the power series composition `f(x) \to (1-x)^{-1} f(x/(x-1))`, and is its own inverse. The *basecase* version evaluates coefficients one by one from the definition, generating the binomial coefficients by a recurrence relation. The *convolution* version uses the identity `T(f(x)) = B^{-1}(e^x B(f(-x)))` where `T` denotes the binomial transform operator and `B` denotes the Borel transform operator. This only costs a single polynomial multiplication, plus some scalar operations. The default version automatically chooses an algorithm. The underscore methods do not support aliasing, and assume that the lengths are nonzero. .. function:: void _arb_poly_graeffe_transform(arb_ptr b, arb_srcptr a, slong len, slong prec) .. function:: void arb_poly_graeffe_transform(arb_poly_t b, arb_poly_t a, slong prec) Computes the Graeffe transform of input polynomial. The Graeffe transform `G` of a polynomial `P` is defined through the equation `G(x^2) = \pm P(x)P(-x)`. The sign is given by `(-1)^d`, where `d = deg(P)`. The Graeffe transform has the property that its roots are exactly the squares of the roots of P. The underscore method assumes that *a* and *b* are initialized, *a* is of length *len*, and *b* is of length at least *len*. Both methods allow aliasing. Powers and elementary functions ------------------------------------------------------------------------------- .. function:: void _arb_poly_pow_ui_trunc_binexp(arb_ptr res, arb_srcptr f, slong flen, ulong exp, slong len, slong prec) Sets *{res, len}* to *{f, flen}* raised to the power *exp*, truncated to length *len*. Requires that *len* is no longer than the length of the power as computed without truncation (i.e. no zero-padding is performed). Does not support aliasing of the input and output, and requires that *flen* and *len* are positive. Uses binary exponentiation. .. function:: void arb_poly_pow_ui_trunc_binexp(arb_poly_t res, const arb_poly_t poly, ulong exp, slong len, slong prec) Sets *res* to *poly* raised to the power *exp*, truncated to length *len*. Uses binary exponentiation. .. function:: void _arb_poly_pow_ui(arb_ptr res, arb_srcptr f, slong flen, ulong exp, slong prec) Sets *res* to *{f, flen}* raised to the power *exp*. Does not support aliasing of the input and output, and requires that *flen* is positive. .. function:: void arb_poly_pow_ui(arb_poly_t res, const arb_poly_t poly, ulong exp, slong prec) Sets *res* to *poly* raised to the power *exp*. .. function:: void _arb_poly_pow_series(arb_ptr h, arb_srcptr f, slong flen, arb_srcptr g, slong glen, slong len, slong prec) Sets *{h, len}* to the power series `f(x)^{g(x)} = \exp(g(x) \log f(x))` truncated to length *len*. This function detects special cases such as *g* being an exact small integer or `\pm 1/2`, and computes such powers more efficiently. This function does not support aliasing of the output with either of the input operands. It requires that all lengths are positive, and assumes that *flen* and *glen* do not exceed *len*. .. function:: void arb_poly_pow_series(arb_poly_t h, const arb_poly_t f, const arb_poly_t g, slong len, slong prec) Sets *h* to the power series `f(x)^{g(x)} = \exp(g(x) \log f(x))` truncated to length *len*. This function detects special cases such as *g* being an exact small integer or `\pm 1/2`, and computes such powers more efficiently. .. function:: void _arb_poly_pow_arb_series(arb_ptr h, arb_srcptr f, slong flen, const arb_t g, slong len, slong prec) Sets *{h, len}* to the power series `f(x)^g = \exp(g \log f(x))` truncated to length *len*. This function detects special cases such as *g* being an exact small integer or `\pm 1/2`, and computes such powers more efficiently. This function does not support aliasing of the output with either of the input operands. It requires that all lengths are positive, and assumes that *flen* does not exceed *len*. .. function:: void arb_poly_pow_arb_series(arb_poly_t h, const arb_poly_t f, const arb_t g, slong len, slong prec) Sets *h* to the power series `f(x)^g = \exp(g \log f(x))` truncated to length *len*. .. function:: void _arb_poly_sqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sqrt_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) Sets *g* to the power series square root of *h*, truncated to length *n*. Uses division-free Newton iteration for the reciprocal square root, followed by a multiplication. The underscore method does not support aliasing of the input and output arrays. It requires that *hlen* and *n* are greater than zero. .. function:: void _arb_poly_rsqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_rsqrt_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) Sets *g* to the reciprocal power series square root of *h*, truncated to length *n*. Uses division-free Newton iteration. The underscore method does not support aliasing of the input and output arrays. It requires that *hlen* and *n* are greater than zero. .. function:: void _arb_poly_log_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_log_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) Sets *res* to the power series logarithm of *f*, truncated to length *n*. Uses the formula `\log(f(x)) = \int f'(x) / f(x) dx`, adding the logarithm of the constant term in *f* as the constant of integration. The underscore method supports aliasing of the input and output arrays. It requires that *flen* and *n* are greater than zero. .. function:: void _arb_poly_log1p_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_log1p_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) Computes the power series `\log(1+f)`, with better accuracy when the constant term of *f* is small. .. function:: void _arb_poly_atan_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_atan_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) .. function:: void _arb_poly_asin_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_asin_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) .. function:: void _arb_poly_acos_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) .. function:: void arb_poly_acos_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec) Sets *res* respectively to the power series inverse tangent, inverse sine and inverse cosine of *f*, truncated to length *n*. Uses the formulas .. math :: \tan^{-1}(f(x)) = \int f'(x) / (1+f(x)^2) dx, \sin^{-1}(f(x)) = \int f'(x) / (1-f(x)^2)^{1/2} dx, \cos^{-1}(f(x)) = -\int f'(x) / (1-f(x)^2)^{1/2} dx, adding the inverse function of the constant term in *f* as the constant of integration. The underscore methods supports aliasing of the input and output arrays. They require that *flen* and *n* are greater than zero. .. function:: void _arb_poly_exp_series_basecase(arb_ptr f, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_exp_series_basecase(arb_poly_t f, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_exp_series(arb_ptr f, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_exp_series(arb_poly_t f, const arb_poly_t h, slong n, slong prec) Sets `f` to the power series exponential of `h`, truncated to length `n`. The basecase version uses a simple recurrence for the coefficients, requiring `O(nm)` operations where `m` is the length of `h`. The main implementation uses Newton iteration, starting from a small number of terms given by the basecase algorithm. The complexity is `O(M(n))`. Redundant operations in the Newton iteration are avoided by using the scheme described in [HZ2004]_. The underscore methods support aliasing and allow the input to be shorter than the output, but require the lengths to be nonzero. .. function:: void _arb_poly_sin_cos_series_basecase(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec, int times_pi) .. function:: void arb_poly_sin_cos_series_basecase(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec, int times_pi) .. function:: void _arb_poly_sin_cos_series_tangent(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec, int times_pi) .. function:: void arb_poly_sin_cos_series_tangent(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec, int times_pi) .. function:: void _arb_poly_sin_cos_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sin_cos_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) Sets *s* and *c* to the power series sine and cosine of *h*, computed simultaneously. The *basecase* version uses a simple recurrence for the coefficients, requiring `O(nm)` operations where `m` is the length of `h`. The *tangent* version uses the tangent half-angle formulas to compute the sine and cosine via :func:`_arb_poly_tan_series`. This requires `O(M(n))` operations. When `h = h_0 + h_1` where the constant term `h_0` is nonzero, the evaluation is done as `\sin(h_0 + h_1) = \cos(h_0) \sin(h_1) + \sin(h_0) \cos(h_1)`, `\cos(h_0 + h_1) = \cos(h_0) \cos(h_1) - \sin(h_0) \sin(h_1)`, to improve accuracy and avoid dividing by zero at the poles of the tangent function. The default version automatically selects between the *basecase* and *tangent* algorithms depending on the input. The *basecase* and *tangent* versions take a flag *times_pi* specifying that the input is to be multiplied by `\pi`. The underscore methods support aliasing and require the lengths to be nonzero. .. function:: void _arb_poly_sin_series(arb_ptr s, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sin_series(arb_poly_t s, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_cos_series(arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_cos_series(arb_poly_t c, const arb_poly_t h, slong n, slong prec) Respectively evaluates the power series sine or cosine. These functions simply wrap :func:`_arb_poly_sin_cos_series`. The underscore methods support aliasing and require the lengths to be nonzero. .. function:: void _arb_poly_tan_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) .. function:: void arb_poly_tan_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) Sets *g* to the power series tangent of *h*. For small *n* takes the quotient of the sine and cosine as computed using the basecase algorithm. For large *n*, uses Newton iteration to invert the inverse tangent series. The complexity is `O(M(n))`. The underscore version does not support aliasing, and requires the lengths to be nonzero. .. function:: void _arb_poly_sin_cos_pi_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sin_cos_pi_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_sin_pi_series(arb_ptr s, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sin_pi_series(arb_poly_t s, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_cos_pi_series(arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_cos_pi_series(arb_poly_t c, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_cot_pi_series(arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_cot_pi_series(arb_poly_t c, const arb_poly_t h, slong n, slong prec) Compute the respective trigonometric functions of the input multiplied by `\pi`. .. function:: void _arb_poly_sinh_cosh_series_basecase(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sinh_cosh_series_basecase(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_sinh_cosh_series_exponential(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sinh_cosh_series_exponential(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_sinh_cosh_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sinh_cosh_series(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_sinh_series(arb_ptr s, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sinh_series(arb_poly_t s, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_cosh_series(arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_cosh_series(arb_poly_t c, const arb_poly_t h, slong n, slong prec) Sets *s* and *c* respectively to the hyperbolic sine and cosine of the power series *h*, truncated to length *n*. The implementations mirror those for sine and cosine, except that the *exponential* version computes both functions using the exponential function instead of the hyperbolic tangent. .. function:: void _arb_poly_sinc_series(arb_ptr s, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sinc_series(arb_poly_t s, const arb_poly_t h, slong n, slong prec) Sets *c* to the sinc function of the power series *h*, truncated to length *n*. .. function:: void _arb_poly_sinc_pi_series(arb_ptr s, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_sinc_pi_series(arb_poly_t s, const arb_poly_t h, slong n, slong prec) Compute the sinc function of the input multiplied by `\pi`. Lambert W function ------------------------------------------------------------------------------- .. function:: void _arb_poly_lambertw_series(arb_ptr res, arb_srcptr z, slong zlen, int flags, slong len, slong prec) .. function:: void arb_poly_lambertw_series(arb_poly_t res, const arb_poly_t z, int flags, slong len, slong prec) Sets *res* to the Lambert W function of the power series *z*. If *flags* is 0, the principal branch is computed; if *flags* is 1, the second real branch `W_{-1}(z)` is computed. The underscore method allows aliasing, but assumes that the lengths are nonzero. Gamma function and factorials ------------------------------------------------------------------------------- .. function:: void _arb_poly_gamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_gamma_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_rgamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_rgamma_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_lgamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_lgamma_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec) .. function:: void _arb_poly_digamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_digamma_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec) Sets *res* to the series expansion of `\Gamma(h(x))`, `1/\Gamma(h(x))`, or `\log \Gamma(h(x))`, `\psi(h(x))`, truncated to length *n*. These functions first generate the Taylor series at the constant term of *h*, and then call :func:`_arb_poly_compose_series`. The Taylor coefficients are generated using the Riemann zeta function if the constant term of *h* is a small integer, and with Stirling's series otherwise. The underscore methods support aliasing of the input and output arrays, and require that *hlen* and *n* are greater than zero. .. function:: void _arb_poly_rising_ui_series(arb_ptr res, arb_srcptr f, slong flen, ulong r, slong trunc, slong prec) .. function:: void arb_poly_rising_ui_series(arb_poly_t res, const arb_poly_t f, ulong r, slong trunc, slong prec) Sets *res* to the rising factorial `(f) (f+1) (f+2) \cdots (f+r-1)`, truncated to length *trunc*. The underscore method assumes that *flen*, *r* and *trunc* are at least 1, and does not support aliasing. Uses binary splitting. Zeta function ------------------------------------------------------------------------------- .. function:: void arb_poly_zeta_series(arb_poly_t res, const arb_poly_t s, const arb_t a, int deflate, slong n, slong prec) Sets *res* to the Hurwitz zeta function `\zeta(s,a)` where `s` a power series and `a` is a constant, truncated to length *n*. To evaluate the usual Riemann zeta function, set `a = 1`. If *deflate* is nonzero, evaluates `\zeta(s,a) + 1/(1-s)`, which is well-defined as a limit when the constant term of `s` is 1. In particular, expanding `\zeta(s,a) + 1/(1-s)` with `s = 1+x` gives the Stieltjes constants .. math :: \sum_{k=0}^{n-1} \frac{(-1)^k}{k!} \gamma_k(a) x^k. If `a = 1`, this implementation uses the reflection formula if the midpoint of the constant term of `s` is negative. .. function:: void _arb_poly_riemann_siegel_theta_series(arb_ptr res, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_riemann_siegel_theta_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec) Sets *res* to the series expansion of the Riemann-Siegel theta function .. math :: \theta(h) = \arg \left(\Gamma\left(\frac{2ih+1}{4}\right)\right) - \frac{\log \pi}{2} h where the argument of the gamma function is chosen continuously as the imaginary part of the log gamma function. The underscore method does not support aliasing of the input and output arrays, and requires that the lengths are greater than zero. .. function:: void _arb_poly_riemann_siegel_z_series(arb_ptr res, arb_srcptr h, slong hlen, slong n, slong prec) .. function:: void arb_poly_riemann_siegel_z_series(arb_poly_t res, const arb_poly_t h, slong n, slong prec) Sets *res* to the series expansion of the Riemann-Siegel Z-function .. math :: Z(h) = e^{i\theta(h)} \zeta(1/2+ih). The zeros of the Z-function on the real line precisely correspond to the imaginary parts of the zeros of the Riemann zeta function on the critical line. The underscore method supports aliasing of the input and output arrays, and requires that the lengths are greater than zero. Root-finding ------------------------------------------------------------------------------- .. function:: void _arb_poly_root_bound_fujiwara(mag_t bound, arb_srcptr poly, slong len) .. function:: void arb_poly_root_bound_fujiwara(mag_t bound, arb_poly_t poly) Sets *bound* to an upper bound for the magnitude of all the complex roots of *poly*. Uses Fujiwara's bound .. math :: 2 \max \left\{\left|\frac{a_{n-1}}{a_n}\right|, \left|\frac{a_{n-2}}{a_n}\right|^{1/2}, \cdots, \left|\frac{a_1}{a_n}\right|^{1/(n-1)}, \left|\frac{a_0}{2a_n}\right|^{1/n} \right\} where `a_0, \ldots, a_n` are the coefficients of *poly*. .. function:: void _arb_poly_newton_convergence_factor(arf_t convergence_factor, arb_srcptr poly, slong len, const arb_t convergence_interval, slong prec) Given an interval `I` specified by *convergence_interval*, evaluates a bound for `C = \sup_{t,u \in I} \frac{1}{2} |f''(t)| / |f'(u)|`, where `f` is the polynomial defined by the coefficients *{poly, len}*. The bound is obtained by evaluating `f'(I)` and `f''(I)` directly. If `f` has large coefficients, `I` must be extremely precise in order to get a finite factor. .. function:: int _arb_poly_newton_step(arb_t xnew, arb_srcptr poly, slong len, const arb_t x, const arb_t convergence_interval, const arf_t convergence_factor, slong prec) Performs a single step with Newton's method. The input consists of the polynomial `f` specified by the coefficients *{poly, len}*, an interval `x = [m-r, m+r]` known to contain a single root of `f`, an interval `I` (*convergence_interval*) containing `x` with an associated bound (*convergence_factor*) for `C = \sup_{t,u \in I} \frac{1}{2} |f''(t)| / |f'(u)|`, and a working precision *prec*. The Newton update consists of setting `x' = [m'-r', m'+r']` where `m' = m - f(m) / f'(m)` and `r' = C r^2`. The expression `m - f(m) / f'(m)` is evaluated using ball arithmetic at a working precision of *prec* bits, and the rounding error during this evaluation is accounted for in the output. We now check that `x' \in I` and `m' < m`. If both conditions are satisfied, we set *xnew* to `x'` and return nonzero. If either condition fails, we set *xnew* to `x` and return zero, indicating that no progress was made. .. function:: void _arb_poly_newton_refine_root(arb_t r, arb_srcptr poly, slong len, const arb_t start, const arb_t convergence_interval, const arf_t convergence_factor, slong eval_extra_prec, slong prec) Refines a precise estimate of a polynomial root to high precision by performing several Newton steps, using nearly optimally chosen doubling precision steps. The inputs are defined as for *_arb_poly_newton_step*, except for the precision parameters: *prec* is the target accuracy and *eval_extra_prec* is the estimated number of guard bits that need to be added to evaluate the polynomial accurately close to the root (typically, if the polynomial has large coefficients of alternating signs, this needs to be approximately the bit size of the coefficients). Other special polynomials ------------------------------------------------------------------------------- .. function:: void _arb_poly_swinnerton_dyer_ui(arb_ptr poly, ulong n, slong trunc, slong prec) .. function:: void arb_poly_swinnerton_dyer_ui(arb_poly_t poly, ulong n, slong prec) Computes the Swinnerton-Dyer polynomial `S_n`, which has degree `2^n` and is the rational minimal polynomial of the sum of the square roots of the first *n* prime numbers. If *prec* is set to zero, a precision is chosen automatically such that :func:`arb_poly_get_unique_fmpz_poly` should be successful. Otherwise a working precision of *prec* bits is used. The underscore version accepts an additional *trunc* parameter. Even when computing a truncated polynomial, the array *poly* must have room for `2^n + 1` coefficients, used as temporary space. arb-2.22.1/doc/source/arf.rst000066400000000000000000000746471417376376500157560ustar00rootroot00000000000000.. _arf: **arf.h** -- arbitrary-precision floating-point numbers =============================================================================== A variable of type :type:`arf_t` holds an arbitrary-precision binary floating-point number: that is, a rational number of the form `x \cdot 2^y` where `x, y \in \mathbb{Z}` and `x` is odd, or one of the special values zero, plus infinity, minus infinity, or NaN (not-a-number). There is currently no support for negative zero, unsigned infinity, or a NaN with a payload. The *exponent* of a finite and nonzero floating-point number can be defined in different ways: for example, as the component *y* above, or as the unique integer *e* such that `x \cdot 2^y = m \cdot 2^e` where `0.5 \le |m| < 1`. The internal representation of an :type:`arf_t` stores the exponent in the latter format. Except where otherwise noted, functions have the following semantics: * Functions taking *prec* and *rnd* parameters at the end of the argument list and returning an ``int`` flag round the result in the output variable to *prec* bits in the direction specified by *rnd*. The return flag is 0 if the result is exact (not rounded) and 1 if the result is inexact (rounded). Correct rounding is guaranteed: the result is the floating-point number obtained by viewing the inputs as exact numbers, in principle carrying out the mathematical operation exactly, and rounding the resulting real number to the nearest representable floating-point number whose mantissa has at most the specified number of bits, in the specified direction of rounding. In particular, the error is at most 1 ulp with directed rounding modes and 0.5 ulp when rounding to nearest. * Other functions perform the operation exactly. Since exponents are bignums, overflow or underflow cannot occur. Types, macros and constants ------------------------------------------------------------------------------- .. type:: arf_struct .. type:: arf_t An :type:`arf_struct` contains four words: an :type:`fmpz` exponent (*exp*), a *size* field tracking the number of limbs used (one bit of this field is also used for the sign of the number), and two more words. The last two words hold the value directly if there are at most two limbs, and otherwise contain one *alloc* field (tracking the total number of allocated limbs, not all of which might be used) and a pointer to the actual limbs. Thus, up to 128 bits on a 64-bit machine and 64 bits on a 32-bit machine, no space outside of the :type:`arf_struct` is used. An :type:`arf_t` is defined as an array of length one of type :type:`arf_struct`, permitting an :type:`arf_t` to be passed by reference. .. type:: arf_rnd_t Specifies the rounding mode for the result of an approximate operation. .. macro:: ARF_RND_DOWN Specifies that the result of an operation should be rounded to the nearest representable number in the direction towards zero. .. macro:: ARF_RND_UP Specifies that the result of an operation should be rounded to the nearest representable number in the direction away from zero. .. macro:: ARF_RND_FLOOR Specifies that the result of an operation should be rounded to the nearest representable number in the direction towards minus infinity. .. macro:: ARF_RND_CEIL Specifies that the result of an operation should be rounded to the nearest representable number in the direction towards plus infinity. .. macro:: ARF_RND_NEAR Specifies that the result of an operation should be rounded to the nearest representable number, rounding to even if there is a tie between two values. .. macro:: ARF_PREC_EXACT If passed as the precision parameter to a function, indicates that no rounding is to be performed. **Warning**: use of this value is unsafe in general. It must only be passed as input under the following two conditions: * The operation in question can inherently be viewed as an exact operation in `\mathbb{Z}[\tfrac{1}{2}]` for all possible inputs, provided that the precision is large enough. Examples include addition, multiplication, conversion from integer types to arbitrary-precision floating-point types, and evaluation of some integer-valued functions. * The exact result of the operation will certainly fit in memory. Note that, for example, adding two numbers whose exponents are far apart can easily produce an exact result that is far too large to store in memory. The typical use case is to work with small integer values, double precision constants, and the like. It is also useful when writing test code. If in doubt, simply try with some convenient high precision instead of using this special value, and check that the result is exact. Memory management ------------------------------------------------------------------------------- .. function:: void arf_init(arf_t x) Initializes the variable *x* for use. Its value is set to zero. .. function:: void arf_clear(arf_t x) Clears the variable *x*, freeing or recycling its allocated memory. .. function:: slong arf_allocated_bytes(const arf_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(arf_struct)`` to get the size of the object as a whole. Special values ------------------------------------------------------------------------------- .. function:: void arf_zero(arf_t res) .. function:: void arf_one(arf_t res) .. function:: void arf_pos_inf(arf_t res) .. function:: void arf_neg_inf(arf_t res) .. function:: void arf_nan(arf_t res) Sets *res* respectively to 0, 1, `+\infty`, `-\infty`, NaN. .. function:: int arf_is_zero(const arf_t x) .. function:: int arf_is_one(const arf_t x) .. function:: int arf_is_pos_inf(const arf_t x) .. function:: int arf_is_neg_inf(const arf_t x) .. function:: int arf_is_nan(const arf_t x) Returns nonzero iff *x* respectively equals 0, 1, `+\infty`, `-\infty`, NaN. .. function:: int arf_is_inf(const arf_t x) Returns nonzero iff *x* equals either `+\infty` or `-\infty`. .. function:: int arf_is_normal(const arf_t x) Returns nonzero iff *x* is a finite, nonzero floating-point value, i.e. not one of the special values 0, `+\infty`, `-\infty`, NaN. .. function:: int arf_is_special(const arf_t x) Returns nonzero iff *x* is one of the special values 0, `+\infty`, `-\infty`, NaN, i.e. not a finite, nonzero floating-point value. .. function:: int arf_is_finite(const arf_t x) Returns nonzero iff *x* is a finite floating-point value, i.e. not one of the values `+\infty`, `-\infty`, NaN. (Note that this is not equivalent to the negation of :func:`arf_is_inf`.) Assignment, rounding and conversions ------------------------------------------------------------------------------- .. function:: void arf_set(arf_t res, const arf_t x) .. function:: void arf_set_mpz(arf_t res, const mpz_t x) .. function:: void arf_set_fmpz(arf_t res, const fmpz_t x) .. function:: void arf_set_ui(arf_t res, ulong x) .. function:: void arf_set_si(arf_t res, slong x) .. function:: void arf_set_mpfr(arf_t res, const mpfr_t x) .. function:: void arf_set_fmpr(arf_t res, const fmpr_t x) .. function:: void arf_set_d(arf_t res, double x) Sets *res* to the exact value of *x*. .. function:: void arf_swap(arf_t x, arf_t y) Swaps *x* and *y* efficiently. .. function:: void arf_init_set_ui(arf_t res, ulong x) .. function:: void arf_init_set_si(arf_t res, slong x) Initializes *res* and sets it to *x* in a single operation. .. function:: int arf_set_round(arf_t res, const arf_t x, slong prec, arf_rnd_t rnd) .. function:: int arf_set_round_si(arf_t res, slong x, slong prec, arf_rnd_t rnd) .. function:: int arf_set_round_ui(arf_t res, ulong x, slong prec, arf_rnd_t rnd) .. function:: int arf_set_round_mpz(arf_t res, const mpz_t x, slong prec, arf_rnd_t rnd) .. function:: int arf_set_round_fmpz(arf_t res, const fmpz_t x, slong prec, arf_rnd_t rnd) Sets *res* to *x*, rounded to *prec* bits in the direction specified by *rnd*. .. function:: void arf_set_si_2exp_si(arf_t res, slong m, slong e) .. function:: void arf_set_ui_2exp_si(arf_t res, ulong m, slong e) .. function:: void arf_set_fmpz_2exp(arf_t res, const fmpz_t m, const fmpz_t e) Sets *res* to `m \cdot 2^e`. .. function:: int arf_set_round_fmpz_2exp(arf_t res, const fmpz_t x, const fmpz_t e, slong prec, arf_rnd_t rnd) Sets *res* to `x \cdot 2^e`, rounded to *prec* bits in the direction specified by *rnd*. .. function:: void arf_get_fmpz_2exp(fmpz_t m, fmpz_t e, const arf_t x) Sets *m* and *e* to the unique integers such that `x = m \cdot 2^e` and *m* is odd, provided that *x* is a nonzero finite fraction. If *x* is zero, both *m* and *e* are set to zero. If *x* is infinite or NaN, the result is undefined. .. function:: void arf_frexp(arf_t m, fmpz_t e, const arf_t x) Writes *x* as `m \cdot 2^e`, where `0.5 \le |m| < 1` if *x* is a normal value. If *x* is a special value, copies this to *m* and sets *e* to zero. Note: for the inverse operation (*ldexp*), use :func:`arf_mul_2exp_fmpz`. .. function:: double arf_get_d(const arf_t x, arf_rnd_t rnd) Returns *x* rounded to a double in the direction specified by *rnd*. This method rounds correctly when overflowing or underflowing the double exponent range (this was not the case in an earlier version). .. function:: void arf_get_fmpr(fmpr_t res, const arf_t x) Sets *res* exactly to *x*. .. function:: int arf_get_mpfr(mpfr_t res, const arf_t x, mpfr_rnd_t rnd) Sets the MPFR variable *res* to the value of *x*. If the precision of *x* is too small to allow *res* to be represented exactly, it is rounded in the specified MPFR rounding mode. The return value (-1, 0 or 1) indicates the direction of rounding, following the convention of the MPFR library. If *x* has an exponent too large or small to fit in the MPFR type, the result overflows to an infinity or underflows to a (signed) zero, and the corresponding MPFR exception flags are set. .. function:: int arf_get_fmpz(fmpz_t res, const arf_t x, arf_rnd_t rnd) Sets *res* to *x* rounded to the nearest integer in the direction specified by *rnd*. If rnd is *ARF_RND_NEAR*, rounds to the nearest even integer in case of a tie. Returns inexact (beware: accordingly returns whether *x* is *not* an integer). This method aborts if *x* is infinite or NaN, or if the exponent of *x* is so large that allocating memory for the result fails. Warning: this method will allocate a huge amount of memory to store the result if the exponent of *x* is huge. Memory allocation could succeed even if the required space is far larger than the physical memory available on the machine, resulting in swapping. It is recommended to check that *x* is within a reasonable range before calling this method. .. function:: slong arf_get_si(const arf_t x, arf_rnd_t rnd) Returns *x* rounded to the nearest integer in the direction specified by *rnd*. If *rnd* is *ARF_RND_NEAR*, rounds to the nearest even integer in case of a tie. Aborts if *x* is infinite, NaN, or the value is too large to fit in a slong. .. function:: int arf_get_fmpz_fixed_fmpz(fmpz_t res, const arf_t x, const fmpz_t e) .. function:: int arf_get_fmpz_fixed_si(fmpz_t res, const arf_t x, slong e) Converts *x* to a mantissa with predetermined exponent, i.e. sets *res* to an integer *y* such that `y \times 2^e \approx x`, truncating if necessary. Returns 0 if exact and 1 if truncation occurred. The warnings for :func:`arf_get_fmpz` apply. .. function:: void arf_floor(arf_t res, const arf_t x) .. function:: void arf_ceil(arf_t res, const arf_t x) Sets *res* to `\lfloor x \rfloor` and `\lceil x \rceil` respectively. The result is always represented exactly, requiring no more bits to store than the input. To round the result to a floating-point number with a lower precision, call :func:`arf_set_round` afterwards. .. function:: void arf_get_fmpq(fmpq_t res, const arf_t x) Set *res* to the exact rational value of *x*. This method aborts if *x* is infinite or NaN, or if the exponent of *x* is so large that allocating memory for the result fails. Comparisons and bounds ------------------------------------------------------------------------------- .. function:: int arf_equal(const arf_t x, const arf_t y) int arf_equal_si(const arf_t x, slong y) int arf_equal_ui(const arf_t x, ulong y) int arf_equal_d(const arf_t x, double y) Returns nonzero iff *x* and *y* are exactly equal. NaN is not treated specially, i.e. NaN compares as equal to itself. For comparison with a *double*, the values -0 and +0 are both treated as zero, and all NaN values are treated as identical. .. function:: int arf_cmp(const arf_t x, const arf_t y) .. function:: int arf_cmp_si(const arf_t x, slong y) .. function:: int arf_cmp_ui(const arf_t x, ulong y) .. function:: int arf_cmp_d(const arf_t x, double y) Returns negative, zero, or positive, depending on whether *x* is respectively smaller, equal, or greater compared to *y*. Comparison with NaN is undefined. .. function:: int arf_cmpabs(const arf_t x, const arf_t y) .. function:: int arf_cmpabs_ui(const arf_t x, ulong y) .. function:: int arf_cmpabs_d(const arf_t x, double y) .. function:: int arf_cmpabs_mag(const arf_t x, const mag_t y) Compares the absolute values of *x* and *y*. .. function:: int arf_cmp_2exp_si(const arf_t x, slong e) .. function:: int arf_cmpabs_2exp_si(const arf_t x, slong e) Compares *x* (respectively its absolute value) with `2^e`. .. function:: int arf_sgn(const arf_t x) Returns `-1`, `0` or `+1` according to the sign of *x*. The sign of NaN is undefined. .. function:: void arf_min(arf_t res, const arf_t a, const arf_t b) .. function:: void arf_max(arf_t res, const arf_t a, const arf_t b) Sets *res* respectively to the minimum and the maximum of *a* and *b*. .. function:: slong arf_bits(const arf_t x) Returns the number of bits needed to represent the absolute value of the mantissa of *x*, i.e. the minimum precision sufficient to represent *x* exactly. Returns 0 if *x* is a special value. .. function:: int arf_is_int(const arf_t x) Returns nonzero iff *x* is integer-valued. .. function:: int arf_is_int_2exp_si(const arf_t x, slong e) Returns nonzero iff *x* equals `n 2^e` for some integer *n*. .. function:: void arf_abs_bound_lt_2exp_fmpz(fmpz_t res, const arf_t x) Sets *res* to the smallest integer *b* such that `|x| < 2^b`. If *x* is zero, infinity or NaN, the result is undefined. .. function:: void arf_abs_bound_le_2exp_fmpz(fmpz_t res, const arf_t x) Sets *res* to the smallest integer *b* such that `|x| \le 2^b`. If *x* is zero, infinity or NaN, the result is undefined. .. function:: slong arf_abs_bound_lt_2exp_si(const arf_t x) Returns the smallest integer *b* such that `|x| < 2^b`, clamping the result to lie between -*ARF_PREC_EXACT* and *ARF_PREC_EXACT* inclusive. If *x* is zero, -*ARF_PREC_EXACT* is returned, and if *x* is infinity or NaN, *ARF_PREC_EXACT* is returned. Magnitude functions ------------------------------------------------------------------------------- .. function:: void arf_get_mag(mag_t res, const arf_t x) Sets *res* to an upper bound for the absolute value of *x*. .. function:: void arf_get_mag_lower(mag_t res, const arf_t x) Sets *res* to a lower bound for the absolute value of *x*. .. function:: void arf_set_mag(arf_t res, const mag_t x) Sets *res* to *x*. This operation is exact. .. function:: void mag_init_set_arf(mag_t res, const arf_t x) Initializes *res* and sets it to an upper bound for *x*. .. function:: void mag_fast_init_set_arf(mag_t res, const arf_t x) Initializes *res* and sets it to an upper bound for *x*. Assumes that the exponent of *res* is small (this function is unsafe). .. function:: void arf_mag_set_ulp(mag_t res, const arf_t x, slong prec) Sets *res* to the magnitude of the unit in the last place (ulp) of *x* at precision *prec*. .. function:: void arf_mag_add_ulp(mag_t res, const mag_t x, const arf_t y, slong prec) Sets *res* to an upper bound for the sum of *x* and the magnitude of the unit in the last place (ulp) of *y* at precision *prec*. .. function:: void arf_mag_fast_add_ulp(mag_t res, const mag_t x, const arf_t y, slong prec) Sets *res* to an upper bound for the sum of *x* and the magnitude of the unit in the last place (ulp) of *y* at precision *prec*. Assumes that all exponents are small. Shallow assignment ------------------------------------------------------------------------------- .. function:: void arf_init_set_shallow(arf_t z, const arf_t x) .. function:: void arf_init_set_mag_shallow(arf_t z, const mag_t x) Initializes *z* to a shallow copy of *x*. A shallow copy just involves copying struct data (no heap allocation is performed). The target variable *z* may not be cleared or modified in any way (it can only be used as constant input to functions), and may not be used after *x* has been cleared. Moreover, after *x* has been assigned shallowly to *z*, no modification of *x* is permitted as slong as *z* is in use. .. function:: void arf_init_neg_shallow(arf_t z, const arf_t x) .. function:: void arf_init_neg_mag_shallow(arf_t z, const mag_t x) Initializes *z* shallowly to the negation of *x*. Random number generation ------------------------------------------------------------------------------- .. function:: void arf_randtest(arf_t res, flint_rand_t state, slong bits, slong mag_bits) Generates a finite random number whose mantissa has precision at most *bits* and whose exponent has at most *mag_bits* bits. The values are distributed non-uniformly: special bit patterns are generated with high probability in order to allow the test code to exercise corner cases. .. function:: void arf_randtest_not_zero(arf_t res, flint_rand_t state, slong bits, slong mag_bits) Identical to :func:`arf_randtest`, except that zero is never produced as an output. .. function:: void arf_randtest_special(arf_t res, flint_rand_t state, slong bits, slong mag_bits) Identical to :func:`arf_randtest`, except that the output occasionally is set to an infinity or NaN. .. function:: void arf_urandom(arf_t res, flint_rand_t state, slong bits, arf_rnd_t rnd) Sets *res* to a uniformly distributed random number in the interval `[0, 1]`. The method uses rounding from integers to floats based on the rounding mode *rnd*. Input and output ------------------------------------------------------------------------------- .. function:: void arf_debug(const arf_t x) Prints information about the internal representation of *x*. .. function:: void arf_print(const arf_t x) Prints *x* as an integer mantissa and exponent. .. function:: void arf_printd(const arf_t x, slong d) Prints *x* as a decimal floating-point number, rounding to *d* digits. Rounding is faithful (at most 1 ulp error). .. function:: char * arf_get_str(const arf_t x, slong d) Returns *x* as a decimal floating-point number, rounding to *d* digits. Rounding is faithful (at most 1 ulp error). .. function:: void arf_fprint(FILE * file, const arf_t x) Prints *x* as an integer mantissa and exponent to the stream *file*. .. function:: void arf_fprintd(FILE * file, const arf_t y, slong d) Prints *x* as a decimal floating-point number to the stream *file*, rounding to *d* digits. Rounding is faithful (at most 1 ulp error). .. function:: char * arf_dump_str(const arf_t x) Allocates a string and writes a binary representation of *x* to it that can be read by :func:`arf_load_str`. The returned string needs to be deallocated with *flint_free*. .. function:: int arf_load_str(arf_t x, const char * str) Parses *str* into *x*. Returns a nonzero value if *str* is not formatted correctly. .. function:: int arf_dump_file(FILE * stream, const arf_t x) Writes a binary representation of *x* to *stream* that can be read by :func:`arf_load_file`. Returns a nonzero value if the data could not be written. .. function:: int arf_load_file(arf_t x, FILE * stream) Reads *x* from *stream*. Returns a nonzero value if the data is not formatted correctly or the read failed. Note that the data is assumed to be delimited by a whitespace or end-of-file, i.e., when writing multiple values with :func:`arf_dump_file` make sure to insert a whitespace to separate consecutive values. Addition and multiplication ------------------------------------------------------------------------------- .. function:: void arf_abs(arf_t res, const arf_t x) Sets *res* to the absolute value of *x* exactly. .. function:: void arf_neg(arf_t res, const arf_t x) Sets *res* to `-x` exactly. .. function:: int arf_neg_round(arf_t res, const arf_t x, slong prec, arf_rnd_t rnd) Sets *res* to `-x`. .. function:: int arf_add(arf_t res, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_add_si(arf_t res, const arf_t x, slong y, slong prec, arf_rnd_t rnd) .. function:: int arf_add_ui(arf_t res, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) .. function:: int arf_add_fmpz(arf_t res, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) Sets *res* to `x + y`. .. function:: int arf_add_fmpz_2exp(arf_t res, const arf_t x, const fmpz_t y, const fmpz_t e, slong prec, arf_rnd_t rnd) Sets *res* to `x + y 2^e`. .. function:: int arf_sub(arf_t res, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_sub_si(arf_t res, const arf_t x, slong y, slong prec, arf_rnd_t rnd) .. function:: int arf_sub_ui(arf_t res, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) .. function:: int arf_sub_fmpz(arf_t res, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) Sets *res* to `x - y`. .. function:: void arf_mul_2exp_si(arf_t res, const arf_t x, slong e) .. function:: void arf_mul_2exp_fmpz(arf_t res, const arf_t x, const fmpz_t e) Sets *res* to `x 2^e` exactly. .. function:: int arf_mul(arf_t res, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_mul_ui(arf_t res, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) .. function:: int arf_mul_si(arf_t res, const arf_t x, slong y, slong prec, arf_rnd_t rnd) .. function:: int arf_mul_mpz(arf_t res, const arf_t x, const mpz_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_mul_fmpz(arf_t res, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) Sets *res* to `x \cdot y`. .. function:: int arf_addmul(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_addmul_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) .. function:: int arf_addmul_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd) .. function:: int arf_addmul_mpz(arf_t z, const arf_t x, const mpz_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_addmul_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) Performs a fused multiply-add `z = z + x \cdot y`, updating *z* in-place. .. function:: int arf_submul(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_submul_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) .. function:: int arf_submul_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd) .. function:: int arf_submul_mpz(arf_t z, const arf_t x, const mpz_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_submul_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) Performs a fused multiply-subtract `z = z - x \cdot y`, updating *z* in-place. .. function:: int arf_fma(arf_t res, const arf_t x, const arf_t y, const arf_t z, slong prec, arf_rnd_t rnd) Sets *res* to `x \cdot y + z`. This is equivalent to an *addmul* except that *res* and *z* can be separate variables. .. function:: int arf_sosq(arf_t res, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) Sets *res* to `x^2 + y^2`, rounded to *prec* bits in the direction specified by *rnd*. Summation ------------------------------------------------------------------------------- .. function:: int arf_sum(arf_t res, arf_srcptr terms, slong len, slong prec, arf_rnd_t rnd) Sets *res* to the sum of the array *terms* of length *len*, rounded to *prec* bits in the direction specified by *rnd*. The sum is computed as if done without any intermediate rounding error, with only a single rounding applied to the final result. Unlike repeated calls to :func:`arf_add` with infinite precision, this function does not overflow if the magnitudes of the terms are far apart. Warning: this function is implemented naively, and the running time is quadratic with respect to *len* in the worst case. Division ------------------------------------------------------------------------------- .. function:: int arf_div(arf_t res, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_div_ui(arf_t res, const arf_t x, ulong y, slong prec, arf_rnd_t rnd) .. function:: int arf_ui_div(arf_t res, ulong x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_div_si(arf_t res, const arf_t x, slong y, slong prec, arf_rnd_t rnd) .. function:: int arf_si_div(arf_t res, slong x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_div_fmpz(arf_t res, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_fmpz_div(arf_t res, const fmpz_t x, const arf_t y, slong prec, arf_rnd_t rnd) .. function:: int arf_fmpz_div_fmpz(arf_t res, const fmpz_t x, const fmpz_t y, slong prec, arf_rnd_t rnd) Sets *res* to `x / y`, rounded to *prec* bits in the direction specified by *rnd*, returning nonzero iff the operation is inexact. The result is NaN if *y* is zero. Square roots ------------------------------------------------------------------------------- .. function:: int arf_sqrt(arf_t res, const arf_t x, slong prec, arf_rnd_t rnd) .. function:: int arf_sqrt_ui(arf_t res, ulong x, slong prec, arf_rnd_t rnd) .. function:: int arf_sqrt_fmpz(arf_t res, const fmpz_t x, slong prec, arf_rnd_t rnd) Sets *res* to `\sqrt{x}`. The result is NaN if *x* is negative. .. function:: int arf_rsqrt(arf_t res, const arf_t x, slong prec, arf_rnd_t rnd) Sets *res* to `1/\sqrt{x}`. The result is NaN if *x* is negative, and `+\infty` if *x* is zero. .. function:: int arf_root(arf_t res, const arf_t x, ulong k, slong prec, arf_rnd_t rnd) Sets *res* to `x^{1/k}`. The result is NaN if *x* is negative. Warning: this function is a wrapper around the MPFR root function. It gets slow and uses much memory for large *k*. Consider working with :func:`arb_root_ui` for large *k* instead of using this function directly. Complex arithmetic ------------------------------------------------------------------------------- .. function:: int arf_complex_mul(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd) .. function:: int arf_complex_mul_fallback(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd) Computes the complex product `e + fi = (a + bi)(c + di)`, rounding both `e` and `f` correctly to *prec* bits in the direction specified by *rnd*. The first bit in the return code indicates inexactness of `e`, and the second bit indicates inexactness of `f`. If any of the components *a*, *b*, *c*, *d* is zero, two real multiplications and no additions are done. This convention is used even if any other part contains an infinity or NaN, and the behavior with infinite/NaN input is defined accordingly. The *fallback* version is implemented naively, for testing purposes. No squaring optimization is implemented. .. function:: int arf_complex_sqr(arf_t e, arf_t f, const arf_t a, const arf_t b, slong prec, arf_rnd_t rnd) Computes the complex square `e + fi = (a + bi)^2`. This function has identical semantics to :func:`arf_complex_mul` (with `c = a, b = d`), but is faster. Low-level methods ------------------------------------------------------------------------------- .. function:: int _arf_get_integer_mpn(mp_ptr y, mp_srcptr xp, mp_size_t xn, slong exp) Given a floating-point number *x* represented by *xn* limbs at *xp* and an exponent *exp*, writes the integer part of *x* to *y*, returning whether the result is inexact. The correct number of limbs is written (no limbs are written if the integer part of *x* is zero). Assumes that ``xp[0]`` is nonzero and that the top bit of ``xp[xn-1]`` is set. .. function:: int _arf_set_mpn_fixed(arf_t z, mp_srcptr xp, mp_size_t xn, mp_size_t fixn, int negative, slong prec, arf_rnd_t rnd) Sets *z* to the fixed-point number having *xn* total limbs and *fixn* fractional limbs, negated if *negative* is set, rounding *z* to *prec* bits in the direction *rnd* and returning whether the result is inexact. Both *xn* and *fixn* must be nonnegative and not so large that the bit shift would overflow an *slong*, but otherwise no assumptions are made about the input. .. function:: int _arf_set_round_ui(arf_t z, ulong x, int sgnbit, slong prec, arf_rnd_t rnd) Sets *z* to the integer *x*, negated if *sgnbit* is 1, rounded to *prec* bits in the direction specified by *rnd*. There are no assumptions on *x*. .. function:: int _arf_set_round_uiui(arf_t z, slong * fix, mp_limb_t hi, mp_limb_t lo, int sgnbit, slong prec, arf_rnd_t rnd) Sets the mantissa of *z* to the two-limb mantissa given by *hi* and *lo*, negated if *sgnbit* is 1, rounded to *prec* bits in the direction specified by *rnd*. Requires that not both *hi* and *lo* are zero. Writes the exponent shift to *fix* without writing the exponent of *z* directly. .. function:: int _arf_set_round_mpn(arf_t z, slong * exp_shift, mp_srcptr x, mp_size_t xn, int sgnbit, slong prec, arf_rnd_t rnd) Sets the mantissa of *z* to the mantissa given by the *xn* limbs in *x*, negated if *sgnbit* is 1, rounded to *prec* bits in the direction specified by *rnd*. Returns the inexact flag. Requires that *xn* is positive and that the top limb of *x* is nonzero. If *x* has leading zero bits, writes the shift to *exp_shift*. This method does not write the exponent of *z* directly. Requires that *x* does not point to the limbs of *z*. arb-2.22.1/doc/source/bernoulli.rst000066400000000000000000000122371417376376500171640ustar00rootroot00000000000000.. _bernoulli: **bernoulli.h** -- support for Bernoulli numbers =============================================================================== This module provides helper functions for exact or approximate calculation of the Bernoulli numbers, which are defined by the exponential generating function .. math :: \frac{x}{e^x-1} = \sum_{n=0}^{\infty} B_n \frac{x^n}{n!}. Efficient algorithms are implemented for both multi-evaluation and calculation of isolated Bernoulli numbers. A global (or thread-local) cache is also provided, to support fast repeated evaluation of various special functions that depend on the Bernoulli numbers (including the gamma function and the Riemann zeta function). Generation of Bernoulli numbers -------------------------------------------------------------------------------- .. type:: bernoulli_rev_t An iterator object for generating a range of even-indexed Bernoulli numbers exactly in reverse order, i.e. computing the exact fractions `B_n, B_{n-2}, B_{n-4}, \ldots, B_0`. The Bernoulli numbers are generated from scratch, i.e. no caching is performed. The Bernoulli numbers are computed by direct summation of the zeta series. This is made fast by storing a table of powers (as done by [Blo2009]_). As an optimization, we only include the odd powers, and use fixed-point arithmetic. The reverse iteration order is preferred for performance reasons, as the powers can be updated using multiplications instead of divisions, and we avoid having to periodically recompute terms to higher precision. To generate Bernoulli numbers in the forward direction without having to store all of them, one can split the desired range into smaller blocks and compute each block with a single reverse pass. .. function:: void bernoulli_rev_init(bernoulli_rev_t iter, ulong n) Initializes the iterator *iter*. The first Bernoulli number to be generated by calling :func:`bernoulli_rev_next` is `B_n`. It is assumed that `n` is even. .. function:: void bernoulli_rev_next(fmpz_t numer, fmpz_t denom, bernoulli_rev_t iter) Sets *numer* and *denom* to the exact, reduced numerator and denominator of the Bernoulli number `B_k` and advances the state of *iter* so that the next invocation generates `B_{k-2}`. .. function:: void bernoulli_rev_clear(bernoulli_rev_t iter) Frees all memory allocated internally by *iter*. Caching ------------------------------------------------------------------------------- .. var:: slong bernoulli_cache_num .. var:: fmpq * bernoulli_cache Cache of Bernoulli numbers. Uses thread-local storage if enabled in FLINT. .. function:: void bernoulli_cache_compute(slong n) Makes sure that the Bernoulli numbers up to at least `B_{n-1}` are cached. Calling :func:`flint_cleanup()` frees the cache. Bounding ------------------------------------------------------------------------------- .. function:: slong bernoulli_bound_2exp_si(ulong n) Returns an integer `b` such that `|B_n| \le 2^b`. Uses a lookup table for small `n`, and for larger `n` uses the inequality `|B_n| < 4 n! / (2 \pi)^n < 4 (n+1)^{n+1} e^{-n} / (2 \pi)^n`. Uses integer arithmetic throughout, with the bound for the logarithm being looked up from a table. If `|B_n| = 0`, returns *LONG_MIN*. Otherwise, the returned exponent `b` is never more than one percent larger than the true magnitude. This function is intended for use when `n` small enough that one might comfortably compute `B_n` exactly. It aborts if `n` is so large that internal overflow occurs. Isolated Bernoulli numbers ------------------------------------------------------------------------------- .. function:: ulong bernoulli_mod_p_harvey(ulong n, ulong p) Returns the `B_n` modulo the prime number *p*, computed using Harvey's algorithm [Har2010]_. The running time is linear in *p*. If *p* divides the numerator of `B_n`, *UWORD_MAX* is returned as an error code. .. function:: void _bernoulli_fmpq_ui_zeta(fmpz_t num, fmpz_t den, ulong n) void _bernoulli_fmpq_ui_multi_mod(fmpz_t num, fmpz_t den, ulong n, double alpha) Sets *num* and *den* to the reduced numerator and denominator of the Bernoulli number `B_n`. The *zeta* version computes the denominator `d` using the von Staudt-Clausen theorem, numerically approximates `B_n` using :func:`arb_bernoulli_ui_zeta`, and then rounds `d B_n` to the correct numerator. The *multi_mod* version reconstructs `B_n` by computing the high bits via the Riemann zeta function and the low bits via Harvey's multimodular algorithm. The tuning parameter *alpha* should be a fraction between 0 and 1 controlling the number of bits to compute by the multimodular algorithm. If set to a negative number, a default value will be used. .. function:: void _bernoulli_fmpq_ui(fmpz_t num, fmpz_t den, ulong n) void bernoulli_fmpq_ui(fmpq_t b, ulong n) Computes the Bernoulli number `B_n` as an exact fraction, for an isolated integer `n`. This function reads `B_n` from the global cache if the number is already cached, but does not automatically extend the cache by itself. arb-2.22.1/doc/source/bool_mat.rst000066400000000000000000000217121417376376500167630ustar00rootroot00000000000000.. _bool-mat: **bool_mat.h** -- matrices over booleans =============================================================================== A :type:`bool_mat_t` represents a dense matrix over the boolean semiring `\langle \left\{0, 1\right\}, \vee, \wedge \rangle`, implemented as an array of entries of type ``int``. The dimension (number of rows and columns) of a matrix is fixed at initialization, and the user must ensure that inputs and outputs to an operation have compatible dimensions. The number of rows or columns in a matrix can be zero. Types, macros and constants ------------------------------------------------------------------------------- .. type:: bool_mat_struct .. type:: bool_mat_t Contains a pointer to a flat array of the entries (entries), an array of pointers to the start of each row (rows), and the number of rows (r) and columns (c). An *bool_mat_t* is defined as an array of length one of type *bool_mat_struct*, permitting an *bool_mat_t* to be passed by reference. .. function:: int bool_mat_get_entry(const bool_mat_t mat, slong i, slong j) Returns the entry of matrix *mat* at row *i* and column *j*. .. function:: void bool_mat_set_entry(bool_mat_t mat, slong i, slong j, int x) Sets the entry of matrix *mat* at row *i* and column *j* to *x*. .. macro:: bool_mat_nrows(mat) Returns the number of rows of the matrix. .. macro:: bool_mat_ncols(mat) Returns the number of columns of the matrix. Memory management ------------------------------------------------------------------------------- .. function:: void bool_mat_init(bool_mat_t mat, slong r, slong c) Initializes the matrix, setting it to the zero matrix with *r* rows and *c* columns. .. function:: void bool_mat_clear(bool_mat_t mat) Clears the matrix, deallocating all entries. .. function:: int bool_mat_is_empty(const bool_mat_t mat) Returns nonzero iff the number of rows or the number of columns in *mat* is zero. Note that this does not depend on the entry values of *mat*. .. function:: int bool_mat_is_square(const bool_mat_t mat) Returns nonzero iff the number of rows is equal to the number of columns in *mat*. Conversions ------------------------------------------------------------------------------- .. function:: void bool_mat_set(bool_mat_t dest, const bool_mat_t src) Sets *dest* to *src*. The operands must have identical dimensions. Input and output ------------------------------------------------------------------------------- .. function:: void bool_mat_print(const bool_mat_t mat) Prints each entry in the matrix. .. function:: void bool_mat_fprint(FILE * file, const bool_mat_t mat) Prints each entry in the matrix to the stream *file*. Value comparisons ------------------------------------------------------------------------------- .. function:: int bool_mat_equal(const bool_mat_t mat1, const bool_mat_t mat2) Returns nonzero iff the matrices have the same dimensions and identical entries. .. function:: int bool_mat_any(const bool_mat_t mat) Returns nonzero iff *mat* has a nonzero entry. .. function:: int bool_mat_all(const bool_mat_t mat) Returns nonzero iff all entries of *mat* are nonzero. .. function:: int bool_mat_is_diagonal(const bool_mat_t A) Returns nonzero iff `i \ne j \implies \bar{A_{ij}}`. .. function:: int bool_mat_is_lower_triangular(const bool_mat_t A) Returns nonzero iff `i < j \implies \bar{A_{ij}}`. .. function:: int bool_mat_is_transitive(const bool_mat_t mat) Returns nonzero iff `A_{ij} \wedge A_{jk} \implies A_{ik}`. .. function:: int bool_mat_is_nilpotent(const bool_mat_t A) Returns nonzero iff some positive matrix power of `A` is zero. Random generation ------------------------------------------------------------------------------- .. function:: void bool_mat_randtest(bool_mat_t mat, flint_rand_t state) Sets *mat* to a random matrix. .. function:: void bool_mat_randtest_diagonal(bool_mat_t mat, flint_rand_t state) Sets *mat* to a random diagonal matrix. .. function:: void bool_mat_randtest_nilpotent(bool_mat_t mat, flint_rand_t state) Sets *mat* to a random nilpotent matrix. Special matrices ------------------------------------------------------------------------------- .. function:: void bool_mat_zero(bool_mat_t mat) Sets all entries in mat to zero. .. function:: void bool_mat_one(bool_mat_t mat) Sets the entries on the main diagonal to ones, and all other entries to zero. .. function:: void bool_mat_directed_path(bool_mat_t A) Sets `A_{ij}` to `j = i + 1`. Requires that `A` is a square matrix. .. function:: void bool_mat_directed_cycle(bool_mat_t A) Sets `A_{ij}` to `j = (i + 1) \mod n` where `n` is the order of the square matrix `A`. Transpose ------------------------------------------------------------------------------- .. function:: void bool_mat_transpose(bool_mat_t dest, const bool_mat_t src) Sets *dest* to the transpose of *src*. The operands must have compatible dimensions. Aliasing is allowed. Arithmetic ------------------------------------------------------------------------------- .. function:: void bool_mat_complement(bool_mat_t B, const bool_mat_t A) Sets *B* to the logical complement of *A*. That is `B_{ij}` is set to `\bar{A_{ij}}`. The operands must have the same dimensions. .. function:: void bool_mat_add(bool_mat_t res, const bool_mat_t mat1, const bool_mat_t mat2) Sets *res* to the sum of *mat1* and *mat2*. The operands must have the same dimensions. .. function:: void bool_mat_mul(bool_mat_t res, const bool_mat_t mat1, const bool_mat_t mat2) Sets *res* to the matrix product of *mat1* and *mat2*. The operands must have compatible dimensions for matrix multiplication. .. function:: void bool_mat_mul_entrywise(bool_mat_t res, const bool_mat_t mat1, const bool_mat_t mat2) Sets *res* to the entrywise product of *mat1* and *mat2*. The operands must have the same dimensions. .. function:: void bool_mat_sqr(bool_mat_t B, const bool_mat_t A) Sets *B* to the matrix square of *A*. The operands must both be square with the same dimensions. .. function:: void bool_mat_pow_ui(bool_mat_t B, const bool_mat_t A, ulong exp) Sets *B* to *A* raised to the power *exp*. Requires that *A* is a square matrix. Special functions ------------------------------------------------------------------------------- .. function:: int bool_mat_trace(const bool_mat_t mat) Returns the trace of the matrix, i.e. the sum of entries on the main diagonal of *mat*. The matrix is required to be square. The sum is in the boolean semiring, so this function returns nonzero iff any entry on the diagonal of *mat* is nonzero. .. function:: slong bool_mat_nilpotency_degree(const bool_mat_t A) Returns the nilpotency degree of the `n \times n` matrix *A*. It returns the smallest positive `k` such that `A^k = 0`. If no such `k` exists then the function returns `-1` if `n` is positive, and otherwise it returns `0`. .. function:: void bool_mat_transitive_closure(bool_mat_t B, const bool_mat_t A) Sets *B* to the transitive closure `\sum_{k=1}^\infty A^k`. The matrix *A* is required to be square. .. function:: slong bool_mat_get_strongly_connected_components(slong * p, const bool_mat_t A) Partitions the `n` row and column indices of the `n \times n` matrix *A* according to the strongly connected components (SCC) of the graph for which *A* is the adjacency matrix. If the graph has `k` SCCs then the function returns `k`, and for each vertex `i \in [0, n-1]`, `p_i` is set to the index of the SCC to which the vertex belongs. The SCCs themselves can be considered as nodes in a directed acyclic graph (DAG), and the SCCs are indexed in postorder with respect to that DAG. .. function:: slong bool_mat_all_pairs_longest_walk(fmpz_mat_t B, const bool_mat_t A) Sets `B_{ij}` to the length of the longest walk with endpoint vertices `i` and `j` in the graph whose adjacency matrix is *A*. The matrix *A* must be square. Empty walks with zero length which begin and end at the same vertex are allowed. If `j` is not reachable from `i` then no walk from `i` to `j` exists and `B_{ij}` is set to the special value `-1`. If arbitrarily long walks from `i` to `j` exist then `B_{ij}` is set to the special value `-2`. The function returns `-2` if any entry of `B_{ij}` is `-2`, and otherwise it returns the maximum entry in `B`, except if `A` is empty in which case `-1` is returned. Note that the returned value is one less than that of :func:`nilpotency_degree`. This function can help quantify entrywise errors in a truncated evaluation of a matrix power series. If *A* is an indicator matrix with the same sparsity pattern as a matrix `M` over the real or complex numbers, and if `B_{ij}` does not take the special value `-2`, then the tail `\left[ \sum_{k=N}^\infty a_k M^k \right]_{ij}` vanishes when `N > B_{ij}`. arb-2.22.1/doc/source/conf.py000066400000000000000000000204651417376376500157400ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Arb documentation build configuration file, created by # sphinx-quickstart on Thu Oct 11 09:33:44 2012. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.mathjax'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Arb' copyright = u'2012-2022, Fredrik Johansson' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. for _line in open("../../arb/version.c").readlines(): if _line.startswith("const char * arb_version"): _i1 = _line.find('"') _i2 = _line.find('"', _i1 + 1) version = _line[_i1+1:_i2] release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all documents. default_role = 'math' latex_preamble = r""" \usepackage{amsmath,amssymb} \usepackage{breakurl} \setcounter{tocdepth}{2} """ primary_domain = 'c' # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' html_context = { 'css_files': ['_static/default.css'], } # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { 'sidebarwidth' : 280, 'collapsiblesidebar': True, 'bodyfont': "'arial', sans-serif", 'headfont': "'arial', sans-serif", 'sidebarbtncolor': '#666', 'sidebarbgcolor': '#444', 'sidebarlinkcolor': '#ddd', 'relbarbgcolor': '#333', 'footerbgcolor': '#333', 'headbgcolor': '#fff', } # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = "_static/arbwhite.png" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. html_favicon = "_static/arb.ico" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Arbdoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). 'papersize': 'a4paper', 'fontpkg': '', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. 'preamble': '\\usepackage{lmodern}\n\\setcounter{tocdepth}{2}\n\\urlstyle{tt}', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'Arb.tex', u'Arb Documentation', u'Fredrik Johansson', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. latex_logo = "_static/arbtext.pdf" # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'arb', u'Arb Documentation', [u'Fredrik Johansson'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'Arb', u'Arb Documentation', u'Fredrik Johansson', 'Arb', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' arb-2.22.1/doc/source/constants.rst000066400000000000000000000100211417376376500171720ustar00rootroot00000000000000.. _algorithms_constants: Algorithms for mathematical constants =============================================================================== Most mathematical constants are evaluated using the generic hypergeometric summation code. Pi ------------------------------------------------------------------------------- `\pi` is computed using the Chudnovsky series .. math :: \frac{1}{\pi} = 12 \sum^\infty_{k=0} \frac{(-1)^k (6k)! (13591409 + 545140134k)}{(3k)!(k!)^3 640320^{3k + 3/2}} which is hypergeometric and adds roughly 14 digits per term. Methods based on the arithmetic-geometric mean seem to be slower by a factor three in practice. A small trick is to compute `1/\sqrt{640320}` instead of `\sqrt{640320}` at the end. Logarithms of integers ------------------------------------------------------------------------------- We use the formulas .. math :: \log(2) = \frac{3}{4} \sum_{k=0}^{\infty} \frac{(-1)^k (k!)^2}{2^k (2k+1)!} .. math :: \log(10) = 46 \operatorname{atanh}(1/31) + 34 \operatorname{atanh}(1/49) + 20 \operatorname{atanh}(1/161) Euler's constant ------------------------------------------------------------------------------- Euler's constant `\gamma` is computed using the Brent-McMillan formula ([BM1980]_, [MPFR2012]_) .. math :: \gamma = \frac{S_0(2n) - K_0(2n)}{I_0(2n)} - \log(n) in which `n` is a free parameter and .. math :: S_0(x) = \sum_{k=0}^{\infty} \frac{H_k}{(k!)^2} \left(\frac{x}{2}\right)^{2k}, \quad I_0(x) = \sum_{k=0}^{\infty} \frac{1}{(k!)^2} \left(\frac{x}{2}\right)^{2k} .. math :: 2x I_0(x) K_0(x) \sim \sum_{k=0}^{\infty} \frac{[(2k)!]^3}{(k!)^4 8^{2k} x^{2k}}. All series are evaluated using binary splitting. The first two series are evaluated simultaneously, with the summation taken up to `k = N - 1` inclusive where `N \ge \alpha n + 1` and `\alpha \approx 4.9706257595442318644` satisfies `\alpha (\log \alpha - 1) = 3`. The third series is taken up to `k = 2n-1` inclusive. With these parameters, it is shown in [BJ2013]_ that the error is bounded by `24e^{-8n}`. Catalan's constant ------------------------------------------------------------------------------- Catalan's constant is computed using the hypergeometric series .. math :: C = \frac{1}{64} \sum_{k=1}^{\infty} \frac{256^k (580k^2-184k+15)}{k^3(2k-1){6k\choose 3k}{6k\choose 4k}{4k\choose 2k}} given in [PP2010]_. Khinchin's constant ------------------------------------------------------------------------------- Khinchin's constant `K_0` is computed using the formula .. math :: \log K_0 = \frac{1}{\log 2} \left[ \sum_{k=2}^{N-1} \log \left(\frac{k-1}{k} \right) \log \left(\frac{k+1}{k} \right) + \sum_{n=1}^\infty \frac {\zeta (2n,N)}{n} \sum_{k=1}^{2n-1} \frac{(-1)^{k+1}}{k} \right] where `N \ge 2` is a free parameter that can be used for tuning [BBC1997]_. If the infinite series is truncated after `n = M`, the remainder is smaller in absolute value than .. math :: \sum_{n=M+1}^{\infty} \zeta(2n, N) = \sum_{n=M+1}^{\infty} \sum_{k=0}^{\infty} (k+N)^{-2n} \le \sum_{n=M+1}^{\infty} \left( N^{-2n} + \int_0^{\infty} (t+N)^{-2n} dt \right) = \sum_{n=M+1}^{\infty} \frac{1}{N^{2n}} \left(1 + \frac{N}{2n-1}\right) \le \sum_{n=M+1}^{\infty} \frac{N+1}{N^{2n}} = \frac{1}{N^{2M} (N-1)} \le \frac{1}{N^{2M}}. Thus, for an error of at most `2^{-p}` in the series, it is sufficient to choose `M \ge p / (2 \log_2 N)`. Glaisher's constant ------------------------------------------------------------------------------- Glaisher's constant `A = \exp(1/12 - \zeta'(-1))` is computed directly from this formula. We don't use the reflection formula for the zeta function, as the arithmetic in Euler-Maclaurin summation is faster at `s = -1` than at `s = 2`. Apery's constant ------------------------------------------------------------------------------- Apery's constant `\zeta(3)` is computed using the hypergeometric series .. math :: \zeta(3) = \frac{1}{64} \sum_{k=0}^\infty (-1)^k (205k^2 + 250k + 77) \frac{(k!)^{10}}{[(2k+1)!]^5}. arb-2.22.1/doc/source/contributing.rst000066400000000000000000000116321417376376500176760ustar00rootroot00000000000000.. _contributing: Contributing to Arb =============================================================================== The Arb project welcomes new feature contributions in addition to patches for bugs and performance problems. What are appropriate new features? Most of the numerical functionality that can be found in a general-purpose computer algebra system is certainly within scope (of course, the main restriction is that the algorithm must have a proof of correctness). However, if the functionality is easily accomplished by combining existing functions in Arb, consider whether it is worth the increase in code size, maintenance effort and test time. Prospective contributors are recommended to discuss their ideas on the mailing list or the issue tracker. The process for actually submitting code is simple: anyone can submit a pull request on GitHub. If the patch looks good to the maintainer and the test code passes, the patch will get merged into the git master. Code conventions ------------------------------------------------------------------------------- Four steps are needed to add a new function: * Add the function ``module_foo()`` in a new file ``module/foo.c``. * Add a corresponding test program in a new file ``module/test/t-foo.c``. * Add the function prototype to ``module.h``. * Document the function in ``doc/source/module.rst``. The build system takes care of everything else automatically. Test code (see below) can be omitted if ``module_foo()`` is a trivial helper function, but it should at least be tested indirectly via another function in that case. Auxiliary functions needed to implement ``module_foo()`` but which have no use elsewhere should be declared as ``static`` in ``module/foo.c``. If ``module_foo()`` is very short, it can be declared inline directly in ``module.h`` with the ``MODULE_INLINE`` macro. Use the following checklist regarding code style: * Try to keep names and function arguments consistent with existing code. * Follow the conventions regarding types, aliasing rules, etc. described in :ref:`issues` and in ``code_conventions.txt`` in FLINT (https://github.com/wbhart/flint2/blob/trunk/code_conventions.txt). * Use basic FLINT constants, types and functions: ``FLINT_BITS``, ``flint_malloc``/``flint_free``, ``flint_abort``, ``flint_printf``, etc. * Complex macros should be avoided. * Indentation is four spaces. * Curly braces normally go on a new line. * Binary operators are surrounded by spaces (but parentheses and brackets are not). * Logically distinct chunks of code (variable declarations, initialization, precomputations, the main loop, cleanup, etc.) should be separated by a single blank line. * Lines are up to 79 characters long, but this rule can be broken if it helps readability. * Add correct copyright notices at the top of each file. Test code ------------------------------------------------------------------------------- See :ref:`setup` for instructions on running test code. The easiest way to write a test program for a new function is to adapt the test code for an existing, similar function. Most of the test code in Arb uses the strategy of computing the same mathematical quantity in two or more different ways (for example, using functional equations, interchanging the order of parameter, or varying the precision and other algorithm parameters) and verifying that the results are consistent. It is also a good idea to test that aliasing works. Input data is usually generated randomly, but in some cases including precomputed reference values also makes sense. Faster test code is better. A single test program should not take more than 10 seconds to run, and preferably no more than 1 second. Most functions can be tested effectively in less than 0.1 seconds. Think of what the corner cases are and try to generate random input biased toward such cases. The ``randtest()`` functions attempt to generate corner cases automatically, but some thought may be needed to use them optimally. Try to ensure that the test code fails if you deliberately break the tested function in any way. It is also a good idea to run the test code once with ``ARB_TEST_MULTIPLIER=10.0`` or higher. If a function's input space is too large to probe effectively for corner cases with random input, that can be a hint that the function should be split into smaller logical parts that can be tested separately. The test code must complete without errors when run with ``valgrind``. The most common mistake leading to memory corruption or memory leaks is to miss or duplicate an ``init()`` or ``clear()`` call. Check that the ``init()`` and ``clear()`` calls exactly match the variable declarations in each code block, including the test code itself. Profiling code is not needed in most cases, but it is often a good idea to run some benchmarks at least during the initial development of a new feature. The ``TIMEIT_START``/``TIMEIT_STOP`` and ``SHOW_MEMORY_USAGE`` macros in FLINT are useful for quick measurements. arb-2.22.1/doc/source/credits.rst000066400000000000000000000453621417376376500166330ustar00rootroot00000000000000.. _credits: Credits and references =============================================================================== .. _license: License ------------------------------------------------------------------------------- Arb is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Arb 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Arb (see the LICENSE file in the root of the Arb source directory). If not, see http://www.gnu.org/licenses/. Versions of Arb up to and including 2.8 were distributed under the GNU General Public License (GPL), not the LGPL. The switch to the LGPL applies retroactively; i.e. users may redistribute older versions of Arb under the LGPL if they prefer. Authors ------------------------------------------------------------------------------- Fredrik Johansson is the main author. The project was started in 2012 as a numerical extension of FLINT, and the initial design was heavily based on FLINT 2.0 (with particular credit to Bill Hart and Sebastian Pancratz). The following authors have developed major new features. * Pascal Molin - discrete Fourier transform (DFT), Dirichlet characters, Dirichlet L-functions, discrete logarithm computation * Alex Griffing - sinc function, matrix trace, improved matrix squaring, boolean matrices, improved structured matrix exponentials, Cholesky decomposition, miscellaneous patches * Marc Mezzarobba - fast evaluation of Legendre polynomials, work on Arb interface in Sage, bug reports, feedback Several people have contributed patches, bug reports, or substantial feedback. This list (ordered by time of first contribution) is probably incomplete. * Bill Hart - build system, Windows 64 support, design of FLINT * Sebastian Pancratz - divide-and-conquer polynomial composition algorithm (taken from FLINT) * The MPFR development team - Arb includes two-limb multiplication code taken from MPFR * Jonathan Bober - original code for Dirichlet characters, C++ compatibility fixes * Yuri Matiyasevich - feedback about the zeta function and root-finding code * Abhinav Baid - dot product and norm functions * OndÅ™ej ÄŒertík - bug reports, feedback * Andrew Booker - bug reports, feedback * Francesco Biscani - C++ compatibility fixes, feedback * Clemens Heuberger - work on Arb interface in Sage, feedback * Ricky Farr - convenience functions, feedback * Marcello Seri - fix for static builds on OS X * Tommy Hofmann - matrix transpose, comparison, other utility methods, Julia interface * Alexander Kobel - documentation and code cleanup patches * Hrvoje Abraham - patches for MinGW compatibility * Julien Puydt - soname versioning support, bug reports, Debian testing * Jeroen Demeyer - patch for major bug on PPC64 * Isuru Fernando - continuous integration setup, support for cmake and MSVC builds * François Bissey - build system patches * Jean-Pierre Flori - code simplifications for Gauss periods, feedback * arbguest - preconditioned linear algebra algorithms * Ralf Stephan - return exact real parts in acos and acosh * Vincent Delecroix - various feedback and patches, work on Sage interface * D.H.J Polymath - Riemann xi function * Joel Dahne - feedback and improvements for Legendre functions * Gianfranco Costamagna - bug reports, Debian testing * Julian Rüth - serialization support * Michael Orlitzky - build system patches * David Berghaus - aliased window matrix multiplication * Albin Ahlbäck - uniformly distributed random numbers * Daniel Schultz - derivative of Weierstrass elliptic function * Matthias Gessinger - Graeffe transforms * David Harvey - modular computation of Bernoulli numbers (code taken from Harvey's bernmm package) Funding ------------------------------------------------------------------------------- From 2012 to July 2014, Fredrik's work on Arb was supported by Austrian Science Fund FWF Grant Y464-N18 (Fast Computer Algebra for Special Functions). During that period, he was a PhD student (and briefly a postdoc) at RISC, Johannes Kepler University, Linz, supervised by Manuel Kauers. From September 2014 to October 2015, Fredrik was a postdoc at INRIA Bordeaux and Institut de Mathématiques de Bordeaux, in the LFANT project-team headed by Andreas Enge. During that period, Fredrik's work on Arb was supported by ERC Starting Grant ANTICS 278537 (Algorithmic Number Theory in Computer Science) http://cordis.europa.eu/project/rcn/101288_en.html Since October 2015, Fredrik is a CR2 researcher in the LFANT team, funded by INRIA. Software ------------------------------------------------------------------------------- The following software has been helpful in the development of Arb. * GMP (Torbjörn Granlund and others), http://gmplib.org * MPIR (Brian Gladman, Jason Moxham, William Hart and others), http://mpir.org * MPFR (Guillaume Hanrot, Vincent Lefèvre, Patrick Pélissier, Philippe Théveny, Paul Zimmermann and others), http://mpfr.org * FLINT (William Hart, Sebastian Pancratz, Andy Novocin, Fredrik Johansson, David Harvey and others), http://flintlib.org * Sage (William Stein and others), http://sagemath.org * Pari/GP (The Pari group), http://pari.math.u-bordeaux.fr/ * SymPy (OndÅ™ej ÄŒertík, Aaron Meurer and others), http://sympy.org * mpmath (Fredrik Johansson and others), http://mpmath.org * Mathematica (Wolfram Research), http://www.wolfram.com/mathematica * HolonomicFunctions (Christoph Koutschan), http://www.risc.jku.at/research/combinat/software/HolonomicFunctions/ * Sphinx (George Brandl and others), http://sphinx.pocoo.org * CM (Andreas Enge), http://www.multiprecision.org/index.php?prog=cm * ore_algebra (Manuel Kauers, Maximilian Jaroschek, Fredrik Johansson), http://www.risc.jku.at/research/combinat/software/ore_algebra/ Citing Arb ------------------------------------------------------------------------------- To cite Arb in a scientific paper, the following reference can be used: \F. Johansson. "Arb: efficient arbitrary-precision midpoint-radius interval arithmetic", *IEEE Transactions on Computers*, 66(8):1281-1292, 2017. DOI: `10.1109/TC.2017.2690633 `_. In BibTeX format:: @article{Johansson2017arb, author = {F. Johansson}, title = {Arb: efficient arbitrary-precision midpoint-radius interval arithmetic}, journal = {IEEE Transactions on Computers}, year = {2017}, volume = {66}, issue = {8}, pages = {1281--1292}, doi = {10.1109/TC.2017.2690633}, } Alternatively, the Arb manual or website can be cited directly. The *IEEE Transactions on Computers* paper supersedes the following extended abstract, which is now outdated: \F. Johansson. "Arb: a C library for ball arithmetic", *ACM Communications in Computer Algebra*, 47(4):166-169, 2013. Bibliography ------------------------------------------------------------------------------- (In the PDF edition, this section is empty. See the bibliography listing at the end of the document.) .. [Ari2011] \J. Arias de Reyna, "High precision computation of Riemann’s zeta function by the Riemann-Siegel formula, I", Mathematics of Computation 80 (2011), 995-1009 .. [Ari2012] \J. Arias de Reyna, "Programs for Riemann's zeta function", (J. A. J. van Vonderen, Ed.) *Leven met getallen : liber amicorum ter gelegenheid van de pensionering van Herman te Riele* CWI (2012) 102-112, https://ir.cwi.nl/pub/19724 .. [Arn2010] \J. Arndt, *Matters Computational*, Springer (2010), http://www.jjj.de/fxt/#fxtbook .. [BBC1997] \D. H. Bailey, J. M. Borwein and R. E. Crandall, "On the Khintchine constant", Mathematics of Computation 66 (1997) 417-431 .. [Blo2009] \R. Bloemen, "Even faster zeta(2n) calculation!", https://web.archive.org/web/20141101133659/http://xn--2-umb.com/09/11/even-faster-zeta-calculation .. [BBC2000] \J. Borwein, D. M. Bradley and R. E. Crandall, "Computational strategies for the Riemann zeta function", Journal of Computational and Applied Mathematics 121 (2000) 247-296 .. [BZ1992] \J. Borwein and I. Zucker, "Fast evaluation of the gamma function for small rational fractions using complete elliptic integrals of the first kind", IMA Journal of Numerical Analysis 12 (1992) 519-526 .. [Bog2012] \I. Bogaert, B. Michiels and J. Fostier, "O(1) computation of Legendre polynomials and Gauss-Legendre nodes and weights for parallel computing", SIAM Journal on Scientific Computing 34:3 (2012), C83-C101 .. [Bor1987] \P. Borwein, "Reduced complexity evaluation of hypergeometric functions", Journal of Approximation Theory 50:3 (1987) .. [Bor2000] \P. Borwein, "An Efficient Algorithm for the Riemann Zeta Function", Constructive experimental and nonlinear analysis, CMS Conference Proc. 27 (2000) 29-34, http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf .. [BM1980] \R. P. Brent and E. M. McMillan, "Some new algorithms for high-precision computation of Euler's constant", Mathematics of Computation 34 (1980) 305-312. .. [Bre1978] \R. P. Brent, "A Fortran multiple-precision arithmetic package", ACM Transactions on Mathematical Software, 4(1):57–70, March 1978. .. [Bre1979] \R. P. Brent, "On the Zeros of the Riemann Zeta Function in the Critical Strip", Mathematics of Computation 33 (1979), 1361-1372, https://doi.org/10.1090/S0025-5718-1979-0537983-2 .. [Bre2010] \R. P. Brent, "Ramanujan and Euler's Constant", http://wwwmaths.anu.edu.au/~brent/pd/Euler_CARMA_10.pdf .. [BJ2013] \R. P. Brent and F. Johansson, "A bound for the error term in the Brent-McMillan algorithm", preprint (2013), http://arxiv.org/abs/1312.0039 .. [BZ2011] \R. P. Brent and P. Zimmermann, *Modern Computer Arithmetic*, Cambridge University Press (2011), http://www.loria.fr/~zimmerma/mca/pub226.html .. [Car1995] \B. C. Carlson, "Numerical computation of real or complex elliptic integrals". Numerical Algorithms, 10(1):13-26 (1995). .. [CP2005] \R. Crandall and C. Pomerance, *Prime Numbers: A Computational Perspective*, second edition, Springer (2005). .. [CGHJK1996] \R. M. Corless, G. H. Gonnet, D. E. Hare, D. J. Jeffrey and D. E. Knuth, "On the Lambert W function", Advances in Computational Mathematics, 5(1) (1996), 329-359 .. [Dup2006] \R. Dupont. "Moyenne arithmético-géométrique, suites de Borchardt et applications." These de doctorat, École polytechnique, Palaiseau (2006). http://http://www.lix.polytechnique.fr/Labo/Regis.Dupont/these_soutenance.pdf .. [DYF1999] \A. Dzieciol, S. Yngve and P. O. Fröman, "Coulomb wave functions with complex values of the variable and the parameters", J. Math. Phys. 40, 6145 (1999), https://doi.org/10.1063/1.533083 .. [EHJ2016] \A. Enge, W. Hart and F. Johansson, "Short addition sequences for theta functions", preprint (2016), https://arxiv.org/abs/1608.06810 .. [EM2004] \O. Espinosa and V. Moll, "A generalized polygamma function", Integral Transforms and Special Functions (2004), 101-115. .. [Fil1992] \S. Fillebrown, "Faster Computation of Bernoulli Numbers", Journal of Algorithms 13 (1992) 431-445 .. [Gas2018] \D. Gaspard, "Connection formulas between Coulomb wave functions" (2018), https://arxiv.org/abs/1804.10976 .. [GG2003] \J. von zur Gathen and J. Gerhard, *Modern Computer Algebra*, second edition, Cambridge University Press (2003) .. [GVL1996] \G. H. Golub and C. F. Van Loan, *Matrix Computations*, third edition, Johns Hopkins University Press (1996). .. [GS2003] \X. Gourdon and P. Sebah, "Numerical evaluation of the Riemann Zeta-function" (2003), http://numbers.computation.free.fr/Constants/Miscellaneous/zetaevaluations.pdf .. [HS1967] \E. Hansen and R. Smith, "Interval Arithmetic in Matrix Computations, Part II", SIAM Journal of Numerical Analysis, 4(1):1-9 (1967). https://doi.org/10.1137/0704001 .. [HZ2004] \G. Hanrot and P. Zimmermann, "Newton Iteration Revisited" (2004), http://www.loria.fr/~zimmerma/papers/fastnewton.ps.gz .. [Har2010] \D. Harvey, "A multimodular algorithm for computing Bernoulli numbers" (2010), Mathematics of Computation 79.272: 2361-2370 .. [Hoe2009] \J. van der Hoeven, "Ball arithmetic", Technical Report, HAL 00432152 (2009), http://www.texmacs.org/joris/ball/ball-abs.html .. [Hoe2001] \J. van der Hoeven. "Fast evaluation of holonomic functions near and in regular singularities", Journal of Symbolic Computation, 31(6):717-743 (2001). .. [HM2017] \J. van der Hoeven and B. Mourrain. "Efficient certification of numeric solutions to eigenproblems", MACIS 2017, 81-94, (2017), https://hal.archives-ouvertes.fr/hal-01579079 .. [JB2018] \F. Johansson and I. Blagouchine. "Computing Stieltjes constants using complex integration", preprint (2018), https://arxiv.org/abs/1804.01679 .. [Joh2012] \F. Johansson, "Efficient implementation of the Hardy-Ramanujan-Rademacher formula", LMS Journal of Computation and Mathematics, Volume 15 (2012), 341-359, http://journals.cambridge.org/action/displayAbstract?fromPage=online&aid=8710297 .. [Joh2013] \F. Johansson, "Rigorous high-precision computation of the Hurwitz zeta function and its derivatives", Numerical Algorithms, http://arxiv.org/abs/1309.2877 http://dx.doi.org/10.1007/s11075-014-9893-1 .. [Joh2014a] \F. Johansson, *Fast and rigorous computation of special functions to high precision*, PhD thesis, RISC, Johannes Kepler University, Linz, 2014. http://fredrikj.net/thesis/ .. [Joh2014b] \F. Johansson, "Evaluating parametric holonomic sequences using rectangular splitting", ISSAC 2014, 256-263. http://dx.doi.org/10.1145/2608628.2608629 .. [Joh2014c] \F. Johansson, "Efficient implementation of elementary functions in the medium-precision range", http://arxiv.org/abs/1410.7176 .. [Joh2015] \F. Johansson, "Computing Bell numbers", http://fredrikj.net/blog/2015/08/computing-bell-numbers/ .. [Joh2016] \F. Johansson, "Computing hypergeometric functions rigorously", preprint (2016), https://arxiv.org/abs/1606.06977 .. [Joh2017a] \F. Johansson. "Arb: efficient arbitrary-precision midpoint-radius interval arithmetic", IEEE Transactions on Computers, 66(8):1281-1292 (2017). https://doi.org/10.1109/TC.2017.2690633 .. [Joh2017b] \F. Johansson, "Computing the Lambert W function in arbitrary-precision complex interval arithmetic", preprint (2017), https://arxiv.org/abs/1705.03266 .. [Joh2018a] \F. Johansson, "Numerical integration in arbitrary-precision ball arithmetic", preprint (2018), https://arxiv.org/abs/1802.07942 .. [Joh2018b] \F. Johansson and others, "mpmath: a Python library for arbitrary-precision floating-point arithmetic (version 1.1.0)", December 2018. http://mpmath.org/ .. [JM2018] \F. Johansson and M. Mezzarobba, "Fast and rigorous arbitrary-precision computation of Gauss-Legendre quadrature nodes and weights", preprint (2018), https://arxiv.org/abs/1802.03948 .. [Kar1998] \E. A. Karatsuba, "Fast evaluation of the Hurwitz zeta function and Dirichlet L-series", Problems of Information Transmission 34:4 (1998), 342-353, http://www.mathnet.ru/php/archive.phtml?wshow=paper&jrnid=ppi&paperid=425&option_lang=eng .. [Kob2010] \A. Kobel, "Certified Complex Numerical Root Finding", Seminar on Computational Geometry and Geometric Computing (2010), http://www.mpi-inf.mpg.de/departments/d1/teaching/ss10/Seminar_CGGC/Slides/02_Kobel_NRS.pdf .. [Kri2013] \A. Krishnamoorthy and D. Menon, "Matrix Inversion Using Cholesky Decomposition" Proc. of the International Conference on Signal Processing Algorithms, Architectures, Arrangements, and Applications (SPA-2013), pp. 70-72, 2013. .. [Leh1970] \R. S. Lehman, "On the Distribution of Zeros of the Riemann Zeta-Function", Proc. of the London Mathematical Society 20(3) (1970), 303-320, https://doi.org/10.1112/plms/s3-20.2.303 .. [Mic2007] \N. Michel, "Precise Coulomb wave functions for a wide range of complex l, eta and z", Computer Physics Communications, Volume 176, Issue 3, (2007), 232-249, https://doi.org/10.1016/j.cpc.2006.10.004 .. [Miy2010] \S. Miyajima, "Fast enclosure for all eigenvalues in generalized eigenvalue problems", Journal of Computational and Applied Mathematics, 233 (2010), 2994-3004, https://dx.doi.org/10.1016/j.cam.2009.11.048 .. [MPFR2012] The MPFR team, "MPFR Algorithms" (2012), http://www.mpfr.org/algo.html .. [NIST2012] National Institute of Standards and Technology, *Digital Library of Mathematical Functions* (2012), http://dlmf.nist.gov/ .. [Olv1997] \F. Olver, *Asymptotics and special functions*, AKP Classics, AK Peters Ltd., Wellesley, MA, 1997. Reprint of the 1974 original. .. [Rad1973] \H. Rademacher, *Topics in analytic number theory*, Springer, 1973. .. [Pet1999] \K. Petras, "On the computation of the Gauss-Legendre quadrature formula with a given precision", Journal of Computational and Applied Mathematics 112 (1999), 253-267 .. [Pla2011] \D. J. Platt, "Computing degree 1 L-functions rigorously", Ph.D. Thesis, University of Bristol (2011), https://people.maths.bris.ac.uk/~madjp/thesis5.pdf .. [Pla2017] \D. J. Platt, "Isolating some non-trivial zeros of zeta", Mathematics of Computation 86 (2017), 2449-2467, https://doi.org/10.1090/mcom/3198 .. [PP2010] \K. H. Pilehrood and T. H. Pilehrood. "Series acceleration formulas for beta values", Discrete Mathematics and Theoretical Computer Science, DMTCS, 12 (2) (2010), 223-236, https://hal.inria.fr/hal-00990465/ .. [PS1973] \M. S. Paterson and L. J. Stockmeyer, "On the number of nonscalar multiplications necessary to evaluate polynomials", SIAM J. Comput (1973) .. [PS1991] \G. Pittaluga and L. Sacripante, "Inequalities for the zeros of the Airy functions", SIAM J. Math. Anal. 22:1 (1991), 260-267. .. [Rum2010] \S. M. Rump, "Verification methods: Rigorous results using floating-point arithmetic", Acta Numerica 19 (2010), 287-449. .. [Smi2001] \D. M. Smith, "Algorithm: Fortran 90 Software for Floating-Point Multiple Precision Arithmetic, Gamma and Related Functions", Transactions on Mathematical Software 27 (2001) 377-387, http://myweb.lmu.edu/dmsmith/toms2001.pdf .. [Tak2000] \D. Takahashi, "A fast algorithm for computing large Fibonacci numbers", Information Processing Letters 75 (2000) 243-246, http://www.ii.uni.wroc.pl/~lorys/IPL/article75-6-1.pdf .. [Tre2008] \L. N. Trefethen, "Is Gauss Quadrature Better than Clenshaw-Curtis?", SIAM Review, 50:1 (2008), 67-87, https://doi.org/10.1137/060659831 .. [Tru2011] \T. S. Trudgian, "Improvements to Turing's method", Mathematics of Computation 80 (2011), 2259-2279, https://doi.org/10.1090/S0025-5718-2011-02470-1 .. [Tru2014] \T. S. Trudgian, "An improved upper bound for the argument of the Riemann zeta-function on the critical line II", Journal of Number Theory 134 (2014), 280-292, https://doi.org/10.1016/j.jnt.2013.07.017 .. [Tur1953] \A. M. Turing, "Some Calculations of the Riemann Zeta-Function", Proc. of the London Mathematical Society 3(3) (1953), 99-117, https://doi.org/10.1112/plms/s3-3.1.99 arb-2.22.1/doc/source/dirichlet.rst000066400000000000000000000267771417376376500171560ustar00rootroot00000000000000.. _dirichlet: **dirichlet.h** -- Dirichlet characters =================================================================================== *Warning: the interfaces in this module are experimental and may change without notice.* This module allows working with Dirichlet characters algebraically. For evaluations of characters as complex numbers, see :ref:`acb-dirichlet`. Dirichlet characters ------------------------------------------------------------------------------- Working with Dirichlet characters mod *q* consists mainly in going from residue classes mod *q* to exponents on a set of generators of the group. This implementation relies on the Conrey numbering scheme introduced in the `L-functions and Modular Forms DataBase `_, which is an explicit choice of generators allowing to represent Dirichlet characters via the pairing .. math:: \begin{array}{ccccc} (\mathbb Z/q\mathbb Z)^\times \times (\mathbb Z/q\mathbb Z)^\times & \to & \bigoplus_i \mathbb Z/\phi_i\mathbb Z \times \mathbb Z/\phi_i\mathbb Z & \to &\mathbb C \\ (m,n) & \mapsto& (a_i,b_i) &\mapsto& \chi_q(m,n) = \exp(2i\pi\sum \frac{a_ib_i}{\phi_i} ) \end{array} We call *number* a residue class `m` modulo *q*, and *log* the corresponding vector `(a_i)` of exponents of Conrey generators. Going from a *log* to the corresponding *number* is a cheap operation we call exponential, while the converse requires computing discrete logarithms. Multiplicative group modulo *q* ------------------------------------------------------------------------------- .. type:: dirichlet_group_struct .. type:: dirichlet_group_t Represents the group of Dirichlet characters mod *q*. An *dirichlet_group_t* is defined as an array of *dirichlet_group_struct* of length 1, permitting it to be passed by reference. .. function:: void dirichlet_group_init(dirichlet_group_t G, ulong q) Initializes *G* to the group of Dirichlet characters mod *q*. This method computes a canonical decomposition of *G* in terms of cyclic groups, which are the mod `p^e` subgroups for `p^e\|q`, plus the specific generator described by Conrey for each subgroup. In particular *G* contains: - the number *num* of components - the generators - the exponent *expo* of the group It does *not* automatically precompute lookup tables of discrete logarithms or numerical roots of unity, and can therefore safely be called even with large *q*. For implementation reasons, the largest prime factor of *q* must not exceed `10^{12}` (an abort will be raised). This restriction could be removed in the future. .. function:: void dirichlet_subgroup_init(dirichlet_group_t H, const dirichlet_group_t G, ulong h) Given an already computed group *G* mod `q`, initialize its subgroup *H* defined mod `h\mid q`. Precomputed discrete log tables are inherited. .. function:: void dirichlet_group_clear(dirichlet_group_t G) Clears *G*. Remark this function does *not* clear the discrete logarithm tables stored in *G* (which may be shared with another group). .. function:: ulong dirichlet_group_size(const dirichlet_group_t G) Returns the number of elements in *G*, i.e. `\varphi(q)`. .. function:: ulong dirichlet_group_num_primitive(const dirichlet_group_t G) Returns the number of primitive elements in *G*. .. function:: void dirichlet_group_dlog_precompute(dirichlet_group_t G, ulong num) Precompute decomposition and tables for discrete log computations in *G*, so as to minimize the complexity of *num* calls to discrete logarithms. If *num* gets very large, the entire group may be indexed. .. function:: void dirichlet_group_dlog_clear(dirichlet_group_t G, ulong num) Clear discrete logarithm tables in *G*. When discrete logarithm tables are shared with subgroups, those subgroups must be cleared before clearing the tables. Character type ------------------------------------------------------------------------------- .. type:: dirichlet_char_struct .. type:: dirichlet_char_t Represents a Dirichlet character. This structure contains both a *number* (residue class) and the corresponding *log* (exponents on the group generators). An *dirichlet_char_t* is defined as an array of *dirichlet_char_struct* of length 1, permitting it to be passed by reference. .. function:: void dirichlet_char_init(dirichlet_char_t chi, const dirichlet_group_t G) Initializes *chi* to an element of the group *G* and sets its value to the principal character. .. function:: void dirichlet_char_clear(dirichlet_char_t chi) Clears *chi*. .. function:: void dirichlet_char_print(const dirichlet_group_t G, const dirichlet_char_t chi) Prints the array of exponents representing this character. .. function:: void dirichlet_char_log(dirichlet_char_t x, const dirichlet_group_t G, ulong m) Sets *x* to the character of number *m*, computing its log using discrete logarithm in *G*. .. function:: ulong dirichlet_char_exp(const dirichlet_group_t G, const dirichlet_char_t x) Returns the number *m* corresponding to exponents in *x*. .. function:: ulong _dirichlet_char_exp(dirichlet_char_t x, const dirichlet_group_t G) Computes and returns the number *m* corresponding to exponents in *x*. This function is for internal use. .. function:: void dirichlet_char_one(dirichlet_char_t x, const dirichlet_group_t G) Sets *x* to the principal character in *G*, having *log* `[0,\dots 0]`. .. function:: void dirichlet_char_first_primitive(dirichlet_char_t x, const dirichlet_group_t G) Sets *x* to the first primitive character of *G*, having *log* `[1,\dots 1]`, or `[0, 1, \dots 1]` if `8\mid q`. .. function:: void dirichlet_char_set(dirichlet_char_t x, const dirichlet_group_t G, const dirichlet_char_t y) Sets *x* to the element *y*. .. function:: int dirichlet_char_next(dirichlet_char_t x, const dirichlet_group_t G) Sets *x* to the next character in *G* according to lexicographic ordering of *log*. The return value is the index of the last updated exponent of *x*, or *-1* if the last element has been reached. This function allows to iterate on all elements of *G* looping on their *log*. Note that it produces elements in seemingly random *number* order. The following template can be used for such a loop:: dirichlet_char_one(chi, G); do { /* use character chi */ } while (dirichlet_char_next(chi, G) >= 0); .. function:: int dirichlet_char_next_primitive(dirichlet_char_t x, const dirichlet_group_t G) Same as :func:`dirichlet_char_next`, but jumps to the next primitive character of *G*. .. function:: ulong dirichlet_index_char(const dirichlet_group_t G, const dirichlet_char_t x) Returns the lexicographic index of the *log* of *x* as an integer in `0\dots \varphi(q)`. .. function:: void dirichlet_char_index(dirichlet_char_t x, const dirichlet_group_t G, ulong j) Sets *x* to the character whose *log* has lexicographic index *j*. .. function:: int dirichlet_char_eq(const dirichlet_char_t x, const dirichlet_char_t y) .. function:: int dirichlet_char_eq_deep(const dirichlet_group_t G, const dirichlet_char_t x, const dirichlet_char_t y) Return 1 if *x* equals *y*. The second version checks every byte of the representation and is intended for testing only. Character properties ------------------------------------------------------------------------------- As a consequence of the Conrey numbering, all these numbers are available at the level of *number* and *char* object. Both case require no discrete log computation. .. function:: int dirichlet_char_is_principal(const dirichlet_group_t G, const dirichlet_char_t chi) Returns 1 if *chi* is the principal character mod *q*. .. function:: ulong dirichlet_conductor_ui(const dirichlet_group_t G, ulong a) .. function:: ulong dirichlet_conductor_char(const dirichlet_group_t G, const dirichlet_char_t x) Returns the *conductor* of `\chi_q(a,\cdot)`, that is the smallest `r` dividing `q` such `\chi_q(a,\cdot)` can be obtained as a character mod `r`. .. function:: int dirichlet_parity_ui(const dirichlet_group_t G, ulong a) .. function:: int dirichlet_parity_char(const dirichlet_group_t G, const dirichlet_char_t x) Returns the *parity* `\lambda` in `\{0,1\}` of `\chi_q(a,\cdot)`, such that `\chi_q(a,-1)=(-1)^\lambda`. .. function:: ulong dirichlet_order_ui(const dirichlet_group_t G, ulong a) .. function:: ulong dirichlet_order_char(const dirichlet_group_t G, const dirichlet_char_t x) Returns the order of `\chi_q(a,\cdot)` which is the order of `a\bmod q`. .. function:: int dirichlet_char_is_real(const dirichlet_group_t G, const dirichlet_char_t chi) Returns 1 if *chi* is a real character (iff it has order `\leq 2`). .. function:: int dirichlet_char_is_primitive(const dirichlet_group_t G, const dirichlet_char_t chi) Returns 1 if *chi* is primitive (iff its conductor is exactly *q*). Character evaluation ------------------------------------------------------------------------------- Dirichlet characters take value in a finite cyclic group of roots of unity plus zero. Evaluation functions return a *ulong*, this number corresponds to the power of a primitive root of unity, the special value *DIRICHLET_CHI_NULL* encoding the zero value. .. function:: ulong dirichlet_pairing(const dirichlet_group_t G, ulong m, ulong n) .. function:: ulong dirichlet_pairing_char(const dirichlet_group_t G, const dirichlet_char_t chi, const dirichlet_char_t psi) Compute the value of the Dirichlet pairing on numbers *m* and *n*, as exponent modulo *G->expo*. The *char* variant takes as input two characters, so that no discrete logarithm is computed. The returned value is the numerator of the actual value exponent mod the group exponent *G->expo*. .. function:: ulong dirichlet_chi(const dirichlet_group_t G, const dirichlet_char_t chi, ulong n) Compute the value `\chi(n)` as the exponent modulo *G->expo*. .. function:: void dirichlet_chi_vec(ulong * v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv) Compute the list of exponent values *v[k]* for `0\leq k < nv`, as exponents modulo *G->expo*. .. function:: void dirichlet_chi_vec_order(ulong * v, const dirichlet_group_t G, const dirichlet_char_t chi, ulong order, slong nv) Compute the list of exponent values *v[k]* for `0\leq k < nv`, as exponents modulo *order*, which is assumed to be a multiple of the order of *chi*. Character operations ------------------------------------------------------------------------------- .. function:: void dirichlet_char_mul(dirichlet_char_t chi12, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2) Multiply two characters of the same group *G*. .. function:: void dirichlet_char_pow(dirichlet_char_t c, const dirichlet_group_t G, const dirichlet_char_t a, ulong n) Take the power of a character. .. function:: void dirichlet_char_lift(dirichlet_char_t chi_G, const dirichlet_group_t G, const dirichlet_char_t chi_H, const dirichlet_group_t H) If *H* is a subgroup of *G*, computes the character in *G* corresponding to *chi_H* in *H*. .. function:: void dirichlet_char_lower(dirichlet_char_t chi_H, const dirichlet_group_t H, const dirichlet_char_t chi_G, const dirichlet_group_t G) If *chi_G* is a character of *G* which factors through *H*, sets *chi_H* to the corresponding restriction in *H*. This requires `c(\chi_G)\mid q_H\mid q_G`, where `c(\chi_G)` is the conductor of `\chi_G` and `q_G, q_H` are the moduli of G and H. arb-2.22.1/doc/source/dlog.rst000066400000000000000000000243641417376376500161220ustar00rootroot00000000000000.. _dlog: **dlog.h** -- discrete logarithms mod ulong primes =============================================================================== This module implements discrete logarithms, with the application to Dirichlet characters in mind. In particular, this module defines a :type:`dlog_precomp_t` structure permitting to describe a discrete log problem in some subgroup of `(\mathbb Z/p^e \mathbb Z)^\times` for primepower moduli `p^e`, and store precomputed data for faster computation of several such discrete logarithms. When initializing this data, the user provides both a group description and the expected number of subsequent discrete logarithms calls. The choice of algorithm and the amount of stored data depend both on the structure of the group and this number. No particular effort has been made towards single discrete logarithm computation. Currently only machine size primepower moduli are supported. Types, macros and constants ------------------------------------------------------------------------------- .. macro:: DLOG_NONE Return value when the discrete logarithm does not exist .. type:: dlog_precomp_struct .. type:: dlog_precomp_t Structure for discrete logarithm precomputed data. A :type:`dlog_precomp_t` is defined as an array of length one of type :type:`dlog_precomp_struct`, permitting a :type:`dlog_precomp_t` to be passed by reference. Single evaluation ------------------------------------------------------------------------------- .. function:: ulong dlog_once(ulong b, ulong a, const nmod_t mod, ulong n) Return `x` such that `b = a^x` in `(\mathbb Z/mod \mathbb Z)^\times`, where *a* is known to have order *n*. Precomputations ------------------------------------------------------------------------------- .. function:: void dlog_precomp_n_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num) Precompute data for *num* discrete logarithms evaluations in the subgroup generated by *a* modulo *mod*, where *a* is known to have order *n*. .. function:: ulong dlog_precomp(const dlog_precomp_t pre, ulong b) Return `\log(b)` for the group described in *pre*. .. function:: void dlog_precomp_clear(dlog_precomp_t pre) Clears *t*. Specialized versions of :func:`dlog_precomp_n_init` are available when specific information is known about the group: .. function:: void dlog_precomp_modpe_init(dlog_precomp_t pre, ulong a, ulong p, ulong e, ulong pe, ulong num) Assume that *a* generates the group of residues modulo *pe* equal `p^e` for prime *p*. .. function:: void dlog_precomp_p_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong num) Assume that *a* has prime order *p*. .. function:: void dlog_precomp_pe_init(dlog_precomp_t pre, ulong a, ulong mod, ulong p, ulong e, ulong pe, ulong num) Assume that *a* has primepower order *pe* `p^e`. .. function:: void dlog_precomp_small_init(dlog_precomp_t pre, ulong a, ulong mod, ulong n, ulong num) Make a complete lookup table of size *n*. If *mod* is small, this is done using an element-indexed array (see :type:`dlog_table_t`), otherwise with a sorted array allowing binary search. Vector evaluations ------------------------------------------------------------------------------- These functions compute all logarithms of successive integers `1\dots n`. .. function:: void dlog_vec_fill(ulong * v, ulong nv, ulong x) Sets values *v[k]* to *x* for all *k* less than *nv*. .. function:: void dlog_vec_set_not_found(ulong * v, ulong nv, nmod_t mod) Sets values *v[k]* to :macro:`DLOG_NONE` for all *k* not coprime to *mod*. .. function:: void dlog_vec(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) Sets *v[k]* to `\log(k,a)` times value *va* for `0\leq k < nv`, where *a* has order *na*. *va* should be *1* for usual log computation. .. function:: void dlog_vec_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) Same parameters as before, but adds `\log(k,a)\times v_a` to *v[k]* and reduce modulo *order* instead of replacing the value. Indices *k* such that *v[k]* equals *DLOG_NONE* are ignored. Depending on the relative size of *nv* and *na*, these two *dlog_vec* functions call one of the following functions. .. function:: void dlog_vec_loop(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) .. function:: void dlog_vec_loop_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) Perform a complete loop of size *na* on powers of *a* to fill the logarithm values, discarding powers outside the bounds of *v*. This requires no discrete logarithm computation. .. function:: void dlog_vec_eratos(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) .. function:: void dlog_vec_eratos_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) Compute discrete logarithms of prime numbers less than *nv* and propagate to composite numbers. .. function:: void dlog_vec_sieve_add(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) .. function:: void dlog_vec_sieve(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) Compute the discrete logarithms of the first few prime numbers, then use them as a factor base to obtain the logarithms of larger primes by sieving techniques. In the the present implementation, the full index-calculus method is not implemented. Internal discrete logarithm strategies ------------------------------------------------------------------------------- Several discrete logarithms strategies are implemented: - Complete lookup table for small groups. - Baby-step giant-step table. combined with mathematical reductions: - Pohlig-Hellman decomposition (Chinese remainder decomposition on the order of the group and base `p` decomposition for primepower order). - p-adic log for primepower modulus `p^e`. The *dlog_precomp* structure makes recursive use of the following method-specific structures. Complete table ............................................................................... .. type:: dlog_table_struct .. type:: dlog_table_t Structure for complete lookup table. .. function:: ulong dlog_table_init(dlog_table_t t, ulong a, ulong mod) Initialize a table of powers of *a* modulo *mod*, storing all elements in an array of size *mod*. .. function:: void dlog_table_clear(dlog_table_t t) Clears *t*. .. function:: ulong dlog_table(dlog_table_t t, ulong b) Return `\log(b,a)` using the precomputed data *t*. Baby-step giant-step table ............................................................................... .. type:: dlog_bsgs_struct .. type:: dlog_bsgs_t Structure for Baby-Step Giant-Step decomposition. .. function:: ulong dlog_bsgs_init(dlog_bsgs_t t, ulong a, ulong mod, ulong n, ulong m) Initialize *t* and store the first *m* powers of *a* in a sorted array. The return value is a rought measure of the cost of each logarithm using this table. The user should take `m\approx\sqrt{kn}` to compute k logarithms in a group of size n. .. function:: void dlog_bsgs_clear(dlog_bsgs_t t) Clears *t*. .. function:: ulong dlog_bsgs(dlog_bsgs_t t, ulong b) Return `\log(b,a)` using the precomputed data *t*. Prime-power modulus decomposition ............................................................................... .. type:: dlog_modpe_struct .. type:: dlog_modpe_t Structure for discrete logarithm modulo primepower `p^e`. A :type:`dlog_modpe_t` is defined as an array of length one of type :type:`dlog_modpe_struct`, permitting a :type:`dlog_modpe_t` to be passed by reference. .. function:: ulong dlog_modpe_init(dlog_modpe_t t, ulong a, ulong p, ulong e, ulong pe, ulong num) .. function:: void dlog_modpe_clear(dlog_modpe_t t) Clears *t*. .. function:: ulong dlog_modpe(dlog_modpe_t t, ulong b) Return `\log(b,a)` using the precomputed data *t*. CRT decomposition ............................................................................... .. type:: dlog_crt_struct .. type:: dlog_crt_t Structure for discrete logarithm for groups of composite order. A :type:`dlog_crt_t` is defined as an array of length one of type :type:`dlog_crt_struct`, permitting a :type:`dlog_crt_t` to be passed by reference. .. function:: ulong dlog_crt_init(dlog_crt_t t, ulong a, ulong mod, ulong n, ulong num) Precompute data for *num* evaluations of discrete logarithms in base *a* modulo *mod*, where *a* has composite order *n*, using chinese remainder decomposition. .. function:: void dlog_crt_clear(dlog_crt_t t) Clears *t*. .. function:: ulong dlog_crt(dlog_crt_t t, ulong b) Return `\log(b,a)` using the precomputed data *t*. padic decomposition ............................................................................... .. type:: dlog_power_struct .. type:: dlog_power_t Structure for discrete logarithm for groups of primepower order. A :type:`dlog_power_t` is defined as an array of length one of type :type:`dlog_power_struct`, permitting a :type:`dlog_power_t` to be passed by reference. .. function:: ulong dlog_power_init(dlog_power_t t, ulong a, ulong mod, ulong p, ulong e, ulong num) Precompute data for *num* evaluations of discrete logarithms in base *a* modulo *mod*, where *a* has prime power order *pe* equals `p^e`, using decomposition in base *p*. .. function:: void dlog_power_clear(dlog_power_t t) Clears *t*. .. function:: ulong dlog_power(dlog_power_t t, ulong b) Return `\log(b,a)` using the precomputed data *t*. Pollard rho method ............................................................................... .. type:: dlog_rho_struct .. type:: dlog_rho_t Structure for discrete logarithm using Pollard rho. A :type:`dlog_rho_t` is defined as an array of length one of type :type:`dlog_rho_struct`, permitting a :type:`dlog_rho_t` to be passed by reference. .. function:: ulong dlog_rho_init(dlog_rho_t t, ulong a, ulong mod, ulong n, ulong num) Initialize random walks for evaluations of discrete logarithms in base *a* modulo *mod*, where *a* has order *n*. .. function:: void dlog_rho_clear(dlog_rho_t t) Clears *t*. .. function:: ulong dlog_rho(dlog_rho_t t, ulong b) Return `\log(b,a)` by the rho method in the group described by *t*. arb-2.22.1/doc/source/double_interval.rst000066400000000000000000000061351417376376500203470ustar00rootroot00000000000000.. _double_interval: **double_interval.h** -- double-precision interval arithmetic and helpers =============================================================================== This module provides helper functions for computing fast enclosures using ``double`` arithmetic. Types, macros and constants ------------------------------------------------------------------------------- .. type:: di_t Holds two ``double`` endpoints ``a`` and ``b`` representing the extended real interval `[a, b]`. We generally assume that `a \le b` and that neither endpoint is NaN. Basic manipulation ------------------------------------------------------------------------------- .. function:: di_t di_interval(double a, double b) Returns the interval `[a, b]`. We require that the endpoints are ordered and not NaN. .. function:: di_t arb_get_di(const arb_t x) Returns the ball *x* converted to a double-precision interval. .. function:: void arb_set_di(arb_t res, di_t x, slong prec) Sets the ball *res* to the double-precision interval *x*, rounded to *prec* bits. .. function:: void di_print(di_t x) Prints *x* to standard output. This simply prints decimal representations of the floating-point endpoints; the decimals are not guaranteed to be rounded outward. .. function:: double d_randtest2(flint_rand_t state) Returns a random non-NaN ``double`` with any exponent. The value can be infinite or subnormal. .. function:: di_t di_randtest(flint_rand_t state) Returns an interval with random endpoints. Arithmetic ------------------------------------------------------------------------------- .. function:: di_t di_neg(di_t x) Returns the exact negation of *x*. Fast arithmetic ------------------------------------------------------------------------------- The following methods perform fast but sloppy interval arithmetic: we manipulate the endpoints with default rounding and then add or subtract generic perturbations regardless of whether the operations were exact. It is currently assumed that the CPU rounding mode is to nearest. .. function:: di_t di_fast_add(di_t x, di_t y) di_t di_fast_sub(di_t x, di_t y) di_t di_fast_mul(di_t x, di_t y) di_t di_fast_div(di_t x, di_t y) Returns the sum, difference, product or quotient of *x* and *y*. Division by zero is currently defined to return `[-\infty, +\infty]`. .. function:: di_t di_fast_sqr(di_t x) Returns the square of *x*. The output is clamped to be nonnegative. .. function:: di_t di_fast_add_d(di_t x, double y) di_t di_fast_sub_d(di_t x, double y) di_t di_fast_mul_d(di_t x, double y) di_t di_fast_div_d(di_t x, double y) Arithmetic with an exact ``double`` operand. .. function:: di_t di_fast_log_nonnegative(di_t x) Returns an enclosure of `\log(x)`. The lower endpoint of *x* is rounded up to 0 if it is negative. .. function:: di_t di_fast_mid(di_t x) Returns an enclosure of the midpoint of *x*. .. function:: double di_fast_ubound_radius(di_t x) Returns an upper bound for the radius of *x*. arb-2.22.1/doc/source/examples.rst000066400000000000000000000717201417376376500170110ustar00rootroot00000000000000.. _examples: Example programs =============================================================================== .. highlight:: text The *examples* directory (https://github.com/fredrik-johansson/arb/tree/master/examples) contains several complete C programs, which are documented below. Running:: make examples will compile the programs and place the binaries in ``build/examples``. pi.c ------------------------------------------------------------------------------- This program computes `\pi` to an accuracy of roughly *n* decimal digits by calling the :func:`arb_const_pi` function with a working precision of roughly `n \log_2(10)` bits. Sample output, computing `\pi` to one million digits:: > build/examples/pi 1000000 computing pi with a precision of 3321933 bits... cpu/wall(s): 0.58 0.586 virt/peak/res/peak(MB): 28.24 36.84 8.86 15.56 [3.14159265358979323846{...999959 digits...}42209010610577945815 +/- 3e-1000000] The program prints an interval guaranteed to contain `\pi`, and where all displayed digits are correct up to an error of plus or minus one unit in the last place (see :func:`arb_printn`). By default, only the first and last few digits are printed. Pass 0 as a second argument to print all digits (or pass *m* to print *m* + 1 leading and *m* trailing digits, as above with the default *m* = 20). hilbert_matrix.c ------------------------------------------------------------------------------- Given an input integer *n*, this program accurately computes the determinant of the *n* by *n* Hilbert matrix. Hilbert matrices are notoriously ill-conditioned: although the entries are close to unit magnitude, the determinant `h_n` decreases superexponentially (nearly as `1/4^{n^2}`) as a function of *n*. This program automatically doubles the working precision until the ball computed for `h_n` by :func:`arb_mat_det` does not contain zero. Sample output:: $ build/examples/hilbert_matrix 200 prec=20: [+/- 1.32e-335] prec=40: [+/- 1.63e-545] prec=80: [+/- 1.30e-933] prec=160: [+/- 3.62e-1926] prec=320: [+/- 1.81e-4129] prec=640: [+/- 3.84e-8838] prec=1280: [2.955454297e-23924 +/- 8.29e-23935] success! cpu/wall(s): 8.494 8.513 virt/peak/res/peak(MB): 134.98 134.98 111.57 111.57 Called with ``-eig n``, instead of computing the determinant, the program computes the smallest eigenvalue of the Hilbert matrix (in fact, it isolates all eigenvalues and prints the smallest eigenvalue):: $ build/examples/hilbert_matrix -eig 50 prec=20: nan prec=40: nan prec=80: nan prec=160: nan prec=320: nan prec=640: [1.459157797e-74 +/- 2.49e-84] success! cpu/wall(s): 1.84 1.841 virt/peak/res/peak(MB): 33.97 33.97 10.51 10.51 keiper_li.c ------------------------------------------------------------------------------- Given an input integer *n*, this program rigorously computes numerical values of the Keiper-Li coefficients `\lambda_0, \ldots, \lambda_n`. The Keiper-Li coefficients have the property that `\lambda_n > 0` for all `n > 0` if and only if the Riemann hypothesis is true. This program was used for the record computations described in [Joh2013]_ (the paper describes the algorithm in some more detail). The program takes the following parameters:: keiper_li n [-prec prec] [-threads num_threads] [-out out_file] The program prints the first and last few coefficients. It can optionally write all the computed data to a file. The working precision defaults to a value that should give all the coefficients to a few digits of accuracy, but can optionally be set higher (or lower). On a multicore system, using several threads results in faster execution. Sample output:: > build/examples/keiper_li 1000 -threads 2 zeta: cpu/wall(s): 0.4 0.244 virt/peak/res/peak(MB): 167.98 294.69 5.09 7.43 log: cpu/wall(s): 0.03 0.038 gamma: cpu/wall(s): 0.02 0.016 binomial transform: cpu/wall(s): 0.01 0.018 0: -0.69314718055994530941723212145817656807550013436026 +/- 6.5389e-347 1: 0.023095708966121033814310247906495291621932127152051 +/- 2.0924e-345 2: 0.046172867614023335192864243096033943387066108314123 +/- 1.674e-344 3: 0.0692129735181082679304973488726010689942120263932 +/- 5.0219e-344 4: 0.092197619873060409647627872409439018065541673490213 +/- 2.0089e-343 5: 0.11510854289223549048622128109857276671349132303596 +/- 1.0044e-342 6: 0.13792766871372988290416713700341666356138966078654 +/- 6.0264e-342 7: 0.16063715965299421294040287257385366292282442046163 +/- 2.1092e-341 8: 0.18321945964338257908193931774721859848998098273432 +/- 8.4368e-341 9: 0.20565733870917046170289387421343304741236553410044 +/- 7.5931e-340 10: 0.22793393631931577436930340573684453380748385942738 +/- 7.5931e-339 991: 2.3196617961613367928373899656994682562101430813341 +/- 2.461e-11 992: 2.3203766239254884035349896518332550233162909717288 +/- 9.5363e-11 993: 2.321092061239733282811659116333262802034375592414 +/- 1.8495e-10 994: 2.3218073540188462110258826121503870112747188888893 +/- 3.5907e-10 995: 2.3225217392815185726928702951225314023773358152533 +/- 6.978e-10 996: 2.3232344485814623873333223609413703912358283071281 +/- 1.3574e-09 997: 2.3239447114886014522889542667580382034526509232475 +/- 2.6433e-09 998: 2.3246517591032700808344143240352605148856869322209 +/- 5.1524e-09 999: 2.3253548275861382119812576052060526988544993162101 +/- 1.0053e-08 1000: 2.3260531616864664574065046940832238158044982041872 +/- 3.927e-08 virt/peak/res/peak(MB): 170.18 294.69 7.51 7.51 logistic.c ------------------------------------------------------------------------------- This program computes the *n*-th iterate of the logistic map defined by `x_{n+1} = r x_n (1 - x_n)` where `r` and `x_0` are given. It takes the following parameters:: logistic n [x_0] [r] [digits] The inputs `x_0`, *r* and *digits* default to 0.5, 3.75 and 10 respectively. The computation is automatically restarted with doubled precision until the result is accurate to *digits* decimal digits. Sample output:: > build/examples/logistic 10 Trying prec=64 bits...success! cpu/wall(s): 0 0.001 x_10 = [0.6453672908 +/- 3.10e-11] > build/examples/logistic 100 Trying prec=64 bits...ran out of accuracy at step 18 Trying prec=128 bits...ran out of accuracy at step 53 Trying prec=256 bits...success! cpu/wall(s): 0 0 x_100 = [0.8882939923 +/- 1.60e-11] > build/examples/logistic 10000 Trying prec=64 bits...ran out of accuracy at step 18 Trying prec=128 bits...ran out of accuracy at step 53 Trying prec=256 bits...ran out of accuracy at step 121 Trying prec=512 bits...ran out of accuracy at step 256 Trying prec=1024 bits...ran out of accuracy at step 525 Trying prec=2048 bits...ran out of accuracy at step 1063 Trying prec=4096 bits...ran out of accuracy at step 2139 Trying prec=8192 bits...ran out of accuracy at step 4288 Trying prec=16384 bits...ran out of accuracy at step 8584 Trying prec=32768 bits...success! cpu/wall(s): 0.859 0.858 x_10000 = [0.8242048008 +/- 4.35e-11] > build/examples/logistic 1234 0.1 3.99 30 Trying prec=64 bits...ran out of accuracy at step 0 Trying prec=128 bits...ran out of accuracy at step 10 Trying prec=256 bits...ran out of accuracy at step 76 Trying prec=512 bits...ran out of accuracy at step 205 Trying prec=1024 bits...ran out of accuracy at step 461 Trying prec=2048 bits...ran out of accuracy at step 974 Trying prec=4096 bits...success! cpu/wall(s): 0.009 0.009 x_1234 = [0.256445391958651410579677945635 +/- 3.92e-31] real_roots.c ------------------------------------------------------------------------------- This program isolates the roots of a function on the interval `(a,b)` (where *a* and *b* are input as double-precision literals) using the routines in the :ref:`arb_calc ` module. The program takes the following arguments:: real_roots function a b [-refine d] [-verbose] [-maxdepth n] [-maxeval n] [-maxfound n] [-prec n] The following functions (specified by an integer code) are implemented: * 0 - `Z(x)` (Riemann-Siegel Z-function) * 1 - `\sin(x)` * 2 - `\sin(x^2)` * 3 - `\sin(1/x)` * 4 - `\operatorname{Ai}(x)` (Airy function) * 5 - `\operatorname{Ai}'(x)` (Airy function) * 6 - `\operatorname{Bi}(x)` (Airy function) * 7 - `\operatorname{Bi}'(x)` (Airy function) The following options are available: * ``-refine d``: If provided, after isolating the roots, attempt to refine the roots to *d* digits of accuracy using a few bisection steps followed by Newton's method with adaptive precision, and then print them. * ``-verbose``: Print more information. * ``-maxdepth n``: Stop searching after *n* recursive subdivisions. * ``-maxeval n``: Stop searching after approximately *n* function evaluations (the actual number evaluations will be a small multiple of this). * ``-maxfound n``: Stop searching after having found *n* isolated roots. * ``-prec n``: Working precision to use for the root isolation. With *function* 0, the program isolates roots of the Riemann zeta function on the critical line, and guarantees that no roots are missed (there are more efficient ways to do this, but it is a nice example):: > build/examples/real_roots 0 0.0 50.0 -verbose interval: [0, 50] maxdepth = 30, maxeval = 100000, maxfound = 100000, low_prec = 30 found isolated root in: [14.111328125, 14.16015625] found isolated root in: [20.99609375, 21.044921875] found isolated root in: [25, 25.048828125] found isolated root in: [30.419921875, 30.4443359375] found isolated root in: [32.91015625, 32.958984375] found isolated root in: [37.548828125, 37.59765625] found isolated root in: [40.91796875, 40.966796875] found isolated root in: [43.310546875, 43.3349609375] found isolated root in: [47.998046875, 48.0224609375] found isolated root in: [49.755859375, 49.7802734375] --------------------------------------------------------------- Found roots: 10 Subintervals possibly containing undetected roots: 0 Function evaluations: 3058 cpu/wall(s): 0.202 0.202 virt/peak/res/peak(MB): 26.12 26.14 2.76 2.76 Find just one root and refine it to approximately 75 digits:: > build/examples/real_roots 0 0.0 50.0 -maxfound 1 -refine 75 interval: [0, 50] maxdepth = 30, maxeval = 100000, maxfound = 1, low_prec = 30 refined root (0/8): [14.134725141734693790457251983562470270784257115699243175685567460149963429809 +/- 2.57e-76] --------------------------------------------------------------- Found roots: 1 Subintervals possibly containing undetected roots: 7 Function evaluations: 761 cpu/wall(s): 0.055 0.056 virt/peak/res/peak(MB): 26.12 26.14 2.75 2.75 Find the first few roots of an Airy function and refine them to 50 digits each:: > build/examples/real_roots 4 -10 0 -refine 50 interval: [-10, 0] maxdepth = 30, maxeval = 100000, maxfound = 100000, low_prec = 30 refined root (0/6): [-9.022650853340980380158190839880089256524677535156083 +/- 4.85e-52] refined root (1/6): [-7.944133587120853123138280555798268532140674396972215 +/- 1.92e-52] refined root (2/6): [-6.786708090071758998780246384496176966053882477393494 +/- 3.84e-52] refined root (3/6): [-5.520559828095551059129855512931293573797214280617525 +/- 1.05e-52] refined root (4/6): [-4.087949444130970616636988701457391060224764699108530 +/- 2.46e-52] refined root (5/6): [-2.338107410459767038489197252446735440638540145672388 +/- 1.48e-52] --------------------------------------------------------------- Found roots: 6 Subintervals possibly containing undetected roots: 0 Function evaluations: 200 cpu/wall(s): 0.003 0.003 virt/peak/res/peak(MB): 26.12 26.14 2.24 2.24 Find roots of `\sin(x^2)` on `(0,100)`. The algorithm cannot isolate the root at `x = 0` (it is at the endpoint of the interval, and in any case a root of multiplicity higher than one). The failure is reported:: > build/examples/real_roots 2 0 100 interval: [0, 100] maxdepth = 30, maxeval = 100000, maxfound = 100000, low_prec = 30 --------------------------------------------------------------- Found roots: 3183 Subintervals possibly containing undetected roots: 1 Function evaluations: 34058 cpu/wall(s): 0.032 0.032 virt/peak/res/peak(MB): 26.32 26.37 2.04 2.04 This does not miss any roots:: > build/examples/real_roots 2 1 100 interval: [1, 100] maxdepth = 30, maxeval = 100000, maxfound = 100000, low_prec = 30 --------------------------------------------------------------- Found roots: 3183 Subintervals possibly containing undetected roots: 0 Function evaluations: 34039 cpu/wall(s): 0.023 0.023 virt/peak/res/peak(MB): 26.32 26.37 2.01 2.01 Looking for roots of `\sin(1/x)` on `(0,1)`, the algorithm finds many roots, but will never find all of them since there are infinitely many:: > build/examples/real_roots 3 0.0 1.0 interval: [0, 1] maxdepth = 30, maxeval = 100000, maxfound = 100000, low_prec = 30 --------------------------------------------------------------- Found roots: 10198 Subintervals possibly containing undetected roots: 24695 Function evaluations: 202587 cpu/wall(s): 0.171 0.171 virt/peak/res/peak(MB): 28.39 30.38 4.05 4.05 Remark: the program always computes rigorous containing intervals for the roots, but the accuracy after refinement could be less than *d* digits. poly_roots.c ------------------------------------------------------------------------------- This program finds the complex roots of an integer polynomial by calling :func:`arb_fmpz_poly_complex_roots`, which in turn calls :func:`acb_poly_find_roots` with increasing precision until the roots certainly have been isolated. The program takes the following arguments:: poly_roots [-refine d] [-print d] Isolates all the complex roots of a polynomial with integer coefficients. If -refine d is passed, the roots are refined to a relative tolerance better than 10^(-d). By default, the roots are only computed to sufficient accuracy to isolate them. The refinement is not currently done efficiently. If -print d is passed, the computed roots are printed to d decimals. By default, the roots are not printed. The polynomial can be specified by passing the following as : a Easy polynomial 1 + 2x + ... + (n+1)x^n t Chebyshev polynomial T_n u Chebyshev polynomial U_n p Legendre polynomial P_n c Cyclotomic polynomial Phi_n s Swinnerton-Dyer polynomial S_n b Bernoulli polynomial B_n w Wilkinson polynomial W_n e Taylor series of exp(x) truncated to degree n m The Mignotte-like polynomial x^n + (100x+1)^m, n > m coeffs c0 + c1 x + ... + cn x^n Concatenate to multiply polynomials, e.g.: p 5 t 6 coeffs 1 2 3 for P_5(x)*T_6(x)*(1+2x+3x^2) This finds the roots of the Wilkinson polynomial with roots at the positive integers 1, 2, ..., 100:: > build/examples/poly_roots -print 15 w 100 computing squarefree factorization... cpu/wall(s): 0.001 0.001 roots with multiplicity 1 searching for 100 roots, 100 deflated prec=32: 0 isolated roots | cpu/wall(s): 0.098 0.098 prec=64: 0 isolated roots | cpu/wall(s): 0.247 0.247 prec=128: 0 isolated roots | cpu/wall(s): 0.498 0.497 prec=256: 0 isolated roots | cpu/wall(s): 0.713 0.713 prec=512: 100 isolated roots | cpu/wall(s): 0.104 0.105 done! [1.00000000000000 +/- 3e-20] [2.00000000000000 +/- 3e-19] [3.00000000000000 +/- 1e-19] [4.00000000000000 +/- 1e-19] [5.00000000000000 +/- 1e-19] ... [96.0000000000000 +/- 1e-17] [97.0000000000000 +/- 1e-17] [98.0000000000000 +/- 3e-17] [99.0000000000000 +/- 3e-17] [100.000000000000 +/- 3e-17] cpu/wall(s): 1.664 1.664 This finds the roots of a Bernoulli polynomial which has both real and complex roots:: > build/examples/poly_roots -refine 100 -print 20 b 16 computing squarefree factorization... cpu/wall(s): 0.001 0 roots with multiplicity 1 searching for 16 roots, 16 deflated prec=32: 16 isolated roots | cpu/wall(s): 0.006 0.006 prec=64: 16 isolated roots | cpu/wall(s): 0.001 0.001 prec=128: 16 isolated roots | cpu/wall(s): 0.001 0.001 prec=256: 16 isolated roots | cpu/wall(s): 0.001 0.002 prec=512: 16 isolated roots | cpu/wall(s): 0.002 0.001 done! [-0.94308706466055783383 +/- 2.02e-21] [-0.75534059252067985752 +/- 2.70e-21] [-0.24999757119077421009 +/- 4.27e-21] [0.24999757152512726002 +/- 4.43e-21] [0.75000242847487273998 +/- 4.43e-21] [1.2499975711907742101 +/- 1.43e-20] [1.7553405925206798575 +/- 1.74e-20] [1.9430870646605578338 +/- 3.21e-20] [-0.99509334829256233279 +/- 9.42e-22] + [0.44547958157103608805 +/- 3.59e-21]*I [-0.99509334829256233279 +/- 9.42e-22] + [-0.44547958157103608805 +/- 3.59e-21]*I [1.9950933482925623328 +/- 1.10e-20] + [0.44547958157103608805 +/- 3.59e-21]*I [1.9950933482925623328 +/- 1.10e-20] + [-0.44547958157103608805 +/- 3.59e-21]*I [-0.92177327714429290564 +/- 4.68e-21] + [-1.0954360955079385542 +/- 1.71e-21]*I [-0.92177327714429290564 +/- 4.68e-21] + [1.0954360955079385542 +/- 1.71e-21]*I [1.9217732771442929056 +/- 3.54e-20] + [1.0954360955079385542 +/- 1.71e-21]*I [1.9217732771442929056 +/- 3.54e-20] + [-1.0954360955079385542 +/- 1.71e-21]*I cpu/wall(s): 0.011 0.012 Roots are automatically separated by multiplicity by performing an initial squarefree factorization:: > build/examples/poly_roots -print 5 p 5 p 5 t 7 coeffs 1 5 10 10 5 1 computing squarefree factorization... cpu/wall(s): 0 0 roots with multiplicity 1 searching for 6 roots, 3 deflated prec=32: 3 isolated roots | cpu/wall(s): 0 0.001 done! [-0.97493 +/- 2.10e-6] [-0.78183 +/- 1.49e-6] [-0.43388 +/- 3.75e-6] [0.43388 +/- 3.75e-6] [0.78183 +/- 1.49e-6] [0.97493 +/- 2.10e-6] roots with multiplicity 2 searching for 4 roots, 2 deflated prec=32: 2 isolated roots | cpu/wall(s): 0 0 done! [-0.90618 +/- 1.56e-7] [-0.53847 +/- 6.91e-7] [0.53847 +/- 6.91e-7] [0.90618 +/- 1.56e-7] roots with multiplicity 3 searching for 1 roots, 0 deflated prec=32: 0 isolated roots | cpu/wall(s): 0 0 done! 0 roots with multiplicity 5 searching for 1 roots, 1 deflated prec=32: 1 isolated roots | cpu/wall(s): 0 0 done! -1.0000 cpu/wall(s): 0 0.001 complex_plot.c ------------------------------------------------------------------------------- This program plots one of the predefined functions over a complex interval `[x_a, x_b] + [y_a, y_b]i` using domain coloring, at a resolution of *xn* times *yn* pixels. The program takes the parameters:: complex_plot [-range xa xb ya yb] [-size xn yn] Defaults parameters are `[-10,10] + [-10,10]i` and *xn* = *yn* = 512. A color function can be selected with -color. Valid options are 0 (phase=hue, magnitude=brightness) and 1 (phase only, white-gold-black-blue-white counterclockwise). The output is written to ``arbplot.ppm``. If you have ImageMagick, run ``convert arbplot.ppm arbplot.png`` to get a PNG. Function codes ```` are: * ``gamma`` - Gamma function * ``digamma`` - Digamma function * ``lgamma`` - Logarithmic gamma function * ``zeta`` - Riemann zeta function * ``erf`` - Error function * ``ai`` - Airy function Ai * ``bi`` - Airy function Bi * ``besselj`` - Bessel function `J_0` * ``bessely`` - Bessel function `Y_0` * ``besseli`` - Bessel function `I_0` * ``besselk`` - Bessel function `K_0` * ``modj`` - Modular j-function * ``modeta`` - Dedekind eta function * ``barnesg`` - Barnes G-function * ``agm`` - Arithmetic geometric mean The function is just sampled at point values; no attempt is made to resolve small features by adaptive subsampling. For example, the following plots the Riemann zeta function around a portion of the critical strip with imaginary part between 100 and 140:: > build/examples/complex_plot zeta -range -10 10 100 140 -size 256 512 lvalue.c ------------------------------------------------------------------------------- This program evaluates Dirichlet L-functions. It takes the following input:: > build/examples/lvalue lvalue [-character q n] [-re a] [-im b] [-prec p] [-z] [-deflate] [-len l] Print value of Dirichlet L-function at s = a+bi. Default a = 0.5, b = 0, p = 53, (q, n) = (1, 0) (Riemann zeta) [-z] - compute Z(s) instead of L(s) [-deflate] - remove singular term at s = 1 [-len l] - compute l terms in Taylor series at s Evaluating the Riemann zeta function and the Dirichlet beta function at `s = 2`:: > build/examples/lvalue -re 2 -prec 128 L(s) = [1.64493406684822643647241516664602518922 +/- 4.37e-39] cpu/wall(s): 0.001 0.001 virt/peak/res/peak(MB): 26.86 26.88 2.05 2.05 > build/examples/lvalue -character 4 3 -re 2 -prec 128 L(s) = [0.91596559417721901505460351493238411077 +/- 7.86e-39] cpu/wall(s): 0.002 0.003 virt/peak/res/peak(MB): 26.86 26.88 2.31 2.31 Evaluating the L-function for character number 101 modulo 1009 at `s = 1/2` and `s = 1`:: > build/examples/lvalue -character 1009 101 L(s) = [-0.459256562383872 +/- 5.24e-16] + [1.346937111206009 +/- 3.03e-16]*I cpu/wall(s): 0.012 0.012 virt/peak/res/peak(MB): 26.86 26.88 2.30 2.30 > build/examples/lvalue -character 1009 101 -re 1 L(s) = [0.657952586112728 +/- 6.02e-16] + [1.004145273214022 +/- 3.10e-16]*I cpu/wall(s): 0.017 0.018 virt/peak/res/peak(MB): 26.86 26.88 2.30 2.30 Computing the first few coefficients in the Laurent series of the Riemann zeta function at `s = 1`:: > build/examples/lvalue -re 1 -deflate -len 8 L(s) = [0.577215664901532861 +/- 5.29e-19] L'(s) = [0.072815845483676725 +/- 2.68e-19] [x^2] L(s+x) = [-0.004845181596436159 +/- 3.87e-19] [x^3] L(s+x) = [-0.000342305736717224 +/- 4.20e-19] [x^4] L(s+x) = [9.6890419394471e-5 +/- 2.40e-19] [x^5] L(s+x) = [-6.6110318108422e-6 +/- 4.51e-20] [x^6] L(s+x) = [-3.316240908753e-7 +/- 3.85e-20] [x^7] L(s+x) = [1.0462094584479e-7 +/- 7.78e-21] cpu/wall(s): 0.003 0.004 virt/peak/res/peak(MB): 26.86 26.88 2.30 2.30 Evaluating the Riemann zeta function near the first nontrivial root:: > build/examples/lvalue -re 0.5 -im 14.134725 L(s) = [1.76743e-8 +/- 1.93e-14] + [-1.110203e-7 +/- 2.84e-14]*I cpu/wall(s): 0.001 0.001 virt/peak/res/peak(MB): 26.86 26.88 2.31 2.31 > build/examples/lvalue -z -re 14.134725 -prec 200 Z(s) = [-1.12418349839417533300111494358128257497862927935658e-7 +/- 4.62e-58] cpu/wall(s): 0.001 0.001 virt/peak/res/peak(MB): 26.86 26.88 2.57 2.57 > build/examples/lvalue -z -re 14.134725 -len 4 Z(s) = [-1.124184e-7 +/- 7.00e-14] Z'(s) = [0.793160414884 +/- 4.09e-13] [x^2] Z(s+x) = [0.065164586492 +/- 5.39e-13] [x^3] Z(s+x) = [-0.020707762705 +/- 5.37e-13] cpu/wall(s): 0.002 0.003 virt/peak/res/peak(MB): 26.86 26.88 2.57 2.57 lcentral.c ------------------------------------------------------------------------------- This program computes the central value `L(1/2)` for each Dirichlet L-function character modulo *q* for each *q* in the range *qmin* to *qmax*. Usage:: > build/examples/lcentral Computes central values (s = 0.5) of Dirichlet L-functions. usage: build/examples/lcentral [--quiet] [--check] [--prec ] qmin qmax The first few values:: > build/examples/lcentral 1 8 3,2: [0.48086755769682862618122006324 +/- 7.35e-30] 4,3: [0.66769145718960917665869092930 +/- 1.62e-30] 5,2: [0.76374788011728687822451215264 +/- 2.32e-30] + [0.21696476751886069363858659310 +/- 3.06e-30]*I 5,4: [0.23175094750401575588338366176 +/- 2.21e-30] 5,3: [0.76374788011728687822451215264 +/- 2.32e-30] + [-0.21696476751886069363858659310 +/- 3.06e-30]*I 7,3: [0.71394334376831949285993820742 +/- 1.21e-30] + [0.47490218277139938263745243935 +/- 4.52e-30]*I 7,2: [0.31008936259836766059195052534 +/- 5.29e-30] + [-0.07264193137017790524562171245 +/- 5.48e-30]*I 7,6: [1.14658566690370833367712697646 +/- 1.95e-30] 7,4: [0.31008936259836766059195052534 +/- 5.29e-30] + [0.07264193137017790524562171245 +/- 5.48e-30]*I 7,5: [0.71394334376831949285993820742 +/- 1.21e-30] + [-0.47490218277139938263745243935 +/- 4.52e-30]*I 8,5: [0.37369171291254730738158695002 +/- 4.01e-30] 8,3: [1.10042140952554837756713576997 +/- 3.37e-30] cpu/wall(s): 0.002 0.003 virt/peak/res/peak(MB): 26.32 26.34 2.35 2.35 Testing a large *q*:: > build/examples/lcentral --quiet --check --prec 256 100000 100000 cpu/wall(s): 1.668 1.667 virt/peak/res/peak(MB): 35.67 46.66 11.67 22.61 It is conjectured that the central value never vanishes. Running with ``--check`` verifies that the interval certainly is nonzero. This can fail with insufficient precision:: > build/examples/lcentral --check --prec 15 100000 100000 100000,71877: [0.1 +/- 0.0772] + [+/- 0.136]*I 100000,90629: [2e+0 +/- 0.106] + [+/- 0.920]*I 100000,28133: [+/- 0.811] + [-2e+0 +/- 0.501]*I 100000,3141: [0.8 +/- 0.0407] + [-0.1 +/- 0.0243]*I 100000,53189: [4.0 +/- 0.0826] + [+/- 0.107]*I 100000,53253: [1.9 +/- 0.0855] + [-3.9 +/- 0.0681]*I Value could be zero! 100000,53381: [+/- 0.0329] + [+/- 0.0413]*I Aborted integrals.c ------------------------------------------------------------------------------- This program computes integrals using :func:`acb_calc_integrate`. Invoking the program without parameters shows usage:: > build/examples/integrals Compute integrals using acb_calc_integrate. Usage: integrals -i n [-prec p] [-tol eps] [-twice] [...] -i n - compute integral n (0 <= n <= 23), or "-i all" -prec p - precision in bits (default p = 64) -goal p - approximate relative accuracy goal (default p) -tol eps - approximate absolute error goal (default 2^-p) -twice - run twice (to see overhead of computing nodes) -heap - use heap for subinterval queue -verbose - show information -verbose2 - show more information -deg n - use quadrature degree up to n -eval n - limit number of function evaluations to n -depth n - limit subinterval queue size to n Implemented integrals: I0 = int_0^100 sin(x) dx I1 = 4 int_0^1 1/(1+x^2) dx I2 = 2 int_0^{inf} 1/(1+x^2) dx (using domain truncation) I3 = 4 int_0^1 sqrt(1-x^2) dx I4 = int_0^8 sin(x+exp(x)) dx I5 = int_1^101 floor(x) dx I6 = int_0^1 |x^4+10x^3+19x^2-6x-6| exp(x) dx I7 = 1/(2 pi i) int zeta(s) ds (closed path around s = 1) I8 = int_0^1 sin(1/x) dx (slow convergence, use -heap and/or -tol) I9 = int_0^1 x sin(1/x) dx (slow convergence, use -heap and/or -tol) I10 = int_0^10000 x^1000 exp(-x) dx I11 = int_1^{1+1000i} gamma(x) dx I12 = int_{-10}^{10} sin(x) + exp(-200-x^2) dx I13 = int_{-1020}^{-1010} exp(x) dx (use -tol 0 for relative error) I14 = int_0^{inf} exp(-x^2) dx (using domain truncation) I15 = int_0^1 sech(10(x-0.2))^2 + sech(100(x-0.4))^4 + sech(1000(x-0.6))^6 dx I16 = int_0^8 (exp(x)-floor(exp(x))) sin(x+exp(x)) dx (use higher -eval) I17 = int_0^{inf} sech(x) dx (using domain truncation) I18 = int_0^{inf} sech^3(x) dx (using domain truncation) I19 = int_0^1 -log(x)/(1+x) dx (using domain truncation) I20 = int_0^{inf} x exp(-x)/(1+exp(-x)) dx (using domain truncation) I21 = int_C wp(x)/x^(11) dx (contour for 10th Laurent coefficient of Weierstrass p-function) I22 = N(1000) = count zeros with 0 < t <= 1000 of zeta(s) using argument principle I23 = int_0^{1000} W_0(x) dx I24 = int_0^pi max(sin(x), cos(x)) dx I25 = int_{-1}^1 erf(x/sqrt(0.0002)*0.5+1.5)*exp(-x) dx I26 = int_{-10}^10 Ai(x) dx I27 = int_0^10 (x-floor(x)-1/2) max(sin(x),cos(x)) dx I28 = int_{-1-i}^{-1+i} sqrt(x) dx I29 = int_0^{inf} exp(-x^2+ix) dx (using domain truncation) I30 = int_0^{inf} exp(-x) Ai(-x) dx (using domain truncation) I31 = int_0^pi x sin(x) / (1 + cos(x)^2) dx A few examples:: build/examples/integrals -i 4 I4 = int_0^8 sin(x+exp(x)) dx ... cpu/wall(s): 0.02 0.02 I4 = [0.34740017265725 +/- 3.95e-15] > build/examples/integrals -i 3 -prec 333 -tol 1e-80 I3 = 4 int_0^1 sqrt(1-x^2) dx ... cpu/wall(s): 0.024 0.024 I3 = [3.141592653589793238462643383279502884197169399375105820974944592307816406286209 +/- 4.24e-79] > build/examples/integrals -i 9 -heap I9 = int_0^1 x sin(1/x) dx (slow convergence, use -heap and/or -tol) ... cpu/wall(s): 0.019 0.018 I9 = [0.3785300 +/- 3.17e-8] fpwrap.c ------------------------------------------------------------------------------- This program demonstrates calling the floating-point wrapper:: > build/examples/fpwrap zeta(2) = 1.644934066848226 zeta(0.5 + 123i) = 0.006252861175594465 + 0.08206030514520983i .. highlight:: c arb-2.22.1/doc/source/fmpr.rst000066400000000000000000000553151417376376500161410ustar00rootroot00000000000000.. _fmpr: **fmpr.h** -- Arb 1.x floating-point numbers (deprecated) =============================================================================== This module is deprecated, and any methods contained herein could disappear in the future. This module is mainly kept for testing the faster :type:`arf_t` type that was introduced in Arb 2.0. Please use :type:`arf_t` instead of the :type:`fmpr_t` type. A variable of type :type:`fmpr_t` holds an arbitrary-precision binary floating-point number, i.e. a rational number of the form `x \times 2^y` where `x, y \in \mathbb{Z}` and `x` is odd; or one of the special values zero, plus infinity, minus infinity, or NaN (not-a-number). The component `x` is called the *mantissa*, and `y` is called the *exponent*. Note that this is just one among many possible conventions: the mantissa (alternatively *significand*) is sometimes viewed as a fraction in the interval `[1/2, 1)`, with the exponent pointing to the position above the top bit rather than the position of the bottom bit, and with a separate sign. The conventions for special values largely follow those of the IEEE floating-point standard. At the moment, there is no support for negative zero, unsigned infinity, or a NaN with a payload, though some these might be added in the future. An *fmpr* number is exact and has no inherent "accuracy". We use the term *precision* to denote either the target precision of an operation, or the bit size of a mantissa (which in general is unrelated to the "accuracy" of the number: for example, the floating-point value 1 has a precision of 1 bit in this sense and is simultaneously an infinitely accurate approximation of the integer 1 and a 2-bit accurate approximation of `\sqrt 2 = 1.011010100\ldots_2`). Except where otherwise noted, the output of an operation is the floating-point number obtained by taking the inputs as exact numbers, in principle carrying out the operation exactly, and rounding the resulting real number to the nearest representable floating-point number whose mantissa has at most the specified number of bits, in the specified direction of rounding. Some operations are always or optionally done exactly. Types, macros and constants ------------------------------------------------------------------------------- .. type:: fmpr_struct An *fmpr_struct* holds a mantissa and an exponent. If the mantissa and exponent are sufficiently small, their values are stored as immediate values in the *fmpr_struct*; large values are represented by pointers to heap-allocated arbitrary-precision integers. Currently, both the mantissa and exponent are implemented using the FLINT *fmpz* type. Special values are currently encoded by the mantissa being set to zero. .. type:: fmpr_t An *fmpr_t* is defined as an array of length one of type *fmpr_struct*, permitting an *fmpr_t* to be passed by reference. .. type:: fmpr_rnd_t Specifies the rounding mode for the result of an approximate operation. .. macro:: FMPR_RND_DOWN Specifies that the result of an operation should be rounded to the nearest representable number in the direction towards zero. .. macro:: FMPR_RND_UP Specifies that the result of an operation should be rounded to the nearest representable number in the direction away from zero. .. macro:: FMPR_RND_FLOOR Specifies that the result of an operation should be rounded to the nearest representable number in the direction towards minus infinity. .. macro:: FMPR_RND_CEIL Specifies that the result of an operation should be rounded to the nearest representable number in the direction towards plus infinity. .. macro:: FMPR_RND_NEAR Specifies that the result of an operation should be rounded to the nearest representable number, rounding to an odd mantissa if there is a tie between two values. *Warning*: this rounding mode is currently not implemented (except for a few conversions functions where this stated explicitly). .. macro:: FMPR_PREC_EXACT If passed as the precision parameter to a function, indicates that no rounding is to be performed. This must only be used when it is known that the result of the operation can be represented exactly and fits in memory (the typical use case is working small integer values). Note that, for example, adding two numbers whose exponents are far apart can easily produce an exact result that is far too large to store in memory. Memory management ------------------------------------------------------------------------------- .. function:: void fmpr_init(fmpr_t x) Initializes the variable *x* for use. Its value is set to zero. .. function:: void fmpr_clear(fmpr_t x) Clears the variable *x*, freeing or recycling its allocated memory. Special values ------------------------------------------------------------------------------- .. function:: void fmpr_zero(fmpr_t x) .. function:: void fmpr_one(fmpr_t x) .. function:: void fmpr_pos_inf(fmpr_t x) .. function:: void fmpr_neg_inf(fmpr_t x) .. function:: void fmpr_nan(fmpr_t x) Sets *x* respectively to 0, 1, `+\infty`, `-\infty`, NaN. .. function:: int fmpr_is_zero(const fmpr_t x) .. function:: int fmpr_is_one(const fmpr_t x) .. function:: int fmpr_is_pos_inf(const fmpr_t x) .. function:: int fmpr_is_neg_inf(const fmpr_t x) .. function:: int fmpr_is_nan(const fmpr_t x) Returns nonzero iff *x* respectively equals 0, 1, `+\infty`, `-\infty`, NaN. .. function:: int fmpr_is_inf(const fmpr_t x) Returns nonzero iff *x* equals either `+\infty` or `-\infty`. .. function:: int fmpr_is_normal(const fmpr_t x) Returns nonzero iff *x* is a finite, nonzero floating-point value, i.e. not one of the special values 0, `+\infty`, `-\infty`, NaN. .. function:: int fmpr_is_special(const fmpr_t x) Returns nonzero iff *x* is one of the special values 0, `+\infty`, `-\infty`, NaN, i.e. not a finite, nonzero floating-point value. .. function:: int fmpr_is_finite(fmpr_t x) Returns nonzero iff *x* is a finite floating-point value, i.e. not one of the values `+\infty`, `-\infty`, NaN. (Note that this is not equivalent to the negation of :func:`fmpr_is_inf`.) Assignment, rounding and conversions ------------------------------------------------------------------------------- .. function:: slong _fmpr_normalise(fmpz_t man, fmpz_t exp, slong prec, fmpr_rnd_t rnd) Rounds the mantissa and exponent in-place. .. function:: void fmpr_set(fmpr_t y, const fmpr_t x) Sets *y* to a copy of *x*. .. function:: void fmpr_swap(fmpr_t x, fmpr_t y) Swaps *x* and *y* efficiently. .. function:: slong fmpr_set_round(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_set_round_fmpz(fmpr_t y, const fmpz_t x, slong prec, fmpr_rnd_t rnd) Sets *y* to a copy of *x* rounded in the direction specified by rnd to the number of bits specified by prec. .. function:: slong _fmpr_set_round_mpn(slong * shift, fmpz_t man, mp_srcptr x, mp_size_t xn, int negative, slong prec, fmpr_rnd_t rnd) Given an integer represented by a pointer *x* to a raw array of *xn* limbs (negated if *negative* is nonzero), sets *man* to the corresponding floating-point mantissa rounded to *prec* bits in direction *rnd*, sets *shift* to the exponent, and returns the error bound. We require that *xn* is positive and that the leading limb of *x* is nonzero. .. function:: slong fmpr_set_round_ui_2exp_fmpz(fmpr_t z, mp_limb_t lo, const fmpz_t exp, int negative, slong prec, fmpr_rnd_t rnd) Sets *z* to the unsigned integer *lo* times two to the power *exp*, negating the value if *negative* is nonzero, and rounding the result to *prec* bits in direction *rnd*. .. function:: slong fmpr_set_round_uiui_2exp_fmpz(fmpr_t z, mp_limb_t hi, mp_limb_t lo, const fmpz_t exp, int negative, slong prec, fmpr_rnd_t rnd) Sets *z* to the unsigned two-limb integer *{hi, lo}* times two to the power *exp*, negating the value if *negative* is nonzero, and rounding the result to *prec* bits in direction *rnd*. .. function:: void fmpr_set_error_result(fmpr_t err, const fmpr_t result, slong rret) Given the return value *rret* and output variable *result* from a function performing a rounding (e.g. *fmpr_set_round* or *fmpr_add*), sets *err* to a bound for the absolute error. .. function:: void fmpr_add_error_result(fmpr_t err, const fmpr_t err_in, const fmpr_t result, slong rret, slong prec, fmpr_rnd_t rnd) Like *fmpr_set_error_result*, but adds *err_in* to the error. .. function:: void fmpr_ulp(fmpr_t u, const fmpr_t x, slong prec) Sets *u* to the floating-point unit in the last place (ulp) of *x*. The ulp is defined as in the MPFR documentation and satisfies `2^{-n} |x| < u \le 2^{-n+1} |x|` for any finite nonzero *x*. If *x* is a special value, *u* is set to the absolute value of *x*. .. function:: int fmpr_check_ulp(const fmpr_t x, slong r, slong prec) Assume that *r* is the return code and *x* is the floating-point result from a single floating-point rounding. Then this function returns nonzero iff *x* and *r* define an error of exactly 0 or 1 ulp. In other words, this function checks that :func:`fmpr_set_error_result` gives exactly 0 or 1 ulp as expected. .. function:: int fmpr_get_mpfr(mpfr_t x, const fmpr_t y, mpfr_rnd_t rnd) Sets the MPFR variable *x* to the value of *y*. If the precision of *x* is too small to allow *y* to be represented exactly, it is rounded in the specified MPFR rounding mode. The return value indicates the direction of rounding, following the standard convention of the MPFR library. .. function:: void fmpr_set_mpfr(fmpr_t x, const mpfr_t y) Sets *x* to the exact value of the MPFR variable *y*. .. function:: double fmpr_get_d(const fmpr_t x, fmpr_rnd_t rnd) Returns *x* rounded to a *double* in the direction specified by *rnd*. .. function:: void fmpr_set_d(fmpr_t x, double v) Sets *x* the the exact value of the argument *v* of type *double*. .. function:: void fmpr_set_ui(fmpr_t x, ulong c) .. function:: void fmpr_set_si(fmpr_t x, slong c) .. function:: void fmpr_set_fmpz(fmpr_t x, const fmpz_t c) Sets *x* exactly to the integer *c*. .. function:: void fmpr_get_fmpz(fmpz_t z, const fmpr_t x, fmpr_rnd_t rnd) Sets *z* to *x* rounded to the nearest integer in the direction specified by *rnd*. If *rnd* is *FMPR_RND_NEAR*, rounds to the nearest even integer in case of a tie. Aborts if *x* is infinite, NaN or if the exponent is unreasonably large. .. function:: slong fmpr_get_si(const fmpr_t x, fmpr_rnd_t rnd) Returns *x* rounded to the nearest integer in the direction specified by *rnd*. If *rnd* is *FMPR_RND_NEAR*, rounds to the nearest even integer in case of a tie. Aborts if *x* is infinite, NaN, or the value is too large to fit in an *slong*. .. function:: void fmpr_get_fmpq(fmpq_t y, const fmpr_t x) Sets *y* to the exact value of *x*. The result is undefined if *x* is not a finite fraction. .. function:: slong fmpr_set_fmpq(fmpr_t x, const fmpq_t y, slong prec, fmpr_rnd_t rnd) Sets *x* to the value of *y*, rounded according to *prec* and *rnd*. .. function:: void fmpr_set_fmpz_2exp(fmpr_t x, const fmpz_t man, const fmpz_t exp) .. function:: void fmpr_set_si_2exp_si(fmpr_t x, slong man, slong exp) .. function:: void fmpr_set_ui_2exp_si(fmpr_t x, ulong man, slong exp) Sets *x* to `\mathrm{man} \times 2^{\mathrm{exp}}`. .. function:: slong fmpr_set_round_fmpz_2exp(fmpr_t x, const fmpz_t man, const fmpz_t exp, slong prec, fmpr_rnd_t rnd) Sets *x* to `\mathrm{man} \times 2^{\mathrm{exp}}`, rounded according to *prec* and *rnd*. .. function:: void fmpr_get_fmpz_2exp(fmpz_t man, fmpz_t exp, const fmpr_t x) Sets *man* and *exp* to the unique integers such that `x = \mathrm{man} \times 2^{\mathrm{exp}}` and *man* is odd, provided that *x* is a nonzero finite fraction. If *x* is zero, both *man* and *exp* are set to zero. If *x* is infinite or NaN, the result is undefined. .. function:: int fmpr_get_fmpz_fixed_fmpz(fmpz_t y, const fmpr_t x, const fmpz_t e) .. function:: int fmpr_get_fmpz_fixed_si(fmpz_t y, const fmpr_t x, slong e) Converts *x* to a mantissa with predetermined exponent, i.e. computes an integer *y* such that `y \times 2^e \approx x`, truncating if necessary. Returns 0 if exact and 1 if truncation occurred. Comparisons ------------------------------------------------------------------------------- .. function:: int fmpr_equal(const fmpr_t x, const fmpr_t y) Returns nonzero iff *x* and *y* are exactly equal. This function does not treat NaN specially, i.e. NaN compares as equal to itself. .. function:: int fmpr_cmp(const fmpr_t x, const fmpr_t y) Returns negative, zero, or positive, depending on whether *x* is respectively smaller, equal, or greater compared to *y*. Comparison with NaN is undefined. .. function:: int fmpr_cmpabs(const fmpr_t x, const fmpr_t y) .. function:: int fmpr_cmpabs_ui(const fmpr_t x, ulong y) Compares the absolute values of *x* and *y*. .. function:: int fmpr_cmp_2exp_si(const fmpr_t x, slong e) .. function:: int fmpr_cmpabs_2exp_si(const fmpr_t x, slong e) Compares *x* (respectively its absolute value) with `2^e`. .. function:: int fmpr_sgn(const fmpr_t x) Returns `-1`, `0` or `+1` according to the sign of *x*. The sign of NaN is undefined. .. function:: void fmpr_min(fmpr_t z, const fmpr_t a, const fmpr_t b) .. function:: void fmpr_max(fmpr_t z, const fmpr_t a, const fmpr_t b) Sets *z* respectively to the minimum and the maximum of *a* and *b*. .. function:: slong fmpr_bits(const fmpr_t x) Returns the number of bits needed to represent the absolute value of the mantissa of *x*, i.e. the minimum precision sufficient to represent *x* exactly. Returns 0 if *x* is a special value. .. function:: int fmpr_is_int(const fmpr_t x) Returns nonzero iff *x* is integer-valued. .. function:: int fmpr_is_int_2exp_si(const fmpr_t x, slong e) Returns nonzero iff *x* equals `n 2^e` for some integer *n*. Random number generation ------------------------------------------------------------------------------- .. function:: void fmpr_randtest(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) Generates a finite random number whose mantissa has precision at most *bits* and whose exponent has at most *mag_bits* bits. The values are distributed non-uniformly: special bit patterns are generated with high probability in order to allow the test code to exercise corner cases. .. function:: void fmpr_randtest_not_zero(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) Identical to *fmpr_randtest*, except that zero is never produced as an output. .. function:: void fmpr_randtest_special(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) Identical to *fmpr_randtest*, except that the output occasionally is set to an infinity or NaN. Input and output ------------------------------------------------------------------------------- .. function:: void fmpr_print(const fmpr_t x) Prints the mantissa and exponent of *x* as integers, precisely showing the internal representation. .. function:: void fmpr_printd(const fmpr_t x, slong digits) Prints *x* as a decimal floating-point number, rounding to the specified number of digits. This function is currently implemented using MPFR, and does not support large exponents. Arithmetic ------------------------------------------------------------------------------- .. function:: void fmpr_neg(fmpr_t y, const fmpr_t x) Sets *y* to the negation of *x*. .. function:: slong fmpr_neg_round(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) Sets *y* to the negation of *x*, rounding the result. .. function:: void fmpr_abs(fmpr_t y, const fmpr_t x) Sets *y* to the absolute value of *x*. .. function:: slong fmpr_add(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_add_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_add_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_add_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) Sets `z = x + y`, rounded according to *prec* and *rnd*. The precision can be *FMPR_PREC_EXACT* to perform an exact addition, provided that the result fits in memory. .. function:: slong _fmpr_add_eps(fmpr_t z, const fmpr_t x, int sign, slong prec, fmpr_rnd_t rnd) Sets *z* to the value that results by adding an infinitesimal quantity of the given sign to *x*, and rounding. The result is undefined if *x* is zero. .. function:: slong fmpr_sub(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_sub_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_sub_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_sub_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) Sets `z = x - y`, rounded according to *prec* and *rnd*. The precision can be *FMPR_PREC_EXACT* to perform an exact addition, provided that the result fits in memory. .. function:: slong fmpr_mul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_mul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_mul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_mul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) Sets `z = x \times y`, rounded according to prec and rnd. The precision can be *FMPR_PREC_EXACT* to perform an exact multiplication, provided that the result fits in memory. .. function:: void fmpr_mul_2exp_si(fmpr_t y, const fmpr_t x, slong e) .. function:: void fmpr_mul_2exp_fmpz(fmpr_t y, const fmpr_t x, const fmpz_t e) Sets *y* to *x* multiplied by `2^e` without rounding. .. function:: slong fmpr_div(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_div_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_ui_div(fmpr_t z, ulong x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_div_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_si_div(fmpr_t z, slong x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_div_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_fmpz_div(fmpr_t z, const fmpz_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_fmpz_div_fmpz(fmpr_t z, const fmpz_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) Sets `z = x / y`, rounded according to *prec* and *rnd*. If *y* is zero, *z* is set to NaN. .. function:: slong fmpr_addmul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_addmul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_addmul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_addmul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) Sets `z = z + x \times y`, rounded according to *prec* and *rnd*. The intermediate multiplication is always performed without roundoff. The precision can be *FMPR_PREC_EXACT* to perform an exact addition, provided that the result fits in memory. .. function:: slong fmpr_submul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_submul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_submul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) .. function:: slong fmpr_submul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) Sets `z = z - x \times y`, rounded according to *prec* and *rnd*. The intermediate multiplication is always performed without roundoff. The precision can be *FMPR_PREC_EXACT* to perform an exact subtraction, provided that the result fits in memory. .. function:: slong fmpr_sqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) Sets *z* to the square root of *x*, rounded according to *prec* and *rnd*. The result is NaN if *x* is negative. .. function:: slong fmpr_rsqrt(fmpr_t z, const fmpr_t x, slong prec, fmpr_rnd_t rnd) Sets *z* to the reciprocal square root of *x*, rounded according to *prec* and *rnd*. The result is NaN if *x* is negative. At high precision, this is faster than computing a square root. .. function:: slong fmpr_root(fmpr_t z, const fmpr_t x, ulong k, slong prec, fmpr_rnd_t rnd) Sets *z* to the *k*-th root of *x*, rounded to *prec* bits in the direction *rnd*. Warning: this function wraps MPFR, and is currently only fast for small *k*. .. function:: void fmpr_pow_sloppy_fmpz(fmpr_t y, const fmpr_t b, const fmpz_t e, slong prec, fmpr_rnd_t rnd) .. function:: void fmpr_pow_sloppy_ui(fmpr_t y, const fmpr_t b, ulong e, slong prec, fmpr_rnd_t rnd) .. function:: void fmpr_pow_sloppy_si(fmpr_t y, const fmpr_t b, slong e, slong prec, fmpr_rnd_t rnd) Sets `y = b^e`, computed using without guaranteeing correct (optimal) rounding, but guaranteeing that the result is a correct upper or lower bound if the rounding is directional. Currently requires `b \ge 0`. Special functions ------------------------------------------------------------------------------- .. function:: slong fmpr_log(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) Sets *y* to `\log(x)`, rounded according to *prec* and *rnd*. The result is NaN if *x* is negative. This function is currently implemented using MPFR and does not support large exponents. .. function:: slong fmpr_log1p(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) Sets *y* to `\log(1+x)`, rounded according to *prec* and *rnd*. This function computes an accurate value when *x* is small. The result is NaN if `1+x` is negative. This function is currently implemented using MPFR and does not support large exponents. .. function:: slong fmpr_exp(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) Sets *y* to `\exp(x)`, rounded according to *prec* and *rnd*. This function is currently implemented using MPFR and does not support large exponents. .. function:: slong fmpr_expm1(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) Sets *y* to `\exp(x)-1`, rounded according to *prec* and *rnd*. This function computes an accurate value when *x* is small. This function is currently implemented using MPFR and does not support large exponents. arb-2.22.1/doc/source/fmpz_extras.rst000066400000000000000000000112541417376376500175310ustar00rootroot00000000000000.. _fmpz_extras: **fmpz_extras.h** -- extra methods for FLINT integers =============================================================================== This module implements a few utility methods for the FLINT multiprecision integer type (*fmpz_t*). It is mainly intended for internal use. Memory-related methods ------------------------------------------------------------------------------- .. function:: slong fmpz_allocated_bytes(const fmpz_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(fmpz)`` to get the size of the object as a whole. Convenience methods ------------------------------------------------------------------------------- .. function:: void fmpz_add_si(fmpz_t z, const fmpz_t x, slong y) .. function:: void fmpz_sub_si(fmpz_t z, const fmpz_t x, slong y) Sets *z* to the sum (respectively difference) of *x* and *y*. .. function:: void fmpz_adiv_q_2exp(fmpz_t z, const fmpz_t x, flint_bitcnt_t exp) Sets *z* to `x / 2^{exp}`, rounded away from zero. .. function:: void fmpz_ui_mul_ui(fmpz_t x, ulong a, ulong b) Sets *x* to *a* times *b*. .. function:: void fmpz_ui_pow_ui(fmpz_t x, ulong b, ulong e) Sets *x* to *b* raised to the power *e*. .. function:: void fmpz_max(fmpz_t z, const fmpz_t x, const fmpz_t y) .. function:: void fmpz_min(fmpz_t z, const fmpz_t x, const fmpz_t y) Sets *z* to the maximum (respectively minimum) of *x* and *y*. Inlined arithmetic ------------------------------------------------------------------------------- The *fmpz_t* bignum type uses an immediate representation for small integers, specifically when the absolute value is at most `2^{62}-1` (on 64-bit machines) or `2^{30}-1` (on 32-bit machines). The following methods completely inline the case where all operands (and possibly some intermediate values in the calculation) are known to be small. This is faster in code where all values *almost certainly will be much smaller than a full word*. In particular, these methods are used within Arb for manipulating exponents of floating-point numbers. Inlining slows down the general case, and increases code size, so these methods should not be used gratuitously. .. function:: void fmpz_add_inline(fmpz_t z, const fmpz_t x, const fmpz_t y) .. function:: void fmpz_add_si_inline(fmpz_t z, const fmpz_t x, slong y) .. function:: void fmpz_add_ui_inline(fmpz_t z, const fmpz_t x, ulong y) Sets *z* to the sum of *x* and *y*. .. function:: void fmpz_sub_si_inline(fmpz_t z, const fmpz_t x, slong y) Sets *z* to the difference of *x* and *y*. .. function:: void fmpz_add2_fmpz_si_inline(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c) Sets *z* to the sum of *x*, *y*, and *c*. .. function:: mp_size_t _fmpz_size(const fmpz_t x) Returns the number of limbs required to represent *x*. .. function:: slong _fmpz_sub_small(const fmpz_t x, const fmpz_t y) Computes the difference of *x* and *y* and returns the result as an *slong*. The result is clamped between -*WORD_MAX* and *WORD_MAX*, i.e. between `\pm (2^{63}-1)` inclusive on a 64-bit machine. .. function:: slong _fmpz_set_si_small(fmpz_t x, slong v) Sets *x* to the integer *v* which is required to be a value between *COEFF_MIN* and *COEFF_MAX* so that promotion to a bignum cannot occur. Low-level conversions ------------------------------------------------------------------------------- .. function:: void fmpz_set_mpn_large(fmpz_t z, mp_srcptr src, mp_size_t n, int negative) Sets *z* to the integer represented by the *n* limbs in the array *src*, or minus this value if *negative* is 1. Requires `n \ge 2` and that the top limb of *src* is nonzero. Note that *fmpz_set_ui*, *fmpz_neg_ui* can be used for single-limb integers. .. macro:: FMPZ_GET_MPN_READONLY(zsign, zn, zptr, ztmp, zv) Given an *fmpz_t* *zv*, this macro sets *zptr* to a pointer to the limbs of *zv*, *zn* to the number of limbs, and *zsign* to a sign bit (0 if nonnegative, 1 if negative). The variable *ztmp* must be a single *mp_limb_t*, which is used as a buffer. If *zv* is a small value, *zv* itself contains no limb array that *zptr* could point to, so the single limb is copied to *ztmp* and *zptr* is set to point to *ztmp*. The case where *zv* is zero is not handled specially, and *zn* is set to 1. .. function:: void fmpz_lshift_mpn(fmpz_t z, mp_srcptr src, mp_size_t n, int negative, flint_bitcnt_t shift) Sets *z* to the integer represented by the *n* limbs in the array *src*, or minus this value if *negative* is 1, shifted left by *shift* bits. Requires `n \ge 1` and that the top limb of *src* is nonzero. arb-2.22.1/doc/source/formulas.rst000066400000000000000000000126761417376376500170300ustar00rootroot00000000000000.. _general_formulas: General formulas and bounds =============================================================================== This section collects some results from real and complex analysis that are useful when deriving error bounds. Beware of typos. Error propagation ------------------------------------------------------------------------------- We want to bound the error when `f(x+a)` is approximated by `f(x)`. Specifically, the goal is to bound `f(x + a) - f(x)` in terms of `r` for the set of values `a` with `|a| \le r`. Most bounds will be monotone increasing with `|a|` (assuming that `x` is fixed), so for brevity we simply express the bounds in terms of `|a|`. **Theorem (generic first-order bound)**: .. math :: |f(x+a) - f(x)| \le \min(2 C_0, C_1 |a|) where .. math :: C_0 = \sup_{|t| \le |a|} |f(x+t)|, \quad C_1 = \sup_{|t| \le |a|} |f'(x+t)|. The statement is valid with either `a, t \in \mathbb{R}` or `a, t \in \mathbb{C}`. **Theorem (product)**: For `x, y \in \mathbb{C}` and `a, b \in \mathbb{C}`, .. math :: \left| (x+a)(y+b) - x y \right| \le |xb| + |ya| + |ab|. **Theorem (quotient)**: For `x, y \in \mathbb{C}` and `a, b \in \mathbb{C}` with `|b| < |y|`, .. math :: \left| \frac{x}{y} - \frac{x+a}{y+b} \right| \le \frac{|xb|+|ya|}{|y| (|y|-|b|)}. **Theorem (square root)**: For `x, a \in \mathbb{R}` with `0 \le |a| \le x`, .. math :: \left| \sqrt{x+a} - \sqrt{x} \right| \le \sqrt{x} \left(1 - \sqrt{1-\frac{|a|}{x}}\right) \le \frac{\sqrt{x}}{2} \left(\frac{|a|}{x} + \frac{|a|^2}{x^2}\right) where the first inequality is an equality if `a \le 0`. (When `x = a = 0`, the limiting value is 0.) **Theorem (reciprocal square root)**: For `x, a \in \mathbb{R}` with `0 \le |a| < x`, .. math :: \left| \frac{1}{\sqrt{x+a}} - \frac{1}{\sqrt{x}} \right| \le \frac{|a|}{2 (x-|a|)^{3/2}}. **Theorem (k-th root)**: For `k > 1` and `x, a \in \mathbb{R}` with `0 \le |a| \le x`, .. math :: \left| (x+a)^{1/k} - x^{1/k} \right| \le x^{1/k} \min\left(1, \frac{1}{k} \, \log\left(1+\frac{|a|}{x-|a|}\right)\right). *Proof*: The error is largest when `a = -r` is negative, and .. math :: x^{1/k} - (x-r)^{1/k} &= x^{1/k} [1 - (1-r/x)^{1/k}] &= x^{1/k} [1 - \exp(\log(1-r/x)/k)] \le x^{1/k} \min(1, -\log(1-r/x)/k) &= x^{1/k} \min(1, \log(1+r/(x-r))/k). **Theorem (sine, cosine)**: For `x, a \in \mathbb{R}`, `|\sin(x+a) - \sin(x)| \le \min(2, |a|)`. **Theorem (logarithm)**: For `x, a \in \mathbb{R}` with `0 \le |a| < x`, .. math :: |\log(x+a) - \log(x)| \le \log\left(1 + \frac{|a|}{x-|a|}\right), with equality if `a \le 0`. **Theorem (exponential)**: For `x, a \in \mathbb{R}`, `|e^{x+a} - e^x| = e^x (e^a-1) \le e^x (e^{|a|}-1)`, with equality if `a \ge 0`. **Theorem (inverse tangent)**: For `x, a \in \mathbb{R}`, .. math :: |\operatorname{atan}(x+a) - \operatorname{atan}(x)| \le \min(\pi, C_1 |a|). where .. math :: C_1 = \sup_{|t| \le |a|} \frac{1}{1 + (x+t)^2}. If `|a| < |x|`, then `C_1 = (1 + (|x| - |a|)^2)^{-1}` gives a monotone bound. An exact bound: if `|a| < |x|` or `|x(x+a)| < 1`, then .. math :: |\operatorname{atan}(x+a) - \operatorname{atan}(x)| = \operatorname{atan}\left(\frac{|a|}{1 + x(x+a)}\right). In the last formula, a case distinction has to be made depending on the signs of *x* and *a*. Sums and series ------------------------------------------------------------------------------- **Theorem (geometric bound)**: If `|c_k| \le C` and `|z| \le D < 1`, then .. math :: \left| \sum_{k=N}^{\infty} c_k z^k \right| \le \frac{C D^N}{1 - D}. **Theorem (integral bound)**: If `f(x)` is nonnegative and monotone decreasing, then .. math :: \int_N^{\infty} f(x) \le \sum_{k=N}^{\infty} f(k) \le f(N) + \int_N^{\infty} f(x) dx. Complex analytic functions ------------------------------------------------------------------------------- **Theorem (Cauchy's integral formula)**: If `f(z) = \sum_{k=0}^{\infty} c_k z^k` is analytic (on an open subset of `\mathbb{C}` containing the disk `D = \{ z : |z| \le R \}` in its interior, where `R > 0`), then .. math :: c_k = \frac{1}{2\pi i} \int_{|z|=R} \frac{f(z)}{z^{k+1}}\, dz. **Corollary (derivative bound)**: .. math :: |c_k| \le \frac{C}{R^k}, \quad C = \max_{|z|=R} |f(z)|. **Corollary (Taylor series tail)**: If `0 \le r < R` and `|z| \le r`, then .. math :: \left|\sum_{k=N}^{\infty} c_k z^k\right| \le \frac{C D^N}{1-D}, \quad D = \left|\frac{r}{R}\right|. Euler-Maclaurin formula ------------------------------------------------------------------------------- **Theorem (Euler-Maclaurin)**: If `f(t)` is `2M`-times differentiable, then .. math :: \sum_{k=L}^U f(k) = S + I + T + R .. math :: S = \sum_{k=L}^{N-1} f(k), \quad I = \int_N^U f(t) dt, .. math :: T = \frac{1}{2} \left( f(N) + f(U) \right) + \sum_{k=1}^M \frac{B_{2k}}{(2k)!} \left(f^{(2k-1)}(U) - f^{(2k-1)}(N)\right), .. math :: R = -\int_N^U \frac{B_{2M}(t - \lfloor t \rfloor)}{(2M)!} f^{(2M)}(t) dt. **Lemma (Bernoulli polynomials)**: `|B_n(t - \lfloor t \rfloor)| \le 4 n! / (2 \pi)^n`. **Theorem (remainder bound)**: .. math :: |R| \le \frac{4}{(2\pi)^{2M}} \int_N^U \left| f^{(2M)}(t) \right| dt. **Theorem (parameter derivatives)**: If `f(t) = f(t,x) = \sum_{k=0}^{\infty} a_k(t) x^k` and `R = R(x) = \sum_{k=0}^{\infty} c_k x^k` are analytic functions of `x`, then .. math :: |c_k| \le \frac{4}{(2\pi)^{2M}} \int_N^U |a_k^{(2M)}(t)| dt. arb-2.22.1/doc/source/gamma.rst000066400000000000000000000064651417376376500162610ustar00rootroot00000000000000.. _algorithms_gamma: Algorithms for the gamma function =============================================================================== The Stirling series ------------------------------------------------------------------------------- In general, the gamma function is computed via the Stirling series .. math :: \log \Gamma(z) = \left(z-\frac{1}{2}\right)\log z - z + \frac{\ln {2 \pi}}{2} + \sum_{k=1}^{n-1} \frac{B_{2k}}{2k(2k-1)z^{2k-1}} + R(n,z) where ([Olv1997]_ pp. 293-295) the remainder term is exactly .. math :: R_n(z) = \int_0^{\infty} \frac{B_{2n} - {\tilde B}_{2n}(x)}{2n(x+z)^{2n}} dx. To evaluate the gamma function of a power series argument, we substitute `z \to z + t \in \mathbb{C}[[t]]`. Using the bound for `|x+z|` given by [Olv1997]_ and the fact that the numerator of the integrand is bounded in absolute value by `2 |B_{2n}|`, the remainder can be shown to satisfy the bound .. math :: |[t^k] R_n(z+t)| \le 2 |B_{2n}| \frac{\Gamma(2n+k-1)}{\Gamma(k+1) \Gamma(2n+1)} \; |z| \; \left(\frac{b}{|z|}\right)^{2n+k} where `b = 1/\cos(\operatorname{arg}(z)/2)`. Note that by trigonometric identities, assuming that `z = x+yi`, we have `b = \sqrt{1 + u^2}` where .. math :: u = \frac{y}{\sqrt{x^2 + y^2} + x} = \frac{\sqrt{x^2 + y^2} - x}{y}. To use the Stirling series at `p`-bit precision, we select parameters `r`, `n` such that the remainder `R(n,z)` approximately is bounded by `2^{-p}`. If `|z|` is too small for the Stirling series to give sufficient accuracy directly, we first translate to `z + r` using the formula `\Gamma(z) = \Gamma(z+r) / (z (z+1) (z+2) \cdots (z+r-1))`. To obtain a remainder smaller than `2^{-p}`, we must choose an `r` such that, in the real case, `z + r > \beta p`, where `\beta > \log(2) / (2 \pi) \approx 0.11`. In practice, a slightly larger factor `\beta \approx 0.2` more closely balances `n` and `r`. A much larger `\beta` (e.g. `\beta = 1`) could be used to reduce the number of Bernoulli numbers that have to be precomputed, at the expense of slower repeated evaluation. Rational arguments ------------------------------------------------------------------------------- We use efficient methods to compute `y = \Gamma(p/q)` where `q` is one of `1, 2, 3, 4, 6` and `p` is a small integer. The cases `\Gamma(1) = 1` and `\Gamma(1/2) = \sqrt \pi` are trivial. We reduce all remaining cases to `\Gamma(1/3)` or `\Gamma(1/4)` using the following relations: .. math :: \Gamma(2/3) = \frac{2 \pi}{3^{1/2} \Gamma(1/3)}, \quad \quad \Gamma(3/4) = \frac{2^{1/2} \pi}{\Gamma(1/4)}, .. math :: \Gamma(1/6) = \frac{\Gamma(1/3)^2}{(\pi/3)^{1/2} 2^{1/3}}, \quad \quad \Gamma(5/6) = \frac{2 \pi (\pi/3)^{1/2} 2^{1/3}}{\Gamma(1/3)^2}. We compute `\Gamma(1/3)` and `\Gamma(1/4)` rapidly to high precision using .. math :: \Gamma(1/3) = \left( \frac{12 \pi^4}{\sqrt{10}} \sum_{k=0}^{\infty} \frac{(6k)!(-1)^k}{(k!)^3 (3k)! 3^k 160^{3k}} \right)^{1/6}, \quad \quad \Gamma(1/4) = \sqrt{\frac{(2\pi)^{3/2}}{\operatorname{agm}(1, \sqrt 2)}}. An alternative formula which could be used for `\Gamma(1/3)` is .. math :: \Gamma(1/3) = \frac{2^{4/9} \pi^{2/3}}{3^{1/12} \left( \operatorname{agm}\left(1,\frac{1}{2} \sqrt{2+\sqrt{3}}\right)\right)^{1/3}}, but this appears to be slightly slower in practice. arb-2.22.1/doc/source/history.rst000066400000000000000000002162551417376376500167000ustar00rootroot00000000000000.. _history: History and changes =============================================================================== For more details, view the commit log in the git repository https://github.com/fredrik-johansson/arb Old releases of the code can be accessed from https://github.com/fredrik-johansson/arb/releases Old versions of the documentation ------------------------------------------------------------------------------- * http://arblib.org/arb-2.22.0.pdf * http://arblib.org/arb-2.21.0.pdf * http://arblib.org/arb-2.20.0.pdf * http://arblib.org/arb-2.19.0.pdf * http://arblib.org/arb-2.18.1.pdf * http://arblib.org/arb-2.18.0.pdf * http://arblib.org/arb-2.17.0.pdf * http://arblib.org/arb-2.16.0.pdf * http://arblib.org/arb-2.15.0.pdf * http://arblib.org/arb-2.14.0.pdf * http://arblib.org/arb-2.13.0.pdf * http://arblib.org/arb-2.12.0.pdf * http://arblib.org/arb-2.11.1.pdf * http://arblib.org/arb-2.11.0.pdf * http://arblib.org/arb-2.10.0.pdf * http://arblib.org/arb-2.9.0.pdf * http://arblib.org/arb-2.8.1.pdf * http://arblib.org/arb-2.8.0.pdf * http://arblib.org/arb-2.7.0.pdf * http://arblib.org/arb-2.6.0.pdf * http://arblib.org/arb-2.5.0.pdf * http://arblib.org/arb-2.4.0.pdf * http://arblib.org/arb-2.3.0.pdf 2022-01-25 -- version 2.22.1 ------------------------------------------------------------------------------- * Fixed bugs causing some hypergeometric functions hang or crash for some input on various non-x86 architectures. * Fixed a minor bug in acb_hypgeom_m (NaN result sometimes only set the real part to NaN). 2022-01-15 -- version 2.22.0 ------------------------------------------------------------------------------- * Special functions * Use numerical integration in some cases to compute the hypergeometric functions 0F1, 1F1, U, 2F1, incomplete gamma and beta, modified Bessel, etc. with real parameters and argument, improving performance and accuracy when the parameters are large. * Much faster computation of Bernoulli numbers using hybrid numerical-modular algorithm (modular code adapted from bernmm by David Harvey). * Faster computation of Euler numbers using hybrid algorithm; added arb_fmpz_euler_number_ui. * Added inverse error function (arb_hypgeom_erfinv, arb_hypgeom_erfcinv). * New (faster, more accurate) implementations of real error functions (arb_hypgeom_erf, arb_hypgeom_erfc) and trigonometric integrals (arb_hypgeom_si, arb_hypgeom_ci). * Added acb_dirichlet_l_fmpq and acb_dirichlet_l_fmpq_afe: reduced-complexity evaluation of L-functions at rational points. * Added functions for computing primorials (arb_primorial_ui, arb_primorial_nth_ui). * New, highly optimized internal code for real hypergeometric series (arb_hypgeom_sum_fmpq_arb, etc.; currently only used in some functions). * Fix arb_fpwrap_double_hypgeom_2f1 which computed the wrong thing. * Core arithmetic and functions * Faster implementation of arb_ui_pow_ui. * Added arb_fma_si, arb_fma_fmpz. * Added arf_equal_ui, arf_equal_d. * Added arf_get_str. * Use arb-based printing code instead of MPFR in arf_printd and mag_printd so that large exponents work. * Fixed bug in arb_get_str that caused loss of precision when printing more than about 10^6 digits. * Allow negative exponents in mag_pow_fmpz. * Added the double_interval module for fast machine-precision interval arithmetic (experimental, intended for internal use). 2021-10-20 -- version 2.21.1 ------------------------------------------------------------------------------- * Fixed 32-bit test failures for arb_hypgeom_gamma_fmpq. * Added pow function to the fpwrap module. * Added missing header file includes. * Do not encode the library version in the SONAME on Android (contributed by Andreas Enge). 2021-09-25 -- version 2.21.0 ------------------------------------------------------------------------------- * Experimental new arb_fpwrap module: accurate floating-point wrappers of Arb mathematical functions (supersedes the external arbcmath.h). * Fixed memory leak in arf_load_file (reported by Dave Platt). * New and faster gamma function code. * Most gamma function internals are now located in the arb_hypgeom and acb_hypgeom modules. The user-facing functions (arb_gamma, etc.) are still available under the old names for compatibility. The internal algorithms for rising factorials (binary splitting, etc.) have been moved without aliases. * Added arb_fma, arb_fma_arf, arb_fma_ui (like addmul, but take a separate input and output). * Slightly faster internal Bernoulli number generation for small n. * Better enclosures for acb_barnes_g at negative reals. * Added Graeffe transforms (arb_poly_graeffe_transform, acb_poly_graeffe_transform) (contributed by Matthias Gessinger). * Fixed conflict with musl libc (reported by Gonzalo Tornaría). * Added acb_add_error_arb (contributed by Albin Ahlbäck). 2021-07-25 -- version 2.20.0 ------------------------------------------------------------------------------- * Flint 2.8 support. * Change arb_get_str with ARB_STR_NO_RADIUS: [+/- 1.20e-15] now prints as 0e-14. * Uniformly distributed random number functions arf_urandom, arb_urandom (contributed by Albin Ahlbäck). * Use quasilinear algorithm in arb_gamma_fmpq for all small fractions. * Added derivative of Weierstrass elliptic function (acb_elliptic_p_prime) (contributed by Daniel Schultz). * Added dot products with integer coefficients: arb_dot_fmpz, arb_dot_siui, arb_dot_uiui, arb_dot_si, arb_dot_ui, acb_dot_fmpz, acb_dot_siui, acb_dot_uiui, acb_dot_si, acb_dot_ui. * Faster arb_fmpz_poly_evaluate_arb and arb_fmpz_poly_evaluate_acb. * Explicitly guarantee that roots are isolated in arb_fmpz_poly_complex_roots (could previously theoretically fail when using the deflation hack). * Use GNUInstallDirs in CMakeLists.txt to support standard GNU installation directories (contributed by Michael Orlitzky). * Fixed bug for aliased multiplication of window matrices (contributed by David Berghaus). * Documentation fixes (contributed by Joel Dahne, Hanno Rein). 2020-12-06 -- version 2.19.0 ------------------------------------------------------------------------------- * Significant improvements to the implementation of Platt's algorithm for computing Riemann zeta function zeros at large height (contributed by p15-git-acc). * Better criterion for selecting asymptotic expansion of incomplete gamma function (contributed by p15-git-acc). * Multithreaded acb_dft for power-of-two lengths (contributed by p15-git-acc). * Added acb_csc_pi, arb_csc_pi (contributed by p15-git-acc). * Fixed segfault in acb_mat_eig_simple_rump when called with L non-NULL and R NULL (contributed by p15-git-acc). * Fixed bug in acb_real_abs (contributed by Joel Dahne). * Changed several functions to more consistently return infinities instead of NaNs where reasonable (contributed by p15-git-acc). * Added Fransen-Robinson as an integral example (contributed by p15-git-acc). * Cleaned up makefile (contributed by p15-git-acc). * Fixed several typos and some omitted functions in the documentation (contributed by Joel-Dahne, p15-git-acc). 2020-06-25 -- version 2.18.1 ------------------------------------------------------------------------------- * Support MinGW64. * Added version numbers (__ARB_VERSION, __ARB_RELEASE, ARB_VERSION) to arb.h. 2020-06-09 -- version 2.18.0 ------------------------------------------------------------------------------- * General * Flint 2.6 support. * Several build system improvements (contributed by Isuru Fernando). * Changed arf_get_mpfr to return an MPFR underflow/overflow result (rounding to 0 or infinity with the right sign and MPFR overflow flags) instead of throwing flint_abort() if the exponent is out of bounds for MPFR. * Documentation and type corrections (contributed by Joel Dahne). * Arithmetic * The number of iterations per precision level in arb_fmpz_poly_complex_roots has been tweaked to avoid extreme slowdown for some polynomials with closely clustered roots. * Added arb_contains_interior, acb_contains_interior. * Special functions * Fixed unsafe shifts causing Dirichlet characters for certain moduli exceeding 32 bits to crash. * Added acb_agm for computing the arithmetic-geometric mean of two complex numbers. * acb_elliptic_rj now uses a slow fallback algorithm in cases where Carlson's algorithm is not known to be valid. This fixes instances where acb_elliptic_pi, acb_elliptic_pi_inc and acb_elliptic_rj previously ended up on the wrong branch. Users should be cautioned that the new version can give worse enclosures and sometimes fails to converge in some cases where the old algorithm did (the pi flag for acb_elliptic_pi_inc is useful as a workaround). * Optimized some special cases in acb_hurwitz_zeta. 2019-10-16 -- version 2.17.0 ------------------------------------------------------------------------------- * General * Added exact serialization methods (arb_dump_str, arb_load_str, arb_dump_file, arb_load_file, arf_dump_str, arf_load_str, arf_dump_file, arf_load_file, mag_dump_str, mag_load_str, mag_dump_file, mag_load_file) (contributed by Julian Rüth). * Removed many obsolete fmpr methods and de-inlined several helper functions to slightly improve compile time and library size. * Fixed a namespace clash for an internal function (contributed by Julian Rüth). * Added the helper function arb_sgn_nonzero. * Added the helper function acb_rel_one_accuracy_bits. * Riemann zeta function * Added a function for efficiently computing individual zeros of the Riemann zeta function using Turing's method (acb_dirichlet_zeta_zero) (contributed by D.H.J. Polymath). * Added a function for counting zeros of the Riemann zeta function up to given height using Turing's method (acb_dirichlet_zeta_nzeros) (contributed by D.H.J. Polymath). * Added the Backlund S function (acb_dirichlet_backlund_s). * Added a function for computing Gram points (acb_dirichlet_gram_point). * Added acb_dirichlet_zeta_deriv_bound for quickly bounding the derivative of the Riemann zeta function. * Fast multi-evaluation of the Riemann zeta function using Platt's algorithm (acb_dirichlet_platt_multieval) (contributed by D.H.J. Polymath). * Other special functions * Improved the algorithm in acb_hypgeom_u to estimate precision loss more accurately. * Implemented Coulomb wave functions (acb_hypgeom_coulomb, acb_hypgeom_coulomb_series and other functions). * Faster algorithm for Catalan's constant. * Added acb_modular_theta_series. * Added arb_poly_sinc_pi_series (contributed by D.H.J. Polymath). * Improved tuning in acb_hypgeom_pfq_series_sum for higher derivatives at high precision (reported by Mark Watkins). 2018-12-07 -- version 2.16.0 ------------------------------------------------------------------------------- * Linear algebra and arithmetic * Added acb_mat_approx_eig_qr for approximate computation of eigenvalues and eigenvectors of complex matrices. * Added acb_mat_eig_enclosure_rump implementing Rump's algorithm for certification of eigenvalue-eigenvector pairs as well as clusters. * Added acb_mat_eig_simple_rump for certified diagonalization of matrices with simple eigenvalues. * Added acb_mat_eig_simple_vdhoeven_mourrain, acb_mat_eig_simple for fast certified diagonalization of matrices with simple eigenvalues. * Added acb_mat_eig_multiple_rump, acb_mat_eig_multiple for certified computation of eigenvalues with possible overlap. * Added acb_mat_eig_global_enclosure for fast global inclusion of eigenvalues without isolation. * Added arb_mat_companion, acb_mat_companion for constructing companion matrices. * Added several arb_mat and acb_mat helper functions: indeterminate, is_exact, is_zero, is_finite, is_triu, is_tril, is_diag, diag_prod. * Added arb_mat_approx_inv, acb_mat_approx_inv. * Optimized arb_mat_mul_block by using arb_dot when the blocks are small. * Added acb_get_mid. * Updated hilbert_matrix example program. 2018-10-25 -- version 2.15.1 ------------------------------------------------------------------------------- * Fixed precision issue leading to spurious NaN results in incomplete elliptic integrals 2018-09-18 -- version 2.15.0 ------------------------------------------------------------------------------- * Arithmetic * Added arb_dot and acb_dot for efficient evaluation of dot products. * Added arb_approx_dot and acb_approx_dot for efficient evaluation of dot products without error bounds. * Converted loops to arb_dot and acb_dot in the arb_poly and acb_poly methods mullow_classical, inv_series, div_series, exp_series_basecase, sin_cos_series_basecase, sinh_cosh_series_basecase, evaluate_rectangular, evaluate2_rectangular, revert_series_lagrange_fast. Also changed the algorithm cutoffs for mullow, exp_series, sin_cos_series, sinh_cosh_series. * Converted loops to arb_dot and acb_dot in the arb_mat and acb_mat methods mul_classical, mul_threaded, solve_tril, solve_triu, charpoly. Also changed the algorithm cutoffs for mul, solve_tril, solve_triu. * Converted loops to arb_approx_dot and acb_approx_dot in the arb_mat and acb_mat methods approx_solve_tril, approx_solve_triu. Also changed the algorithm cutoffs. * Added arb_mat_approx_mul and acb_mat_approx_mul for matrix multiplication without error bounds. * Miscellaneous * Added arb_hypgeom_airy_zero for computing zeros of Airy functions. * Added arb_hypgeom_dilog wrapper. * Optimized arb_const_pi and arb_const_log2 by using a static table at low precision, giving a small speedup and avoiding common recomputation when starting threads. * Optimized mag_set_ui_2exp_si. * Remove obsolete and unused function _arb_vec_dot. * Converted some inline functions to ordinary functions to reduce library size. * Fixed acb_dirichlet_stieltjes to use the integration algorithm also when a != 1. * Fixed test failure for acb_dirichlet_stieltjes on ARM64 (reported by Gianfranco Costamagna). Special thanks to Julien Puydt for assistance with debugging. * Fixed crash in acb_dft_bluestein with zero length (reported by Gianfranco Costamagna). 2018-07-22 -- version 2.14.0 ------------------------------------------------------------------------------- * Linear algebra * Faster and more accurate real matrix multiplication using block decomposition, scaling, and multiplying via FLINT integer matrices in combination with safe use of doubles for radius matrix multiplications. * Faster and more accurate complex matrix multiplication by reordering and taking advantage of real matrix multiplication. * The new multiplication algorithm methods (arb_mat_mul_block, acb_mat_mul_reorder) are used automatically by the main multiplication methods. * Faster and more accurate LU factorization by using a block recursive algorithm that takes advantage of matrix multiplication. Added separate algorithm methods (arb/acb)_mat_lu_(recursive/classical) with an automatic algorithm choice in the default lu methods. * Added methods (arb/acb)_mat_solve_(tril/triu) (and variants) for solving upper or lower triangular systems using a block recursive algorithm taking advantage of matrix multiplication. * Improved linear solving and inverse for large well-conditioned matrices by using a preconditioning algorithm. Added separate solving algorithm methods (arb/acb)_mat_solve_(lu/precond) with an automatic algorithm choice in the default solve methods (contributed by anonymous user arbguest). * Improved determinants using a preconditioning algorithm. Added separate determinant algorithm methods (arb/acb)_mat_det_(lu/precond) with an automatic algorithm choice in the default det methods. * Added automatic detection of triangular matrices in arb_mat_det and acb_mat_det. * Added arb_mat_solve_preapprox which allows certifying a precomputed approximate solution (contributed by anonymous user arbguest). * Added methods for constructing various useful test matrices: arb_mat_ones, arb_mat_hilbert, arb_mat_pascal, arb_mat_stirling, arb_mat_dct, acb_mat_ones, acb_mat_dft. * Added support for window matrices (arb/acb_mat_window_init/clear). * Changed random test matrix generation (arb/acb_mat_randtest) to produce sparse matrices with higher probability. * Added acb_mat_conjugate and acb_mat_conjugate_transpose. * Arithmetic and elementary functions * Improved arb_sin_cos, arb_sin and arb_cos to produce more accurate enclosures for wide input intervals. The working precision is also reduced automatically based on the accuracy of the input to improve efficiency. * Improved arb_sinh_cosh, arb_sinh and arb_cosh to produce more accurate enclosures for wide input intervals. The working precision is also reduced automatically based on the accuracy of the input to improve efficiency. * Improved arb_exp_invexp and arb_expm1 to produce more accurate enclosures for wide input intervals. The working precision is also reduced automatically based on the accuracy of the input to improve efficiency. * Improved acb_rsqrt to produce more accurate enclosures for wide intervals. * Made mag_add_ui_lower public. * Added mag_sinh, mag_cosh, mag_sinh_lower, mag_cosh_lower. * Fixed minor precision loss near -1 in arb_log_hypot and acb_log. * Return imaginary numbers with exact zero real part when possible in acb_acos and acb_acosh (contributed by Ralf Stephan). * Improved special cases in arb_set_interval_arf (reported by Marc Mezzarobba). * Special functions * Added a function for computing isolated generalized Stieltjes constants (acb_dirichlet_stieltjes). * Added scaled versions of Bessel functions (acb_hypgeom_bessel_i_scaled, acb_hypgeom_bessel_k_scaled). * The interface for the internal methods computing Bessel functions (i_asymp, k_asymp, etc.) has been changed to accommodate computing scaled versions. * Added Riemann xi function (acb_dirichlet_xi) (contributed by D.H.J Polymath). * Fixed infinite error bounds in the Riemann zeta function when evaluating at a ball containing zero centered in the left plane (contributed by D.H.J Polymath). * Fixed precision loss in Airy functions with huge input and high precision. * Legendre functions of the first kind (legendre_p): handle inexact integer a+b-c in 2F1 better (contributed by Joel Dahne). * Example programs and documentation * Added more color functions to complex_plot.c. * Added more example integrals suggested by Nicolas Brisebarre and Bruno Salvy to integrals.c * Changed Sphinx style and redesigned the documentation front page. * Miscellaneous documentation cleanups. * Added documentation page about contributing. * Other * Fixed a crash on some systems when calling acb_dft methods with a length of zero. * Fixed issue with setting rpath in configure (contributed by Vincent Delecroix). 2018-02-23 -- version 2.13.0 ------------------------------------------------------------------------------- * Major bugs * Fixed rounding direction in arb_get_abs_lbound_arf() which in some cases could result in an invalid lower bound being returned, and added forgotten test code for this and related functions (reported by deinst). Although this bug could lead to incorrect results, it probably had limited impact in practice (explaining why it was not caught indirectly by other test code) since a single rounding in the wrong direction in this operation generally will be dwarfed by multiple roundings in the correct direction in surrounding operations. * Important notes about bounds * Many functions have been modified to compute tighter enclosures when the input balls are wide. In most cases the bounds should be improved, but there may be some regressions. Bug reports about any significant regressions are welcome. * Division by zero in arb_div() has been changed to return [NaN +/- inf] instead of [+/- inf]. This change might be reverted in the future if it proves to be too inconvenient. In either case, users should only assume that division by zero produces something non-finite, and user code that depends on division by zero to produce [0 +/- inf] should be modified to handle zero-containing denominators as a separate case. * Improvements to arithmetic and elementary functions * Faster implementation of acb_get_mag_lower(). * Optimized arb_get_mag_lower(), arb_get_mag_lower_nonnegative(). * Added arb_set_interval_mag() and arb_set_interval_neg_pos_mag() for constructing an arb_t from a pair of mag_t endpoints. * Added mag_const_pi_lower(), mag_atan(), mag_atan_lower(). * Added mag_div_lower(), mag_inv(), mag_inv_lower(). * Added mag_sqrt_lower() and mag_rsqrt_lower(). * Added mag_log(), mag_log_lower(), mag_neg_log(), mag_neg_log_lower(). * Added mag_exp_lower(), mag_expinv_lower() and tweaked mag_exp(). * Added mag_pow_fmpz_lower(), mag_get_fmpz(), mag_get_fmpz_lower(). * Improved arb_exp() for wide input. * Improved arb_log() for wide input. * Improved arb_sqrt() for wide input. * Improved arb_rsqrt() for wide input. * Improved arb_div() for wide input. * Improved arb_atan() for wide input and slightly optimized arb_atan2() for input spanning multiple signs. * Improved acb_rsqrt() for wide input and improved stability of this function generally in the left half plane. * Added arb_log_hypot() and improved acb_log() for wide input. * Slightly optimized trigonometric functions (acb_sin(), acb_sin_pi(), acb_cos(), acb_cos_pi(), acb_sin_cos(), acb_sin_cos_pi()) for pure real or imaginary input. * Special functions * Slightly improved bounds for gamma function (arb_gamma(), acb_gamma(), arb_rgamma(), acb_rgamma()) for wide input. * Improved bounds for Airy functions for wide input. * Simplifications to code for computing Gauss period minimal polynomials (contributed by Jean-Pierre Flori). * Optimized arb_hypgeom_legendre_p_ui() further by avoiding divisions in the basecase recurrence and computing the prefactor more quickly in the asymptotic series (contributed by Marc Mezzarobba). * Small further optimization of arb_hypgeom_legendre_p_ui_root() (contributed by Marc Mezzarobba). * Improved derivative bounds for Legendre polynomials (contributed by Marc Mezzarobba). * Numerical integration * Increased default quadrature deg_limit at low precision to improve performance for integration of functions without singularities near the path. * Added several more integrals to examples/integrals.c * Added utility functions acb_real_abs(), acb_real_sgn(), acb_real_heaviside(), acb_real_floor(), acb_real_ceil(), acb_real_min(), acb_real_max(), acb_real_sqrtpos(), useful for numerical integration. * Added utility functions acb_sqrt_analytic(), acb_rsqrt_analytic(), acb_log_analytic(), acb_pow_analytic() with branch cut detection, useful for numerical integration. * Build system and compatibility issues * Removed -Wl flag from Makefile.subdirs to fix "-r and -pie may not be used together" compilation error on some newer Linux distributions (reported by many users). * Fixed broken test code for l_vec_hurwitz which resulted in spurious failures on 32-bit systems (originally reported by Thierry Monteil on Sage trac). * Avoid using deprecated MPFR function mpfr_root() with MPFR versions >= 4.0.0. * Remark: the recently released MPFR 4.0.0 has a bug in mpfr_div() leading to test failures in Arb (though not affecting correctness of Arb itself). Users should make sure to install the patched version MPFR 4.0.1. * Added missing C++ include guards in arb_fmpz_poly.h and dlog.h (reported by Marc Mezzarobba). * Fixed Travis builds on Mac OS again (contributed by Isuru Fernando). * Added missing declaration for arb_bell_ui() (reported by numsys). 2017-11-29 - version 2.12.0 ------------------------------------------------------------------------------- * Numerical integration * Added a new function (acb_calc_integrate) for rigorous numerical integration using adaptive subdivision and Gauss-Legendre quadrature. This largely obsoletes the old integration code using Taylor series. * Added new integrals.c example program (old example program moved to integrals_taylor.c). * Discrete Fourier transforms * Added acb_dft module with various FFT algorithm implementations, including top level O(n log n) acb_dft and acb_dft_inverse functions (contributed by Pascal Molin). * Legendre polynomials * Added arb_hypgeom_legendre_p_ui for fast and accurate evaluation of Legendre polynomials. This is also used automatically by the Legendre functions, where it is substantially faster and gives better error bounds than the generic algorithm. * Added arb_hypgeom_legendre_p_ui_root for fast computation of Legendre polynomial roots and Gauss-Legendre quadrature nodes (used internally by the new integration code). * Added arb_hypgeom_central_bin_ui for fast computation of central binomial coefficients (used internally for Legendre polynomials). * Dirichlet L-functions and zeta functions * Fixed a bug in the Riemann zeta function involving a too small error bound in the implementation of the Riemann-Siegel formula for inexact input. This bug could result in a too small enclosure when evaluating the Riemann zeta function at an argument of large imaginary height without also computing derivatives, if the input interval was very wide. * Add acb_dirichlet_zeta_jet; also made computation of the first derivative of Riemann zeta function use the Riemann-Siegel formula where appropriate. * Added acb_dirichlet_l_vec_hurwitz for fast simultaneous evaluation of Dirichlet L-functions for multiple characters using Hurwitz zeta function and FFT (contributed by Pascal Molin). * Simplified interface for using hurwitz_precomp functions. * Added lcentral.c example program (contributed by Pascal Molin). * Improved error bounds when evaluating Dirichlet L-functions using Euler product. * Elementary functions * Faster custom implementation of sin, cos at 4600 bits and above instead of using MPFR (30-40% asymptotic improvement, up to a factor two speedup). * Faster code for exp between 4600 and 19000 bits. * Improved error bounds for acb_atan by using derivative. * Improved error bounds for arb_sinh_cosh, arb_sinh and arb_cosh when the input has a small midpoint and large radius. * Added reciprocal trigonometric and hyperbolic functions (arb_sec, arb_csc, arb_sech, arb_csch, acb_sec, acb_csc, acb_sech, acb_csch). * Changed the interface of _acb_vec_unit_roots to take an extra length parameter (compatibility-breaking change). * Improved arb_pow and acb_pow with an inexact base and a negative integer or negative half-integer exponent; the inverse is now computed before performing binary exponentiation in this case to avoid spurious blow-up. * Elliptic functions * Improved Jacobi theta functions to reduce the argument modulo the lattice parameter, greatly improving speed and numerical stability for large input. * Optimized arb_agm by using a final series expansion and using special code for wide intervals. * Optimized acb_agm1 by using a final series expansion and using special code for positive real input. * Optimized derivative of AGM for high precision by using a central difference instead of a forward difference. * Optimized acb_elliptic_rf and acb_elliptic_rj for high precision by using a variable length series expansion. * Other * Fixed incorrect handling of subnormals in arf_set_d. * Added mag_bin_uiui for bounding binomial coefficients. * Added mag_set_d_lower, mag_sqrt_lower, mag_set_d_2exp_fmpz_lower. * Implemented multithreaded complex matrix multiplication. * Optimized arb_rel_accuracy_bits by adding fast path. * Fixed a spurious floating-point exception (division by zero) in the t-gauss_period_minpoly test program triggered by new code optimizations in recent versions of GCC that are unsafe together with FLINT inline assembly functions (a workaround was added to the test code, and a proper fix for the assembly code has been added to FLINT). 2017-07-10 - version 2.11.1 ------------------------------------------------------------------------------- * Avoid use of a function that was unavailable in the latest public FLINT release 2017-07-09 - version 2.11.0 ------------------------------------------------------------------------------- * Special functions * Added the Lambert W function (arb_lambertw, acb_lambertw, arb_poly_lambertw_series, acb_poly_lambertw_series). All complex branches and evaluation of derivatives are supported. * Added the acb_expm1 method, complementing arb_expm1. * Added arb_sinc_pi, acb_sinc_pi. * Optimized handling of more special cases in the Hurwitz zeta function. * Polynomials * Added the arb_fmpz_poly module to provide Arb methods for FLINT integer polynomials. * Added methods for evaluating an fmpz_poly at arb_t and acb_t arguments. * Added arb_fmpz_poly_complex_roots for computing the real and complex roots of an integer polynomial, turning the functionality previously available in the poly_roots.c example program into a proper library function. * Added a method (arb_fmpz_poly_gauss_period_minpoly) for constructing minimal polynomials of Gaussian periods. * Added arb_poly_product_roots_complex for constructing a real polynomial from complex conjugate roots. * Miscellaneous * Fixed test code in the dirichlet module for 32-bit systems (contributed by Pascal Molin). * Use flint_abort() instead of abort() (contributed by Tommy Hofmann). * Fixed the static library install path (contributed by François Bissey). * Made arb_nonnegative_part() a publicly documented method. * Arb now requires FLINT version 2.5 or later. 2017-02-27 - version 2.10.0 ------------------------------------------------------------------------------- * General * Changed a large number of methods from inline functions to normal functions, substantially reducing the size of the built library. * Fixed a few minor memory leaks (missing clear() calls). * Basic arithmetic * Added arb_is_int_2exp_si and acb_is_int_2exp_si. * Added arf_sosq for computing x^2+y^2 of floating-point numbers. * Improved error bounds for complex square roots in the left half plane. * Improved error bounds for complex reciprocal (acb_inv) and division. * Added the internal helper mag_get_d_log2_approx as a public method. * Elliptic functions and integrals * New module acb_elliptic.h for elliptic functions and integrals. * Added complete elliptic integral of the third kind. * Added Legendre incomplete elliptic integrals (first, second, third kinds). * Added Carlson symmetric incomplete elliptic integrals (RF, RC, RG, RJ, RD). * Added Weierstrass elliptic zeta and sigma functions. * Added inverse Weierstrass elliptic p-function. * Added utility functions for computing the Weierstrass invariants and lattice roots. * Improved computation of derivatives of Jacobi theta functions by using modular transformations, and added a main evaluation function (acb_modular_theta_jet). * Improved detection of pure real or pure imaginary parts in various cases of evaluating theta and modular functions. * Other special functions * New, far more efficient implementation of the dilogarithm function (acb_polylog with s = 2). * Fixed an issue in the Hurwitz zeta function leading to unreasonable slowdown for certain complex input. * Added add acb_poly_exp_pi_i_series. * Added arb_poly_log1p_series, acb_poly_log1p_series. 2016-12-02 - version 2.9.0 ------------------------------------------------------------------------------- * License * Changed license from GPL to LGPL. * Build system and compatibility * Fixed FLINT includes to use flint/foo.h instead of foo.h, simplifying compilation on many systems. * Added another alias for the dynamic library to fix make check on certain systems (contributed by Andreas Enge). * Travis CI support (contributed by Isuru Fernando). * Added support for ARB_TEST_MULTIPLIER environment variable to control the number of test iterations. * Support building with CMake (contributed by Isuru Fernando). * Support building with MSVC on Windows (contributed by Isuru Fernando). * Fixed unsafe use of FLINT_ABS for slong -> ulong conversion in arf.h, which caused failures on MIPS and ARM systems. * Basic arithmetic and methods * Fixed mag_addmul(x,x,x) with x having a mantissa of all ones. This could produce a non-normalized mag_t value, potentially leading to incorrect results in arb and acb level arithmetic. This bug was caught by new test code, and fortunately would have been hard to trigger accidentally. * Added fasth paths for error bound calculations in arb_sqrt and arb_div, speeding up these operations significantly at low precision * Added support for round-to-nearest in all arf methods. * Added fprint methods (contributed by Alex Griffing). * Added acb_printn and acb_fprintn methods to match arb_printn. * Added arb_equal_si and acb_equal_si. * Added arb_can_round_mpfr. * Added arb_get_ubound_arf, arb_get_lbound_arf (contributed by Tommy Hofmann). * Added sign function (arb_sgn). * Added complex sign functions (acb_sgn, acb_csgn). * Rewrote arb_contains_fmpq to make the test exact. * Optimized mag_get_fmpq. * Optimized arf_get_fmpz and added more robust test code. * Rewrote arb_get_unique_fmpz and arb_get_interval_fmpz_2exp, reducing overhead, making them more robust with huge exponents, and documenting their behavior more carefully. * Optimized arb_union. * Optimized arf_is_int, arf_is_int_2exp_si and changed these from inline to normal functions. * Added mag_const_pi, mag_sub, mag_expinv. * Optimized binary-to-decimal conversion for huge exponents by using exponential function instead of binary powering. * Added arb_intersection (contributed by Alex Griffing). * Added arb_min, arb_max (contributed by Alex Griffing). * Fixed a bug in arb_log and in test code on 64-bit Windows due to unsafe use of MPFR which only uses 32-bit exponents on Win64. * Improved some test functions to reduce the chance of reporting spurious failures. * Added squaring functions (arb_sqr, acb_sqr) (contributed by Ricky Farr). * Added arf_frexp. * Added arf_cmp_si, arf_cmp_ui, arf_cmp_d. * Added methods to count allocated bytes (arb_allocated_bytes, _arb_vec_allocated_bytes, etc.). * Added methods to predict memory usage for large vectors (_arb/_acb_vec_estimate_allocated_bytes). * Changed clear() methods from inline to normal functions, giving 8% faster compilation and 25% smaller libarb.so. * Added acb_unit_root and _acb_vec_unit_roots (contributed by Pascal Molin). * Polynomials * Added sinh and cosh functions of power series (arb/acb_poly_sinh/cosh_series and sinh_cosh_series). * Use basecase series inversion algorithm to improve speed and error bounds in arb/acb_poly_inv_series. * Added functions for fast polynomial Taylor shift (arb_poly_taylor_shift, acb_poly_taylor_shift and variants). * Fast handling of special cases in polynomial composition. * Added acb_poly scalar mul and div convenience methods (contributed by Alex Griffing). * Added set_trunc, set_trunc_round convenience methods. * Added add_series, sub_series methods for truncating addition. * Added polynomial is_zero, is_one, is_x, valuation convenience methods. * Added hack to arb_poly_mullow and acb_poly_mullow to avoid overhead when doing an in-place multiplication with length at most 2. * Added binomial and Borel transform methods for acb_poly. * Matrices * Added Cholesky decomposition plus solving and inverse for positive definite matrices (arb_mat_cho, arb_mat_spd_solve, arb_mat_spd_inv and related methods) (contributed by Alex Griffing). * Added LDL decomposition and inverse and solving based on LDL decomposition for real matrices (arb_mat_ldl, arb_mat_solve_ldl_precomp, arb_mat_inv_ldl_precomp) (contributed by Alex Griffing). * Improved the entrywise error bounds in matrix exponential computation to preserve sparsity and give exact entries where possible in many cases (contributed by Alex Griffing). * Added public functions for computing the truncated matrix exponential Taylor series (arb_mat_exp_taylor_sum, acb_mat_exp_taylor_sum). * Added functions related to sparsity structure (arb_mat_entrywise_is_zero, arb_mat_count_is_zero, etc.) (contributed by Alex Griffing). * Entrywise multiplication (arb_mat_mul_entrywise, acb_mat_mul_entrywise) (contributed by Alex Griffing). * Added is_empty and is_square convenience methods (contributed by Alex Griffing). * Added the bool_mat helper module for matrices over the boolean semiring (contributed by Alex Griffing). * Added Frobenius norm computation (contributed by Alex Griffing). * Miscellaneous special functions * Added evaluation of Bernoulli polynomials (arb_bernoulli_poly_ui, acb_bernoulli_poly_ui). * Added convenience function for evaluation of huge Bernoulli numbers (arb_bernoulli_fmpz). * Added Euler numbers (arb_euler_number_ui, arb_euler_number_fmpz). * Added fast approximate partition function (arb_partitions_fmpz/ui). * Optimized partition function for n < 1000 by using recurrence for the low 64 bits. * Improved the worst-case error bound in arb_atan. * Added arb_log_base_ui. * Added complex sinc function (acb_sinc). * Special handling of z = 1 when computing polylogarithms. * Fixed agm(-1,-1) to output 0 instead of indeterminate. * Made working precision in arb_gamma and acb_gamma more sensitive to the input accuracy. * Hypergeometric functions * Compute erf and erfc without cancellation problems for large or complex z. * Avoid re-computing the square root of pi in several places. * Added generalized hypergeometric function (acb_hypgeom_pfq). * Implement binary splitting and rectangular splitting for evaluation of hypergeometric series with a power series parameter, greatly speeding up Y_n, K_n and other functions at high precision, as well as speeding up high-order parameter derivatives. * Use binary splitting more aggressively in acb_hypgeom_pfq_sum to reduce error bound inflation. * Asymptotic expansions of hypergeometric functions: more accurate parameter selection, and better handling of terminating cases. * Tweaked algorithm selection and working precision in acb_hypgeom_m. * Avoid dividing by the denominator of the next term in acb_hypgeom_sum, which would lead to a division by zero when evaluating hypergeometric polynomials. * Fixed a bug in hypergeometric series evaluation resulting in near-integers not being skipped in some cases, leading to unnecessary loss of precision. * Added series expansions of Airy functions (acb_hypgeom_airy_series, acb_hypgeom_airy_jet). * Fixed a case where Airy functions accidentally chose the worst algorithm instead of the best one. * Added functions for computing erf, erfc, erfi of power series in the acb_hypgeom module. * Added series expansion of the logarithmic integral (acb_hypgeom_li_series). * Added Fresnel integrals (acb_hypgeom_fresnel, acb_hypgeom_fresnel_series). * Added the lower incomplete gamma function (acb_hypgeom_gamma_lower) (contributed by Alex Griffing). * Added series expansion of the lower incomplete gamma function (acb_hypgeom_gamma_lower_series) (contributed by Alex Griffing). * Added support for computing the regularized incomplete gamma functions. * Use slightly sharper error bound for analytic continuation of 2F1. * Added support for computing finite limits of 2F1 with inexact parameters differing by integers. * Added the incomplete beta function (acb_hypgeom_beta_lower, acb_hypgeom_beta_lower_series) * Improved acb_hypgeom_u to use a division-avoiding algorithm for small polynomial cases. * Added arb_hypgeom module, wrapping the complex hypergeometric functions for more convenient use with the arb_t type. * Dirichlet L-functions and Riemann zeta function * New module dirichlet for working algebraically with Dirichlet groups and characters (contributed by Pascal Molin). * New module acb_dirichlet for numerical evaluation of Dirichlet characters and L-functions (contributed by Pascal Molin). * Efficient representation and manipulation of Dirichlet characters using the Conrey representation (contributed by Pascal Molin). * New module dlog for word-size discrete logarithm evaluation, used to support algorithms on Dirichlet characters (contributed by Pascal Molin). * Methods for properties, evaluation, iteration, pairing, lift, lowering etc. of Dirichlet characters (contributed by Pascal Molin). * Added acb_dirichlet_roots methods for fast evaluation of many roots of unity (contributed by Pascal Molin). * Added acb_dirichlet_hurwitz_precomp methods for fast multi-evaluation of the Hurwitz zeta function for many parameter values. * Added methods for computing Gauss, Jacobi and theta sums over Dirichlet characters (contributed by Pascal Molin). * Added methods (acb_dirichlet_l, acb_dirichlet_l_jet, acb_dirichlet_l_series) for evaluation of Dirichlet L-functions and their derivatives. * Implemented multiple algorithms for evaluation of Dirichlet L-functions depending on the argument (Hurwitz zeta function decomposition, Euler product, functional equation). * Added methods (acb_dirichlet_hardy_z, acb_dirichlet_hardy_z_series, etc.) for computing the Hardy Z-function corresponding to a Dirichlet L-function. * Added fast bound for Hurwitz zeta function (mag_hurwitz_zeta_uiui). * Improved parameter selection in Hurwitz zeta function to target relative instead of absolute error for large positive s. * Improved parameter selection in Hurwitz zeta function to avoid computing unnecessary Bernoulli numbers for large imaginary s. * Added Dirichlet eta function (acb_dirichlet_eta). * Implemented the Riemann-Siegel formula for faster evaluation of the Riemann zeta function at large height. * Added smooth-index algorithm for the main sum when evaluating the Riemann zeta function, avoiding the high memory usage of the full sieving algorithm when the number of terms gets huge. * Improved tuning for using the Euler product when computing the Riemann zeta function. * Example programs * Added logistic map example program. * Added lvalue example program. * Improved poly_roots in several ways: identify roots that are exactly real, automatically perform squarefree factorization, use power hack, and allow specifying a product of polynomials as input on the command line. * Housekeeping * New section in the documentation giving an introduction to ball arithmetic and using the library. * Tidied, documented and added test code for the fmpz_extras module. * Added proper documentation and test code for many helper methods. * Removed the obsolete fmprb module entirely. * Documented more algorithms and formulas. * Clarified integer overflow issues and use of ARF_PREC_EXACT in the documentation. * Added .gitignore file. * Miscellaneous improvements to the documentation. 2015-12-31 - version 2.8.1 ------------------------------------------------------------------------------- * Fixed 32-bit test failure for the Laguerre function. * Made the Laguerre function indeterminate at negative integer orders, to be consistent with the test code. 2015-12-29 - version 2.8.0 ------------------------------------------------------------------------------- * Compatibility and build system * Windows64 support (contributed by Bill Hart). * Fixed a bug that broke basic arithmetic on targets where FLINT uses fallback code instead of assembly code, such as PPC64 (contributed by Jeroen Demeyer). * Fixed configure to use EXTRA_SHARED_FLAGS/LDFLAGS, and other build system fixes (contributed by Tommy Hofmann, Bill Hart). * Added soname versioning (contributed by Julien Puydt). * Fixed test code on MinGW (contributed by Hrvoje Abraham). * Miscellaneous fixes to simplify interfacing Arb from Julia. * Arithmetic and elementary functions * Fixed arf_get_d to handle underflow/overflow correctly and to support round-to-nearest. * Added more complex inverse hyperbolic functions (acb_asin, acb_acos, acb_asinh, acb_acosh, acb_atanh). * Added arb_contains_int and acb_contains_int for testing whether an interval contains any integer. * Added acb_quadratic_roots_fmpz. * Improved arb_sinh to use a more accurate formula for x < 0. * Added sinc function (arb_sinc) (contributed by Alex Griffing). * Fixed bug in arb_exp affecting convergence for huge input. * Faster implementation of arb_div_2expm1_ui. * Added mag_root, mag_geom_series. * Improved and added test code for arb_add_error functions. * Changed arb_pow and acb_pow to make pow(0,positive) = 0 instead of nan. * Improved acb_sqrt to return finite output for finite input straddling the branch cut. * Improved arb_set_interval_arf so that [inf,inf] = inf instead of an infinite interval. * Added computation of Bell numbers (arb_bell_fmpz). * Added arb_power_sum_vec for computing power sums using Bernoulli numbers. * Added computation of the Fujiwara root bound for acb_poly. * Added code to identify all the real roots of a real polynomial (acb_poly_validate_real_roots). * Added several convenient assignment functions, including arb_set_d, acb_set_d, acb_set_d_d, acb_set_fmpz_fmpz (contributed by Ricky Farr). * Added many accessor functions (_arb/acb_vec_entry_ptr, arb_get_mid/rad_arb, acb_real/imag_ptr, arb_mid/rad_ptr, acb_get_real/imag). * Added missing functions acb_add_si, acb_sub_si. * Renamed arb_root to arb_root_ui (keeping alias) and added acb_root_ui. * Special functions * Implemented the Gauss hypergeometric function 2F1 and its regularized version. * Fixed two bugs in acb_hypgeom_pfq_series_direct discovered while implementing 2F1. In rare cases, these could lead to incorrect values for functions depending on parameter derivatives of hypergeometric series. * The first bug involved incorrect handling of negative integer parameters. The bug only affected 2F1 and higher functions; it did not affect correctness of any previously implemented functions that relied on acb_hypgeom_pfq_series_direct (such as Bessel Y and K functions of integer order). * The second bug involved a too small bound being computed for the sum of a geometric series. The geometric series bound is nearly tight for 2F1, and the incorrect version caused immediate test failures for that function. Theoretically, this bug affected correctness of some previously-implemented functions that relied on acb_hypgeom_pfq_series_direct (such as Bessel Y and K functions of integer order), but since the geometric bound is not as tight in those cases, those functions were still reliable in practice (no failing test case has been found). * Implemented Airy functions and their derivatives (acb_hypgeom_airy). * Implemented the confluent hypergeometric function 0F1 (acb_hypgeom_0f1). * Implemented associated Legendre functions P and Q. * Implemented Chebyshev, Jacobi, Gegenbauer, Laguerre, Hermite functions. * Implemented spherical harmonics. * Added function for computing Bessel J and Y functions simultaneously. * Added rising factorials for non-integer n (arb_rising, acb_rising). * Made rising factorials use gamma function for large integer n. * Faster algorithm for theta constants and Dedekind eta function at very high precision. * Fixed erf to give finite values instead of +/-inf for big imaginary input. * Improved acb_zeta (and arb_zeta) to automatically use fast code for integer zeta values. * Added double factorial (arb_doublefac_ui). * Added code for generating Hilbert class polynomials (acb_modular_hilbert_class_poly). * Matrices * Added faster matrix squaring (arb/acb_mat_sqr) (contributed by Alex Griffing). * Added matrix trace (arb/acb_mat_trace) (contributed by Alex Griffing). * Added arb/acb_mat_set_round_fmpz_mat, acb_mat_set(_round)_arb_mat (contributed by Tommy Hofmann). * Added arb/acb_mat_transpose (contributed by Tommy Hofmann). * Added comparison methods arb/acb_mat_eq/ne (contributed by Tommy Hofmann). * Other * Added complex_plot example program. * Added Airy functions to real_roots example program. * Other minor patches were contributed by Alexander Kobel, Marc Mezzarobba, Julien Puydt. * Removed obsolete file config.h. 2015-07-14 - version 2.7.0 ------------------------------------------------------------------------------- * Hypergeometric functions * Implemented Bessel I and Y functions (acb_hypgeom_bessel_i, acb_hypgeom_bessel_y). * Fixed bug in Bessel K function giving the wrong branch for negative real arguments. * Added code for evaluating complex hypergeometric series binary splitting. * Added code for evaluating complex hypergeometric series using fast multipoint evaluation. * Gamma related functions * Implemented the Barnes G-function and its continuous logarithm (acb_barnes_g, acb_log_barnes_g). * Implemented the generalized polygamma function (acb_polygamma). * Implemented the reflection formula for the logarithmic gamma function (acb_lgamma, acb_poly_lgamma_series). * Implemented the digamma function of power series (arb_poly_digamma_series, acb_poly_digamma_series). * Improved acb_poly_zeta_series to produce exact zero imaginary parts in most cases when the result should be real-valued. * Made the real logarithmic gamma function (arb_lgamma, arb_poly_lgamma_series) abort more quickly for negative input. * Elementary functions * Added arb_exp_expinv and acb_exp_expinv functions for simultaneously computing exp(x), exp(-x). * Improved acb_tan, acb_tan_pi, acb_cot and acb_cot_pi for input with large imaginary parts. * Added complex hyperbolic functions (acb_sinh, acb_cosh, acb_sinh_cosh, acb_tanh, acb_coth). * Added acb_log_sin_pi for computing the logarithmic sine function without branch cuts away from the real line. * Added arb_poly_cot_pi_series, acb_poly_cot_pi_series. * Added arf_root and improved speed of arb_root. * Tuned algorithm selection in arb_pow_fmpq. * Other * Added documentation for arb and acb vector functions. 2015-04-19 - version 2.6.0 ------------------------------------------------------------------------------- * Special functions * Added the Bessel K function. * Added the confluent hypergeometric functions M and U. * Added exponential, trigonometric and logarithmic integrals ei, si, shi, ci, chi, li. * Added the complete elliptic integral of the second kind E. * Added support for computing hypergeometric functions with power series as parameters. * Fixed special cases in Bessel J function returning useless output. * Fixed precision of zeta function accidentally being capped at 7000 digits (bug in 2.5). * Special-cased real input in the gamma functions for complex types. * Fixed exp of huge numbers outputting unnecessarily useless intervals. * Fixed broken code in erf that sometimes gave useless output. * Made selection of number of terms in hypergeometric series more robust. * Polynomials and power series. * Added sin_pi, cos_pi and sin_cos_pi for real and complex power series. * Speeded up series reciprocal and division for length = 2. * Added add_si methods for polynomials. * Made inv_series and div_series with zero input produce indeterminates instead of aborting. * Added arb_poly_majorant, acb_poly_majorant. * Basic functions * Added comparison methods arb_eq, arb_ne, arb_lt, arb_le, arb_gt, arb_ge, acb_eq, acb_ne. * Added acb_rel_accuracy_bits and improved the real version. * Fixed precision of constants like pi behaving more nondeterministically than necessary. * Fixed arf_get_mag_lower(nan) to output 0 instead of inf. * Other * Removed call to fmpq_dedekind_sum which only exists in the git version of flint. * Fixed a test code bug that could cause crashes on some systems. * Added fix for static build on OS X (thanks Marcello Seri). * Miscellaneous corrections to the documentation. 2015-01-28 - version 2.5.0 ------------------------------------------------------------------------------- * String conversion * Added arb_set_str. * Added arb_get_str and arb_printn for pretty-printed rigorous decimal output. * Added helper functions for binary to decimal conversion. * Core arithmetic * Improved speed of division when using GMP instead of MPIR. * Improved complex division with a small denominator. * Removed a little bit of overhead for complex squaring. * Special functions * Faster code for atan at very high precision, used instead of mpfr_atan. * Optimized elementary functions slightly for small input. * Added modified error functions erfc and erfi. * Added the generalized exponential integral. * Added the upper incomplete gamma function. * Implemented the complete elliptic integral of the first kind. * Implemented the arithmetic-geometric mean of complex numbers. * Optimized arb_digamma for small integers. * Made mag_log_ui, mag_binpow_uiui and mag_polylog_tail proper functions. * Added pow, agm, erf, elliptic_k, elliptic_p as functions of complex power series. * Added incomplete gamma function of complex power series. * Improved code for bounding complex rising factorials (the old code could potentially have given wrong results in degenerate cases). * Added arb_sqrt1pm1, arb_atanh, arb_asinh, arb_atanh. * Added arb_log1p, acb_log1p, acb_atan. * Added arb_hurwitz_zeta. * Improved parameter selection in the Hurwitz zeta function to try to avoid stalling when given enormous input. * Optimized sqrt and rsqrt of power series when given a binomial as input. * Made arb_bernoulli_ui(2^64-2) not crash. * Fixed rgamma of negative integers returning indeterminate. * Polynomials and matrices * Added characteristic polynomial computation for real and complex matrices. * Added polynomial set_round methods. * Added is_real methods for more types. * Added more get_unique_fmpz methods. * Added code for generating Swinnerton-Dyer polynomials. * Improved error bounding in det() and exp() of complex matrices to recognize when the result is real-valued. * Changed polynomial divrem to return success/fail instead of aborting on divide by zero. * Miscellaneous * Added logo to documentation. * Made inlined functions build as part of the library. * Silenced a clang warning. * Made _acb_vec_sort_pretty a library function. 2014-11-15 - version 2.4.0 ------------------------------------------------------------------------------- * Arithmetic and core functions * Made evaluation of sin, cos and exp at medium precision faster using the sqrt trick. * Optimized arb_sinh and arb_sinh_cosh. * Optimized complex division with a small denominator. * Optimized cubing of complex numbers. * Added floor and ceil functions for the arf and arb types. * Added acb_poly powering functions. * Added acb_exp_pi_i. * Added functions for evaluation of Chebyshev polynomials. * Fixed arb_div to output nan for input containing nan. * Added a module acb_hypgeom for hypergeometric functions * Evaluation of the generalized hypergeometric function in convergent cases. * Evaluation of confluent hypergeometric functions using asymptotic expansions. * The Bessel function of the first kind for complex input. * The error function for complex input. * Added a module acb_modular for modular forms and elliptic functions * Support for working with modular transformations. * Mapping a point to the fundamental domain. * Evaluation of Jacobi theta functions and their series expansions. * The Dedekind eta function. * The j-invariant and the modular lambda and delta function. * Eisenstein series. * The Weierstrass elliptic function and its series expansion. * Miscellaneous * Fixed mag_print printing a too large exponent. * Fixed printd methods to use a fallback instead of aborting when printing numbers too large for MPFR. * Added version number string (arb_version). * Various additions to the documentation. 2014-09-25 - version 2.3.0 ------------------------------------------------------------------------------- * Removed most of the legacy (Arb 1.x) modules. * Updated build scripts, hopefully fixing various issues. * New implementations of arb_sin, arb_cos, arb_sin_cos, arb_atan, arb_log, arb_exp, arb_expm1, much faster up to a few thousand bits. * Ported the bit-burst code for high-precision exponentials to the arb type. * Speeded up arb_log_ui_from_prev. * Added mag_exp, mag_expm1, mag_exp_tail, mag_pow_fmpz. * Improved various mag functions. * Added arb_get/set_interval_mpfr, arb_get_interval_arf, and improved arb_set_interval_arf. * Improved arf_get_fmpz. * Prettier printing of complex numbers with negative imaginary part. * Changed some frequently-used functions from inline to non-inline to reduce code size. 2014-08-01 - version 2.2.0 ------------------------------------------------------------------------------- * Added functions for computing polylogarithms and order expansions of polylogarithms, with support for real and complex s, z. * Added a missing cast affecting C++ compatibility. * Generalized powsum functions to allow a geometric factor. * Improved powsum functions slightly when the exponent is an integer. * Faster arb_log_ui_from_prev. * Added mag_sqrt and mag_rsqrt functions. * Fixed various minor bugs and added missing tests and documentation entries. 2014-06-20 - version 2.1.0 ------------------------------------------------------------------------------- * Ported most of the remaining functions to the new arb/acb types, including: * Elementary functions (log, atan, etc.). * Hypergeometric series summation. * The gamma function. * The Riemann zeta function and related functions. * Bernoulli numbers. * The partition function. * The calculus modules (rigorous real root isolation, rigorous numerical integration of complex-valued functions). * Example programs. * Added several missing utility functions to the arf and mag modules. 2014-05-27 - version 2.0.0 ------------------------------------------------------------------------------- * New modules mag, arf, arb, arb_poly, arb_mat, acb, acb_poly, acb_mat for higher-performance ball arithmetic. * Poly_roots2 and hilbert_matrix2 example programs. * Vector dot product and norm functions (contributed by Abhinav Baid). 2014-05-03 - version 1.1.0 ------------------------------------------------------------------------------- * Faster and more accurate error bounds for polynomial multiplication (error bounds are now always as good as with classical multiplication, and multiplying high-degree polynomials with approximately equal coefficients now has proper quasilinear complexity). * Faster and much less memory-hungry exponentials at very high precision. * Improved the partition function to support n bigger than a single word, and enabled the possibility to use two threads for the computation. * Fixed a bug in floating-point arithmetic that caused a too small bound for the rounding error to be reported when the result of an inexact operation was rounded up to a power of two (this bug did not affect the correctness of ball arithmetic, because operations on ball midpoints always round down). * Minor optimizations to floating-point arithmetic. * Improved argument reduction of the digamma function and short series expansions of the rising factorial. * Removed the holonomic module for now, as it did not really do anything very useful. 2013-12-21 - version 1.0.0 ------------------------------------------------------------------------------- * New example programs directory * poly_roots example program. * real_roots example program. * pi_digits example program. * hilbert_matrix example program. * keiper_li example program. * New fmprb_calc module for calculus with real functions * Bisection-based root isolation. * Asymptotically fast Newton root refinement. * New fmpcb_calc module for calculus with complex functions * Numerical integration using Taylor series. * Scalar functions * Simplified fmprb_const_euler using published error bound. * Added fmprb_inv. * Added fmprb_trim, fmpcb_trim. * Added fmpcb_rsqrt (complex reciprocal square root). * Fixed bug in fmprb_sqrtpos with nonfinite input. * Slightly improved fmprb powering code. * Added various functions for bounding fmprs by powers of two. * Added fmpr_is_int. * Polynomials and power series * Implemented scaling to speed up blockwise multiplication. * Slightly faster basecase power series exponentials. * Improved sin/cos/tan/exp for short power series. * Added complex sqrt_series, rsqrt_series. * Implemented the Riemann-Siegel Z and theta functions for real power series. * Added fmprb_poly_pow_series, fmprb_poly_pow_ui and related methods. * Added fmprb/fmpcb_poly_contains_fmpz_poly. * Faster composition by monomials. * Implemented Borel transform and binomial transform for real power series. * Matrices * Implemented matrix exponentials. * Multithreaded fmprb_mat_mul. * Added matrix infinity norm functions. * Added some more matrix-scalar functions. * Added matrix contains and overlaps methods. * Zeta function evaluation * Multithreaded power sum evaluation. * Faster parameter selection when computing many derivatives. * Implemented binary splitting to speed up computing many derivatives. * Miscellaneous * Corrections for C++ compatibility (contributed by Jonathan Bober). * Several minor bugfixes and test code enhancements. 2013-08-07 - version 0.7 ------------------------------------------------------------------------------- * Floating-point and ball functions * Documented, added test code, and fixed bugs for various operations involving a ball containing an infinity or NaN. * Added reciprocal square root functions (fmpr_rsqrt, fmprb_rsqrt) based on mpfr_rec_sqrt. * Faster high-precision division by not computing an explicit remainder. * Slightly faster computation of pi by using new reciprocal square root and division code. * Added an fmpr function for approximate division to speed up certain radius operations. * Added fmpr_set_d for conversion from double. * Allow use of doubles to optionally compute the partition function faster but without an error bound. * Bypass mpfr overflow when computing the exponential function to extremely high precision (approximately 1 billion digits). * Made fmprb_exp faster for large numbers at extremely high precision by skipping the log(2) removal. * Made fmpcb_lgamma faster at high precision by speeding up the argument reduction branch computation. * Added fmprb_asin, fmprb_acos. * Added various other utility functions to the fmprb module. * Added a function for computing the Glaisher constant. * Optimized evaluation of the Riemann zeta function at high precision. * Polynomials and power series * Made squaring of polynomials faster than generic multiplication. * Implemented power series reversion (various algorithms) for the fmprb_poly type. * Added many fmprb_poly utility functions (shifting, truncating, setting/getting coefficients, etc.). * Improved power series division when either operand is short * Improved power series logarithm when the input is short. * Improved power series exponential to use the basecase algorithm for short input regardless of the output size. * Added power series square root and reciprocal square root. * Added atan, tan, sin, cos, sin_cos, asin, acos fmprb_poly power series functions. * Added Newton iteration macros to simplify various functions. * Added gamma functions of real and complex power series ([fmprb/fmpcb]_poly_[gamma/rgamma/lgamma]_series). * Added wrappers for computing the Hurwitz zeta function of a power series ([fmprb/fmpcb]_poly_zeta_series). * Implemented sieving and other optimizations to improve performance for evaluating the zeta function of a short power series. * Improved power series composition when the inner series is linear. * Added many fmpcb_poly versions of nearly all fmprb_poly functions. * Improved speed and stability of series composition/reversion by balancing the power table exponents. * Other * Added support for freeing all cached data by calling flint_cleanup(). * Introduced fmprb_ptr, fmprb_srcptr, fmpcb_ptr, fmpcb_srcptr typedefs for cleaner function signatures. * Various bug fixes and general cleanup. 2013-05-31 - version 0.6 ------------------------------------------------------------------------------- * Made fast polynomial multiplication over the reals numerically stable by using a blockwise algorithm. * Disabled default use of the Gauss formula for multiplication of complex polynomials, to improve numerical stability. * Added division and remainder for complex polynomials. * Added fast multipoint evaluation and interpolation for complex polynomials. * Added missing fmprb_poly_sub and fmpcb_poly_sub functions. * Faster exponentials (fmprb_exp and dependent functions) at low precision, using precomputation. * Rewrote fmpr_add and fmpr_sub using mpn level code, improving efficiency at low precision. * Ported the partition function implementation from flint (using ball arithmetic in all steps of the calculation to guarantee correctness). * Ported algorithm for computing the cosine minimal polynomial from flint (using ball arithmetic to guarantee correctness). * Support using GMP instead of MPIR. * Only use thread-local storage when enabled in flint. * Slightly faster error bounding for the zeta function. * Added some other helper functions. 2013-03-28 - version 0.5 ------------------------------------------------------------------------------- * Arithmetic and elementary functions * Added fmpr_get_fmpz, fmpr_get_si. * Fixed accuracy problem with fmprb_div_2expm1. * Special-cased squaring of complex numbers. * Added various fmpcb convenience functions (addmul_ui, etc). * Optimized fmpr_cmp_2exp_si and fmpr_cmpabs_2exp_si, and added test code for comparison functions. * Added fmprb_atan2, also fixing a bug in fmpcb_arg. * Added fmprb_sin_pi, cos_pi, sin_cos_pi, etc. * Added fmprb_sin_pi_fmpq (etc.) using algebraic methods for fast evaluation of roots of unity. * Faster fmprb_poly_evaluate and evaluate_fmpcb using rectangular splitting. * Added fmprb_poly_evaluate2, evaluate2_fmpcb for simultaneously evaluating the derivative. * Added fmprb_poly root polishing code using near-optimal Newton steps (experimental). * Added fmpr_root, fmprb_root (currently based on MPFR). * Added fmpr_min, fmpr_max. * Added fmprb_set_interval_fmpr, fmprb_union. * Added fmpr_bits, fmprb_bits, fmpcb_bits for obtaining the mantissa width. * Added fmprb_hypot. * Added complex square roots. * Improved fmprb_log to slightly improve speed, and properly support huge arguments. * Fixed exp, cosh, sinh to work with huge arguments. * Added fmprb_expm1. * Fixed sin, cos, atan to work with huge arguments. * Improved fmprb_pow and fmpcb_pow, including automatic detection of small integer and half-integer exponents. * Added many more elementary functions: fmprb_tan/cot/tanh/coth, fmpcb_tan/cot, and pi versions. * Added fmprb const_e, const_log2, const_log10, const_catalan. * Fixed ball containment/overlap checking to work operate efficiently and correctly with huge exponents. * Strengthened test code for many core operations. * Special functions * Reorganized zeta function related code. * Faster evaluation of the Riemann zeta function via sieving. * Documented and improved efficiency of the zeta constant binary splitting code. * Calculate error bound in Borwein's algorithm with fmprs instead of using doubles. * Optimized divisions in zeta evaluation via the Euler product. * Use functional equation for Riemann zeta function of a negative argument. * Compute single Bernoulli numbers using ball arithmetic instead of relying on the floating-point code in flint. * Initial code for evaluating the gamma function using its Taylor series. * Much faster rising factorials at high precision, using difference polynomials. * Much faster gamma function at high precision. * Added complex gamma function, log gamma function, and other versions. * Added fmprb_agm (real arithmetic-geometric mean). * Added fmprb_gamma_fmpq, supporting rapid computation of gamma(p/q) for q = 1,2,3,4,6. * Added real and complex digamma function. * Fixed unnecessary recomputation of Bernoulli numbers. * Optimized computation of Euler's constant, and added proper error bounds. * Avoid reliance on doubles in the hypergeometric series tail bound. * Cleaned up factorials and binomials, computing factorials via gamma. * Other * Added an fmpz_extras module to collect various internal fmpz helper functions. * Fixed detection of flint header files. * Fixed various other small bugs. 2013-01-26 - version 0.4 ------------------------------------------------------------------------------- * Much faster fmpr_mul, fmprb_mul and set_round, resulting in general speed improvements. * Code for computing the complex Hurwitz zeta function with derivatives. * Fixed and documented error bounds for hypergeometric series. * Better algorithm for series evaluation of the gamma function at a rational point. * Much faster generation of Bernoulli numbers. * Complex log, exp, pow, trigonometric functions (currently based on MPFR). * Complex nth roots via Newton iteration. * Added code for arithmetic on fmpcb_polys. * Code for computing Khinchin's constant. * Code for rising factorials of polynomials or power series * Faster sin_cos. * Better div_2expm1. * Many other new helper functions. * Improved thread safety. * More test code for core operations. 2012-11-07 - version 0.3 ------------------------------------------------------------------------------- * Converted documentation to Sphinx. * New module fmpcb for ball interval arithmetic over the complex numbers * Conversions, utility functions and arithmetic operations. * New module fmpcb_mat for matrices over the complex numbers * Conversions, utility functions and arithmetic operations. * Multiplication, LU decomposition, solving, inverse and determinant. * New module fmpcb_poly for polynomials over the complex numbers * Root isolation for complex polynomials. * New module fmpz_holonomic for functions/sequences defined by linear differential/difference equations with polynomial coefficients * Functions for creating various special sequences and functions. * Some closure properties for sequences. * Taylor series expansion for differential equations. * Computing the nth entry of a sequence using binary splitting. * Computing the nth entry mod p using fast multipoint evaluation. * Generic binary splitting code with automatic error bounding is now used for evaluating hypergeometric series. * Matrix powering. * Various other helper functions. 2012-09-29 - version 0.2 ------------------------------------------------------------------------------- * Code for computing the gamma function (Karatsuba, Stirling's series). * Rising factorials. * Fast exp_series using Newton iteration. * Improved multiplication of small polynomials by using classical multiplication. * Implemented error propagation for square roots. * Polynomial division (Newton-based). * Polynomial evaluation (Horner) and composition (divide-and-conquer). * Product trees, fast multipoint evaluation and interpolation (various algorithms). * Power series composition (Horner, Brent-Kung). * Added the fmprb_mat module for matrices of balls of real numbers. * Matrix multiplication. * Interval-aware LU decomposition, solving, inverse and determinant. * Many helper functions and small bugfixes. 2012-09-14 - version 0.1 ------------------------------------------------------------------------------- * 2012-08-05 - Began simplified rewrite. * 2012-04-05 - Experimental ball and polynomial code (first commit). arb-2.22.1/doc/source/hurwitz.rst000066400000000000000000000030021417376376500166730ustar00rootroot00000000000000.. _algorithms_hurwitz: Algorithms for the Hurwitz zeta function =============================================================================== Euler-Maclaurin summation ------------------------------------------------------------------------------- The Euler-Maclaurin formula allows evaluating the Hurwitz zeta function and its derivatives for general complex input. The algorithm is described in [Joh2013]_. Parameter Taylor series ------------------------------------------------------------------------------- To evaluate `\zeta(s,a)` for several nearby parameter values, the following Taylor expansion is useful: .. math :: \zeta(s,a+x) = \sum_{k=0}^{\infty} (-x)^k \frac{(s)_k}{k!} \zeta(s+k,a) We assume that `a \ge 1` is real and that `\sigma = \operatorname{re}(s)` with `K + \sigma > 1`. The tail is bounded by .. math :: \sum_{k=K}^{\infty} |x|^k \frac{|(s)_k|}{k!} \zeta(\sigma+k,a) \le \sum_{k=K}^{\infty} |x|^k \frac{|(s)_k|}{k!} \left[ \frac{1}{a^{\sigma+k}} + \frac{1}{(\sigma+k-1) a^{\sigma+k-1}} \right]. Denote the term on the right by `T(k)`. Then .. math :: \left|\frac{T(k+1)}{T(k)}\right| = \frac{|x|}{a} \frac{(k+\sigma-1)}{(k+\sigma)} \frac{(k+\sigma+a)}{(k+\sigma+a-1)} \frac{|k+s|}{(k+1)} \le \frac{|x|}{a} \left(1 + \frac{1}{K+\sigma+a-1}\right) \left(1 + \frac{|s-1|}{K+1}\right) = C and if `C < 1`, .. math :: \sum_{k=K}^{\infty} T(k) \le \frac{T(K)}{1-C}. arb-2.22.1/doc/source/hypergeometric.rst000066400000000000000000000242341417376376500202170ustar00rootroot00000000000000.. _algorithms_hypergeometric: Algorithms for hypergeometric functions =============================================================================== The algorithms used to compute hypergeometric functions are described in [Joh2016]_. Here, we state the most important error bounds. .. _algorithms_hypergeometric_convergent: Convergent series ------------------------------------------------------------------------------- Let .. math :: T(k) = \frac{\prod_{i=0}^{p-1} (a_i)_k}{\prod_{i=0}^{q-1} (b_i)_k} z^k. We compute a factor *C* such that .. math :: \left|\sum_{k=n}^{\infty} T(k)\right| \le C |T(n)|. We check that `\operatorname{Re}(b+n) > 0` for all lower parameters *b*. If this does not hold, *C* is set to infinity. Otherwise, we cancel out pairs of parameters `a` and `b` against each other. We have .. math :: \left|\frac{a+k}{b+k}\right| = \left|1 + \frac{a-b}{b+k}\right| \le 1 + \frac{|a-b|}{|b+n|} and .. math :: \left|\frac{1}{b+k}\right| \le \frac{1}{|b+n|} for all `k \ge n`. This gives us a constant *D* such that `T(k+1) \le D T(k)` for all `k \ge n`. If `D \ge 1`, we set *C* to infinity. Otherwise, we take `C = \sum_{k=0}^{\infty} D^k = (1-D)^{-1}`. Convergent series of power series ------------------------------------------------------------------------------- The same principle is used to get tail bounds for with `a_i, b_i, z \in \mathbb{C}[[x]]`, or more precisely, bounds for each coefficient in `\sum_{k=N}^{\infty} T(k) \in \mathbb{C}[[x]] / \langle x^n \rangle` given `a_i, b_i, z \in \mathbb{C}[[x]] / \langle x^n \rangle`. First, we fix some notation, assuming that `A` and `B` are power series: * `A_{[k]}` denotes the coefficient of `x^k` in `A`, and `A_{[m:n]}` denotes the power series `\sum_{k=m}^{n-1} A_{[k]} x^k`. * `|A|` denotes `\sum_{k=0}^{\infty} |A_{[k]}| x^k` (this can be viewed as an element of `\mathbb{R}_{\ge 0}[[x]]`). * `A \le B` signifies that `|A|_{[k]} \le |B|_{[k]}` holds for all `k`. * We define `\mathcal{R}(B) = |B_{[0]}| - |B_{[1:\infty]}|`. Using the formulas .. math :: (A B)_{[k]} = \sum_{j=0}^k A_{[j]} B_{[k-j]}, \quad (1 / B)_{[k]} = \frac{1}{B_{[0]}} \sum_{j=1}^k -B_{[j]} (1/B)_{[k-j]}, it is easy prove the following bounds for the coefficients of sums, products and quotients of formal power series: .. math :: |A + B| \le |A| + |B|, \quad |A B| \le |A| |B|, \quad |A / B| \le |A| / \mathcal{R}(B). If `p \le q` and `\operatorname{Re}({b_i}_{[0]}+N) > 0` for all `b_i`, then we may take .. math :: D = |z| \, \prod_{i=1}^p \left(1 + \frac{|a_i-b_i|}{\mathcal{R}(b_i+N)}\right) \prod_{i=p+1}^{q} \frac{1}{\mathcal{R}(b_i + N)}. If `D_{[0]} < 1`,then `(1 - D)^{-1} |T(n)|` gives the error bound. Note when adding and multiplying power series with (complex) interval coefficients, we can use point-valued upper bounds for the absolute values instead of performing interval arithmetic throughout. For `\mathcal{R}(B)`, we must then pick a lower bound for `|B_{[0]}|` and upper bounds for the coefficients of `|B_{[1:\infty]}|`. .. _algorithms_hypergeometric_asymptotic_confluent: Asymptotic series for the confluent hypergeometric function ------------------------------------------------------------------------------- Let `U(a,b,z)` denote the confluent hypergeometric function of the second kind with the principal branch cut, and let `U^{*} = z^a U(a,b,z)`. For all `z \ne 0` and `b \notin \mathbb{Z}` (but valid for all `b` as a limit), we have (DLMF 13.2.42) .. math :: U(a,b,z) = \frac{\Gamma(1-b)}{\Gamma(a-b+1)} M(a,b,z) + \frac{\Gamma(b-1)}{\Gamma(a)} z^{1-b} M(a-b+1,2-b,z). Moreover, for all `z \ne 0` we have .. math :: \frac{{}_1F_1(a,b,z)}{\Gamma(b)} = \frac{(-z)^{-a}}{\Gamma(b-a)} U^{*}(a,b,z) + \frac{z^{a-b} e^z}{\Gamma(a)} U^{*}(b-a,b,-z) which is equivalent to DLMF 13.2.41 (but simpler in form). We have the asymptotic expansion .. math :: U^{*}(a,b,z) \sim {}_2F_0(a, a-b+1, -1/z) where `{}_2F_0(a,b,z)` denotes a formal hypergeometric series, i.e. .. math :: U^{*}(a,b,z) = \sum_{k=0}^{n-1} \frac{(a)_k (a-b+1)_k}{k! (-z)^k} + \varepsilon_n(z). The error term `\varepsilon_n(z)` is bounded according to DLMF 13.7. A case distinction is made depending on whether `z` lies in one of three regions which we index by `R`. Our formula for the error bound increases with the value of `R`, so we can always choose the larger out of two indices if `z` lies in the union of two regions. Let `r = |b-2a|`. If `\operatorname{Re}(z) \ge r`, set `R = 1`. Otherwise, if `\operatorname{Im}(z) \ge r` or `\operatorname{Re}(z) \ge 0 \land |z| \ge r`, set `R = 2`. Otherwise, if `|z| \ge 2r`, set `R = 3`. Otherwise, the bound is infinite. If the bound is finite, we have .. math :: |\varepsilon_n(z)| \le 2 \alpha C_n \left|\frac{(a)_n (a-b+1)_n}{n! z^n} \right| \exp(2 \alpha \rho C_1 / |z|) in terms of the following auxiliary quantities .. math :: \sigma = |(b-2a)/z| .. math :: C_n = \begin{cases} 1 & \text{if } R = 1 \\ \chi(n) & \text{if } R = 2 \\ (\chi(n) + \sigma \nu^2 n) \nu^n & \text{if } R = 3 \end{cases} .. math :: \nu = \left(\tfrac{1}{2} + \tfrac{1}{2}\sqrt{1-4\sigma^2}\right)^{-1/2} \le 1 + 2 \sigma^2 .. math :: \chi(n) = \sqrt{\pi} \Gamma(\tfrac{1}{2}n+1) / \Gamma(\tfrac{1}{2} n + \tfrac{1}{2}) .. math :: \sigma' = \begin{cases} \sigma & \text{if } R \ne 3 \\ \nu \sigma & \text{if } R = 3 \end{cases} .. math :: \alpha = (1 - \sigma')^{-1} .. math :: \rho = \tfrac{1}{2} |2a^2-2ab+b| + \sigma' (1+ \tfrac{1}{4} \sigma') (1-\sigma')^{-2} .. _algorithms_hypergeometric_asymptotic_airy: Asymptotic series for Airy functions ------------------------------------------------------------------------------- Error bounds are based on Olver (DLMF section 9.7). For `\arg(z) < \pi` and `\zeta = (2/3) z^{3/2}`, we have .. math :: \operatorname{Ai}(z) = \frac{e^{-\zeta}}{2 \sqrt{\pi} z^{1/4}} \left[S_n(\zeta) + R_n(z)\right], \quad \operatorname{Ai}'(z) = -\frac{z^{1/4} e^{-\zeta}}{2 \sqrt{\pi}} \left[(S'_n(\zeta) + R'_n(z)\right] .. math :: S_n(\zeta) = \sum_{k=0}^{n-1} (-1)^k \frac{u(k)}{\zeta^k}, \quad S'_n(\zeta) = \sum_{k=0}^{n-1} (-1)^k \frac{v(k)}{\zeta^k} .. math :: u(k) = \frac{(1/6)_k (5/6)_k}{2^k k!}, \quad v(k) = \frac{6k+1}{1-6k} u(k). Assuming that *n* is positive, the error terms are bounded by .. math :: |R_n(z)| \le C |u(n)| |\zeta|^{-n}, \quad |R'_n(z)| \le C |v(n)| |\zeta|^{-n} where .. math :: C = \begin{cases} 2 \exp(7 / (36 |\zeta|)) & |\arg(z)| \le \pi/3 \\ 2 \chi(n) \exp(7 \pi / (72 |\zeta|)) & \pi/3 \le |\arg(z)| \le 2\pi/3 \\ 4 \chi(n) \exp(7 \pi / (36 |\operatorname{re}(\zeta)|)) |\cos(\arg(\zeta))|^{-n} & 2\pi/3 \le |\arg(z)| < \pi. \end{cases} For computing Bi when *z* is roughly in the positive half-plane, we use the connection formulas .. math :: \operatorname{Bi}(z) = -i (2 w^{+1} \operatorname{Ai}(z w^{-2}) - \operatorname{Ai}(z)) \operatorname{Bi}(z) = +i (2 w^{-1} \operatorname{Ai}(z w^{+2}) - \operatorname{Ai}(z)) where `w = \exp(\pi i/3)`. Combining roots of unity gives .. math :: \operatorname{Bi}(z) = \frac{1}{2 \sqrt{\pi} z^{1/4}} [2X + iY] .. math :: \operatorname{Bi}(z) = \frac{1}{2 \sqrt{\pi} z^{1/4}} [2X - iY] .. math :: X = \exp(+\zeta) [S_n(-\zeta) + R_n(z w^{\mp 2})], \quad Y = \exp(-\zeta) [S_n(\zeta) + R_n(z)] where the upper formula is valid for `-\pi/3 < \arg(z) < \pi` and the lower formula is valid for `-\pi < \arg(z) < \pi/3`. We proceed analogously for the derivative of Bi. In the negative half-plane, we use the connection formulas .. math :: \operatorname{Ai}(z) = e^{+\pi i/3} \operatorname{Ai}(z_1) + e^{-\pi i/3} \operatorname{Ai}(z_2) .. math :: \operatorname{Bi}(z) = e^{-\pi i/6} \operatorname{Ai}(z_1) + e^{+\pi i/6} \operatorname{Ai}(z_2) where `z_1 = -z e^{+\pi i/3}`, `z_2 = -z e^{-\pi i/3}`. Provided that `|\arg(-z)| < 2 \pi / 3`, we have `|\arg(z_1)|, |\arg(z_2)| < \pi`, and thus the asymptotic expansion for Ai can be used. As before, we collect roots of unity to obtain .. math :: \operatorname{Ai}(z) = A_1 [S_n(i \zeta) + R_n(z_1)] + A_2 [S_n(-i \zeta) + R_n(z_2)] .. math :: \operatorname{Bi}(z) = A_3 [S_n(i \zeta) + R_n(z_1)] + A_4 [S_n(-i \zeta) + R_n(z_2)] where `\zeta = (2/3) (-z)^{3/2}` and .. math :: A_1 = \frac{\exp(-i (\zeta - \pi/4))}{2 \sqrt{\pi} (-z)^{1/4}}, \quad A_2 = \frac{\exp(+i (\zeta - \pi/4))}{2 \sqrt{\pi} (-z)^{1/4}}, \quad A_3 = -i A_1, \quad A_4 = +i A_2. The differentiated formulas are analogous. Corner case of the Gauss hypergeometric function ------------------------------------------------------------------------------- In the corner case where `z` is near `\exp(\pm \pi i / 3)`, none of the linear fractional transformations is effective. In this case, we use Taylor series to analytically continue the solution of the hypergeometric differential equation from the origin. The function `f(z) = {}_2F_1(a,b,c,z_0+z)` satisfies .. math :: f''(z) = -\frac{((z_0+z)(a+b+1)-c)}{(z_0+z)(z_0-1+z)} f'(z) - \frac{a b}{(z_0+z)(z_0-1+z)} f(z). Knowing `f(0), f'(0)`, we can compute the consecutive derivatives recursively, and evaluating the truncated Taylor series allows us to compute `f(z), f'(z)` to high accuracy for sufficiently small `z`. Some experimentation showed that two continuation steps .. math :: 0 \quad \to \quad 0.375 \pm 0.625i \quad \to \quad 0.5 \pm 0.8125i \quad \to \quad z gives good performance. Error bounds for the truncated Taylor series are obtained using the Cauchy-Kovalevskaya majorant method, following the outline in [Hoe2001]_. The differential equation is majorized by .. math :: g''(z) = \frac{N+1}{2} \left( \frac{\nu}{1-\nu z} \right) g'(z) + \frac{(N+1)N}{2} \left( \frac{\nu}{1-\nu z} \right)^2 g(z) provided that `N` and `\nu \ge \max(1/|z_0|, 1/|z_0-1|)` are chosen sufficiently large. It follows that we can compute explicit numbers `A, N, \nu` such that the simple solution `g(z) = A (1-\nu z)^{-N}` of the differential equation provides the bound .. math :: |f_{[k]}| \le g_{[k]} = A {{N+k} \choose k} \nu^k. arb-2.22.1/doc/source/hypgeom.rst000066400000000000000000000146721417376376500166460ustar00rootroot00000000000000.. _hypgeom: **hypgeom.h** -- support for hypergeometric series =============================================================================== This module provides functions for high-precision evaluation of series of the form .. math :: \sum_{k=0}^{n-1} \frac{A(k)}{B(k)} \prod_{j=1}^k \frac{P(k)}{Q(k)} z^k where `A, B, P, Q` are polynomials. The present version only supports `A, B, P, Q \in \mathbb{Z}[k]` (represented using the FLINT *fmpz_poly_t* type). This module also provides functions for high-precision evaluation of infinite series (`n \to \infty`), with automatic, rigorous error bounding. Note that we can standardize to `A = B = 1` by setting `\tilde P(k) = P(k) A(k) B(k-1), \tilde Q(k) = Q(k) A(k-1) B(k)`. However, separating out `A` and `B` is convenient and improves efficiency during evaluation. Strategy for error bounding ------------------------------------------------------------------------------- We wish to evaluate `S(z) = \sum_{k=0}^{\infty} T(k) z^k` where `T(k)` satisfies `T(0) = 1` and .. math :: T(k) = R(k) T(k-1) = \left( \frac{P(k)}{Q(k)} \right) T(k-1) for given polynomials .. math :: P(k) = a_p k^p + a_{p-1} k^{p-1} + \ldots a_0 Q(k) = b_q k^q + b_{q-1} k^{q-1} + \ldots b_0. For convergence, we require `p < q`, or `p = q` with `|z| |a_p| < |b_q|`. We also assume that `P(k)` and `Q(k)` have no roots among the positive integers (if there are positive integer roots, the sum is either finite or undefined). With these conditions satisfied, our goal is to find a parameter `n \ge 0` such that .. math :: \left\lvert \sum_{k=n}^{\infty} T(k) z^k \right\rvert \le 2^{-d}. We can rewrite the hypergeometric term ratio as .. math :: z R(k) = z \frac{P(k)}{Q(k)} = z \left( \frac{a_p}{b_q} \right) \frac{1}{k^{q-p}} F(k) where .. math :: F(k) = \frac{ 1 + \tilde a_{1} / k + \tilde a_{2} / k^2 + \ldots + \tilde a_q / k^p }{ 1 + \tilde b_{1} / k + \tilde b_{2} / k^2 + \ldots + \tilde b_q / k^q } = 1 + O(1/k) and where `\tilde a_i = a_{p-i} / a_p`, `\tilde b_i = b_{q-i} / b_q`. Next, we define .. math :: C = \max_{1 \le i \le p} |\tilde a_i|^{(1/i)}, \quad D = \max_{1 \le i \le q} |\tilde b_i|^{(1/i)}. Now, if `k > C`, the magnitude of the numerator of `F(k)` is bounded from above by .. math :: 1 + \sum_{i=1}^p \left(\frac{C}{k}\right)^i \le 1 + \frac{C}{k-C} and if `k > 2D`, the magnitude of the denominator of `F(k)` is bounded from below by .. math :: 1 - \sum_{i=1}^q \left(\frac{D}{k}\right)^i \ge 1 + \frac{D}{D-k}. Putting the inequalities together gives the following bound, valid for `k > K = \max(C, 2D)`: .. math :: |F(k)| \le \frac{k (k-D)}{(k-C)(k-2D)} = \left(1 + \frac{C}{k-C} \right) \left(1 + \frac{D}{k-2D} \right). Let `r = q-p` and `\tilde z = |z a_p / b_q|`. Assuming `k > \max(C, 2D, {\tilde z}^{1/r})`, we have .. math :: |z R(k)| \le G(k) = \frac{\tilde z F(k)}{k^r} where `G(k)` is monotonically decreasing. Now we just need to find an `n` such that `G(n) < 1` and for which `|T(n)| / (1 - G(n)) \le 2^{-d}`. This can be done by computing a floating-point guess for `n` then trying successively larger values. This strategy leaves room for some improvement. For example, if `\tilde b_1` is positive and large, the bound `B` becomes very pessimistic (a larger positive `\tilde b_1` causes faster convergence, not slower convergence). Types, macros and constants ------------------------------------------------------------------------------- .. type:: hypgeom_struct .. type:: hypgeom_t Stores polynomials *A*, *B*, *P*, *Q* and precomputed bounds, representing a fixed hypergeometric series. Memory management ------------------------------------------------------------------------------- .. function:: void hypgeom_init(hypgeom_t hyp) .. function:: void hypgeom_clear(hypgeom_t hyp) Error bounding ------------------------------------------------------------------------------- .. function:: slong hypgeom_estimate_terms(const mag_t z, int r, slong d) Computes an approximation of the largest `n` such that `|z|^n/(n!)^r = 2^{-d}`, giving a first-order estimate of the number of terms needed to approximate the sum of a hypergeometric series of weight `r \ge 0` and argument `z` to an absolute precision of `d \ge 0` bits. If `r = 0`, the direct solution of the equation is given by `n = (\log(1-z) - d \log 2) / \log z`. If `r > 0`, using `\log n! \approx n \log n - n` gives an equation that can be solved in terms of the Lambert *W*-function as `n = (d \log 2) / (r\,W\!(t))` where `t = (d \log 2) / (e r z^{1/r})`. The evaluation is done using double precision arithmetic. The function aborts if the computed value of `n` is greater than or equal to LONG_MAX / 2. .. function:: slong hypgeom_bound(mag_t error, int r, slong C, slong D, slong K, const mag_t TK, const mag_t z, slong prec) Computes a truncation parameter sufficient to achieve *prec* bits of absolute accuracy, according to the strategy described above. The input consists of `r`, `C`, `D`, `K`, precomputed bound for `T(K)`, and `\tilde z = z (a_p / b_q)`, such that for `k > K`, the hypergeometric term ratio is bounded by .. math :: \frac{\tilde z}{k^r} \frac{k(k-D)}{(k-C)(k-2D)}. Given this information, we compute a `\varepsilon` and an integer `n` such that `\left| \sum_{k=n}^{\infty} T(k) \right| \le \varepsilon \le 2^{-\mathrm{prec}}`. The output variable *error* is set to the value of `\varepsilon`, and `n` is returned. .. function:: void hypgeom_precompute(hypgeom_t hyp) Precomputes the bounds data `C`, `D`, `K` and an upper bound for `T(K)`. Summation ------------------------------------------------------------------------------- .. function:: void arb_hypgeom_sum(arb_t P, arb_t Q, const hypgeom_t hyp, const slong n, slong prec) Computes `P, Q` such that `P / Q = \sum_{k=0}^{n-1} T(k)` where `T(k)` is defined by *hyp*, using binary splitting and a working precision of *prec* bits. .. function:: void arb_hypgeom_infsum(arb_t P, arb_t Q, hypgeom_t hyp, slong tol, slong prec) Computes `P, Q` such that `P / Q = \sum_{k=0}^{\infty} T(k)` where `T(k)` is defined by *hyp*, using binary splitting and working precision of *prec* bits. The number of terms is chosen automatically to bound the truncation error by at most `2^{-\mathrm{tol}}`. The bound for the truncation error is included in the output as part of *P*. arb-2.22.1/doc/source/index.rst000066400000000000000000000153521417376376500163010ustar00rootroot00000000000000Arb - a C library for arbitrary-precision ball arithmetic ============================================================= .. only:: latex Introduction :::::::::::: Welcome to Arb's documentation! Arb is a C library for rigorous real and complex arithmetic with arbitrary precision. Arb tracks numerical errors automatically using *ball arithmetic*, a form of interval arithmetic based on a midpoint-radius representation. On top of this, Arb provides a wide range of mathematical functionality, including polynomials, power series, matrices, integration, root-finding, and transcendental functions. Arb is designed with efficiency as a primary goal, and is usually competitive with or faster than other arbitrary-precision packages. The code is thread-safe, portable, and extensively tested. Arb is free software distributed under the GNU Lesser General Public License (LGPL), version 2.1 or later (see :ref:`license`). The git repository is https://github.com/fredrik-johansson/arb/ Arb is developed by `Fredrik Johansson `_ (fredrik.johansson@gmail.com), with help from many contributors (see :ref:`credits`). Questions and discussion about Arb are welcome on the `flint-devel `_ mailing list. There is also an `issue tracker `_ for bug reports and feature requests. Development progress is sometimes covered on `Fredrik's blog `_. This documentation is available in HTML format at http://arblib.org and in PDF format at http://arblib.org/arb.pdf. This edition of the documentation was updated |today| and describes Arb |version|. Documentation for :ref:`specific release versions ` is also available in PDF format. .. only:: html .. image:: _static/banner.jpg :align: center Welcome to Arb's documentation! Arb is a C library for rigorous real and complex arithmetic with arbitrary precision. Arb tracks numerical errors automatically using *ball arithmetic*, a form of interval arithmetic based on a midpoint-radius representation. On top of this, Arb provides a wide range of mathematical functionality, including polynomials, power series, matrices, integration, root-finding, and many transcendental functions. Arb is designed with efficiency as a primary goal, and is usually competitive with or faster than other arbitrary-precision packages. The code is thread-safe, portable, and extensively tested. Arb is free software distributed under the GNU Lesser General Public License (LGPL), version 2.1 or later (see :ref:`license`). The git repository is https://github.com/fredrik-johansson/arb/ Arb is developed by `Fredrik Johansson `_ (fredrik.johansson@gmail.com), with help from many contributors (see :ref:`credits`). Questions and discussion about Arb are welcome on the `flint-devel `_ mailing list. There is also an `issue tracker `_ for bug reports and feature requests. Development progress is sometimes covered on `Fredrik's blog `_. This documentation is available in HTML format at http://arblib.org and in PDF format at http://arblib.org/arb.pdf. This edition of the documentation was updated |today| and describes Arb |version|. Documentation for :ref:`specific release versions ` is also available in PDF format. General information :::::::::::::::::::: .. toctree:: :maxdepth: 2 overview.rst setup.rst using.rst issues.rst contributing.rst credits.rst Example programs :::::::::::::::::::: .. toctree:: :maxdepth: 2 examples.rst Floating-point numbers :::::::::::::::::::::::::::::::::::: Arb uses two custom floating-point types in its implementation of ball arithmetic. The radius of a ball is represented using the type *mag_t* which is unsigned and has a fixed precision. The midpoint is represented using the type *arf_t* which has arbitrary precision. .. toctree:: :maxdepth: 2 mag.rst arf.rst Real and complex numbers :::::::::::::::::::::::::::::::::::: Real numbers (*arb_t*) are represented as midpoint-radius intervals, also known as balls. Complex numbers (*acb_t*) are represented in rectangular form, with *arb_t* balls for the real and imaginary parts. .. toctree:: :maxdepth: 2 arb.rst acb.rst Polynomials and power series :::::::::::::::::::::::::::::::::::: These modules implement dense univariate polynomials with real and complex coefficients. Truncated power series are supported via methods acting on polynomials, without introducing a separate power series type. .. toctree:: :maxdepth: 2 arb_poly.rst acb_poly.rst .. toctree:: :maxdepth: 2 arb_fmpz_poly.rst Transforms :::::::::::::::::::::::::::::::::::: .. toctree:: :maxdepth: 2 acb_dft.rst Matrices :::::::::::::::::::::::::::::::::::: These modules implement dense matrices with real and complex coefficients. Rudimentary linear algebra is supported. .. toctree:: :maxdepth: 2 arb_mat.rst acb_mat.rst Special functions :::::::::::::::::::::::::::::::::::: These modules implement mathematical functions with complexity that goes beyond the basics covered directly in the *arb* and *acb* modules. .. toctree:: :maxdepth: 2 acb_hypgeom.rst arb_hypgeom.rst acb_elliptic.rst acb_modular.rst dirichlet.rst acb_dirichlet.rst bernoulli.rst hypgeom.rst partitions.rst Calculus :::::::::::::::::::::::::::::::::::: Using ball arithmetic, it is possible to do rigorous root-finding and integration (among other operations) with generic functions. This code should be considered experimental. .. toctree:: :maxdepth: 2 arb_calc.rst acb_calc.rst Wrappers :::::::::::::::::::::::::::::::::::: Floating-point wrappers for Arb functions. .. toctree:: :maxdepth: 2 arb_fpwrap.rst Extra utility modules :::::::::::::::::::::::::::::::::::: Mainly for internal use. .. toctree:: :maxdepth: 1 double_interval.rst fmpz_extras.rst bool_mat.rst dlog.rst fmpr.rst Supplementary algorithm notes :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Here, we give extra proofs, error bounds, and formulas that would be too lengthy to reproduce in the documentation for each module. .. toctree:: :maxdepth: 1 formulas.rst constants.rst gamma.rst hurwitz.rst polylogarithms.rst hypergeometric.rst agm.rst Version history ::::::::::::::::::::::::::::::::: .. toctree:: :maxdepth: 1 history.rst arb-2.22.1/doc/source/issues.rst000066400000000000000000000326261417376376500165100ustar00rootroot00000000000000.. _issues: Technical conventions and potential issues =============================================================================== Integer types ------------------------------------------------------------------------------- Arb generally uses the *int* type for boolean values and status flags. The *char*, *short* and *int* types are assumed to be two's complement types with exactly 8, 16 and 32 bits. This is not technically guaranteed by the C standard, but there are no mainstream platforms where this assumption does not hold, and new ones are unlikely to appear in the near future (ignoring certain low-power DSPs and the like, which are out of scope for this software). Since the C types *long* and *unsigned long* do not have a standardized size in practice, FLINT defines *slong* and *ulong* types which are guaranteed to be 32 bits on a 32-bit system and 64 bits on a 64-bit system. They are also guaranteed to have the same size as GMP's :type:`mp_limb_t`. GMP builds with a different limb size configuration are not supported at all. For convenience, the macro *FLINT_BITS* specifies the word length (32 or 64) of the system. .. type:: slong The *slong* type is used for precisions, bit counts, loop indices, array sizes, and the like, even when those values are known to be nonnegative. It is also used for small integer-valued coefficients. In method names, an *slong* parameter is denoted by *si*, for example :func:`arb_add_si`. The constants *WORD_MIN* and *WORD_MAX* give the range of this type. This type can be printed with *flint_printf* using the format string ``%wd``. .. type:: ulong The *ulong* type is used for integer-valued coefficients that are known to be unsigned, and for values that require the full 32-bit or 64-bit range. In method names, a *ulong* parameter is denoted by *ui*, for example :func:`arb_add_ui`. The constant *UWORD_MAX* gives the range of this type. This type can be printed with *flint_printf* using the format string ``%wu``. The following GMP-defined types are used in methods that manipulate the internal representation of numbers (using limb arrays). .. type:: mp_limb_t A single limb. .. type:: mp_ptr Pointer to a writable array of limbs. .. type:: mp_srcptr Pointer to a read-only array of limbs. .. type:: mp_size_t A limb count (always nonnegative). .. type:: flint_bitcnt_t A bit offset within an array of limbs (always nonnegative). Arb uses the following FLINT types for exact (integral and rational) arbitrary-size values. For details, refer to the FLINT documentation. .. type:: fmpz .. type:: fmpz_t The FLINT multi-precision integer type uses an inline representation for small integers, specifically when the absolute value is at most `2^{62}-1` (on 64-bit machines) or `2^{30}-1` (on 32-bit machines). It switches automatically to a GMP integer for larger values. The *fmpz_t* type is functionally identical to the GMP *mpz_t* type, but faster for small values. An :type:`fmpz_t` is defined as an array of length one of type :type:`fmpz` (which is just an alias for :type:`slong`), permitting an :type:`fmpz_t` to be passed by reference. .. type:: fmpq_t FLINT multi-precision rational number. .. type:: fmpz_poly_t .. type:: fmpq_poly_t .. type:: fmpz_mat_t .. type:: fmpq_mat_t FLINT polynomials and matrices with integer and rational coefficients. Integer overflow ------------------------------------------------------------------------------- When machine-size integers are used for precisions, sizes of integers in bits, lengths of polynomials, and similar quantities that relate to sizes in memory, very few internal checks are performed to verify that such quantities do not overflow. Precisions and lengths exceeding a small fraction of *LONG_MAX*, say `2^{24} \approx 10^7` on 32-bit systems, should be regarded as resulting in undefined behavior. On 64-bit systems this should generally not be an issue, since most calculations will exhaust the available memory (or the user's patience waiting for the computation to complete) long before running into integer overflows. However, the user needs to be wary of unintentionally passing input parameters of order *LONG_MAX* or negative parameters where positive parameters are expected, for example due to a runaway loop that repeatedly increases the precision. Currently, no hard upper limit on the precision is defined, but `2^{24} \approx 10^7` bits on 32-bit system and `2^{36} \approx 10^{11}` bits on a 64-bit system can be considered safe for most purposes. The relatively low limit on 64-bit systems is due to the fact that GMP integers are used internally in some algorithms, and GMP integers are limited to `2^{37}` bits. The minimum allowed precision is 2 bits. This caveat does not apply to exponents of floating-point numbers, which are represented as arbitrary-precision integers, nor to integers used as numerical scalars (e.g. :func:`arb_mul_si`). However, it still applies to conversions and operations where the result is requested exactly and sizes become an issue. For example, trying to convert the floating-point number `2^{2^{100}}` to an integer could result in anything from a silent wrong value to thrashing followed by a crash, and it is the user's responsibility not to attempt such a thing. Aliasing ------------------------------------------------------------------------------- As a rule, Arb allows aliasing of operands. For example, in the function call ``arb_add(z, x, y, prec)``, which performs `z \gets x + y`, any two (or all three) of the variables *x*, *y* and *z* are allowed to be the same. Exceptions to this rule are documented explicitly. The general rule that input and output variables can be aliased with each other only applies to variables *of the same type* (ignoring *const* qualifiers on input variables -- a special case is that :type:`arb_srcptr` is considered the *const* version of :type:`arb_ptr`). This is a natural extension of the so-called *strict aliasing rule* in C. For example, in :func:`arb_poly_evaluate` which evaluates `y = f(x)` for a polynomial *f*, the output variable *y* is not allowed to be a pointer to one of the coefficients of *f* (but aliasing between *x* and *y* or between *x* and the coefficients of *f* is allowed). This also applies to :func:`_arb_poly_evaluate`: for the purposes of aliasing, :type:`arb_srcptr` (the type of the coefficient array within *f*) and :type:`arb_t` (the type of *x*) are *not* considered to be the same type, and therefore must not be aliased with each other, even though an :type:`arb_ptr`/:type:`arb_srcptr` variable pointing to a length 1 array would otherwise be interchangeable with an :type:`arb_t`/*const* :type:`arb_t`. Moreover, in functions that allow aliasing between an input array and an output array, the arrays must either be identical or completely disjoint, never partially overlapping. There are natural exceptions to these aliasing restrictions, which may used internally without being documented explicitly. However, third party code should avoid relying on such exceptions. An important caveat applies to **aliasing of input variables**. Identical pointers are understood to give permission for **algebraic simplification**. This assumption is made to improve performance. For example, the call ``arb_mul(z, x, x, prec)`` sets *z* to a ball enclosing the set .. math :: \{ t^2 \,:\, t \in x \} and not the (generally larger) set .. math :: \{ t u \,:\, t \in x, u \in x \}. If the user knows that two values *x* and *y* both lie in the interval `[-1,1]` and wants to compute an enclosure for `f(x,y)`, then it would be a mistake to create an :type:`arb_t` variable *x* enclosing `[-1,1]` and reusing the same variable for *y*, calling `f(x,x)`. Instead, the user has to create a distinct variable *y* also enclosing `[-1,1]`. Algebraic simplification is not guaranteed to occur. For example, ``arb_add(z, x, x, prec)`` and ``arb_sub(z, x, x, prec)`` currently do not implement this optimization. It is better to use ``arb_mul_2exp_si(z, x, 1)`` and ``arb_zero(z)``, respectively. Thread safety and caches ------------------------------------------------------------------------------- Arb should be fully threadsafe, provided that both MPFR and FLINT have been built in threadsafe mode. Use ``flint_set_num_threads()`` to set the number of threads that Arb is allowed to use internally for single computations (this is currently only exploited by a handful of operations). Please note that thread safety is only tested minimally, and extra caution when developing multithreaded code is therefore recommended. Arb may cache some data (such as the value of `\pi` and Bernoulli numbers) to speed up various computations. In threadsafe mode, caches use thread-local storage. There is currently no way to save memory and avoid recomputation by having several threads share the same cache. Caches can be freed by calling the ``flint_cleanup()`` function. To avoid memory leaks, the user should call ``flint_cleanup()`` when exiting a thread. It is also recommended to call ``flint_cleanup()`` when exiting the main program (this should result in a clean output when running `Valgrind `_, and can help catching memory issues). There does not seem to be an obvious way to make sure that ``flint_cleanup()`` is called when exiting a thread using OpenMP. A possible solution to this problem is to use OpenMP sections, or to use C++ and create a thread-local object whose destructor invokes ``flint_cleanup()``. Use of hardware floating-point arithmetic ------------------------------------------------------------------------------- Arb uses hardware floating-point arithmetic (the ``double`` type in C) in two different ways. First, ``double`` arithmetic as well as transcendental ``libm`` functions (such as ``exp``, ``log``) are used to select parameters heuristically in various algorithms. Such heuristic use of approximate arithmetic does not affect correctness: when any error bounds depend on the parameters, the error bounds are evaluated separately using rigorous methods. At worst, flaws in the floating-point arithmetic on a particular machine could cause an algorithm to become inefficient due to inefficient parameters being selected. Second, ``double`` arithmetic is used internally for some rigorous error bound calculations. To guarantee correctness, we make the following assumptions. With the stated exceptions, these should hold on all commonly used platforms. * A ``double`` uses the standard IEEE 754 format (with a 53-bit significand, 11-bit exponent, encoding of infinities and NaNs, etc.) * We assume that the compiler does not perform "unsafe" floating-point optimizations, such as reordering of operations. Unsafe optimizations are disabled by default in most modern C compilers, including GCC and Clang. The exception appears to be the Intel C++ compiler, which does some unsafe optimizations by default. These must be disabled by the user. * We do not assume that floating-point operations are correctly rounded (a counterexample is the x87 FPU), or that rounding is done in any particular direction (the rounding mode may have been changed by the user). We assume that any floating-point operation is done with at most 1.1 ulp error. * We do not assume that underflow or overflow behaves in a particular way (we only use doubles that fit in the regular exponent range, or explicit infinities). * We do not use transcendental ``libm`` functions, since these can have errors of several ulps, and there is unfortunately no way to get guaranteed bounds. However, we do use functions such as ``ldexp`` and ``sqrt``, which we assume to be correctly implemented. Interface changes ------------------------------------------------------------------------------- Most of the core API should be stable at this point, and significant compatibility-breaking changes will be specified in the release notes. In general, Arb does not distinguish between "private" and "public" parts of the API. The implementation is meant to be transparent by design. All methods are intended to be fully documented and tested (exceptions to this are mainly due to lack of time on part of the author). The user should use common sense to determine whether a function is concerned with implementation details, making it likely to change as the implementation changes in the future. The interface of :func:`arb_add` is probably not going to change in the next version, but :func:`_arb_get_mpn_fixed_mod_pi4` just might. General note on correctness ------------------------------------------------------------------------------- Except where otherwise specified, Arb is designed to produce provably correct error bounds. The code has been written carefully, and the library is extensively tested. However, like any complex mathematical software, Arb is virtually certain to contain bugs, so the usual precautions are advised: * Do sanity checks. For example, check that the result satisfies an expected mathematical relation, or compute the same result in two different ways, with different settings, and with different levels of precision. Arb's unit tests already do such checks, but they are not guaranteed to catch every possible bug, and they provide no protection against the user accidentally using the interface incorrectly. * Compare results with other mathematical software. * Read the source code to verify that it really does what it is supposed to do. All bug reports are highly appreciated. arb-2.22.1/doc/source/mag.rst000066400000000000000000000425411417376376500157360ustar00rootroot00000000000000.. _mag: **mag.h** -- fixed-precision unsigned floating-point numbers for bounds =============================================================================== The :type:`mag_t` type holds an unsigned floating-point number with a fixed-precision mantissa (30 bits) and an arbitrary-precision exponent (represented as an :type:`fmpz_t`), suited for representing magnitude bounds. The special values zero and positive infinity are supported, but not NaN. Operations that involve rounding will always produce a valid upper bound, or a lower bound if the function name has the suffix *lower*. For performance reasons, no attempt is made to compute the best possible bounds: in general, a bound may be several ulps larger/smaller than the optimal bound. Some functions such as :func:`mag_set` and :func:`mag_mul_2exp_si` are always exact and therefore do not require separate *lower* versions. A common mistake is to forget computing a lower bound for the argument of a decreasing function that is meant to be bounded from above, or vice versa. For example, to compute an upper bound for `(x+1)/(y+1)`, the parameter *x* should initially be an upper bound while *y* should be a lower bound, and one should do:: mag_add_ui(tmp1, x, 1); mag_add_ui_lower(tmp2, y, 1); mag_div(res, tmp1, tmp2); For a lower bound of the same expression, *x* should be a lower bound while *y* should be an upper bound, and one should do:: mag_add_ui_lower(tmp1, x, 1); mag_add_ui(tmp2, y, 1); mag_div_lower(res, tmp1, tmp2); Applications requiring floating-point arithmetic with more flexibility (such as correct rounding, or higher precision) should use the :type:`arf_t` type instead. For calculations where a complex alternation between upper and lower bounds is necessary, it may be cleaner to use :type:`arb_t` arithmetic and convert to a :type:`mag_t` bound only in the end. Types, macros and constants ------------------------------------------------------------------------------- .. type:: mag_struct A :type:`mag_struct` holds a mantissa and an exponent. Special values are encoded by the mantissa being set to zero. .. type:: mag_t A :type:`mag_t` is defined as an array of length one of type :type:`mag_struct`, permitting a :type:`mag_t` to be passed by reference. Memory management ------------------------------------------------------------------------------- .. function:: void mag_init(mag_t x) Initializes the variable *x* for use. Its value is set to zero. .. function:: void mag_clear(mag_t x) Clears the variable *x*, freeing or recycling its allocated memory. .. function:: void mag_swap(mag_t x, mag_t y) Swaps *x* and *y* efficiently. .. function:: mag_ptr _mag_vec_init(slong n) Allocates a vector of length *n*. All entries are set to zero. .. function:: void _mag_vec_clear(mag_ptr v, slong n) Clears a vector of length *n*. .. function:: slong mag_allocated_bytes(const mag_t x) Returns the total number of bytes heap-allocated internally by this object. The count excludes the size of the structure itself. Add ``sizeof(mag_struct)`` to get the size of the object as a whole. Special values ------------------------------------------------------------------------------- .. function:: void mag_zero(mag_t res) Sets *res* to zero. .. function:: void mag_one(mag_t res) Sets *res* to one. .. function:: void mag_inf(mag_t res) Sets *res* to positive infinity. .. function:: int mag_is_special(const mag_t x) Returns nonzero iff *x* is zero or positive infinity. .. function:: int mag_is_zero(const mag_t x) Returns nonzero iff *x* is zero. .. function:: int mag_is_inf(const mag_t x) Returns nonzero iff *x* is positive infinity. .. function:: int mag_is_finite(const mag_t x) Returns nonzero iff *x* is not positive infinity (since there is no NaN value, this function is exactly the logical negation of :func:`mag_is_inf`). Assignment and conversions ------------------------------------------------------------------------------- .. function:: void mag_init_set(mag_t res, const mag_t x) Initializes *res* and sets it to the value of *x*. This operation is always exact. .. function:: void mag_set(mag_t res, const mag_t x) Sets *res* to the value of *x*. This operation is always exact. .. function:: void mag_set_d(mag_t res, double x) .. function:: void mag_set_fmpr(mag_t res, const fmpr_t x) .. function:: void mag_set_ui(mag_t res, ulong x) .. function:: void mag_set_fmpz(mag_t res, const fmpz_t x) Sets *res* to an upper bound for `|x|`. The operation may be inexact even if *x* is exactly representable. .. function:: void mag_set_d_lower(mag_t res, double x) .. function:: void mag_set_ui_lower(mag_t res, ulong x) .. function:: void mag_set_fmpz_lower(mag_t res, const fmpz_t x) Sets *res* to a lower bound for `|x|`. The operation may be inexact even if *x* is exactly representable. .. function:: void mag_set_d_2exp_fmpz(mag_t res, double x, const fmpz_t y) .. function:: void mag_set_fmpz_2exp_fmpz(mag_t res, const fmpz_t x, const fmpz_t y) .. function:: void mag_set_ui_2exp_si(mag_t res, ulong x, slong y) Sets *res* to an upper bound for `|x| \cdot 2^y`. .. function:: void mag_set_d_2exp_fmpz_lower(mag_t res, double x, const fmpz_t y) .. function:: void mag_set_fmpz_2exp_fmpz_lower(mag_t res, const fmpz_t x, const fmpz_t y) Sets *res* to a lower bound for `|x| \cdot 2^y`. .. function:: double mag_get_d(const mag_t x) Returns a *double* giving an upper bound for *x*. .. function:: double mag_get_d_log2_approx(const mag_t x) Returns a *double* approximating `\log_2(x)`, suitable for estimating magnitudes (warning: not a rigorous bound). The value is clamped between *COEFF_MIN* and *COEFF_MAX*. .. function:: void mag_get_fmpr(fmpr_t res, const mag_t x) Sets *res* exactly to *x*. .. function:: void mag_get_fmpq(fmpq_t res, const mag_t x) .. function:: void mag_get_fmpz(fmpz_t res, const mag_t x) .. function:: void mag_get_fmpz_lower(fmpz_t res, const mag_t x) Sets *res*, respectively, to the exact rational number represented by *x*, the integer exactly representing the ceiling function of *x*, or the integer exactly representing the floor function of *x*. These functions are unsafe: the user must check in advance that *x* is of reasonable magnitude. If *x* is infinite or has a bignum exponent, an abort will be raised. If the exponent otherwise is too large or too small, the available memory could be exhausted resulting in undefined behavior. Comparisons ------------------------------------------------------------------------------- .. function:: int mag_equal(const mag_t x, const mag_t y) Returns nonzero iff *x* and *y* have the same value. .. function:: int mag_cmp(const mag_t x, const mag_t y) Returns negative, zero, or positive, depending on whether *x* is smaller, equal, or larger than *y*. .. function:: int mag_cmp_2exp_si(const mag_t x, slong y) Returns negative, zero, or positive, depending on whether *x* is smaller, equal, or larger than `2^y`. .. function:: void mag_min(mag_t res, const mag_t x, const mag_t y) .. function:: void mag_max(mag_t res, const mag_t x, const mag_t y) Sets *res* respectively to the smaller or the larger of *x* and *y*. Input and output ------------------------------------------------------------------------------- .. function:: void mag_print(const mag_t x) Prints *x* to standard output. .. function:: void mag_fprint(FILE * file, const mag_t x) Prints *x* to the stream *file*. .. function:: char * mag_dump_str(const mag_t x) Allocates a string and writes a binary representation of *x* to it that can be read by :func:`mag_load_str`. The returned string needs to be deallocated with *flint_free*. .. function:: int mag_load_str(mag_t x, const char * str) Parses *str* into *x*. Returns a nonzero value if *str* is not formatted correctly. .. function:: int mag_dump_file(FILE * stream, const mag_t x) Writes a binary representation of *x* to *stream* that can be read by :func:`mag_load_file`. Returns a nonzero value if the data could not be written. .. function:: int mag_load_file(mag_t x, FILE * stream) Reads *x* from *stream*. Returns a nonzero value if the data is not formatted correctly or the read failed. Note that the data is assumed to be delimited by a whitespace or end-of-file, i.e., when writing multiple values with :func:`mag_dump_file` make sure to insert a whitespace to separate consecutive values. Random generation ------------------------------------------------------------------------------- .. function:: void mag_randtest(mag_t res, flint_rand_t state, slong expbits) Sets *res* to a random finite value, with an exponent up to *expbits* bits large. .. function:: void mag_randtest_special(mag_t res, flint_rand_t state, slong expbits) Like :func:`mag_randtest`, but also sometimes sets *res* to infinity. Arithmetic ------------------------------------------------------------------------------- .. function:: void mag_add(mag_t res, const mag_t x, const mag_t y) .. function:: void mag_add_ui(mag_t res, const mag_t x, ulong y) Sets *res* to an upper bound for `x + y`. .. function:: void mag_add_lower(mag_t res, const mag_t x, const mag_t y) .. function:: void mag_add_ui_lower(mag_t res, const mag_t x, ulong y) Sets *res* to a lower bound for `x + y`. .. function:: void mag_add_2exp_fmpz(mag_t res, const mag_t x, const fmpz_t e) Sets *res* to an upper bound for `x + 2^e`. .. function:: void mag_add_ui_2exp_si(mag_t res, const mag_t x, ulong y, slong e) Sets *res* to an upper bound for `x + y 2^e`. .. function:: void mag_sub(mag_t res, const mag_t x, const mag_t y) Sets *res* to an upper bound for `\max(x-y, 0)`. .. function:: void mag_sub_lower(mag_t res, const mag_t x, const mag_t y) Sets *res* to a lower bound for `\max(x-y, 0)`. .. function:: void mag_mul_2exp_si(mag_t res, const mag_t x, slong y) .. function:: void mag_mul_2exp_fmpz(mag_t res, const mag_t x, const fmpz_t y) Sets *res* to `x \cdot 2^y`. This operation is exact. .. function:: void mag_mul(mag_t res, const mag_t x, const mag_t y) .. function:: void mag_mul_ui(mag_t res, const mag_t x, ulong y) .. function:: void mag_mul_fmpz(mag_t res, const mag_t x, const fmpz_t y) Sets *res* to an upper bound for `xy`. .. function:: void mag_mul_lower(mag_t res, const mag_t x, const mag_t y) .. function:: void mag_mul_ui_lower(mag_t res, const mag_t x, ulong y) .. function:: void mag_mul_fmpz_lower(mag_t res, const mag_t x, const fmpz_t y) Sets *res* to a lower bound for `xy`. .. function:: void mag_addmul(mag_t z, const mag_t x, const mag_t y) Sets *z* to an upper bound for `z + xy`. .. function:: void mag_div(mag_t res, const mag_t x, const mag_t y) .. function:: void mag_div_ui(mag_t res, const mag_t x, ulong y) .. function:: void mag_div_fmpz(mag_t res, const mag_t x, const fmpz_t y) Sets *res* to an upper bound for `x / y`. .. function:: void mag_div_lower(mag_t res, const mag_t x, const mag_t y) Sets *res* to a lower bound for `x / y`. .. function:: void mag_inv(mag_t res, const mag_t x) Sets *res* to an upper bound for `1 / x`. .. function:: void mag_inv_lower(mag_t res, const mag_t x) Sets *res* to a lower bound for `1 / x`. Fast, unsafe arithmetic ------------------------------------------------------------------------------- The following methods assume that all inputs are finite and that all exponents (in all inputs as well as the final result) fit as *fmpz* inline values. They also assume that the output variables do not have promoted exponents, as they will be overwritten directly (thus leaking memory). .. function:: void mag_fast_init_set(mag_t x, const mag_t y) Initialises *x* and sets it to the value of *y*. .. function:: void mag_fast_zero(mag_t res) Sets *res* to zero. .. function:: int mag_fast_is_zero(const mag_t x) Returns nonzero iff *x* to zero. .. function:: void mag_fast_mul(mag_t res, const mag_t x, const mag_t y) Sets *res* to an upper bound for `xy`. .. function:: void mag_fast_addmul(mag_t z, const mag_t x, const mag_t y) Sets *z* to an upper bound for `z + xy`. .. function:: void mag_fast_add_2exp_si(mag_t res, const mag_t x, slong e) Sets *res* to an upper bound for `x + 2^e`. .. function:: void mag_fast_mul_2exp_si(mag_t res, const mag_t x, slong e) Sets *res* to an upper bound for `x 2^e`. Powers and logarithms ------------------------------------------------------------------------------- .. function:: void mag_pow_ui(mag_t res, const mag_t x, ulong e) .. function:: void mag_pow_fmpz(mag_t res, const mag_t x, const fmpz_t e) Sets *res* to an upper bound for `x^e`. .. function:: void mag_pow_ui_lower(mag_t res, const mag_t x, ulong e) .. function:: void mag_pow_fmpz_lower(mag_t res, const mag_t x, const fmpz_t e) Sets *res* to a lower bound for `x^e`. .. function:: void mag_sqrt(mag_t res, const mag_t x) Sets *res* to an upper bound for `\sqrt{x}`. .. function:: void mag_sqrt_lower(mag_t res, const mag_t x) Sets *res* to a lower bound for `\sqrt{x}`. .. function:: void mag_rsqrt(mag_t res, const mag_t x) Sets *res* to an upper bound for `1/\sqrt{x}`. .. function:: void mag_rsqrt_lower(mag_t res, const mag_t x) Sets *res* to an lower bound for `1/\sqrt{x}`. .. function:: void mag_hypot(mag_t res, const mag_t x, const mag_t y) Sets *res* to an upper bound for `\sqrt{x^2 + y^2}`. .. function:: void mag_root(mag_t res, const mag_t x, ulong n) Sets *res* to an upper bound for `x^{1/n}`. .. function:: void mag_log(mag_t res, const mag_t x) Sets *res* to an upper bound for `\log(\max(1,x))`. .. function:: void mag_log_lower(mag_t res, const mag_t x) Sets *res* to a lower bound for `\log(\max(1,x))`. .. function:: void mag_neg_log(mag_t res, const mag_t x) Sets *res* to an upper bound for `-\log(\min(1,x))`, i.e. an upper bound for `|\log(x)|` for `x \le 1`. .. function:: void mag_neg_log_lower(mag_t res, const mag_t x) Sets *res* to a lower bound for `-\log(\min(1,x))`, i.e. a lower bound for `|\log(x)|` for `x \le 1`. .. function:: void mag_log_ui(mag_t res, ulong n) Sets *res* to an upper bound for `\log(n)`. .. function:: void mag_log1p(mag_t res, const mag_t x) Sets *res* to an upper bound for `\log(1+x)`. The bound is computed accurately for small *x*. .. function:: void mag_exp(mag_t res, const mag_t x) Sets *res* to an upper bound for `\exp(x)`. .. function:: void mag_exp_lower(mag_t res, const mag_t x) Sets *res* to a lower bound for `\exp(x)`. .. function:: void mag_expinv(mag_t res, const mag_t x) Sets *res* to an upper bound for `\exp(-x)`. .. function:: void mag_expinv_lower(mag_t res, const mag_t x) Sets *res* to a lower bound for `\exp(-x)`. .. function:: void mag_expm1(mag_t res, const mag_t x) Sets *res* to an upper bound for `\exp(x) - 1`. The bound is computed accurately for small *x*. .. function:: void mag_exp_tail(mag_t res, const mag_t x, ulong N) Sets *res* to an upper bound for `\sum_{k=N}^{\infty} x^k / k!`. .. function:: void mag_binpow_uiui(mag_t res, ulong m, ulong n) Sets *res* to an upper bound for `(1 + 1/m)^n`. .. function:: void mag_geom_series(mag_t res, const mag_t x, ulong N) Sets *res* to an upper bound for `\sum_{k=N}^{\infty} x^k`. Special functions ------------------------------------------------------------------------------- .. function:: void mag_const_pi(mag_t res) .. function:: void mag_const_pi_lower(mag_t res) Sets *res* to an upper (respectively lower) bound for `\pi`. .. function:: void mag_atan(mag_t res, const mag_t x) .. function:: void mag_atan_lower(mag_t res, const mag_t x) Sets *res* to an upper (respectively lower) bound for `\operatorname{atan}(x)`. .. function:: void mag_cosh(mag_t res, const mag_t x) .. function:: void mag_cosh_lower(mag_t res, const mag_t x) .. function:: void mag_sinh(mag_t res, const mag_t x) .. function:: void mag_sinh_lower(mag_t res, const mag_t x) Sets *res* to an upper or lower bound for `\cosh(x)` or `\sinh(x)`. .. function:: void mag_fac_ui(mag_t res, ulong n) Sets *res* to an upper bound for `n!`. .. function:: void mag_rfac_ui(mag_t res, ulong n) Sets *res* to an upper bound for `1/n!`. .. function:: void mag_bin_uiui(mag_t res, ulong n, ulong k) Sets *res* to an upper bound for the binomial coefficient `{n \choose k}`. .. function:: void mag_bernoulli_div_fac_ui(mag_t res, ulong n) Sets *res* to an upper bound for `|B_n| / n!` where `B_n` denotes a Bernoulli number. .. function:: void mag_polylog_tail(mag_t res, const mag_t z, slong s, ulong d, ulong N) Sets *res* to an upper bound for .. math :: \sum_{k=N}^{\infty} \frac{z^k \log^d(k)}{k^s}. The bounding strategy is described in :ref:`algorithms_polylogarithms`. Note: in applications where `s` in this formula may be real or complex, the user can simply substitute any convenient integer `s'` such that `s' \le \operatorname{Re}(s)`. .. function:: void mag_hurwitz_zeta_uiui(mag_t res, ulong s, ulong a) Sets *res* to an upper bound for `\zeta(s,a) = \sum_{k=0}^{\infty} (k+a)^{-s}`. We use the formula .. math :: \zeta(s,a) \le \frac{1}{a^s} + \frac{1}{(s-1) a^{s-1}} which is obtained by estimating the sum by an integral. If `s \le 1` or `a = 0`, the bound is infinite. arb-2.22.1/doc/source/overview.rst000066400000000000000000000106601417376376500170350ustar00rootroot00000000000000.. _overview: Feature overview =============================================================================== Arb builds upon `FLINT `_, which deals with efficient computation over exact domains such as the rational numbers and finite fields. Arb extends FLINT to cover computations with real and complex numbers. The problem when computing with real and complex numbers is that approximations (typically floating-point numbers) must be used, potentially leading to incorrect results. Ball arithmetic, also known as mid-rad interval arithmetic, is an extension of floating-point arithmetic in which an error bound is attached to each variable. This allows computing rigorously with real and complex numbers. With plain floating-point arithmetic, the user must do an error analysis to guarantee that results are correct. Manual error analysis is time-consuming and bug-prone. Ball arithmetic effectively makes error analysis automatic. In traditional (inf-sup) interval arithmetic, both endpoints of an interval `[a,b]` are full-precision numbers, which makes interval arithmetic twice as expensive as floating-point arithmetic. In ball arithmetic, only the midpoint *m* of an interval `[m \pm r]` is a full-precision number, and a few bits suffice for the radius *r*. At high precision, ball arithmetic is therefore not more expensive than plain floating-point arithmetic. Joris van der Hoeven's paper [Hoe2009]_ is a good introduction to the subject. Other implementations of ball arithmetic include `iRRAM `_ and `Mathemagix `_. Arb differs from earlier implementations in technical aspects of the implementation, which makes certain computations more efficient. It also provides a more comprehensive low-level interface, giving the user full access to the internals. Finally, it implements a wider range of transcendental functions, covering a large portion of the special functions in standard reference works such as [NIST2012]_. Arb is designed for computer algebra and computational number theory, but may be useful in any area demanding reliable or precise numerical computing. Arb scales seamlessly from tens of digits up to billions of digits. Efficiency is achieved by low level optimizations and use of asymptotically fast algorithms. Arb contains: * A module (:ref:`arf `) for correctly rounded arbitrary-precision floating-point arithmetic. Arb's floating-point numbers have a few special features, such as arbitrary-size exponents (useful for combinatorics and asymptotics) and dynamic allocation (facilitating implementation of hybrid integer/floating-point and mixed-precision algorithms). * A module (:ref:`mag `) for representing magnitudes (error bounds) more efficiently than with an arbitrary-precision floating-point type. * A module (:ref:`arb `) for real ball arithmetic, where a ball is implemented as an *arf* midpoint and a *mag* radius. * A module (:ref:`acb `) for complex numbers in rectangular form, represented as pairs of real balls. * Modules (:ref:`arb_poly `, :ref:`acb_poly `) for polynomials or power series over the real and complex numbers, implemented using balls as coefficients, with asymptotically fast polynomial multiplication and many other operations. * Modules (:ref:`arb_mat `, :ref:`acb_mat `) for matrices over the real and complex numbers, implemented using balls as coefficients. At the moment, only rudimentary linear algebra operations are provided. * Functions for high-precision evaluation of various mathematical constants and special functions, implemented using ball arithmetic with rigorous error bounds. Arb 1.x used a different set of numerical base types (*fmpr*, *fmprb* and *fmpcb*). These types had a slightly simpler internal representation, but generally had worse performance. All methods for the Arb 1.x types have now been ported to faster equivalents for the Arb 2.x types. The last version to include both the Arb 1.x and Arb 2.x types and methods was Arb 2.2. As of Arb 2.9, only a small set of *fmpr* methods are left for fallback and testing purposes. Arb uses `GMP `_ / `MPIR `_ and `FLINT `_ for the underlying integer arithmetic and various utility functions. Arb also uses `MPFR `_ for testing purposes and internally to evaluate some functions. arb-2.22.1/doc/source/partitions.rst000066400000000000000000000071571417376376500173720ustar00rootroot00000000000000.. _partitions: **partitions.h** -- computation of the partition function =============================================================================== This module implements the asymptotically fast algorithm for evaluating the integer partition function `p(n)` described in [Joh2012]_. The idea is to evaluate a truncation of the Hardy-Ramanujan-Rademacher series using tight precision estimates, and symbolically factoring the occurring exponential sums. An implementation based on floating-point arithmetic can also be found in FLINT. That version relies on some numerical subroutines that have not been proved correct. The implementation provided here uses ball arithmetic throughout to guarantee a correct error bound for the numerical approximation of `p(n)`. Optionally, hardware double arithmetic can be used for low-precision terms. This gives a significant speedup for small (e.g. `n < 10^6`). .. function:: void partitions_rademacher_bound(arf_t b, const fmpz_t n, ulong N) Sets `b` to an upper bound for .. math :: M(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(\frac{\pi}{N} \sqrt{\frac{2n}{3}}\right). This formula gives an upper bound for the truncation error in the Hardy-Ramanujan-Rademacher formula when the series is taken up to the term `t(n,N)` inclusive. .. function:: void partitions_hrr_sum_arb(arb_t x, const fmpz_t n, slong N0, slong N, int use_doubles) Evaluates the partial sum `\sum_{k=N_0}^N t(n,k)` of the Hardy-Ramanujan-Rademacher series. If *use_doubles* is nonzero, doubles and the system's standard library math functions are used to evaluate the smallest terms. This significantly speeds up evaluation for small `n` (e.g. `n < 10^6`), and gives a small speed improvement for larger `n`, but the result is not guaranteed to be correct. In practice, the error is estimated very conservatively, and unless the system's standard library is broken, use of doubles can be considered safe. Setting *use_doubles* to zero gives a fully guaranteed bound. .. function:: void partitions_fmpz_fmpz(fmpz_t p, const fmpz_t n, int use_doubles) Computes the partition function `p(n)` using the Hardy-Ramanujan-Rademacher formula. This function computes a numerical ball containing `p(n)` and verifies that the ball contains a unique integer. If *n* is sufficiently large and a number of threads greater than 1 has been selected with :func:`flint_set_num_threads()`, the computation time will be reduced by using two threads. See :func:`partitions_hrr_sum_arb` for an explanation of the *use_doubles* option. .. function:: void partitions_fmpz_ui(fmpz_t p, ulong n) Computes the partition function `p(n)` using the Hardy-Ramanujan-Rademacher formula. This function computes a numerical ball containing `p(n)` and verifies that the ball contains a unique integer. .. function:: void partitions_fmpz_ui_using_doubles(fmpz_t p, ulong n) Computes the partition function `p(n)`, enabling the use of doubles internally. This significantly speeds up evaluation for small `n` (e.g. `n < 10^6`), but the error bounds are not certified (see remarks for :func:`partitions_hrr_sum_arb`). .. function:: void partitions_leading_fmpz(arb_t res, const fmpz_t n, slong prec) Sets *res* to the leading term in the Hardy-Ramanujan series for `p(n)` (without Rademacher's correction of this term, which is vanishingly small when `n` is large), that is, `\sqrt{12} (1-1/t) e^t / (24n-1)` where `t = \pi \sqrt{24n-1} / 6`. arb-2.22.1/doc/source/polylogarithms.rst000066400000000000000000000077641417376376500202570ustar00rootroot00000000000000.. _algorithms_polylogarithms: Algorithms for polylogarithms =============================================================================== The polylogarithm is defined for `s, z \in \mathbb{C}` with `|z| < 1` by .. math :: \operatorname{Li}_s(z) = \sum_{k=1}^{\infty} \frac{z^k}{k^s} and for `|z| \ge 1` by analytic continuation, except for the singular point `z = 1`. Computation for small z ------------------------------------------------------------------------------- The power sum converges rapidly when `|z| \ll 1`. To compute the series expansion with respect to `s`, we substitute `s \to s + x \in \mathbb{C}[[x]]` and obtain .. math :: \operatorname{Li}_{s+x}(z) = \sum_{d=0}^{\infty} x^d \frac{(-1)^d}{d!} \sum_{k=1}^{\infty} T(k) where .. math :: T(k) = \frac{z^k \log^d(k)}{k^s}. The remainder term `\left| \sum_{k=N}^{\infty} T(k) \right|` is bounded via the following strategy, implemented in :func:`mag_polylog_tail`. Denote the terms by `T(k)`. We pick a nonincreasing function `U(k)` such that .. math :: \frac{T(k+1)}{T(k)} = z \left(\frac{k}{k+1}\right)^s \left( \frac{\log(k+1)}{\log(k)} \right)^d \le U(k). Then, as soon as `U(N) < 1`, .. math :: \sum_{k=N}^{\infty} T(k) \le T(N) \sum_{k=0}^{\infty} U(N)^k = \frac{T(N)}{1 - U(N)}. In particular, we take .. math :: U(k) = z \; B(k, \max(0, -s)) \; B(k \log(k), d) where `B(m,n) = (1 + 1/m)^n`. This follows from the bounds .. math :: \left(\frac{k}{k+1}\right)^{s} \le \begin{cases} 1 & \text{if } s \ge 0 \\ (1 + 1/k)^{-s} & \text{if } s < 0. \end{cases} and .. math :: \left( \frac{\log(k+1)}{\log(k)} \right)^d \le \left(1 + \frac{1}{k \log(k)}\right)^d. Expansion for general z ------------------------------------------------------------------------------- For general complex `s, z`, we write the polylogarithm as a sum of two Hurwitz zeta functions .. math :: \operatorname{Li}_s(z) = \frac{\Gamma(v)}{(2\pi)^v} \left[ i^v \zeta \left(v, \frac{1}{2} + \frac{\log(-z)}{2\pi i}\right) + i^{-v} \zeta \left(v, \frac{1}{2} - \frac{\log(-z)}{2\pi i}\right) \right] in which `s = 1-v`. With the principal branch of `\log(-z)`, we obtain the conventional analytic continuation of the polylogarithm with a branch cut on `z \in (1,+\infty)`. To compute the series expansion with respect to `v`, we substitute `v \to v + x \in \mathbb{C}[[x]]` in this formula (at the end of the computation, we map `x \to -x` to obtain the power series for `\operatorname{Li}_{s+x}(z)`). The right hand side becomes .. math :: \Gamma(v+x) [E_1 Z_1 + E_2 Z_2] where `E_1 = (i/(2 \pi))^{v+x}`, `Z_1 = \zeta(v+x,\ldots)`, `E_2 = (1/(2 \pi i))^{v+x}`, `Z_2 = \zeta(v+x,\ldots)`. When `v = 1`, the `Z_1` and `Z_2` terms become Laurent series with a leading `1/x` term. In this case, we compute the deflated series `\tilde Z_1, \tilde Z_2 = \zeta(x,\ldots) - 1/x`. Then .. math :: E_1 Z_1 + E_2 Z_2 = (E_1 + E_2)/x + E_1 \tilde Z_1 + E_2 \tilde Z_2. Note that `(E_1 + E_2) / x` is a power series, since the constant term in `E_1 + E_2` is zero when `v = 1`. So we simply compute one extra derivative of both `E_1` and `E_2`, and shift them one step. When `v = 0, -1, -2, \ldots`, the `\Gamma(v+x)` prefactor has a pole. In this case, we proceed analogously and formally multiply `x \, \Gamma(v+x)` with `[E_1 Z_1 + E_2 Z_2] / x`. Note that the formal cancellation only works when the order `s` (or `v`) is an exact integer: it is not currently possible to use this method when `s` is a small ball containing any of `0, 1, 2, \ldots` (then the result becomes indeterminate). The Hurwitz zeta method becomes inefficient when `|z| \to 0` (it gives an indeterminate result when `z = 0`). This is not a problem since we just use the defining series for the polylogarithm in that region. It also becomes inefficient when `|z| \to \infty`, for which an asymptotic expansion would better. arb-2.22.1/doc/source/setup.rst000066400000000000000000000157121417376376500163320ustar00rootroot00000000000000.. _setup: Setup =============================================================================== Package managers ------------------------------------------------------------------------------- The easiest way to install Arb including all dependencies is via ready-made packages available for various distributions. Note that some package managers may not have the latest version of Arb. * Debian / Ubuntu / Linux Mint - https://packages.debian.org/source/sid/flint-arb * Fedora - https://admin.fedoraproject.org/pkgdb/package/rpms/arb/ * Arch Linux - https://www.archlinux.org/packages/community/x86_64/arb/ * Guix - https://www.gnu.org/software/guix/packages/A/ * Anaconda - https://anaconda.org/conda-forge/arb Installing SageMath or Nemo (see below) will also create an installation of Arb local to those systems. It is possible to link user code to that installation by setting the proper paths. Download ------------------------------------------------------------------------------- Tarballs of released versions can be downloaded from https://github.com/fredrik-johansson/arb/releases Alternatively, you can simply install Arb from a git checkout of https://github.com/fredrik-johansson/arb/. The master branch is recommended for keeping up with the latest improvements and bug fixes and should be safe to use at all times (only stable code that passes the test suite gets merged into the git master). Dependencies ------------------------------------------------------------------------------- Arb has the following dependencies: * Either MPIR (http://www.mpir.org) 2.6.0 or later, or GMP (http://www.gmplib.org) 5.1.0 or later. If MPIR is used instead of GMP, it must be compiled with the ``--enable-gmpcompat`` option. * MPFR (http://www.mpfr.org) 3.0.0 or later. * FLINT (http://www.flintlib.org) version 2.5 or later. You may also use a git checkout of https://github.com/fredrik-johansson/flint2 Standalone installation ------------------------------------------------------------------------------- To compile, test and install Arb from source as a standalone library, first install FLINT. Then go to the Arb source directory and run:: ./configure make make check (optional) make install If GMP/MPIR, MPFR or FLINT is installed in some other location than the default path ``/usr/local``, pass ``--with-gmp=...``, ``--with-mpfr=...`` or ``--with-flint=...`` with the correct path to configure (type ``./configure --help`` to show more options). After the installation, you may have to run ``ldconfig`` to make sure that the system's dynamic linker finds the library. On a multicore system, ``make`` can be run with the ``-j`` flag to build in parallel. For example, use ``make -j4`` on a quad-core machine. Running tests ------------------------------------------------------------------------------- After running ``make``, it is recommended to also run ``make check`` to verify that all unit tests pass. By default, the unit tests run a large number of iterations to improve the chances of detecting subtle problems. The whole test suite might take around 20 minutes on a single core (``make -jN check`` if you have more cores to spare). If you are in a hurry, you can adjust the number of test iterations via the ``ARB_TEST_MULTIPLIER`` environment variable. For example, the following will only run 10% of the default iterations:: export ARB_TEST_MULTIPLIER=0.1 make check It is also possible to run the unit tests for a single module, for instance:: make check MOD=arb_poly Building with MSVC ------------------------------------------------------------------------------- To compile arb with MSVC, compile MPIR, MPFR, pthreads-win32 and FLINT using MSVC. Install CMake >=2.8.12 and make sure it is in the path. Then go to the Arb source directory and run:: mkdir build cd build cmake .. # configure cmake --build . --config Release # build cmake --build . --config Release --target install # install To build a Debug build, create a new build directory and pass ``-DCMAKE_BUILD_TYPE=Debug`` to ``cmake``. To create a dll library, pass ``-DBUILD_SHARED_LIBS=yes`` to ``cmake``. Note that creating a dll library requires CMake >= 3.5.0 If the dependencies are not found, pass ``-DCMAKE_PREFIX_PATH=/path/to/deps`` to ``cmake`` to find the dependencies. To build tests add, pass ``-DBUILD_TESTING=yes`` to ``cmake`` and run ``ctest`` to run the tests. Running code ------------------------------------------------------------------------------- Here is an example program to get started using Arb: .. code-block:: c #include "arb.h" int main() { arb_t x; arb_init(x); arb_const_pi(x, 50 * 3.33); arb_printn(x, 50, 0); flint_printf("\n"); flint_printf("Computed with arb-%s\n", arb_version); arb_clear(x); } Compile it with:: gcc test.c -larb Depending on the environment, you may also have to pass the flags ``-lflint``, ``-lmpfr``, ``-lgmp`` to the compiler. On some Debian based systems, ``-larb`` needs to be replaced with ``-lflint-arb``. If the Arb/FLINT header and library files are not in a standard location (``/usr/local`` on most systems), you may also have to provide flags such as:: -I/path/to/arb -I/path/to/flint -L/path/to/flint -L/path/to/arb Finally, to run the program, make sure that the linker can find the FLINT (and Arb) libraries. If they are installed in a nonstandard location, you can for example add this path to the ``LD_LIBRARY_PATH`` environment variable. The output of the example program should be something like the following:: [3.1415926535897932384626433832795028841971693993751 +/- 6.28e-50] Computed with arb-2.4.0 Computer algebra systems and wrappers ------------------------------------------------------------------------------- * Python-FLINT (https://github.com/fredrik-johansson/python-flint) is a convenient Python interface to both FLINT and Arb. * SageMath (http://sagemath.org/) includes Arb as a standard package and contains a high-level Python interface. Refer to the SageMath documentation: * RealBallField: http://doc.sagemath.org/html/en/reference/rings_numerical/sage/rings/real_arb.html * ComplexBallField: http://doc.sagemath.org/html/en/reference/rings_numerical/sage/rings/complex_arb.html * Nemo (http://nemocas.org/) is a computer algebra package for the Julia programming language which includes a high-level Julia interface to Arb. The Nemo installation script will create a local installation of Arb along with other dependencies. * Real balls: http://nemocas.github.io/Nemo.jl/latest/arb.html * Complex balls: http://nemocas.github.io/Nemo.jl/latest/acb.html * Arblib.jl (https://github.com/kalmarek/Arblib.jl) is a thin, efficient Julia wrapper around Arb. * Other wrappers include: * ArbNumerics (Julia): https://github.com/JeffreySarnoff/ArbNumerics.jl * ArbFloats (Julia): https://github.com/JuliaArbTypes/ArbFloats.jl arb-2.22.1/doc/source/using.rst000066400000000000000000000551461417376376500163240ustar00rootroot00000000000000.. _using: Using ball arithmetic =============================================================================== This section gives an introduction to working with real numbers in Arb (see :ref:`arb` for the API and technical documentation). The general principles carry over to complex numbers, polynomials and matrices. Ball semantics ------------------------------------------------------------------------------- Let `f : A \to B` be a function. A ball implementation of `f` is a function `F` that maps sets `X \subseteq A` to sets `F(X) \subseteq B` subject to the following rule: For all `x \in X`, we have `f(x) \in F(X)`. In other words, `F(X)` is an *enclosure* for the set `\{f(x) : x \in X\}`. This rule is sometimes called the *inclusion principle*. Throughout the documentation (except where otherwise noted), we will simply write `f(x)` instead of `F(X)` when describing ball implementations of pointwise-defined mathematical functions, understanding that the input is a set of point values and that the output is an enclosure. General subsets of `\mathbb{R}` are not possible to represent on a computer. Instead, we work with subsets of the form `[m \pm r] = [m-r, m+r]` where the midpoint *m* and radius *r* are binary floating-point numbers, i.e. numbers of the form `u 2^v` with `u, v \in \mathbb{Z}` (to make this scheme complete, we also need to adjoin the special floating-point values `-\infty`, `+\infty` and `\operatorname{NaN}`). Given a ball `[m \pm r]` with `m \in \mathbb{R}` (not necessarily a floating-point number), we can always round *m* to a nearby floating-point number that has at most most *prec* bits in the component *u*, and add an upper bound for the rounding error to *r*. In Arb, ball functions that take a *prec* argument as input (e.g. :func:`arb_add`) always round their output to *prec* bits. Some functions are always exact (e.g. :func:`arb_neg`), and thus do not take a *prec* argument. The programming interface resembles that of GMP. Each :type:`arb_t` variable must be initialized with :func:`arb_init` before use (this also sets its value to zero), and deallocated with :func:`arb_clear` after use. Variables have pass-by-reference semantics. In the list of arguments to a function, output variables come first, followed by input variables, and finally the precision: .. code-block:: c #include "arb.h" int main() { arb_t x, y; arb_init(x); arb_init(y); arb_set_ui(x, 3); /* x = 3 */ arb_const_pi(y, 128); /* y = pi, to 128 bits */ arb_sub(y, y, x, 53); /* y = y - x, to 53 bits */ arb_clear(x); arb_clear(y); } Binary and decimal ------------------------------------------------------------------------------- While the internal representation uses binary floating-point numbers, it is usually preferable to print numbers in decimal. The binary-to-decimal conversion generally requires rounding. Three different methods are available for printing a number to standard output: * :func:`arb_print` shows the exact internal representation of a ball, with binary exponents. * :func:`arb_printd` shows an inexact view of the internal representation, approximated by decimal floating-point numbers. * :func:`arb_printn` shows a *decimal ball* that is guaranteed to be an enclosure of the binary floating-point ball. By default, it only prints digits in the midpoint that are certain to be correct, up to an error of at most one unit in the last place. Converting from binary to decimal is generally inexact, and the output of this method takes this rounding into account when printing the radius. This snippet computes a 53-bit enclosure of `\pi` and prints it in three ways: .. code-block:: c arb_const_pi(x, 53); arb_print(x); printf("\n"); arb_printd(x, 20); printf("\n"); arb_printn(x, 20, 0); printf("\n"); The output is: .. code-block:: text (884279719003555 * 2^-48) +/- (536870913 * 2^-80) 3.141592653589793116 +/- 4.4409e-16 [3.141592653589793 +/- 5.61e-16] The :func:`arb_get_str` and :func:`arb_set_str` methods are useful for converting rigorously between decimal strings and binary balls (:func:`arb_get_str` produces the same string as :func:`arb_printn`, and :func:`arb_set_str` can parse such strings back). A potential mistake is to create a ball from a ``double`` constant such as ``2.3``, when this actually represents ``2.29999999999999982236431605997495353221893310546875``. To produce a ball containing the rational number `23/10`, one of the following can be used: .. code-block:: c arb_set_str(x, "2.3", prec) arb_set_ui(x, 23); arb_div_ui(x, x, 10, prec) fmpq_set_si(q, 23, 10); /* q is a FLINT fmpq_t */ arb_set_fmpq(x, q, prec); Quality of enclosures ------------------------------------------------------------------------------- The main problem when working with ball arithmetic (or interval arithmetic) is *overestimation*. In general, the enclosure of a value or set of values as computed with ball arithmetic will be larger than the smallest possible enclosure. Overestimation results naturally from rounding errors and cancellations in the individual steps of a calculation. As a general principle, formula rewriting techniques that make floating-point code more numerically stable also make ball arithmetic code more numerically stable, in the sense of producing tighter enclosures. As a result of the *dependency problem*, ball or interval arithmetic can produce error bounds that are much larger than the actual numerical errors resulting from doing floating-point arithmetic. Consider the expression `(x + 1) - x` as an example. When evaluated in floating-point arithmetic, `x` may have a large initial error. However, that error will cancel itself out in the subtraction, so that the result equals 1 (except perhaps for a small rounding error left from the operation `x + 1`). In ball arithmetic, dependent errors add up instead of cancelling out. If `x = [3 \pm 0.1]`, the result will be `[1 \pm 0.2]`, where the error bound has doubled. In unfavorable circumstances, error bounds can grow exponentially with the number of steps. If all inputs to a calculation are "point values", i.e. exact numbers and known mathematical constants that can be approximated arbitrarily closely (such as `\pi`), then an error of order `2^n` can typically be overcome by working with *n* extra bits of precision, increasing the computation time by an amount that is polynomial in *n*. In certain situations, however, overestimation leads to exponential slowdown or even failure of an algorithm to converge. For example, root-finding algorithms that refine the result iteratively may fail to converge in ball arithmetic, even if they do converge in plain floating-point arithmetic. Therefore, ball arithmetic is not a silver bullet: there will always be situations where some amount of numerical or mathematical analysis is required. Some experimentation may be required to find whether (and how) it can be used effectively for a given problem. Predicates ------------------------------------------------------------------------------- A ball implementation of a predicate `f : \mathbb{R} \to \{\operatorname{True}, \operatorname{False}\}` would need to be able to return a third logical value indicating that the result could be either True or False. In most cases, predicates in Arb are implemented as functions that return the *int* value 1 to indicate that the result certainly is True, and the *int* value 0 to indicate that the result could be either True or False. To test whether a predicate certainly is False, the user must test whether the negated predicate certainly is True. For example, the following code would *not* be correct in general: .. code-block:: c if (arb_is_positive(x)) { ... /* do things assuming that x > 0 */ } else { ... /* do things assuming that x <= 0 */ } Instead, the following can be used: .. code-block:: c if (arb_is_positive(x)) { ... /* do things assuming that x > 0 */ } else if (arb_is_nonpositive(x)) { ... /* do things assuming that x <= 0 */ } else { ... /* do things assuming that the sign of x is unknown */ } Likewise, we will write `x \le y` in mathematical notation with the meaning that `x \le y` holds for all `x \in X, y \in Y` where `X` and `Y` are balls. Note that some predicates such as :func:`arb_overlaps` and :func:`arb_contains` actually are predicates on balls viewed as sets, and not ball implementations of pointwise predicates. Some predicates are also complementary. For example :func:`arb_contains_zero` tests whether the input ball contains the point zero. Negated, it is equivalent to :func:`arb_is_nonzero`, and complementary to :func:`arb_is_zero` as a pointwise predicate: .. code-block:: c if (arb_is_zero(x)) { ... /* do things assuming that x = 0 */ } #if 1 else if (arb_is_nonzero(x)) #else else if (!arb_contains_zero(x)) /* equivalent */ #endif { ... /* do things assuming that x != 0 */ } else { ... /* do things assuming that the sign of x is unknown */ } A worked example: the sine function ------------------------------------------------------------------------------- We implement the function `\sin(x)` naively using the Taylor series `\sum_{k=0}^{\infty} (-1)^k x^{2k+1} / (2k+1)!` and :type:`arb_t` arithmetic. Since there are infinitely many terms, we need to split the series in two parts: a finite sum that can be evaluated directly, and a tail that has to be bounded. We stop as soon as we reach a term `t` bounded by `|t| \le 2^{-prec} < 1`. The terms are alternating and must have decreasing magnitude from that point, so the tail of the series is bounded by `|t|`. We add this magnitude to the radius of the output. Since ball arithmetic automatically bounds the numerical errors resulting from all arithmetic operations, the output *res* is a ball guaranteed to contain `\sin(x)`. .. code-block:: c #include "arb.h" void arb_sin_naive(arb_t res, const arb_t x, slong prec) { arb_t s, t, u, tol; slong k; arb_init(s); arb_init(t); arb_init(u); arb_init(tol); arb_one(tol); arb_mul_2exp_si(tol, tol, -prec); /* tol = 2^-prec */ for (k = 0; ; k++) { arb_pow_ui(t, x, 2 * k + 1, prec); arb_fac_ui(u, 2 * k + 1, prec); arb_div(t, t, u, prec); /* t = x^(2k+1) / (2k+1)! */ arb_abs(u, t); if (arb_le(u, tol)) /* if |t| <= 2^-prec */ { arb_add_error(s, u); /* add |t| to the radius and stop */ break; } if (k % 2 == 0) arb_add(s, s, t, prec); else arb_sub(s, s, t, prec); } arb_set(res, s); arb_clear(s); arb_clear(t); arb_clear(u); arb_clear(tol); } This algorithm is naive, because the Taylor series is slow to converge and suffers from catastrophic cancellation when `|x|` is large (we could also improve the efficiency of the code slightly by computing the terms using recurrence relations instead of computing `x^k` and `k!` from scratch each iteration). As a test, we compute `\sin(2016.1)`. The largest term in the Taylor series for `\sin(x)` reaches a magnitude of about `x^x / x!`, or about `10^{873}` in this case. Therefore, we need over 873 digits (about 3000 bits) of precision to overcome the catastrophic cancellation and determine the result with sufficient accuracy to tell whether it is positive or negative. .. code-block:: c int main() { arb_t x, y; slong prec; arb_init(x); arb_init(y); for (prec = 64; ; prec *= 2) { arb_set_str(x, "2016.1", prec); arb_sin_naive(y, x, prec); printf("Using %5ld bits, sin(x) = ", prec); arb_printn(y, 10, 0); printf("\n"); if (!arb_contains_zero(y)) /* stopping condition */ break; } arb_clear(x); arb_clear(y); } The program produces the following output: .. code-block:: text Using 64 bits, sin(x) = [+/- 2.67e+859] Using 128 bits, sin(x) = [+/- 1.30e+840] Using 256 bits, sin(x) = [+/- 3.60e+801] Using 512 bits, sin(x) = [+/- 3.01e+724] Using 1024 bits, sin(x) = [+/- 2.18e+570] Using 2048 bits, sin(x) = [+/- 1.22e+262] Using 4096 bits, sin(x) = [-0.7190842207 +/- 1.20e-11] As an exercise, the reader may improve the naive algorithm by making it subtract a well-chosen multiple of `2 \pi` from `x` before invoking the Taylor series (hint: use :func:`arb_const_pi`, :func:`arb_div` and :func:`arf_get_fmpz`). If done correctly, 64 bits of precision should be more than enough to compute `\sin(2016.1)`, and with minor adjustments to the code, the user should be able to compute `\sin(\exp(2016.1))` quite easily as well. This example illustrates how ball arithmetic can be used to perform nontrivial calculations. To evaluate an infinite series, the user needs to know how to bound the tail of the series, but everything else is automatic. When evaluating a finite formula that can be expressed completely using built-in functions, all error bounding is automatic from the point of view of the user. In particular, the :func:`arb_sin` method should be used to compute the sine of a real number; it uses a much more efficient algorithm than the naive code above. This example also illustrates the "guess-and-verify" paradigm: instead of determining *a priori* the floating-point precision necessary to get a correct result, we *guess* some initial precision, use ball arithmetic to *verify* that the result is accurate enough, and restart with higher precision (or signal failure) if it is not. If we think of rounding errors as essentially random processes, then a floating-point computation is analogous to a *Monte Carlo algorithm*. Using ball arithmetic to get a verified result effectively turns it into the analog of a *Las Vegas algorithm*, which is a randomized algorithm that always gives a correct result if it terminates, but may fail to terminate (alternatively, instead of actually looping forever, it might signal failure after a certain number of iterations). The loop will fail to terminate if we attempt to determine the sign of `\sin(\pi)`: .. code-block:: text Using 64 bits, sin(x) = [+/- 3.96e-18] Using 128 bits, sin(x) = [+/- 2.17e-37] Using 256 bits, sin(x) = [+/- 6.10e-76] Using 512 bits, sin(x) = [+/- 5.13e-153] Using 1024 bits, sin(x) = [+/- 4.01e-307] Using 2048 bits, sin(x) = [+/- 2.13e-615] Using 4096 bits, sin(x) = [+/- 6.85e-1232] Using 8192 bits, sin(x) = [+/- 6.46e-2465] Using 16384 bits, sin(x) = [+/- 5.09e-4931] Using 32768 bits, sin(x) = [+/- 5.41e-9863] ... The sign of a nonzero real number can be decided by computing it to sufficiently high accuracy, but the sign of an expression that is exactly equal to zero cannot be decided by a numerical computation unless the entire computation happens to be exact (in this example, we could use the :func:`arb_sin_pi` function which computes `\sin(\pi x)` in one step, with the input `x = 1`). It is up to the user to implement a stopping criterion appropriate for the circumstances of a given application. For example, breaking when it is clear that `|\sin(x)| < 10^{-10000}` would allow the program to terminate and convey some meaningful information about the input `x = \pi`, though this would not constitute a mathematical proof that `\sin(\pi) = 0`. More on precision and accuracy ------------------------------------------------------------------------------- The relation between the working precision and the accuracy of the output is not always easy predict. The following remarks might help to choose *prec* optimally. For a ball `[m \pm r]` it is convenient to define the following notions: * Absolute error: `e_{abs} = |r|` * Relative error: `e_{rel} = |r| / \max(0, |m| - |r|)` (or `e_{rel} = 0` if `r = m = 0`) * Absolute accuracy: `a_{abs} = 1 / e_{abs}` * Relative accuracy: `a_{rel} = 1 / e_{rel}` Expressed in bits, one takes the corresponding `\log_2` values. Of course, if `x` is the exact value being approximated, then the "absolute error" so defined is an upper bound for the actual absolute error `|x-m|` and "absolute accuracy" a lower bound for `1/|x-m|`, etc. The *prec* argument in Arb should be thought of as controlling the working precision. Generically, when evaluating a fixed expression (that is, when the sequence of operations does not depend on the precision), the absolute or relative error will be bounded by .. math :: 2^{O(1) - prec} where the `O(1)` term depends on the expression and implementation details of the ball functions used to evaluate it. Accordingly, for an accuracy of *p* bits, we need to use a working precision `O(1) + p`. If the expression is numerically well-behaved, then the `O(1)` term will be small, which leads to the heuristic of "adding a few guard bits" (for most basic calculations, 10 or 20 guard bits is enough). If the `O(1)` term is unknown, then increasing the number of guard bits in exponential steps until the result is accurate enough is generally a good heuristic. Sometimes, a partially accurate result can be used to estimate the `O(1)` term. For example, if the goal is to achieve 100 bits of accuracy and a precision of 120 bits yields 80 bits of accuracy, then it is plausible that a precision of just over 140 bits yields 100 bits of accuracy. Built-in functions in Arb can roughly be characterized as belonging to one of two extremes (though there is actually a spectrum): * Simple operations, including basic arithmetic operations and many elementary functions. In most cases, for an input `x = [m \pm r]`, `f(x)` is evaluated by computing `f(m)` and then separately bounding the *propagated error* `|f(m) - f(m + \varepsilon)|, |\varepsilon| \le r`. The working precision is automatically increased internally so that `f(m)` is computed to *prec* bits of relative accuracy with an error of at most a few units in the last place (perhaps with rare exceptions). The propagated error can generally be bounded quite tightly as well (see :ref:`general_formulas`). As a result, the enclosure will be close to the best possible at the given precision, and the user can estimate the precision to use accordingly. * Complex operations, such as certain higher transcendental functions (for example, the Riemann zeta function). The function is evaluated by performing a sequence of simpler operations, each using ball arithmetic with a working precision of roughly *prec* bits. The sequence of operations might depend on *prec*; for example, an infinite series might be truncated so that the remainder is smaller than `2^{-prec}`. The final result can be far from tight, and it is not guaranteed that the error converges to zero as `prec \to \infty`, though in practice, it should do so in most cases. In short, the *inclusion principle* is the fundamental contract in Arb. Enclosures computed by built-in functions may or may not be tight enough to be useful, but the hope is that they will be sufficient for most purposes. Tightening the error bounds for more complex operations is a long term optimization goal, which in many cases will require a fair amount of research. A tradeoff also has to be made for efficiency: tighter error bounds allow the user to work with a lower precision, but they may also be much more expensive to compute. Polynomial time guarantee ------------------------------------------------------------------------------- Arb provides a soft guarantee that the time used to evaluate a ball function will depend polynomially on *prec* and the bit size of the input, uniformly regardless of the numerical value of the input. The idea behind this soft guarantee is to allow Arb to be used as a black box to evaluate expressions numerically without potentially slowing down, hanging indefinitely or crashing because of "bad" input such as nested exponentials. By controlling the precision, the user can cancel a computation before it uses up an unreasonable amount of resources, without having to rely on other timeout or exception mechanisms. A result that is feasible but very expensive to compute can still be forced by setting the precision high enough. As motivation, consider evaluating `\sin(x)` or `\exp(x)` with the exact floating-point number `x = 2^{2^n}` as input. The time and space required to compute an accurate floating-point approximation of `\sin(x)` or `\exp(x)` increases as `2^n`, in the first case because because of the need to subtract an accurate multiple of `2\pi` and in the second case due to the size of the output exponent and the internal subtraction of an accurate multiple of `\log(2)`. This is despite the fact that the size of `x` as an object in memory only increases linearly with `n`. Already `n = 33` would require at least 1 GB of memory, and `n = 100` would be physically impossible to process. For functions that are computed by direct use of power series expansions, e.g. `f(x) = \sum_{k=0}^{\infty} c_k x^k`, without having fast argument-reduction techniques like those for elementary functions, the time would be exponential in `n` already when `x = 2^n`. Therefore, Arb caps internal work parameters (the internal working precision, the number terms of an infinite series to add, etc.) by polynomial, usually linear, functions of *prec*. When the limit is exceeded, the output is set to a crude bound. For example, if `x` is too large, :func:`arb_sin` will simply return `[\pm 1]`, and :func:`arb_exp` will simply return `[\pm \infty]` if `x` is positive or `[\pm 2^{-m}]` if `x` is negative. This is not just a failsafe, but occasionally a useful optimization. It is not entirely uncommon to have formulas where one term is modest and another term decreases exponentially, such as: .. math :: \log(x) + \sin(x) \exp(-x). For example, the reflection formula of the digamma function has a similar structure. When `x` is large, the right term would be expensive to compute to high relative accuracy. Doing so is unnecessary, however, since a crude bound of `[\pm 1] \cdot [\pm 2^{-m}]` is enough to evaluate the expression as a whole accurately. The polynomial time guarantee is "soft" in that there are a few exceptions. For example, the complexity of computing the Riemann zeta function `\zeta(\sigma+it)` increases linearly with the imaginary height `|t|` in the current implementation, and all known algorithms have a complexity of `|t|^{\alpha}` where the best known value for `\alpha` is about `0.3`. Input with large `|t|` is most likely to be given deliberately by users with the explicit intent of evaluating the zeta function itself, so the evaluation is not cut off automatically. arb-2.22.1/doc/source/verify_taylor.py000066400000000000000000000172621417376376500177120ustar00rootroot00000000000000from gmpy import mpq, lcm, denom, numer, fac def atan_coefficients(NN, bits): ps = [] qs = [] temp = [] Q = 1 for k in range(2*NN+50): p = 1 q = 2*k+1 if lcm(Q, q) < 2**bits: temp.append(mpq(p,q)) Q = lcm(Q, q) else: for a in temp: ps.append(int(a * Q)) qs.append(int(Q)) Q = q temp = [mpq(p,q)] return ps[:NN], qs[:NN] def exp_coefficients(M, bits): N = 2*M+50 Qs = [fac(k) for k in range(N)] prevstop = 0 for k in range(N): if Qs[k] >= 2**bits-1: q = Qs[k-1] for i in range(k, N): Qs[i] //= q for i in range(prevstop, k): Qs[i] = q prevstop = k Ps = Qs[:] fact = 1 for k in range(1, N): assert Qs[k] < 2**bits-1 if Qs[k] == Qs[k-1]: fact *= k else: fact = k Ps[k] //= fact return map(int, Ps)[:N], map(int, Qs)[:N] class FixedPointBound(object): def __init__(self, bits, mid, rad): self.bits = bits self.mid = mpq(mid) self.rad = mpq(rad) # rad is in ulp def add(self, other): if isinstance(other, FixedPointBound): mid = self.mid + other.mid rad = self.rad + other.rad else: assert other == int(other) and other >= 0 mid = self.mid + int(other) rad = self.rad return FixedPointBound(self.bits, mid, rad) def mul(self, other): if isinstance(other, FixedPointBound): MAX_ULP = mpq(1, 2**self.bits) mid = self.mid * other.mid rad = 0 rad += self.rad * other.mid # ulp rad += self.mid * other.rad # ulp rad += self.rad * other.rad * MAX_ULP # ulp rad += 1 # ulp rounding else: assert other == int(other) and other >= 0 mid = self.mid * int(other) rad = self.rad * int(other) return FixedPointBound(self.bits, mid, rad) def div(self, other): assert other == int(other) and other >= 0 mid = self.mid / mpq(other) rad = self.rad / mpq(other) + 1 return FixedPointBound(self.bits, mid, rad) def addmul(self, other, c): assert c == int(c) and c >= 0 c = abs(int(c)) mid = self.mid + other.mid * c rad = self.rad + other.rad * c return FixedPointBound(self.bits, mid, rad) def check_overflow_0(self): # check that self fits 0 integral limbs MAX_ULP = mpq(1, 2**self.bits) assert self.mid + self.rad * MAX_ULP < 1 - MAX_ULP def check_overflow_1(self): # check that self fits 1 integral limb MAX_ULP = mpq(1, 2**self.bits) assert self.mid + self.rad * MAX_ULP < 2**self.bits - MAX_ULP def check_le_int(self, c): # check that |self| <= c MAX_ULP = mpq(1, 2**self.bits) assert self.mid + self.rad * MAX_ULP <= c def verify_atan(N, PS, QS, bits): X = FixedPointBound(bits, mpq(1,16), 0) S = FixedPointBound(bits, 0, 0) m = 2 while m * m < N: m += 2 T = [None] * (m+1) T[1] = X.mul(X) T[2] = T[1].mul(T[1]) for k in range(4, m + 1, 2): T[k-1] = T[k//2].mul(T[k//2-1]) T[k] = T[k//2].mul(T[k//2]) for k in range(N-1, -1, -1): c, d, e = PS[k], QS[k], QS[k+1] if d != e and k < N-1: # if alternating, adding e must give a nonnegative number S.check_le_int(e) # adding e must not overflow S.add(e).check_overflow_1() S = S.mul(d).div(e) # if alternating, adding d must not overflow S.add(d).check_overflow_1() if k % m == 0: # if alternating, adding c must give a nonnegative number S.check_le_int(c) S = S.add(c) S.check_overflow_1() if k != 0: S = S.mul(T[m]) S.check_overflow_1() else: S = S.addmul(T[k % m], c) S.check_overflow_1() S = S.div(mpq(QS[0])) S = S.mul(X) S.check_overflow_0() print N, float(S.mid), float(S.rad) assert S.rad <= 2 def verify_exp(N, PS, QS, bits): X = FixedPointBound(bits, mpq(1,16), 0) S = FixedPointBound(bits, 0, 0) m = 2 while m * m < N: m += 2 T = [None] * (m+1) T[1] = X T[2] = T[1].mul(T[1]) for k in range(4, m + 1, 2): T[k-1] = T[k//2].mul(T[k//2-1]) T[k] = T[k//2].mul(T[k//2]) for k in range(N-1, -1, -1): c, d, e = PS[k], QS[k], QS[k+1] if d != e and k < N-1: # if alternating, adding e must give a nonnegative number S.check_le_int(e) # adding e must not overflow S.add(e).check_overflow_1() S = S.div(e) # if alternating, adding 1 must not overflow S.add(1).check_overflow_1() if k % m == 0: # if alternating, adding c must give a nonnegative number S.check_le_int(c) S = S.add(c) S.check_overflow_1() if k != 0: S = S.mul(T[m]) S.check_overflow_1() else: S = S.addmul(T[k % m], c) S.check_overflow_1() S = S.div(mpq(QS[0])) S.check_overflow_1() print N, float(S.mid), float(S.rad) assert S.rad <= 2 def verify_sin_cos(N, PS, QS, bits): X = FixedPointBound(bits, mpq(1,16), 0) m = 2 while m * m < N: m += 2 T = [None] * (m+1) T[1] = X.mul(X) T[2] = T[1].mul(T[1]) for k in range(4, m + 1, 2): T[k-1] = T[k//2].mul(T[k//2-1]) T[k] = T[k//2].mul(T[k//2]) for cosorsin in range(2): S = FixedPointBound(bits, 0, 0) for k in range(N-1, -1, -1): c, d, e = PS[2*k+cosorsin], QS[2*k+cosorsin], QS[2*k+cosorsin+2] if d != e and k < N-1: # if alternating, adding e must give a nonnegative number S.check_le_int(e) # adding e must not overflow S.add(e).check_overflow_1() S = S.div(e) # if alternating, adding 1 must not overflow S.add(1).check_overflow_1() if k % m == 0: # if alternating, adding c must give a nonnegative number S.check_le_int(c) S = S.add(c) S.check_overflow_1() if k != 0: S = S.mul(T[m]) S.check_overflow_1() else: S = S.addmul(T[k % m], c) S.check_overflow_1() if cosorsin == 0: S = S.div(mpq(QS[0])) S.check_overflow_1() # note: top limb must actually be 0 or 1; # but this follows by S.rad <= 2 print N, float(S.mid), float(S.rad) assert S.rad <= 2 else: S = S.div(mpq(QS[0])) S.check_overflow_1() S = S.mul(X) S.check_overflow_0() print N, float(S.mid), float(S.rad) assert S.rad <= 2 for bits in [32, 64]: PS, QS = exp_coefficients(300, bits) for N in range(300): verify_sin_cos(N, PS, QS, bits) for bits in [32, 64]: PS, QS = exp_coefficients(300, bits) for N in range(300): verify_exp(N, PS, QS, bits) for bits in [32, 64]: PS, QS = atan_coefficients(300, bits) for N in range(300): verify_atan(N, PS, QS, bits) arb-2.22.1/double_interval.h000066400000000000000000000073671417376376500157310ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef DOUBLE_INTERVAL_H #define DOUBLE_INTERVAL_H #ifdef DOUBLE_INTERVAL_INLINES_C #define DOUBLE_INTERVAL_INLINE #else #define DOUBLE_INTERVAL_INLINE static __inline__ #endif #include "flint/double_extras.h" #include "arb.h" #ifdef __cplusplus extern "C" { #endif typedef struct { double a; double b; } di_t; #define DI_CHECK(__x) \ if (!(__x.a <= __x.b)) \ { \ flint_printf("di_t endpoints %g, %g not ordered\n", __x.a, __x.b); \ flint_abort(); \ } \ DOUBLE_INTERVAL_INLINE di_t di_interval(double a, double b) { di_t res; if (!(a <= b)) { flint_printf("di_interval endpoints %g, %g not ordered\n", a, b); flint_abort(); } res.a = a; res.b = b; return res; } DOUBLE_INTERVAL_INLINE double _di_below(double x) { double t; if (x <= 1e300) { t = x; if (t < 0.0) t = -t; t += 1e-300; return x - t * 4.440892098500626e-16; } else { if (x != x) return -D_INF; return 1e300; } } DOUBLE_INTERVAL_INLINE double _di_above(double x) { double t; if (x >= -1e300) { t = x; if (t < 0.0) t = -t; t += 1e-300; return x + t * 4.440892098500626e-16; } else { if (x != x) return D_INF; return -1e300; } } DOUBLE_INTERVAL_INLINE di_t di_neg(di_t x) { di_t res; res.a = -x.b; res.b = -x.a; return res; } DOUBLE_INTERVAL_INLINE di_t di_fast_add(di_t x, di_t y) { di_t res; res.a = _di_below(x.a + y.a); res.b = _di_above(x.b + y.b); return res; } DOUBLE_INTERVAL_INLINE di_t di_fast_sub(di_t x, di_t y) { di_t res; res.a = _di_below(x.a - y.b); res.b = _di_above(x.b - y.a); return res; } di_t di_fast_mul(di_t x, di_t y); di_t di_fast_sqr(di_t x); di_t di_fast_div(di_t x, di_t y); DOUBLE_INTERVAL_INLINE di_t di_fast_add_d(di_t x, double y) { return di_fast_add(x, di_interval(y, y)); } DOUBLE_INTERVAL_INLINE di_t di_fast_sub_d(di_t x, double y) { return di_fast_sub(x, di_interval(y, y)); } DOUBLE_INTERVAL_INLINE di_t di_fast_mul_d(di_t x, double y) { return di_fast_mul(x, di_interval(y, y)); } DOUBLE_INTERVAL_INLINE di_t di_fast_div_d(di_t x, double y) { return di_fast_div(x, di_interval(y, y)); } di_t di_fast_log_nonnegative(di_t x); DOUBLE_INTERVAL_INLINE di_t di_fast_mid(di_t x) { di_t a, b; if (x.a == -D_INF || x.b == D_INF) return di_interval(-D_INF, D_INF); a = di_interval(x.a, x.a); b = di_interval(x.b, x.b); return di_fast_mul_d(di_fast_add(a, b), 0.5); } DOUBLE_INTERVAL_INLINE double di_fast_ubound_radius(di_t x) { return _di_above((x.b - x.a) * 0.5); } DOUBLE_INTERVAL_INLINE void di_print(di_t x) { flint_printf("[%.17g, %.17g]", x.a, x.b); } di_t arb_get_di(const arb_t x); void arb_set_di(arb_t res, di_t x, slong prec); DOUBLE_INTERVAL_INLINE double d_randtest2(flint_rand_t state) { double x; x = d_randtest(state); if (n_randint(state, 2)) x = -x; return ldexp(x, n_randint(state, 2400) - 1200); } DOUBLE_INTERVAL_INLINE di_t di_randtest(flint_rand_t state) { di_t res; res.a = d_randtest2(state); res.b = d_randtest2(state); if (res.a > res.b) { double t = res.a; res.a = res.b; res.b = t; } return res; } #ifdef __cplusplus } #endif #endif arb-2.22.1/double_interval/000077500000000000000000000000001417376376500155435ustar00rootroot00000000000000arb-2.22.1/double_interval/arb_get_di.c000066400000000000000000000014571417376376500177750ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" di_t arb_get_di(const arb_t x) { di_t res; if (arf_is_nan(arb_midref(x))) { res.a = -D_INF; res.b = D_INF; } else { arf_t t; arf_init(t); arb_get_lbound_arf(t, x, 53); res.a = arf_get_d(t, ARF_RND_FLOOR); arb_get_ubound_arf(t, x, 53); res.b = arf_get_d(t, ARF_RND_CEIL); arf_clear(t); } return res; } arb-2.22.1/double_interval/arb_set_di.c000066400000000000000000000011741417376376500200050ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" void arb_set_di(arb_t res, di_t x, slong prec) { arf_t t, u; arf_init(t); arf_init(u); arf_set_d(t, x.a); arf_set_d(u, x.b); arb_set_interval_arf(res, t, u, prec); arf_clear(t); arf_clear(u); } arb-2.22.1/double_interval/fast_div.c000066400000000000000000000024071417376376500175110ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" di_t di_fast_div(di_t x, di_t y) { di_t res; if (y.a > 0) { if (x.a >= 0) { res.a = x.a / y.b; res.b = x.b / y.a; } else if (x.b <= 0) { res.a = x.a / y.a; res.b = x.b / y.b; } else { res.a = x.a / y.a; res.b = x.b / y.a; } } else if (y.b < 0) { if (x.a >= 0) { res.a = x.b / y.b; res.b = x.a / y.a; } else if (x.b <= 0) { res.a = x.b / y.a; res.b = x.a / y.b; } else { res.a = x.b / y.b; res.b = x.a / y.b; } } else { res.a = -D_INF; res.b = D_INF; } res.a = _di_below(res.a); res.b = _di_above(res.b); return res; } arb-2.22.1/double_interval/fast_log_nonnegative.c000066400000000000000000000013171417376376500221040ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" #include "mag.h" double mag_d_log_lower_bound(double x); double mag_d_log_upper_bound(double x); di_t di_fast_log_nonnegative(di_t x) { di_t res; if (x.a <= 0.0) res.a = -D_INF; else res.a = mag_d_log_lower_bound(x.a); res.b = mag_d_log_upper_bound(x.b); return res; } arb-2.22.1/double_interval/fast_mul.c000066400000000000000000000025221417376376500175220ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" di_t di_fast_mul(di_t x, di_t y) { di_t res; if (x.a > 0 && y.a > 0) { res.a = x.a * y.a; res.b = x.b * y.b; } else if (x.a > 0 && y.b < 0) { res.a = x.b * y.a; res.b = x.a * y.b; } else if (x.b < 0 && y.a > 0) { res.a = x.a * y.b; res.b = x.b * y.a; } else if (x.b < 0 && y.b < 0) { res.a = x.b * y.b; res.b = x.a * y.a; } else { double a, b, c, d; a = x.a * y.a; b = x.a * y.b; c = x.b * y.a; d = x.b * y.b; if (a != a || b != b || c != c || d != d) { res.a = -D_INF; res.b = D_INF; } else { res.a = FLINT_MIN(FLINT_MIN(a, b), FLINT_MIN(c, d)); res.b = FLINT_MAX(FLINT_MAX(a, b), FLINT_MAX(c, d)); } } res.a = _di_below(res.a); res.b = _di_above(res.b); return res; } arb-2.22.1/double_interval/fast_sqr.c000066400000000000000000000014701417376376500175330ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" di_t di_fast_sqr(di_t x) { di_t res; if (x.a >= 0) { res.a = x.a * x.a; res.b = x.b * x.b; } else if (x.b <= 0) { res.a = x.b * x.b; res.b = x.a * x.a; } else { res.a = 0.0; res.b = FLINT_MAX(x.a * x.a, x.b * x.b); } if (res.a != 0.0) res.a = _di_below(res.a); res.b = _di_above(res.b); return res; } arb-2.22.1/double_interval/inlines.c000066400000000000000000000006741417376376500173570ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define DOUBLE_INTERVAL_INLINES_C #include "double_interval.h" arb-2.22.1/double_interval/test/000077500000000000000000000000001417376376500165225ustar00rootroot00000000000000arb-2.22.1/double_interval/test/t-fast_add.c000066400000000000000000000037131417376376500207000ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" int main() { slong iter; flint_rand_t state; flint_printf("fast_add...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { di_t x, y, z; arf_t a, b, t, za, zb; arf_init(a); arf_init(b); arf_init(t); arf_init(za); arf_init(zb); x = di_randtest(state); y = di_randtest(state); z = di_fast_add(x, y); DI_CHECK(z) arf_set_d(a, x.a); arf_set_d(t, y.a); arf_add(a, a, t, ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_d(b, x.b); arf_set_d(t, y.b); arf_add(b, b, t, ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_d(za, z.a); arf_set_d(zb, z.b); if (arf_cmp(a, za) < 0 || arf_cmp(b, zb) > 0) { flint_printf("FAIL\n"); flint_printf("x = "); di_print(x); printf("\n"); flint_printf("y = "); di_print(y); printf("\n"); flint_printf("z = "); di_print(z); printf("\n"); flint_printf("a = "); arf_printd(a, 20); printf("\n"); flint_printf("b = "); arf_printd(b, 20); printf("\n"); flint_printf("za = "); arf_printd(za, 20); printf("\n"); flint_printf("zb = "); arf_printd(zb, 20); printf("\n"); flint_abort(); } arf_clear(a); arf_clear(b); arf_clear(t); arf_clear(za); arf_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/double_interval/test/t-fast_div.c000066400000000000000000000065361417376376500207400ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" void arf_min2(arf_t res, const arf_t x, const arf_t y) { if (arf_is_nan(x)) arf_set(res, y); else if (arf_is_nan(y)) arf_set(res, x); else arf_min(res, x, y); } void arf_max2(arf_t res, const arf_t x, const arf_t y) { if (arf_is_nan(x)) arf_set(res, y); else if (arf_is_nan(y)) arf_set(res, x); else arf_max(res, x, y); } int main() { slong iter; flint_rand_t state; flint_printf("fast_div...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { di_t x, y, z; arf_t a, b, c, d, ra, rb, rc, rd, va, vb, za, zb; arf_init(a); arf_init(b); arf_init(c); arf_init(d); arf_init(ra); arf_init(rb); arf_init(rc); arf_init(rd); arf_init(va); arf_init(vb); arf_init(za); arf_init(zb); x = di_randtest(state); y = di_randtest(state); z = di_fast_div(x, y); DI_CHECK(z) arf_set_d(a, x.a); arf_set_d(b, x.b); arf_set_d(c, y.a); arf_set_d(d, y.b); arf_div(ra, a, c, 106, ARF_RND_DOWN); arf_div(rb, a, d, 106, ARF_RND_DOWN); arf_div(rc, b, c, 106, ARF_RND_DOWN); arf_div(rd, b, d, 106, ARF_RND_DOWN); arf_min2(va, ra, rb); arf_min2(va, va, rc); arf_min2(va, va, rd); arf_max2(vb, ra, rb); arf_max2(vb, vb, rc); arf_max2(vb, vb, rd); arf_set_d(za, z.a); arf_set_d(zb, z.b); if (arf_cmp(va, za) < 0 || arf_cmp(vb, zb) > 0) { flint_printf("FAIL\n"); flint_printf("x = "); di_print(x); printf("\n"); flint_printf("y = "); di_print(y); printf("\n"); flint_printf("z = "); di_print(z); printf("\n"); flint_printf("a = "); arf_printd(a, 20); printf("\n"); flint_printf("b = "); arf_printd(b, 20); printf("\n"); flint_printf("c = "); arf_printd(c, 20); printf("\n"); flint_printf("d = "); arf_printd(d, 20); printf("\n"); flint_printf("ra = "); arf_printd(ra, 20); printf("\n"); flint_printf("rb = "); arf_printd(rb, 20); printf("\n"); flint_printf("rc = "); arf_printd(rc, 20); printf("\n"); flint_printf("rd = "); arf_printd(rd, 20); printf("\n"); flint_printf("va = "); arf_printd(va, 20); printf("\n"); flint_printf("vb = "); arf_printd(vb, 20); printf("\n"); flint_printf("za = "); arf_printd(za, 20); printf("\n"); flint_printf("zb = "); arf_printd(zb, 20); printf("\n"); flint_abort(); } arf_clear(a); arf_clear(b); arf_clear(c); arf_clear(d); arf_clear(ra); arf_clear(rb); arf_clear(rc); arf_clear(rd); arf_clear(va); arf_clear(vb); arf_clear(za); arf_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/double_interval/test/t-fast_mul.c000066400000000000000000000072141417376376500207450ustar00rootroot00000000000000/* Copyright (C) 2021 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "double_interval.h" void arf_min2(arf_t res, const arf_t x, const arf_t y) { if (arf_is_nan(x)) arf_set(res, y); else if (arf_is_nan(y)) arf_set(res, x); else arf_min(res, x, y); } void arf_max2(arf_t res, const arf_t x, const arf_t y) { if (arf_is_nan(x)) arf_set(res, y); else if (arf_is_nan(y)) arf_set(res, x); else arf_max(res, x, y); } int main() { slong iter; flint_rand_t state; flint_printf("fast_mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { di_t x, y, z; arf_t a, b, c, d, ra, rb, rc, rd, va, vb, za, zb; arf_init(a); arf_init(b); arf_init(c); arf_init(d); arf_init(ra); arf_init(rb); arf_init(rc); arf_init(rd); arf_init(va); arf_init(vb); arf_init(za); arf_init(zb); if (iter == 0) { x.a = 3.5835915908219665e+103; x.b = 4.0874812242073031e+295; y.a = -8.3711609938763647e+298; y.b = -3.414037107833399e+243; } else { x = di_randtest(state); y = di_randtest(state); } z = di_fast_mul(x, y); DI_CHECK(z) arf_set_d(a, x.a); arf_set_d(b, x.b); arf_set_d(c, y.a); arf_set_d(d, y.b); arf_mul(ra, a, c, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(rb, a, d, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(rc, b, c, ARF_PREC_EXACT, ARF_RND_DOWN); arf_mul(rd, b, d, ARF_PREC_EXACT, ARF_RND_DOWN); arf_min2(va, ra, rb); arf_min2(va, va, rc); arf_min2(va, va, rd); arf_max2(vb, ra, rb); arf_max2(vb, vb, rc); arf_max2(vb, vb, rd); arf_set_d(za, z.a); arf_set_d(zb, z.b); if (arf_cmp(va, za) < 0 || arf_cmp(vb, zb) > 0) { flint_printf("FAIL\n"); flint_printf("x = "); di_print(x); printf("\n"); flint_printf("y = "); di_print(y); printf("\n"); flint_printf("z = "); di_print(z); printf("\n"); flint_printf("a = "); arf_printd(a, 20); printf("\n"); flint_printf("b = "); arf_printd(b, 20); printf("\n"); flint_printf("c = "); arf_printd(c, 20); printf("\n"); flint_printf("d = "); arf_printd(d, 20); printf("\n"); flint_printf("ra = "); arf_printd(ra, 20); printf("\n"); flint_printf("rb = "); arf_printd(rb, 20); printf("\n"); flint_printf("rc = "); arf_printd(rc, 20); printf("\n"); flint_printf("rd = "); arf_printd(rd, 20); printf("\n"); flint_printf("va = "); arf_printd(va, 20); printf("\n"); flint_printf("vb = "); arf_printd(vb, 20); printf("\n"); flint_printf("za = "); arf_printd(za, 20); printf("\n"); flint_printf("zb = "); arf_printd(zb, 20); printf("\n"); flint_abort(); } arf_clear(a); arf_clear(b); arf_clear(c); arf_clear(d); arf_clear(ra); arf_clear(rb); arf_clear(rc); arf_clear(rd); arf_clear(va); arf_clear(vb); arf_clear(za); arf_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/examples/000077500000000000000000000000001417376376500142035ustar00rootroot00000000000000arb-2.22.1/examples/complex_plot.c000066400000000000000000000371271417376376500170660ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include #include "acb.h" #include "acb_hypgeom.h" #include "acb_modular.h" #include "acb_elliptic.h" #include "flint/profiler.h" /* some useful color operations */ #define CLAMP(y) FLINT_MAX(0.0, FLINT_MIN((y), 1.0)) #define BLEND(x,y) (0.5*(x) + 0.5*(y)) #define DODGE(a,b) ((a) / ((1.0 - (b)) + 1/256.0)) /* HLS algorithm from python's colorsys module */ static double vv(double m1, double m2, double hue) { hue = hue - floor(hue); if (hue < 1/6.) return m1 + (m2-m1)*hue*6.0; if (hue < 0.5) return m2; if (hue < 2/3.) return m1 + (m2-m1)*(2/3.-hue)*6.0; return m1; } static void hls_to_rgb(double *R, double *G, double *B, double h, double l, double s) { double m1, m2; if (s == 0.0) { *R = *G = *B = l; return; } if (l <= 0.5) m2 = l * (1.0+s); else m2 = l+s-(l*s); m1 = 2.0*l - m2; *R = vv(m1, m2, h + 1/3.); *G = vv(m1, m2, h); *B = vv(m1, m2, h - 1/3.); } static void rgb_to_hls(double *H, double *L, double *S, double R, double G, double B) { double h, l, s, hi, lo, d; hi = FLINT_MAX(FLINT_MAX(R, G), B); lo = FLINT_MIN(FLINT_MIN(R, G), B); l = 0.5 * (lo + hi); d = hi - lo; if (hi == lo) { s = 0.0; h = 0.0; } else { if (l <= 0.5) s = d / (hi + lo); else s = d / (2.0 - hi - lo); if (d == 0.0) d = 1.0; if (R == hi) h = (G - B) / d; else if (G == hi) h = (B - R) / d + 2.0; else h = (R - G) / d + 4.0; h = h / 6.0; if (h < 0.0) h += 1.0; } *H = h; *L = l; *S = s; } /* color balance algorithm from gimp */ static double balance_channel(double value, double l, double shadows, double midtones, double highlights) { double a = 0.25, b = 0.333, scale = 0.7; shadows *= CLAMP((l - b) / (-a) + 0.5) * scale; midtones *= CLAMP((l - b) / ( a) + 0.5) * CLAMP((l + b - 1.0) / (-a) + 0.5) * scale; highlights *= CLAMP((l + b - 1.0) / ( a) + 0.5) * scale; value += shadows; value += midtones; value += highlights; return CLAMP(value); } static void balance(double * R, double * G, double * B, double ra, double rb, double rc, /* red shadows, midtones, highlights */ double ga, double gb, double gc, /* green */ double ba, double bb, double bc) /* blue */ { double h, l, s; double h2, l2, s2; rgb_to_hls(&h, &l, &s, *R, *G, *B); *R = balance_channel(*R, *R, ra, rb, rc); *G = balance_channel(*G, *G, ga, gb, gc); *B = balance_channel(*B, *B, ba, bb, bc); /* preserve lightness */ rgb_to_hls(&h2, &l2, &s2, *R, *G, *B); hls_to_rgb(R, G, B, h2, l, s2); } #define PI 3.1415926535898 const double blue_orange_colors[][4] = { {-1.0, 0.0, 0.0, 0.0}, {-0.95, 0.1, 0.2, 0.5}, {-0.5, 0.0, 0.5, 1.0}, {-0.05, 0.4, 0.8, 0.8}, { 0.0, 1.0, 1.0, 1.0}, { 0.05, 1.0, 0.9, 0.3}, { 0.5, 0.9, 0.5, 0.0}, { 0.95, 0.7, 0.1, 0.0}, { 1.0, 0.0, 0.0, 0.0}, { 2.0, 0.0, 0.0, 0.0}, }; void color_function(double * R, double * G, double * B, const acb_t z, int mode) { double H, L, S; slong prec, i; arb_t t, u; if (!acb_is_finite(z) || acb_rel_accuracy_bits(z) < 4) { *R = *G = *B = 0.5; return; } if (mode >= 2) { double R1, G1, B1; double R2, G2, B2; /* combine both color functions */ color_function(&R1, &G1, &B1, z, 0); color_function(&R2, &G2, &B2, z, 1); *R = BLEND(R1, CLAMP(DODGE(R1, R2))); *G = BLEND(G1, CLAMP(DODGE(G1, G2))); *B = BLEND(B1, CLAMP(DODGE(B1, B2))); /* then play with the levels */ if (mode == 3) balance(R, G, B, 0.0, -0.5, 0.2, 0.0, 0.0, -0.1, 0.0, -1.0, -0.2); else if (mode == 4) balance(R, G, B, 0.0, -0.5, 0.2, 0.0, 0.5, -0.1, 0.0, -0.3, -1.0); else if (mode == 5) balance(R, G, B, 0.0, -0.5, -1.0, 0.0, -0.1, -0.67, 0.0, -0.55, -0.12); else if (mode == 6) balance(R, G, B, 0.86, 0.0, 0.13, 0.57, 0.19, -0.52, 0.31, -0.30, -0.94); return; } arb_init(t); arb_init(u); prec = 32; arf_set_round(arb_midref(t), arb_midref(acb_realref(z)), prec, ARF_RND_DOWN); arf_set_round(arb_midref(u), arb_midref(acb_imagref(z)), prec, ARF_RND_DOWN); arb_atan2(t, u, t, prec); H = arf_get_d(arb_midref(t), ARF_RND_DOWN); if (mode == 0) { H = (H + PI) / (2 * PI) + 0.5; H = H - floor(H); acb_abs(t, z, prec); if (arf_cmpabs_2exp_si(arb_midref(t), 200) > 0) { L = 1.0; } else if (arf_cmpabs_2exp_si(arb_midref(t), -200) < 0) { L = 0.0; } else { L = arf_get_d(arb_midref(t), ARF_RND_DOWN); L = 1.0 - 1.0/(1.0 + pow(L, 0.2)); } S = 0.8; hls_to_rgb(R, G, B, H, L, S); } else { H = H / PI; H = FLINT_MAX(FLINT_MIN(H, 1.0), -1.0); for (i = 1; ; i++) { if (blue_orange_colors[i][0] > H) { double a, ra, ga, ba, b, rb, gb, bb, s; a = blue_orange_colors[i-1][0]; ra = blue_orange_colors[i-1][1]; ga = blue_orange_colors[i-1][2]; ba = blue_orange_colors[i-1][3]; b = blue_orange_colors[i][0]; rb = blue_orange_colors[i][1]; gb = blue_orange_colors[i][2]; bb = blue_orange_colors[i][3]; s = (H - a) / (b - a); *R = ra + (rb - ra) * s; *G = ga + (gb - ga) * s; *B = ba + (bb - ba) * s; break; } } } arb_clear(t); arb_clear(u); } typedef void (*func_ptr)(acb_t, const acb_t, slong); void ai(acb_t res, const acb_t z, slong prec) { acb_hypgeom_airy(res, NULL, NULL, NULL, z, prec); } void bi(acb_t res, const acb_t z, slong prec) { acb_hypgeom_airy(NULL, NULL, res, NULL, z, prec); } void besselj(acb_t res, const acb_t z, slong prec) { acb_t nu; acb_init(nu); acb_hypgeom_bessel_j(res, nu, z, prec); acb_clear(nu); } void bessely(acb_t res, const acb_t z, slong prec) { acb_t nu; acb_init(nu); acb_hypgeom_bessel_y(res, nu, z, prec); acb_clear(nu); } void besseli(acb_t res, const acb_t z, slong prec) { acb_t nu; acb_init(nu); acb_hypgeom_bessel_i(res, nu, z, prec); acb_clear(nu); } void besselk(acb_t res, const acb_t z, slong prec) { acb_t nu; acb_init(nu); acb_hypgeom_bessel_k(res, nu, z, prec); acb_clear(nu); } /* this function looks better when scaled */ void modj(acb_t res, const acb_t z, slong prec) { acb_modular_j(res, z, prec); acb_div_ui(res, res, 1728, prec); } void modjq(acb_t res, const acb_t z, slong prec) { acb_t t; acb_init(t); acb_log(res, z, prec); acb_const_pi(t, prec); acb_div(res, res, t, prec); acb_mul_2exp_si(res, res, -1); acb_div_onei(res, res); acb_modular_j(res, res, prec); acb_div_ui(res, res, 1728, prec); acb_clear(t); } void modetaq(acb_t res, const acb_t z, slong prec) { acb_t t; acb_init(t); acb_log(res, z, prec); acb_const_pi(t, prec); acb_div(res, res, t, prec); acb_mul_2exp_si(res, res, -1); acb_div_onei(res, res); acb_modular_eta(res, res, prec); acb_clear(t); } void modlambdaq(acb_t res, const acb_t z, slong prec) { acb_t t; acb_init(t); acb_log(res, z, prec); acb_const_pi(t, prec); acb_div(res, res, t, prec); acb_mul_2exp_si(res, res, -1); acb_div_onei(res, res); acb_modular_lambda(res, res, prec); acb_clear(t); } void ellipp(acb_t res, const acb_t z, slong prec) { acb_onei(res); acb_elliptic_p(res, z, res, prec); } void ellipzeta(acb_t res, const acb_t z, slong prec) { acb_onei(res); acb_elliptic_zeta(res, z, res, prec); } void ellipsigma(acb_t res, const acb_t z, slong prec) { acb_onei(res); acb_elliptic_sigma(res, z, res, prec); } void fresnels(acb_t res, const acb_t z, slong prec) { acb_hypgeom_fresnel(res, NULL, z, 0, prec); } void fresnelc(acb_t res, const acb_t z, slong prec) { acb_hypgeom_fresnel(NULL, res, z, 0, prec); } int main(int argc, char *argv[]) { slong x, y, xnum, ynum, prec, i; double R, G, B, dxa, dxb, dya, dyb; FILE * fp; arf_t xa, xb, ya, yb; acb_t z, w; func_ptr func; int color_mode; if (argc < 2) { printf("complex_plot [-range xa xb ya yb] [-size xn yn] [-color n] \n\n"); printf("Plots one of the predefined functions on [xa,xb] + [ya,yb]i\n"); printf("using domain coloring, at a resolution of xn by yn pixels.\n\n"); printf("Defaults parameters are [-10,10] + [-10,10]i and xn = yn = 512.\n\n"); printf("A color function can be selected with -color. The choices are:\n"); printf("0 phase=hue, magnitude=brightness\n"); printf("1 phase only, white-gold-black-blue-white counterclockwise\n"); printf("2 0+1 (dodge filter)\n"); printf("3 0+1, shiny\n"); printf("4 0+1, warm\n"); printf("5 0+1, cold\n"); printf("6 0+1, tomato\n\n"); printf("The output is written to arbplot.ppm. If you have ImageMagick,\n"); printf("run [convert arbplot.ppm arbplot.png] to get a PNG.\n\n"); printf("Function codes are:\n"); printf(" sin - Sine\n"); printf(" gamma - Gamma function\n"); printf(" digamma - Digamma function\n"); printf(" lgamma - Logarithmic gamma function\n"); printf(" zeta - Riemann zeta function\n"); printf(" erf - Error function\n"); printf(" ai - Airy function Ai\n"); printf(" bi - Airy function Bi\n"); printf(" besselj - Bessel function J_0\n"); printf(" bessely - Bessel function Y_0\n"); printf(" besseli - Bessel function I_0\n"); printf(" besselk - Bessel function K_0\n"); printf(" modj - Modular j-function\n"); printf(" modjq - Modular j-function (as function of q)\n"); printf(" modeta - Dedekind eta function\n"); printf(" modetaq - Dedekind eta function (as function of q)\n"); printf(" modlambda - Modular lambda function\n"); printf(" modlambdaq - Modular lambda function (as function of q)\n"); printf(" ellipp - Weierstrass elliptic function (on square lattice)\n"); printf(" ellipzeta - Weierstrass elliptic function (on square lattice)\n"); printf(" ellipsigma - Weierstrass elliptic function (on square lattice)\n"); printf(" barnesg - Barnes G-function\n"); printf(" agm - Arithmetic geometric mean\n"); printf(" fresnels - Fresnel integral S\n"); printf(" fresnelc - Fresnel integral C\n\n"); return 1; } xnum = 512; ynum = 512; dxa = dya = -10; dxb = dyb = 10; func = acb_gamma; color_mode = 0; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-size")) { xnum = atol(argv[i+1]); ynum = atol(argv[i+2]); i += 2; } else if (!strcmp(argv[i], "-range")) { dxa = atof(argv[i+1]); dxb = atof(argv[i+2]); dya = atof(argv[i+3]); dyb = atof(argv[i+4]); i += 4; } else if (!strcmp(argv[i], "-color")) { color_mode = atoi(argv[i+1]); i++; } else if (!strcmp(argv[i], "sin")) func = acb_sin; else if (!strcmp(argv[i], "gamma")) func = acb_gamma; else if (!strcmp(argv[i], "digamma")) func = acb_digamma; else if (!strcmp(argv[i], "lgamma")) func = acb_lgamma; else if (!strcmp(argv[i], "zeta")) func = acb_zeta; else if (!strcmp(argv[i], "erf")) func = acb_hypgeom_erf; else if (!strcmp(argv[i], "ai")) func = ai; else if (!strcmp(argv[i], "bi")) func = bi; else if (!strcmp(argv[i], "besselj")) func = besselj; else if (!strcmp(argv[i], "bessely")) func = bessely; else if (!strcmp(argv[i], "besseli")) func = besseli; else if (!strcmp(argv[i], "besselk")) func = besselk; else if (!strcmp(argv[i], "modj")) func = modj; else if (!strcmp(argv[i], "modjq")) func = modjq; else if (!strcmp(argv[i], "modeta")) func = acb_modular_eta; else if (!strcmp(argv[i], "modetaq")) func = modetaq; else if (!strcmp(argv[i], "modlambda")) func = acb_modular_lambda; else if (!strcmp(argv[i], "modlambdaq")) func = modlambdaq; else if (!strcmp(argv[i], "ellipp")) func = ellipp; else if (!strcmp(argv[i], "ellipzeta")) func = ellipzeta; else if (!strcmp(argv[i], "ellipsigma")) func = ellipsigma; else if (!strcmp(argv[i], "barnesg")) func = acb_barnes_g; else if (!strcmp(argv[i], "agm")) func = acb_agm1; else if (!strcmp(argv[i], "fresnels")) func = fresnels; else if (!strcmp(argv[i], "fresnelc")) func = fresnelc; else { printf("unknown option: %s\n", argv[i]); return 1; } } acb_init(z); acb_init(w); arf_init(xa); arf_init(xb); arf_init(ya); arf_init(yb); arf_set_d(xa, dxa); arf_set_d(xb, dxb); arf_set_d(ya, dya); arf_set_d(yb, dyb); fp = fopen("arbplot.ppm", "w"); fprintf(fp, "P6\n%ld %ld 255\n", xnum, ynum); TIMEIT_ONCE_START for (y = ynum - 1; y >= 0; y--) { if (y % (ynum / 16) == 0) printf("row %ld\n", y); for (x = 0; x < xnum; x++) { for (prec = 30; prec < 500; prec *= 2) { arf_sub(arb_midref(acb_imagref(z)), yb, ya, prec, ARF_RND_DOWN); arf_mul_ui(arb_midref(acb_imagref(z)), arb_midref(acb_imagref(z)), y, prec, ARF_RND_DOWN); arf_div_ui(arb_midref(acb_imagref(z)), arb_midref(acb_imagref(z)), ynum - 1, prec, ARF_RND_DOWN); arf_add(arb_midref(acb_imagref(z)), arb_midref(acb_imagref(z)), ya, prec, ARF_RND_DOWN); arf_sub(arb_midref(acb_realref(z)), xb, xa, prec, ARF_RND_DOWN); arf_mul_ui(arb_midref(acb_realref(z)), arb_midref(acb_realref(z)), x, prec, ARF_RND_DOWN); arf_div_ui(arb_midref(acb_realref(z)), arb_midref(acb_realref(z)), xnum - 1, prec, ARF_RND_DOWN); arf_add(arb_midref(acb_realref(z)), arb_midref(acb_realref(z)), xa, prec, ARF_RND_DOWN); func(w, z, prec); if (acb_rel_accuracy_bits(w) > 4) break; } color_function(&R, &G, &B, w, color_mode); fputc(FLINT_MIN(255, floor(R * 255)), fp); fputc(FLINT_MIN(255, floor(G * 255)), fp); fputc(FLINT_MIN(255, floor(B * 255)), fp); } } TIMEIT_ONCE_STOP fclose(fp); arf_clear(xa); arf_clear(xb); arf_clear(ya); arf_clear(yb); acb_clear(z); acb_clear(w); flint_cleanup(); return 0; } arb-2.22.1/examples/fpwrap.c000066400000000000000000000007571417376376500156570ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include "arb_fpwrap.h" int main() { double x, y; complex_double cx, cy; int flags = 0; /* default options */ x = 2.0; cx.real = 0.5; cx.imag = 123.0; arb_fpwrap_double_zeta(&y, x, flags); arb_fpwrap_cdouble_zeta(&cy, cx, flags); printf("zeta(%g) = %.16g\n", x, y); printf("zeta(%g + %gi) = %.16g + %.16gi\n", cx.real, cx.imag, cy.real, cy.imag); flint_cleanup(); return 0; } arb-2.22.1/examples/hilbert_matrix.c000066400000000000000000000041241417376376500173650ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include #include "arb_mat.h" #include "acb_mat.h" #include "flint/profiler.h" int main(int argc, char *argv[]) { arb_mat_t A; arb_t det; slong i, prec, n; int eig; if (argc < 2 || (argc == 3 && strcmp(argv[1], "-eig"))) { flint_printf("usage: build/examples/hilbert_matrix [-eig] n\n"); return 1; } if (argc == 2) eig = 0; else eig = 1; n = atol(argv[argc-1]); if (eig && (n == 0)) { flint_printf("smallest eigenvalue: undefined for n == 0\n"); return 1; } arb_mat_init(A, n, n); arb_init(det); TIMEIT_ONCE_START for (prec = 20; ; prec *= 2) { arb_mat_hilbert(A, prec); flint_printf("prec=%wd: ", prec); if (eig == 0) { arb_mat_det(det, A, prec); } else { acb_mat_t C, R; acb_ptr E; acb_mat_init(R, n, n); acb_mat_init(C, n, n); E = _acb_vec_init(n); acb_mat_set_arb_mat(C, A); acb_mat_approx_eig_qr(E, NULL, R, C, NULL, 0, prec); if (acb_mat_eig_simple(E, NULL, NULL, C, E, R, prec)) { /* A is symmetric so the eigenvalues are real */ for (i = 0; i < n; i++) arb_zero(acb_imagref(E + i)); /* With isolated eigenvalues, sorting midpoints gives the right result. */ _acb_vec_sort_pretty(E, n); acb_get_real(det, E + 0); } else { arb_indeterminate(det); } acb_mat_clear(R); acb_mat_clear(C); _acb_vec_clear(E, n); } arb_printn(det, 10, 0); flint_printf("\n"); if (!arb_contains_zero(det)) { flint_printf("success!\n"); break; } } TIMEIT_ONCE_STOP SHOW_MEMORY_USAGE arb_mat_clear(A); arb_clear(det); flint_cleanup(); return 0; } arb-2.22.1/examples/integrals.c000066400000000000000000001036761417376376500163540ustar00rootroot00000000000000/* Rigorous numerical integration (with fast convergence for piecewise holomorphic functions) using Gauss-Legendre quadrature and adaptive subdivision. Author: Fredrik Johansson. This file is in the public domain. */ #include #include "flint/profiler.h" #include "arb_hypgeom.h" #include "acb_hypgeom.h" #include "acb_dirichlet.h" #include "acb_modular.h" #include "acb_calc.h" /* ------------------------------------------------------------------------- */ /* Example integrands */ /* ------------------------------------------------------------------------- */ /* f(z) = sin(z) */ int f_sin(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_sin(res, z, prec); return 0; } /* f(z) = floor(z) */ int f_floor(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_real_floor(res, z, order != 0, prec); return 0; } /* f(z) = sqrt(1-z^2) */ int f_circle(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_one(res); acb_submul(res, z, z, prec); acb_real_sqrtpos(res, res, order != 0, prec); return 0; } /* f(z) = 1/(1+z^2) */ int f_atanderiv(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_mul(res, z, z, prec); acb_add_ui(res, res, 1, prec); acb_inv(res, res, prec); return 0; } /* f(z) = sin(z + exp(z)) -- Rump's oscillatory example */ int f_rump(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_exp(res, z, prec); acb_add(res, res, z, prec); acb_sin(res, res, prec); return 0; } /* f(z) = |z^4 + 10z^3 + 19z^2 - 6z - 6| exp(z) (for real z) -- Helfgott's integral on MathOverflow */ int f_helfgott(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_add_si(res, z, 10, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, 19, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, -6, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, -6, prec); acb_real_abs(res, res, order != 0, prec); if (acb_is_finite(res)) { acb_t t; acb_init(t); acb_exp(t, z, prec); acb_mul(res, res, t, prec); acb_clear(t); } return 0; } /* f(z) = zeta(z) */ int f_zeta(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_zeta(res, z, prec); return 0; } /* f(z) = z sin(1/z), assume on real interval */ int f_essing2(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ if ((order == 0) && acb_is_real(z) && arb_contains_zero(acb_realref(z))) { /* todo: arb_zero_pm_one, arb_unit_interval? */ acb_zero(res); mag_one(arb_radref(acb_realref(res))); } else { acb_inv(res, z, prec); acb_sin(res, res, prec); } acb_mul(res, res, z, prec); return 0; } /* f(z) = sin(1/z), assume on real interval */ int f_essing(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ if ((order == 0) && acb_is_real(z) && arb_contains_zero(acb_realref(z))) { /* todo: arb_zero_pm_one, arb_unit_interval? */ acb_zero(res); mag_one(arb_radref(acb_realref(res))); } else { acb_inv(res, z, prec); acb_sin(res, res, prec); } return 0; } /* f(z) = exp(-z) z^1000 */ int f_factorial1000(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_pow_ui(t, z, 1000, prec); acb_neg(res, z); acb_exp(res, res, prec); acb_mul(res, res, t, prec); acb_clear(t); return 0; } /* f(z) = gamma(z) */ int f_gamma(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_gamma(res, z, prec); return 0; } /* f(z) = sin(z) + exp(-200-z^2) */ int f_sin_plus_small(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_mul(t, z, z, prec); acb_add_ui(t, t, 200, prec); acb_neg(t, t); acb_exp(t, t, prec); acb_sin(res, z, prec); acb_add(res, res, t, prec); acb_clear(t); return 0; } /* f(z) = exp(z) */ int f_exp(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_exp(res, z, prec); return 0; } /* f(z) = exp(-z^2) */ int f_gaussian(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_mul(res, z, z, prec); acb_neg(res, res); acb_exp(res, res, prec); return 0; } int f_monster(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_exp(t, z, prec); acb_real_floor(res, t, order != 0, prec); if (acb_is_finite(res)) { acb_sub(res, t, res, prec); acb_add(t, t, z, prec); acb_sin(t, t, prec); acb_mul(res, res, t, prec); } acb_clear(t); return 0; } /* f(z) = sech(10(x-0.2))^2 + sech(100(x-0.4))^4 + sech(1000(x-0.6))^6 */ int f_spike(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t a, b, c; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(a); acb_init(b); acb_init(c); acb_mul_ui(a, z, 10, prec); acb_sub_ui(a, a, 2, prec); acb_sech(a, a, prec); acb_pow_ui(a, a, 2, prec); acb_mul_ui(b, z, 100, prec); acb_sub_ui(b, b, 40, prec); acb_sech(b, b, prec); acb_pow_ui(b, b, 4, prec); acb_mul_ui(c, z, 1000, prec); acb_sub_ui(c, c, 600, prec); acb_sech(c, c, prec); acb_pow_ui(c, c, 6, prec); acb_add(res, a, b, prec); acb_add(res, res, c, prec); acb_clear(a); acb_clear(b); acb_clear(c); return 0; } /* f(z) = sech(z) */ int f_sech(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_sech(res, z, prec); return 0; } /* f(z) = sech^3(z) */ int f_sech3(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_sech(res, z, prec); acb_cube(res, res, prec); return 0; } /* f(z) = -log(z) / (1 + z) */ int f_log_div1p(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_add_ui(t, z, 1, prec); acb_log(res, z, prec); acb_div(res, res, t, prec); acb_neg(res, res); acb_clear(t); return 0; } /* f(z) = z exp(-z) / (1 + exp(-z)) */ int f_log_div1p_transformed(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_neg(t, z); acb_exp(t, t, prec); acb_add_ui(res, t, 1, prec); acb_div(res, t, res, prec); acb_mul(res, res, z, prec); acb_clear(t); return 0; } int f_elliptic_p_laurent_n(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { slong n; acb_t tau; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ n = ((slong *)(param))[0]; acb_init(tau); acb_onei(tau); acb_modular_elliptic_p(res, z, tau, prec); acb_pow_si(tau, z, -n - 1, prec); acb_mul(res, res, tau, prec); acb_clear(tau); return 0; } /* f(z) = zeta'(z) / zeta(z) */ int f_zeta_frac(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_struct t[2]; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_init(t + 1); acb_dirichlet_zeta_jet(t, z, 0, 2, prec); acb_div(res, t + 1, t, prec); acb_clear(t); acb_clear(t + 1); return 0; } int f_lambertw(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); prec = FLINT_MIN(prec, acb_rel_accuracy_bits(z) + 10); if (order != 0) { /* check for branch cut */ arb_const_e(acb_realref(t), prec); acb_inv(t, t, prec); acb_add(t, t, z, prec); if (arb_contains_zero(acb_imagref(t)) && arb_contains_nonpositive(acb_realref(t))) { acb_indeterminate(t); } } if (acb_is_finite(t)) { fmpz_t k; fmpz_init(k); acb_lambertw(res, z, k, 0, prec); fmpz_clear(k); } else { acb_indeterminate(res); } acb_clear(t); return 0; } /* f(z) = max(sin(z), cos(z)) */ int f_max_sin_cos(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, c; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(s); acb_init(c); acb_sin_cos(s, c, z, prec); acb_real_max(res, s, c, order != 0, prec); acb_clear(s); acb_clear(c); return 0; } /* f(z) = erf(z/sqrt(0.0002)*0.5 +1.5)*exp(-z), example provided by Silviu-Ioan Filip */ int f_erf_bent(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_set_ui(t, 1250); acb_sqrt(t, t, prec); acb_mul(t, t, z, prec); acb_set_d(res, 1.5); acb_add(res, res, t, prec); acb_hypgeom_erf(res, res, prec); acb_neg(t, z); acb_exp(t, t, prec); acb_mul(res, res, t, prec); acb_clear(t); return 0; } /* f(z) = Ai(z) */ int f_airy_ai(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_hypgeom_airy(res, NULL, NULL, NULL, z, prec); return 0; } int f_horror(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(s); acb_init(t); acb_real_floor(res, z, order != 0, prec); if (acb_is_finite(res)) { acb_sub(res, z, res, prec); acb_set_d(t, 0.5); acb_sub(res, res, t, prec); acb_sin_cos(s, t, z, prec); acb_real_max(s, s, t, order != 0, prec); acb_mul(res, res, s, prec); } acb_clear(s); acb_clear(t); return 0; } /* f(z) = sqrt(z) */ int f_sqrt(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_sqrt_analytic(res, z, order != 0, prec); return 0; } /* f(z) = 1/sqrt(z) */ int f_rsqrt(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_rsqrt_analytic(res, z, order != 0, prec); return 0; } /* f(z) = rgamma(z) */ int f_rgamma(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_rgamma(res, z, prec); return 0; } /* f(z) = exp(-z^2+iz) */ int f_gaussian_twist(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_mul_onei(res, z); acb_submul(res, z, z, prec); acb_exp(res, res, prec); return 0; } /* f(z) = exp(-z) Ai(-z) */ int f_exp_airy(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_neg(t, z); acb_hypgeom_airy(res, NULL, NULL, NULL, t, prec); acb_exp(t, t, prec); acb_mul(res, res, t, prec); acb_clear(t); return 0; } /* f(z) = z sin(z) / (1 + cos(z)^2) */ int f_sin_cos_frac(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t s, c; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(s); acb_init(c); acb_sin_cos(s, c, z, prec); acb_mul(c, c, c, prec); acb_add_ui(c, c, 1, prec); acb_mul(s, s, z, prec); acb_div(res, s, c, prec); acb_clear(s); acb_clear(c); return 0; } /* f(z) = sin((1/1000 + (1-z)^2)^(-3/2)), example from Mioara Joldes' thesis (suggested by Nicolas Brisebarre) */ int f_sin_near_essing(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t, u; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_init(u); acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_mul(t, t, t, prec); acb_one(u); acb_div_ui(u, u, 1000, prec); acb_add(t, t, u, prec); acb_set_d(u, -1.5); acb_pow_analytic(t, t, u, order != 0, prec); acb_sin(res, t, prec); acb_clear(t); acb_clear(u); return 0; } /* f(z) = exp(-z) (I_0(z/k))^k, from Bruno Salvy */ int f_scaled_bessel(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t nu; ulong k = ((ulong *) param)[0]; acb_init(nu); acb_div_ui(res, z, k, prec); acb_hypgeom_bessel_i_scaled(res, nu, res, prec); acb_pow_ui(res, res, k, prec); acb_clear(nu); return 0; } /* Bound for scaled Bessel function: 2/(2 pi x)^(1/2) Bound for tail of integral: 2 N (k / (pi N))^(k / 2) / (k - 2). */ void scaled_bessel_tail_bound(arb_t b, ulong k, const arb_t N, slong prec) { arb_const_pi(b, prec); arb_mul(b, b, N, prec); arb_ui_div(b, k, b, prec); arb_sqrt(b, b, prec); arb_pow_ui(b, b, k, prec); arb_mul(b, b, N, prec); arb_mul_ui(b, b, 2, prec); arb_div_ui(b, b, k - 2, prec); } void scaled_bessel_select_N(arb_t N, ulong k, slong prec) { slong e; double f = log(k/3.14159265358979)/log(2); e = 1; while ((k / 2.0) * (e - f) - e < prec + 5) e++; arb_one(N); arb_mul_2exp_si(N, N, e); } /* ------------------------------------------------------------------------- */ /* Main test program */ /* ------------------------------------------------------------------------- */ #define NUM_INTEGRALS 37 const char * descr[NUM_INTEGRALS] = { "int_0^100 sin(x) dx", "4 int_0^1 1/(1+x^2) dx", "2 int_0^{inf} 1/(1+x^2) dx (using domain truncation)", "4 int_0^1 sqrt(1-x^2) dx", "int_0^8 sin(x+exp(x)) dx", "int_1^101 floor(x) dx", "int_0^1 |x^4+10x^3+19x^2-6x-6| exp(x) dx", "1/(2 pi i) int zeta(s) ds (closed path around s = 1)", "int_0^1 sin(1/x) dx (slow convergence, use -heap and/or -tol)", "int_0^1 x sin(1/x) dx (slow convergence, use -heap and/or -tol)", "int_0^10000 x^1000 exp(-x) dx", "int_1^{1+1000i} gamma(x) dx", "int_{-10}^{10} sin(x) + exp(-200-x^2) dx", "int_{-1020}^{-1010} exp(x) dx (use -tol 0 for relative error)", "int_0^{inf} exp(-x^2) dx (using domain truncation)", "int_0^1 sech(10(x-0.2))^2 + sech(100(x-0.4))^4 + sech(1000(x-0.6))^6 dx", "int_0^8 (exp(x)-floor(exp(x))) sin(x+exp(x)) dx (use higher -eval)", "int_0^{inf} sech(x) dx (using domain truncation)", "int_0^{inf} sech^3(x) dx (using domain truncation)", "int_0^1 -log(x)/(1+x) dx (using domain truncation)", "int_0^{inf} x exp(-x)/(1+exp(-x)) dx (using domain truncation)", "int_C wp(x)/x^(11) dx (contour for 10th Laurent coefficient of Weierstrass p-function)", "N(1000) = count zeros with 0 < t <= 1000 of zeta(s) using argument principle", "int_0^{1000} W_0(x) dx", "int_0^pi max(sin(x), cos(x)) dx", "int_{-1}^1 erf(x/sqrt(0.0002)*0.5+1.5)*exp(-x) dx", "int_{-10}^10 Ai(x) dx", "int_0^10 (x-floor(x)-1/2) max(sin(x),cos(x)) dx", "int_{-1-i}^{-1+i} sqrt(x) dx", "int_0^{inf} exp(-x^2+ix) dx (using domain truncation)", "int_0^{inf} exp(-x) Ai(-x) dx (using domain truncation)", "int_0^pi x sin(x) / (1 + cos(x)^2) dx", "int_0^3 sin(0.001 + (1-x)^2)^(-3/2)) dx (slow convergence, use higher -eval)", "int_0^{inf} exp(-x) I_0(x/3)^3 dx (using domain truncation)", "int_0^{inf} exp(-x) I_0(x/15)^{15} dx (using domain truncation)", "int_{-1-i}^{-1+i} 1/sqrt(x) dx", "int_0^{inf} 1/gamma(x) dx (using domain truncation)", }; int main(int argc, char *argv[]) { acb_t s, t, a, b; mag_t tol; slong prec, goal; slong N; ulong k; int integral, ifrom, ito; int i, twice, havegoal, havetol; acb_calc_integrate_opt_t options; ifrom = ito = -1; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-i")) { if (!strcmp(argv[i+1], "all")) { ifrom = 0; ito = NUM_INTEGRALS - 1; } else { ifrom = ito = atol(argv[i+1]); if (ito < 0 || ito >= NUM_INTEGRALS) flint_abort(); } } } if (ifrom == -1) { flint_printf("Compute integrals using acb_calc_integrate.\n"); flint_printf("Usage: integrals -i n [-prec p] [-tol eps] [-twice] [...]\n\n"); flint_printf("-i n - compute integral n (0 <= n <= %d), or \"-i all\"\n", NUM_INTEGRALS - 1); flint_printf("-prec p - precision in bits (default p = 64)\n"); flint_printf("-goal p - approximate relative accuracy goal (default p)\n"); flint_printf("-tol eps - approximate absolute error goal (default 2^-p)\n"); flint_printf("-twice - run twice (to see overhead of computing nodes)\n"); flint_printf("-heap - use heap for subinterval queue\n"); flint_printf("-verbose - show information\n"); flint_printf("-verbose2 - show more information\n"); flint_printf("-deg n - use quadrature degree up to n\n"); flint_printf("-eval n - limit number of function evaluations to n\n"); flint_printf("-depth n - limit subinterval queue size to n\n\n"); flint_printf("Implemented integrals:\n"); for (integral = 0; integral < NUM_INTEGRALS; integral++) flint_printf("I%d = %s\n", integral, descr[integral]); flint_printf("\n"); return 1; } acb_calc_integrate_opt_init(options); prec = 64; twice = 0; goal = 0; havetol = havegoal = 0; acb_init(a); acb_init(b); acb_init(s); acb_init(t); mag_init(tol); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-prec")) { prec = atol(argv[i+1]); } else if (!strcmp(argv[i], "-twice")) { twice = 1; } else if (!strcmp(argv[i], "-goal")) { goal = atol(argv[i+1]); if (goal < 0) { flint_printf("expected goal >= 0\n"); return 1; } havegoal = 1; } else if (!strcmp(argv[i], "-tol")) { arb_t x; arb_init(x); arb_set_str(x, argv[i+1], 10); arb_get_mag(tol, x); arb_clear(x); havetol = 1; } else if (!strcmp(argv[i], "-deg")) { options->deg_limit = atol(argv[i+1]); } else if (!strcmp(argv[i], "-eval")) { options->eval_limit = atol(argv[i+1]); } else if (!strcmp(argv[i], "-depth")) { options->depth_limit = atol(argv[i+1]); } else if (!strcmp(argv[i], "-verbose")) { options->verbose = 1; } else if (!strcmp(argv[i], "-verbose2")) { options->verbose = 2; } else if (!strcmp(argv[i], "-heap")) { options->use_heap = 1; } } if (!havegoal) goal = prec; if (!havetol) mag_set_ui_2exp_si(tol, 1, -prec); for (integral = ifrom; integral <= ito; integral++) { flint_printf("I%d = %s ...\n", integral, descr[integral]); for (i = 0; i < 1 + twice; i++) { TIMEIT_ONCE_START switch (integral) { case 0: acb_set_d(a, 0); acb_set_d(b, 100); acb_calc_integrate(s, f_sin, NULL, a, b, goal, tol, options, prec); break; case 1: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_atanderiv, NULL, a, b, goal, tol, options, prec); acb_mul_2exp_si(s, s, 2); break; case 2: acb_set_d(a, 0); acb_one(b); acb_mul_2exp_si(b, b, goal); acb_calc_integrate(s, f_atanderiv, NULL, a, b, goal, tol, options, prec); arb_add_error_2exp_si(acb_realref(s), -goal); acb_mul_2exp_si(s, s, 1); break; case 3: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_circle, NULL, a, b, goal, tol, options, prec); acb_mul_2exp_si(s, s, 2); break; case 4: acb_set_d(a, 0); acb_set_d(b, 8); acb_calc_integrate(s, f_rump, NULL, a, b, goal, tol, options, prec); break; case 5: acb_set_d(a, 1); acb_set_d(b, 101); acb_calc_integrate(s, f_floor, NULL, a, b, goal, tol, options, prec); break; case 6: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_helfgott, NULL, a, b, goal, tol, options, prec); break; case 7: acb_zero(s); acb_set_d_d(a, -1.0, -1.0); acb_set_d_d(b, 2.0, -1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 2.0, -1.0); acb_set_d_d(b, 2.0, 1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 2.0, 1.0); acb_set_d_d(b, -1.0, 1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, -1.0, 1.0); acb_set_d_d(b, -1.0, -1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_const_pi(t, prec); acb_div(s, s, t, prec); acb_mul_2exp_si(s, s, -1); acb_div_onei(s, s); break; case 8: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_essing, NULL, a, b, goal, tol, options, prec); break; case 9: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_essing2, NULL, a, b, goal, tol, options, prec); break; case 10: acb_set_d(a, 0); acb_set_d(b, 10000); acb_calc_integrate(s, f_factorial1000, NULL, a, b, goal, tol, options, prec); break; case 11: acb_set_d_d(a, 1.0, 0.0); acb_set_d_d(b, 1.0, 1000.0); acb_calc_integrate(s, f_gamma, NULL, a, b, goal, tol, options, prec); break; case 12: acb_set_d(a, -10.0); acb_set_d(b, 10.0); acb_calc_integrate(s, f_sin_plus_small, NULL, a, b, goal, tol, options, prec); break; case 13: acb_set_d(a, -1020.0); acb_set_d(b, -1010.0); acb_calc_integrate(s, f_exp, NULL, a, b, goal, tol, options, prec); break; case 14: acb_set_d(a, 0); acb_set_d(b, ceil(sqrt(goal * 0.693147181) + 1.0)); acb_calc_integrate(s, f_gaussian, NULL, a, b, goal, tol, options, prec); acb_mul(b, b, b, prec); acb_neg(b, b); acb_exp(b, b, prec); arb_add_error(acb_realref(s), acb_realref(b)); break; case 15: acb_set_d(a, 0.0); acb_set_d(b, 1.0); acb_calc_integrate(s, f_spike, NULL, a, b, goal, tol, options, prec); break; case 16: acb_set_d(a, 0.0); acb_set_d(b, 8.0); acb_calc_integrate(s, f_monster, NULL, a, b, goal, tol, options, prec); break; case 17: acb_set_d(a, 0); acb_set_d(b, ceil(goal * 0.693147181 + 1.0)); acb_calc_integrate(s, f_sech, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_exp(b, b, prec); acb_mul_2exp_si(b, b, 1); arb_add_error(acb_realref(s), acb_realref(b)); break; case 18: acb_set_d(a, 0); acb_set_d(b, ceil(goal * 0.693147181 / 3.0 + 2.0)); acb_calc_integrate(s, f_sech3, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_mul_ui(b, b, 3, prec); acb_exp(b, b, prec); acb_mul_2exp_si(b, b, 3); acb_div_ui(b, b, 3, prec); arb_add_error(acb_realref(s), acb_realref(b)); break; case 19: if (goal < 0) abort(); /* error bound 2^-N (1+N) when truncated at 2^-N */ N = goal + FLINT_BIT_COUNT(goal); acb_one(a); acb_mul_2exp_si(a, a, -N); acb_one(b); acb_calc_integrate(s, f_log_div1p, NULL, a, b, goal, tol, options, prec); acb_set_ui(b, N + 1); acb_mul_2exp_si(b, b, -N); arb_add_error(acb_realref(s), acb_realref(b)); break; case 20: if (goal < 0) abort(); /* error bound (N+1) exp(-N) when truncated at N */ N = goal + FLINT_BIT_COUNT(goal); acb_zero(a); acb_set_ui(b, N); acb_calc_integrate(s, f_log_div1p_transformed, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_exp(b, b, prec); acb_mul_ui(b, b, N + 1, prec); arb_add_error(acb_realref(s), acb_realref(b)); break; case 21: acb_zero(s); N = 10; acb_set_d_d(a, 0.5, -0.5); acb_set_d_d(b, 0.5, 0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 0.5, 0.5); acb_set_d_d(b, -0.5, 0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, -0.5, 0.5); acb_set_d_d(b, -0.5, -0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, -0.5, -0.5); acb_set_d_d(b, 0.5, -0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_const_pi(t, prec); acb_div(s, s, t, prec); acb_mul_2exp_si(s, s, -1); acb_div_onei(s, s); break; case 22: acb_zero(s); N = 1000; acb_set_d_d(a, 100.0, 0.0); acb_set_d_d(b, 100.0, N); acb_calc_integrate(t, f_zeta_frac, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 100, N); acb_set_d_d(b, 0.5, N); acb_calc_integrate(t, f_zeta_frac, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_div_onei(s, s); arb_zero(acb_imagref(s)); acb_set_ui(t, N); acb_dirichlet_hardy_theta(t, t, NULL, NULL, 1, prec); acb_add(s, s, t, prec); acb_const_pi(t, prec); acb_div(s, s, t, prec); acb_add_ui(s, s, 1, prec); break; case 23: acb_set_d(a, 0.0); acb_set_d(b, 1000.0); acb_calc_integrate(s, f_lambertw, NULL, a, b, goal, tol, options, prec); break; case 24: acb_set_d(a, 0.0); acb_const_pi(b, prec); acb_calc_integrate(s, f_max_sin_cos, NULL, a, b, goal, tol, options, prec); break; case 25: acb_set_si(a, -1); acb_set_si(b, 1); acb_calc_integrate(s, f_erf_bent, NULL, a, b, goal, tol, options, prec); break; case 26: acb_set_si(a, -10); acb_set_si(b, 10); acb_calc_integrate(s, f_airy_ai, NULL, a, b, goal, tol, options, prec); break; case 27: acb_set_si(a, 0); acb_set_si(b, 10); acb_calc_integrate(s, f_horror, NULL, a, b, goal, tol, options, prec); break; case 28: acb_set_d_d(a, -1, -1); acb_set_d_d(b, -1, 1); acb_calc_integrate(s, f_sqrt, NULL, a, b, goal, tol, options, prec); break; case 29: acb_set_d(a, 0); acb_set_d(b, ceil(sqrt(goal * 0.693147181) + 1.0)); acb_calc_integrate(s, f_gaussian_twist, NULL, a, b, goal, tol, options, prec); acb_mul(b, b, b, prec); acb_neg(b, b); acb_exp(b, b, prec); arb_add_error(acb_realref(s), acb_realref(b)); arb_add_error(acb_imagref(s), acb_realref(b)); break; case 30: acb_set_d(a, 0); acb_set_d(b, ceil(goal * 0.693147181 + 1.0)); acb_calc_integrate(s, f_exp_airy, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_exp(b, b, prec); acb_mul_2exp_si(b, b, 1); arb_add_error(acb_realref(s), acb_realref(b)); break; case 31: acb_zero(a); acb_const_pi(b, prec); acb_calc_integrate(s, f_sin_cos_frac, NULL, a, b, goal, tol, options, prec); break; case 32: acb_zero(a); acb_set_ui(b, 3); acb_calc_integrate(s, f_sin_near_essing, NULL, a, b, goal, tol, options, prec); break; case 33: acb_zero(a); acb_zero(b); k = 3; scaled_bessel_select_N(acb_realref(b), k, prec); acb_calc_integrate(s, f_scaled_bessel, &k, a, b, goal, tol, options, prec); scaled_bessel_tail_bound(acb_realref(a), k, acb_realref(b), prec); arb_add_error(acb_realref(s), acb_realref(a)); break; case 34: acb_zero(a); acb_zero(b); k = 15; scaled_bessel_select_N(acb_realref(b), k, prec); acb_calc_integrate(s, f_scaled_bessel, &k, a, b, goal, tol, options, prec); scaled_bessel_tail_bound(acb_realref(a), k, acb_realref(b), prec); arb_add_error(acb_realref(s), acb_realref(a)); break; case 35: acb_set_d_d(a, -1, -1); acb_set_d_d(b, -1, 1); acb_calc_integrate(s, f_rsqrt, NULL, a, b, goal, tol, options, prec); case 36: if (goal < 0) abort(); acb_zero(a); acb_set_ui(b, 4 + (goal + 1) / 2); acb_calc_integrate(s, f_rgamma, NULL, a, b, goal, tol, options, prec); arb_add_error_2exp_si(acb_realref(s), -goal); break; default: abort(); } TIMEIT_ONCE_STOP } flint_printf("I%d = ", integral); acb_printn(s, 3.333 * prec, 0); flint_printf("\n\n"); } acb_clear(a); acb_clear(b); acb_clear(s); acb_clear(t); mag_clear(tol); flint_cleanup(); return 0; } arb-2.22.1/examples/keiper_li.c000066400000000000000000000066051417376376500163210ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include #include "arb.h" #include "acb.h" #include "arb_poly.h" #include "flint/profiler.h" void keiper_li_series(arb_ptr z, slong len, slong prec) { arb_ptr t, u, v; t = _arb_vec_init(len); u = _arb_vec_init(len); v = _arb_vec_init(len); /* -zeta(s) */ flint_printf("zeta: "); TIMEIT_ONCE_START arb_zero(t + 0); arb_one(t + 1); arb_one(u); _arb_poly_zeta_series(v, t, 2, u, 0, len, prec); _arb_vec_neg(v, v, len); TIMEIT_ONCE_STOP SHOW_MEMORY_USAGE /* logarithm */ flint_printf("log: "); TIMEIT_ONCE_START _arb_poly_log_series(t, v, len, len, prec); TIMEIT_ONCE_STOP /* add log(gamma(1+s/2)) */ flint_printf("gamma: "); TIMEIT_ONCE_START arb_one(u); arb_one(u + 1); arb_mul_2exp_si(u + 1, u + 1, -1); _arb_poly_lgamma_series(v, u, 2, len, prec); _arb_vec_add(t, t, v, len, prec); TIMEIT_ONCE_STOP /* subtract 0.5 s log(pi) */ arb_const_pi(u, prec); arb_log(u, u, prec); arb_mul_2exp_si(u, u, -1); arb_sub(t + 1, t + 1, u, prec); /* add log(1-s) */ arb_one(u); arb_set_si(u + 1, -1); _arb_poly_log_series(v, u, 2, len, prec); _arb_vec_add(t, t, v, len, prec); /* binomial transform */ flint_printf("binomial transform: "); TIMEIT_ONCE_START arb_set(z, t); _arb_vec_neg(t + 1, t + 1, len - 1); _arb_poly_binomial_transform(z + 1, t + 1, len - 1, len - 1, prec); TIMEIT_ONCE_STOP _arb_vec_clear(t, len); _arb_vec_clear(u, len); _arb_vec_clear(v, len); } int main(int argc, char *argv[]) { slong i, len, prec, num_threads; char * out_file; arb_ptr z; if (argc < 2) { flint_printf("keiper_li n [-prec prec] [-threads num_threads] [-out out_file]\n"); return 1; } len = atol(argv[1]) + 1; prec = 1.1 * len + 50; num_threads = 1; out_file = NULL; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-prec")) prec = atol(argv[i+1]); else if (!strcmp(argv[i], "-threads")) num_threads = atol(argv[i+1]); else if (!strcmp(argv[i], "-out")) out_file = argv[i+1]; } flint_set_num_threads(num_threads); z = _arb_vec_init(len); keiper_li_series(z, len, prec); for (i = 0; i < len; i++) { if (i <= 10 || len - i <= 10) { flint_printf("%wd: ", i); arb_printd(z + i, 50); flint_printf("\n"); } } SHOW_MEMORY_USAGE if (out_file != NULL) { fmpz_t man, exp; arf_t t; FILE * fp = fopen(out_file, "w"); fmpz_init(man); fmpz_init(exp); arf_init(t); for (i = 0; i < len; i++) { arf_get_fmpz_2exp(man, exp, arb_midref(z + i)); flint_fprintf(fp, "%wd ", i); fmpz_fprint(fp, man); flint_fprintf(fp, " "); fmpz_fprint(fp, exp); flint_fprintf(fp, " "); arf_set_mag(t, arb_radref(z + i)); arf_get_fmpz_2exp(man, exp, t); fmpz_fprint(fp, man); flint_fprintf(fp, " "); fmpz_fprint(fp, exp); flint_fprintf(fp, "\n"); } fclose(fp); fmpz_clear(man); fmpz_clear(exp); arf_clear(t); } _arb_vec_clear(z, len); flint_cleanup(); return 0; } arb-2.22.1/examples/lcentral.c000066400000000000000000000051741417376376500161620ustar00rootroot00000000000000/* This file is public domain. Author: Pascal Molin. */ #include #include #include "flint/profiler.h" #include "acb_dirichlet.h" static int usage(char *argv[]) { printf("Computes central values (s = 0.5) of Dirichlet L-functions.\n\n"); printf("usage: %s [--quiet] [--check] [--prec ] qmin qmax\n", argv[0]); return 1; } int main(int argc, char *argv[]) { int i, check = 0, out = 1; slong prec = 100, digits = 30; ulong qmin, qmax, q; acb_t s; acb_dirichlet_hurwitz_precomp_t pre; if (argc < 3) return usage(argv); for (i = 1; i < argc - 2; i++) { if (!strcmp(argv[i], "--quiet")) out = 0; else if (!strcmp(argv[i], "--check")) check = 1; else if (!strcmp(argv[i], "--prec")) { i++; prec = atol(argv[i]); digits = floor(prec * 0.3); } } if (argc < i + 2) return usage(argv); qmin = atol(argv[i]); qmax = atol(argv[i+1]); fflush(stdout); acb_init(s); TIMEIT_ONCE_START acb_one(s); acb_div_si(s, s, 2, prec); acb_dirichlet_hurwitz_precomp_init_num(pre, s, 0, (qmax - qmin + 1) * 0.5 * qmax, prec); for (q = qmin; q <= qmax; q++) { ulong k; dirichlet_group_t G; dirichlet_char_t x; acb_ptr z; if (q % 4 == 2) continue; dirichlet_group_init(G, q); dirichlet_char_init(x, G); z = _acb_vec_init(G->phi_q); acb_dirichlet_l_vec_hurwitz(z, s, pre, G, prec); if (out || check) { k = 0; dirichlet_char_one(x, G); while (dirichlet_char_next(x, G) >= 0) { k++; if (dirichlet_conductor_char(G,x) < q) continue; if (acb_contains_zero(z + k)) { flint_printf("Value could be zero!\n"); flint_printf("%wu,%wu: ", q, x->n); acb_printn(z + k, digits, 0); flint_printf("\n"); flint_abort(); } if (out) { flint_printf("%wu,%wu: ", q, x->n); acb_printn(z + k, digits, 0); flint_printf("\n"); } } } _acb_vec_clear(z, G->phi_q); dirichlet_char_clear(x); dirichlet_group_clear(G); } acb_dirichlet_hurwitz_precomp_clear(pre); acb_clear(s); TIMEIT_ONCE_STOP SHOW_MEMORY_USAGE flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/examples/logistic.c000066400000000000000000000035131417376376500161660ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include "arb.h" #include "flint/profiler.h" int main(int argc, char *argv[]) { slong prec, goal, digits; const char * xs; const char * rs; arb_t x, r, s, t; slong i, n; if (argc < 2) { flint_printf("nth iterate of the logistic map x_{n+1} = r x_n (1-x_n)\n"); flint_printf("usage: build/examples/logistic n [x_0=0.5] [r=3.75] [digits=10]\n"); return 1; } n = atol(argv[1]); n = FLINT_MAX(n, 0); xs = (argc >= 3) ? argv[2] : "0.5"; rs = (argc >= 4) ? argv[3] : "3.75"; digits = (argc >= 5) ? atol(argv[4]) : 10; if (digits < 1) digits = 1; goal = digits * 3.3219280948873623 + 3; arb_init(x); arb_init(r); arb_init(s); arb_init(t); TIMEIT_ONCE_START for (prec = 64; ; prec *= 2) { flint_printf("Trying prec=%wd bits...", prec); fflush(stdout); arb_set_str(x, xs, prec); arb_set_str(r, rs, prec); if (!arb_is_finite(x) || !arb_is_finite(r)) { flint_printf("unable to parse input string!\n"); flint_abort(); } for (i = 0; i < n; i++) { arb_sub_ui(t, x, 1, prec); arb_neg(t, t); arb_mul(x, x, t, prec); arb_mul(x, x, r, prec); if (arb_rel_accuracy_bits(x) < goal) { flint_printf("ran out of accuracy at step %wd\n", i); break; } } if (i == n) { flint_printf("success!\n"); break; } } TIMEIT_ONCE_STOP flint_printf("x_%wd = ", n); arb_printn(x, digits, 0); flint_printf("\n"); arb_clear(x); arb_clear(r); arb_clear(s); arb_clear(t); flint_cleanup(); return 0; } arb-2.22.1/examples/lvalue.c000066400000000000000000000054031417376376500156410ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include #include "acb_dirichlet.h" #include "flint/profiler.h" int main(int argc, char *argv[]) { dirichlet_group_t G; dirichlet_char_t chi; acb_t s; acb_ptr z; slong prec, i, len; ulong q, n; int zfunction, deflate; if (argc < 2) { flint_printf("lvalue [-character q n] [-re a] [-im b] [-prec p] [-z] [-deflate] [-len l]\n\n"); flint_printf("Print value of Dirichlet L-function at s = a+bi.\n"); flint_printf("Default a = 0.5, b = 0, p = 53, (q, n) = (1, 0) (Riemann zeta)\n"); flint_printf("[-z] - compute Z(s) instead of L(s)\n"); flint_printf("[-deflate] - remove singular term at s = 1\n"); flint_printf("[-len l] - compute l terms in Taylor series at s\n"); return 1; } acb_init(s); zfunction = 0; prec = 53; q = 1; n = 0; len = 1; deflate = 0; acb_set_d(s, 0.5); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-prec")) { prec = atol(argv[i+1]); } } for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-character")) { q = atol(argv[i+1]); n = atol(argv[i+2]); } else if (!strcmp(argv[i], "-len")) { len = atol(argv[i+1]); } else if (!strcmp(argv[i], "-z")) { zfunction = 1; } else if (!strcmp(argv[i], "-deflate")) { deflate = 1; } else if (!strcmp(argv[i], "-re")) { arb_set_str(acb_realref(s), argv[i+1], prec); } else if (!strcmp(argv[i], "-im")) { arb_set_str(acb_imagref(s), argv[i+1], prec); } } if (n_gcd(q, n) != 1) { flint_printf("need gcd(q,n) = 1 to define a character\n"); flint_abort(); } z = _acb_vec_init(len); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_log(chi, G, n); TIMEIT_ONCE_START if (zfunction) acb_dirichlet_hardy_z(z, s, G, chi, len, prec); else acb_dirichlet_l_jet(z, s, G, chi, deflate, len, prec); for (i = 0; i < len; i++) { if (i == 0) flint_printf("%s(s) = ", zfunction ? "Z" : "L"); else if (i == 1) flint_printf("%s'(s) = ", zfunction ? "Z" : "L"); else flint_printf("[x^%wd] %s(s+x) = ", i, zfunction ? "Z" : "L"); acb_printn(z + i, prec * 0.333 + 1, 0); flint_printf("\n"); } TIMEIT_ONCE_STOP SHOW_MEMORY_USAGE _acb_vec_clear(z, len); acb_clear(s); dirichlet_char_clear(chi); dirichlet_group_clear(G); flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/examples/pi.c000066400000000000000000000014361417376376500147630ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include "arb.h" #include "flint/profiler.h" int main(int argc, char *argv[]) { arb_t x; slong prec, digits, condense; if (argc < 2) { flint_printf("usage: build/examples/pi digits [condense = 20]\n"); return 1; } digits = atol(argv[1]); if (argc > 2) condense = atol(argv[2]); else condense = 20; arb_init(x); prec = digits * 3.3219280948873623 + 5; flint_printf("computing pi with a precision of %wd bits... ", prec); TIMEIT_ONCE_START arb_const_pi(x, prec); TIMEIT_ONCE_STOP SHOW_MEMORY_USAGE arb_printn(x, digits, ARB_STR_CONDENSE * condense); flint_printf("\n"); arb_clear(x); flint_cleanup(); return 0; } arb-2.22.1/examples/poly_roots.c000066400000000000000000000147551417376376500165740ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include #include #include "acb.h" #include "arb_fmpz_poly.h" #include "flint/arith.h" #include "flint/profiler.h" int main(int argc, char *argv[]) { fmpz_poly_t f, g; fmpz_poly_factor_t fac; fmpz_t t; acb_ptr roots; slong compd, printd, i, j, deg; int flags; if (argc < 2) { flint_printf("poly_roots [-refine d] [-print d] \n\n"); flint_printf("Isolates all the complex roots of a polynomial with integer coefficients.\n\n"); flint_printf("If -refine d is passed, the roots are refined to a relative tolerance\n"); flint_printf("better than 10^(-d). By default, the roots are only computed to sufficient\n"); flint_printf("accuracy to isolate them. The refinement is not currently done efficiently.\n\n"); flint_printf("If -print d is passed, the computed roots are printed to d decimals.\n"); flint_printf("By default, the roots are not printed.\n\n"); flint_printf("The polynomial can be specified by passing the following as :\n\n"); flint_printf("a Easy polynomial 1 + 2x + ... + (n+1)x^n\n"); flint_printf("t Chebyshev polynomial T_n\n"); flint_printf("u Chebyshev polynomial U_n\n"); flint_printf("p Legendre polynomial P_n\n"); flint_printf("c Cyclotomic polynomial Phi_n\n"); flint_printf("s Swinnerton-Dyer polynomial S_n\n"); flint_printf("b Bernoulli polynomial B_n\n"); flint_printf("w Wilkinson polynomial W_n\n"); flint_printf("e Taylor series of exp(x) truncated to degree n\n"); flint_printf("m The Mignotte-like polynomial x^n + (100x+1)^m, n > m\n"); flint_printf("coeffs c0 + c1 x + ... + cn x^n\n\n"); flint_printf("Concatenate to multiply polynomials, e.g.: p 5 t 6 coeffs 1 2 3\n"); flint_printf("for P_5(x)*T_6(x)*(1+2x+3x^2)\n\n"); return 1; } compd = 0; printd = 0; flags = ARB_FMPZ_POLY_ROOTS_VERBOSE; fmpz_poly_init(f); fmpz_poly_init(g); fmpz_init(t); fmpz_poly_one(f); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-refine")) { compd = atol(argv[i+1]); i++; } else if (!strcmp(argv[i], "-print")) { printd = atol(argv[i+1]); i++; } else if (!strcmp(argv[i], "a")) { slong n = atol(argv[i+1]); fmpz_poly_zero(g); for (j = 0; j <= n; j++) fmpz_poly_set_coeff_ui(g, j, j+1); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "t")) { arith_chebyshev_t_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "u")) { arith_chebyshev_u_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "p")) { fmpq_poly_t h; fmpq_poly_init(h); arith_legendre_polynomial(h, atol(argv[i+1])); fmpq_poly_get_numerator(g, h); fmpz_poly_mul(f, f, g); fmpq_poly_clear(h); i++; } else if (!strcmp(argv[i], "c")) { arith_cyclotomic_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "s")) { arith_swinnerton_dyer_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "b")) { fmpq_poly_t h; fmpq_poly_init(h); arith_bernoulli_polynomial(h, atol(argv[i+1])); fmpq_poly_get_numerator(g, h); fmpz_poly_mul(f, f, g); fmpq_poly_clear(h); i++; } else if (!strcmp(argv[i], "w")) { slong n = atol(argv[i+1]); fmpz_poly_zero(g); fmpz_poly_fit_length(g, n+2); arith_stirling_number_1_vec(g->coeffs, n+1, n+2); _fmpz_poly_set_length(g, n+2); fmpz_poly_shift_right(g, g, 1); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "e")) { fmpq_poly_t h; fmpq_poly_init(h); fmpq_poly_set_coeff_si(h, 0, 0); fmpq_poly_set_coeff_si(h, 1, 1); fmpq_poly_exp_series(h, h, atol(argv[i+1]) + 1); fmpq_poly_get_numerator(g, h); fmpz_poly_mul(f, f, g); fmpq_poly_clear(h); i++; } else if (!strcmp(argv[i], "m")) { fmpz_poly_zero(g); fmpz_poly_set_coeff_ui(g, 0, 1); fmpz_poly_set_coeff_ui(g, 1, 100); fmpz_poly_pow(g, g, atol(argv[i+2])); fmpz_poly_set_coeff_ui(g, atol(argv[i+1]), 1); fmpz_poly_mul(f, f, g); i += 2; } else if (!strcmp(argv[i], "coeffs")) { fmpz_poly_zero(g); i++; j = 0; while (i < argc) { if (fmpz_set_str(t, argv[i], 10) != 0) { i--; break; } fmpz_poly_set_coeff_fmpz(g, j, t); i++; j++; } fmpz_poly_mul(f, f, g); } } fmpz_poly_factor_init(fac); flint_printf("computing squarefree factorization...\n"); TIMEIT_ONCE_START fmpz_poly_factor_squarefree(fac, f); TIMEIT_ONCE_STOP TIMEIT_ONCE_START for (i = 0; i < fac->num; i++) { deg = fmpz_poly_degree(fac->p + i); flint_printf("%wd roots with multiplicity %wd\n", deg, fac->exp[i]); roots = _acb_vec_init(deg); arb_fmpz_poly_complex_roots(roots, fac->p + i, flags, compd * 3.32193 + 2); if (printd) { for (j = 0; j < deg; j++) { acb_printn(roots + j, printd, 0); flint_printf("\n"); } } _acb_vec_clear(roots, deg); } TIMEIT_ONCE_STOP fmpz_poly_factor_clear(fac); fmpz_poly_clear(f); fmpz_poly_clear(g); fmpz_clear(t); flint_cleanup(); return EXIT_SUCCESS; } arb-2.22.1/examples/real_roots.c000066400000000000000000000236031417376376500165240ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include #include "arb_calc.h" #include "acb_hypgeom.h" #include "acb_dirichlet.h" #include "flint/profiler.h" slong eval_count = 0; typedef struct { dirichlet_group_t * G; dirichlet_char_t * chi; } z_param_struct; int z_function(arb_ptr out, const arb_t inp, void * params, slong order, slong prec) { z_param_struct * par = params; if (par->G == NULL) { arb_struct x[2]; arb_init(x); arb_init(x + 1); arb_set(x, inp); arb_one(x + 1); _arb_poly_riemann_siegel_z_series(out, x, FLINT_MIN(2, order), order, prec); arb_clear(x); arb_clear(x + 1); } else { acb_ptr tmp; slong k; tmp = _acb_vec_init(order); acb_set_arb(tmp, inp); acb_dirichlet_hardy_z(tmp, tmp, *(par->G), *(par->chi), order, prec); for (k = 0; k < order; k++) arb_set(out + k, acb_realref(tmp + k)); _acb_vec_clear(tmp, order); } eval_count++; return 0; } int sin_x(arb_ptr out, const arb_t inp, void * params, slong order, slong prec) { int xlen = FLINT_MIN(2, order); arb_set(out, inp); if (xlen > 1) arb_one(out + 1); _arb_poly_sin_series(out, out, xlen, order, prec); eval_count++; return 0; } int sin_x2(arb_ptr out, const arb_t inp, void * params, slong order, slong prec) { arb_ptr x; int xlen = FLINT_MIN(2, order); int ylen = FLINT_MIN(3, order); x = _arb_vec_init(xlen); arb_set(x, inp); if (xlen > 1) arb_one(x + 1); _arb_poly_mullow(out, x, xlen, x, xlen, ylen, prec); _arb_poly_sin_series(out, out, ylen, order, prec); _arb_vec_clear(x, xlen); eval_count++; return 0; } int sin_1x(arb_ptr out, const arb_t inp, void * params, slong order, slong prec) { arb_ptr x; int xlen = FLINT_MIN(2, order); x = _arb_vec_init(xlen); arb_set(x, inp); if (xlen > 1) arb_one(x + 1); _arb_poly_inv_series(out, x, xlen, order, prec); _arb_poly_sin_series(out, out, order, order, prec); _arb_vec_clear(x, xlen); eval_count++; return 0; } int airy(arb_ptr out, const arb_t inp, void * params, slong order, slong prec) { acb_t t, u; int which = ((int *) params)[0]; int xlen = FLINT_MIN(2, order); acb_init(t); acb_init(u); acb_set_arb(t, inp); if (xlen == 1) { if (which == 0) acb_hypgeom_airy(t, NULL, NULL, NULL, t, prec); else if (which == 1) acb_hypgeom_airy(NULL, t, NULL, NULL, t, prec); else if (which == 2) acb_hypgeom_airy(NULL, NULL, t, NULL, t, prec); else acb_hypgeom_airy(NULL, NULL, NULL, t, t, prec); arb_set(out, acb_realref(t)); } else { if (which == 0 || which == 1) acb_hypgeom_airy(t, u, NULL, NULL, t, prec); else acb_hypgeom_airy(NULL, NULL, t, u, t, prec); if (which == 0 || which == 2) { arb_set(out + 0, acb_realref(t)); arb_set(out + 1, acb_realref(u)); /* f''(z) = z f(z) */ if (xlen == 3) arb_mul(out + 2, out + 0, inp, prec); } else { arb_set(out + 0, acb_realref(u)); arb_mul(out + 1, acb_realref(t), inp, prec); /* f'''(z) = f(z) + z f'(z) */ if (xlen == 3) { arb_mul(out + 2, out + 0, inp, prec); arb_add(out + 2, out + 2, acb_realref(t), prec); } } } acb_clear(t); acb_clear(u); eval_count++; return 0; } int main(int argc, char *argv[]) { arf_interval_ptr blocks; arb_calc_func_t function; int * info; void * params; int param1; z_param_struct param2; dirichlet_group_t G; dirichlet_char_t chi; slong digits, low_prec, high_prec, i, num, found_roots, found_unknown; slong maxdepth, maxeval, maxfound; int refine; double a, b; arf_t C; arf_interval_t t, interval; arb_t v, w, z; if (argc < 4) { flint_printf("real_roots function a b [-refine d] [-verbose] " "[-maxdepth n] [-maxeval n] [-maxfound n] [-prec n]\n"); flint_printf("available functions:\n"); flint_printf(" 0 Z(x), Z-function (Riemann zeta or Dirichlet L-function)\n"); flint_printf(" 1 sin(x)\n"); flint_printf(" 2 sin(x^2)\n"); flint_printf(" 3 sin(1/x)\n"); flint_printf(" 4 Ai(x), Airy function\n"); flint_printf(" 5 Ai'(x), Airy function\n"); flint_printf(" 6 Bi(x), Airy function\n"); flint_printf(" 7 Bi'(x), Airy function\n"); flint_printf("With 0, specify optional Dirichlet character with [-character q n]\n"); return 1; } param1 = 0; param2.G = NULL; param2.chi = NULL; params = ¶m1; switch (atoi(argv[1])) { case 0: function = z_function; params = ¶m2; break; case 1: function = sin_x; break; case 2: function = sin_x2; break; case 3: function = sin_1x; break; case 4: function = airy; param1 = 0; break; case 5: function = airy; param1 = 1; break; case 6: function = airy; param1 = 2; break; case 7: function = airy; param1 = 3; break; default: flint_printf("require a function 0-7\n"); return 1; } a = atof(argv[2]); b = atof(argv[3]); if (a >= b) { flint_printf("require a < b!\n"); return 1; } refine = 0; digits = 0; maxdepth = 30; maxeval = 100000; maxfound = 100000; low_prec = 30; for (i = 4; i < argc; i++) { if (!strcmp(argv[i], "-refine")) { refine = 1; digits = atol(argv[i+1]); } else if (!strcmp(argv[i], "-verbose")) { arb_calc_verbose = 1; } else if (!strcmp(argv[i], "-maxdepth")) { maxdepth = atol(argv[i+1]); } else if (!strcmp(argv[i], "-maxeval")) { maxeval = atol(argv[i+1]); } else if (!strcmp(argv[i], "-maxfound")) { maxfound = atol(argv[i+1]); } else if (!strcmp(argv[i], "-prec")) { low_prec = atol(argv[i+1]); } else if (!strcmp(argv[i], "-character")) { dirichlet_group_init(G, atol(argv[i+1])); dirichlet_char_init(chi, G); dirichlet_char_log(chi, G, atol(argv[i+2])); param2.G = &G; param2.chi = χ } } high_prec = digits * 3.32192809488736 + 10; found_roots = 0; found_unknown = 0; arf_init(C); arf_interval_init(t); arf_interval_init(interval); arb_init(v); arb_init(w); arb_init(z); arf_set_d(&interval->a, a); arf_set_d(&interval->b, b); flint_printf("interval: "); arf_interval_printd(interval, 15); flint_printf("\n"); flint_printf("maxdepth = %wd, maxeval = %wd, maxfound = %wd, low_prec = %wd\n", maxdepth, maxeval, maxfound, low_prec); TIMEIT_ONCE_START num = arb_calc_isolate_roots(&blocks, &info, function, params, interval, maxdepth, maxeval, maxfound, low_prec); for (i = 0; i < num; i++) { if (info[i] != 1) { if (arb_calc_verbose) { flint_printf("unable to count roots in "); arf_interval_printd(blocks + i, 15); flint_printf("\n"); } found_unknown++; continue; } found_roots++; if (!refine) continue; if (arb_calc_refine_root_bisect(t, function, params, blocks + i, 5, low_prec) != ARB_CALC_SUCCESS) { flint_printf("warning: some bisection steps failed!\n"); } if (arb_calc_verbose) { flint_printf("after bisection 1: "); arf_interval_printd(t, 15); flint_printf("\n"); } if (arb_calc_refine_root_bisect(blocks + i, function, params, t, 5, low_prec) != ARB_CALC_SUCCESS) { flint_printf("warning: some bisection steps failed!\n"); } if (arb_calc_verbose) { flint_printf("after bisection 2: "); arf_interval_printd(blocks + i, 15); flint_printf("\n"); } arf_interval_get_arb(v, t, high_prec); arb_calc_newton_conv_factor(C, function, params, v, low_prec); arf_interval_get_arb(w, blocks + i, high_prec); if (arb_calc_refine_root_newton(z, function, params, w, v, C, 10, high_prec) != ARB_CALC_SUCCESS) { flint_printf("warning: some newton steps failed!\n"); } flint_printf("refined root (%wd/%wd):\n", i, num); arb_printn(z, digits + 2, 0); flint_printf("\n\n"); } flint_printf("---------------------------------------------------------------\n"); flint_printf("Found roots: %wd\n", found_roots); flint_printf("Subintervals possibly containing undetected roots: %wd\n", found_unknown); flint_printf("Function evaluations: %wd\n", eval_count); TIMEIT_ONCE_STOP SHOW_MEMORY_USAGE for (i = 0; i < num; i++) arf_interval_clear(blocks + i); flint_free(blocks); flint_free(info); if (param2.G != NULL) { dirichlet_group_clear(G); dirichlet_char_clear(chi); } arf_interval_clear(t); arf_interval_clear(interval); arf_clear(C); arb_clear(v); arb_clear(w); arb_clear(z); flint_cleanup(); return 0; } arb-2.22.1/examples/taylor_integrals.c000066400000000000000000000100431417376376500177270ustar00rootroot00000000000000/* This file is public domain. Author: Fredrik Johansson. */ #include "acb_calc.h" #include "flint/profiler.h" int sinx(acb_ptr out, const acb_t inp, void * params, slong order, slong prec) { int xlen = FLINT_MIN(2, order); acb_set(out, inp); if (xlen > 1) acb_one(out + 1); _acb_poly_sin_series(out, out, xlen, order, prec); return 0; } int elliptic(acb_ptr out, const acb_t inp, void * params, slong order, slong prec) { acb_ptr t; t = _acb_vec_init(order); acb_set(t, inp); if (order > 1) acb_one(t + 1); _acb_poly_sin_series(t, t, FLINT_MIN(2, order), order, prec); _acb_poly_mullow(out, t, order, t, order, order, prec); _acb_vec_scalar_mul_2exp_si(t, out, order, -1); acb_sub_ui(t, t, 1, prec); _acb_vec_neg(t, t, order); _acb_poly_rsqrt_series(out, t, order, order, prec); _acb_vec_clear(t, order); return 0; } int bessel(acb_ptr out, const acb_t inp, void * params, slong order, slong prec) { acb_ptr t; acb_t z; ulong n; t = _acb_vec_init(order); acb_init(z); acb_set(t, inp); if (order > 1) acb_one(t + 1); n = 10; arb_set_si(acb_realref(z), 20); arb_set_si(acb_imagref(z), 10); /* z sin(t) */ _acb_poly_sin_series(out, t, FLINT_MIN(2, order), order, prec); _acb_vec_scalar_mul(out, out, order, z, prec); /* t n */ _acb_vec_scalar_mul_ui(t, t, FLINT_MIN(2, order), n, prec); _acb_poly_sub(out, t, FLINT_MIN(2, order), out, order, prec); _acb_poly_cos_series(out, out, order, order, prec); _acb_vec_clear(t, order); acb_clear(z); return 0; } int main(int argc, char *argv[]) { acb_t r, s, a, b; arf_t inr, outr; slong digits, prec; if (argc < 2) { flint_printf("integrals d\n"); flint_printf("compute integrals using d decimal digits of precision\n"); return 1; } acb_init(r); acb_init(s); acb_init(a); acb_init(b); arf_init(inr); arf_init(outr); arb_calc_verbose = 0; digits = atol(argv[1]); prec = digits * 3.32193; flint_printf("Digits: %wd\n", digits); flint_printf("----------------------------------------------------------------\n"); flint_printf("Integral of sin(t) from 0 to 100.\n"); arf_set_d(inr, 0.125); arf_set_d(outr, 1.0); TIMEIT_ONCE_START acb_set_si(a, 0); acb_set_si(b, 100); acb_calc_integrate_taylor(r, sinx, NULL, a, b, inr, outr, prec, 1.1 * prec); flint_printf("RESULT:\n"); acb_printn(r, digits, 0); flint_printf("\n"); TIMEIT_ONCE_STOP flint_printf("----------------------------------------------------------------\n"); flint_printf("Elliptic integral F(phi, m) = integral of 1/sqrt(1 - m*sin(t)^2)\n"); flint_printf("from 0 to phi, with phi = 6+6i, m = 1/2. Integration path\n"); flint_printf("0 -> 6 -> 6+6i.\n"); arf_set_d(inr, 0.2); arf_set_d(outr, 0.5); TIMEIT_ONCE_START acb_set_si(a, 0); acb_set_si(b, 6); acb_calc_integrate_taylor(r, elliptic, NULL, a, b, inr, outr, prec, 1.1 * prec); acb_set_si(a, 6); arb_set_si(acb_realref(b), 6); arb_set_si(acb_imagref(b), 6); acb_calc_integrate_taylor(s, elliptic, NULL, a, b, inr, outr, prec, 1.1 * prec); acb_add(r, r, s, prec); flint_printf("RESULT:\n"); acb_printn(r, digits, 0); flint_printf("\n"); TIMEIT_ONCE_STOP flint_printf("----------------------------------------------------------------\n"); flint_printf("Bessel function J_n(z) = (1/pi) * integral of cos(t*n - z*sin(t))\n"); flint_printf("from 0 to pi. With n = 10, z = 20 + 10i.\n"); arf_set_d(inr, 0.1); arf_set_d(outr, 0.5); TIMEIT_ONCE_START acb_set_si(a, 0); acb_const_pi(b, 3 * prec); acb_calc_integrate_taylor(r, bessel, NULL, a, b, inr, outr, prec, 3 * prec); acb_div(r, r, b, prec); flint_printf("RESULT:\n"); acb_printn(r, digits, 0); flint_printf("\n"); TIMEIT_ONCE_STOP acb_clear(r); acb_clear(s); acb_clear(a); acb_clear(b); arf_clear(inr); arf_clear(outr); flint_cleanup(); return 0; } arb-2.22.1/fmpr.h000066400000000000000000000505651417376376500135150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef FMPR_H #define FMPR_H #if defined(__MINGW64__) || defined(_MSC_VER) #include "stdint.h" #endif #include #include #include #include #include "flint/flint.h" #include "flint/fmpz.h" #include "flint/fmpq.h" #if __FLINT_RELEASE < 20600 #include "flint/config.h" #else #include "flint/flint-config.h" #endif #include "fmpz_extras.h" #ifndef flint_abort #if __FLINT_RELEASE <= 20502 #define flint_abort abort #endif #endif #define TLS_PREFIX FLINT_TLS_PREFIX #if defined(_MSC_VER) && defined(ARB_BUILD_DLL) #define ARB_DLL __declspec(dllexport) #else #define ARB_DLL FLINT_DLL #endif #define fmpr_rnd_t int #define FMPR_RND_DOWN 0 #define FMPR_RND_UP 1 #define FMPR_RND_FLOOR 2 #define FMPR_RND_CEIL 3 #define FMPR_RND_NEAR 4 #ifdef __cplusplus extern "C" { #endif /* currently defined in the arb module, but global to the library */ double arb_test_multiplier(void); static __inline__ int rounds_up(fmpr_rnd_t rnd, int negative) { if (rnd == FMPR_RND_DOWN) return 0; if (rnd == FMPR_RND_UP) return 1; if (rnd == FMPR_RND_FLOOR) return negative; return !negative; } static __inline__ mpfr_rnd_t rnd_to_mpfr(fmpr_rnd_t rnd) { if (rnd == FMPR_RND_DOWN) return MPFR_RNDZ; else if (rnd == FMPR_RND_UP) return MPFR_RNDA; else if (rnd == FMPR_RND_FLOOR) return MPFR_RNDD; else if (rnd == FMPR_RND_CEIL) return MPFR_RNDU; else return MPFR_RNDN; } typedef struct { fmpz man; fmpz exp; } fmpr_struct; typedef fmpr_struct fmpr_t[1]; typedef fmpr_struct * fmpr_ptr; typedef const fmpr_struct * fmpr_srcptr; #define fmpr_manref(x) (&(x)->man) #define fmpr_expref(x) (&(x)->exp) static __inline__ void fmpr_init(fmpr_t x) { fmpz_init(fmpr_manref(x)); fmpz_init(fmpr_expref(x)); } static __inline__ void fmpr_clear(fmpr_t x) { fmpz_clear(fmpr_manref(x)); fmpz_clear(fmpr_expref(x)); } /* The return value encodes an error bound, or FMPR_RESULT_EXACT if exact */ #define FMPR_RESULT_EXACT WORD_MAX /* Allow 'infinite' precision for operations where a result can be computed exactly */ #define FMPR_PREC_EXACT WORD_MAX #define FMPR_PREC_ADD(prec,extra) ((prec) == FMPR_PREC_EXACT ? FMPR_PREC_EXACT : (prec) + (extra)) /* ------------------------------------------------------------------------ */ /* Special values */ /* Special values (0, +inf, -inf, NaN) are encoded using a zero mantissa. Zero is encoded with a zero exponent. */ #define FMPR_EXP_POS_INF WORD(1) #define FMPR_EXP_NEG_INF WORD(2) #define FMPR_EXP_NAN WORD(3) static __inline__ void fmpr_zero(fmpr_t x) { fmpz_zero(fmpr_manref(x)); fmpz_zero(fmpr_expref(x)); } static __inline__ int fmpr_is_zero(const fmpr_t x) { return fmpz_is_zero(fmpr_manref(x)) && fmpz_is_zero(fmpr_expref(x)); } static __inline__ int fmpr_is_special(const fmpr_t x) { return fmpz_is_zero(fmpr_manref(x)); } static __inline__ int fmpr_is_normal(const fmpr_t x) { return !fmpz_is_zero(fmpr_manref(x)); } static __inline__ int fmpr_is_inf(const fmpr_t x) { return fmpr_is_special(x) && (*fmpr_expref(x) == FMPR_EXP_POS_INF || *fmpr_expref(x) == FMPR_EXP_NEG_INF); } static __inline__ int fmpr_is_pos_inf(const fmpr_t x) { return fmpr_is_special(x) && (*fmpr_expref(x) == FMPR_EXP_POS_INF); } static __inline__ int fmpr_is_neg_inf(const fmpr_t x) { return fmpr_is_special(x) && (*fmpr_expref(x) == FMPR_EXP_NEG_INF); } static __inline__ int fmpr_is_nan(const fmpr_t x) { return fmpr_is_special(x) && (*fmpr_expref(x) == FMPR_EXP_NAN); } static __inline__ int fmpr_is_finite(const fmpr_t x) { return fmpr_is_zero(x) || !fmpr_is_special(x); } static __inline__ void fmpr_pos_inf(fmpr_t x) { fmpz_zero(fmpr_manref(x)); fmpz_set_si(fmpr_expref(x), FMPR_EXP_POS_INF); } static __inline__ void fmpr_neg_inf(fmpr_t x) { fmpz_zero(fmpr_manref(x)); fmpz_set_si(fmpr_expref(x), FMPR_EXP_NEG_INF); } static __inline__ void fmpr_nan(fmpr_t x) { fmpz_zero(fmpr_manref(x)); fmpz_set_si(fmpr_expref(x), FMPR_EXP_NAN); } static __inline__ int fmpr_is_one(const fmpr_t x) { return fmpz_is_one(fmpr_manref(x)) && fmpz_is_zero(fmpr_expref(x)); } static __inline__ void fmpr_one(fmpr_t x) { fmpz_one(fmpr_manref(x)); fmpz_zero(fmpr_expref(x)); } /* ------------------------------------------------------------------------ */ slong _fmpr_normalise_naive(fmpz_t man, fmpz_t exp, slong prec, fmpr_rnd_t rnd); static __inline__ void fmpr_set(fmpr_t y, const fmpr_t x) { if (y != x) { fmpz_set(fmpr_manref(y), fmpr_manref(x)); fmpz_set(fmpr_expref(y), fmpr_expref(x)); } } static __inline__ void fmpr_swap(fmpr_t x, fmpr_t y) { fmpz_swap(fmpr_manref(x), fmpr_manref(y)); fmpz_swap(fmpr_expref(x), fmpr_expref(y)); } slong _fmpr_set_round(fmpz_t rman, fmpz_t rexp, const fmpz_t man, const fmpz_t exp, slong prec, fmpr_rnd_t rnd); static __inline__ slong _fmpr_normalise(fmpz_t man, fmpz_t exp, slong prec, fmpr_rnd_t rnd) { if (fmpz_is_zero(man)) { fmpz_zero(man); fmpz_zero(exp); return FMPR_RESULT_EXACT; } else { return _fmpr_set_round(man, exp, man, exp, prec, rnd); } } static __inline__ slong fmpr_set_round_naive(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { fmpr_set(y, x); if (fmpr_is_special(y)) return FMPR_RESULT_EXACT; else return _fmpr_normalise(fmpr_manref(y), fmpr_expref(y), prec, rnd); } static __inline__ slong fmpr_set_round(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { fmpr_set(y, x); return FMPR_RESULT_EXACT; } else { return _fmpr_set_round(fmpr_manref(y), fmpr_expref(y), fmpr_manref(x), fmpr_expref(x), prec, rnd); } } static __inline__ slong fmpr_set_round_fmpz_2exp(fmpr_t y, const fmpz_t x, const fmpz_t exp, slong prec, fmpr_rnd_t rnd) { if (fmpz_is_zero(x)) { fmpr_zero(y); return FMPR_RESULT_EXACT; } else { return _fmpr_set_round(fmpr_manref(y), fmpr_expref(y), x, exp, prec, rnd); } } static __inline__ slong fmpr_set_round_fmpz(fmpr_t y, const fmpz_t x, slong prec, fmpr_rnd_t rnd) { if (fmpz_is_zero(x)) { fmpr_zero(y); return FMPR_RESULT_EXACT; } else { slong ret; fmpz_t exp; fmpz_init(exp); ret = _fmpr_set_round(fmpr_manref(y), fmpr_expref(y), x, exp, prec, rnd); fmpz_clear(exp); return ret; } } slong _fmpr_set_round_mpn(slong * shift, fmpz_t man, mp_srcptr x, mp_size_t xn, int negative, slong prec, fmpr_rnd_t rnd); slong fmpr_set_round_ui_2exp_fmpz(fmpr_t z, mp_limb_t lo, const fmpz_t exp, int negative, slong prec, fmpr_rnd_t rnd); slong fmpr_set_round_uiui_2exp_fmpz(fmpr_t z, mp_limb_t hi, mp_limb_t lo, const fmpz_t exp, int negative, slong prec, fmpr_rnd_t rnd); void fmpr_ulp(fmpr_t u, const fmpr_t x, slong prec); int fmpr_check_ulp(const fmpr_t result, slong r, slong prec); static __inline__ int fmpr_equal(const fmpr_t x, const fmpr_t y) { return fmpz_equal(fmpr_expref(x), fmpr_expref(y)) && fmpz_equal(fmpr_manref(x), fmpr_manref(y)); } static __inline__ int fmpr_sgn(const fmpr_t x) { if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) return 0; if (fmpr_is_pos_inf(x)) return 1; if (fmpr_is_neg_inf(x)) return -1; return 0; } return fmpz_sgn(fmpr_manref(x)); } int fmpr_cmp(const fmpr_t x, const fmpr_t y); int fmpr_cmpabs(const fmpr_t x, const fmpr_t y); int fmpr_cmpabs_ui(const fmpr_t x, ulong y); void fmpr_randtest(fmpr_t x, flint_rand_t state, slong bits, slong exp_bits); void fmpr_randtest_not_zero(fmpr_t x, flint_rand_t state, slong bits, slong exp_bits); void fmpr_randtest_special(fmpr_t x, flint_rand_t state, slong bits, slong exp_bits); int fmpr_get_mpfr(mpfr_t x, const fmpr_t y, mpfr_rnd_t rnd); void fmpr_set_mpfr(fmpr_t x, const mpfr_t y); double fmpr_get_d(const fmpr_t x, fmpr_rnd_t rnd); void fmpr_set_d(fmpr_t x, double v); static __inline__ void fmpr_set_ui(fmpr_t x, ulong c) { if (c == 0) { fmpr_zero(x); } else { int b; count_trailing_zeros(b, c); fmpz_set_ui(fmpr_manref(x), c >> b); fmpz_set_ui(fmpr_expref(x), b); } } static __inline__ void fmpr_set_si(fmpr_t x, slong c) { if (c == 0) { fmpr_zero(x); } else { int b; count_trailing_zeros(b, c); fmpz_set_si(fmpr_manref(x), c >> b); fmpz_set_ui(fmpr_expref(x), b); } } static __inline__ void fmpr_set_fmpz(fmpr_t x, const fmpz_t c) { if (fmpz_is_zero(c)) { fmpr_zero(x); } else { slong v = fmpz_val2(c); fmpz_tdiv_q_2exp(fmpr_manref(x), c, v); fmpz_set_ui(fmpr_expref(x), v); } } /* Arithmetic */ slong _fmpr_add_eps(fmpr_t z, const fmpr_t x, int sign, slong prec, fmpr_rnd_t rnd); slong _fmpr_add_mpn(fmpr_t z, mp_srcptr xman, mp_size_t xn, int xsign, const fmpz_t xexp, mp_srcptr yman, mp_size_t yn, int ysign, const fmpz_t yexp, slong shift, slong prec, fmpr_rnd_t rnd); slong _fmpr_add_1x1(fmpr_t z, mp_limb_t x, int xsign, const fmpz_t xexp, mp_limb_t y, int ysign, const fmpz_t yexp, slong shift, slong prec, slong rnd); slong fmpr_add_naive(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong _fmpr_mul_mpn(fmpr_t z, mp_srcptr xman, mp_size_t xn, const fmpz_t xexp, mp_srcptr yman, mp_size_t yn, const fmpz_t yexp, int negative, slong prec, fmpr_rnd_t rnd); slong _fmpr_mul_1x1(fmpr_t z, mp_limb_t u, const fmpz_t xexp, mp_limb_t v, const fmpz_t yexp, int negative, slong prec, fmpr_rnd_t rnd); slong fmpr_mul_naive(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_mul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_mul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd); slong fmpr_mul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd); slong fmpr_mul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_add(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_add_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd); slong fmpr_add_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd); slong fmpr_add_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_sub(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_sub_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd); slong fmpr_sub_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd); slong fmpr_sub_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_div(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_div_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd); slong fmpr_ui_div(fmpr_t z, ulong x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_div_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd); slong fmpr_si_div(fmpr_t z, slong x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_div_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_fmpz_div(fmpr_t z, const fmpz_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_fmpz_div_fmpz(fmpr_t z, const fmpz_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_addmul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_addmul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd); slong fmpr_addmul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd); slong fmpr_addmul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_submul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_submul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd); slong fmpr_submul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd); slong fmpr_submul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd); slong fmpr_sqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd); slong fmpr_sqrt_ui(fmpr_t z, ulong x, slong prec, fmpr_rnd_t rnd); slong fmpr_sqrt_fmpz(fmpr_t z, const fmpz_t x, slong prec, fmpr_rnd_t rnd); slong fmpr_rsqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd); slong fmpr_root(fmpr_t y, const fmpr_t x, ulong k, slong prec, fmpr_rnd_t rnd); slong fmpr_log(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd); slong fmpr_log1p(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd); slong fmpr_exp(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd); slong fmpr_expm1(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd); static __inline__ void fmpr_neg(fmpr_t y, const fmpr_t x) { if (fmpr_is_special(x)) { if (fmpr_is_pos_inf(x)) fmpr_neg_inf(y); else if (fmpr_is_neg_inf(x)) fmpr_pos_inf(y); else fmpr_set(y, x); } else { fmpz_neg(fmpr_manref(y), fmpr_manref(x)); fmpz_set(fmpr_expref(y), fmpr_expref(x)); } } static __inline__ slong fmpr_neg_round(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { fmpr_neg(y, x); if (fmpr_is_special(y)) return FMPR_RESULT_EXACT; else return _fmpr_normalise(fmpr_manref(y), fmpr_expref(y), prec, rnd); } static __inline__ void fmpr_abs(fmpr_t y, const fmpr_t x) { if (fmpr_sgn(x) < 0) fmpr_neg(y, x); else fmpr_set(y, x); } /* Convert return value to error bound */ static __inline__ void fmpr_set_error_result(fmpr_t err, const fmpr_t result, slong rret) { if (rret == FMPR_RESULT_EXACT) { fmpr_zero(err); } /* XXX: normally, a special value should not result from inexact arithmetic else if (fmpr_is_special(result)) { fmpr_pos_inf(err); } */ else { /* TODO: inline this */ fmpz_sub_ui(fmpr_expref(err), fmpr_expref(result), rret); fmpz_one(fmpr_manref(err)); } } static __inline__ void fmpr_add_error_result(fmpr_t err, const fmpr_t err_in, const fmpr_t result, slong rret, slong prec, fmpr_rnd_t rnd) { if (rret == FMPR_RESULT_EXACT) { fmpr_set(err, err_in); } else { fmpr_t t; fmpr_init(t); fmpr_set_error_result(t, result, rret); fmpr_add(err, err_in, t, prec, rnd); fmpr_clear(t); } } void fmpr_print(const fmpr_t x); void fmpr_printd(const fmpr_t x, slong digits); static __inline__ void fmpr_mul_2exp_si(fmpr_t y, const fmpr_t x, slong e) { if (e == 0 || fmpr_is_special(x)) { fmpr_set(y, x); } else { fmpz_set(fmpr_manref(y), fmpr_manref(x)); fmpz_add_si_inline(fmpr_expref(y), fmpr_expref(x), e); } } static __inline__ void fmpr_mul_2exp_fmpz(fmpr_t y, const fmpr_t x, const fmpz_t e) { if (e == 0 || fmpr_is_special(x)) { fmpr_set(y, x); } else { fmpz_set(fmpr_manref(y), fmpr_manref(x)); fmpz_add(fmpr_expref(y), fmpr_expref(x), e); } } void fmpr_get_fmpq(fmpq_t y, const fmpr_t x); slong fmpr_set_fmpq(fmpr_t x, const fmpq_t y, slong prec, fmpr_rnd_t rnd); void fmpr_get_fmpz(fmpz_t z, const fmpr_t x, fmpr_rnd_t rnd); slong fmpr_get_si(const fmpr_t x, fmpr_rnd_t rnd); void fmpr_set_fmpz_2exp(fmpr_t x, const fmpz_t man, const fmpz_t exp); void fmpr_get_fmpz_2exp(fmpz_t man, fmpz_t exp, const fmpr_t x); int fmpr_get_fmpz_fixed_fmpz(fmpz_t y, const fmpr_t x, const fmpz_t e); int fmpr_get_fmpz_fixed_si(fmpz_t y, const fmpr_t x, slong e); static __inline__ void fmpr_set_si_2exp_si(fmpr_t x, slong man, slong exp) { fmpr_set_si(x, man); fmpr_mul_2exp_si(x, x, exp); } static __inline__ void fmpr_set_ui_2exp_si(fmpr_t x, ulong man, slong exp) { fmpr_set_ui(x, man); fmpr_mul_2exp_si(x, x, exp); } int fmpr_cmp_2exp_si(const fmpr_t x, slong e); int fmpr_cmpabs_2exp_si(const fmpr_t x, slong e); static __inline__ void fmpr_min(fmpr_t z, const fmpr_t a, const fmpr_t b) { if (fmpr_cmp(a, b) <= 0) fmpr_set(z, a); else fmpr_set(z, b); } static __inline__ void fmpr_max(fmpr_t z, const fmpr_t a, const fmpr_t b) { if (fmpr_cmp(a, b) > 0) fmpr_set(z, a); else fmpr_set(z, b); } static __inline__ slong fmpr_bits(const fmpr_t x) { if (fmpr_is_special(x)) return 0; else return fmpz_bits(fmpr_manref(x)); } static __inline__ int fmpr_is_int(const fmpr_t x) { if (fmpr_is_special(x)) return fmpr_is_zero(x); else return fmpz_sgn(fmpr_expref(x)) >= 0; } static __inline__ int fmpr_is_int_2exp_si(const fmpr_t x, slong e) { if (fmpr_is_special(x)) return fmpr_is_zero(x); else return fmpz_cmp_si(fmpr_expref(x), e) >= 0; } #define CALL_MPFR_FUNC(r, func, y, x, prec, rnd) \ do { \ mpfr_t __t, __u; \ mpfr_rnd_t __rnd; \ __rnd = rnd_to_mpfr(rnd); \ mpfr_init2(__t, 2 + fmpz_bits(fmpr_manref(x))); \ mpfr_init2(__u, FLINT_MAX(2, prec)); \ mpfr_set_emin(MPFR_EMIN_MIN); \ mpfr_set_emax(MPFR_EMAX_MAX); \ fmpr_get_mpfr(__t, x, MPFR_RNDD); \ r = func(__u, __t, __rnd); \ if (mpfr_overflow_p() || mpfr_underflow_p()) \ { \ flint_printf("exception: mpfr overflow\n"); \ flint_abort(); \ } \ fmpr_set_mpfr(y, __u); \ if (r == 0) \ r = FMPR_RESULT_EXACT; \ else \ r = prec - fmpz_bits(fmpr_manref(y)); \ mpfr_clear(__t); \ mpfr_clear(__u); \ } while (0); #define CALL_MPFR_FUNC_K(r, func, y, x, k, prec, rnd) \ do { \ mpfr_t __t, __u; \ mpfr_rnd_t __rnd; \ __rnd = rnd_to_mpfr(rnd); \ mpfr_init2(__t, 2 + fmpz_bits(fmpr_manref(x))); \ mpfr_init2(__u, FLINT_MAX(2, prec)); \ mpfr_set_emin(MPFR_EMIN_MIN); \ mpfr_set_emax(MPFR_EMAX_MAX); \ fmpr_get_mpfr(__t, x, MPFR_RNDD); \ r = func(__u, __t, k, __rnd); \ if (mpfr_overflow_p() || mpfr_underflow_p()) \ { \ flint_printf("exception: mpfr overflow\n"); \ flint_abort(); \ } \ fmpr_set_mpfr(y, __u); \ if (r == 0) \ r = FMPR_RESULT_EXACT; \ else \ r = prec - fmpz_bits(fmpr_manref(y)); \ mpfr_clear(__t); \ mpfr_clear(__u); \ } while (0); #define CALL_MPFR_FUNC_2X1(r1, r2, func, y1, y2, x, prec, rnd) \ do { \ mpfr_t __t, __u, __v; \ mpfr_rnd_t __rnd; \ __rnd = rnd_to_mpfr(rnd); \ mpfr_init2(__t, 2 + fmpz_bits(fmpr_manref(x))); \ mpfr_init2(__u, FLINT_MAX(2, prec)); \ mpfr_init2(__v, FLINT_MAX(2, prec)); \ mpfr_set_emin(MPFR_EMIN_MIN); \ mpfr_set_emax(MPFR_EMAX_MAX); \ fmpr_get_mpfr(__t, x, MPFR_RNDD); \ func(__u, __v, __t, __rnd); \ if (mpfr_overflow_p() || mpfr_underflow_p()) \ { \ flint_printf("exception: mpfr overflow\n"); \ flint_abort(); \ } \ fmpr_set_mpfr(y1, __u); \ r1 = prec - fmpz_bits(fmpr_manref(y1)); \ fmpr_set_mpfr(y2, __v); \ r2 = prec - fmpz_bits(fmpr_manref(y2)); \ mpfr_clear(__t); \ mpfr_clear(__u); \ mpfr_clear(__v); \ } while (0); void fmpr_pow_sloppy_fmpz(fmpr_t y, const fmpr_t b, const fmpz_t e, slong prec, fmpr_rnd_t rnd); void fmpr_pow_sloppy_ui(fmpr_t y, const fmpr_t b, ulong e, slong prec, fmpr_rnd_t rnd); void fmpr_pow_sloppy_si(fmpr_t y, const fmpr_t b, slong e, slong prec, fmpr_rnd_t rnd); /* vector functions */ static __inline__ fmpr_ptr _fmpr_vec_init(slong n) { slong i; fmpr_ptr v = (fmpr_ptr) flint_malloc(sizeof(fmpr_struct) * n); for (i = 0; i < n; i++) fmpr_init(v + i); return v; } static __inline__ void _fmpr_vec_clear(fmpr_ptr v, slong n) { slong i; for (i = 0; i < n; i++) fmpr_clear(v + i); flint_free(v); } #ifdef __cplusplus } #endif #endif arb-2.22.1/fmpr/000077500000000000000000000000001417376376500133315ustar00rootroot00000000000000arb-2.22.1/fmpr/add.c000066400000000000000000000063271417376376500142350ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong _fmpr_add_1x1(fmpr_t z, mp_limb_t x, int xsign, const fmpz_t xexp, mp_limb_t y, int ysign, const fmpz_t yexp, slong shift, slong prec, slong rnd) { mp_limb_t hi, lo, t, u; int sign = ysign; t = x; u = y; (void) yexp; /* unused */ lo = u << shift; hi = (shift == 0) ? 0 : (u >> (FLINT_BITS - shift)); if (xsign == ysign) { add_ssaaaa(hi, lo, hi, lo, 0, t); } else { if (hi == 0) { if (lo >= t) { lo = lo - t; } else { lo = t - lo; sign = !sign; } } else { sub_ddmmss(hi, lo, hi, lo, 0, t); } } if (hi == 0) return fmpr_set_round_ui_2exp_fmpz(z, lo, xexp, sign, prec, rnd); else return fmpr_set_round_uiui_2exp_fmpz(z, hi, lo, xexp, sign, prec, rnd); } static slong _fmpr_add_special(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_zero(x)) { if (fmpr_is_zero(y)) { fmpr_zero(z); return FMPR_RESULT_EXACT; } else return fmpr_set_round(z, y, prec, rnd); } else if (fmpr_is_zero(y)) { return fmpr_set_round(z, x, prec, rnd); } else if (fmpr_is_nan(x) || fmpr_is_nan(y) || (fmpr_is_pos_inf(x) && fmpr_is_neg_inf(y)) || (fmpr_is_neg_inf(x) && fmpr_is_pos_inf(y))) { fmpr_nan(z); return FMPR_RESULT_EXACT; } else if (fmpr_is_special(x)) { fmpr_set(z, x); return FMPR_RESULT_EXACT; } else { fmpr_set(z, y); return FMPR_RESULT_EXACT; } } slong fmpr_add(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { slong shift, xn, yn; mp_limb_t xtmp, ytmp; mp_ptr xptr, yptr; fmpz xv, yv; const fmpz * xexp; const fmpz * yexp; int xsign, ysign; if (fmpr_is_special(x) || fmpr_is_special(y)) { return _fmpr_add_special(z, x, y, prec, rnd); } shift = _fmpz_sub_small(fmpr_expref(y), fmpr_expref(x)); if (shift >= 0) { xexp = fmpr_expref(x); yexp = fmpr_expref(y); xv = *fmpr_manref(x); yv = *fmpr_manref(y); } else { xexp = fmpr_expref(y); yexp = fmpr_expref(x); xv = *fmpr_manref(y); yv = *fmpr_manref(x); shift = -shift; } FMPZ_GET_MPN_READONLY(xsign, xn, xptr, xtmp, xv) FMPZ_GET_MPN_READONLY(ysign, yn, yptr, ytmp, yv) if ((xn == 1) && (yn == 1) && (shift < FLINT_BITS)) return _fmpr_add_1x1(z, xptr[0], xsign, xexp, yptr[0], ysign, yexp, shift, prec, rnd); else return _fmpr_add_mpn(z, xptr, xn, xsign, xexp, yptr, yn, ysign, yexp, shift, prec, rnd); } arb-2.22.1/fmpr/add_eps.c000066400000000000000000000026071417376376500151010ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong _fmpr_add_eps(fmpr_t z, const fmpr_t x, int sign, slong prec, fmpr_rnd_t rnd) { slong bits, shift; int xsign; xsign = fmpz_sgn(fmpr_manref(x)); if ((rnd == FMPR_RND_DOWN && xsign != sign) || (rnd == FMPR_RND_UP && xsign == sign) || (rnd == FMPR_RND_FLOOR && sign < 0) || (rnd == FMPR_RND_CEIL && sign > 0)) { bits = fmpz_bits(fmpr_manref(x)); shift = 2 + FLINT_MAX(0, prec - bits); fmpz_mul_2exp(fmpr_manref(z), fmpr_manref(x), shift); fmpz_sub_ui(fmpr_expref(z), fmpr_expref(x), shift); if (sign > 0) fmpz_add_ui(fmpr_manref(z), fmpr_manref(z), 1); else fmpz_sub_ui(fmpr_manref(z), fmpr_manref(z), 1); return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); } else { slong ret = fmpr_set_round(z, x, prec, rnd); if (ret == FMPR_RESULT_EXACT) return prec - fmpz_bits(fmpr_manref(z)); else return ret; } } arb-2.22.1/fmpr/add_fmpz.c000066400000000000000000000011671417376376500152660ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_add_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, y); r = fmpr_add(z, x, t, prec, rnd); fmpr_clear(t); return r; } arb-2.22.1/fmpr/add_mpn.c000066400000000000000000000240671417376376500151100ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" #define ADD_STACK_ALLOC 40 #define ADD_TLS_ALLOC 1000 TLS_PREFIX mp_ptr __add_tmp = NULL; TLS_PREFIX slong __add_alloc = 0; void _add_tmp_cleanup(void) { flint_free(__add_tmp); __add_tmp = NULL; __add_alloc = 0; } #define ADD_TMP_ALLOC \ if (alloc <= ADD_STACK_ALLOC) \ { \ tmp = tmp_stack; \ } \ else if (alloc <= ADD_TLS_ALLOC) \ { \ if (__add_alloc < alloc) \ { \ if (__add_alloc == 0) \ { \ flint_register_cleanup_function(_add_tmp_cleanup); \ } \ __add_tmp = flint_realloc(__add_tmp, sizeof(mp_limb_t) * alloc); \ __add_alloc = alloc; \ } \ tmp = __add_tmp; \ } \ else \ { \ tmp = flint_malloc(sizeof(mp_limb_t) * alloc); \ } #define ADD_TMP_FREE \ if (alloc > ADD_TLS_ALLOC) \ flint_free(tmp); /* computes x + y * 2^shift (optionally negated) */ slong _fmpr_add_mpn(fmpr_t z, mp_srcptr xman, mp_size_t xn, int xsign, const fmpz_t xexp, mp_srcptr yman, mp_size_t yn, int ysign, const fmpz_t yexp, slong shift, slong prec, fmpr_rnd_t rnd) { slong tn, zn, alloc, ret, shift_bits, shift_limbs; int negative; mp_limb_t tmp_stack[ADD_STACK_ALLOC]; mp_limb_t cy; mp_ptr tmp, tmp2; shift_limbs = shift / FLINT_BITS; shift_bits = shift % FLINT_BITS; /* x does not overlap with y or the result -- outcome is equivalent to adding/subtracting a small number to/from y and rounding */ if (shift > xn * FLINT_BITS && prec != FMPR_PREC_EXACT && xn * FLINT_BITS + prec - (FLINT_BITS * (yn - 1)) < shift) { zn = (prec + FLINT_BITS - 1) / FLINT_BITS; zn = FLINT_MAX(zn, yn) + 2; shift_limbs = zn - yn; alloc = zn; ADD_TMP_ALLOC flint_mpn_zero(tmp, shift_limbs); flint_mpn_copyi(tmp + shift_limbs, yman, yn); if (xsign == ysign) { tmp[0] = 1; } else { mpn_sub_1(tmp, tmp, zn, 1); while (tmp[zn-1] == 0) zn--; } ret = _fmpr_set_round_mpn(&shift, fmpr_manref(z), tmp, zn, ysign, prec, rnd); shift -= shift_limbs * FLINT_BITS; fmpz_add_si_inline(fmpr_expref(z), yexp, shift); ADD_TMP_FREE return ret; } if (xsign == ysign) { negative = xsign; /* certainly no overlap between x and y * 2^shift XXXXX YYYYY |-------| shift_limbs todo: handle huge case efficiently! */ if (shift_limbs >= xn) { alloc = shift_limbs + yn + 1; ADD_TMP_ALLOC flint_mpn_copyi(tmp, xman, xn); flint_mpn_zero(tmp + xn, shift_limbs - xn); if (shift_bits == 0) { flint_mpn_copyi(tmp + shift_limbs, yman, yn); zn = shift_limbs + yn; } else { cy = mpn_lshift(tmp + shift_limbs, yman, yn, shift_bits); tmp[shift_limbs + yn] = cy; zn = shift_limbs + yn + (cy != 0); } } else /* may have overlap between x and y * 2^shift */ { slong alloc1, alloc2; alloc2 = yn + 1; /* shifted value of y */ alloc1 = FLINT_MAX(alloc2 + shift_limbs, xn) + 1; /* space for sum */ alloc = alloc1 + alloc2; ADD_TMP_ALLOC tmp2 = tmp + alloc1; flint_mpn_copyi(tmp, xman, shift_limbs); /* {t, tn} = shift of y (ignoring shift_limbs zero limbs) */ if (shift_bits == 0) { flint_mpn_copyi(tmp2, yman, yn); tn = yn; } else { cy = mpn_lshift(tmp2, yman, yn, shift_bits); tmp2[yn] = cy; tn = yn + (cy != 0); } if (tn + shift_limbs == xn) { /* XXXXXXXX TTTTT */ cy = mpn_add_n(tmp + shift_limbs, xman + shift_limbs, tmp2, tn); tmp[xn] = cy; zn = xn + (cy != 0); } else if (tn + shift_limbs < xn) { /* XXXXXXXX TTTTT */ cy = mpn_add_n(tmp + shift_limbs, xman + shift_limbs, tmp2, tn); cy = mpn_add_1(tmp + shift_limbs + tn, xman + shift_limbs + tn, xn - tn - shift_limbs, cy); tmp[xn] = cy; zn = xn + (cy != 0); } else { /* XXXXXXXX TTTTTTT */ cy = mpn_add_n(tmp + shift_limbs, xman + shift_limbs, tmp2, xn - shift_limbs); cy = mpn_add_1(tmp + xn, tmp2 + xn - shift_limbs, tn + shift_limbs - xn, cy); tmp[tn + shift_limbs] = cy; zn = tn + shift_limbs + (cy != 0); } } } else { /* certainly no overlap between x and y * 2^shift XXXXX YYYYY |-------| shift_limbs todo: handle huge case efficiently! */ if (shift_limbs >= xn) { alloc = shift_limbs + yn + 1; ADD_TMP_ALLOC mpn_neg_n(tmp, xman, xn); /* since x is nonzero, there is certainly carry (borrow) */ flint_mpn_store(tmp + xn, shift_limbs - xn, (mp_limb_t) -1); if (shift_bits == 0) { flint_mpn_copyi(tmp + shift_limbs, yman, yn); zn = shift_limbs + yn; } else { cy = mpn_lshift(tmp + shift_limbs, yman, yn, shift_bits); tmp[shift_limbs + yn] = cy; zn = shift_limbs + yn + (cy != 0); } mpn_sub_1(tmp + shift_limbs, tmp + shift_limbs, zn - shift_limbs, 1); /* y has larger absolute value, and determines the sign */ negative = ysign; } else /* may have overlap between x and y * 2^shift */ { slong alloc1, alloc2; alloc2 = yn + 1; /* shifted value of y */ alloc1 = FLINT_MAX(alloc2 + shift_limbs, xn); /* space for difference */ alloc = alloc1 + alloc2; ADD_TMP_ALLOC tmp2 = tmp + alloc1; /* {t, tn} = shift of y (ignoring shift_limbs zero limbs) */ if (shift_bits == 0) { flint_mpn_copyi(tmp2, yman, yn); tn = yn; } else { cy = mpn_lshift(tmp2, yman, yn, shift_bits); tmp2[yn] = cy; tn = yn + (cy != 0); } if (tn + shift_limbs == xn) { int comp; /* XXXXXXXX TTTTT */ comp = mpn_cmp(xman + shift_limbs, tmp2, tn); if (comp == 0) { slong i; for (i = 0; i < shift_limbs; i++) { if (xman[i] != 0) { comp = 1; break; } } /* the result is exactly zero */ if (comp == 0) { fmpr_zero(z); ret = FMPR_RESULT_EXACT; goto cleanup; } } /* x is larger */ if (comp > 0) { flint_mpn_copyi(tmp, xman, shift_limbs); mpn_sub_n(tmp + shift_limbs, xman + shift_limbs, tmp2, tn); negative = xsign; } else { mpn_sub_n(tmp + shift_limbs, tmp2, xman + shift_limbs, tn); if (shift_limbs != 0) { cy = mpn_neg_n(tmp, xman, shift_limbs); mpn_sub_1(tmp + shift_limbs, tmp + shift_limbs, tn, cy); } negative = ysign; } zn = xn; } else if (tn + shift_limbs < xn) { /* XXXXXXXX TTTTT */ flint_mpn_copyi(tmp, xman, shift_limbs); cy = mpn_sub_n(tmp + shift_limbs, xman + shift_limbs, tmp2, tn); mpn_sub_1(tmp + shift_limbs + tn, xman + shift_limbs + tn, xn - tn - shift_limbs, cy); zn = xn; negative = xsign; } else { /* XXXXXXXX TTTTTTT */ cy = mpn_sub_n(tmp + shift_limbs, tmp2, xman + shift_limbs, xn - shift_limbs); mpn_sub_1(tmp + xn, tmp2 + xn - shift_limbs, tn + shift_limbs - xn, cy); if (shift_limbs != 0) { cy = mpn_neg_n(tmp, xman, shift_limbs); mpn_sub_1(tmp + shift_limbs, tmp + shift_limbs, tn, cy); } zn = shift_limbs + tn; negative = ysign; } } /* there might have been cancellation */ while (tmp[zn-1] == 0) zn--; } ret = _fmpr_set_round_mpn(&shift, fmpr_manref(z), tmp, zn, negative, prec, rnd); fmpz_add_si_inline(fmpr_expref(z), xexp, shift); cleanup: ADD_TMP_FREE return ret; } arb-2.22.1/fmpr/add_naive.c000066400000000000000000000060271417376376500154140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" static __inline__ void fmpz_addmul_2exp(fmpz_t z, const fmpz_t x, const fmpz_t y, ulong shift) { fmpz_t t; fmpz_init(t); fmpz_mul_2exp(t, y, shift); fmpz_add(z, x, t); fmpz_clear(t); } static slong _fmpr_add_special(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_zero(x)) { if (fmpr_is_zero(y)) { fmpr_zero(z); return FMPR_RESULT_EXACT; } else return fmpr_set_round(z, y, prec, rnd); } else if (fmpr_is_zero(y)) { return fmpr_set_round(z, x, prec, rnd); } else if (fmpr_is_nan(x) || fmpr_is_nan(y) || (fmpr_is_pos_inf(x) && fmpr_is_neg_inf(y)) || (fmpr_is_neg_inf(x) && fmpr_is_pos_inf(y))) { fmpr_nan(z); return FMPR_RESULT_EXACT; } else if (fmpr_is_special(x)) { fmpr_set(z, x); return FMPR_RESULT_EXACT; } else { fmpr_set(z, y); return FMPR_RESULT_EXACT; } } slong fmpr_add_naive(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { slong shift, xsize, ysize; if (fmpr_is_special(x) || fmpr_is_special(y)) { return _fmpr_add_special(z, x, y, prec, rnd); } shift = _fmpz_sub_small(fmpr_expref(x), fmpr_expref(y)); if (shift == 0) { fmpz_add(fmpr_manref(z), fmpr_manref(x), fmpr_manref(y)); fmpz_set(fmpr_expref(z), fmpr_expref(x)); } else if (shift > 0) { ysize = _fmpz_size(fmpr_manref(y)) * FLINT_BITS; /* x and y do not overlap */ if (shift > ysize && prec != FMPR_PREC_EXACT) { /* y does not overlap with result */ if (ysize + prec - (slong) fmpz_bits(fmpr_manref(x)) < shift) { return _fmpr_add_eps(z, x, fmpz_sgn(fmpr_manref(y)), prec, rnd); } } fmpz_addmul_2exp(fmpr_manref(z), fmpr_manref(y), fmpr_manref(x), shift); fmpz_set(fmpr_expref(z), fmpr_expref(y)); } else { shift = -shift; xsize = _fmpz_size(fmpr_manref(x)) * FLINT_BITS; /* x and y do not overlap */ if (shift > xsize && prec != FMPR_PREC_EXACT) { /* y does not overlap with result */ if (xsize + prec - (slong) fmpz_bits(fmpr_manref(y)) < shift) { return _fmpr_add_eps(z, y, fmpz_sgn(fmpr_manref(x)), prec, rnd); } } fmpz_addmul_2exp(fmpr_manref(z), fmpr_manref(x), fmpr_manref(y), shift); fmpz_set(fmpr_expref(z), fmpr_expref(x)); } return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); } arb-2.22.1/fmpr/add_si.c000066400000000000000000000011541417376376500147210ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_add_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, y); r = fmpr_add(z, x, t, prec, rnd); fmpr_clear(t); return r; } arb-2.22.1/fmpr/add_ui.c000066400000000000000000000011541417376376500147230ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_add_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_ui(t, y); r = fmpr_add(z, x, t, prec, rnd); fmpr_clear(t); return r; } arb-2.22.1/fmpr/addmul.c000066400000000000000000000025121417376376500147430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_addmul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_mul(t, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); r = fmpr_add(z, z, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_addmul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_ui(t, y); r = fmpr_addmul(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_addmul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, y); r = fmpr_addmul(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_addmul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, y); r = fmpr_addmul(z, x, t, prec, rnd); fmpr_clear(t); return r; } arb-2.22.1/fmpr/check_ulp.c000066400000000000000000000015161417376376500154350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int fmpr_check_ulp(const fmpr_t result, slong r, slong prec) { if (r == FMPR_RESULT_EXACT) { return 1; } else { fmpr_t err; fmpr_t ulp; int ok; fmpr_init(err); fmpr_init(ulp); fmpr_ulp(ulp, result, prec); fmpr_set_error_result(err, result, r); ok = fmpr_equal(err, ulp); fmpr_clear(err); fmpr_clear(ulp); return ok; } } arb-2.22.1/fmpr/cmp.c000066400000000000000000000025301417376376500142540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int fmpr_cmp(const fmpr_t x, const fmpr_t y) { int res, xsign, ysign; fmpr_t t; if (fmpr_equal(x, y)) return 0; if (fmpr_is_special(x) || fmpr_is_special(y)) { if (fmpr_is_nan(x) || fmpr_is_nan(y)) return 0; if (fmpr_is_zero(y)) return fmpr_sgn(x); if (fmpr_is_zero(x)) return -fmpr_sgn(y); if (fmpr_is_pos_inf(x)) return 1; if (fmpr_is_neg_inf(y)) return 1; return -1; } xsign = fmpr_sgn(x); ysign = fmpr_sgn(y); if (xsign != ysign) return (xsign < 0) ? -1 : 1; /* Reduces to integer comparison if bottom exponents are the same */ if (fmpz_equal(fmpr_expref(x), fmpr_expref(y))) return fmpz_cmp(fmpr_manref(x), fmpr_manref(y)) < 0 ? -1 : 1; /* TODO: compare position of top exponents to avoid subtraction */ fmpr_init(t); fmpr_sub(t, x, y, 2, FMPR_RND_DOWN); res = fmpr_sgn(t); fmpr_clear(t); return res; } arb-2.22.1/fmpr/cmp_2exp_si.c000066400000000000000000000021671417376376500157130ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" static __inline__ int sgn(int x) { return (x > 0) - (x < 0); } int fmpr_cmp_2exp_si(const fmpr_t x, slong e) { slong bc; int ret; fmpz_t t; if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) return -1; if (fmpr_is_pos_inf(x)) return 1; if (fmpr_is_neg_inf(x)) return -1; if (fmpr_is_nan(x)) return 0; return -1; } if (fmpz_is_one(fmpr_manref(x))) return sgn(fmpz_cmp_si(fmpr_expref(x), e)); if (fmpz_sgn(fmpr_manref(x)) < 0) return -1; bc = fmpz_bits(fmpr_manref(x)); fmpz_init(t); fmpz_add_si_inline(t, fmpr_expref(x), bc); fmpz_sub_si_inline(t, t, e); ret = (fmpz_sgn(t) <= 0) ? -1 : 1; fmpz_clear(t); return ret; } arb-2.22.1/fmpr/cmpabs.c000066400000000000000000000027501417376376500147460ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int fmpr_cmpabs(const fmpr_t x, const fmpr_t y) { int res, xsign, ysign; fmpr_t t; if (fmpr_equal(x, y)) return 0; if (fmpr_is_special(x) || fmpr_is_special(y)) { if (fmpr_is_nan(x) || fmpr_is_nan(y)) return 0; if (fmpr_is_zero(x)) return -1; if (fmpr_is_zero(y)) return 1; if (fmpr_is_inf(x)) return fmpr_is_inf(y) ? 0 : 1; if (fmpr_is_inf(y)) return -1; return -1; } /* Reduces to integer comparison if bottom exponents are the same */ if (fmpz_equal(fmpr_expref(x), fmpr_expref(y))) { res = fmpz_cmpabs(fmpr_manref(x), fmpr_manref(y)); if (res != 0) res = (res < 0) ? -1 : 1; } else { /* TODO: compare position of top exponents to avoid subtraction */ xsign = fmpr_sgn(x); ysign = fmpr_sgn(y); fmpr_init(t); if (xsign == ysign) fmpr_sub(t, x, y, 2, FMPR_RND_DOWN); else fmpr_add(t, x, y, 2, FMPR_RND_DOWN); res = fmpr_sgn(t) * xsign; fmpr_clear(t); } return res; } arb-2.22.1/fmpr/cmpabs_2exp_si.c000066400000000000000000000020211417376376500163660ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" static __inline__ int sgn(int x) { return (x > 0) - (x < 0); } int fmpr_cmpabs_2exp_si(const fmpr_t x, slong e) { slong bc; int ret; fmpz_t t; if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) return -1; if (fmpr_is_inf(x)) return 1; if (fmpr_is_nan(x)) return 0; return -1; } if (fmpz_is_pm1(fmpr_manref(x))) return sgn(fmpz_cmp_si(fmpr_expref(x), e)); bc = fmpz_bits(fmpr_manref(x)); fmpz_init(t); fmpz_add_si_inline(t, fmpr_expref(x), bc); fmpz_sub_si_inline(t, t, e); ret = (fmpz_sgn(t) <= 0) ? -1 : 1; fmpz_clear(t); return ret; } arb-2.22.1/fmpr/cmpabs_ui.c000066400000000000000000000011041417376376500154330ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int fmpr_cmpabs_ui(const fmpr_t x, ulong y) { fmpr_t t; int res; fmpr_init(t); fmpr_set_ui(t, y); res = fmpr_cmpabs(x, t); fmpr_clear(t); return res; } arb-2.22.1/fmpr/div.c000066400000000000000000000111751417376376500142640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" static void _fmpr_div_special(fmpr_t z, const fmpr_t x, const fmpr_t y) { if ((fmpr_is_zero(x) && !fmpr_is_zero(y) && !fmpr_is_nan(y)) || (fmpr_is_inf(y) && !fmpr_is_special(x))) { fmpr_zero(z); } else if (fmpr_is_zero(y) || (fmpr_is_special(x) && fmpr_is_special(y)) || fmpr_is_nan(x) || fmpr_is_nan(y)) { fmpr_nan(z); } else if (fmpr_sgn(x) == fmpr_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); } static __inline__ int low_bits_are_zero(const fmpz_t u, int bits) { fmpz f = *u; mp_limb_t low; if (!COEFF_IS_MPZ(f)) low = FLINT_ABS(f); else low = COEFF_TO_PTR(f)->_mp_d[0]; return (low & ((UWORD(1) << bits) - 1)) == 0; } slong fmpr_div(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x) || fmpr_is_special(y)) { _fmpr_div_special(z, x, y); return FMPR_RESULT_EXACT; } /* division by power of two <=> shift exponents */ if (fmpz_is_pm1(fmpr_manref(y))) { if (fmpz_is_one(fmpr_manref(y))) fmpz_set(fmpr_manref(z), fmpr_manref(x)); else fmpz_neg(fmpr_manref(z), fmpr_manref(x)); fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y)); return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); } else { slong xbits, ybits, extra, extra_pad, extra_control; int negative; fmpz_t t, u; /* todo: work out exact needed shift */ xbits = fmpz_bits(fmpr_manref(x)); ybits = fmpz_bits(fmpr_manref(y)); extra = prec - xbits + ybits; extra = FLINT_MAX(extra, 0); extra_pad = 32; extra_control = 24; extra += extra_pad; fmpz_init(t); fmpz_init(u); fmpz_mul_2exp(t, fmpr_manref(x), extra); fmpz_tdiv_q(u, t, fmpr_manref(y)); if (low_bits_are_zero(u, extra_control)) { fmpz_t v; fmpz_init(v); fmpz_mul(v, u, fmpr_manref(y)); negative = fmpz_sgn(fmpr_manref(x)) != fmpz_sgn(fmpr_manref(y)); if (!fmpz_equal(t, v)) { if (negative) fmpz_sub_ui(u, u, 1); else fmpz_add_ui(u, u, 1); } fmpz_clear(v); } fmpz_swap(fmpr_manref(z), u); fmpz_clear(t); fmpz_clear(u); fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y)); fmpz_sub_ui(fmpr_expref(z), fmpr_expref(z), extra); return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); } } slong fmpr_div_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_ui(t, y); r = fmpr_div(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_ui_div(fmpr_t z, ulong x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_ui(t, x); r = fmpr_div(z, t, y, prec, rnd); fmpr_clear(t); return r; } slong fmpr_div_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, y); r = fmpr_div(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_si_div(fmpr_t z, slong x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, x); r = fmpr_div(z, t, y, prec, rnd); fmpr_clear(t); return r; } slong fmpr_div_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, y); r = fmpr_div(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_fmpz_div(fmpr_t z, const fmpz_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, x); r = fmpr_div(z, t, y, prec, rnd); fmpr_clear(t); return r; } slong fmpr_fmpz_div_fmpz(fmpr_t z, const fmpz_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t, u; slong r; fmpr_init(t); fmpr_init(u); fmpr_set_fmpz(t, x); fmpr_set_fmpz(u, y); r = fmpr_div(z, t, u, prec, rnd); fmpr_clear(t); fmpr_clear(u); return r; } arb-2.22.1/fmpr/exp.c000066400000000000000000000025371417376376500143000ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_exp(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_one(y); else if (fmpr_is_pos_inf(x)) fmpr_pos_inf(y); else if (fmpr_is_neg_inf(x)) fmpr_zero(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_exp, y, x, prec, rnd); return r; } } slong fmpr_expm1(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_zero(y); else if (fmpr_is_pos_inf(x)) fmpr_pos_inf(y); else if (fmpr_is_neg_inf(x)) fmpr_set_si(y, -WORD(1)); else fmpr_nan(y); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_expm1, y, x, prec, rnd); return r; } } arb-2.22.1/fmpr/get_d.c000066400000000000000000000014011417376376500145530ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" double fmpr_get_d(const fmpr_t x, fmpr_rnd_t rnd) { double r; mpfr_rnd_t mrnd; mpfr_t t; mp_limb_t tmp[2]; if (fmpr_is_zero(x)) return 0.0; mrnd = rnd_to_mpfr(rnd); t->_mpfr_prec = 53; t->_mpfr_sign = 1; t->_mpfr_exp = 0; t->_mpfr_d = tmp; fmpr_get_mpfr(t, x, mrnd); r = mpfr_get_d(t, mrnd); return r; } arb-2.22.1/fmpr/get_fmpq.c000066400000000000000000000020351417376376500152770ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_get_fmpq(fmpq_t y, const fmpr_t x) { if (fmpr_is_zero(x)) { fmpq_zero(y); } else if (fmpr_is_special(x) || COEFF_IS_MPZ(*fmpr_expref(x))) { flint_printf("exception: fmpr_get_fmpq: cannot convert to rational\n"); flint_abort(); } else { slong exp = *fmpr_expref(x); fmpz_set_ui(fmpq_denref(y), UWORD(1)); if (exp >= 0) { fmpz_mul_2exp(fmpq_numref(y), fmpr_manref(x), exp); } else { fmpz_set(fmpq_numref(y), fmpr_manref(x)); fmpz_mul_2exp(fmpq_denref(y), fmpq_denref(y), -exp); } } } arb-2.22.1/fmpr/get_fmpz.c000066400000000000000000000056221417376376500153150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_get_fmpz(fmpz_t z, const fmpr_t x, fmpr_rnd_t rnd) { slong exp; if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) { fmpz_zero(z); } else { flint_printf("fmpr_get_fmpz: cannot convert infinity or nan to integer\n"); flint_abort(); } } if (!COEFF_IS_MPZ(*fmpr_expref(x))) { exp = *fmpr_expref(x); } else { /* tiny */ if (fmpz_sgn(fmpr_expref(x)) < 0) { int sign = fmpz_sgn(fmpr_manref(x)); if (rnd == FMPR_RND_NEAR || rnd == FMPR_RND_DOWN || (rnd == FMPR_RND_FLOOR && sign > 0) || (rnd == FMPR_RND_CEIL && sign < 0)) fmpz_zero(z); else fmpz_set_si(z, sign); return; } else { flint_printf("fmpr_get_fmpz: number too large to convert to integer\n"); flint_abort(); return; /* dummy return because flint_abort() is not declared noreturn */ } } if (exp >= 0) { fmpz_mul_2exp(z, fmpr_manref(x), exp); } else { exp = -exp; if (rnd == FMPR_RND_NEAR) { int sign = fmpz_sgn(fmpr_manref(x)); /* half-integer -> tie, so round to even */ if (exp == 1) { fmpz_tdiv_q_2exp(z, fmpr_manref(x), 1); if (fmpz_is_odd(z)) { if (sign > 0) fmpz_add_ui(z, z, 1); else fmpz_sub_ui(z, z, 1); } } else if (fmpz_bits(fmpr_manref(x)) < exp) /* < 0.5 */ { fmpz_zero(z); } else { /* add 1/2 and round to floor */ fmpz_t t; fmpz_init(t); fmpz_one(t); fmpz_mul_2exp(t, t, exp - 1); fmpz_add(t, t, fmpr_manref(x)); fmpz_fdiv_q_2exp(z, t, exp); fmpz_clear(t); } } else if (rnd == FMPR_RND_DOWN) fmpz_tdiv_q_2exp(z, fmpr_manref(x), exp); else if (rnd == FMPR_RND_UP) fmpz_adiv_q_2exp(z, fmpr_manref(x), exp); else if (rnd == FMPR_RND_FLOOR) fmpz_fdiv_q_2exp(z, fmpr_manref(x), exp); else if (rnd == FMPR_RND_CEIL) fmpz_cdiv_q_2exp(z, fmpr_manref(x), exp); } } arb-2.22.1/fmpr/get_fmpz_2exp.c000066400000000000000000000012131417376376500162430ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_get_fmpz_2exp(fmpz_t man, fmpz_t exp, const fmpr_t x) { if (fmpr_is_zero(x)) { fmpz_zero(man); fmpz_zero(exp); } else { fmpz_set(man, fmpr_manref(x)); fmpz_set(exp, fmpr_expref(x)); } } arb-2.22.1/fmpr/get_fmpz_fixed.c000066400000000000000000000020221417376376500164630ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int fmpr_get_fmpz_fixed_fmpz(fmpz_t y, const fmpr_t x, const fmpz_t exp) { slong shift; if (fmpr_is_zero(x)) { fmpz_zero(y); return 0; } shift = _fmpz_sub_small(fmpr_expref(x), exp); if (shift >= 0) { fmpz_mul_2exp(y, fmpr_manref(x), shift); return 0; } else { fmpz_tdiv_q_2exp(y, fmpr_manref(x), -shift); return 1; } } int fmpr_get_fmpz_fixed_si(fmpz_t y, const fmpr_t x, slong exp) { int result; fmpz_t t; fmpz_init(t); fmpz_set_si(t, exp); result = fmpr_get_fmpz_fixed_fmpz(y, x, t); fmpz_clear(t); return result; } arb-2.22.1/fmpr/get_mpfr.c000066400000000000000000000027461417376376500153110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int fmpr_get_mpfr(mpfr_t x, const fmpr_t y, mpfr_rnd_t rnd) { int r; if (fmpr_is_special(y)) { if (fmpr_is_zero(y)) mpfr_set_zero(x, 0); else if (fmpr_is_pos_inf(y)) mpfr_set_inf(x, 1); else if (fmpr_is_neg_inf(y)) mpfr_set_inf(x, -1); else mpfr_set_nan(x); r = 0; } else if (COEFF_IS_MPZ(*fmpr_expref(y))) { flint_printf("exception: exponent too large to convert to mpfr"); flint_abort(); r = 0; /* dummy return because flint_abort() is not declared noreturn */ } else { if (!COEFF_IS_MPZ(*fmpr_manref(y))) #if defined(__MINGW64__) || defined(_MSC_VER) r = mpfr_set_sj_2exp(x, *fmpr_manref(y), *fmpr_expref(y), rnd); #else r = mpfr_set_si_2exp(x, *fmpr_manref(y), *fmpr_expref(y), rnd); #endif else r = mpfr_set_z_2exp(x, COEFF_TO_PTR(*fmpr_manref(y)), *fmpr_expref(y), rnd); if (!mpfr_regular_p(x)) { flint_printf("exception: exponent too large to convert to mpfr"); flint_abort(); } } return r; } arb-2.22.1/fmpr/get_si.c000066400000000000000000000013251417376376500147500ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_get_si(const fmpr_t x, fmpr_rnd_t rnd) { fmpz_t t; slong v; fmpz_init(t); fmpr_get_fmpz(t, x, rnd); if (!fmpz_fits_si(t)) { flint_printf("fmpr_get_si: result does not fit in a signed slong\n"); flint_abort(); } v = fmpz_get_si(t); fmpz_clear(t); return v; } arb-2.22.1/fmpr/log.c000066400000000000000000000026331417376376500142620ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_log(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_neg_inf(y); else if (fmpr_is_pos_inf(x)) fmpr_pos_inf(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } else if (fmpr_sgn(x) < 0) { fmpr_nan(y); return FMPR_RESULT_EXACT; } else if (fmpr_is_one(x)) { fmpr_zero(y); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_log, y, x, prec, rnd); return r; } } slong fmpr_log1p(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_zero(y); else if (fmpr_is_pos_inf(x)) fmpr_pos_inf(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_log1p, y, x, prec, rnd); return r; } } arb-2.22.1/fmpr/mul.c000066400000000000000000000036131417376376500142750ustar00rootroot00000000000000/* Copyright (C) 2012, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_mul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpz xv, yv; if (fmpr_is_special(x) || fmpr_is_special(y)) { if (fmpr_is_zero(x) && fmpr_is_finite(y)) { fmpr_zero(z); } else if (fmpr_is_zero(y) && fmpr_is_finite(x)) { fmpr_zero(z); } else if ((fmpr_is_inf(x) && (fmpr_is_inf(y) || !fmpr_is_special(y))) || (fmpr_is_inf(y) && !fmpr_is_special(x))) { if (fmpr_sgn(x) == fmpr_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); } else { fmpr_nan(z); } return FMPR_RESULT_EXACT; } xv = *fmpr_manref(x); yv = *fmpr_manref(y); if (!COEFF_IS_MPZ(xv) && !COEFF_IS_MPZ(yv)) { return _fmpr_mul_1x1(z, FLINT_ABS(xv), fmpr_expref(x), FLINT_ABS(yv), fmpr_expref(y), (xv ^ yv) < 0, prec, rnd); } else { slong xn, yn; int xsign, ysign; mp_limb_t xtmp, ytmp; mp_ptr xptr, yptr; FMPZ_GET_MPN_READONLY(xsign, xn, xptr, xtmp, xv) FMPZ_GET_MPN_READONLY(ysign, yn, yptr, ytmp, yv) if (xn >= yn) return _fmpr_mul_mpn(z, xptr, xn, fmpr_expref(x), yptr, yn, fmpr_expref(y), xsign ^ ysign, prec, rnd); else return _fmpr_mul_mpn(z, yptr, yn, fmpr_expref(y), xptr, xn, fmpr_expref(x), ysign ^ xsign, prec, rnd); } } arb-2.22.1/fmpr/mul_1x1.c000066400000000000000000000070041417376376500147640ustar00rootroot00000000000000/* Copyright (C) 2013, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong _fmpr_mul_1x1(fmpr_t z, mp_limb_t u, const fmpz_t xexp, mp_limb_t v, const fmpz_t yexp, int negative, slong prec, fmpr_rnd_t rnd) { slong lead, trail, bc, shift, ret; mp_limb_t hi, lo; umul_ppmm(hi, lo, u, v); shift = 0; if (hi == 0) { /* 1 limb */ count_leading_zeros(lead, lo); bc = FLINT_BITS - lead; ret = FMPR_RESULT_EXACT; if (bc > prec) { shift += bc - prec; lo = (lo >> shift) + rounds_up(rnd, negative); count_trailing_zeros(trail, lo); lo >>= trail; shift += trail; ret = trail; /* special case: if the mantissa overflowed to the next power of two, the error bound must be multiplied by two */ ret -= (trail == prec); } if (!negative) fmpz_set_ui(fmpr_manref(z), lo); else fmpz_neg_ui(fmpr_manref(z), lo); } else { /* 2 limbs */ count_leading_zeros(lead, hi); bc = 2 * FLINT_BITS - lead; ret = FMPR_RESULT_EXACT; if (bc > prec) { shift += bc - prec; /* round */ if (shift < FLINT_BITS) { lo = (lo >> shift) | (hi << (FLINT_BITS - shift)); hi >>= shift; } else { lo = hi >> (shift - FLINT_BITS); hi = 0; } if (rounds_up(rnd, negative)) add_ssaaaa(hi, lo, hi, lo, 0, 1); /* remove trailing zeros */ if (lo == 0) { count_trailing_zeros(trail, hi); hi >>= trail; shift += FLINT_BITS + trail; ret = FLINT_BITS + trail; /* special case: if the mantissa overflowed to the next power of two, the error bound must be multiplied by two */ ret -= (FLINT_BITS + trail == prec); if (!negative) fmpz_set_ui(fmpr_manref(z), hi); else fmpz_neg_ui(fmpr_manref(z), hi); } else { count_trailing_zeros(trail, lo); if (trail != 0) { lo = (lo >> trail) | (hi << (FLINT_BITS - trail)); hi >>= trail; shift += trail; } ret = trail; /* special case: if the mantissa overflowed to the next power of two, the error bound must be multiplied by two */ ret -= (trail == prec); if (!negative) fmpz_set_uiui(fmpr_manref(z), hi, lo); else fmpz_neg_uiui(fmpr_manref(z), hi, lo); } } else { if (!negative) fmpz_set_uiui(fmpr_manref(z), hi, lo); else fmpz_neg_uiui(fmpr_manref(z), hi, lo); } } fmpz_add2_fmpz_si_inline(fmpr_expref(z), xexp, yexp, shift); return ret; } arb-2.22.1/fmpr/mul_fmpz.c000066400000000000000000000104641417376376500153330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_mul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpz xv, yv; fmpz yexp; if (fmpr_is_special(x) || fmpz_is_zero(y)) { if (fmpr_is_zero(x)) { fmpr_zero(z); } else if (fmpz_is_zero(y) && fmpr_is_finite(x)) { fmpr_zero(z); } else if (fmpr_is_inf(x) && !fmpz_is_zero(y)) { if (fmpr_sgn(x) == fmpz_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); } else { fmpr_nan(z); } return FMPR_RESULT_EXACT; } xv = *fmpr_manref(x); yv = *y; if (!COEFF_IS_MPZ(xv) && !COEFF_IS_MPZ(yv)) { mp_limb_t ytmp; unsigned int bc; ytmp = FLINT_ABS(yv); count_trailing_zeros(bc, ytmp); ytmp >>= bc; yexp = bc; return _fmpr_mul_1x1(z, FLINT_ABS(xv), fmpr_expref(x), ytmp, &yexp, (xv ^ yv) < 0, prec, rnd); } else { slong xn, yn; int xsign, ysign; mp_limb_t xtmp, ytmp; mp_ptr xptr, yptr; yexp = 0; FMPZ_GET_MPN_READONLY(xsign, xn, xptr, xtmp, xv) FMPZ_GET_MPN_READONLY(ysign, yn, yptr, ytmp, yv) if (xn >= yn) return _fmpr_mul_mpn(z, xptr, xn, fmpr_expref(x), yptr, yn, &yexp, xsign ^ ysign, prec, rnd); else return _fmpr_mul_mpn(z, yptr, yn, &yexp, xptr, xn, fmpr_expref(x), ysign ^ xsign, prec, rnd); } } slong fmpr_mul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpz xv; fmpz yexp; slong xn; int xsign, ysign; mp_limb_t xtmp, ytmp; mp_ptr xptr; if (fmpr_is_special(x) || (y == 0)) { if (fmpr_is_zero(x)) { fmpr_zero(z); } else if ((y == 0) && fmpr_is_finite(x)) { fmpr_zero(z); } else if (fmpr_is_inf(x) && (y != 0)) { if (fmpr_sgn(x) == ((y > 0) - (y < 0))) fmpr_pos_inf(z); else fmpr_neg_inf(z); } else { fmpr_nan(z); } return FMPR_RESULT_EXACT; } xv = *fmpr_manref(x); ytmp = FLINT_ABS(y); ysign = y < 0; yexp = 0; if (!COEFF_IS_MPZ(xv)) { unsigned int bc; count_trailing_zeros(bc, ytmp); ytmp >>= bc; yexp = bc; return _fmpr_mul_1x1(z, FLINT_ABS(xv), fmpr_expref(x), ytmp, &yexp, (xv < 0) ^ ysign, prec, rnd); } else { FMPZ_GET_MPN_READONLY(xsign, xn, xptr, xtmp, xv) return _fmpr_mul_mpn(z, xptr, xn, fmpr_expref(x), &ytmp, 1, &yexp, xsign ^ ysign, prec, rnd); } } slong fmpr_mul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) { fmpz xv; fmpz yexp; slong xn; int xsign; mp_limb_t xtmp, ytmp; mp_ptr xptr; if (fmpr_is_special(x) || (y == 0)) { if (fmpr_is_zero(x)) { fmpr_zero(z); } else if ((y == 0) && fmpr_is_finite(x)) { fmpr_zero(z); } else if (fmpr_is_inf(x) && (y != 0)) { if (fmpr_sgn(x) == (y != 0)) fmpr_pos_inf(z); else fmpr_neg_inf(z); } else { fmpr_nan(z); } return FMPR_RESULT_EXACT; } xv = *fmpr_manref(x); ytmp = y; yexp = 0; if (!COEFF_IS_MPZ(xv)) { unsigned int bc; count_trailing_zeros(bc, ytmp); ytmp >>= bc; yexp = bc; return _fmpr_mul_1x1(z, FLINT_ABS(xv), fmpr_expref(x), ytmp, &yexp, xv < 0, prec, rnd); } else { FMPZ_GET_MPN_READONLY(xsign, xn, xptr, xtmp, xv) return _fmpr_mul_mpn(z, xptr, xn, fmpr_expref(x), &ytmp, 1, &yexp, xsign, prec, rnd); } } arb-2.22.1/fmpr/mul_mpn.c000066400000000000000000000040101417376376500151370ustar00rootroot00000000000000/* Copyright (C) 2013, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" #define MUL_STACK_ALLOC 40 #define MUL_TLS_ALLOC 1000 TLS_PREFIX mp_ptr __mul_tmp = NULL; TLS_PREFIX slong __mul_alloc = 0; void _mul_tmp_cleanup(void) { flint_free(__mul_tmp); __mul_tmp = NULL; __mul_alloc = 0; } #define MUL_TMP_ALLOC \ if (alloc <= MUL_STACK_ALLOC) \ { \ tmp = tmp_stack; \ } \ else if (alloc <= MUL_TLS_ALLOC) \ { \ if (__mul_alloc < alloc) \ { \ if (__mul_alloc == 0) \ { \ flint_register_cleanup_function(_mul_tmp_cleanup); \ } \ __mul_tmp = flint_realloc(__mul_tmp, sizeof(mp_limb_t) * alloc); \ __mul_alloc = alloc; \ } \ tmp = __mul_tmp; \ } \ else \ { \ tmp = flint_malloc(sizeof(mp_limb_t) * alloc); \ } #define MUL_TMP_FREE \ if (alloc > MUL_TLS_ALLOC) \ flint_free(tmp); slong _fmpr_mul_mpn(fmpr_t z, mp_srcptr xman, mp_size_t xn, const fmpz_t xexp, mp_srcptr yman, mp_size_t yn, const fmpz_t yexp, int negative, slong prec, fmpr_rnd_t rnd) { slong zn, alloc, ret, shift; mp_limb_t tmp_stack[MUL_STACK_ALLOC]; mp_ptr tmp; zn = xn + yn; alloc = zn; MUL_TMP_ALLOC if (yn == 1) { mp_limb_t cy = mpn_mul_1(tmp, xman, xn, yman[0]); tmp[zn - 1] = cy; zn = zn - (cy == 0); } else { mpn_mul(tmp, xman, xn, yman, yn); zn = zn - (tmp[zn - 1] == 0); } ret = _fmpr_set_round_mpn(&shift, fmpr_manref(z), tmp, zn, negative, prec, rnd); fmpz_add2_fmpz_si_inline(fmpr_expref(z), xexp, yexp, shift); MUL_TMP_FREE return ret; } arb-2.22.1/fmpr/mul_naive.c000066400000000000000000000027311417376376500154570ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" static void _fmpr_mul_special(fmpr_t z, const fmpr_t x, const fmpr_t y) { if (fmpr_is_zero(x)) { if (!fmpr_is_special(y) || fmpr_is_zero(y)) fmpr_zero(z); else fmpr_nan(z); return; } if (fmpr_is_zero(y)) { if (!fmpr_is_special(x)) fmpr_zero(z); else fmpr_nan(z); return; } if ((fmpr_is_inf(x) && (fmpr_is_inf(y) || !fmpr_is_special(y))) || (fmpr_is_inf(y) && !fmpr_is_special(x))) { if (fmpr_sgn(x) == fmpr_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); return; } fmpr_nan(z); } slong fmpr_mul_naive(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x) || fmpr_is_special(y)) { _fmpr_mul_special(z, x, y); return FMPR_RESULT_EXACT; } fmpz_mul(fmpr_manref(z), fmpr_manref(x), fmpr_manref(y)); fmpz_add(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y)); return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); } arb-2.22.1/fmpr/normalise.c000066400000000000000000000037151417376376500154740ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong _fmpr_normalise_naive(fmpz_t man, fmpz_t exp, slong prec, fmpr_rnd_t rnd) { /* TODO: this should perhaps raise an exception to avoid ambiguity */ if (fmpz_is_zero(man)) { fmpz_zero(exp); return FMPR_RESULT_EXACT; } else { slong bc, val; bc = fmpz_bits(man); val = fmpz_val2(man); if (bc - val <= prec) { if (val != 0) { fmpz_tdiv_q_2exp(man, man, val); fmpz_add_ui(exp, exp, val); } return FMPR_RESULT_EXACT; } else { slong exp_shift = bc - prec; if (rnd == FMPR_RND_NEAR) { flint_abort(); } else if (rnd == FMPR_RND_DOWN) { fmpz_tdiv_q_2exp(man, man, exp_shift); } else if (rnd == FMPR_RND_FLOOR) { fmpz_fdiv_q_2exp(man, man, exp_shift); } else if (rnd == FMPR_RND_CEIL) { fmpz_cdiv_q_2exp(man, man, exp_shift); } else { if (fmpz_sgn(man) > 0) fmpz_cdiv_q_2exp(man, man, exp_shift); else fmpz_fdiv_q_2exp(man, man, exp_shift); } val = fmpz_val2(man); exp_shift += val; if (val != 0) fmpz_tdiv_q_2exp(man, man, val); fmpz_add_ui(exp, exp, exp_shift); return val - (val == prec); } } } arb-2.22.1/fmpr/pow_sloppy.c000066400000000000000000000034511417376376500157130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" /* TODO: correct rounding with negative b */ void fmpr_pow_sloppy_fmpz(fmpr_t y, const fmpr_t b, const fmpz_t e, slong prec, fmpr_rnd_t rnd) { slong i, wp, bits; if (fmpz_is_zero(e)) { fmpr_set_ui(y, UWORD(1)); return; } if (fmpz_sgn(e) < 0) { fmpz_t f; fmpz_init(f); fmpz_neg(f, e); fmpr_pow_sloppy_fmpz(y, b, f, prec + 2, (rnd == FMPR_RND_FLOOR || rnd == FMPR_RND_DOWN) ? FMPR_RND_UP : FMPR_RND_DOWN); fmpr_ui_div(y, UWORD(1), y, prec, rnd); fmpz_clear(f); return; } if (y == b) { fmpr_t t; fmpr_init(t); fmpr_set(t, b); fmpr_pow_sloppy_fmpz(y, t, e, prec, rnd); fmpr_clear(t); return; } fmpr_set(y, b); bits = fmpz_bits(e); wp = FMPR_PREC_ADD(prec, bits); for (i = bits - 2; i >= 0; i--) { fmpr_mul(y, y, y, wp, rnd); if (fmpz_tstbit(e, i)) fmpr_mul(y, y, b, wp, rnd); } } void fmpr_pow_sloppy_ui(fmpr_t y, const fmpr_t b, ulong e, slong prec, fmpr_rnd_t rnd) { fmpz_t f; fmpz_init_set_ui(f, e); fmpr_pow_sloppy_fmpz(y, b, f, prec, rnd); fmpz_clear(f); } void fmpr_pow_sloppy_si(fmpr_t y, const fmpr_t b, slong e, slong prec, fmpr_rnd_t rnd) { fmpz_t f; fmpz_init(f); fmpz_set_si(f, e); fmpr_pow_sloppy_fmpz(y, b, f, prec, rnd); fmpz_clear(f); } arb-2.22.1/fmpr/print.c000066400000000000000000000015341417376376500146340ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_print(const fmpr_t x) { if (fmpr_is_normal(x)) { flint_printf("("); fmpz_print(fmpr_manref(x)); flint_printf(" * 2^"); fmpz_print(fmpr_expref(x)); flint_printf(")"); } else { if (fmpr_is_zero(x)) flint_printf("(0)"); else if (fmpr_is_pos_inf(x)) flint_printf("(+inf)"); else if (fmpr_is_neg_inf(x)) flint_printf("(-inf)"); else flint_printf("(nan)"); } } arb-2.22.1/fmpr/printd.c000066400000000000000000000012451417376376500147770ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_printd(const fmpr_t x, slong digits) { mpfr_t t; mpfr_init2(t, digits * 3.33 + 10); mpfr_set_emin(MPFR_EMIN_MIN); mpfr_set_emax(MPFR_EMAX_MAX); fmpr_get_mpfr(t, x, MPFR_RNDN); mpfr_printf("%.*Rg", FLINT_MAX(digits, 1), t); mpfr_clear(t); } arb-2.22.1/fmpr/randtest.c000066400000000000000000000030101417376376500153130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_randtest(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) { fmpz_randtest(fmpr_manref(x), state, bits); fmpz_randtest(fmpr_expref(x), state, mag_bits); fmpz_sub_ui(fmpr_expref(x), fmpr_expref(x), fmpz_bits(fmpr_manref(x))); _fmpr_normalise(fmpr_manref(x), fmpr_expref(x), bits, FMPR_RND_DOWN); } void fmpr_randtest_not_zero(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) { fmpz_randtest_not_zero(fmpr_manref(x), state, bits); fmpz_randtest(fmpr_expref(x), state, mag_bits); fmpz_sub_ui(fmpr_expref(x), fmpr_expref(x), fmpz_bits(fmpr_manref(x))); _fmpr_normalise(fmpr_manref(x), fmpr_expref(x), bits, FMPR_RND_DOWN); } void fmpr_randtest_special(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) { switch (n_randint(state, 32)) { case 0: fmpr_zero(x); break; case 1: fmpr_pos_inf(x); break; case 2: fmpr_neg_inf(x); break; case 3: fmpr_nan(x); break; default: fmpr_randtest_not_zero(x, state, bits, mag_bits); } } arb-2.22.1/fmpr/root.c000066400000000000000000000032471417376376500144660ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_root(fmpr_t y, const fmpr_t x, ulong k, slong prec, fmpr_rnd_t rnd) { slong r; if (k == 0) { fmpr_nan(y); return FMPR_RESULT_EXACT; } else if (k == 1) { return fmpr_set_round(y, x, prec, rnd); } else if (k == 2) { return fmpr_sqrt(y, x, prec, rnd); } if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_zero(y); else if (fmpr_is_pos_inf(x)) fmpr_pos_inf(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } if (fmpr_sgn(x) < 0) { fmpr_nan(y); return FMPR_RESULT_EXACT; } { fmpr_t t; fmpz_t a, b; fmpr_init(t); fmpz_init(a); fmpz_init(b); /* (m * 2^(aq+b))^(1/q) = (m*2^b)^(1/q) * 2^a */ fmpz_set_ui(a, k); fmpz_fdiv_qr(a, b, fmpr_expref(x), a); fmpz_set(fmpr_manref(t), fmpr_manref(x)); fmpz_set(fmpr_expref(t), b); #if MPFR_VERSION_MAJOR >= 4 CALL_MPFR_FUNC_K(r, mpfr_rootn_ui, y, t, k, prec, rnd); #else CALL_MPFR_FUNC_K(r, mpfr_root, y, t, k, prec, rnd); #endif fmpr_mul_2exp_fmpz(y, y, a); fmpr_clear(t); fmpz_clear(a); fmpz_clear(b); return r; } } arb-2.22.1/fmpr/rsqrt.c000066400000000000000000000027721417376376500146600ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_rsqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { slong r; if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_pos_inf(y); else if (fmpr_is_pos_inf(x)) fmpr_zero(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } if (fmpr_sgn(x) < 0) { fmpr_nan(y); return FMPR_RESULT_EXACT; } /* special case: 4^n */ if (fmpz_is_one(fmpr_manref(x)) && fmpz_is_even(fmpr_expref(x))) { r = fmpr_set_round(y, x, prec, rnd); fmpz_tdiv_q_2exp(fmpr_expref(y), fmpr_expref(y), 1); fmpz_neg(fmpr_expref(y), fmpr_expref(y)); return r; } { fmpr_t t; fmpz_t e; fmpr_init(t); fmpz_init(e); fmpz_neg(e, fmpr_expref(x)); if (fmpz_is_odd(e)) fmpz_add_ui(e, e, 1); fmpr_mul_2exp_fmpz(t, x, e); CALL_MPFR_FUNC(r, mpfr_rec_sqrt, y, t, prec, rnd); fmpz_tdiv_q_2exp(e, e, 1); fmpr_mul_2exp_fmpz(y, y, e); fmpr_clear(t); fmpz_clear(e); return r; } } arb-2.22.1/fmpr/set_d.c000066400000000000000000000031741417376376500146000ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "fmpr.h" void fmpr_set_d(fmpr_t x, double v) { #if FLINT_BITS == 64 mp_limb_t h, sign, exp, frac; slong real_exp, real_man; union { double uf; mp_limb_t ul; } u; u.uf = v; h = u.ul; sign = h >> 63; exp = (h << 1) >> 53; frac = (h << 12) >> 12; if (exp == 0 && frac == 0) { fmpr_zero(x); return; } else if (exp == 0x7ff) { if (frac == 0) { if (sign) fmpr_neg_inf(x); else fmpr_pos_inf(x); } else { fmpr_nan(x); } return; } /* handle subnormals */ if (exp == 0 && frac != 0) { int exp2; v = frexp(v, &exp2); u.uf = v; h = u.ul; sign = h >> 63; exp = (h << 1) >> 53; frac = (h << 12) >> 12; exp += exp2; } real_exp = exp - 1023 - 52; frac |= (UWORD(1) << 52); real_man = sign ? (-frac) : frac; fmpr_set_si_2exp_si(x, real_man, real_exp); #else mpfr_t t; mp_limb_t tmp[2]; t->_mpfr_prec = 53; t->_mpfr_sign = 1; t->_mpfr_exp = 0; t->_mpfr_d = tmp; mpfr_set_d(t, v, MPFR_RNDD); fmpr_set_mpfr(x, t); #endif } arb-2.22.1/fmpr/set_fmpq.c000066400000000000000000000016001417376376500153100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_set_fmpq(fmpr_t x, const fmpq_t y, slong prec, fmpr_rnd_t rnd) { if (fmpz_is_one(fmpq_denref(y))) { return fmpr_set_round_fmpz(x, fmpq_numref(y), prec, rnd); } else { slong res; fmpr_t t, u; fmpr_init(t); fmpr_init(u); fmpr_set_fmpz(t, fmpq_numref(y)); fmpr_set_fmpz(u, fmpq_denref(y)); res = fmpr_div(x, t, u, prec, rnd); fmpr_clear(t); fmpr_clear(u); return res; } } arb-2.22.1/fmpr/set_fmpz_2exp.c000066400000000000000000000012011417376376500162540ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_set_fmpz_2exp(fmpr_t x, const fmpz_t man, const fmpz_t exp) { if (fmpz_is_zero(man)) { fmpr_zero(x); } else { fmpr_set_fmpz(x, man); fmpz_add(fmpr_expref(x), fmpr_expref(x), exp); } } arb-2.22.1/fmpr/set_mpfr.c000066400000000000000000000017011417376376500153130ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_set_mpfr(fmpr_t x, const mpfr_t y) { if (!mpfr_regular_p(y)) { if (mpfr_zero_p(y)) fmpr_zero(x); else if (mpfr_inf_p(y) && mpfr_sgn(y) > 0) fmpr_pos_inf(x); else if (mpfr_inf_p(y) && mpfr_sgn(y) < 0) fmpr_neg_inf(x); else fmpr_nan(x); } else { __mpz_struct * z = _fmpz_promote(fmpr_manref(x)); fmpz_set_si(fmpr_expref(x), mpfr_get_z_2exp(z, y)); _fmpz_demote_val(fmpr_manref(x)); _fmpr_normalise(fmpr_manref(x), fmpr_expref(x), y->_mpfr_prec, FMPR_RND_DOWN); } } arb-2.22.1/fmpr/set_round.c000066400000000000000000000123531417376376500155030ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" /* like mpn_scan0b, but takes an upper size */ static __inline__ flint_bitcnt_t mpn_scan0b(mp_srcptr up, mp_size_t size, flint_bitcnt_t from_bit) { mp_limb_t t; slong i, c; i = from_bit / GMP_NUMB_BITS; c = from_bit % FLINT_BITS; t = ((~up[i]) >> c) << c; while (t == 0) { i++; if (i == size) return size * FLINT_BITS; else t = ~up[i]; } count_trailing_zeros(c, t); return (i * FLINT_BITS) + c; } slong _fmpr_set_round(fmpz_t rman, fmpz_t rexp, const fmpz_t man, const fmpz_t exp, slong prec, fmpr_rnd_t rnd) { if (!COEFF_IS_MPZ(*man)) { slong lead, trail, bc, v, w, shift, ret; int negative; v = *man; count_trailing_zeros(trail, v); v >>= trail; shift = trail; ret = FMPR_RESULT_EXACT; /* may need to round */ if (prec < FLINT_BITS - 2 - trail) { if (v < 0) { negative = 1; w = -v; } else { negative = 0; w = v; } count_leading_zeros(lead, w); bc = FLINT_BITS - lead; /* round */ if (prec < bc) { w = (w >> (bc - prec)) + rounds_up(rnd, negative); shift += bc - prec; count_trailing_zeros(trail, w); w >>= trail; shift += trail; v = negative ? -w : w; ret = trail; /* special case: if w overflowed to the next power of two, the error bound must be multiplied by 2 */ ret -= (trail == prec); } } /* the input is small, so the output must be small too */ _fmpz_demote(rman); *rman = v; fmpz_add_ui_inline(rexp, exp, shift); return ret; } else { slong size, bc, val, val_bits, val_limbs, ret; int negative, increment; mp_ptr d; __mpz_struct * z = COEFF_TO_PTR(*man); size = z->_mp_size; negative = size < 0; size = FLINT_ABS(size); d = z->_mp_d; /* bit size */ count_leading_zeros(bc, d[size - 1]); bc = FLINT_BITS - bc; bc += (size - 1) * FLINT_BITS; /* quick exit */ if (bc <= prec && (d[0] & 1)) { if (rman != man) fmpz_set(rman, man); if (rexp != exp) fmpz_set(rexp, exp); return FMPR_RESULT_EXACT; } /* trailing zeros */ val_limbs = 0; while (d[val_limbs] == 0) val_limbs++; count_trailing_zeros(val_bits, d[val_limbs]); val = val_bits + (val_limbs * FLINT_BITS); /* no rounding necessary; just copy or shift to destination */ if (bc - val <= prec) { ret = FMPR_RESULT_EXACT; increment = 0; } else { /* truncation */ if (!rounds_up(rnd, negative)) { val = mpn_scan1(d, bc - prec); increment = 0; } /* round to next higher odd mantissa */ else { val = mpn_scan0b(d, size, bc - prec); /* can overflow to next power of 2 */ if (val == bc) { fmpz_set_si(rman, negative ? -1 : 1); fmpz_add_ui_inline(rexp, exp, bc); return prec - 1; } /* otherwise, incrementing will not cause overflow below */ increment = 1; } val_limbs = val / FLINT_BITS; val_bits = val % FLINT_BITS; ret = prec - (bc - val); } /* the output mantissa is a small fmpz */ if (bc - val <= FLINT_BITS - 2) { mp_limb_t h; if (val_limbs + 1 == size || val_bits == 0) h = d[val_limbs] >> val_bits; else h = (d[val_limbs] >> val_bits) | (d[val_limbs + 1] << (FLINT_BITS - val_bits)); h += increment; _fmpz_demote(rman); *rman = negative ? -h : h; } /* the output mantissa is an mpz */ else { if (rman == man) { mpz_tdiv_q_2exp(z, z, val); if (increment) z->_mp_d[0]++; } else { __mpz_struct * w = _fmpz_promote(rman); /* must reload pointer, as promoting rman could change it */ z = COEFF_TO_PTR(*man); mpz_tdiv_q_2exp(w, z, val); if (increment) w->_mp_d[0]++; } } fmpz_add_ui_inline(rexp, exp, val); return ret; } } arb-2.22.1/fmpr/set_round_mpn.c000066400000000000000000000101741417376376500163540ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" /* like mpn_scan0, but takes an upper size */ static __inline__ flint_bitcnt_t mpn_scan0b(mp_srcptr up, mp_size_t size, flint_bitcnt_t from_bit) { mp_limb_t t; slong i, c; i = from_bit / GMP_NUMB_BITS; c = from_bit % FLINT_BITS; t = ((~up[i]) >> c) << c; while (t == 0) { i++; if (i == size) return size * FLINT_BITS; else t = ~up[i]; } count_trailing_zeros(c, t); return (i * FLINT_BITS) + c; } slong _fmpr_set_round_mpn(slong * shift, fmpz_t man, mp_srcptr x, mp_size_t xn, int negative, slong prec, fmpr_rnd_t rnd) { slong bc, val, val_bits, val_limbs, ret; int increment; /* compute the total bit length of x */ count_leading_zeros(bc, x[xn - 1]); bc = FLINT_BITS - bc; bc += (xn - 1) * FLINT_BITS; /* already odd */ if (x[0] & 1) { /* quick exit */ if (bc <= prec) { if (bc <= FLINT_BITS - 2) { mp_limb_t t = x[0]; _fmpz_demote(man); *man = negative ? -t : t; } else fmpz_set_mpn_large(man, x, xn, negative); *shift = 0; return FMPR_RESULT_EXACT; } else { val_limbs = val_bits = val = 0; } } else { /* trailing zero bits: val = val_limbs * FLINT_BITS + val_bits */ val_limbs = 0; while (x[val_limbs] == 0) val_limbs++; count_trailing_zeros(val_bits, x[val_limbs]); val = val_bits + (val_limbs * FLINT_BITS); } /* no rounding necessary; just copy or shift to destination */ if (bc - val <= prec) { ret = FMPR_RESULT_EXACT; increment = 0; } else { /* truncation */ if (!rounds_up(rnd, negative)) { val = mpn_scan1(x, bc - prec); increment = 0; } /* round to next higher odd mantissa */ else { val = mpn_scan0b(x, xn, bc - prec); /* can overflow to next power of 2 */ if (val == bc) { fmpz_set_si(man, negative ? -1 : 1); *shift = bc; return prec - 1; } /* otherwise, we are cutting off at a zero bit, and incrementing at that position will not cause carry propagation below */ increment = 1; } val_limbs = val / FLINT_BITS; val_bits = val % FLINT_BITS; ret = prec - (bc - val); } /* the output mantissa is a small fmpz */ if (bc - val <= FLINT_BITS - 2) { mp_limb_t h; if (val_limbs + 1 == xn || val_bits == 0) h = x[val_limbs] >> val_bits; else h = (x[val_limbs] >> val_bits) | (x[val_limbs + 1] << (FLINT_BITS - val_bits)); h += increment; _fmpz_demote(man); *man = negative ? -h : h; } /* the output mantissa is an mpz */ else { mp_ptr dest; slong res_limbs, res_alloc; __mpz_struct * zptr = _fmpz_promote(man); res_limbs = ((bc - val) + FLINT_BITS - 1) / FLINT_BITS; /* todo: only allocate the required size, not the size before shifting */ res_alloc = xn - val_limbs; if (zptr->_mp_alloc < res_alloc) mpz_realloc2(zptr, res_alloc * FLINT_BITS); dest = zptr->_mp_d; /* right shift by val */ if (val_bits == 0) flint_mpn_copyi(dest, x + val_limbs, res_limbs); else mpn_rshift(dest, x + val_limbs, xn - val_limbs, val_bits); dest[0] += increment; zptr->_mp_size = negative ? -res_limbs : res_limbs; } *shift = val; return ret; } arb-2.22.1/fmpr/set_round_ui_2exp_fmpz.c000066400000000000000000000027561417376376500202000ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_set_round_ui_2exp_fmpz(fmpr_t z, mp_limb_t lo, const fmpz_t exp, int negative, slong prec, fmpr_rnd_t rnd) { slong lead, trail, bc, shift, shift2, ret; shift = 0; if ((lo & 1) == 0) { if (lo == 0) { fmpr_zero(z); return FMPR_RESULT_EXACT; } count_trailing_zeros(trail, lo); lo >>= trail; shift = trail; } count_leading_zeros(lead, lo); bc = FLINT_BITS - lead; ret = FMPR_RESULT_EXACT; if (bc > prec) { shift2 = bc - prec; lo = (lo >> shift2) + rounds_up(rnd, negative); count_trailing_zeros(trail, lo); lo >>= trail; shift += shift2; shift += trail; ret = trail; /* special case: if the mantissa overflowed to the next power of two, the error bound must be multiplied by two */ ret -= (trail == prec); } if (!negative) fmpz_set_ui(fmpr_manref(z), lo); else fmpz_neg_ui(fmpr_manref(z), lo); fmpz_add_si_inline(fmpr_expref(z), exp, shift); return ret; } arb-2.22.1/fmpr/set_round_uiui_2exp_fmpz.c000066400000000000000000000067011417376376500205300ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_set_round_uiui_2exp_fmpz(fmpr_t z, mp_limb_t hi, mp_limb_t lo, const fmpz_t exp, int negative, slong prec, fmpr_rnd_t rnd) { if (hi == 0) { return fmpr_set_round_ui_2exp_fmpz(z, lo, exp, negative, prec, rnd); } else { /* 2 limbs */ slong lead, trail, bc, shift, ret; if ((lo & 1) == 0) { if (lo == 0) { shift = FLINT_BITS; ret = fmpr_set_round_ui_2exp_fmpz(z, hi, exp, negative, prec, rnd); } else { count_trailing_zeros(shift, lo); lo = (hi << (FLINT_BITS - shift)) | lo >> shift; hi = hi >> shift; ret = fmpr_set_round_uiui_2exp_fmpz(z, hi, lo, exp, negative, prec, rnd); } fmpz_add_si_inline(fmpr_expref(z), fmpr_expref(z), shift); return ret; } count_leading_zeros(lead, hi); bc = 2 * FLINT_BITS - lead; shift = 0; ret = FMPR_RESULT_EXACT; if (bc > prec) { shift = bc - prec; /* round */ if (shift < FLINT_BITS) { lo = (lo >> shift) | (hi << (FLINT_BITS - shift)); hi >>= shift; } else { lo = hi >> (shift - FLINT_BITS); hi = 0; } if (rounds_up(rnd, negative)) add_ssaaaa(hi, lo, hi, lo, 0, 1); /* remove trailing zeros */ if (lo == 0) { count_trailing_zeros(trail, hi); hi >>= trail; shift += FLINT_BITS + trail; ret = FLINT_BITS + trail; /* special case: if the mantissa overflowed to the next power of two, the error bound must be multiplied by two */ ret -= (trail + FLINT_BITS == prec); if (!negative) fmpz_set_ui(fmpr_manref(z), hi); else fmpz_neg_ui(fmpr_manref(z), hi); } else { count_trailing_zeros(trail, lo); if (trail != 0) { lo = (lo >> trail) | (hi << (FLINT_BITS - trail)); hi >>= trail; shift += trail; } ret = trail; /* special case: if the mantissa overflowed to the next power of two, the error bound must be multiplied by two */ ret -= (trail == prec); if (!negative) fmpz_set_uiui(fmpr_manref(z), hi, lo); else fmpz_neg_uiui(fmpr_manref(z), hi, lo); } } else { if (!negative) fmpz_set_uiui(fmpr_manref(z), hi, lo); else fmpz_neg_uiui(fmpr_manref(z), hi, lo); } fmpz_add_si_inline(fmpr_expref(z), exp, shift); return ret; } } arb-2.22.1/fmpr/sqrt.c000066400000000000000000000030341417376376500144660ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_sqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { slong r; if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_zero(y); else if (fmpr_is_pos_inf(x)) fmpr_pos_inf(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } if (fmpr_sgn(x) < 0) { fmpr_nan(y); return FMPR_RESULT_EXACT; } /* special case: 4^n */ /* TODO: process all small exact square roots efficiently */ if (fmpz_is_one(fmpr_manref(x)) && fmpz_is_even(fmpr_expref(x))) { r = fmpr_set_round(y, x, prec, rnd); fmpz_tdiv_q_2exp(fmpr_expref(y), fmpr_expref(y), 1); return r; } { fmpr_t t; fmpz_t e; fmpr_init(t); fmpz_init(e); fmpz_neg(e, fmpr_expref(x)); if (fmpz_is_odd(e)) fmpz_add_ui(e, e, 1); fmpr_mul_2exp_fmpz(t, x, e); CALL_MPFR_FUNC(r, mpfr_sqrt, y, t, prec, rnd); fmpz_neg(e, e); fmpz_tdiv_q_2exp(e, e, 1); fmpr_mul_2exp_fmpz(y, y, e); fmpr_clear(t); fmpz_clear(e); return r; } } arb-2.22.1/fmpr/sub.c000066400000000000000000000056451417376376500143000ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" static slong _fmpr_sub_special(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_zero(x)) { return fmpr_neg_round(z, y, prec, rnd); } else if (fmpr_is_zero(y)) { return fmpr_set_round(z, x, prec, rnd); } else if (fmpr_is_nan(x) || fmpr_is_nan(y) || (fmpr_is_pos_inf(x) && fmpr_is_pos_inf(y)) || (fmpr_is_neg_inf(x) && fmpr_is_neg_inf(y))) { fmpr_nan(z); return FMPR_RESULT_EXACT; } else if (fmpr_is_special(x)) { fmpr_set(z, x); return FMPR_RESULT_EXACT; } else { fmpr_neg(z, y); return FMPR_RESULT_EXACT; } } slong fmpr_sub(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { slong shift, xn, yn; mp_limb_t xtmp, ytmp; mp_ptr xptr, yptr; fmpz xv, yv; const fmpz * xexp; const fmpz * yexp; int xsign, ysign; if (fmpr_is_special(x) || fmpr_is_special(y)) { return _fmpr_sub_special(z, x, y, prec, rnd); } shift = _fmpz_sub_small(fmpr_expref(y), fmpr_expref(x)); if (shift >= 0) { xexp = fmpr_expref(x); yexp = fmpr_expref(y); xv = *fmpr_manref(x); yv = *fmpr_manref(y); } else { xexp = fmpr_expref(y); yexp = fmpr_expref(x); xv = *fmpr_manref(y); yv = *fmpr_manref(x); } FMPZ_GET_MPN_READONLY(xsign, xn, xptr, xtmp, xv) FMPZ_GET_MPN_READONLY(ysign, yn, yptr, ytmp, yv) if (shift >= 0) { ysign = !ysign; } else { shift = -shift; xsign = !xsign; } if ((xn == 1) && (yn == 1) && (shift < FLINT_BITS)) return _fmpr_add_1x1(z, xptr[0], xsign, xexp, yptr[0], ysign, yexp, shift, prec, rnd); else return _fmpr_add_mpn(z, xptr, xn, xsign, xexp, yptr, yn, ysign, yexp, shift, prec, rnd); } slong fmpr_sub_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_ui(t, y); r = fmpr_sub(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_sub_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, y); r = fmpr_sub(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_sub_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, y); r = fmpr_sub(z, x, t, prec, rnd); fmpr_clear(t); return r; } arb-2.22.1/fmpr/submul.c000066400000000000000000000025121417376376500150040ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" slong fmpr_submul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_mul(t, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); r = fmpr_sub(z, z, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_submul_ui(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_ui(t, y); r = fmpr_submul(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_submul_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, y); r = fmpr_submul(z, x, t, prec, rnd); fmpr_clear(t); return r; } slong fmpr_submul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, y); r = fmpr_submul(z, x, t, prec, rnd); fmpr_clear(t); return r; } arb-2.22.1/fmpr/test/000077500000000000000000000000001417376376500143105ustar00rootroot00000000000000arb-2.22.1/fmpr/test/t-add.c000066400000000000000000000173141417376376500154530ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("add...."); fflush(stdout); flint_randinit(state); /* test exact addition: (x + y) + z == x + (y + z) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, res1, res2, res3, res4; fmpr_t x, y, z, t, u; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(t); fmpr_init(u); fmpr_randtest_special(x, state, bits, 10); fmpr_randtest_special(y, state, bits, 10); fmpr_randtest_special(z, state, bits, 10); fmpr_randtest_special(t, state, bits, 10); fmpr_randtest_special(u, state, bits, 10); res1 = fmpr_add(t, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); res2 = fmpr_add(t, t, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res3 = fmpr_add(u, y, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res4 = fmpr_add(u, x, u, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (!fmpr_equal(t, u) || res1 != FMPR_RESULT_EXACT || res2 != FMPR_RESULT_EXACT || res3 != FMPR_RESULT_EXACT || res4 != FMPR_RESULT_EXACT) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("t = "); fmpr_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpr_print(u); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(t); fmpr_clear(u); } /* compare with add_naive */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong prec, ret1, ret2; fmpr_t x, y, z, w; fmpr_rnd_t rnd; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); fmpr_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); fmpr_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); fmpr_randtest_special(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); prec = 2 + n_randint(state, 1000); if (n_randint(state, 10) == 0 && fmpz_bits(fmpr_expref(x)) < 10 && fmpz_bits(fmpr_expref(y)) < 10) prec = FMPR_PREC_EXACT; switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } ret1 = fmpr_add(z, x, y, prec, rnd); ret2 = fmpr_add_naive(w, x, y, prec, rnd); if (!fmpr_equal(z, w) || ret1 != ret2 || !fmpr_check_ulp(z, ret1, prec) || !fmpr_check_ulp(w, ret2, prec)) { flint_printf("FAIL\n\n"); flint_printf("iter %wd\n", iter); flint_printf("prec = %wd\n", prec); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_printf("ret1 = %wd, ret2 = %wd\n", ret1, ret2); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); } /* compare rounding with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits, res; int mpfr_res; fmpr_t x, y, z, w; mpfr_t X, Y, Z; bits = 2 + n_randint(state, 500); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 500); mpfr_init2(Y, bits + 500); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 500), 10); fmpr_randtest_special(y, state, bits + n_randint(state, 500), 10); fmpr_randtest_special(z, state, bits, 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDZ); res = fmpr_add(z, x, y, bits, FMPR_RND_DOWN); break; case 1: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDA); res = fmpr_add(z, x, y, bits, FMPR_RND_UP); break; case 2: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDD); res = fmpr_add(z, x, y, bits, FMPR_RND_FLOOR); break; default: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDU); res = fmpr_add(z, x, y, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || (res == FMPR_RESULT_EXACT) != (mpfr_res == 0) || !fmpr_check_ulp(z, res, bits)) { flint_printf("FAIL\n\n"); flint_printf("iter %wd\n", iter); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_printf("returned: %wd, %d\n", res, mpfr_res); flint_abort(); } /* check error bound */ if (!fmpr_is_nan(z) && !fmpr_is_inf(z)) { fmpr_t z_exact, error_bound, true_error; fmpr_init(z_exact); fmpr_init(error_bound); fmpr_init(true_error); fmpr_set_error_result(error_bound, z, res); fmpr_add(z_exact, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_sub(true_error, z, z_exact, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_abs(true_error, true_error); if (fmpr_is_zero(error_bound) != fmpr_is_zero(true_error) || fmpr_cmp(true_error, error_bound) > 0) { flint_printf("FAIL: error bound\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z_exact = "); fmpr_print(z_exact); flint_printf("\n\n"); flint_printf("true_error = "); fmpr_print(true_error); flint_printf("\n\n"); flint_printf("error_bound = "); fmpr_print(error_bound); flint_printf("\n\n"); flint_abort(); } fmpr_clear(z_exact); fmpr_clear(error_bound); fmpr_clear(true_error); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Y); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-add_naive.c000066400000000000000000000135621417376376500166360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("add_naive...."); fflush(stdout); flint_randinit(state); /* test exact addition: (x + y) + z == x + (y + z) */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, res1, res2, res3, res4; fmpr_t x, y, z, t, u; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(t); fmpr_init(u); fmpr_randtest_special(x, state, bits, 10); fmpr_randtest_special(y, state, bits, 10); fmpr_randtest_special(z, state, bits, 10); fmpr_randtest_special(t, state, bits, 10); fmpr_randtest_special(u, state, bits, 10); res1 = fmpr_add_naive(t, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); res2 = fmpr_add_naive(t, t, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res3 = fmpr_add_naive(u, y, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res4 = fmpr_add_naive(u, x, u, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (!fmpr_equal(t, u) || res1 != FMPR_RESULT_EXACT || res2 != FMPR_RESULT_EXACT || res3 != FMPR_RESULT_EXACT || res4 != FMPR_RESULT_EXACT) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("t = "); fmpr_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpr_print(u); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(t); fmpr_clear(u); } /* compare rounding with mpfr */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, res; int mpfr_res; fmpr_t x, y, z, w; mpfr_t X, Y, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Y, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(y, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits, 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDZ); res = fmpr_add_naive(z, x, y, bits, FMPR_RND_DOWN); break; case 1: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDA); res = fmpr_add_naive(z, x, y, bits, FMPR_RND_UP); break; case 2: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDD); res = fmpr_add_naive(z, x, y, bits, FMPR_RND_FLOOR); break; default: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDU); res = fmpr_add_naive(z, x, y, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || (res == FMPR_RESULT_EXACT) != (mpfr_res == 0) || !fmpr_check_ulp(z, res, bits)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_printf("returned: %wd, %d\n", res, mpfr_res); flint_abort(); } /* check error bound */ if (!fmpr_is_nan(z) && !fmpr_is_inf(z)) { fmpr_t z_exact, error_bound, true_error; fmpr_init(z_exact); fmpr_init(error_bound); fmpr_init(true_error); fmpr_set_error_result(error_bound, z, res); fmpr_add_naive(z_exact, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_sub(true_error, z, z_exact, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_abs(true_error, true_error); if (fmpr_is_zero(error_bound) != fmpr_is_zero(true_error) || fmpr_cmp(true_error, error_bound) > 0) { flint_printf("FAIL: error bound\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z_exact = "); fmpr_print(z_exact); flint_printf("\n\n"); flint_printf("true_error = "); fmpr_print(true_error); flint_printf("\n\n"); flint_printf("error_bound = "); fmpr_print(error_bound); flint_printf("\n\n"); flint_abort(); } fmpr_clear(z_exact); fmpr_clear(error_bound); fmpr_clear(true_error); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Y); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-cmp.c000066400000000000000000000031101417376376500154670ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("cmp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, y; mpfr_t X, Y; int cmp1, cmp2; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); mpfr_init2(X, bits); mpfr_init2(Y, bits); fmpr_randtest_special(x, state, bits, 10); fmpr_randtest_special(y, state, bits, 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); cmp1 = fmpr_cmp(x, y); cmp2 = mpfr_cmp(X, Y); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } fmpr_clear(x); fmpr_clear(y); mpfr_clear(X); mpfr_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-cmp_2exp_si.c000066400000000000000000000026401417376376500171270ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("cmp_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, e; fmpr_t x, y; int cmp1, cmp2; bits = 2 + n_randint(state, 1000); e = n_randtest(state); fmpr_init(x); fmpr_init(y); fmpr_randtest_special(x, state, bits, 100); fmpr_set_ui_2exp_si(y, 1, e); cmp1 = fmpr_cmp(x, y); cmp2 = fmpr_cmp_2exp_si(x, e); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } fmpr_clear(x); fmpr_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-cmpabs.c000066400000000000000000000032251417376376500161640ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("cmpabs...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, y; mpfr_t X, Y; int cmp1, cmp2; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); mpfr_init2(X, bits); mpfr_init2(Y, bits); fmpr_randtest_special(x, state, bits, 10); fmpr_randtest_special(y, state, bits, 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); mpfr_abs(X, X, MPFR_RNDN); mpfr_abs(Y, Y, MPFR_RNDN); cmp1 = fmpr_cmpabs(x, y); cmp2 = mpfr_cmp(X, Y); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } fmpr_clear(x); fmpr_clear(y); mpfr_clear(X); mpfr_clear(Y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-cmpabs_2exp_si.c000066400000000000000000000026511417376376500176170ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("cmpabs_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, e; fmpr_t x, y; int cmp1, cmp2; bits = 2 + n_randint(state, 1000); e = n_randtest(state); fmpr_init(x); fmpr_init(y); fmpr_randtest_special(x, state, bits, 100); fmpr_set_ui_2exp_si(y, 1, e); cmp1 = fmpr_cmpabs(x, y); cmp2 = fmpr_cmpabs_2exp_si(x, e); if (cmp1 != cmp2) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("cmp1 = %d, cmp2 = %d\n\n", cmp1, cmp2); flint_abort(); } fmpr_clear(x); fmpr_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-div.c000066400000000000000000000056721417376376500155110ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("div...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, r1, r2; fmpr_t x, y, z, w; mpfr_t X, Y, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Y, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(y, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: r1 = mpfr_div(Z, X, Y, MPFR_RNDZ); r2 = fmpr_div(z, x, y, bits, FMPR_RND_DOWN); break; case 1: r1 = mpfr_div(Z, X, Y, MPFR_RNDA); r2 = fmpr_div(z, x, y, bits, FMPR_RND_UP); break; case 2: r1 = mpfr_div(Z, X, Y, MPFR_RNDD); r2 = fmpr_div(z, x, y, bits, FMPR_RND_FLOOR); break; default: r1 = mpfr_div(Z, X, Y, MPFR_RNDU); r2 = fmpr_div(z, x, y, bits, FMPR_RND_CEIL); break; } /* we use slightly different semantics for special values (?) */ if (mpfr_zero_p(Y)) mpfr_set_nan(Z); if (mpfr_inf_p(X) && mpfr_zero_p(Y)) mpfr_set_nan(Z); fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || ((r1 == 0) != (r2 == FMPR_RESULT_EXACT)) || !fmpr_check_ulp(z, r2, bits)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Y); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-exp.c000066400000000000000000000043521417376376500155150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("exp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, z, w; mpfr_t X, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 3); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 3); fmpr_get_mpfr(X, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_exp(Z, X, MPFR_RNDZ); fmpr_exp(z, x, bits, FMPR_RND_DOWN); break; case 1: mpfr_exp(Z, X, MPFR_RNDA); fmpr_exp(z, x, bits, FMPR_RND_UP); break; case 2: mpfr_exp(Z, X, MPFR_RNDD); fmpr_exp(z, x, bits, FMPR_RND_FLOOR); break; case 3: mpfr_exp(Z, X, MPFR_RNDU); fmpr_exp(z, x, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-expm1.c000066400000000000000000000043741417376376500157570ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("expm1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, z, w; mpfr_t X, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 3); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 3); fmpr_get_mpfr(X, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_expm1(Z, X, MPFR_RNDZ); fmpr_expm1(z, x, bits, FMPR_RND_DOWN); break; case 1: mpfr_expm1(Z, X, MPFR_RNDA); fmpr_expm1(z, x, bits, FMPR_RND_UP); break; case 2: mpfr_expm1(Z, X, MPFR_RNDD); fmpr_expm1(z, x, bits, FMPR_RND_FLOOR); break; case 3: mpfr_expm1(Z, X, MPFR_RNDU); fmpr_expm1(z, x, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-get_d.c000066400000000000000000000024251417376376500160020ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("get_d...."); fflush(stdout); flint_randinit(state); /* test exact roundtrip */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, z; double y; fmpr_init(x); fmpr_init(z); fmpr_randtest_special(x, state, 53, 8); y = fmpr_get_d(x, FMPR_RND_DOWN); fmpr_set_d(z, y); if (!fmpr_equal(x, z)) { flint_printf("FAIL:\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = %.17g\n\n", y); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-get_fmpz.c000066400000000000000000000043721417376376500165360ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("get_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x; mpfr_t y; fmpz_t z, z2; mpz_t w; bits = 2 + n_randint(state, 1000); fmpr_init(x); mpfr_init2(y, bits); fmpz_init(z); fmpz_init(z2); mpz_init(w); fmpr_randtest(x, state, bits, 10); fmpr_get_mpfr(y, x, MPFR_RNDN); switch (n_randint(state, 5)) { case 0: fmpr_get_fmpz(z, x, FMPR_RND_FLOOR); mpfr_get_z(w, y, MPFR_RNDD); break; case 1: fmpr_get_fmpz(z, x, FMPR_RND_CEIL); mpfr_get_z(w, y, MPFR_RNDU); break; case 2: fmpr_get_fmpz(z, x, FMPR_RND_DOWN); mpfr_get_z(w, y, MPFR_RNDZ); break; case 3: fmpr_get_fmpz(z, x, FMPR_RND_UP); mpfr_get_z(w, y, MPFR_RNDA); break; default: fmpr_get_fmpz(z, x, FMPR_RND_NEAR); mpfr_get_z(w, y, MPFR_RNDN); break; } fmpz_set_mpz(z2, w); if (!fmpz_equal(z, z2)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpz_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpz_print(z2); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); mpfr_clear(y); fmpz_clear(z); fmpz_clear(z2); mpz_clear(w); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-get_mpfr.c000066400000000000000000000025011417376376500165160ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("get_mpfr...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, z; mpfr_t y; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); mpfr_init2(y, bits); fmpr_randtest_special(x, state, bits, 10); fmpr_get_mpfr(y, x, MPFR_RNDN); fmpr_set_mpfr(z, y); if (!fmpr_equal(x, z)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); mpfr_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-log.c000066400000000000000000000043541417376376500155040ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("log...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, z, w; mpfr_t X, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); fmpr_get_mpfr(X, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_log(Z, X, MPFR_RNDZ); fmpr_log(z, x, bits, FMPR_RND_DOWN); break; case 1: mpfr_log(Z, X, MPFR_RNDA); fmpr_log(z, x, bits, FMPR_RND_UP); break; case 2: mpfr_log(Z, X, MPFR_RNDD); fmpr_log(z, x, bits, FMPR_RND_FLOOR); break; case 3: mpfr_log(Z, X, MPFR_RNDU); fmpr_log(z, x, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-log1p.c000066400000000000000000000043761417376376500157510ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("log1p...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, z, w; mpfr_t X, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); fmpr_get_mpfr(X, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_log1p(Z, X, MPFR_RNDZ); fmpr_log1p(z, x, bits, FMPR_RND_DOWN); break; case 1: mpfr_log1p(Z, X, MPFR_RNDA); fmpr_log1p(z, x, bits, FMPR_RND_UP); break; case 2: mpfr_log1p(Z, X, MPFR_RNDD); fmpr_log1p(z, x, bits, FMPR_RND_FLOOR); break; case 3: mpfr_log1p(Z, X, MPFR_RNDU); fmpr_log1p(z, x, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-mul.c000066400000000000000000000115361417376376500155200ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, v; slong prec, r1, r2; fmpr_rnd_t rnd; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(v); for (iter2 = 0; iter2 < 100; iter2++) { fmpr_randtest_special(x, state, 2000, 200); fmpr_randtest_special(y, state, 2000, 200); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } switch (n_randint(state, 5)) { case 0: r1 = fmpr_mul(z, x, y, prec, rnd); r2 = fmpr_mul_naive(v, x, y, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 1: r1 = fmpr_mul(z, x, x, prec, rnd); r2 = fmpr_mul_naive(v, x, x, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 2: r2 = fmpr_mul_naive(v, x, x, prec, rnd); r1 = fmpr_mul(x, x, x, prec, rnd); if (!fmpr_equal(v, x) || r1 != r2 || !fmpr_check_ulp(x, r1, prec)) { flint_printf("FAIL (aliasing 2)!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; case 3: r2 = fmpr_mul_naive(v, x, y, prec, rnd); r1 = fmpr_mul(x, x, y, prec, rnd); if (!fmpr_equal(x, v) || r1 != r2 || !fmpr_check_ulp(x, r1, prec)) { flint_printf("FAIL (aliasing 3)!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: r2 = fmpr_mul_naive(v, x, y, prec, rnd); r1 = fmpr_mul(x, y, x, prec, rnd); if (!fmpr_equal(x, v) || r1 != r2 || !fmpr_check_ulp(x, r1, prec)) { flint_printf("FAIL (aliasing 4)!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-mul_fmpz.c000066400000000000000000000064641417376376500165600ustar00rootroot00000000000000/* Copyright (C) 2012, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" static slong fmpr_mul_fmpz_naive(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, y); r = fmpr_mul(z, x, t, prec, rnd); fmpr_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 300 * arb_test_multiplier(); iter++) { fmpr_t x, z, v; fmpz_t y; slong prec, r1, r2; fmpr_rnd_t rnd; fmpr_init(x); fmpr_init(z); fmpr_init(v); fmpz_init(y); for (iter2 = 0; iter2 < 30; iter2++) { fmpr_randtest_special(x, state, 2000, 200); fmpz_randtest(y, state, 2000); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } switch (n_randint(state, 2)) { case 0: r1 = fmpr_mul_fmpz(z, x, y, prec, rnd); r2 = fmpr_mul_fmpz_naive(v, x, y, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: fmpr_set(v, x); fmpr_set(z, x); r1 = fmpr_mul_fmpz(z, z, y, prec, rnd); r2 = fmpr_mul_fmpz_naive(v, v, y, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } fmpr_clear(x); fmpr_clear(z); fmpr_clear(v); fmpz_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-mul_naive.c000066400000000000000000000052121417376376500166740ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_naive...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, y, z, w; mpfr_t X, Y, Z; slong r; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Y, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(y, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_mul(Z, X, Y, MPFR_RNDZ); r = fmpr_mul_naive(z, x, y, bits, FMPR_RND_DOWN); break; case 1: mpfr_mul(Z, X, Y, MPFR_RNDA); r = fmpr_mul_naive(z, x, y, bits, FMPR_RND_UP); break; case 2: mpfr_mul(Z, X, Y, MPFR_RNDD); r = fmpr_mul_naive(z, x, y, bits, FMPR_RND_FLOOR); break; default: mpfr_mul(Z, X, Y, MPFR_RNDU); r = fmpr_mul_naive(z, x, y, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || !fmpr_check_ulp(z, r, bits)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Y); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-mul_si.c000066400000000000000000000063161417376376500162130ustar00rootroot00000000000000/* Copyright (C) 2012, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/long_extras.h" #include "fmpr.h" static slong fmpr_mul_si_naive(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, y); r = fmpr_mul(z, x, t, prec, rnd); fmpr_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 300 * arb_test_multiplier(); iter++) { fmpr_t x, z, v; slong y; slong prec, r1, r2; fmpr_rnd_t rnd; fmpr_init(x); fmpr_init(z); fmpr_init(v); for (iter2 = 0; iter2 < 30; iter2++) { fmpr_randtest_special(x, state, 2000, 200); y = z_randtest(state); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } switch (n_randint(state, 2)) { case 0: r1 = fmpr_mul_si(z, x, y, prec, rnd); r2 = fmpr_mul_si_naive(v, x, y, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = %wd\n\n", y); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: fmpr_set(v, x); fmpr_set(z, x); r1 = fmpr_mul_si(z, z, y, prec, rnd); r2 = fmpr_mul_si_naive(v, v, y, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = %wd\n\n", y); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } fmpr_clear(x); fmpr_clear(z); fmpr_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-mul_ui.c000066400000000000000000000063171417376376500162160ustar00rootroot00000000000000/* Copyright (C) 2012, 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/ulong_extras.h" #include "fmpr.h" static slong fmpr_mul_ui_naive(fmpr_t z, const fmpr_t x, ulong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_ui(t, y); r = fmpr_mul(z, x, t, prec, rnd); fmpr_clear(t); return r; } int main() { slong iter, iter2; flint_rand_t state; flint_printf("mul_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 300 * arb_test_multiplier(); iter++) { fmpr_t x, z, v; ulong y; slong prec, r1, r2; fmpr_rnd_t rnd; fmpr_init(x); fmpr_init(z); fmpr_init(v); for (iter2 = 0; iter2 < 30; iter2++) { fmpr_randtest_special(x, state, 2000, 200); y = n_randtest(state); prec = 2 + n_randint(state, 2000); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } switch (n_randint(state, 2)) { case 0: r1 = fmpr_mul_ui(z, x, y, prec, rnd); r2 = fmpr_mul_ui_naive(v, x, y, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = %wu\n\n", y); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; default: fmpr_set(v, x); fmpr_set(z, x); r1 = fmpr_mul_ui(z, z, y, prec, rnd); r2 = fmpr_mul_ui_naive(v, v, y, prec, rnd); if (!fmpr_equal(z, v) || r1 != r2 || !fmpr_check_ulp(z, r1, prec)) { flint_printf("FAIL (aliasing 1)!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = %wu\n\n", y); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("v = "); fmpr_print(v); flint_printf("\n\n"); flint_printf("r1 = %wd, r2 = %wd\n", r1, r2); flint_abort(); } break; } } fmpr_clear(x); fmpr_clear(z); fmpr_clear(v); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-normalise.c000066400000000000000000000054631417376376500167160ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("normalise...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, xcopy, y, err_bound, err; slong prec, ret1, ret2, bits, ebits; fmpr_rnd_t rnd; fmpr_init(x); fmpr_init(xcopy); fmpr_init(y); fmpr_init(err_bound); fmpr_init(err); bits = 2 + n_randint(state, 2000); ebits = 2 + n_randint(state, 200); fmpz_randtest_not_zero(fmpr_manref(x), state, bits); fmpz_randtest(fmpr_expref(x), state, ebits); fmpz_set(fmpr_manref(y), fmpr_manref(x)); fmpz_set(fmpr_expref(y), fmpr_expref(x)); fmpr_set(xcopy, x); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } prec = 2 + n_randint(state, 2000); ret1 = _fmpr_normalise(fmpr_manref(x), fmpr_expref(x), prec, rnd); ret2 = _fmpr_normalise_naive(fmpr_manref(y), fmpr_expref(y), prec, rnd); if (!fmpr_equal(x, y) || ret1 != ret2) { flint_printf("FAIL!\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("ret1 = %wd, ret2 = %wd\n", ret1, ret2); flint_abort(); } fmpr_sub(err, x, xcopy, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_abs(err, err); fmpr_set_error_result(err_bound, x, ret1); if (fmpr_cmp(err, err_bound) > 0) { flint_printf("FAIL (error bound)!\n"); flint_printf("x (original) = "); fmpr_print(xcopy); flint_printf("\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("error: "); fmpr_print(err); flint_printf("\n\n"); flint_printf("error bound: "); fmpr_print(err_bound); flint_printf("\n\n"); flint_printf("ret = %wd\n", ret1); flint_abort(); } fmpr_clear(x); fmpr_clear(xcopy); fmpr_clear(y); fmpr_clear(err_bound); fmpr_clear(err); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-root.c000066400000000000000000000052101417376376500156760ustar00rootroot00000000000000/* Copyright (C) 2012, 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" #if MPFR_VERSION_MAJOR >= 4 #define func_mpfr_root mpfr_rootn_ui #else #define func_mpfr_root mpfr_root #endif int main() { slong iter; flint_rand_t state; flint_printf("root...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; ulong k; fmpr_t x, z, w; mpfr_t X, Z; bits = 2 + n_randint(state, 200); k = 1 + n_randint(state, 20); fmpr_init(x); fmpr_init(z); fmpr_init(w); mpfr_init2(X, k * (bits + 100)); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_abs(x, x); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); /* occasionally produce perfect powers */ if (n_randint(state, 4) == 0) fmpr_mul(x, x, x, k * bits, FMPR_RND_DOWN); fmpr_get_mpfr(X, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: func_mpfr_root(Z, X, k, MPFR_RNDZ); fmpr_root(z, x, k, bits, FMPR_RND_DOWN); break; case 1: func_mpfr_root(Z, X, k, MPFR_RNDA); fmpr_root(z, x, k, bits, FMPR_RND_UP); break; case 2: func_mpfr_root(Z, X, k, MPFR_RNDD); fmpr_root(z, x, k, bits, FMPR_RND_FLOOR); break; case 3: func_mpfr_root(Z, X, k, MPFR_RNDU); fmpr_root(z, x, k, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd, k = %wu\n", bits, k); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-rsqrt.c000066400000000000000000000045171417376376500160770ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("rsqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, res; fmpr_t x, z, w; mpfr_t X, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpr_init(w); mpfr_init2(X, 2 * (bits + 100)); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); fmpr_get_mpfr(X, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_rec_sqrt(Z, X, MPFR_RNDZ); res = fmpr_rsqrt(z, x, bits, FMPR_RND_DOWN); break; case 1: mpfr_rec_sqrt(Z, X, MPFR_RNDA); res = fmpr_rsqrt(z, x, bits, FMPR_RND_UP); break; case 2: mpfr_rec_sqrt(Z, X, MPFR_RNDD); res = fmpr_rsqrt(z, x, bits, FMPR_RND_FLOOR); break; default: mpfr_rec_sqrt(Z, X, MPFR_RNDU); res = fmpr_rsqrt(z, x, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || !fmpr_check_ulp(z, res, bits)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-set_fmpq.c000066400000000000000000000030651417376376500165370ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("set_fmpq...."); fflush(stdout); flint_randinit(state); /* test exact roundtrip R -> Q -> R */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, res; fmpr_t x, z; fmpq_t y; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpq_init(y); fmpr_randtest(x, state, bits, 10); fmpr_randtest(z, state, bits, 10); fmpr_get_fmpq(y, x); res = fmpr_set_fmpq(z, y, bits, FMPR_RND_DOWN); if (!fmpr_equal(x, z) || !fmpr_check_ulp(z, res, bits)) { flint_printf("FAIL\n\n"); flint_printf("bits: %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpq_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpq_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-set_fmpz_2exp.c000066400000000000000000000032001417376376500174750ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("set_fmpz_2exp...."); fflush(stdout); flint_randinit(state); /* test exact roundtrip R -> Q -> R */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits; fmpr_t x, z; fmpz_t y, e; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpz_init(y); fmpz_init(e); fmpr_randtest(x, state, bits, 10); fmpr_randtest(z, state, bits, 10); fmpr_get_fmpz_2exp(y, e, x); fmpr_set_fmpz_2exp(z, y, e); if (!fmpr_equal(x, z)) { flint_printf("FAIL\n\n"); flint_printf("bits: %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpz_clear(y); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-set_round_mpn.c000066400000000000000000000047261417376376500176020ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round_mpn...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong prec, bits, shift, ret1, ret2; fmpz_t man, exp; fmpr_t y; mpz_t x; fmpz_t fx; fmpr_rnd_t rnd; fmpz_init(man); fmpz_init(exp); mpz_init(x); fmpz_init(fx); fmpr_init(y); bits = 1 + n_randint(state, 1000); prec = 2 + n_randint(state, 1000); if (n_randint(state, 10) == 0) prec = FMPR_PREC_EXACT; fmpz_randtest_not_zero(fx, state, bits); fmpz_get_mpz(x, fx); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } ret1 = _fmpr_set_round_mpn(&shift, man, x->_mp_d, FLINT_ABS(x->_mp_size), (x->_mp_size < 0) ? 1 : 0, prec, rnd); fmpz_set_si(exp, shift); ret2 = fmpr_set_round_fmpz(y, fx, prec, rnd); if (!fmpz_equal(fmpr_manref(y), man) || !fmpz_equal(fmpr_expref(y), exp) || ret1 != ret2 || !fmpr_check_ulp(y, ret2, prec)) { flint_printf("FAIL\n\n"); flint_printf("bits: %wd\n", bits); flint_printf("prec: %wd\n", prec); flint_printf("x = "); fmpz_print(fx); flint_printf("\n\n"); flint_printf("man = "); fmpz_print(man); flint_printf("\n\n"); flint_printf("exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("ret1 = %wd, ret2 = %wd\n\n", ret1, ret2); flint_abort(); } fmpz_clear(man); fmpz_clear(exp); mpz_clear(x); fmpz_clear(fx); fmpr_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-set_round_ui_2exp_fmpz.c000066400000000000000000000046401417376376500214120ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round_ui_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong prec, ret1, ret2; fmpz_t man, exp; fmpr_t x, y; mp_limb_t lo; fmpr_rnd_t rnd; int negative; fmpz_init(man); fmpz_init(exp); fmpr_init(x); fmpr_init(y); prec = 2 + n_randint(state, 1000); if (n_randint(state, 10) == 0) prec = FMPR_PREC_EXACT; negative = n_randint(state, 2); lo = n_randtest(state); fmpz_randtest(exp, state, 1 + n_randint(state, 100)); if (negative) fmpz_neg_ui(man, lo); else fmpz_set_ui(man, lo); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } ret1 = fmpr_set_round_ui_2exp_fmpz(x, lo, exp, negative, prec, rnd); fmpr_set_fmpz_2exp(y, man, exp); ret2 = fmpr_set_round(y, y, prec, rnd); if (!fmpr_equal(x, y) || ret1 != ret2 || !fmpr_check_ulp(x, ret1, prec) || !fmpr_check_ulp(y, ret2, prec)) { flint_printf("FAIL\n\n"); flint_printf("prec: %wd\n", prec); flint_printf("man = "); fmpz_print(man); flint_printf("\n\n"); flint_printf("exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("ret1 = %wd, ret2 = %wd\n\n", ret1, ret2); flint_abort(); } fmpz_clear(man); fmpz_clear(exp); fmpr_clear(x); fmpr_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-set_round_uiui_2exp_fmpz.c000066400000000000000000000050221417376376500217430ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("set_round_uiui_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong prec, ret1, ret2; fmpz_t man, exp; fmpr_t x, y; mp_limb_t hi, lo; fmpr_rnd_t rnd; int negative; fmpz_init(man); fmpz_init(exp); fmpr_init(x); fmpr_init(y); prec = 2 + n_randint(state, 1000); if (n_randint(state, 10) == 0) prec = FMPR_PREC_EXACT; negative = n_randint(state, 2); hi = n_randtest(state); lo = n_randtest(state); fmpz_randtest(exp, state, 1 + n_randint(state, 100)); if (negative) fmpz_neg_uiui(man, hi, lo); else fmpz_set_uiui(man, hi, lo); switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } ret1 = fmpr_set_round_uiui_2exp_fmpz(x, hi, lo, exp, negative, prec, rnd); fmpr_set_fmpz_2exp(y, man, exp); ret2 = fmpr_set_round(y, y, prec, rnd); if (!fmpr_equal(x, y) || ret1 != ret2 || !fmpr_check_ulp(x, ret1, prec) || !fmpr_check_ulp(y, ret2, prec)) { flint_printf("FAIL\n\n"); flint_printf("prec: %wd\n", prec); flint_printf("hi = %wu, lo = %wu\n", hi, lo); flint_printf("man = "); fmpz_print(man); flint_printf("\n\n"); flint_printf("exp = "); fmpz_print(exp); flint_printf("\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("ret1 = %wd, ret2 = %wd\n\n", ret1, ret2); flint_abort(); } fmpz_clear(man); fmpz_clear(exp); fmpr_clear(x); fmpr_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-sqrt.c000066400000000000000000000047141417376376500157140ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, res; fmpr_t x, z, w; mpfr_t X, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(z); fmpr_init(w); mpfr_init2(X, 2 * (bits + 100)); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); /* occasionally produce perfect squares */ if (n_randint(state, 4) == 0) fmpr_mul(x, x, x, 2 * bits, FMPR_RND_DOWN); fmpr_get_mpfr(X, x, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_sqrt(Z, X, MPFR_RNDZ); res = fmpr_sqrt(z, x, bits, FMPR_RND_DOWN); break; case 1: mpfr_sqrt(Z, X, MPFR_RNDA); res = fmpr_sqrt(z, x, bits, FMPR_RND_UP); break; case 2: mpfr_sqrt(Z, X, MPFR_RNDD); res = fmpr_sqrt(z, x, bits, FMPR_RND_FLOOR); break; default: mpfr_sqrt(Z, X, MPFR_RNDU); res = fmpr_sqrt(z, x, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || !fmpr_check_ulp(z, res, bits)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-sub.c000066400000000000000000000134721417376376500155150ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("sub...."); fflush(stdout); flint_randinit(state); /* test exact subtraction: (x - y) - z == (x - z) - y */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong bits, res1, res2, res3, res4; fmpr_t x, y, z, t, u; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(t); fmpr_init(u); fmpr_randtest_special(x, state, bits, 10); fmpr_randtest_special(y, state, bits, 10); fmpr_randtest_special(z, state, bits, 10); fmpr_randtest_special(t, state, bits, 10); fmpr_randtest_special(u, state, bits, 10); res1 = fmpr_sub(t, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); res2 = fmpr_sub(t, t, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res3 = fmpr_sub(u, x, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res4 = fmpr_sub(u, u, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (!fmpr_equal(t, u) || res1 != FMPR_RESULT_EXACT || res2 != FMPR_RESULT_EXACT || res3 != FMPR_RESULT_EXACT || res4 != FMPR_RESULT_EXACT) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("t = "); fmpr_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpr_print(u); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(t); fmpr_clear(u); } /* compare rounding with mpfr */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits, res; int mpfr_res; fmpr_t x, y, z, w; mpfr_t X, Y, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Y, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(y, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits, 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_res = mpfr_sub(Z, X, Y, MPFR_RNDZ); res = fmpr_sub(z, x, y, bits, FMPR_RND_DOWN); break; case 1: mpfr_res = mpfr_sub(Z, X, Y, MPFR_RNDA); res = fmpr_sub(z, x, y, bits, FMPR_RND_UP); break; case 2: mpfr_res = mpfr_sub(Z, X, Y, MPFR_RNDD); res = fmpr_sub(z, x, y, bits, FMPR_RND_FLOOR); break; default: mpfr_res = mpfr_sub(Z, X, Y, MPFR_RNDU); res = fmpr_sub(z, x, y, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || (res == FMPR_RESULT_EXACT) != (mpfr_res == 0) || !fmpr_check_ulp(z, res, bits)) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_printf("returned: %wd, %d\n", res, mpfr_res); flint_abort(); } /* check error bound */ if (!fmpr_is_nan(z) && !fmpr_is_inf(z)) { fmpr_t z_exact, error_bound, true_error; fmpr_init(z_exact); fmpr_init(error_bound); fmpr_init(true_error); fmpr_set_error_result(error_bound, z, res); fmpr_sub(z_exact, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_sub(true_error, z, z_exact, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_abs(true_error, true_error); if (fmpr_is_zero(error_bound) != fmpr_is_zero(true_error) || fmpr_cmp(true_error, error_bound) > 0) { flint_printf("FAIL: error bound\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z_exact = "); fmpr_print(z_exact); flint_printf("\n\n"); flint_printf("true_error = "); fmpr_print(true_error); flint_printf("\n\n"); flint_printf("error_bound = "); fmpr_print(error_bound); flint_printf("\n\n"); flint_abort(); } fmpr_clear(z_exact); fmpr_clear(error_bound); fmpr_clear(true_error); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Y); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/test/t-ulp.c000066400000000000000000000033171417376376500155210ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" int main() { slong iter; flint_rand_t state; flint_printf("ulp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, ulp, a, b; slong prec; fmpr_init(x); fmpr_init(ulp); fmpr_init(a); fmpr_init(b); prec = 2 + n_randint(state, 1000); fmpr_randtest_not_zero(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); fmpr_ulp(ulp, x, prec); fmpr_abs(a, x); fmpr_mul_2exp_si(a, a, -prec); fmpr_abs(b, x); fmpr_mul_2exp_si(b, b, -prec+1); if (!((fmpr_cmp(a, ulp) < 0) && (fmpr_cmp(ulp, b) <= 0))) { flint_printf("FAIL!\n"); flint_printf("prec = %wd\n", prec); flint_printf("x = "); fmpr_print(x); flint_printf("\n"); flint_printf("ulp = "); fmpr_print(ulp); flint_printf("\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(ulp); fmpr_clear(a); fmpr_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpr/ulp.c000066400000000000000000000014071417376376500142770ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpr.h" void fmpr_ulp(fmpr_t u, const fmpr_t x, slong prec) { if (fmpr_is_special(x)) { fmpr_abs(u, x); } else { fmpz_t e; fmpz_init(e); fmpz_add_ui(e, fmpr_expref(x), fmpz_bits(fmpr_manref(x))); fmpz_sub_ui(e, e, prec); fmpz_one(fmpr_manref(u)); fmpz_set(fmpr_expref(u), e); fmpz_clear(e); } } arb-2.22.1/fmpz_extras.h000066400000000000000000000121271417376376500151030ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef FMPZ_EXTRAS_H #define FMPZ_EXTRAS_H #include #include "flint/flint.h" #include "flint/fmpz.h" #ifdef __cplusplus extern "C" { #endif #ifndef flint_abort #if __FLINT_RELEASE <= 20502 #define flint_abort abort #endif #endif #if __FLINT_RELEASE < 20600 #define flint_bitcnt_t ulong #endif /* currently defined in the arb module, but global to the library */ double arb_test_multiplier(void); static __inline__ void fmpz_add_inline(fmpz_t z, const fmpz_t x, const fmpz_t y) { fmpz f, g; f = *x; g = *y; if (!COEFF_IS_MPZ(f) && !COEFF_IS_MPZ(g)) fmpz_set_si(z, f + g); else fmpz_add(z, x, y); } #if __FLINT_RELEASE < 20600 static __inline__ void fmpz_add_si(fmpz_t z, const fmpz_t x, slong y) { if (y >= 0) fmpz_add_ui(z, x, y); else fmpz_sub_ui(z, x, -y); } static __inline__ void fmpz_sub_si(fmpz_t z, const fmpz_t x, slong y) { if (y >= 0) fmpz_sub_ui(z, x, y); else fmpz_add_ui(z, x, -y); } #endif static __inline__ void fmpz_add_si_inline(fmpz_t z, const fmpz_t x, slong y) { fmpz f; f = *x; if (!COEFF_IS_MPZ(f) && (COEFF_MIN <= y && y <= COEFF_MAX)) fmpz_set_si(z, f + y); else fmpz_add_si(z, x, y); } static __inline__ void fmpz_sub_si_inline(fmpz_t z, const fmpz_t x, slong y) { fmpz f; f = *x; if (!COEFF_IS_MPZ(f) && (COEFF_MIN <= y && y <= COEFF_MAX)) fmpz_set_si(z, f - y); else fmpz_sub_si(z, x, y); } static __inline__ void fmpz_add_ui_inline(fmpz_t z, const fmpz_t x, ulong y) { fmpz f = *x; if (!COEFF_IS_MPZ(f) && y <= COEFF_MAX) fmpz_set_si(z, f + y); else fmpz_add_ui(z, x, y); } static __inline__ void fmpz_add2_fmpz_si_inline(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c) { fmpz f, g, h; f = *x; g = *y; if (!COEFF_IS_MPZ(f) && !COEFF_IS_MPZ(g)) { h = f + g; if ((COEFF_MIN <= h && h <= COEFF_MAX) && (COEFF_MIN <= c && c <= COEFF_MAX)) { fmpz_set_si(z, h + c); return; } } fmpz_add(z, x, y); fmpz_add_si(z, z, c); } static __inline__ void fmpz_set_mpn_large(fmpz_t z, mp_srcptr src, mp_size_t n, int negative) { __mpz_struct * zz; zz = _fmpz_promote(z); if (zz->_mp_alloc < n) mpz_realloc2(zz, n * FLINT_BITS); flint_mpn_copyi(zz->_mp_d, src, n); zz->_mp_size = negative ? -n : n; } static __inline__ void fmpz_adiv_q_2exp(fmpz_t z, const fmpz_t x, flint_bitcnt_t exp) { int sign = fmpz_sgn(x); if (sign > 0) fmpz_cdiv_q_2exp(z, x, exp); else fmpz_fdiv_q_2exp(z, x, exp); } static __inline__ void _fmpz_set_si_small(fmpz_t x, slong v) { fmpz_clear(x); *x = v; } slong _fmpz_sub_small_large(const fmpz_t x, const fmpz_t y); static __inline__ slong _fmpz_sub_small(const fmpz_t x, const fmpz_t y) { if (!COEFF_IS_MPZ(*x) && !COEFF_IS_MPZ(*y)) { return (*x) - (*y); } else { return _fmpz_sub_small_large(x, y); } } static __inline__ mp_size_t _fmpz_size(const fmpz_t f) { fmpz d = *f; if (!COEFF_IS_MPZ(d)) return 1; else return mpz_size(COEFF_TO_PTR(d)); } static __inline__ void fmpz_ui_mul_ui(fmpz_t r, ulong a, ulong b) { if (a < (UWORD(1) << (FLINT_BITS / 2)) && b < (UWORD(1) << (FLINT_BITS / 2))) { fmpz_set_ui(r, a * b); } else { fmpz_set_ui(r, a); fmpz_mul_ui(r, r, b); } } static __inline__ void fmpz_ui_pow_ui(fmpz_t x, ulong b, ulong e) { if (e <= 1) { fmpz_set_ui(x, e == 0 ? UWORD(1) : b); } else { fmpz_set_ui(x, b); fmpz_pow_ui(x, x, e); } } static __inline__ void fmpz_max(fmpz_t z, const fmpz_t x, const fmpz_t y) { if (fmpz_cmp(x, y) >= 0) fmpz_set(z, x); else fmpz_set(z, y); } static __inline__ void fmpz_min(fmpz_t z, const fmpz_t x, const fmpz_t y) { if (fmpz_cmp(x, y) < 0) fmpz_set(z, x); else fmpz_set(z, y); } #define FMPZ_GET_MPN_READONLY(zsign, zn, zptr, ztmp, zv) \ if (!COEFF_IS_MPZ(zv)) \ { \ (zsign) = (zv) < 0; \ (ztmp) = FLINT_ABS(zv); \ (zptr) = &(ztmp); \ (zn) = 1; \ } \ else \ { \ __mpz_struct * ___zz = COEFF_TO_PTR(zv); \ (zptr) = ___zz->_mp_d; \ (zn) = ___zz->_mp_size; \ (zsign) = (zn) < 0; \ (zn) = FLINT_ABS(zn); \ } void fmpz_lshift_mpn(fmpz_t z, mp_srcptr d, mp_size_t dn, int sgnbit, flint_bitcnt_t shift); static __inline__ slong fmpz_allocated_bytes(const fmpz_t x) { if (COEFF_IS_MPZ(*x)) return sizeof(__mpz_struct) + COEFF_TO_PTR(*x)->_mp_alloc * sizeof(mp_limb_t); else return 0; } #ifdef __cplusplus } #endif #endif arb-2.22.1/fmpz_extras/000077500000000000000000000000001417376376500147275ustar00rootroot00000000000000arb-2.22.1/fmpz_extras/lshift_mpn.c000066400000000000000000000022551417376376500172420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" void fmpz_lshift_mpn(fmpz_t z, mp_srcptr d, mp_size_t dn, int sgnbit, flint_bitcnt_t shift) { __mpz_struct * zmpz; mp_ptr zp; mp_size_t zn, shift_limbs; flint_bitcnt_t shift_bits; zmpz = _fmpz_promote(z); shift_limbs = shift / FLINT_BITS; shift_bits = shift % FLINT_BITS; zn = dn + shift_limbs + (shift_bits != 0); if (zmpz->_mp_alloc < zn) mpz_realloc2(zmpz, zn * FLINT_BITS); zp = zmpz->_mp_d; flint_mpn_zero(zp, shift_limbs); if (shift_bits == 0) { flint_mpn_copyi(zp + shift_limbs, d, dn); } else { zp[zn - 1] = mpn_lshift(zp + shift_limbs, d, dn, shift_bits); while (zp[zn - 1] == 0) zn--; } zmpz->_mp_size = sgnbit ? -(slong) zn : zn; _fmpz_demote_val(z); } arb-2.22.1/fmpz_extras/sub_small_large.c000066400000000000000000000013451417376376500202310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" slong _fmpz_sub_small_large(const fmpz_t x, const fmpz_t y) { fmpz_t t; fmpz_init(t); fmpz_sub(t, x, y); if (!COEFF_IS_MPZ(*t)) { /* no need to free t */ return *t; } else { int sign = fmpz_sgn(t); fmpz_clear(t); return (sign > 0) ? WORD_MAX : -WORD_MAX; } } arb-2.22.1/fmpz_extras/test/000077500000000000000000000000001417376376500157065ustar00rootroot00000000000000arb-2.22.1/fmpz_extras/test/t-add2_fmpz_si_inline.c000066400000000000000000000067511417376376500222230ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("add2_fmpz_si_inline...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpz_t a, b, c, d; slong e; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_init(d); fmpz_randtest(a, state, 1 + n_randint(state, 200)); fmpz_randtest(b, state, 1 + n_randint(state, 200)); fmpz_randtest(c, state, 1 + n_randint(state, 200)); fmpz_randtest(d, state, 1 + n_randint(state, 200)); e = n_randtest(state); fmpz_add(c, a, b); fmpz_add_si(c, c, e); fmpz_add2_fmpz_si_inline(d, a, b, e); if (!fmpz_equal(c, d)) { flint_printf("FAIL\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_printf("%wd\n\n", e); flint_abort(); } fmpz_add2_fmpz_si_inline(a, a, b, e); if (!fmpz_equal(c, a)) { flint_printf("FAIL (aliasing 1)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_printf("%wd\n\n", e); flint_abort(); } fmpz_randtest(a, state, 1 + n_randint(state, 200)); fmpz_add(c, a, b); fmpz_add_si(c, c, e); fmpz_add2_fmpz_si_inline(b, a, b, e); if (!fmpz_equal(c, b)) { flint_printf("FAIL (aliasing 2)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_printf("%wd\n\n", e); flint_abort(); } fmpz_add(d, a, a); fmpz_add_si(d, d, e); fmpz_add2_fmpz_si_inline(c, a, a, e); if (!fmpz_equal(c, d)) { flint_printf("FAIL (aliasing 3)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_printf("%wd\n\n", e); flint_abort(); } fmpz_add(d, a, a); fmpz_add_si(d, d, e); fmpz_add2_fmpz_si_inline(a, a, a, e); if (!fmpz_equal(d, a)) { flint_printf("FAIL (aliasing 4)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_printf("%wd\n\n", e); flint_abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); fmpz_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpz_extras/test/t-add_inline.c000066400000000000000000000060641417376376500204070ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("add_inline...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpz_t a, b, c, d; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_init(d); fmpz_randtest(a, state, 1 + n_randint(state, 200)); fmpz_randtest(b, state, 1 + n_randint(state, 200)); fmpz_randtest(c, state, 1 + n_randint(state, 200)); fmpz_randtest(d, state, 1 + n_randint(state, 200)); fmpz_add(c, a, b); fmpz_add_inline(d, a, b); if (!fmpz_equal(c, d)) { flint_printf("FAIL\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_add_inline(a, a, b); if (!fmpz_equal(c, a)) { flint_printf("FAIL (aliasing 1)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_randtest(a, state, 1 + n_randint(state, 200)); fmpz_add(c, a, b); fmpz_add_inline(b, a, b); if (!fmpz_equal(c, b)) { flint_printf("FAIL (aliasing 2)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_add(d, a, a); fmpz_add_inline(c, a, a); if (!fmpz_equal(c, d)) { flint_printf("FAIL (aliasing 3)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_add(d, a, a); fmpz_add_inline(a, a, a); if (!fmpz_equal(d, a)) { flint_printf("FAIL (aliasing 4)\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); fmpz_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpz_extras/test/t-add_si_inline.c000066400000000000000000000035261417376376500211020ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("add_si_inline...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpz_t a, c, d; slong b; fmpz_init(a); fmpz_init(c); fmpz_init(d); fmpz_randtest(a, state, 1 + n_randint(state, 200)); fmpz_randtest(c, state, 1 + n_randint(state, 200)); fmpz_randtest(d, state, 1 + n_randint(state, 200)); b = n_randtest(state); fmpz_add_si(c, a, b); fmpz_add_si_inline(d, a, b); if (!fmpz_equal(c, d)) { flint_printf("FAIL\n"); fmpz_print(a); flint_printf("\n\n"); flint_printf("%wd", b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_add_si_inline(a, a, b); if (!fmpz_equal(c, a)) { flint_printf("FAIL (aliasing)\n"); fmpz_print(a); flint_printf("\n\n"); flint_printf("%wd", b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_clear(a); fmpz_clear(c); fmpz_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpz_extras/test/t-add_ui_inline.c000066400000000000000000000035261417376376500211040ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("add_ui_inline...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpz_t a, c, d; ulong b; fmpz_init(a); fmpz_init(c); fmpz_init(d); fmpz_randtest(a, state, 1 + n_randint(state, 200)); fmpz_randtest(c, state, 1 + n_randint(state, 200)); fmpz_randtest(d, state, 1 + n_randint(state, 200)); b = n_randtest(state); fmpz_add_ui(c, a, b); fmpz_add_ui_inline(d, a, b); if (!fmpz_equal(c, d)) { flint_printf("FAIL\n"); fmpz_print(a); flint_printf("\n\n"); flint_printf("%wu", b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_add_ui_inline(a, a, b); if (!fmpz_equal(c, a)) { flint_printf("FAIL (aliasing)\n"); fmpz_print(a); flint_printf("\n\n"); flint_printf("%wu", b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_clear(a); fmpz_clear(c); fmpz_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpz_extras/test/t-lshift_mpn.c000066400000000000000000000031361417376376500204610ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("lshift_mpn...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpz_t a, b, c; ulong e; mp_limb_t atmp; mp_ptr aptr; mp_size_t an; int asgnbit; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_randtest_not_zero(a, state, 1 + n_randint(state, 2000)); fmpz_randtest(b, state, 1 + n_randint(state, 2000)); fmpz_randtest(c, state, 1 + n_randint(state, 2000)); e = n_randint(state, 1000); FMPZ_GET_MPN_READONLY(asgnbit, an, aptr, atmp, *a) fmpz_lshift_mpn(b, aptr, an, asgnbit, e); fmpz_mul_2exp(c, a, e); if (!fmpz_equal(b, c)) { flint_printf("FAIL\n"); fmpz_print(a); flint_printf("\n\n"); fmpz_print(b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); flint_abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/fmpz_extras/test/t-sub_si_inline.c000066400000000000000000000035261417376376500211430ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "fmpz_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_si_inline...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpz_t a, c, d; slong b; fmpz_init(a); fmpz_init(c); fmpz_init(d); fmpz_randtest(a, state, 1 + n_randint(state, 200)); fmpz_randtest(c, state, 1 + n_randint(state, 200)); fmpz_randtest(d, state, 1 + n_randint(state, 200)); b = n_randtest(state); fmpz_sub_si(c, a, b); fmpz_sub_si_inline(d, a, b); if (!fmpz_equal(c, d)) { flint_printf("FAIL\n"); fmpz_print(a); flint_printf("\n\n"); flint_printf("%wd", b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_sub_si_inline(a, a, b); if (!fmpz_equal(c, a)) { flint_printf("FAIL (aliasing)\n"); fmpz_print(a); flint_printf("\n\n"); flint_printf("%wd", b); flint_printf("\n\n"); fmpz_print(c); flint_printf("\n\n"); fmpz_print(d); flint_printf("\n\n"); flint_abort(); } fmpz_clear(a); fmpz_clear(c); fmpz_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/hypgeom.h000066400000000000000000000024401417376376500142060ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef HYPGEOM_H #define HYPGEOM_H #include "flint/fmpz_poly.h" #include "arb.h" #include "mag.h" #ifdef __cplusplus extern "C" { #endif typedef struct { fmpz_poly_t A; fmpz_poly_t B; fmpz_poly_t P; fmpz_poly_t Q; /* precomputation data */ int have_precomputed; slong r; slong boundC; slong boundD; slong boundK; mag_t MK; } hypgeom_struct; typedef hypgeom_struct hypgeom_t[1]; void hypgeom_init(hypgeom_t hyp); void hypgeom_clear(hypgeom_t hyp); void hypgeom_precompute(hypgeom_t hyp); slong hypgeom_estimate_terms(const mag_t z, int r, slong prec); slong hypgeom_bound(mag_t error, int r, slong C, slong D, slong K, const mag_t TK, const mag_t z, slong prec); void arb_hypgeom_sum(arb_t P, arb_t Q, const hypgeom_t hyp, slong n, slong prec); void arb_hypgeom_infsum(arb_t P, arb_t Q, hypgeom_t hyp, slong target_prec, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/hypgeom/000077500000000000000000000000001417376376500140355ustar00rootroot00000000000000arb-2.22.1/hypgeom/bound.c000066400000000000000000000103241417376376500153100ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "flint/double_extras.h" #include "hypgeom.h" slong hypgeom_root_bound(const mag_t z, int r) { if (r == 0) { return 0; } else { arf_t t; slong v; arf_init(t); arf_set_mag(t, z); arf_root(t, t, r, MAG_BITS, ARF_RND_UP); arf_add_ui(t, t, 1, MAG_BITS, ARF_RND_UP); v = arf_get_si(t, ARF_RND_UP); arf_clear(t); return v; } } /* Given T(K), compute bound for T(n) z^n. We need to multiply by z^n * 1/rf(K+1,m)^r * (rf(K+1,m)/rf(K+1-A,m)) * (rf(K+1-B,m)/rf(K+1-2B,m)) where m = n - K. This is equal to z^n * (K+A)! (K-2B)! (K-B+m)! ----------------------- * ((K+m)! / K!)^(1-r) (K-B)! (K-A+m)! (K-2B+m)! */ void hypgeom_term_bound(mag_t Tn, const mag_t TK, slong K, slong A, slong B, int r, const mag_t z, slong n) { mag_t t, u, num; slong m; mag_init(t); mag_init(u); mag_init(num); m = n - K; if (m < 0) { flint_printf("hypgeom term bound\n"); flint_abort(); } /* TK * z^n */ mag_pow_ui(t, z, n); mag_mul(num, TK, t); /* numerator: (K+A)! (K-2B)! (K-B+m)! */ mag_fac_ui(t, K+A); mag_mul(num, num, t); mag_fac_ui(t, K-2*B); mag_mul(num, num, t); mag_fac_ui(t, K-B+m); mag_mul(num, num, t); /* denominator: (K-B)! (K-A+m)! (K-2B+m)! */ mag_rfac_ui(t, K-B); mag_mul(num, num, t); mag_rfac_ui(t, K-A+m); mag_mul(num, num, t); mag_rfac_ui(t, K-2*B+m); mag_mul(num, num, t); /* ((K+m)! / K!)^(1-r) */ if (r == 0) { mag_fac_ui(t, K+m); mag_mul(num, num, t); mag_rfac_ui(t, K); mag_mul(num, num, t); } else if (r != 1) { mag_fac_ui(t, K); mag_rfac_ui(u, K+m); mag_mul(t, t, u); mag_pow_ui(t, t, r-1); mag_mul(num, num, t); } mag_set(Tn, num); mag_clear(t); mag_clear(u); mag_clear(num); } slong hypgeom_bound(mag_t error, int r, slong A, slong B, slong K, const mag_t TK, const mag_t z, slong tol_2exp) { mag_t Tn, t, u, one, tol, num, den; slong n, m; mag_init(Tn); mag_init(t); mag_init(u); mag_init(one); mag_init(tol); mag_init(num); mag_init(den); mag_one(one); mag_set_ui_2exp_si(tol, UWORD(1), -tol_2exp); /* approximate number of needed terms */ n = hypgeom_estimate_terms(z, r, tol_2exp); /* required for 1 + O(1/k) part to be decreasing */ n = FLINT_MAX(n, K + 1); /* required for z^k / (k!)^r to be decreasing */ m = hypgeom_root_bound(z, r); n = FLINT_MAX(n, m); /* We now have |R(k)| <= G(k) where G(k) is monotonically decreasing, and can bound the tail using a geometric series as soon as soon as G(k) < 1. */ /* bound T(n-1) */ hypgeom_term_bound(Tn, TK, K, A, B, r, z, n-1); while (1) { /* bound R(n) */ mag_mul_ui(num, z, n); mag_mul_ui(num, num, n - B); mag_set_ui_lower(den, n - A); mag_mul_ui_lower(den, den, n - 2*B); if (r != 0) { mag_set_ui_lower(u, n); mag_pow_ui_lower(u, u, r); mag_mul_lower(den, den, u); } mag_div(t, num, den); /* multiply bound for T(n-1) by bound for R(n) to bound T(n) */ mag_mul(Tn, Tn, t); /* geometric series termination check */ /* u = max(1-t, 0), rounding down [lower bound] */ mag_sub_lower(u, one, t); if (!mag_is_zero(u)) { mag_div(u, Tn, u); if (mag_cmp(u, tol) < 0) { mag_set(error, u); break; } } /* move on to next term */ n++; } mag_clear(Tn); mag_clear(t); mag_clear(u); mag_clear(one); mag_clear(tol); mag_clear(num); mag_clear(den); return n; } arb-2.22.1/hypgeom/estimate_terms_d.c000066400000000000000000000024241417376376500175330ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "flint/double_extras.h" #include "hypgeom.h" #define LOG2 0.69314718055994530942 #define EXP1 2.7182818284590452354 static __inline__ double d_root(double x, int r) { if (r == 1) return x; if (r == 2) return sqrt(x); return pow(x, 1. / r); } slong hypgeom_estimate_terms(const mag_t z, int r, slong prec) { double y, t; t = mag_get_d(z); if (t == 0) return 1; if (r == 0) { if (t >= 1) { flint_printf("z must be smaller than 1\n"); flint_abort(); } y = (log(1-t) - prec * LOG2) / log(t) + 1; } else { y = (prec * LOG2) / (d_root(t, r) * EXP1 * r); y = (prec * LOG2) / (r * d_lambertw(y)) + 1; } if (y >= WORD_MAX / 2) { flint_printf("error: series will converge too slowly\n"); flint_abort(); } return y; } arb-2.22.1/hypgeom/init.c000066400000000000000000000014201417376376500151410ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "hypgeom.h" void hypgeom_init(hypgeom_t hyp) { fmpz_poly_init(hyp->A); fmpz_poly_init(hyp->B); fmpz_poly_init(hyp->P); fmpz_poly_init(hyp->Q); mag_init(hyp->MK); hyp->have_precomputed = 0; } void hypgeom_clear(hypgeom_t hyp) { fmpz_poly_clear(hyp->A); fmpz_poly_clear(hyp->B); fmpz_poly_clear(hyp->P); fmpz_poly_clear(hyp->Q); mag_clear(hyp->MK); } arb-2.22.1/hypgeom/precompute.c000066400000000000000000000064701417376376500163730ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "hypgeom.h" /* Compute a pure ratio P2(k)/Q2(k) for the term A(k)/B(k) * [P(1)P(2)...P(k)] / [Q(1)Q(2)...Q(k)] */ void hypgeom_standardize(fmpz_poly_t P2, fmpz_poly_t Q2, const fmpz_poly_t A, const fmpz_poly_t B, const fmpz_poly_t P, const fmpz_poly_t Q) { fmpz_t s; fmpz_poly_t T; fmpz_init(s); fmpz_poly_init(T); fmpz_set_si(s, -WORD(1)); /* P = A * B(k-1) * P */ fmpz_poly_taylor_shift(T, B, s); fmpz_poly_mul(P2, A, T); fmpz_poly_mul(P2, P2, P); /* Q = B * A(k-1) * Q */ fmpz_poly_taylor_shift(T, A, s); fmpz_poly_mul(Q2, B, T); fmpz_poly_mul(Q2, Q2, Q); fmpz_clear(s); fmpz_poly_clear(T); } /* quotient of absolute value, rounded up */ static __inline__ void fmpz_cdiv_abs_q(fmpz_t q, const fmpz_t x, const fmpz_t y) { if (fmpz_sgn(x) == fmpz_sgn(y)) { fmpz_cdiv_q(q, x, y); } else { fmpz_fdiv_q(q, x, y); fmpz_neg(q, q); } } slong hypgeom_root_norm(const fmpz_poly_t P) { slong res, i, p; fmpz_t t, A; fmpz_init(A); fmpz_init(t); p = fmpz_poly_degree(P); fmpz_zero(A); for (i = 1; i <= p; i++) { fmpz_cdiv_abs_q(t, P->coeffs + p - i, P->coeffs + p); fmpz_root(t, t, i); fmpz_add_ui(t, t, 1); if (fmpz_cmp(t, A) > 0) fmpz_swap(t, A); } if (!fmpz_fits_si(A)) flint_abort(); res = fmpz_get_si(A); fmpz_clear(A); fmpz_clear(t); return res; } static __inline__ void fmpz_poly_evaluate_si(fmpz_t y, const fmpz_poly_t poly, slong x) { fmpz_set_si(y, x); fmpz_poly_evaluate_fmpz(y, poly, y); } void _hypgeom_precompute(hypgeom_t hyp, const fmpz_poly_t P, const fmpz_poly_t Q) { slong k; fmpz_t t; fmpz_init(t); hyp->r = fmpz_poly_degree(Q) - fmpz_poly_degree(P); hyp->boundC = hypgeom_root_norm(P); hyp->boundD = hypgeom_root_norm(Q); hyp->boundK = 1 + FLINT_MAX(hyp->boundC, 2 * hyp->boundD); mag_one(hyp->MK); for (k = 1; k <= hyp->boundK; k++) { fmpz_poly_evaluate_si(t, P, k); mag_mul_fmpz(hyp->MK, hyp->MK, t); fmpz_poly_evaluate_si(t, Q, k); mag_div_fmpz(hyp->MK, hyp->MK, t); } fmpz_clear(t); } void hypgeom_precompute(hypgeom_t hyp) { if (fmpz_poly_is_one(hyp->A) && fmpz_poly_is_one(hyp->B)) { _hypgeom_precompute(hyp, hyp->P, hyp->Q); } else { fmpz_poly_t P2, Q2; fmpz_poly_init(P2); fmpz_poly_init(Q2); hypgeom_standardize(P2, Q2, hyp->A, hyp->B, hyp->P, hyp->Q); _hypgeom_precompute(hyp, P2, Q2); { fmpz_t t; fmpz_init(t); fmpz_poly_evaluate_si(t, hyp->A, 0); mag_mul_fmpz(hyp->MK, hyp->MK, t); fmpz_poly_evaluate_si(t, hyp->B, 0); mag_div_fmpz(hyp->MK, hyp->MK, t); fmpz_clear(t); } fmpz_poly_clear(P2); fmpz_poly_clear(Q2); } } arb-2.22.1/hypgeom/sum.c000066400000000000000000000110441417376376500150050ustar00rootroot00000000000000/* Copyright (C) 2012 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "hypgeom.h" static __inline__ void fmpz_poly_evaluate_si(fmpz_t y, const fmpz_poly_t poly, slong x) { fmpz_set_si(y, x); fmpz_poly_evaluate_fmpz(y, poly, y); } static void bsplit_recursive_fmpz(fmpz_t P, fmpz_t Q, fmpz_t B, fmpz_t T, const hypgeom_t hyp, slong a, slong b, int cont) { if (b - a == 1) { if (a == 0) { fmpz_one(P); fmpz_one(Q); } else { fmpz_poly_evaluate_si(P, hyp->P, a); fmpz_poly_evaluate_si(Q, hyp->Q, a); } fmpz_poly_evaluate_si(B, hyp->B, a); fmpz_poly_evaluate_si(T, hyp->A, a); fmpz_mul(T, T, P); } else { slong m; fmpz_t P2, Q2, B2, T2; m = (a + b) / 2; fmpz_init(P2); fmpz_init(Q2); fmpz_init(B2); fmpz_init(T2); bsplit_recursive_fmpz(P, Q, B, T, hyp, a, m, 1); bsplit_recursive_fmpz(P2, Q2, B2, T2, hyp, m, b, 1); if (fmpz_is_one(B) && fmpz_is_one(B2)) { fmpz_mul(T, T, Q2); fmpz_addmul(T, P, T2); } else { fmpz_mul(T, T, B2); fmpz_mul(T, T, Q2); fmpz_mul(T2, T2, B); fmpz_addmul(T, P, T2); } fmpz_mul(B, B, B2); fmpz_mul(Q, Q, Q2); if (cont) fmpz_mul(P, P, P2); fmpz_clear(P2); fmpz_clear(Q2); fmpz_clear(B2); fmpz_clear(T2); } } static void bsplit_recursive_arb(arb_t P, arb_t Q, arb_t B, arb_t T, const hypgeom_t hyp, slong a, slong b, int cont, slong prec) { if (b - a < 4) { fmpz_t PP, QQ, BB, TT; fmpz_init(PP); fmpz_init(QQ); fmpz_init(BB); fmpz_init(TT); bsplit_recursive_fmpz(PP, QQ, BB, TT, hyp, a, b, cont); arb_set_fmpz(P, PP); arb_set_fmpz(Q, QQ); arb_set_fmpz(B, BB); arb_set_fmpz(T, TT); fmpz_clear(PP); fmpz_clear(QQ); fmpz_clear(BB); fmpz_clear(TT); } else { slong m; arb_t P2, Q2, B2, T2; m = (a + b) / 2; arb_init(P2); arb_init(Q2); arb_init(B2); arb_init(T2); bsplit_recursive_arb(P, Q, B, T, hyp, a, m, 1, prec); bsplit_recursive_arb(P2, Q2, B2, T2, hyp, m, b, 1, prec); if (arb_is_one(B) && arb_is_one(B2)) { arb_mul(T, T, Q2, prec); arb_addmul(T, P, T2, prec); } else { arb_mul(T, T, B2, prec); arb_mul(T, T, Q2, prec); arb_mul(T2, T2, B, prec); arb_addmul(T, P, T2, prec); } arb_mul(B, B, B2, prec); arb_mul(Q, Q, Q2, prec); if (cont) arb_mul(P, P, P2, prec); arb_clear(P2); arb_clear(Q2); arb_clear(B2); arb_clear(T2); } } void arb_hypgeom_sum(arb_t P, arb_t Q, const hypgeom_t hyp, slong n, slong prec) { if (n < 1) { arb_zero(P); arb_one(Q); } else { arb_t B, T; arb_init(B); arb_init(T); bsplit_recursive_arb(P, Q, B, T, hyp, 0, n, 0, prec); if (!arb_is_one(B)) arb_mul(Q, Q, B, prec); arb_swap(P, T); arb_clear(B); arb_clear(T); } } void arb_hypgeom_infsum(arb_t P, arb_t Q, hypgeom_t hyp, slong target_prec, slong prec) { mag_t err, z; slong n; mag_init(err); mag_init(z); mag_set_fmpz(z, hyp->P->coeffs + hyp->P->length - 1); mag_div_fmpz(z, z, hyp->Q->coeffs + hyp->Q->length - 1); if (!hyp->have_precomputed) { hypgeom_precompute(hyp); hyp->have_precomputed = 1; } n = hypgeom_bound(err, hyp->r, hyp->boundC, hyp->boundD, hyp->boundK, hyp->MK, z, target_prec); arb_hypgeom_sum(P, Q, hyp, n, prec); if (arf_sgn(arb_midref(Q)) < 0) { arb_neg(P, P); arb_neg(Q, Q); } /* We have p/q = s + err i.e. (p + q*err)/q = s */ { mag_t u; mag_init(u); arb_get_mag(u, Q); mag_mul(u, u, err); mag_add(arb_radref(P), arb_radref(P), u); mag_clear(u); } mag_clear(z); mag_clear(err); } arb-2.22.1/mag.h000066400000000000000000000377071417376376500133200ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef MAG_H #define MAG_H #ifdef MAG_INLINES_C #define MAG_INLINE #else #define MAG_INLINE static __inline__ #endif #include #include #include "flint/flint.h" #include "flint/fmpz.h" #include "fmpz_extras.h" #ifndef flint_abort #if __FLINT_RELEASE <= 20502 #define flint_abort abort #endif #endif #ifdef __cplusplus extern "C" { #endif #define LIMB_ONE ((mp_limb_t) 1) #define LIMB_ONES (-(mp_limb_t) 1) #define LIMB_TOP (((mp_limb_t) 1) << (FLINT_BITS - 1)) #define MASK_LIMB(n, c) ((n) & (LIMB_ONES << (c))) #define MAG_MAX_LAGOM_EXP (COEFF_MAX / 4) #define MAG_MIN_LAGOM_EXP (-MAG_MAX_LAGOM_EXP) #define ADD2_FAST_MAX (COEFF_MAX / 4) #define ADD2_FAST_MIN (-ADD2_FAST_MAX) /* TODO: rename these and move them to fmpz_extras */ static __inline__ void _fmpz_set_fast(fmpz_t f, const fmpz_t g) { if (!COEFF_IS_MPZ(*f) && !COEFF_IS_MPZ(*g)) *f = *g; else fmpz_set(f, g); } static __inline__ void _fmpz_add_fast(fmpz_t z, const fmpz_t x, slong c) { fmpz ze, xe; ze = *z; xe = *x; if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX)) *z = xe + c; else fmpz_add_si(z, x, c); } static __inline__ void _fmpz_add2_fast(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c) { fmpz ze, xe, ye; ze = *z; xe = *x; ye = *y; if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX) && (ye > ADD2_FAST_MIN && ye < ADD2_FAST_MAX)) { *z = xe + ye + c; } else { fmpz_add(z, x, y); fmpz_add_si(z, z, c); } } static __inline__ void _fmpz_sub2_fast(fmpz_t z, const fmpz_t x, const fmpz_t y, slong c) { fmpz ze, xe, ye; ze = *z; xe = *x; ye = *y; if (!COEFF_IS_MPZ(ze) && (xe > ADD2_FAST_MIN && xe < ADD2_FAST_MAX) && (ye > ADD2_FAST_MIN && ye < ADD2_FAST_MAX)) { *z = xe - ye + c; } else { fmpz_sub(z, x, y); fmpz_add_si(z, z, c); } } #define MAG_EXP_POS_INF (COEFF_MIN+1) /* Finite and with lagom big exponents. */ #define MAG_IS_LAGOM(x) (MAG_EXP(x) >= MAG_MIN_LAGOM_EXP && \ MAG_EXP(x) <= MAG_MAX_LAGOM_EXP) #define MAG_EXPREF(x) (&(x)->exp) #define MAG_EXP(x) ((x)->exp) #define MAG_MAN(x) ((x)->man) #define MAG_BITS 30 #define MAG_ONE_HALF (UWORD(1) << (MAG_BITS - 1)) static __inline__ mp_limb_t __mag_fixmul32(mp_limb_t x, mp_limb_t y) { mp_limb_t u, v; umul_ppmm(u, v, x, y); return (u << (32 - MAG_BITS)) | (v >> MAG_BITS); } #if FLINT_BITS == 64 #define MAG_FIXMUL(x, y) (((x) * (y)) >> MAG_BITS) #else #define MAG_FIXMUL(x, y) __mag_fixmul32((x), (y)) #endif #define MAG_CHECK_BITS(rr) \ if (MAG_MAN(rr) != 0 && FLINT_BIT_COUNT(MAG_MAN(rr)) != MAG_BITS) \ { \ flint_printf("FAIL: wrong number of bits in mantissa!\n"); \ flint_abort(); \ } /* Note: assumes mantissa either has the right number of bits, or one more bit (but in that case must not be all ones, as that would round up to one extra bit again, requiring a second correction). */ #define MAG_ADJUST_ONE_TOO_LARGE(x) \ do { \ mp_limb_t __t = MAG_MAN(x) >> MAG_BITS; \ MAG_MAN(x) = (MAG_MAN(x) >> __t) + (__t & MAG_MAN(x)); \ if (__t) \ fmpz_add_ui(MAG_EXPREF(x), MAG_EXPREF(x), __t); \ } while (0) #define MAG_FAST_ADJUST_ONE_TOO_LARGE(x) \ do { \ mp_limb_t __t = MAG_MAN(x) >> MAG_BITS; \ MAG_MAN(x) = (MAG_MAN(x) >> __t) + (__t & MAG_MAN(x)); \ MAG_EXP(x) += __t; \ } while (0) #define MAG_ADJUST_ONE_TOO_SMALL(x) \ do { \ mp_limb_t __t = !(MAG_MAN(x) >> (MAG_BITS - 1)); \ MAG_MAN(x) = (MAG_MAN(x) << __t); \ if (__t) \ fmpz_sub_ui(MAG_EXPREF(x), MAG_EXPREF(x), __t); \ } while (0) #define MAG_FAST_ADJUST_ONE_TOO_SMALL(x) \ do { \ mp_limb_t __t = !(MAG_MAN(x) >> (MAG_BITS - 1)); \ MAG_MAN(x) = (MAG_MAN(x) << __t); \ MAG_EXP(x) -= __t; \ } while (0) typedef struct { fmpz exp; mp_limb_t man; } mag_struct; typedef mag_struct mag_t[1]; typedef mag_struct * mag_ptr; typedef const mag_struct * mag_srcptr; MAG_INLINE void mag_init(mag_t x) { fmpz_init(MAG_EXPREF(x)); MAG_MAN(x) = 0; } MAG_INLINE void mag_init_set(mag_t x, const mag_t y) { fmpz_init_set(MAG_EXPREF(x), MAG_EXPREF(y)); MAG_MAN(x) = MAG_MAN(y); } void mag_clear(mag_t x); MAG_INLINE void mag_swap(mag_t x, mag_t y) { mag_struct t = *x; *x = *y; *y = t; } MAG_INLINE void mag_set(mag_t x, const mag_t y) { _fmpz_set_fast(MAG_EXPREF(x), MAG_EXPREF(y)); x->man = y->man; } MAG_INLINE void mag_zero(mag_t x) { fmpz_zero(MAG_EXPREF(x)); MAG_MAN(x) = 0; } MAG_INLINE void mag_one(mag_t x) { fmpz_one(MAG_EXPREF(x)); MAG_MAN(x) = MAG_ONE_HALF; } MAG_INLINE int mag_is_special(const mag_t x) { return MAG_MAN(x) == 0; } MAG_INLINE int mag_is_zero(const mag_t x) { return (MAG_MAN(x) == 0) && (MAG_EXP(x) == 0); } MAG_INLINE void mag_inf(mag_t x) { fmpz_clear(MAG_EXPREF(x)); MAG_EXP(x) = MAG_EXP_POS_INF; MAG_MAN(x) = 0; } MAG_INLINE int mag_is_inf(const mag_t x) { return (MAG_MAN(x) == 0) && (MAG_EXP(x) != 0); } MAG_INLINE int mag_is_finite(const mag_t x) { return !mag_is_inf(x); } MAG_INLINE int mag_equal(const mag_t x, const mag_t y) { return (MAG_MAN(x) == MAG_MAN(y)) && fmpz_equal(MAG_EXPREF(x), MAG_EXPREF(y)); } /* general versions */ void mag_mul(mag_t z, const mag_t x, const mag_t y); void mag_mul_lower(mag_t z, const mag_t x, const mag_t y); void mag_addmul(mag_t z, const mag_t x, const mag_t y); void mag_add_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t e); void mag_add(mag_t z, const mag_t x, const mag_t y); void mag_add_lower(mag_t z, const mag_t x, const mag_t y); void mag_add_ui(mag_t z, const mag_t x, ulong y); void mag_add_ui_lower(mag_t res, const mag_t x, ulong y); void mag_add_ui_2exp_si(mag_t z, const mag_t x, ulong y, slong e); void mag_div(mag_t z, const mag_t x, const mag_t y); void mag_div_lower(mag_t z, const mag_t x, const mag_t y); MAG_INLINE void mag_inv(mag_t res, const mag_t x) { mag_t t; mag_init(t); /* no need to free */ mag_one(t); mag_div(res, t, x); } MAG_INLINE void mag_inv_lower(mag_t res, const mag_t x) { mag_t t; mag_init(t); /* no need to free */ mag_one(t); mag_div_lower(res, t, x); } void mag_mul_2exp_si(mag_t z, const mag_t x, slong y); void mag_mul_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t y); void mag_sub(mag_t z, const mag_t x, const mag_t y); void mag_sub_lower(mag_t z, const mag_t x, const mag_t y); /* Fast versions (no infs/nans, small exponents). Note that this applies to outputs too! */ MAG_INLINE void mag_fast_init_set(mag_t x, const mag_t y) { MAG_EXP(x) = MAG_EXP(y); MAG_MAN(x) = MAG_MAN(y); } MAG_INLINE void mag_fast_zero(mag_t x) { MAG_EXP(x) = 0; MAG_MAN(x) = 0; } MAG_INLINE int mag_fast_is_zero(const mag_t x) { return MAG_MAN(x) == 0; } MAG_INLINE void mag_fast_mul(mag_t z, const mag_t x, const mag_t y) { if (MAG_MAN(x) == 0 || MAG_MAN(y) == 0) { mag_fast_zero(z); } else { MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + LIMB_ONE; MAG_EXP(z) = MAG_EXP(x) + MAG_EXP(y); MAG_FAST_ADJUST_ONE_TOO_SMALL(z); } } MAG_INLINE void mag_fast_mul_2exp_si(mag_t z, const mag_t x, slong y) { if (MAG_MAN(x) == 0) { mag_fast_zero(z); } else { MAG_MAN(z) = MAG_MAN(x); MAG_EXP(z) = MAG_EXP(x) + y; } } MAG_INLINE void mag_fast_addmul(mag_t z, const mag_t x, const mag_t y) { if (MAG_MAN(z) == 0) { mag_fast_mul(z, x, y); } else if (MAG_MAN(x) == 0 || MAG_MAN(y) == 0) { return; } else { slong shift, e; /* x*y < 2^e */ e = MAG_EXP(x) + MAG_EXP(y); shift = MAG_EXP(z) - e; if (shift >= 0) { if (shift >= MAG_BITS) MAG_MAN(z)++; else MAG_MAN(z) = MAG_MAN(z) + (MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) >> shift) + 1; } else { shift = -shift; MAG_EXP(z) = e; if (shift >= MAG_BITS) MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + 2; else MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + (MAG_MAN(z) >> shift) + 2; MAG_FAST_ADJUST_ONE_TOO_SMALL(z); } MAG_FAST_ADJUST_ONE_TOO_LARGE(z); } } MAG_INLINE void mag_fast_add_2exp_si(mag_t z, const mag_t x, slong e) { /* Must be zero */ if (mag_is_special(x)) { MAG_MAN(z) = MAG_ONE_HALF; MAG_EXP(z) = e + 1; } else { slong shift; shift = MAG_EXP(x) - e; if (shift > 0) { MAG_EXP(z) = MAG_EXP(x); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(x) + LIMB_ONE; else MAG_MAN(z) = MAG_MAN(x) + (LIMB_ONE << (MAG_BITS - shift)); } else { shift = -shift; MAG_EXP(z) = e + 1; if (shift >= MAG_BITS) MAG_MAN(z) = MAG_ONE_HALF + LIMB_ONE; else MAG_MAN(z) = MAG_ONE_HALF + (MAG_MAN(x) >> (shift + 1)) + LIMB_ONE; } MAG_FAST_ADJUST_ONE_TOO_LARGE(z); } } /* requires that x is positive and finite */ #define MAG_SET_D_2EXP(man, exp, x, xexp) \ do { \ int __cexp; \ double __x; \ int __fix; \ mp_limb_t __man; \ __x = frexp((x), &__cexp); \ __man = (mp_limb_t)(__x * (double)(LIMB_ONE << MAG_BITS)) + 1; \ __fix = __man >> (MAG_BITS); \ __man = (__man >> __fix) + __fix; \ (man) = __man; \ (exp) = (xexp) + __cexp + __fix; \ } while (0); /* requires that x is positive and finite */ #define MAG_SET_D_2EXP_LOWER(man, exp, x, xexp) \ do { \ int __cexp; \ double __x; \ int __fix; \ mp_limb_t __man; \ __x = frexp((x), &__cexp); \ __man = (mp_limb_t)(__x * (double)(LIMB_ONE << MAG_BITS)) - 1; \ __fix = __man < MAG_ONE_HALF; \ __man = (__man << __fix); \ (man) = __man; \ (exp) = (xexp) + __cexp - __fix; \ } while (0); void mag_set_d(mag_t z, double x); void mag_set_d_lower(mag_t z, double x); void mag_set_d_2exp_fmpz(mag_t z, double c, const fmpz_t exp); void mag_set_d_2exp_fmpz_lower(mag_t z, double c, const fmpz_t exp); void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t man, const fmpz_t exp); #include "fmpr.h" void mag_set_fmpr(mag_t x, const fmpr_t y); void mag_get_fmpr(fmpr_t x, const mag_t r); void mag_randtest_special(mag_t x, flint_rand_t state, slong expbits); void mag_randtest(mag_t x, flint_rand_t state, slong expbits); void mag_fprint(FILE * file, const mag_t x); void mag_fprintd(FILE * file, const mag_t x, slong d); MAG_INLINE void mag_print(const mag_t x) { mag_fprint(stdout, x); } MAG_INLINE void mag_printd(const mag_t x, slong d) { mag_fprintd(stdout, x, d); } void mag_get_fmpq(fmpq_t y, const mag_t x); void mag_get_fmpz(fmpz_t res, const mag_t x); void mag_get_fmpz_lower(fmpz_t res, const mag_t x); int mag_cmp(const mag_t x, const mag_t y); int mag_cmp_2exp_si(const mag_t x, slong e); MAG_INLINE void mag_min(mag_t z, const mag_t x, const mag_t y) { if (mag_cmp(x, y) <= 0) mag_set(z, x); else mag_set(z, y); } MAG_INLINE void mag_max(mag_t z, const mag_t x, const mag_t y) { if (mag_cmp(x, y) >= 0) mag_set(z, x); else mag_set(z, y); } MAG_INLINE mag_ptr _mag_vec_init(slong n) { slong i; mag_ptr v = (mag_ptr) flint_malloc(sizeof(mag_struct) * n); for (i = 0; i < n; i++) mag_init(v + i); return v; } MAG_INLINE void _mag_vec_clear(mag_ptr v, slong n) { slong i; for (i = 0; i < n; i++) mag_clear(v + i); flint_free(v); } double mag_get_d(const mag_t z); double mag_get_d_log2_approx(const mag_t x); /* TODO: document */ double mag_d_log_upper_bound(double x); double mag_d_log_lower_bound(double x); void mag_log1p(mag_t z, const mag_t x); void mag_log_ui(mag_t t, ulong n); void mag_log(mag_t z, const mag_t x); void mag_log_lower(mag_t z, const mag_t x); void mag_neg_log(mag_t z, const mag_t x); void mag_neg_log_lower(mag_t z, const mag_t x); void mag_exp(mag_t y, const mag_t x); void mag_exp_lower(mag_t y, const mag_t x); void mag_expinv(mag_t res, const mag_t x); void mag_expinv_lower(mag_t y, const mag_t x); void mag_expm1(mag_t y, const mag_t x); void mag_exp_tail(mag_t z, const mag_t x, ulong N); void mag_sinh(mag_t y, const mag_t x); void mag_sinh_lower(mag_t y, const mag_t x); void mag_cosh(mag_t y, const mag_t x); void mag_cosh_lower(mag_t y, const mag_t x); void mag_pow_ui(mag_t z, const mag_t x, ulong e); void mag_pow_ui_lower(mag_t z, const mag_t x, ulong e); void mag_pow_fmpz(mag_t z, const mag_t x, const fmpz_t e); void mag_pow_fmpz_lower(mag_t z, const mag_t x, const fmpz_t e); void mag_const_pi(mag_t res); void mag_const_pi_lower(mag_t res); void mag_atan(mag_t res, const mag_t x); void mag_atan_lower(mag_t res, const mag_t x); void mag_fac_ui(mag_t z, ulong n); void mag_rfac_ui(mag_t z, ulong n); void mag_bin_uiui(mag_t res, ulong n, ulong k); /* TODO: test */ void mag_bernoulli_div_fac_ui(mag_t z, ulong n); /* TODO: test */ void mag_set_fmpz_2exp_fmpz_lower(mag_t z, const fmpz_t man, const fmpz_t exp); void mag_sqrt(mag_t y, const mag_t x); void mag_sqrt_lower(mag_t y, const mag_t x); void mag_rsqrt(mag_t y, const mag_t x); void mag_rsqrt_lower(mag_t y, const mag_t x); void mag_root(mag_t y, const mag_t x, ulong n); void mag_hypot(mag_t z, const mag_t x, const mag_t y); void mag_binpow_uiui(mag_t b, ulong m, ulong n); void mag_polylog_tail(mag_t u, const mag_t z, slong sigma, ulong d, ulong N); void mag_geom_series(mag_t res, const mag_t x, ulong n); void mag_hurwitz_zeta_uiui(mag_t res, ulong s, ulong a); void mag_set_ui(mag_t z, ulong x); void mag_set_ui_lower(mag_t z, ulong x); /* TODO: test functions below */ void mag_set_ui_2exp_si(mag_t z, ulong v, slong e); MAG_INLINE void mag_set_fmpz(mag_t z, const fmpz_t x) { fmpz_t exp; *exp = 0; mag_set_fmpz_2exp_fmpz(z, x, exp); } MAG_INLINE void mag_set_fmpz_lower(mag_t z, const fmpz_t x) { fmpz_t exp; *exp = 0; mag_set_fmpz_2exp_fmpz_lower(z, x, exp); } MAG_INLINE void mag_mul_ui(mag_t z, const mag_t x, ulong y) { mag_t t; mag_init(t); /* no need to clear */ mag_set_ui(t, y); mag_mul(z, x, t); } MAG_INLINE void mag_mul_ui_lower(mag_t z, const mag_t x, ulong y) { mag_t t; mag_init(t); /* no need to clear */ mag_set_ui_lower(t, y); mag_mul_lower(z, x, t); } MAG_INLINE void mag_mul_fmpz(mag_t z, const mag_t x, const fmpz_t y) { mag_t t; mag_init(t); mag_set_fmpz(t, y); mag_mul(z, x, t); mag_clear(t); } MAG_INLINE void mag_mul_fmpz_lower(mag_t z, const mag_t x, const fmpz_t y) { mag_t t; mag_init(t); mag_set_fmpz_lower(t, y); mag_mul_lower(z, x, t); mag_clear(t); } MAG_INLINE void mag_div_ui(mag_t z, const mag_t x, ulong y) { mag_t t; mag_init(t); /* no need to clear */ mag_set_ui_lower(t, y); mag_div(z, x, t); } MAG_INLINE void mag_div_fmpz(mag_t z, const mag_t x, const fmpz_t y) { mag_t t; mag_init(t); mag_set_fmpz_lower(t, y); mag_div(z, x, t); mag_clear(t); } MAG_INLINE slong mag_allocated_bytes(const mag_t x) { return fmpz_allocated_bytes(MAG_EXPREF(x)); } int mag_load_str(mag_t res, const char * data); char * mag_dump_str(const mag_t x); int mag_load_file(mag_t res, FILE *stream); int mag_dump_file(FILE* stream, const mag_t x); #ifdef __cplusplus } #endif #endif arb-2.22.1/mag/000077500000000000000000000000001417376376500131315ustar00rootroot00000000000000arb-2.22.1/mag/add.c000066400000000000000000000054411417376376500140310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_add(mag_t z, const mag_t x, const mag_t y) { if (mag_is_zero(x)) { mag_set(z, y); } else if (mag_is_zero(y)) { mag_set(z, x); } else if (mag_is_inf(x) || mag_is_inf(y)) { mag_inf(z); } else { slong shift; shift = _fmpz_sub_small(MAG_EXPREF(x), MAG_EXPREF(y)); if (shift == 0) { _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(x)); MAG_MAN(z) = MAG_MAN(x) + MAG_MAN(y); MAG_ADJUST_ONE_TOO_LARGE(z); /* may need two adjustments */ } else if (shift > 0) { _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(x)); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(x) + LIMB_ONE; else MAG_MAN(z) = MAG_MAN(x) + (MAG_MAN(y) >> shift) + LIMB_ONE; } else { shift = -shift; _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(y)); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(y) + LIMB_ONE; else MAG_MAN(z) = MAG_MAN(y) + (MAG_MAN(x) >> shift) + LIMB_ONE; } /* TODO: combine */ MAG_ADJUST_ONE_TOO_LARGE(z); } } void mag_add_lower(mag_t z, const mag_t x, const mag_t y) { if (mag_is_zero(x)) { mag_set(z, y); } else if (mag_is_zero(y)) { mag_set(z, x); } else if (mag_is_inf(x) || mag_is_inf(y)) { mag_inf(z); } else { slong shift; shift = _fmpz_sub_small(MAG_EXPREF(x), MAG_EXPREF(y)); if (shift == 0) { _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(x)); MAG_MAN(z) = MAG_MAN(x) + MAG_MAN(y); } else if (shift > 0) { _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(x)); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(x); else MAG_MAN(z) = MAG_MAN(x) + (MAG_MAN(y) >> shift); } else { shift = -shift; _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(y)); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(y); else MAG_MAN(z) = MAG_MAN(y) + (MAG_MAN(x) >> shift); } if (MAG_MAN(z) >> MAG_BITS) { MAG_MAN(z) >>= 1; _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(z), 1); } } } arb-2.22.1/mag/add_2exp_fmpz.c000066400000000000000000000026071417376376500160240ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_add_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t e) { if (mag_is_special(x)) { if (mag_is_zero(x)) { MAG_MAN(z) = MAG_ONE_HALF; _fmpz_add_fast(MAG_EXPREF(z), e, 1); } else { mag_inf(z); } } else { slong shift; shift = _fmpz_sub_small(MAG_EXPREF(x), e); if (shift > 0) { _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(x)); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_MAN(x) + LIMB_ONE; else MAG_MAN(z) = MAG_MAN(x) + (LIMB_ONE << (MAG_BITS - shift)); } else { shift = -shift; _fmpz_add_fast(MAG_EXPREF(z), e, 1); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_ONE_HALF + LIMB_ONE; else MAG_MAN(z) = MAG_ONE_HALF + (MAG_MAN(x) >> (shift + 1)) + LIMB_ONE; } MAG_ADJUST_ONE_TOO_LARGE(z); } } arb-2.22.1/mag/add_ui.c000066400000000000000000000013211417376376500145170ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_add_ui(mag_t y, const mag_t x, ulong k) { mag_t t; mag_init(t); /* no need to free */ mag_set_ui(t, k); mag_add(y, x, t); } void mag_add_ui_lower(mag_t res, const mag_t x, ulong k) { mag_t t; mag_init(t); mag_set_ui_lower(t, k); /* no need to free */ mag_add_lower(res, x, t); } arb-2.22.1/mag/add_ui_2exp_si.c000066400000000000000000000010741417376376500161550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_add_ui_2exp_si(mag_t z, const mag_t x, ulong y, slong e) { mag_t t; mag_init(t); mag_set_ui_2exp_si(t, y, e); mag_add(z, x, t); mag_clear(t); } arb-2.22.1/mag/addmul.c000066400000000000000000000031531417376376500145450ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_addmul(mag_t z, const mag_t x, const mag_t y) { if (mag_is_zero(z)) { mag_mul(z, x, y); } else if (mag_is_inf(z) || mag_is_inf(x) || mag_is_inf(y)) { mag_inf(z); } else if (mag_is_zero(x) || mag_is_zero(y)) { return; } else { slong shift; fmpz_t e; fmpz_init(e); /* x*y < 2^e */ _fmpz_add2_fast(e, MAG_EXPREF(x), MAG_EXPREF(y), 0); shift = _fmpz_sub_small(MAG_EXPREF(z), e); if (shift >= 0) { if (shift >= MAG_BITS) MAG_MAN(z)++; else MAG_MAN(z) = MAG_MAN(z) + (MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) >> shift) + LIMB_ONE; } else { shift = -shift; fmpz_swap(MAG_EXPREF(z), e); if (shift >= MAG_BITS) MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + (2 * LIMB_ONE); else MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + (MAG_MAN(z) >> shift) + (2 * LIMB_ONE); MAG_ADJUST_ONE_TOO_SMALL(z); } MAG_ADJUST_ONE_TOO_LARGE(z); fmpz_clear(e); } } arb-2.22.1/mag/atan.c000066400000000000000000000051511417376376500142220ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arb.h" /* for atan table */ static double mag_atan_d(double x) { double t, u, v; int p, q, flip; t = x; flip = 0; if (t > 1.0) { t = 1.0 / t; flip = 1; } q = ldexp(1.0, ARB_ATAN_TAB1_BITS); p = t * (1 << ARB_ATAN_TAB1_BITS); if (p == (1 << ARB_ATAN_TAB1_BITS)) p--; #if FLINT_BITS == 64 v = arb_atan_tab1[p][ARB_ATAN_TAB1_LIMBS - 1] * ldexp(1.0, -FLINT_BITS); #else v = arb_atan_tab1[p][ARB_ATAN_TAB1_LIMBS - 1] * ldexp(1.0, -FLINT_BITS) + arb_atan_tab1[p][ARB_ATAN_TAB1_LIMBS - 2] * ldexp(1.0, -2 * FLINT_BITS); #endif t = (q * t - p) / (p * t + q); /* t - t^3/3 + t^5/5 */ u = t * t; t = (t * (1.0 / 15.0)) * (15.0 - 5.0 * u + 3.0 * (u * u)); v += t; if (flip) v = 1.5707963267948966192 - v; return v; } void mag_atan(mag_t res, const mag_t x) { if (mag_is_zero(x)) { mag_zero(res); } else if (mag_cmp_2exp_si(x, MAG_BITS) > 0) { mag_const_pi(res); mag_mul_2exp_si(res, res, -1); } else if (mag_cmp_2exp_si(x, -(MAG_BITS / 2)) < 0) { mag_set(res, x); } else { double t; t = ldexp(MAG_MAN(x), MAG_EXP(x) - MAG_BITS); t = mag_atan_d(t); t = t * (1.0 + 1e-12); mag_set_d(res, t); } } void mag_atan_lower(mag_t res, const mag_t x) { if (mag_is_zero(x)) { mag_zero(res); } else if (mag_is_inf(x)) { mag_const_pi_lower(res); mag_mul_2exp_si(res, res, -1); } else if (mag_cmp_2exp_si(x, MAG_BITS) > 0) { /* atan(x) > pi/2 - 1/x */ mag_t t; mag_init(t); mag_one(t); mag_div(t, t, x); mag_const_pi_lower(res); mag_mul_2exp_si(res, res, -1); mag_sub_lower(res, res, t); mag_clear(t); } else if (mag_cmp_2exp_si(x, -MAG_BITS) < 0) { /* atan(x) > x - x^2 */ mag_t t; mag_init(t); mag_mul(t, x, x); mag_sub_lower(res, x, t); mag_clear(t); } else { double t; t = ldexp(MAG_MAN(x), MAG_EXP(x) - MAG_BITS); t = mag_atan_d(t); t = t * (1.0 - 1e-12); mag_set_d_lower(res, t); } } arb-2.22.1/mag/bernoulli_div_fac_ui.c000066400000000000000000000031671417376376500174470ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" const int mag_bernoulli_div_fac_ui_tab[32] = { 1, 536870912, -3, 715827883, -9, 763549742, -14, 581752185, -20, 930803495, -25, 752164440, -30, 609225645, -36, 987456906, -41, 800365631, -46, 648744507, -52, 1051701970, -57, 852476898, -62, 690991623, -67, 560096688, -73, 907994540, -78, 735992650, }; /* computes upper bound for B_n / n! */ void mag_bernoulli_div_fac_ui(mag_t z, ulong n) { if (n % 2 == 1) { if (n == 1) { mag_one(z); mag_mul_2exp_si(z, z, -1); } else { mag_zero(z); } } else if (n < 32) { _fmpz_demote(MAG_EXPREF(z)); MAG_EXP(z) = mag_bernoulli_div_fac_ui_tab[n]; MAG_MAN(z) = mag_bernoulli_div_fac_ui_tab[n + 1]; } else { /* upper bound for 1/(2pi) */ mag_set_ui_2exp_si(z, 683565276, -32); /* 2 (1/(2pi))^n */ mag_pow_ui(z, z, n); mag_mul_2exp_si(z, z, 1); /* we should multiply by an upper bound for zeta(n), but the error in the upper bound for 1/(2pi) used above is already larger than this factor when n >= 32, so there is no need */ } } arb-2.22.1/mag/bin_uiui.c000066400000000000000000000026451417376376500151070ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_bin_uiui(mag_t res, ulong n, ulong k) { mag_t t; if (k > n) { mag_zero(res); return; } if (k > n / 2) k = n - k; if (k == 0) { mag_one(res); return; } if (k == 1) { mag_set_ui(res, n); return; } mag_init(t); if (n < 256 && k < 256) { /* using accurate (lookup table) factorials */ mag_fac_ui(res, n); mag_rfac_ui(t, k); mag_mul(res, res, t); mag_rfac_ui(t, n - k); mag_mul(res, res, t); } else { /* binary entropy bound (n/(n-k))^(n-k) (n/k)^k = n^n / (k^k (n-k)^(n-k)) */ mag_set_ui(res, n); mag_div_ui(res, res, n - k); mag_pow_ui(res, res, n - k); /* (n/(n-k))^(n-k) is also bounded by exp(k) */ mag_set_ui(t, k); mag_exp(t, t); mag_min(res, res, t); mag_set_ui(t, n); mag_div_ui(t, t, k); mag_pow_ui(t, t, k); mag_mul(res, res, t); } mag_clear(t); } arb-2.22.1/mag/binpow_uiui.c000066400000000000000000000020071417376376500156250ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" /* bound (1 + 1/m)^n, m > 0, n >= 0 */ void mag_binpow_uiui(mag_t b, ulong m, ulong n) { mag_t t; if (m == 0) { mag_inf(b); return; } mag_init(t); /* bound by exp(n/m) <= 1 + (n/m) + (n/m)^2 */ if (m > n) { mag_set_ui(t, n); /* x = n/m */ mag_div_ui(t, t, m); mag_mul(b, t, t); /* x^2 */ mag_add(b, b, t); /* x */ mag_one(t); mag_add(b, b, t); /* 1 */ } else { mag_one(b); mag_div_ui(b, b, m); mag_one(t); mag_add(t, t, b); mag_pow_ui(b, t, n); } mag_clear(t); } arb-2.22.1/mag/clear.c000066400000000000000000000010471417376376500143650ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_clear(mag_t x) { /* fmpz_clear(), but avoids a redundant store */ if (COEFF_IS_MPZ(MAG_EXP(x))) _fmpz_clear_mpz(MAG_EXP(x)); } arb-2.22.1/mag/cmp.c000066400000000000000000000015341417376376500140570ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int mag_cmp(const mag_t x, const mag_t y) { int c; if (mag_equal(x, y)) return 0; if (mag_is_special(x) || mag_is_special(y)) { if (mag_is_zero(x)) return -1; if (mag_is_zero(y)) return 1; if (mag_is_inf(x)) return 1; if (mag_is_inf(y)) return -1; } c = fmpz_cmp(MAG_EXPREF(x), MAG_EXPREF(y)); if (c == 0) return (MAG_MAN(x) < MAG_MAN(y)) ? -1 : 1; return (c < 0) ? -1 : 1; } arb-2.22.1/mag/cmp_2exp_si.c000066400000000000000000000021511417376376500155040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int mag_cmp_2exp_si(const mag_t x, slong e) { int ispow2; if (mag_is_special(x)) { if (mag_is_zero(x)) return -1; return 1; } ispow2 = (MAG_MAN(x) == MAG_ONE_HALF); /* Fast path. */ if (!COEFF_IS_MPZ(MAG_EXP(x))) { if (ispow2 && (MAG_EXP(x) - 1 == e)) return 0; else return (MAG_EXP(x) <= e) ? -1 : 1; } if (ispow2) { fmpz_t t; fmpz_init(t); fmpz_one(t); fmpz_add_si(t, t, e); if (fmpz_equal(MAG_EXPREF(x), t)) { fmpz_clear(t); return 0; } fmpz_clear(t); } return (fmpz_cmp_si(MAG_EXPREF(x), e) <= 0) ? -1 : 1; } arb-2.22.1/mag/const_pi.c000066400000000000000000000012021417376376500151060ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_const_pi(mag_t res) { fmpz_clear(MAG_EXPREF(res)); MAG_MAN(res) = 843314857; MAG_EXP(res) = 2; } void mag_const_pi_lower(mag_t res) { fmpz_clear(MAG_EXPREF(res)); MAG_MAN(res) = 843314856; MAG_EXP(res) = 2; } arb-2.22.1/mag/cosh.c000066400000000000000000000022011417376376500142240ustar00rootroot00000000000000/* Copyright (C) 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_cosh(mag_t res, const mag_t x) { if (mag_is_zero(x)) { mag_one(res); } else if (mag_is_inf(x)) { mag_inf(res); } else { mag_t t; mag_init(t); mag_exp(t, x); mag_expinv(res, x); mag_add(res, res, t); mag_mul_2exp_si(res, res, -1); mag_clear(t); } } void mag_cosh_lower(mag_t res, const mag_t x) { if (mag_is_zero(x)) { mag_one(res); } else if (mag_is_inf(x)) { mag_inf(res); } else { mag_t t; mag_init(t); mag_exp_lower(t, x); mag_expinv_lower(res, x); mag_add_lower(res, res, t); mag_mul_2exp_si(res, res, -1); mag_clear(t); } } arb-2.22.1/mag/d_log.c000066400000000000000000000153151417376376500143660ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" /* This is a bad implementation the logarithm function, Any decent libm should compute log() with < 1 ulp error, but we have no way to know that this is the case (the IEEE 754 and C language standards make virtually no guarantees whatsoever about transcendental functions). So here is a bad implementation which almost certainly has much worse accuracy than the libm log(), but which is simple and for which we can give an explicit error bound. The only precomputed constants are rational numbers and logarithms of rational numbers, which are easy to validate. First write x = 2^n * t with sqrt(2)/2 < t < sqrt(2) (a few ulps outside this range is fine). Then write t = m/32 + u with |u| <= 1/64. We have 23 <= m <= 45. Let v = 32*u/m (note that |v| <= 1/46). Then we have log(x) = log(2^n*t) = n*log(2) + log(t) = n*log(2) + log(m/32 + u) = n*log(2) + log(m/32 + m/32 * 32*u/m) = n*log(2) + log(m/32) + log(1 + 32*u/m) = n*log(2) + (log(m/32) + log(1 + v)) We compute log(x) as t1 + (t2 + t3) where t1 ~= n*log(2) involves two roundings, t2 involves one rounding, and t3 ~= v - [v^2/2 + ...] involves two roundings for the multiplication by 1/m, one rounding for subtraction, plus a much smaller error contribution due to the error in the approximation of the terms in brackets. Now consider the outer sum t1 + (t2 + t3). When n != 0, t1 will always be about twice as large as (t2+t3). When n = 0, t2 will always be exactly zero or about twice as large as t3. So there can be no significant cancellation, and most of the final error comes from the largest nonzero term. By inspection, the final error is clearly bounded by 10 ulp (a 3 ulp or maybe even 2 ulp bound could probably be proved with a careful calculation). Multiplying the output by 1 +/- 1e-14, we get guaranteed upper/lower bounds for the logarithm. This factor is chosen conservatively so that we get correct bounds even on x87 or if the CPU rounding mode has been changed. */ #define LOG_TAB_STEP 32 const double d_log_tab[] = { -0.6931471805599453094172, /* log(16/32) */ -0.6325225587435104668366, /* log(17/32) */ -0.5753641449035618548784, /* log(18/32) */ -0.5212969236332860870771, /* log(19/32) */ -0.4700036292457355536509, /* log(20/32) */ -0.4212134650763035505856, /* log(21/32) */ -0.374693449441410693607, /* log(22/32) */ -0.3302416868705768562794, /* log(23/32) */ -0.2876820724517809274392, /* log(24/32) */ -0.2468600779315257978846, /* log(25/32) */ -0.2076393647782445016154, /* log(26/32) */ -0.1698990367953974729004, /* log(27/32) */ -0.1335313926245226231463, /* log(28/32) */ -0.09844007281325251990289, /* log(29/32) */ -0.06453852113757117167292, /* log(30/32) */ -0.031748698314580301157, /* log(31/32) */ 0.0, /* log(32/32) */ 0.03077165866675368837103, /* log(33/32) */ 0.06062462181643484258061, /* log(34/32) */ 0.08961215868968713261995, /* log(35/32) */ 0.1177830356563834545388, /* log(36/32) */ 0.1451820098444978972819, /* log(37/32) */ 0.1718502569266592223401, /* log(38/32) */ 0.1978257433299198803626, /* log(39/32) */ 0.2231435513142097557663, /* log(40/32) */ 0.2478361639045812567806, /* log(41/32) */ 0.2719337154836417588317, /* log(42/32) */ 0.2954642128938358763867, /* log(43/32) */ 0.3184537311185346158102, /* log(44/32) */ 0.3409265869705932103051, /* log(45/32) */ 0.3629054936893684531378, /* log(46/32) */ 0.3844116989103320397348, /* log(47/32) */ }; const double d_log_inverses[] = { 0.0, 1.0, /* 1/1 */ 0.5, /* 1/2 */ 0.3333333333333333333333, /* 1/3 */ 0.25, /* 1/4 */ 0.2, /* 1/5 */ 0.1666666666666666666667, /* 1/6 */ 0.1428571428571428571429, /* 1/7 */ 0.125, /* 1/8 */ 0.1111111111111111111111, /* 1/9 */ 0.1, /* 1/10 */ 0.09090909090909090909091, /* 1/11 */ 0.08333333333333333333333, /* 1/12 */ 0.07692307692307692307692, /* 1/13 */ 0.07142857142857142857143, /* 1/14 */ 0.06666666666666666666667, /* 1/15 */ 0.0625, /* 1/16 */ 0.05882352941176470588235, /* 1/17 */ 0.05555555555555555555556, /* 1/18 */ 0.05263157894736842105263, /* 1/19 */ 0.05, /* 1/20 */ 0.04761904761904761904762, /* 1/21 */ 0.04545454545454545454545, /* 1/22 */ 0.0434782608695652173913, /* 1/23 */ 0.04166666666666666666667, /* 1/24 */ 0.04, /* 1/25 */ 0.03846153846153846153846, /* 1/26 */ 0.03703703703703703703704, /* 1/27 */ 0.03571428571428571428571, /* 1/28 */ 0.03448275862068965517241, /* 1/29 */ 0.03333333333333333333333, /* 1/30 */ 0.03225806451612903225806, /* 1/31 */ 0.03125, /* 1/32 */ 0.0303030303030303030303, /* 1/33 */ 0.02941176470588235294118, /* 1/34 */ 0.02857142857142857142857, /* 1/35 */ 0.02777777777777777777778, /* 1/36 */ 0.02702702702702702702703, /* 1/37 */ 0.02631578947368421052632, /* 1/38 */ 0.02564102564102564102564, /* 1/39 */ 0.025, /* 1/40 */ 0.02439024390243902439024, /* 1/41 */ 0.02380952380952380952381, /* 1/42 */ 0.02325581395348837209302, /* 1/43 */ 0.02272727272727272727273, /* 1/44 */ 0.02222222222222222222222, /* 1/45 */ 0.02173913043478260869565, /* 1/46 */ 0.02127659574468085106383, /* 1/47 */ }; double mag_d_bad_log(double x) { double t, u, v, t1, t2, t3; int m, n; if (x <= 0.0 || (x-x) != (x-x)) { if (x == 0.0) return -D_INF; else if (x > 0.0) return D_INF; else return D_NAN; } if (x < 1 + 1./LOG_TAB_STEP && x > 1 - 1./LOG_TAB_STEP) { return -d_polyval(d_log_inverses, 12, 1.-x); } t = frexp(x, &n); if (t < 0.7071067811865475244008) { t *= 2.0; n -= 1; } m = floor(t * LOG_TAB_STEP + 0.5); u = t * LOG_TAB_STEP - m; /* v = -u / m; */ v = -u * d_log_inverses[m]; t1 = n * (-d_log_tab[0]); t2 = d_log_tab[m - LOG_TAB_STEP / 2]; t3 = -d_polyval(d_log_inverses, 11, v); return t1 + (t2 + t3); } double mag_d_log_upper_bound(double x) { if (x >= 1.0) return mag_d_bad_log(x) * (1 + 1e-14); else return mag_d_bad_log(x) * (1 - 1e-14); } double mag_d_log_lower_bound(double x) { if (x >= 1.0) return mag_d_bad_log(x) * (1 - 1e-14); else return mag_d_bad_log(x) * (1 + 1e-14); } arb-2.22.1/mag/div.c000066400000000000000000000023451417376376500140630ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_div(mag_t z, const mag_t x, const mag_t y) { if (mag_is_special(x) || mag_is_special(y)) { if (mag_is_zero(y) || mag_is_inf(x)) mag_inf(z); else mag_zero(z); } else { mp_limb_t q; slong fix; #if FLINT_BITS == 64 q = (MAG_MAN(x) << MAG_BITS) / MAG_MAN(y) + 1; #else mp_limb_t hi, lo, r; lo = MAG_MAN(x) << MAG_BITS; hi = MAG_MAN(x) >> (FLINT_BITS - MAG_BITS); udiv_qrnnd(q, r, hi, lo, MAG_MAN(y)); q += 1; #endif fix = q >> MAG_BITS; q = (q >> fix) + fix; /* could overflow to next power of two */ if (q >> MAG_BITS) { q >>= 1; fix += 1; } MAG_MAN(z) = q; _fmpz_sub2_fast(MAG_EXPREF(z), MAG_EXPREF(x), MAG_EXPREF(y), fix); } } arb-2.22.1/mag/div_lower.c000066400000000000000000000023171417376376500152720ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_div_lower(mag_t z, const mag_t x, const mag_t y) { if (mag_is_special(x) || mag_is_special(y)) { if (mag_is_inf(x) && !mag_is_inf(y)) mag_inf(z); else mag_zero(z); } else { mp_limb_t q; slong fix; #if FLINT_BITS == 64 q = (MAG_MAN(x) << MAG_BITS) / MAG_MAN(y); #else mp_limb_t hi, lo, r; lo = MAG_MAN(x) << MAG_BITS; hi = MAG_MAN(x) >> (FLINT_BITS - MAG_BITS); udiv_qrnnd(q, r, hi, lo, MAG_MAN(y)); #endif fix = q >> MAG_BITS; q = q >> fix; /* could overflow to next power of two */ if (q >> MAG_BITS) { q >>= 1; fix += 1; } MAG_MAN(z) = q; _fmpz_sub2_fast(MAG_EXPREF(z), MAG_EXPREF(x), MAG_EXPREF(y), fix); } } arb-2.22.1/mag/dump_file.c000066400000000000000000000012141417376376500152370ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "mag.h" int mag_dump_file(FILE* stream, const mag_t x) { int nwrite; char* data = mag_dump_str(x); nwrite = fputs(data, stream); if (nwrite == EOF) return nwrite; flint_free(data); return 0; } arb-2.22.1/mag/dump_str.c000066400000000000000000000010571417376376500151350ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "arf.h" #include "mag.h" char * mag_dump_str(const mag_t x) { char * res; arf_t y; arf_init_set_mag_shallow(y, x); res = arf_dump_str(y); return res; } arb-2.22.1/mag/exp.c000066400000000000000000000104621417376376500140740ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" static const double inverse_factorials[] = { 1.0, 1.0, 0.5, 0.16666666666666666667, 0.041666666666666666667, 0.0083333333333333333333, 0.0013888888888888888889, 0.0001984126984126984127, 0.000024801587301587301587, 2.7557319223985890653e-6, 2.7557319223985890653e-7, 2.5052108385441718775e-8, 2.0876756987868098979e-9, 1.6059043836821614599e-10, 1.1470745597729724714e-11, 7.6471637318198164759e-13 }; /* warning: requires |x| < 2^24 or thereabout */ void _mag_exp_d(mag_t res, double x, int roundup) { double u, nlog2, eps, eps2; slong n; if (roundup) { eps = 1e-13; eps2 = 6e-13; } else { eps = -1e-13; eps2 = -6e-13; } n = floor(x * 1.4426950408889634074 + 0.5); /* does not need to be exact */ /* perturbed in opposite direction before subtraction */ if (n >= 0) nlog2 = n * 0.69314718055994530942 * (1.0 - eps); else nlog2 = n * 0.69314718055994530942 * (1.0 + eps); /* perturbed (assuming |u| < 1 for absolute error to be valid) */ u = x - nlog2 + eps; if (u >= -0.375 && u <= 0.375) u = d_polyval(inverse_factorials, 11, u) + eps2; else flint_abort(); if (roundup) mag_set_d(res, u); else mag_set_d_lower(res, u); MAG_EXP(res) += n; /* assumes x not too large */ } void mag_exp_huge(mag_t res, const mag_t x) { if (mag_cmp_2exp_si(x, 128) <= 0) { fmpz_t t; fmpz_init(t); mag_get_fmpz(t, x); MAG_MAN(res) = 729683223; /* upper bound for e */ fmpz_set_ui(MAG_EXPREF(res), 2); mag_pow_fmpz(res, res, t); fmpz_clear(t); } else { mag_inf(res); } } void mag_exp_huge_lower(mag_t res, const mag_t x) { fmpz_t t; fmpz_init(t); if (mag_cmp_2exp_si(x, 128) <= 0) { mag_get_fmpz_lower(t, x); } else { fmpz_one(t); fmpz_mul_2exp(t, t, 128); } MAG_MAN(res) = 729683222; /* lower bound for e */ fmpz_set_ui(MAG_EXPREF(res), 2); mag_pow_fmpz_lower(res, res, t); fmpz_clear(t); } void mag_exp(mag_t y, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_one(y); else mag_inf(y); } else if (COEFF_IS_MPZ(MAG_EXP(x))) { if (fmpz_sgn(MAG_EXPREF(x)) > 0) { mag_inf(y); } else { MAG_MAN(y) = MAG_ONE_HALF + 1; fmpz_one(MAG_EXPREF(y)); } } else { slong e = MAG_EXP(x); if (e <= -MAG_BITS) /* assumes MAG_BITS == 30 */ { MAG_MAN(y) = MAG_ONE_HALF + 1; fmpz_one(MAG_EXPREF(y)); } else if (e <= -(MAG_BITS / 2)) /* assumes MAG_BITS == 30 */ { MAG_MAN(y) = MAG_ONE_HALF + (MAG_MAN(x) >> (1-e)) + 2; fmpz_one(MAG_EXPREF(y)); } else if (e < 24) { _mag_exp_d(y, ldexp(MAG_MAN(x), e - MAG_BITS), 1); } else { mag_exp_huge(y, x); } } } void mag_exp_lower(mag_t y, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_one(y); else mag_inf(y); } else if (COEFF_IS_MPZ(MAG_EXP(x))) { if (fmpz_sgn(MAG_EXPREF(x)) > 0) mag_exp_huge_lower(y, x); else mag_one(y); } else { slong e = MAG_EXP(x); if (e <= -MAG_BITS) { mag_one(y); } else if (e <= -(MAG_BITS / 2)) { MAG_MAN(y) = MAG_ONE_HALF + (MAG_MAN(x) >> (1 - e)); fmpz_one(MAG_EXPREF(y)); } else if (e < 24) { _mag_exp_d(y, ldexp(MAG_MAN(x), e - MAG_BITS), 0); } else { mag_exp_huge_lower(y, x); } } } arb-2.22.1/mag/exp_tail.c000066400000000000000000000020251417376376500151010ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_exp_tail(mag_t z, const mag_t x, ulong N) { if (N == 0 || mag_is_inf(x)) { mag_exp(z, x); } else if (mag_is_zero(x)) { mag_zero(z); } else { mag_t t; mag_init(t); mag_set_ui_2exp_si(t, N, -1); /* bound by geometric series when N >= 2*x <=> N/2 >= x */ if (mag_cmp(t, x) >= 0) { /* 2 c^N / N! */ mag_pow_ui(t, x, N); mag_rfac_ui(z, N); mag_mul(z, z, t); mag_mul_2exp_si(z, z, 1); } else { mag_exp(z, x); } mag_clear(t); } } arb-2.22.1/mag/expinv.c000066400000000000000000000034701417376376500146120ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" /* defined in exp.c */ void _mag_exp_d(mag_t res, double x, int roundup); void mag_exp_huge(mag_t res, const mag_t x); void mag_exp_huge_lower(mag_t res, const mag_t x); void mag_expinv(mag_t res, const mag_t x) { if (mag_is_zero(x)) { mag_one(res); } else if (mag_is_inf(x)) { mag_zero(res); } else if (mag_cmp_2exp_si(x, 24) >= 0) { mag_exp_huge_lower(res, x); mag_inv(res, res); } else if (COEFF_IS_MPZ(MAG_EXP(x))) { mag_one(res); } else { slong e = MAG_EXP(x); if (e <= -MAG_BITS) mag_one(res); else _mag_exp_d(res, -ldexp(MAG_MAN(x), e - MAG_BITS), 1); } } void mag_expinv_lower(mag_t res, const mag_t x) { if (mag_is_zero(x)) { mag_one(res); } else if (mag_is_inf(x)) { mag_zero(res); } else if (mag_cmp_2exp_si(x, 24) >= 0) { mag_exp_huge(res, x); mag_inv_lower(res, res); } else if (COEFF_IS_MPZ(MAG_EXP(x))) { /* 1 - eps */ MAG_MAN(res) = (1 << MAG_BITS) - 1; fmpz_zero(MAG_EXPREF(res)); } else { slong e = MAG_EXP(x); if (e < -MAG_BITS) { /* 1 - eps */ MAG_MAN(res) = (1 << MAG_BITS) - 1; fmpz_zero(MAG_EXPREF(res)); } else _mag_exp_d(res, -ldexp(MAG_MAN(x), e - MAG_BITS), 0); } } arb-2.22.1/mag/expm1.c000066400000000000000000000033451417376376500143340ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_expm1(mag_t y, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_zero(y); else mag_inf(y); } else if (COEFF_IS_MPZ(MAG_EXP(x))) { if (fmpz_sgn(MAG_EXPREF(x)) > 0) { mag_inf(y); } else { fmpz_set(MAG_EXPREF(y), MAG_EXPREF(x)); MAG_MAN(y) = MAG_MAN(x) + 1; MAG_ADJUST_ONE_TOO_LARGE(y); } } else { slong e = MAG_EXP(x); if (e <= -16) { fmpz_set(MAG_EXPREF(y), MAG_EXPREF(x)); if (e < -MAG_BITS) MAG_MAN(y) = MAG_MAN(x) + 1; else MAG_MAN(y) = MAG_MAN(x) + (MAG_ONE_HALF >> 15); MAG_ADJUST_ONE_TOO_LARGE(y); } else { mag_exp(y, x); /* subtract 1 */ if (e < 6) { slong e2 = MAG_EXP(y); unsigned int c; if (e2 < MAG_BITS) { /* this is correct since exp(x) >= 1 */ MAG_MAN(y) -= (MAG_ONE_HALF >> (e2 - 1)); c = MAG_BITS - FLINT_BIT_COUNT(MAG_MAN(y)); MAG_MAN(y) <<= c; MAG_EXP(y) -= c; } } } } } arb-2.22.1/mag/fac_ui.c000066400000000000000000000300171417376376500145240ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #define MAG_FAC_TABLE_NUM 256 const int mag_fac_tab[MAG_FAC_TABLE_NUM * 2] = { 1, 536870912, 1, 536870912, 2, 536870912, 3, 805306368, 5, 805306368, 7, 1006632960, 10, 754974720, 13, 660602880, 16, 660602880, 19, 743178240, 22, 928972800, 26, 638668800, 29, 958003200, 33, 778377600, 37, 681080400, 41, 638512875, 45, 638512875, 49, 678419930, 53, 763222421, 57, 906326625, 62, 566454141, 66, 743471060, 70, 1022272707, 75, 734758508, 80, 551068881, 84, 861045127, 89, 699599166, 94, 590286796, 98, 1033001893, 103, 936157966, 108, 877648093, 113, 850221590, 118, 850221590, 123, 876791015, 128, 931590453, 133, 1018927058, 139, 573146470, 144, 662700606, 149, 786956970, 154, 959103807, 160, 599439879, 165, 768032345, 170, 1008042453, 176, 677278523, 181, 931257969, 187, 654790760, 192, 941261717, 198, 691239074, 203, 1036858610, 209, 793844874, 215, 620191308, 220, 988429896, 226, 803099291, 232, 665066600, 238, 561149944, 243, 964476466, 249, 843916908, 255, 751613496, 261, 681149731, 267, 627934908, 273, 588688976, 279, 561094181, 285, 543559988, 290, 1070133725, 296, 1070133725, 303, 543427282, 309, 560409385, 315, 586678575, 321, 623345986, 327, 672044891, 333, 735049099, 339, 815445095, 345, 917375731, 351, 1046381693, 358, 604939417, 364, 708913379, 370, 841834637, 376, 1012832298, 383, 617194682, 389, 761849685, 395, 952312106, 402, 602635005, 408, 772126100, 414, 1001351036, 421, 657136617, 427, 872759570, 434, 586385336, 440, 797117566, 447, 548018327, 453, 762087986, 459, 1071686230, 466, 761901929, 473, 547617012, 479, 795755970, 486, 584383290, 492, 867443946, 499, 650582960, 505, 986039798, 512, 754936721, 519, 583896370, 525, 912338078, 532, 719891765, 539, 573663750, 545, 923240098, 552, 750132579, 559, 615343132, 565, 1019162061, 572, 851955786, 579, 718837694, 586, 612135224, 592, 1052107416, 599, 912374400, 606, 798327600, 613, 704773585, 620, 627688974, 627, 563939312, 633, 1022140003, 640, 934299847, 647, 861307671, 654, 800746976, 661, 750700290, 668, 709646368, 675, 676381694, 682, 649960534, 689, 629649268, 696, 614891863, 703, 605284178, 710, 600555395, 717, 600555395, 724, 605247234, 731, 614704222, 738, 629111352, 745, 648771082, 752, 674113702, 759, 705712782, 766, 744306450, 773, 790825603, 780, 846430528, 787, 912557913, 794, 990980859, 802, 541942657, 809, 596983708, 816, 662278801, 823, 739889598, 830, 832375798, 837, 942925709, 845, 537762319, 852, 617586413, 859, 714084290, 866, 831238743, 873, 974107902, 881, 574571458, 888, 682303606, 895, 815566029, 902, 981227879, 910, 594102818, 917, 724062809, 924, 888108289, 932, 548129335, 939, 680879408, 946, 851099260, 953, 1070523287, 961, 677440518, 968, 862678159, 976, 552653196, 983, 712404510, 990, 923899599, 998, 602700129, 1005, 791043920, 1012, 1044425175, 1020, 693563593, 1027, 926557612, 1035, 622530896, 1042, 841389414, 1050, 571881867, 1057, 781869740, 1065, 537535447, 1072, 743310735, 1079, 1033666490, 1087, 722758991, 1094, 1016379831, 1102, 718612303, 1109, 1021776868, 1117, 730410808, 1124, 1049965536, 1132, 758764157, 1140, 551289583, 1147, 805399625, 1155, 591465350, 1162, 873335555, 1170, 648178733, 1177, 967204202, 1185, 725403152, 1193, 546885970, 1200, 828874048, 1208, 631368904, 1215, 966783634, 1223, 743970218, 1231, 575414466, 1238, 894589677, 1246, 698898186, 1254, 548744279, 1261, 865987064, 1269, 686700680, 1277, 547214604, 1284, 876398390, 1292, 705226829, 1300, 570242007, 1307, 926643260, 1315, 756517349, 1323, 620580638, 1330, 1022988396, 1338, 847162265, 1346, 704865479, 1354, 589223486, 1361, 989711324, 1369, 835068930, 1377, 707851397, 1385, 602779706, 1392, 1031318402, 1400, 886289252, 1408, 765116894, 1416, 663499806, 1424, 577970534, 1431, 1011448435, 1439, 888968351, 1447, 784792372, 1455, 695890111, 1463, 619777131, 1471, 554410011, 1478, 996205489, 1486, 898919797, 1494, 814646066, 1502, 741455208, 1510, 677736401, 1518, 622140837, 1526, 573536084, 1533, 1061937906, 1541, 987270397, 1549, 921709472, 1557, 864102630, 1565, 813471617, 1573, 768984888, 1581, 729934874, 1589, 695719177, 1597, 665824993, 1605, 639816204, 1613, 617322666, 1621, 598031333, 1629, 581678914, 1637, 568045814, 1645, 556951169, 1653, 548248807, 1661, 541824017, 1669, 537591016, 1676, 1070982102, }; const int mag_rfac_tab[MAG_FAC_TABLE_NUM * 2] = { 1, 536870912, 1, 536870912, 0, 536870912, -2, 715827883, -4, 715827883, -6, 572662307, -9, 763549742, -12, 872628277, -15, 872628277, -18, 775669579, -21, 620535663, -25, 902597328, -28, 601731552, -32, 740592680, -36, 846391634, -40, 902817743, -44, 902817743, -48, 849710817, -52, 755298504, -56, 636040846, -61, 1017665353, -65, 775364078, -69, 563901148, -74, 784558119, -79, 1046077491, -83, 669489595, -88, 823987193, -93, 976577414, -97, 558044237, -102, 615772951, -107, 656824481, -112, 678012368, -117, 678012368, -122, 657466538, -127, 618792036, -132, 565752719, -138, 1005782611, -143, 869866042, -148, 732518772, -153, 601041044, -159, 961665670, -164, 750568328, -169, 571861583, -175, 851142821, -180, 619012961, -186, 880373989, -191, 612434079, -197, 833952789, -202, 555968526, -208, 726162972, -214, 929488605, -219, 583208536, -225, 717795122, -231, 866771468, -237, 1027284702, -242, 597692918, -248, 683077620, -254, 766964346, -260, 846305485, -266, 918026288, -272, 979228041, -278, 1027386797, -284, 1060528307, -289, 538681045, -295, 538681045, -302, 1060787288, -308, 1028642219, -314, 982583612, -320, 924784576, -326, 857771201, -332, 784247955, -338, 706927734, -344, 628380208, -350, 550908676, -357, 952923115, -363, 813161058, -369, 684767207, -375, 569157159, -382, 934001491, -388, 756659436, -394, 605327549, -401, 956566990, -407, 746588871, -413, 575682985, -420, 877231215, -426, 660503503, -433, 983074981, -439, 723181595, -446, 1051900502, -452, 756422833, -458, 537900681, -465, 756607552, -472, 1052671376, -478, 724419012, -485, 986442909, -491, 664551013, -498, 886068017, -504, 584622197, -511, 763588175, -518, 987265519, -524, 631849933, -531, 800760310, -538, 1004875684, -544, 624388774, -551, 768478492, -558, 936811875, -564, 565622264, -571, 676632242, -578, 801934508, -585, 941721257, -591, 547910550, -598, 631824778, -605, 722085461, -612, 817937513, -619, 918385980, -626, 1022203525, -632, 563974359, -639, 616997589, -646, 669285520, -653, 719903753, -660, 767897336, -667, 812321149, -674, 852271370, -681, 886916547, -688, 915526759, -695, 937499401, -702, 952380344, -709, 959879401, -716, 959879401, -723, 952438476, -730, 937785576, -737, 916309571, -744, 888542614, -751, 855138756, -758, 816848961, -765, 774493830, -772, 728935369, -779, 681049104, -786, 631697720, -793, 581707253, -801, 1063693262, -808, 965622252, -815, 870420058, -822, 779117255, -829, 692548671, -836, 611353310, -844, 1071961968, -851, 933409060, -858, 807272701, -865, 693496012, -872, 591783263, -880, 1003288181, -887, 844874258, -894, 706822909, -901, 587489171, -909, 970304695, -916, 796147442, -923, 649088360, -931, 1051687470, -938, 846641485, -945, 677313188, -952, 538485019, -960, 850939290, -967, 668222264, -975, 1043078656, -982, 809176170, -989, 623943071, -997, 956463629, -1004, 728734194, -1011, 551940691, -1019, 831157747, -1026, 622153167, -1034, 925995411, -1041, 685129553, -1049, 1008006698, -1056, 737284900, -1064, 1072414399, -1071, 775531317, -1078, 557685442, -1086, 797583648, -1093, 567170594, -1101, 802186034, -1108, 564174793, -1116, 789228126, -1123, 549028262, -1131, 759736405, -1139, 1045658708, -1146, 715744998, -1154, 974631486, -1161, 660067885, -1169, 889354624, -1176, 596007287, -1184, 794676383, -1192, 1054078518, -1199, 695474487, -1207, 913033172, -1214, 596266561, -1222, 774843856, -1230, 1001818319, -1237, 644385653, -1245, 824813635, -1253, 1050508908, -1260, 665669011, -1268, 839464369, -1276, 1053445483, -1283, 657761082, -1291, 817411830, -1299, 1010905451, -1306, 622095663, -1314, 761992773, -1322, 928905476, -1329, 563506640, -1337, 680460848, -1345, 817830878, -1353, 978339742, -1360, 582453428, -1368, 690315174, -1376, 814381034, -1384, 956337361, -1391, 558955170, -1399, 650420562, -1407, 753428343, -1415, 868818269, -1423, 997387789, -1430, 569935879, -1438, 648460378, -1446, 734539189, -1454, 828378998, -1462, 930109752, -1470, 1039773347, -1477, 578656472, -1485, 641281631, -1493, 707621110, -1501, 777472121, -1509, 850567790, -1517, 926575975, -1525, 1005099363, -1532, 542838475, -1540, 583893485, -1548, 625425658, -1556, 667120702, -1564, 708642737, -1572, 749638598, -1580, 789742721, -1588, 828582526, -1596, 865784191, -1604, 900978670, -1612, 933807852, -1620, 963930686, -1628, 991029139, -1636, 1014813839, -1644, 1035029254, -1652, 1051458290, -1660, 1063926174, -1668, 1072303546, -1675, 538254329, }; void mag_fac_ui(mag_t z, ulong n) { if (n < MAG_FAC_TABLE_NUM) { _fmpz_demote(MAG_EXPREF(z)); MAG_EXP(z) = mag_fac_tab[n * 2]; MAG_MAN(z) = mag_fac_tab[n * 2 + 1]; } else { double x = n; x = ceil((((x+0.5)*mag_d_log_upper_bound(x) - x) * 1.4426950408889634074 + 2) * 1.0000001); /* x + 1 could round down for huge x, but this doesn't matter as long as the result was perturbed up above */ fmpz_set_d(MAG_EXPREF(z), x + 1); MAG_MAN(z) = MAG_ONE_HALF; } } void mag_rfac_ui(mag_t z, ulong n) { if (n < MAG_FAC_TABLE_NUM) { _fmpz_demote(MAG_EXPREF(z)); MAG_EXP(z) = mag_rfac_tab[n * 2]; MAG_MAN(z) = mag_rfac_tab[n * 2 + 1]; } else { double x = n; x = ceil((((x+0.5)*mag_d_log_lower_bound(x) - x) * 1.4426950408889634074) * -0.9999999); /* x + 1 could round down for huge x, but this doesn't matter as long as the value was perturbed up above */ fmpz_set_d(MAG_EXPREF(z), x + 1); MAG_MAN(z) = MAG_ONE_HALF; } } arb-2.22.1/mag/fprint.c000066400000000000000000000020371417376376500146010ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson Copyright (C) 2015 Arb authors This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arf.h" void mag_fprint(FILE * file, const mag_t x) { flint_fprintf(file, "("); if (mag_is_zero(x)) flint_fprintf(file, "0"); else if (mag_is_inf(x)) flint_fprintf(file, "inf"); else { fmpz_t t; fmpz_init(t); fmpz_sub_ui(t, MAG_EXPREF(x), MAG_BITS); flint_fprintf(file, "%wu * 2^", MAG_MAN(x)); fmpz_fprint(file, t); fmpz_clear(t); } flint_fprintf(file, ")"); } void mag_fprintd(FILE * file, const mag_t x, slong d) { arf_t t; arf_init(t); arf_set_mag(t, x); arf_fprintd(file, t, d); arf_clear(t); } arb-2.22.1/mag/geom_series.c000066400000000000000000000016721417376376500156040ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_geom_series(mag_t res, const mag_t x, ulong n) { if (mag_is_zero(x)) { if (n == 0) mag_one(res); else mag_zero(res); } else if (mag_is_inf(x)) { mag_inf(res); } else { mag_t t; mag_init(t); mag_one(t); mag_sub_lower(t, t, x); if (mag_is_zero(t)) { mag_inf(res); } else { mag_pow_ui(res, x, n); mag_div(res, res, t); } mag_clear(t); } } arb-2.22.1/mag/get_d.c000066400000000000000000000015201417376376500143550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" double mag_get_d(const mag_t z) { if (mag_is_zero(z)) { return 0.0; } else if (mag_is_inf(z)) { return D_INF; } else if (MAG_EXP(z) < -1000 || MAG_EXP(z) > 1000) { if (fmpz_sgn(MAG_EXPREF(z)) < 0) return ldexp(1.0, -1000); else return D_INF; } else { return ldexp(MAG_MAN(z), MAG_EXP(z) - MAG_BITS); } } arb-2.22.1/mag/get_d_log2_approx.c000066400000000000000000000017241417376376500166770ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" double mag_get_d_log2_approx(const mag_t x) { if (mag_is_zero(x)) { return COEFF_MIN; } else if (mag_is_inf(x)) { return COEFF_MAX; } else if (COEFF_IS_MPZ(MAG_EXP(x))) { if (fmpz_sgn(MAG_EXPREF(x)) < 0) return COEFF_MIN; else return COEFF_MAX; } else { slong e = MAG_EXP(x); if (e < -20 || e > 20) return e; else return e + 1.4426950408889634074 * mag_d_log_upper_bound(MAG_MAN(x) * ldexp(1.0, -MAG_BITS)); } } arb-2.22.1/mag/get_fmpq.c000066400000000000000000000010301417376376500150710ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arf.h" void mag_get_fmpq(fmpq_t y, const mag_t x) { arf_t t; arf_init_set_mag_shallow(t, x); arf_get_fmpq(y, t); } arb-2.22.1/mag/get_fmpr.c000066400000000000000000000013201417376376500150740ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_get_fmpr(fmpr_t x, const mag_t r) { if (mag_is_zero(r)) { fmpr_zero(x); } else if (mag_is_inf(r)) { fmpr_pos_inf(x); } else { fmpr_set_ui_2exp_si(x, MAG_MAN(r), -MAG_BITS); _fmpz_add2_fast(fmpr_expref(x), fmpr_expref(x), MAG_EXPREF(r), 0); } } arb-2.22.1/mag/get_fmpz.c000066400000000000000000000012711417376376500151110ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arf.h" void mag_get_fmpz(fmpz_t res, const mag_t x) { arf_t t; arf_init_set_mag_shallow(t, x); arf_get_fmpz(res, t, ARF_RND_UP); } void mag_get_fmpz_lower(fmpz_t res, const mag_t x) { arf_t t; arf_init_set_mag_shallow(t, x); arf_get_fmpz(res, t, ARF_RND_DOWN); } arb-2.22.1/mag/hurwitz_zeta_uiui.c000066400000000000000000000016051417376376500170710ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_hurwitz_zeta_uiui(mag_t res, ulong s, ulong a) { if (s <= 1 || a == 0) { mag_inf(res); } else { mag_t t, u; mag_init(t); mag_init(u); mag_one(t); mag_set_ui_lower(u, a); mag_pow_ui_lower(u, u, s - 1); mag_mul_ui_lower(res, u, a); mag_div(res, t, res); mag_mul_ui_lower(u, u, s - 1); mag_div(u, t, u); mag_add(res, res, u); mag_clear(t); mag_clear(u); } } arb-2.22.1/mag/hypot.c000066400000000000000000000013441417376376500144420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_hypot(mag_t z, const mag_t x, const mag_t y) { if (mag_is_zero(y)) { mag_set(z, x); } else if (mag_is_zero(x)) { mag_set(z, y); } else { mag_t t; mag_init(t); mag_mul(t, x, x); mag_addmul(t, y, y); mag_sqrt(z, t); mag_clear(t); } } arb-2.22.1/mag/inlines.c000066400000000000000000000006441417376376500147420ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #define MAG_INLINES_C #include "mag.h" arb-2.22.1/mag/load.c000066400000000000000000000033241417376376500142160ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "mag.h" #include "arf.h" static void mag_set_arf_dump(mag_t x, const arf_t y) { if (arf_is_special(y)) { if (arf_is_zero(y)) { mag_zero(x); } else if (arf_is_pos_inf(y)) { mag_inf(x); } else { /* a mag cannot be negative infinity or NaN */ flint_abort(); } } else { fmpz_t mantissa, exponent; fmpz_init(mantissa); fmpz_init(exponent); arf_get_fmpz_2exp(mantissa, exponent, y); if(fmpz_cmp_ui(mantissa, 1 << MAG_BITS) >= 0) flint_abort(); /* assert */ mag_set_ui(x, fmpz_get_ui(mantissa)); mag_mul_2exp_fmpz(x, x, exponent); fmpz_clear(exponent); fmpz_clear(mantissa); } } int mag_load_str(mag_t x, const char* data) { int err = 0; arf_t y; arf_init(y); err = arf_load_str(y, data); if (err) { arf_clear(y); return err; } mag_set_arf_dump(x, y); arf_clear(y); return err; } int mag_load_file(mag_t x, FILE* stream) { int err = 0; arf_t y; arf_init(y); err = arf_load_file(y, stream); if (err) { arf_clear(y); return err; } mag_set_arf_dump(x, y); arf_clear(y); return err; } arb-2.22.1/mag/log.c000066400000000000000000000127241417376376500140640ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_neg_log(mag_t z, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_inf(z); else mag_zero(z); } else { double t; fmpz exp = MAG_EXP(x); if (!COEFF_IS_MPZ(exp)) { if (exp >= 1) { mag_zero(z); } else if (exp > -(1000 - MAG_BITS)) { t = ldexp(MAG_MAN(x), exp - MAG_BITS); t = -mag_d_log_lower_bound(t); mag_set_d(z, t); } else { /* -log(2^(exp-1) * (2*v)) = -exp*log(2) - log(2*v), 1 <= 2v < 2 */ t = MAG_MAN(x) * ldexp(1.0, 1 - MAG_BITS); t = -mag_d_log_lower_bound(t); t -= (exp - 1) * 0.69314718055994530942; t *= (1 + 1e-13); mag_set_d(z, t); } } else if (fmpz_sgn(MAG_EXPREF(x)) > 0) { mag_zero(z); } else { mag_inv(z, x); mag_log(z, z); } } } void mag_neg_log_lower(mag_t z, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_inf(z); else mag_zero(z); } else { double t; fmpz exp = MAG_EXP(x); if (!COEFF_IS_MPZ(exp)) { if (exp >= 1) { mag_zero(z); } else if (exp > -(1000 - MAG_BITS)) { t = ldexp(MAG_MAN(x), exp - MAG_BITS); t = -mag_d_log_upper_bound(t); mag_set_d_lower(z, t); } else { /* -log(2^(exp-1) * (2*v)) = -exp*log(2) - log(2*v), 1 <= 2v < 2 */ t = MAG_MAN(x) * ldexp(1.0, 1 - MAG_BITS); t = -mag_d_log_upper_bound(t); t -= (exp - 1) * 0.69314718055994530942; t *= (1 - 1e-13); mag_set_d_lower(z, t); } } else if (fmpz_sgn(MAG_EXPREF(x)) > 0) { mag_zero(z); } else { mag_inv_lower(z, x); mag_log_lower(z, z); } } } void mag_log(mag_t z, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_zero(z); else mag_inf(z); } else { double t; fmpz exp = MAG_EXP(x); if (!COEFF_IS_MPZ(exp)) { if (exp <= 0 || (exp == 1 && MAG_MAN(x) == MAG_ONE_HALF)) { mag_zero(z); } else if (exp < 1000) /* safely within the double range */ { t = ldexp(MAG_MAN(x), exp - MAG_BITS); t = mag_d_log_upper_bound(t); mag_set_d(z, t); } else { /* log(2^(exp-1)*(2v)) = (exp-1)*log(2) + log(2v), 1 <= 2v < 2 */ t = MAG_MAN(x) * ldexp(1.0, 1 - MAG_BITS); /* exact */ t = mag_d_log_upper_bound(t); t += (exp - 1.0) * 0.69314718055994530942; t *= (1 + 1e-13); /* last step could have rounded down */ mag_set_d(z, t); } } else if (fmpz_sgn(MAG_EXPREF(x)) < 0) { mag_zero(z); } else { /* log(2^exp) = exp*log(2), log(2) < 744261118/2^30 */ fmpz_t t; fmpz_init(t); fmpz_mul_ui(t, MAG_EXPREF(x), 744261118); mag_set_fmpz(z, t); mag_mul_2exp_si(z, z, -30); fmpz_clear(t); } } } void mag_log_lower(mag_t z, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_zero(z); else mag_inf(z); } else { double t; fmpz exp = MAG_EXP(x); if (!COEFF_IS_MPZ(exp)) { if (exp <= 0 || (exp == 1 && MAG_MAN(x) == MAG_ONE_HALF)) { mag_zero(z); } else if (exp < 1000) { t = ldexp(MAG_MAN(x), exp - MAG_BITS); t = mag_d_log_lower_bound(t); mag_set_d_lower(z, t); } else { /* log(2^(exp-1) * (2*v)) = exp*log(2) + log(2*v), 1 <= 2v < 2 */ t = MAG_MAN(x) * ldexp(1.0, 1 - MAG_BITS); t = mag_d_log_lower_bound(t); t += (exp - 1) * 0.69314718055994530942; t *= (1 - 1e-13); mag_set_d_lower(z, t); } } else if (fmpz_sgn(MAG_EXPREF(x)) < 0) { mag_zero(z); } else { /* log(2^exp) = exp*log(2), log(2) > 744261117/2^30 */ fmpz_t t; fmpz_init(t); fmpz_sub_ui(t, MAG_EXPREF(x), 1); /* lower bound for x */ fmpz_mul_ui(t, t, 744261117); mag_set_fmpz_lower(z, t); mag_mul_2exp_si(z, z, -30); fmpz_clear(t); } } } arb-2.22.1/mag/log1p.c000066400000000000000000000032071417376376500143210ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" void mag_log1p(mag_t z, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_zero(z); else mag_inf(z); } else { double t; fmpz exp = MAG_EXP(x); if (!COEFF_IS_MPZ(exp)) { /* Quick bound by x */ if (exp < -10) { mag_set(z, x); } else if (exp < 1000) { t = ldexp(MAG_MAN(x), exp - MAG_BITS); t = (1.0 + t) * (1 + 1e-14); t = mag_d_log_upper_bound(t); mag_set_d(z, t); } else { /* log(2^(exp-1) * (2*v)) = exp*log(2) + log(2*v), 1 <= 2v < 2 */ t = (MAG_MAN(x) + 1) * ldexp(1.0, 1 - MAG_BITS); t = mag_d_log_upper_bound(t); t += (exp - 1) * 0.69314718055994530942; t *= (1 + 1e-13); mag_set_d(z, t); } } else if (fmpz_sgn(MAG_EXPREF(x)) < 0) { /* Quick bound by x */ mag_set(z, x); } else { mag_add_ui(z, x, 1); mag_log(z, z); } } } arb-2.22.1/mag/log_ui.c000066400000000000000000000011551417376376500145550ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_log_ui(mag_t t, ulong n) { if (n <= 1) { if (n == 1) mag_zero(t); else mag_inf(t); } else { mag_set_ui(t, n-1); mag_log1p(t, t); } } arb-2.22.1/mag/mul.c000066400000000000000000000025211417376376500140720ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_mul(mag_t z, const mag_t x, const mag_t y) { if (mag_is_special(x) || mag_is_special(y)) { if (mag_is_inf(x) || mag_is_inf(y)) mag_inf(z); else mag_zero(z); } else { slong fix; MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)) + LIMB_ONE; fix = !(MAG_MAN(z) >> (MAG_BITS - 1)); MAG_MAN(z) <<= fix; _fmpz_add2_fast(MAG_EXPREF(z), MAG_EXPREF(x), MAG_EXPREF(y), -fix); } } void mag_mul_lower(mag_t z, const mag_t x, const mag_t y) { if (mag_is_special(x) || mag_is_special(y)) { if (mag_is_zero(x) || mag_is_zero(y)) mag_zero(z); else mag_inf(z); } else { slong fix; MAG_MAN(z) = MAG_FIXMUL(MAG_MAN(x), MAG_MAN(y)); fix = !(MAG_MAN(z) >> (MAG_BITS - 1)); MAG_MAN(z) <<= fix; _fmpz_add2_fast(MAG_EXPREF(z), MAG_EXPREF(x), MAG_EXPREF(y), -fix); } } arb-2.22.1/mag/mul_2exp_fmpz.c000066400000000000000000000012031417376376500160600ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_mul_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t y) { if (mag_is_special(x)) { mag_set(z, x); } else { _fmpz_add2_fast(MAG_EXPREF(z), MAG_EXPREF(x), y, 0); MAG_MAN(z) = MAG_MAN(x); } } arb-2.22.1/mag/mul_2exp_si.c000066400000000000000000000013661417376376500155310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_mul_2exp_si(mag_t z, const mag_t x, slong y) { if (mag_is_special(x)) { mag_set(z, x); } else { if (y >= ADD2_FAST_MIN && y <= ADD2_FAST_MAX) _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(x), y); else fmpz_add_si(MAG_EXPREF(z), MAG_EXPREF(x), y); MAG_MAN(z) = MAG_MAN(x); } } arb-2.22.1/mag/polylog_tail.c000066400000000000000000000040021417376376500157670ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_polylog_tail(mag_t u, const mag_t z, slong sigma, ulong d, ulong N) { mag_t TN, UN, t; if (N < 2) { mag_inf(u); return; } mag_init(TN); mag_init(UN); mag_init(t); if (mag_cmp_2exp_si(z, 0) >= 0) { mag_inf(u); } else { /* Bound T(N) */ mag_pow_ui(TN, z, N); /* multiply by log(N)^d */ if (d > 0) { mag_log_ui(t, N); mag_pow_ui(t, t, d); mag_mul(TN, TN, t); } /* multiply by 1/k^s */ if (sigma > 0) { mag_set_ui_lower(t, N); mag_pow_ui_lower(t, t, sigma); mag_div(TN, TN, t); } else if (sigma < 0) { mag_set_ui(t, N); mag_pow_ui(t, t, -sigma); mag_mul(TN, TN, t); } /* Bound U(N) */ mag_set(UN, z); /* multiply by (1 + 1/N)**S */ if (sigma < 0) { mag_binpow_uiui(t, N, -sigma); mag_mul(UN, UN, t); } /* multiply by (1 + 1/(N log(N)))^d */ if (d > 0) { ulong nl; /* rounds down */ nl = mag_d_log_lower_bound(N) * N * (1 - 1e-13); mag_binpow_uiui(t, nl, d); mag_mul(UN, UN, t); } /* T(N) / (1 - U(N)) */ if (mag_cmp_2exp_si(UN, 0) >= 0) { mag_inf(u); } else { mag_one(t); mag_sub_lower(t, t, UN); mag_div(u, TN, t); } } mag_clear(TN); mag_clear(UN); mag_clear(t); } arb-2.22.1/mag/pow_fmpz.c000066400000000000000000000036241417376376500151430ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_pow_fmpz(mag_t z, const mag_t x, const fmpz_t e) { if (fmpz_sgn(e) < 0) { fmpz_t t; fmpz_init(t); fmpz_neg(t, e); mag_inv(z, x); mag_pow_fmpz(z, z, t); fmpz_clear(t); } else if (!COEFF_IS_MPZ(*e)) { mag_pow_ui(z, x, fmpz_get_ui(e)); } else { mag_t y; mp_srcptr elimbs; slong i, bits; mag_init_set(y, x); bits = fmpz_bits(e); elimbs = COEFF_TO_PTR(*e)->_mp_d; for (i = bits - 2; i >= 0; i--) { mag_mul(y, y, y); if ((elimbs[i / FLINT_BITS] >> (i % FLINT_BITS)) & 1) mag_mul(y, y, x); } mag_swap(z, y); mag_clear(y); } } void mag_pow_fmpz_lower(mag_t z, const mag_t x, const fmpz_t e) { if (fmpz_sgn(e) < 0) { fmpz_t t; fmpz_init(t); fmpz_neg(t, e); mag_inv_lower(z, x); mag_pow_fmpz_lower(z, z, t); fmpz_clear(t); } else if (!COEFF_IS_MPZ(*e)) { mag_pow_ui_lower(z, x, fmpz_get_ui(e)); } else { mag_t y; mp_srcptr elimbs; slong i, bits; mag_init_set(y, x); bits = fmpz_bits(e); elimbs = COEFF_TO_PTR(*e)->_mp_d; for (i = bits - 2; i >= 0; i--) { mag_mul_lower(y, y, y); if ((elimbs[i / FLINT_BITS] >> (i % FLINT_BITS)) & 1) mag_mul_lower(y, y, x); } mag_swap(z, y); mag_clear(y); } } arb-2.22.1/mag/pow_ui.c000066400000000000000000000031621417376376500146010ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_pow_ui(mag_t z, const mag_t x, ulong e) { if (mag_is_inf(x)) { mag_inf(z); } else if (e <= 2) { if (e == 0) mag_one(z); else if (e == 1) mag_set(z, x); else mag_mul(z, x, x); } else { mag_t y; int i, bits; mag_init_set(y, x); bits = FLINT_BIT_COUNT(e); for (i = bits - 2; i >= 0; i--) { mag_mul(y, y, y); if (e & (UWORD(1) << i)) mag_mul(y, y, x); } mag_swap(z, y); mag_clear(y); } } void mag_pow_ui_lower(mag_t z, const mag_t x, ulong e) { if (e <= 2) { if (e == 0) mag_one(z); else if (e == 1) mag_set(z, x); else mag_mul_lower(z, x, x); } else if (mag_is_inf(x)) { mag_inf(z); } else { mag_t y; int i, bits; mag_init_set(y, x); bits = FLINT_BIT_COUNT(e); for (i = bits - 2; i >= 0; i--) { mag_mul_lower(y, y, y); if (e & (UWORD(1) << i)) mag_mul_lower(y, y, x); } mag_swap(z, y); mag_clear(y); } } arb-2.22.1/mag/randtest.c000066400000000000000000000024121417376376500151200ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_randtest_special(mag_t x, flint_rand_t state, slong expbits) { switch (n_randint(state, 32)) { case 0: mag_zero(x); break; case 1: mag_inf(x); break; case 2: MAG_MAN(x) = (LIMB_ONE << MAG_BITS) - 1; fmpz_randtest(MAG_EXPREF(x), state, expbits); break; case 3: MAG_MAN(x) = LIMB_ONE << (MAG_BITS - 1); fmpz_randtest(MAG_EXPREF(x), state, expbits); break; default: MAG_MAN(x) = (n_randtest(state) >> (FLINT_BITS - MAG_BITS)); MAG_MAN(x) |= (LIMB_ONE << (MAG_BITS - 1)); fmpz_randtest(MAG_EXPREF(x), state, expbits); } } void mag_randtest(mag_t x, flint_rand_t state, slong expbits) { mag_randtest_special(x, state, expbits); if (mag_is_inf(x)) mag_zero(x); } arb-2.22.1/mag/root.c000066400000000000000000000024701417376376500142630ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_root(mag_t y, const mag_t x, ulong n) { if (n == 0) { mag_inf(y); } else if (n == 1 || mag_is_special(x)) { mag_set(y, x); } else if (n == 2) { mag_sqrt(y, x); } else if (n == 4) { mag_sqrt(y, x); mag_sqrt(y, y); } else { fmpz_t e, f; fmpz_init_set_ui(e, MAG_BITS); fmpz_init(f); /* We evaluate exp(log(1+2^(kn)x)/n) 2^-k where k is chosen so that 2^(kn) x ~= 2^30. TODO: this rewriting is probably unnecessary with the new exp/log functions. */ fmpz_sub(e, e, MAG_EXPREF(x)); fmpz_cdiv_q_ui(e, e, n); fmpz_mul_ui(f, e, n); mag_mul_2exp_fmpz(y, x, f); mag_log1p(y, y); mag_div_ui(y, y, n); mag_exp(y, y); fmpz_neg(e, e); mag_mul_2exp_fmpz(y, y, e); fmpz_clear(e); fmpz_clear(f); } } arb-2.22.1/mag/rsqrt.c000066400000000000000000000046161417376376500144570ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_rsqrt(mag_t y, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_inf(y); else mag_zero(y); } else { double t; fmpz e; t = MAG_MAN(x) * ldexp(1.0, -MAG_BITS); if (MAG_IS_LAGOM(x)) { e = MAG_EXP(x); if (e % 2 != 0) { e = (1 - e) >> 1; t *= 2.0; } else { e = (-e) >> 1; } t = (1.0 / sqrt(t)) * (1 + 1e-13); _fmpz_demote(MAG_EXPREF(y)); MAG_SET_D_2EXP(MAG_MAN(y), MAG_EXP(y), t, e); } else { if (fmpz_is_odd(MAG_EXPREF(x))) t *= 2.0; fmpz_fdiv_q_2exp(MAG_EXPREF(y), MAG_EXPREF(x), 1); fmpz_neg(MAG_EXPREF(y), MAG_EXPREF(y)); t = (1.0 / sqrt(t)) * (1 + 1e-13); mag_set_d_2exp_fmpz(y, t, MAG_EXPREF(y)); } } } void mag_rsqrt_lower(mag_t y, const mag_t x) { if (mag_is_special(x)) { if (mag_is_zero(x)) mag_inf(y); else mag_zero(y); } else { double t; fmpz e; t = MAG_MAN(x) * ldexp(1.0, -MAG_BITS); if (MAG_IS_LAGOM(x)) { e = MAG_EXP(x); if (e % 2 != 0) { e = (1 - e) >> 1; t *= 2.0; } else { e = (-e) >> 1; } t = (1.0 / sqrt(t)) * (1 - 1e-13); _fmpz_demote(MAG_EXPREF(y)); MAG_SET_D_2EXP_LOWER(MAG_MAN(y), MAG_EXP(y), t, e); } else { if (fmpz_is_odd(MAG_EXPREF(x))) t *= 2.0; fmpz_fdiv_q_2exp(MAG_EXPREF(y), MAG_EXPREF(x), 1); fmpz_neg(MAG_EXPREF(y), MAG_EXPREF(y)); t = (1.0 / sqrt(t)) * (1 - 1e-13); mag_set_d_2exp_fmpz_lower(y, t, MAG_EXPREF(y)); } } } arb-2.22.1/mag/set_d.c000066400000000000000000000020351417376376500143730ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" void mag_set_d(mag_t z, double c) { if (c < 0.0) c = -c; if (c == 0.0) { mag_zero(z); } else if ((c != c) || c == D_INF) { mag_inf(z); } else { _fmpz_demote(MAG_EXPREF(z)); MAG_SET_D_2EXP(MAG_MAN(z), MAG_EXP(z), c, 0); } } void mag_set_d_lower(mag_t z, double c) { if (c < 0.0) c = -c; if (c == 0.0 || (c != c)) { mag_zero(z); } else if (c == D_INF) { mag_inf(z); } else { _fmpz_demote(MAG_EXPREF(z)); MAG_SET_D_2EXP_LOWER(MAG_MAN(z), MAG_EXP(z), c, 0); } } arb-2.22.1/mag/set_d_2exp_fmpz.c000066400000000000000000000031511417376376500163650ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" void mag_set_d_2exp_fmpz(mag_t z, double c, const fmpz_t exp) { if (c < 0.0) c = -c; if (c == 0.0) { mag_zero(z); } else if ((c != c) || c == D_INF) { mag_inf(z); } else { slong cexp = *exp; if (cexp >= MAG_MIN_LAGOM_EXP && cexp <= MAG_MAX_LAGOM_EXP) { _fmpz_demote(MAG_EXPREF(z)); MAG_SET_D_2EXP(MAG_MAN(z), MAG_EXP(z), c, cexp); } else { MAG_SET_D_2EXP(MAG_MAN(z), cexp, c, 0); fmpz_add_si(MAG_EXPREF(z), exp, cexp); } } } void mag_set_d_2exp_fmpz_lower(mag_t z, double c, const fmpz_t exp) { if (c < 0.0) c = -c; if (c == 0.0 || (c != c)) { mag_zero(z); } else if (c == D_INF) { mag_inf(z); } else { slong cexp = *exp; if (cexp >= MAG_MIN_LAGOM_EXP && cexp <= MAG_MAX_LAGOM_EXP) { _fmpz_demote(MAG_EXPREF(z)); MAG_SET_D_2EXP_LOWER(MAG_MAN(z), MAG_EXP(z), c, cexp); } else { MAG_SET_D_2EXP_LOWER(MAG_MAN(z), cexp, c, 0); fmpz_add_si(MAG_EXPREF(z), exp, cexp); } } } arb-2.22.1/mag/set_fmpr.c000066400000000000000000000012521417376376500151140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arf.h" void mag_set_fmpr(mag_t x, const fmpr_t y) { if (fmpr_is_special(y)) { if (fmpr_is_zero(y)) mag_zero(x); else mag_inf(x); } else { mag_set_fmpz_2exp_fmpz(x, fmpr_manref(y), fmpr_expref(y)); } } arb-2.22.1/mag/set_fmpz_2exp_fmpz.c000066400000000000000000000021061417376376500171150ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t man, const fmpz_t exp) { if (fmpz_is_zero(man)) { mag_zero(z); } else { mp_limb_t m; slong cexp; m = fmpz_abs_ubound_ui_2exp(&cexp, man, MAG_BITS); MAG_MAN(z) = m; _fmpz_add_fast(MAG_EXPREF(z), exp, cexp + MAG_BITS); } } void mag_set_fmpz_2exp_fmpz_lower(mag_t z, const fmpz_t man, const fmpz_t exp) { if (fmpz_is_zero(man)) { mag_zero(z); } else { mp_limb_t m; slong cexp; m = fmpz_abs_lbound_ui_2exp(&cexp, man, MAG_BITS); MAG_MAN(z) = m; _fmpz_add_fast(MAG_EXPREF(z), exp, cexp + MAG_BITS); } } arb-2.22.1/mag/set_ui.c000066400000000000000000000026551417376376500145750ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_set_ui(mag_t z, ulong x) { _fmpz_demote(MAG_EXPREF(z)); if (x == 0) { MAG_EXP(z) = 0; MAG_MAN(z) = 0; } else { slong bits; mp_limb_t overflow; count_leading_zeros(bits, x); bits = FLINT_BITS - bits; if (bits <= MAG_BITS) { x = x << (MAG_BITS - bits); } else { x = (x >> (bits - MAG_BITS)) + 1; overflow = x >> MAG_BITS; bits += overflow; x >>= overflow; } MAG_EXP(z) = bits; MAG_MAN(z) = x; } } void mag_set_ui_lower(mag_t z, ulong x) { _fmpz_demote(MAG_EXPREF(z)); if (x == 0) { MAG_EXP(z) = 0; MAG_MAN(z) = 0; } else { unsigned int bits; count_leading_zeros(bits, x); bits = FLINT_BITS - bits; if (bits <= MAG_BITS) x <<= (MAG_BITS - bits); else x >>= (bits - MAG_BITS); MAG_EXP(z) = bits; MAG_MAN(z) = x; } } arb-2.22.1/mag/set_ui_2exp_si.c000066400000000000000000000023431417376376500162200ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_set_ui_2exp_si(mag_t z, ulong x, slong e) { _fmpz_demote(MAG_EXPREF(z)); if (x == 0) { MAG_EXP(z) = 0; MAG_MAN(z) = 0; } else { slong bits; mp_limb_t overflow; count_leading_zeros(bits, x); bits = FLINT_BITS - bits; if (bits <= MAG_BITS) { x = x << (MAG_BITS - bits); } else { x = (x >> (bits - MAG_BITS)) + 1; overflow = x >> MAG_BITS; bits += overflow; x >>= overflow; } if (e >= MAG_MIN_LAGOM_EXP && e <= MAG_MAX_LAGOM_EXP) { MAG_EXP(z) = bits + e; } else { fmpz_set_si(MAG_EXPREF(z), e); fmpz_add_si(MAG_EXPREF(z), MAG_EXPREF(z), bits); } MAG_MAN(z) = x; } } arb-2.22.1/mag/sinh.c000066400000000000000000000041041417376376500142350ustar00rootroot00000000000000/* Copyright (C) 2014, 2018 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" static const double inverse_factorials[] = { 1.0, 0.16666666666666666667, 0.0083333333333333333333, 0.0001984126984126984127, 2.7557319223985890653e-6, 2.5052108385441718775e-8, 1.6059043836821614599e-10, 7.6471637318198164759e-13 }; static double _sinh(double x) { x = x * (1.0 / 27.0); x = x * d_polyval(inverse_factorials, 8, x * x); x = x * (3.0 + 4.0 * (x * x)); x = x * (3.0 + 4.0 * (x * x)); x = x * (3.0 + 4.0 * (x * x)); return x; } void mag_sinh(mag_t res, const mag_t x) { if (mag_is_special(x)) { mag_set(res, x); } else { if (mag_cmp_2exp_si(x, -30) < 0) { mag_expm1(res, x); } else if (mag_cmp_2exp_si(x, 4) > 0) { mag_exp(res, x); mag_mul_2exp_si(res, res, -1); } else { double v; v = mag_get_d(x); v = _sinh(v) * (1 + 1e-12); mag_set_d(res, v); } } } void mag_sinh_lower(mag_t res, const mag_t x) { if (mag_is_special(x)) { mag_set(res, x); } else { if (mag_cmp_2exp_si(x, -15) < 0) { mag_set(res, x); } else if (mag_cmp_2exp_si(x, 4) > 0) { mag_t t; mag_init(t); mag_exp_lower(t, x); mag_expinv(res, x); mag_sub(res, t, res); mag_mul_2exp_si(res, res, -1); mag_clear(t); } else { double v; v = mag_get_d(x); v = _sinh(v) * (1 - 1e-12); mag_set_d_lower(res, v); } } } arb-2.22.1/mag/sqrt.c000066400000000000000000000041621417376376500142710ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" void mag_sqrt(mag_t y, const mag_t x) { if (mag_is_special(x)) { mag_set(y, x); } else { double t; slong e; t = MAG_MAN(x) * ldexp(1.0, -MAG_BITS); if (MAG_IS_LAGOM(x)) { e = MAG_EXP(x); if (e % 2 != 0) { e = (e - 1) >> 1; t *= 2.0; } else { e >>= 1; } t = sqrt(t) * (1 + 1e-13); _fmpz_demote(MAG_EXPREF(y)); MAG_SET_D_2EXP(MAG_MAN(y), MAG_EXP(y), t, e); } else { if (fmpz_is_odd(MAG_EXPREF(x))) t *= 2.0; fmpz_fdiv_q_2exp(MAG_EXPREF(y), MAG_EXPREF(x), 1); t = sqrt(t) * (1 + 1e-13); mag_set_d_2exp_fmpz(y, t, MAG_EXPREF(y)); } } } void mag_sqrt_lower(mag_t y, const mag_t x) { if (mag_is_special(x)) { mag_set(y, x); } else { double t; slong e; t = MAG_MAN(x) * ldexp(1.0, -MAG_BITS); if (MAG_IS_LAGOM(x)) { e = MAG_EXP(x); if (e % 2 != 0) { e = (e - 1) >> 1; t *= 2.0; } else { e >>= 1; } t = sqrt(t) * (1 - 1e-13); _fmpz_demote(MAG_EXPREF(y)); MAG_SET_D_2EXP_LOWER(MAG_MAN(y), MAG_EXP(y), t, e); } else { if (fmpz_is_odd(MAG_EXPREF(x))) t *= 2.0; fmpz_fdiv_q_2exp(MAG_EXPREF(y), MAG_EXPREF(x), 1); t = sqrt(t) * (1 - 1e-13); mag_set_d_2exp_fmpz_lower(y, t, MAG_EXPREF(y)); } } } arb-2.22.1/mag/sub.c000066400000000000000000000021361417376376500140700ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arf.h" void mag_sub(mag_t z, const mag_t x, const mag_t y) { if (mag_is_special(x) || mag_is_special(y)) { if (mag_is_inf(x)) mag_inf(z); else if (mag_is_inf(y)) mag_zero(z); else mag_set(z, x); /* x - 0 = x; max(0 - y, 0) = 0 */ } else { /* this should eventually have a proper implementation... */ arf_t t, u; arf_init(t); arf_init(u); arf_set_mag(t, x); arf_set_mag(u, y); arf_sub(t, t, u, MAG_BITS, ARF_RND_UP); if (arf_sgn(t) >= 0) arf_get_mag(z, t); else mag_zero(z); arf_clear(t); arf_clear(u); } } arb-2.22.1/mag/sub_lower.c000066400000000000000000000043711417376376500153030ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arf.h" void mag_sub_lower(mag_t z, const mag_t x, const mag_t y) { if (mag_is_special(x) || mag_is_special(y)) { if (mag_is_zero(y)) mag_set(z, x); else if (mag_is_zero(x) || mag_is_inf(y)) mag_zero(z); else mag_inf(z); } else { slong shift, fix; shift = _fmpz_sub_small(MAG_EXPREF(x), MAG_EXPREF(y)); /* y > x */ if (shift < 0) { mag_zero(z); } else if (shift == 0) { if (MAG_MAN(y) >= MAG_MAN(x)) { mag_zero(z); } else { MAG_MAN(z) = MAG_MAN(x) - MAG_MAN(y); fix = MAG_BITS - FLINT_BIT_COUNT(MAG_MAN(z)); MAG_MAN(z) <<= fix; _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(x), -fix); } } else { if (shift <= MAG_BITS) { mp_limb_t c = MAG_MAN(x) - (MAG_MAN(y) >> shift) - 1; /* too much cancellation -- compute precisely */ if (c < (UWORD(1) << (MAG_BITS - 4))) { arf_t t, u; arf_init(t); arf_init(u); arf_set_mag(t, x); arf_set_mag(u, y); arf_sub(t, t, u, MAG_BITS, ARF_RND_DOWN); arf_get_mag_lower(z, t); arf_clear(t); arf_clear(u); return; } MAG_MAN(z) = c; } else { MAG_MAN(z) = MAG_MAN(x) - 1; } fix = MAG_BITS - FLINT_BIT_COUNT(MAG_MAN(z)); MAG_MAN(z) <<= fix; _fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(x), -fix); } } } arb-2.22.1/mag/test/000077500000000000000000000000001417376376500141105ustar00rootroot00000000000000arb-2.22.1/mag/test/t-add.c000066400000000000000000000040361417376376500152500ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("add...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_add(z, x, y, MAG_BITS + 10, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_add(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-add_2exp_fmpz.c000066400000000000000000000040571417376376500172450ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("add_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, zb; fmpz_t e; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); fmpz_init(e); mag_init(xb); mag_init(zb); fmpr_randtest(x, state, MAG_BITS, 100); fmpr_abs(x, x); fmpz_randtest(e, state, 100); fmpr_one(y); fmpr_mul_2exp_fmpz(y, y, e); fmpr_add(z, x, y, MAG_BITS + 10, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set_fmpr(xb, x); mag_add_2exp_fmpz(zb, xb, e); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(zb); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-add_lower.c000066400000000000000000000037501417376376500164620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("add_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_add(z2, x, y, 100, FMPR_RND_DOWN); fmpr_mul_ui(z, z2, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z, z, -10); mag_add_lower(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-addmul.c000066400000000000000000000111751417376376500157700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("addmul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_randtest_special(zb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); mag_get_fmpr(z, zb); fmpr_addmul(z, x, y, MAG_BITS + 10, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_addmul(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_addmul(z, z, y, MAG_BITS + 10, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_addmul(zb, zb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, y); fmpr_addmul(z, x, z, MAG_BITS + 10, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, yb); mag_addmul(zb, xb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_addmul(z, z, z, MAG_BITS + 10, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_addmul(zb, zb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 3)\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-atan.c000066400000000000000000000043621417376376500154450ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" slong fmpr_atan(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_zero(x)) { fmpr_zero(y); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_atan, y, x, prec, rnd); return r; } } int main() { slong iter; flint_rand_t state; flint_printf("atan...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 25); mag_randtest_special(yb, state, 25); mag_atan(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_atan(z, x, MAG_BITS, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_atan(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-atan_lower.c000066400000000000000000000044101417376376500166470ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" slong fmpr_atan(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_zero(x)) { fmpr_zero(y); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_atan, y, x, prec, rnd); return r; } } int main() { slong iter; flint_rand_t state; flint_printf("atan_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 25); mag_randtest_special(yb, state, 25); mag_atan_lower(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_atan(z, x, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_atan_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-bin_uiui.c000066400000000000000000000030301417376376500163140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("bin_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpr_t x, y; fmpz_t f; mag_t xb; ulong n, k; fmpr_init(x); fmpr_init(y); fmpz_init(f); mag_init(xb); mag_randtest_special(xb, state, 80); n = n_randtest(state) % 10000; k = n_randtest(state) % 10000; mag_bin_uiui(xb, n, k); fmpz_bin_uiui(f, n, k); fmpr_set_fmpz(x, f); mag_get_fmpr(y, xb); MAG_CHECK_BITS(xb) if (!(fmpr_cmpabs(y, x) >= 0)) { flint_printf("FAIL\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpz_clear(f); mag_clear(xb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-binpow_uiui.c000066400000000000000000000031051417376376500170450ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("binpow_uiui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y; mag_t b; ulong m, n; fmpr_init(x); fmpr_init(y); mag_init(b); m = n_randtest(state); n = n_randtest(state); fmpr_one(x); fmpr_div_ui(x, x, m, 128, FMPR_RND_UP); fmpr_add_ui(x, x, 1, 128, FMPR_RND_UP); fmpr_pow_sloppy_ui(x, x, n, 128, FMPR_RND_UP); mag_binpow_uiui(b, m, n); mag_get_fmpr(y, b); MAG_CHECK_BITS(b) if (!(fmpr_cmpabs(x, y) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("m = %wu\n\n", m); flint_printf("n = %wu\n\n", n); flint_printf("x = "); fmpr_printd(x, 10); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 10); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); mag_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-cmp.c000066400000000000000000000030371417376376500152770ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("cmp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y; mag_t xb, yb; int c1, c2; fmpr_init(x); fmpr_init(y); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); c1 = fmpr_cmp(x, y); c2 = mag_cmp(xb, yb); if (c1 != c2) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("xb = "); mag_print(xb); flint_printf("\n\n"); flint_printf("yb = "); mag_print(yb); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-cmp_2exp_si.c000066400000000000000000000025771417376376500167400ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("cmp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x; mag_t xb; slong y; int c1, c2; fmpr_init(x); mag_init(xb); mag_randtest_special(xb, state, 100); y = z_randtest(state); mag_get_fmpr(x, xb); c1 = fmpr_cmp_2exp_si(x, y); c2 = mag_cmp_2exp_si(xb, y); if (c1 != c2) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = %wd", y); flint_printf("\n\n"); flint_printf("xb = "); mag_print(xb); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); mag_clear(xb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-cosh.c000066400000000000000000000045051417376376500154550ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" slong fmpr_cosh(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { fmpr_add_ui(y, x, 1, prec, rnd); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_cosh, y, x, prec, rnd); return r; } } int main() { slong iter; flint_rand_t state; flint_printf("atan...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_mul_2exp_si(xb, xb, -100 + n_randint(state,120)); mag_randtest_special(yb, state, 25); mag_cosh(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_cosh(z, x, MAG_BITS, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_cosh(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-cosh_lower.c000066400000000000000000000045331417376376500166660ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" slong fmpr_cosh(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { fmpr_add_ui(y, x, 1, prec, rnd); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_cosh, y, x, prec, rnd); return r; } } int main() { slong iter; flint_rand_t state; flint_printf("cosh_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_mul_2exp_si(xb, xb, -100 + n_randint(state,120)); mag_randtest_special(yb, state, 25); mag_cosh_lower(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_cosh(z, x, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_cosh_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-d_log_lower_bound.c000066400000000000000000000045321417376376500202040ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" /* XXX: d_randtest is not good enough */ #define EXP_MINUS_32 2.3283064365386962891e-10 #define EXP_MINUS_64 5.42101086242752217e-20 double d_randtest2(flint_rand_t state) { mp_limb_t m1, m2; double t; if (FLINT_BITS == 64) { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); t = ((double) m1) * EXP_MINUS_64; } else { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); m2 = n_randtest(state); t = ((double) m1) * EXP_MINUS_32 + ((double) m2) * EXP_MINUS_64; } return t; } int main() { slong iter; flint_rand_t state; flint_printf("d_log_lower_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mpfr_t t; double x, y, z; mpfr_init2(t, 53); x = d_randtest2(state); x = ldexp(x, 100 - n_randint(state, 200)); switch (n_randint(state, 10)) { case 0: x = 1.0 + x; break; case 1: x = 1.0 - x; break; case 2: x = D_INF; break; case 3: x = 0.0; break; case 4: x = D_NAN; break; default: break; } y = mag_d_log_lower_bound(x); mpfr_set_d(t, x, MPFR_RNDD); mpfr_log(t, t, MPFR_RNDD); z = mpfr_get_d(t, MPFR_RNDD); if (y > z || fabs(y-z) > 0.000001 * fabs(z)) { flint_printf("FAIL\n"); flint_printf("x = %.20g\n", x); flint_printf("y = %.20g\n", y); flint_printf("z = %.20g\n", z); flint_abort(); } mpfr_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-d_log_upper_bound.c000066400000000000000000000045321417376376500202070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" /* XXX: d_randtest is not good enough */ #define EXP_MINUS_32 2.3283064365386962891e-10 #define EXP_MINUS_64 5.42101086242752217e-20 double d_randtest2(flint_rand_t state) { mp_limb_t m1, m2; double t; if (FLINT_BITS == 64) { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); t = ((double) m1) * EXP_MINUS_64; } else { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); m2 = n_randtest(state); t = ((double) m1) * EXP_MINUS_32 + ((double) m2) * EXP_MINUS_64; } return t; } int main() { slong iter; flint_rand_t state; flint_printf("d_log_upper_bound...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mpfr_t t; double x, y, z; mpfr_init2(t, 53); x = d_randtest2(state); x = ldexp(x, 100 - n_randint(state, 200)); switch (n_randint(state, 10)) { case 0: x = 1.0 + x; break; case 1: x = 1.0 - x; break; case 2: x = D_INF; break; case 3: x = 0.0; break; case 4: x = D_NAN; break; default: break; } y = mag_d_log_upper_bound(x); mpfr_set_d(t, x, MPFR_RNDD); mpfr_log(t, t, MPFR_RNDU); z = mpfr_get_d(t, MPFR_RNDD); if (y < z || fabs(y-z) > 0.000001 * fabs(z)) { flint_printf("FAIL\n"); flint_printf("x = %.20g\n", x); flint_printf("y = %.20g\n", y); flint_printf("z = %.20g\n", z); flint_abort(); } mpfr_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-div.c000066400000000000000000000037401417376376500153030ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("div...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 10); mag_randtest_special(yb, state, 10); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_div(z, x, y, MAG_BITS + 10, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_div(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-div_lower.c000066400000000000000000000037611417376376500165160ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("div_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 10); mag_randtest_special(yb, state, 10); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_div(z, x, y, MAG_BITS + 10, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); mag_div_lower(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z2, w) <= 0 && fmpr_cmpabs(w, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-dump_file.c000066400000000000000000000050311417376376500164600ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include #include "arb.h" int main() { flint_rand_t state; slong iter; flint_printf("dump_file/load_file...."); fflush(stdout); flint_randinit(state); /* assume tmpfile() is broken on windows */ #if !defined(_MSC_VER) && !defined(__MINGW32__) /* just test no crashing... */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { mag_t x; FILE* tmp; mag_init(x); mag_randtest_special(x, state, 1 + n_randint(state, 100)); tmp = tmpfile(); mag_dump_file(tmp, x); fflush(tmp); rewind(tmp); mag_load_file(x, tmp); fclose(tmp); mag_clear(x); } for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mag_t x, y, z; int conversion_error; FILE* tmp; mag_init(x); mag_init(y); mag_init(z); mag_randtest_special(x, state, 1 + n_randint(state, 100)); mag_randtest_special(y, state, 1 + n_randint(state, 100)); mag_randtest_special(z, state, 1 + n_randint(state, 100)); tmp = tmpfile(); mag_dump_file(tmp, x); fputc(' ', tmp); mag_dump_file(tmp, y); fflush(tmp); rewind(tmp); conversion_error = mag_load_file(z, tmp); if (conversion_error || !mag_equal(x, z)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("x = "); mag_printd(x, 50); flint_printf("\n\n"); flint_printf("z = "); mag_printd(z, 50); flint_printf("\n\n"); flint_abort(); } conversion_error = mag_load_file(z, tmp); if (conversion_error || !mag_equal(y, z)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("y = "); mag_printd(y, 50); flint_printf("\n\n"); flint_printf("z = "); mag_printd(z, 50); flint_printf("\n\n"); flint_abort(); } fclose(tmp); mag_clear(x); mag_clear(y); mag_clear(z); } #endif flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-dump_str.c000066400000000000000000000034351417376376500163570ustar00rootroot00000000000000/* Copyright (C) 2019 Julian Rüth This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "mag.h" int main() { flint_rand_t state; slong iter; flint_printf("dump_str/load_str...."); fflush(stdout); flint_randinit(state); /* just test no crashing... */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { mag_t x; char * s; mag_init(x); mag_randtest_special(x, state, 1 + n_randint(state, 100)); s = mag_dump_str(x); flint_free(s); mag_clear(x); } for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mag_t x, y; char * s; int conversion_error; mag_init(x); mag_init(y); mag_randtest_special(x, state, 1 + n_randint(state, 100)); mag_randtest_special(y, state, 1 + n_randint(state, 100)); s = mag_dump_str(x); conversion_error = mag_load_str(y, s); if (conversion_error || !mag_equal(x, y)) { flint_printf("FAIL (roundtrip) iter = %wd\n", iter); flint_printf("x = "); mag_printd(x, 50); flint_printf("\n\n"); flint_printf("s = %s", s); flint_printf("\n\n"); flint_printf("y = "); mag_printd(y, 50); flint_printf("\n\n"); flint_abort(); } flint_free(s); mag_clear(x); mag_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-exp.c000066400000000000000000000042421417376376500153130ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("exp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_randtest_special(yb, state, 0); mag_mul_2exp_si(xb, xb, -28 + n_randint(state,56)); mag_exp(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_exp(z, x, MAG_BITS, FMPR_RND_UP); if (fmpr_cmpabs_ui(x, 1000) < 0) { fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); } else { fmpr_mul_2exp_si(z2, z, 2); } MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_exp(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-exp_lower.c000066400000000000000000000042711417376376500165250ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_randtest_special(yb, state, 0); mag_mul_2exp_si(xb, xb, -28 + n_randint(state,56)); mag_exp_lower(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_exp(z, x, MAG_BITS, FMPR_RND_DOWN); if (fmpr_cmpabs_ui(x, 1000) < 0) { fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); } else { fmpr_mul_2exp_si(z2, z, -2); } MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_exp_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-exp_tail.c000066400000000000000000000044421417376376500163260ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("exp_tail...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { fmpr_t x, t, y, z; fmpz_t f; mag_t xb, yb; ulong N, k; fmpr_init(x); fmpr_init(t); fmpr_init(y); fmpr_init(z); fmpz_init(f); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 6); mag_randtest_special(yb, state, 6); N = n_randint(state, 100); mag_exp_tail(yb, xb, N); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_pow_sloppy_ui(t, x, N, MAG_BITS, FMPR_RND_DOWN); fmpz_fac_ui(f, N); fmpr_div_fmpz(t, t, f, MAG_BITS, FMPR_RND_DOWN); fmpr_set(z, t); for (k = 1; k < 50; k++) { fmpr_mul(t, t, x, MAG_BITS, FMPR_RND_DOWN); fmpr_div_ui(t, t, N + k, MAG_BITS, FMPR_RND_DOWN); fmpr_add(z, z, t, MAG_BITS, FMPR_RND_DOWN); } MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("N = %wu\n\n", N); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_abort(); } mag_exp_tail(xb, xb, N); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(t); fmpr_clear(y); fmpr_clear(z); fmpz_clear(f); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-expinv.c000066400000000000000000000040511417376376500160260ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("expinv...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_randtest_special(yb, state, 0); mag_mul_2exp_si(xb, xb, -28 + n_randint(state,56)); mag_expinv(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_neg(z, x); fmpr_exp(z, z, MAG_BITS, FMPR_RND_UP); /* this implementation is very crude */ fmpr_mul_2exp_si(z2, z, 2); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_expinv(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-expinv_lower.c000066400000000000000000000043561417376376500172460ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("expinv_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_randtest_special(yb, state, 0); mag_mul_2exp_si(xb, xb, -28 + n_randint(state,56)); mag_expinv_lower(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_neg(z, x); fmpr_exp(z, z, MAG_BITS, FMPR_RND_DOWN); if (fmpr_cmpabs_ui(x, 1000) < 0) { fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); } else { fmpr_mul_2exp_si(z2, z, -2); } MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 10); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 10); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 10); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_printd(z2, 10); flint_printf("\n\n"); flint_abort(); } mag_expinv_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-expm1.c000066400000000000000000000043001417376376500155440ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("expm1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_randtest_special(yb, state, 0); mag_mul_2exp_si(xb, xb, -100 + n_randint(state,120)); mag_expm1(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_expm1(z, x, MAG_BITS, FMPR_RND_UP); if (fmpr_cmpabs_ui(x, 1000) < 0) { fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); } else { fmpr_mul_2exp_si(z2, z, 2); } MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_printd(z2, 15); flint_printf("\n\n"); flint_abort(); } mag_expm1(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-fac_ui.c000066400000000000000000000027431417376376500157510ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("fac_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpr_t x, y; fmpz_t f; mag_t xb; ulong n; fmpr_init(x); fmpr_init(y); fmpz_init(f); mag_init(xb); mag_randtest_special(xb, state, 80); n = n_randtest(state) % 2000; mag_fac_ui(xb, n); fmpz_fac_ui(f, n); fmpr_set_fmpz(x, f); mag_get_fmpr(y, xb); MAG_CHECK_BITS(xb) if (!(fmpr_cmpabs(y, x) >= 0)) { flint_printf("FAIL\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpz_clear(f); mag_clear(xb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-fast_add_2exp_si.c000066400000000000000000000040131417376376500177110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("fast_add_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, zb; slong e; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(zb); fmpr_randtest(x, state, MAG_BITS, 15); fmpr_abs(x, x); e = n_randint(state, 10000) - n_randint(state, 10000); fmpr_set_ui_2exp_si(y, 1, e); fmpr_add(z, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set_fmpr(xb, x); mag_fast_add_2exp_si(zb, xb, e); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-fast_addmul.c000066400000000000000000000107431417376376500170050ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("fast_addmul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest(xb, state, 15); mag_randtest(yb, state, 15); mag_randtest(zb, state, 15); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); mag_get_fmpr(z, zb); fmpr_addmul(z, x, y, MAG_BITS + 10, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_fast_addmul(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_addmul(z, z, y, MAG_BITS + 10, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_fast_addmul(zb, zb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, y); fmpr_addmul(z, x, z, MAG_BITS + 10, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, yb); mag_fast_addmul(zb, xb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_addmul(z, z, z, MAG_BITS + 10, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_fast_addmul(zb, zb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 3)\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-fast_mul.c000066400000000000000000000106161417376376500163330ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("fast_mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest(xb, state, 15); mag_randtest(yb, state, 15); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_mul(z, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_fast_mul(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_mul(z, z, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_fast_mul(zb, zb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, y); fmpr_mul(z, x, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, yb); mag_fast_mul(zb, xb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_mul(z, z, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_fast_mul(zb, zb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 3)\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_printf("w = "); fmpr_printd(w, 15); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-fast_mul_2exp_si.c000066400000000000000000000031351417376376500177620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("fast_mul_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z; mag_t xb, yb; slong e; fmpr_init(x); fmpr_init(y); fmpr_init(z); mag_init(xb); mag_init(yb); mag_randtest(xb, state, 15); e = n_randint(state, 10000) - n_randint(state, 10000); mag_get_fmpr(x, xb); mag_fast_mul_2exp_si(yb, xb, e); fmpr_mul_2exp_si(y, x, e); mag_get_fmpr(z, yb); MAG_CHECK_BITS(yb) if (!fmpr_equal(z, y)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-geom_series.c000066400000000000000000000041311417376376500170150ustar00rootroot00000000000000/* Copyright (C) 2015 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("geom_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { fmpr_t x, t, y, z; mag_t xb, yb; ulong N, k; fmpr_init(x); fmpr_init(t); fmpr_init(y); fmpr_init(z); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 6); mag_randtest_special(yb, state, 6); N = n_randint(state, 100); mag_geom_series(yb, xb, N); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_pow_sloppy_ui(t, x, N, MAG_BITS, FMPR_RND_DOWN); fmpr_set(z, t); for (k = 1; k < 50; k++) { fmpr_mul(t, t, x, MAG_BITS, FMPR_RND_DOWN); fmpr_add(z, z, t, MAG_BITS, FMPR_RND_DOWN); } MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("N = %wu\n\n", N); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_abort(); } mag_geom_series(xb, xb, N); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(t); fmpr_clear(y); fmpr_clear(z); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-get_d.c000066400000000000000000000036471417376376500156110ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("get_d...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { mag_t x; fmpr_t a, b; double y; mag_init(x); fmpr_init(a); fmpr_init(b); mag_randtest_special(x, state, 1 + n_randint(state, 100)); y = mag_get_d(x); fmpr_set_d(a, y); mag_get_fmpr(b, x); if (mag_cmp_2exp_si(x, 1000) < 0 && mag_cmp_2exp_si(x, -1000) > 0) { if (!fmpr_equal(a, b)) { flint_printf("FAIL (equality)\n\n"); flint_printf("x = "); mag_print(x); flint_printf("\n\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_abort(); } } else { if (fmpr_cmp(a, b) < 0) { flint_printf("FAIL (bound)\n\n"); flint_printf("x = "); mag_print(x); flint_printf("\n\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_abort(); } } fmpr_clear(a); fmpr_clear(b); mag_clear(x); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-hurwitz_zeta_uiui.c000066400000000000000000000037331417376376500203150ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("hurwitz_zeta_uiui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { mag_t zb; slong prec, k; ulong s, a; arb_t t, r, z; mag_init(zb); arb_init(t); arb_init(r); arb_init(z); mag_randtest_special(zb, state, 6); s = n_randtest(state); a = n_randtest(state); prec = MAG_BITS + 2 * FLINT_BIT_COUNT(s); mag_hurwitz_zeta_uiui(zb, s, a); arb_zero(r); for (k = 0; k < 50; k++) { arb_set_ui(t, a); arb_add_ui(t, t, k, prec); arb_pow_ui(t, t, s, prec); arb_inv(t, t, prec); arb_add(r, r, t, prec); } arb_zero(z); mag_set(arb_radref(z), zb); if (!arb_is_finite(z)) arb_indeterminate(z); if (!arb_contains(z, r)) { flint_printf("FAIL\n\n"); flint_printf("s = %wu\n\n", s); flint_printf("a = %wd\n\n", a); flint_printf("zb = "); mag_printd(zb, 15); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 15); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, 15); flint_printf("\n\n"); flint_abort(); } mag_clear(zb); arb_clear(t); arb_clear(r); arb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-log.c000066400000000000000000000053471417376376500153070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("log...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; fmpz_t n; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); fmpz_init(n); mag_randtest_special(xb, state, 25); mag_randtest_special(yb, state, 25); if (n_randint(state, 2)) { mag_log(yb, xb); mag_get_fmpr(x, xb); if (mag_cmp_2exp_si(xb, 0) <= 0) fmpr_zero(z); else fmpr_log(z, x, MAG_BITS, FMPR_RND_UP); } else { mag_get_fmpr(x, xb); fmpz_randtest(n, state, 100); mag_mul_2exp_fmpz(xb, xb, n); mag_log(yb, xb); if (mag_cmp_2exp_si(xb, 0) <= 0) { fmpr_zero(z); } else { fmpr_log(z, x, 3 * MAG_BITS, FMPR_RND_UP); fmpr_set_ui(z2, 2); fmpr_log(z2, z2, 3 * MAG_BITS, FMPR_RND_UP); fmpr_addmul_fmpz(z, z2, n, 3 * MAG_BITS, FMPR_RND_UP); } } mag_get_fmpr(y, yb); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_log(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-log1p.c000066400000000000000000000037401417376376500155430ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("log1p...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 25); mag_randtest_special(yb, state, 25); mag_log1p(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_log1p(z, x, MAG_BITS, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_log1p(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-log_lower.c000066400000000000000000000054111417376376500165070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("log_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; fmpz_t n; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); fmpz_init(n); mag_randtest_special(xb, state, 25); mag_randtest_special(yb, state, 25); if (n_randint(state, 2)) { mag_log_lower(yb, xb); mag_get_fmpr(x, xb); if (mag_cmp_2exp_si(xb, 0) <= 0) fmpr_zero(z); else fmpr_log(z, x, MAG_BITS, FMPR_RND_DOWN); } else { mag_get_fmpr(x, xb); fmpz_randtest(n, state, 100); mag_mul_2exp_fmpz(xb, xb, n); mag_log_lower(yb, xb); if (mag_cmp_2exp_si(xb, 0) <= 0) { fmpr_zero(z); } else { fmpr_log(z, x, 3 * MAG_BITS, FMPR_RND_DOWN); fmpr_set_ui(z2, 2); fmpr_log(z2, z2, 3 * MAG_BITS, FMPR_RND_DOWN); fmpr_addmul_fmpz(z, z2, n, 3 * MAG_BITS, FMPR_RND_DOWN); } } mag_get_fmpr(y, yb); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_log_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-mul.c000066400000000000000000000110371417376376500153140ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("mul...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_mul(z, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_mul(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_mul(z, z, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_mul(zb, zb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, y); fmpr_mul(z, x, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, yb); mag_mul(zb, xb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_set(z, x); fmpr_mul(z, z, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (fmpr_is_nan(z)) fmpr_pos_inf(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_set(zb, xb); mag_mul(zb, zb, zb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL (aliasing 3)\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-mul_2exp_fmpz.c000066400000000000000000000031711417376376500173060ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z; mag_t xb, yb; fmpz_t e; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpz_init(e); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 100); fmpz_randtest(e, state, 100); mag_get_fmpr(x, xb); mag_mul_2exp_fmpz(yb, xb, e); fmpr_mul_2exp_fmpz(y, x, e); mag_get_fmpr(z, yb); MAG_CHECK_BITS(yb) if (!fmpr_equal(z, y)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); mag_clear(xb); mag_clear(yb); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-mul_2exp_si.c000066400000000000000000000031331417376376500167430ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "flint/long_extras.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z; mag_t xb, yb; slong e; fmpr_init(x); fmpr_init(y); fmpr_init(z); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 100); e = z_randtest(state); mag_get_fmpr(x, xb); mag_mul_2exp_si(yb, xb, e); fmpr_mul_2exp_si(y, x, e); mag_get_fmpr(z, yb); MAG_CHECK_BITS(yb) if (!fmpr_equal(z, y)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-mul_lower.c000066400000000000000000000040541417376376500165250ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("mul_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_mul(z2, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (fmpr_is_nan(z2)) fmpr_zero(z2); fmpr_mul_ui(z, z2, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z, z, -10); mag_mul_lower(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-neg_log.c000066400000000000000000000056321417376376500161350ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("neg_log...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; fmpz_t n; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); fmpz_init(n); mag_randtest_special(xb, state, 25); mag_randtest_special(yb, state, 25); if (n_randint(state, 2)) { mag_neg_log(yb, xb); mag_get_fmpr(x, xb); if (mag_cmp_2exp_si(xb, 0) >= 0) fmpr_zero(z); else { fmpr_log(z, x, MAG_BITS, FMPR_RND_UP); fmpr_neg(z, z); } } else { mag_get_fmpr(x, xb); fmpz_randtest(n, state, 100); mag_mul_2exp_fmpz(xb, xb, n); mag_neg_log(yb, xb); if (mag_cmp_2exp_si(xb, 0) >= 0) { fmpr_zero(z); } else { fmpr_log(z, x, 2 * MAG_BITS, FMPR_RND_UP); fmpr_neg(z, z); fmpr_set_ui(z2, 2); fmpr_log(z2, z2, 2 * MAG_BITS, FMPR_RND_UP); fmpr_submul_fmpz(z, z2, n, 2 * MAG_BITS, FMPR_RND_UP); } } mag_get_fmpr(y, yb); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_neg_log(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-neg_log_lower.c000066400000000000000000000056741417376376500173530ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("neg_log_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; fmpz_t n; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); fmpz_init(n); mag_randtest_special(xb, state, 25); mag_randtest_special(yb, state, 25); if (n_randint(state, 2)) { mag_neg_log_lower(yb, xb); mag_get_fmpr(x, xb); if (mag_cmp_2exp_si(xb, 0) >= 0) fmpr_zero(z); else { fmpr_log(z, x, MAG_BITS, FMPR_RND_DOWN); fmpr_neg(z, z); } } else { mag_get_fmpr(x, xb); fmpz_randtest(n, state, 100); mag_mul_2exp_fmpz(xb, xb, n); mag_neg_log_lower(yb, xb); if (mag_cmp_2exp_si(xb, 0) >= 0) { fmpr_zero(z); } else { fmpr_log(z, x, 2 * MAG_BITS, FMPR_RND_DOWN); fmpr_neg(z, z); fmpr_set_ui(z2, 2); fmpr_log(z2, z2, 2 * MAG_BITS, FMPR_RND_DOWN); fmpr_submul_fmpz(z, z2, n, 2 * MAG_BITS, FMPR_RND_DOWN); } } mag_get_fmpr(y, yb); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("n = "); fmpz_print(n); flint_printf("\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_neg_log_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); fmpz_clear(n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-polylog_tail.c000066400000000000000000000055221417376376500172170ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" #include "arb.h" int main() { slong iter; flint_rand_t state; flint_printf("polylog_tail...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { mag_t xb, yb; ulong N, k, d; slong s, prec; arb_t z, t, u, r; mag_init(xb); mag_init(yb); arb_init(z); arb_init(t); arb_init(u); arb_init(r); mag_randtest_special(xb, state, 6); mag_randtest_special(yb, state, 6); N = n_randint(state, 100); d = n_randint(state, 100); s = n_randint(state, 100) - 50; prec = 4 * MAG_BITS; mag_polylog_tail(yb, xb, s, d, N); arb_zero(z); arf_set_mag(arb_midref(z), xb); arb_zero(r); for (k = N; k < N + 100; k++) { arb_pow_ui(t, z, k, prec); arb_log_ui(u, k, prec); arb_pow_ui(u, u, d, prec); arb_mul(t, t, u, prec); arb_set_ui(u, k); if (s >= 0) { arb_pow_ui(u, u, s, prec); arb_div(t, t, u, prec); } else { arb_pow_ui(u, u, -s, prec); arb_mul(t, t, u, prec); } arb_add(r, r, t, prec); } MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) arb_zero(z); mag_set(arb_radref(z), yb); if (!arb_is_finite(z)) arb_indeterminate(z); if (!arb_contains(z, r)) { flint_printf("FAIL\n\n"); flint_printf("N = %wu\n\n", N); flint_printf("d = %wu\n\n", d); flint_printf("s = %wd\n\n", s); flint_printf("xb = "); mag_printd(xb, 15); flint_printf("\n\n"); flint_printf("yb = "); mag_printd(yb, 15); flint_printf("\n\n"); flint_printf("z = "); arb_printd(z, 15); flint_printf("\n\n"); flint_printf("r = "); arb_printd(r, 15); flint_printf("\n\n"); flint_abort(); } mag_polylog_tail(xb, xb, s, d, N); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } mag_clear(xb); mag_clear(yb); arb_clear(z); arb_clear(t); arb_clear(u); arb_clear(r); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-pow_fmpz.c000066400000000000000000000042261417376376500163620ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, w; mag_t xb, yb; fmpz_t e; fmpr_init(x); fmpr_init(y); fmpr_init(w); fmpz_init(e); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 80); mag_randtest_special(yb, state, 80); fmpz_randtest(e, state, 200); mag_get_fmpr(x, xb); fmpr_pow_sloppy_fmpz(y, x, e, 2 * MAG_BITS, FMPR_RND_UP); if (fmpr_is_nan(y)) fmpr_pos_inf(y); mag_pow_fmpz(yb, xb, e); mag_get_fmpr(w, yb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(y, w) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } mag_pow_fmpz(xb, xb, e); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); mag_print(xb); flint_printf("\n\n"); mag_print(yb); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(w); fmpz_clear(e); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-pow_fmpz_lower.c000066400000000000000000000042521417376376500175710ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_fmpz_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, w; mag_t xb, yb; fmpz_t e; fmpr_init(x); fmpr_init(y); fmpr_init(w); fmpz_init(e); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 80); mag_randtest_special(yb, state, 80); fmpz_randtest(e, state, 200); mag_get_fmpr(x, xb); fmpr_pow_sloppy_fmpz(y, x, e, 2 * MAG_BITS, FMPR_RND_DOWN); if (fmpr_is_nan(y)) fmpr_pos_inf(y); mag_pow_fmpz_lower(yb, xb, e); mag_get_fmpr(w, yb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(w, y) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } mag_pow_fmpz_lower(xb, xb, e); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); mag_print(xb); flint_printf("\n\n"); mag_print(yb); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(w); fmpz_clear(e); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-pow_ui.c000066400000000000000000000040441417376376500160210ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, w; mag_t xb, yb; ulong e; fmpr_init(x); fmpr_init(y); fmpr_init(w); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 80); mag_randtest_special(yb, state, 80); e = n_randtest(state); mag_get_fmpr(x, xb); fmpr_pow_sloppy_ui(y, x, e, 2 * MAG_BITS, FMPR_RND_UP); if (fmpr_is_nan(y)) fmpr_pos_inf(y); mag_pow_ui(yb, xb, e); mag_get_fmpr(w, yb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(y, w) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("e = %wu\n\n", e); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } mag_pow_ui(xb, xb, e); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("e = %wu\n\n", e); mag_print(xb); flint_printf("\n\n"); mag_print(yb); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(w); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-pow_ui_lower.c000066400000000000000000000040701417376376500172300ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("pow_ui_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, w; mag_t xb, yb; ulong e; fmpr_init(x); fmpr_init(y); fmpr_init(w); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 80); mag_randtest_special(yb, state, 80); e = n_randtest(state); mag_get_fmpr(x, xb); fmpr_pow_sloppy_ui(y, x, e, 2 * MAG_BITS, FMPR_RND_DOWN); if (fmpr_is_nan(y)) fmpr_pos_inf(y); mag_pow_ui_lower(yb, xb, e); mag_get_fmpr(w, yb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(w, y) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("e = %wu\n\n", e); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } mag_pow_ui_lower(xb, xb, e); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("e = %wu\n\n", e); mag_print(xb); flint_printf("\n\n"); mag_print(yb); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(w); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-rfac_ui.c000066400000000000000000000030301417376376500161210ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("rfac_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { fmpr_t x, y; fmpz_t f; mag_t xb; ulong n; fmpr_init(x); fmpr_init(y); fmpz_init(f); mag_init(xb); mag_randtest_special(xb, state, 80); n = n_randtest(state) % 2000; mag_rfac_ui(xb, n); fmpz_fac_ui(f, n); fmpr_one(x); fmpr_div_fmpz(x, x, f, 2 * MAG_BITS, FMPR_RND_UP); mag_get_fmpr(y, xb); MAG_CHECK_BITS(xb) if (!(fmpr_cmpabs(y, x) >= 0)) { flint_printf("FAIL\n\n"); flint_printf("n = %wu\n\n", n); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpz_clear(f); mag_clear(xb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-root.c000066400000000000000000000041051417376376500155000ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("root...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; ulong n; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 1 + n_randint(state, 200)); mag_randtest_special(yb, state, 1 + n_randint(state, 200)); n = n_randint(state, 30); mag_root(yb, xb, n); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_root(z, x, n, MAG_BITS, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_root(xb, xb, n); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-rsqrt.c000066400000000000000000000040151417376376500156700ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("rsqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 1 + n_randint(state, 200)); mag_randtest_special(yb, state, 1 + n_randint(state, 200)); mag_rsqrt(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_rsqrt(z, x, MAG_BITS, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_rsqrt(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-rsqrt_lower.c000066400000000000000000000040431417376376500171010ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("rsqrt_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 1 + n_randint(state, 200)); mag_randtest_special(yb, state, 1 + n_randint(state, 200)); mag_rsqrt_lower(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_rsqrt(z, x, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_rsqrt_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-set_d.c000066400000000000000000000057111417376376500156170ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" /* XXX: d_randtest is not good enough */ #define EXP_MINUS_32 2.3283064365386962891e-10 #define EXP_MINUS_64 5.42101086242752217e-20 double d_randtest2(flint_rand_t state) { mp_limb_t m1, m2; double t; if (FLINT_BITS == 64) { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); t = ((double) m1) * EXP_MINUS_64; } else { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); m2 = n_randtest(state); t = ((double) m1) * EXP_MINUS_32 + ((double) m2) * EXP_MINUS_64; } return t; } int main() { slong iter; flint_rand_t state; flint_printf("set_d...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t a, b, c; mag_t m; double x; fmpr_init(a); fmpr_init(b); fmpr_init(c); mag_init(m); x = d_randtest2(state); x = ldexp(x, 1100 - n_randint(state, 2200)); if (n_randint(state, 100) == 0) x = 0.0; if (n_randint(state, 100) == 0) x = D_INF; if (n_randint(state, 100) == 0) x = D_NAN; if (n_randint(state, 2)) x = -x; fmpr_set_d(a, x); mag_set_d(m, x); mag_get_fmpr(b, m); fmpr_set(c, a); fmpr_mul_ui(c, c, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(c, c, -10); MAG_CHECK_BITS(m) if (!(fmpr_cmpabs(a, b) <= 0 && fmpr_cmpabs(b, c) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpr_print(c); flint_printf("\n\n"); flint_abort(); } mag_set_d_lower(m, x); mag_get_fmpr(b, m); fmpr_set(c, a); fmpr_mul_ui(c, c, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(c, c, -10); MAG_CHECK_BITS(m) if (!(fmpr_cmpabs(c, b) <= 0 && fmpr_cmpabs(b, a) <= 0)) { flint_printf("FAIL (lower)\n\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpr_print(c); flint_printf("\n\n"); flint_abort(); } fmpr_clear(a); fmpr_clear(b); fmpr_clear(c); mag_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-set_d_2exp_fmpz.c000066400000000000000000000064021417376376500176070ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/double_extras.h" #include "mag.h" /* XXX: d_randtest is not good enough */ #define EXP_MINUS_32 2.3283064365386962891e-10 #define EXP_MINUS_64 5.42101086242752217e-20 double d_randtest2(flint_rand_t state) { mp_limb_t m1, m2; double t; if (FLINT_BITS == 64) { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); t = ((double) m1) * EXP_MINUS_64; } else { m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); m2 = n_randtest(state); t = ((double) m1) * EXP_MINUS_32 + ((double) m2) * EXP_MINUS_64; } return t; } int main() { slong iter; flint_rand_t state; flint_printf("set_d_2exp_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t a, b, c; fmpz_t e; mag_t m; double x; fmpr_init(a); fmpr_init(b); fmpr_init(c); fmpz_init(e); mag_init(m); x = d_randtest2(state); x = ldexp(x, 1100 - n_randint(state, 2200)); if (n_randint(state, 100) == 0) x = 0.0; if (n_randint(state, 100) == 0) x = D_INF; if (n_randint(state, 100) == 0) x = D_NAN; if (n_randint(state, 2)) x = -x; fmpz_randtest(e, state, 100); fmpr_set_d(a, x); fmpr_abs(a, a); fmpr_mul_2exp_fmpz(a, a, e); mag_set_d_2exp_fmpz(m, x, e); mag_get_fmpr(b, m); fmpr_set(c, a); fmpr_mul_ui(c, c, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(c, c, -10); MAG_CHECK_BITS(m) if (!(fmpr_cmpabs(a, b) <= 0 && fmpr_cmpabs(b, c) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = %g\n\n", x); flint_printf("e = "); fmpz_print(e); flint_printf("\n\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpr_print(c); flint_printf("\n\n"); flint_abort(); } mag_set_d_2exp_fmpz_lower(m, x, e); mag_get_fmpr(b, m); fmpr_set(c, a); fmpr_mul_ui(c, c, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(c, c, -10); MAG_CHECK_BITS(m) if (!(fmpr_cmpabs(c, b) <= 0 && fmpr_cmpabs(b, a) <= 0)) { flint_printf("FAIL (lower)\n\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpr_print(c); flint_printf("\n\n"); flint_abort(); } fmpr_clear(a); fmpr_clear(b); fmpr_clear(c); fmpz_clear(e); mag_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-set_ui.c000066400000000000000000000031271417376376500160100ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("set_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t a, b, c; mag_t m; ulong x; fmpr_init(a); fmpr_init(b); fmpr_init(c); mag_init(m); x = n_randtest(state); fmpr_set_ui(a, x); mag_set_ui(m, x); mag_get_fmpr(b, m); fmpr_set(c, a); fmpr_mul_ui(c, c, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(c, c, -10); MAG_CHECK_BITS(m) if (!(fmpr_cmpabs(a, b) <= 0 && fmpr_cmpabs(b, c) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = %wu\n\n", x); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpr_print(c); flint_printf("\n\n"); flint_abort(); } fmpr_clear(a); fmpr_clear(b); fmpr_clear(c); mag_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-set_ui_lower.c000066400000000000000000000031451417376376500172200ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("set_ui_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t a, b, c; mag_t m; ulong x; fmpr_init(a); fmpr_init(b); fmpr_init(c); mag_init(m); x = n_randtest(state); fmpr_set_ui(a, x); mag_set_ui_lower(m, x); mag_get_fmpr(b, m); fmpr_set(c, a); fmpr_mul_ui(c, c, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(c, c, -10); MAG_CHECK_BITS(m) if (!(fmpr_cmpabs(c, b) <= 0 && fmpr_cmpabs(b, a) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = %wu\n\n", x); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpr_print(c); flint_printf("\n\n"); flint_abort(); } fmpr_clear(a); fmpr_clear(b); fmpr_clear(c); mag_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-sinh.c000066400000000000000000000044641417376376500154660ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" slong fmpr_sinh(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { fmpr_set(y, x); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_sinh, y, x, prec, rnd); return r; } } int main() { slong iter; flint_rand_t state; flint_printf("atan...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_mul_2exp_si(xb, xb, -100 + n_randint(state,120)); mag_randtest_special(yb, state, 25); mag_sinh(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_sinh(z, x, MAG_BITS, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_sinh(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-sinh_lower.c000066400000000000000000000045121417376376500166700ustar00rootroot00000000000000/* Copyright (C) 2017 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" slong fmpr_sinh(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x)) { fmpr_set(y, x); return FMPR_RESULT_EXACT; } else { slong r; CALL_MPFR_FUNC(r, mpfr_sinh, y, x, prec, rnd); return r; } } int main() { slong iter; flint_rand_t state; flint_printf("sinh_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 0); mag_mul_2exp_si(xb, xb, -100 + n_randint(state,120)); mag_randtest_special(yb, state, 25); mag_sinh_lower(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_sinh(z, x, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_sinh_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-sqrt.c000066400000000000000000000040111417376376500155020ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 1 + n_randint(state, 200)); mag_randtest_special(yb, state, 1 + n_randint(state, 200)); mag_sqrt(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_sqrt(z, x, MAG_BITS, FMPR_RND_UP); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z, y) <= 0 && fmpr_cmpabs(y, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_sqrt(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-sqrt_lower.c000066400000000000000000000040371417376376500167220ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("sqrt_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2; mag_t xb, yb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 1 + n_randint(state, 200)); mag_randtest_special(yb, state, 1 + n_randint(state, 200)); mag_sqrt_lower(yb, xb); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_sqrt(z, x, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_ui(z2, z, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z2, z2, -10); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) if (!(fmpr_cmpabs(z2, y) <= 0 && fmpr_cmpabs(y, z) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z2 = "); fmpr_print(z2); flint_printf("\n\n"); flint_abort(); } mag_sqrt_lower(xb, xb); if (!mag_equal(xb, yb)) { flint_printf("FAIL (aliasing)\n\n"); flint_abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-sub.c000066400000000000000000000047271417376376500153200ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("sub...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_sub(z, x, y, 100, FMPR_RND_UP); if (fmpr_sgn(z) < 0) fmpr_zero(z); fmpr_mul_ui(z2, z, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(z2, z2, -10); mag_sub(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } if (n_randint(state, 2)) { mag_sub(xb, xb, yb); if (!mag_equal(xb, zb)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } else { mag_sub(yb, xb, yb); if (!mag_equal(yb, zb)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/mag/test/t-sub_lower.c000066400000000000000000000047641417376376500165310ustar00rootroot00000000000000/* Copyright (C) 2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "mag.h" int main() { slong iter; flint_rand_t state; flint_printf("sub_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z, z2, w; mag_t xb, yb, zb; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(z2); fmpr_init(w); mag_init(xb); mag_init(yb); mag_init(zb); mag_randtest_special(xb, state, 100); mag_randtest_special(yb, state, 100); mag_get_fmpr(x, xb); mag_get_fmpr(y, yb); fmpr_sub(z2, x, y, 100, FMPR_RND_DOWN); if (fmpr_sgn(z2) < 0) fmpr_zero(z2); fmpr_mul_ui(z, z2, 1023, MAG_BITS, FMPR_RND_DOWN); fmpr_mul_2exp_si(z, z, -10); mag_sub_lower(zb, xb, yb); mag_get_fmpr(w, zb); MAG_CHECK_BITS(xb) MAG_CHECK_BITS(yb) MAG_CHECK_BITS(zb) if (!(fmpr_cmpabs(z, w) <= 0 && fmpr_cmpabs(w, z2) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_abort(); } if (n_randint(state, 2)) { mag_sub_lower(xb, xb, yb); if (!mag_equal(xb, zb)) { flint_printf("FAIL (aliasing 1)\n\n"); flint_abort(); } } else { mag_sub_lower(yb, xb, yb); if (!mag_equal(yb, zb)) { flint_printf("FAIL (aliasing 2)\n\n"); flint_abort(); } } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(z2); fmpr_clear(w); mag_clear(xb); mag_clear(yb); mag_clear(zb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; } arb-2.22.1/partitions.h000066400000000000000000000017361417376376500147410ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef PARTITIONS_H #define PARTITIONS_H #include #include "flint/flint.h" #include "flint/arith.h" #include "arb.h" #ifdef __cplusplus extern "C" { #endif void partitions_rademacher_bound(arf_t b, const fmpz_t n, ulong N); void partitions_hrr_sum_arb(arb_t x, const fmpz_t n, slong N0, slong N, int use_doubles); void partitions_fmpz_fmpz(fmpz_t p, const fmpz_t n, int use_doubles); void partitions_fmpz_ui(fmpz_t p, ulong n); void partitions_fmpz_ui_using_doubles(fmpz_t p, ulong n); void partitions_leading_fmpz(arb_t res, const fmpz_t n, slong prec); #ifdef __cplusplus } #endif #endif arb-2.22.1/partitions/000077500000000000000000000000001417376376500145615ustar00rootroot00000000000000arb-2.22.1/partitions/fmpz_fmpz.c000066400000000000000000000116011417376376500167340ustar00rootroot00000000000000/* Copyright (C) 2013-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "partitions.h" /* defined in flint*/ #define NUMBER_OF_SMALL_PARTITIONS 128 FLINT_DLL extern const unsigned int partitions_lookup[NUMBER_OF_SMALL_PARTITIONS]; slong partitions_hrr_needed_terms(double n); typedef struct { arb_ptr x; fmpz * n; ulong N0; ulong N; int use_doubles; } worker_arg_t; static void * worker(void * arg_ptr) { worker_arg_t arg = *((worker_arg_t *) arg_ptr); partitions_hrr_sum_arb(arg.x, arg.n, arg.N0, arg.N, arg.use_doubles); flint_cleanup(); return NULL; } /* TODO: set number of threads in child threads, for future multithreaded evaluation of single terms */ static void hrr_sum_threaded(arb_t x, const fmpz_t n, slong N, int use_doubles) { arb_t y; pthread_t threads[2]; worker_arg_t args[2]; arb_init(y); args[0].x = x; args[0].n = (fmpz *) n; args[0].N0 = 1; args[0].N = 16; args[0].use_doubles = use_doubles; args[1].x = y; args[1].n = (fmpz *) n; args[1].N0 = 17; args[1].N = N; args[1].use_doubles = use_doubles; pthread_create(&threads[0], NULL, worker, &args[0]); pthread_create(&threads[1], NULL, worker, &args[1]); pthread_join(threads[0], NULL); pthread_join(threads[1], NULL); arb_add(x, x, y, ARF_PREC_EXACT); arb_clear(y); } void partitions_fmpz_fmpz_hrr(fmpz_t p, const fmpz_t n, int use_doubles) { arb_t x; arf_t bound; slong N; arb_init(x); arf_init(bound); N = partitions_hrr_needed_terms(fmpz_get_d(n)); if (fmpz_cmp_ui(n, 4e8) >= 0 && flint_get_num_threads() > 1) { hrr_sum_threaded(x, n, N, use_doubles); } else { partitions_hrr_sum_arb(x, n, 1, N, use_doubles); } partitions_rademacher_bound(bound, n, N); arb_add_error_arf(x, bound); if (!arb_get_unique_fmpz(p, x)) { flint_printf("not unique!\n"); arb_printd(x, 50); flint_printf("\n"); flint_abort(); } arb_clear(x); arf_clear(bound); } /* To compute p(n) mod 2^64. */ static void partitions_vec(mp_ptr v, slong len) { slong i, j, n; mp_limb_t p; for (n = 0; n < FLINT_MIN(len, NUMBER_OF_SMALL_PARTITIONS); n++) v[n] = partitions_lookup[n]; for (n = NUMBER_OF_SMALL_PARTITIONS; n < len; n++) { p = 0; for (i = 1, j = 1; j <= n; j += 3 * i + 1, i++) p = v[n - j] - p; if ((i & 1) == 0) p = -p; for (i = 1, j = 2; j <= n; j += 3 * i + 2, i++) p = v[n - j] - p; if ((i & 1) != 0) p = -p; v[n] = p; } } /* The floor+vec method *requires* n <= 1498 for floor(p(n)/2^64) to be equal to floor(T/2^64). It is faster up to n ~= 1200. With doubles, it is faster up to n ~= 500. */ void _partitions_fmpz_ui(fmpz_t res, ulong n, int use_doubles) { if (n < NUMBER_OF_SMALL_PARTITIONS) { fmpz_set_ui(res, partitions_lookup[n]); } else if (FLINT_BITS == 64 && (n < 500 || (!use_doubles && n < 1200))) { mp_ptr tmp = flint_malloc((n + 1) * sizeof(mp_limb_t)); if (n < 417) /* p(n) < 2^64 */ { partitions_vec(tmp, n + 1); fmpz_set_ui(res, tmp[n]); } else { arb_t x; arb_init(x); fmpz_set_ui(res, n); partitions_leading_fmpz(x, res, 4 * sqrt(n) - 50); arb_mul_2exp_si(x, x, -64); arb_floor(x, x, 4 * sqrt(n) - 50); if (arb_get_unique_fmpz(res, x)) { fmpz_mul_2exp(res, res, 64); partitions_vec(tmp, n + 1); fmpz_add_ui(res, res, tmp[n]); } else { flint_printf("warning: failed at %wu\n", n); fmpz_set_ui(res, n); partitions_fmpz_fmpz_hrr(res, res, use_doubles); } arb_clear(x); } flint_free(tmp); } else { fmpz_set_ui(res, n); partitions_fmpz_fmpz_hrr(res, res, use_doubles); } } void partitions_fmpz_fmpz(fmpz_t res, const fmpz_t n, int use_doubles) { if (fmpz_cmp_ui(n, 2000) < 0) { if (fmpz_sgn(n) < 0) fmpz_zero(res); else _partitions_fmpz_ui(res, *n, use_doubles); } else { partitions_fmpz_fmpz_hrr(res, n, use_doubles); } } void partitions_fmpz_ui(fmpz_t res, ulong n) { _partitions_fmpz_ui(res, n, 0); } void partitions_fmpz_ui_using_doubles(fmpz_t res, ulong n) { _partitions_fmpz_ui(res, n, 1); } arb-2.22.1/partitions/hrr_sum_arb.c000066400000000000000000000175671417376376500172500ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "partitions.h" #include "arb.h" #include "math.h" #define DOUBLE_CUTOFF 40 #define DOUBLE_ERR 1e-12 #define DOUBLE_PREC 53 #define MIN_PREC 20 #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 */ 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_hrr_needed_terms(double n) { slong N; for (N = 1; partitions_remainder_bound_log2(n, N) > 10; N++); for ( ; partitions_remainder_bound(n, N) > 0.4; 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(double 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; } static 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); } static double eval_trig_prod_d(trig_prod_t prod) { int i; double s; mp_limb_t v; if (prod->prefactor == 0) return 0.0; s = prod->prefactor; v = n_gcd(FLINT_MAX(prod->sqrt_p, prod->sqrt_q), FLINT_MIN(prod->sqrt_p, prod->sqrt_q)); prod->sqrt_p /= v; prod->sqrt_q /= v; if (prod->sqrt_p != 1) s *= sqrt(prod->sqrt_p); if (prod->sqrt_q != 1) s /= sqrt(prod->sqrt_q); for (i = 0; i < prod->n; i++) s *= cos_pi_pq(prod->cos_p[i], prod->cos_q[i]); return s; } static void eval_trig_prod(arb_t sum, trig_prod_t prod, slong prec) { int i; mp_limb_t v; arb_t t; if (prod->prefactor == 0) { arb_zero(sum); return; } arb_init(t); arb_set_si(sum, prod->prefactor); v = n_gcd(FLINT_MAX(prod->sqrt_p, prod->sqrt_q), FLINT_MIN(prod->sqrt_p, prod->sqrt_q)); prod->sqrt_p /= v; prod->sqrt_q /= v; if (prod->sqrt_p != 1) { arb_sqrt_ui(t, prod->sqrt_p, prec); arb_mul(sum, sum, t, prec); } if (prod->sqrt_q != 1) { arb_rsqrt_ui(t, prod->sqrt_q, prec); arb_mul(sum, sum, t, prec); } for (i = 0; i < prod->n; i++) { fmpq_t pq; *fmpq_numref(pq) = prod->cos_p[i]; *fmpq_denref(pq) = prod->cos_q[i]; arb_cos_pi_fmpq(t, pq, prec); arb_mul(sum, sum, t, prec); } arb_clear(t); } static void sinh_cosh_divk_precomp(arb_t sh, arb_t ch, arb_t ex, slong k, slong prec) { arb_t t; arb_init(t); arb_set_round(t, ex, prec); arb_root_ui(ch, t, k, prec); /* The second term doesn't need full precision, but this doesn't affect performance that much... */ arb_inv(t, ch, prec); arb_sub(sh, ch, t, prec); arb_add(ch, ch, t, prec); arb_mul_2exp_si(ch, ch, -1); arb_mul_2exp_si(sh, sh, -1); arb_clear(t); } void partitions_hrr_sum_arb(arb_t x, const fmpz_t n, slong N0, slong N, int use_doubles) { trig_prod_t prod; arb_t acc, C, t1, t2, t3, t4, exp1; fmpz_t n24; slong k, prec, res_prec, acc_prec, guard_bits; double nd, Cd; if (fmpz_cmp_ui(n, 2) <= 0) { flint_abort(); } nd = fmpz_get_d(n); /* compute initial precision */ guard_bits = 2 * FLINT_BIT_COUNT(N) + 32; prec = partitions_remainder_bound_log2(nd, N0) + guard_bits; prec = FLINT_MAX(prec, DOUBLE_PREC); res_prec = acc_prec = prec; arb_init(acc); arb_init(C); arb_init(t1); arb_init(t2); arb_init(t3); arb_init(t4); arb_init(exp1); fmpz_init(n24); arb_zero(x); /* n24 = 24n - 1 */ fmpz_set(n24, n); fmpz_mul_ui(n24, n24, 24); fmpz_sub_ui(n24, n24, 1); /* C = (pi/6) sqrt(24n-1) */ arb_const_pi(t1, prec); arb_sqrt_fmpz(t2, n24, prec); arb_mul(t1, t1, t2, prec); arb_div_ui(C, t1, 6, prec); /* exp1 = exp(C) */ arb_exp(exp1, C, prec); Cd = PI * sqrt(24*nd-1) / 6; for (k = N0; k <= N; k++) { trig_prod_init(prod); arith_hrr_expsum_factored(prod, k, fmpz_fdiv_ui(n, k)); if (prod->prefactor != 0) { if (prec > MIN_PREC) prec = partitions_prec_bound(nd, k, N); prod->prefactor *= 4; prod->sqrt_p *= 3; prod->sqrt_q *= k; if (prec > DOUBLE_CUTOFF || !use_doubles) { /* Compute A_k(n) * sqrt(3/k) * 4 / (24*n-1) */ eval_trig_prod(t1, prod, prec); arb_div_fmpz(t1, t1, n24, prec); /* Multiply by (cosh(z) - sinh(z)/z) where z = C / k */ arb_set_round(t2, C, prec); arb_div_ui(t2, t2, k, prec); if (k < 35 && prec > 1000) sinh_cosh_divk_precomp(t3, t4, exp1, k, prec); else arb_sinh_cosh(t3, t4, t2, prec); arb_div(t3, t3, t2, prec); arb_sub(t2, t4, t3, prec); arb_mul(t1, t1, t2, prec); } else { double xx, zz, xxerr; xx = eval_trig_prod_d(prod) / (24*nd - 1); zz = Cd / k; xx = xx * (cosh(zz) - sinh(zz) / zz); xxerr = fabs(xx) * DOUBLE_ERR + DOUBLE_ERR; arf_set_d(arb_midref(t1), xx); mag_set_d(arb_radref(t1), xxerr); } /* Add to accumulator */ arb_add(acc, acc, t1, acc_prec); if (acc_prec > 2 * prec + 32) { arb_add(x, x, acc, res_prec); arb_zero(acc); acc_prec = prec + 32; } } } arb_add(x, x, acc, res_prec); fmpz_clear(n24); arb_clear(acc); arb_clear(exp1); arb_clear(C); arb_clear(t1); arb_clear(t2); arb_clear(t3); arb_clear(t4); } arb-2.22.1/partitions/leading_fmpz.c000066400000000000000000000021771417376376500173730ustar00rootroot00000000000000/* Copyright (C) 2016 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "partitions.h" void partitions_leading_fmpz(arb_t res, const fmpz_t n, slong prec) { arb_t t; fmpz_t c; slong eprec; arb_init(t); fmpz_init(c); eprec = prec + fmpz_bits(n) / 2; /* c = 24n-1 */ fmpz_mul_ui(c, n, 24); fmpz_sub_ui(c, c, 1); /* t = pi sqrt(24n-1) / 6 */ arb_sqrt_fmpz(t, c, eprec); arb_const_pi(res, eprec); arb_mul(t, t, res, eprec); arb_div_ui(t, t, 6, eprec); /* res = exp(t) - exp(t) / t */ /* todo: eprec only needed for argument reduction */ arb_exp(res, t, eprec); arb_div(t, res, t, prec); arb_sub(res, res, t, prec); arb_sqrt_ui(t, 12, prec); arb_mul(res, res, t, prec); arb_div_fmpz(res, res, c, prec); arb_clear(t); fmpz_clear(c); } arb-2.22.1/partitions/rademacher_bound.c000066400000000000000000000035201417376376500202070ustar00rootroot00000000000000/* Copyright (C) 2013 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "partitions.h" static void _arf_sinh(arf_t y, const arf_t x, slong prec) { arb_t t; arb_init(t); arb_set_arf(t, x); arb_sinh(t, t, prec); arb_get_abs_ubound_arf(y, t, prec); arb_clear(t); } /* Equation (1.8) in the paper */ void partitions_rademacher_bound(arf_t b, const fmpz_t n, ulong N) { arf_t A, B, C, t, u; fmpz_t n1; arf_init(A); arf_init(B); arf_init(C); arf_init(t); arf_init(u); fmpz_init(n1); /* bound for 44*pi^2/(225*sqrt(3)) */ arf_set_si_2exp_si(A, 18695160, -24); /* bound for pi*sqrt(2)/75 */ arf_set_si_2exp_si(B, 993857, -24); /* bound for pi*sqrt(2/3) */ arf_set_si_2exp_si(C, 43035232, -24); /* first term: A / sqrt(N) */ arf_sqrt_ui(t, N, MAG_BITS, ARF_RND_DOWN); arf_div(b, A, t, MAG_BITS, ARF_RND_UP); /* B * sqrt(N/(n-1)) */ arf_set_ui(t, N); fmpz_sub_ui(n1, n, 1); arf_div_fmpz(t, t, n1, MAG_BITS, ARF_RND_UP); arf_sqrt(t, t, MAG_BITS, ARF_RND_UP); arf_mul(t, B, t, MAG_BITS, ARF_RND_UP); /* sinh(C*sqrt(n)/N) */ arf_sqrt_fmpz(u, n, MAG_BITS, ARF_RND_UP); arf_div_ui(u, u, N, MAG_BITS, ARF_RND_UP); arf_mul(u, C, u, MAG_BITS, ARF_RND_UP); _arf_sinh(u, u, MAG_BITS); /* second term: B * ... * sinh... */ arf_mul(t, t, u, MAG_BITS, ARF_RND_UP); arf_add(b, b, t, MAG_BITS, ARF_RND_UP); arf_clear(A); arf_clear(B); arf_clear(C); arf_clear(t); arf_clear(u); fmpz_clear(n1); } arb-2.22.1/partitions/test/000077500000000000000000000000001417376376500155405ustar00rootroot00000000000000arb-2.22.1/partitions/test/t-partitions_fmpz_ui.c000066400000000000000000000067771417376376500221130ustar00rootroot00000000000000/* Copyright (C) 2011 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "partitions.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}, }; #define NUM 5000 int main(void) { flint_rand_t state; slong i; flint_printf("partitions_fmpz_ui...."); fflush(stdout); flint_randinit(state); { fmpz_t p; fmpz * v; fmpz_init(p); v = _fmpz_vec_init(NUM); arith_number_of_partitions_vec(v, NUM); for (i = 0; i < NUM; i++) { partitions_fmpz_ui(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"); flint_abort(); } } _fmpz_vec_clear(v, NUM); for (i = 0; testdata[i][0] != 0; i++) { partitions_fmpz_ui(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]); flint_abort(); } } fmpz_clear(p); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/partitions/test/t-partitions_fmpz_ui_threaded.c000066400000000000000000000071571417376376500237440ustar00rootroot00000000000000/* Copyright (C) 2011-2014 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "partitions.h" /* Values mod 10^9 */ 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}, {500000000, 143535392}, {1000000000, 685688339}, {UWORD(4000000000), 525944299}, {0, 0}, }; #define NUM 5000 int main(void) { flint_rand_t state; slong i; flint_printf("partitions_fmpz_ui_threaded...."); fflush(stdout); flint_randinit(state); flint_set_num_threads(2); { fmpz_t p; fmpz * v; fmpz_init(p); v = _fmpz_vec_init(NUM); arith_number_of_partitions_vec(v, NUM); for (i = 0; i < NUM; i++) { partitions_fmpz_ui(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"); flint_abort(); } } _fmpz_vec_clear(v, NUM); for (i = 0; testdata[i][0] != 0; i++) { partitions_fmpz_ui(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]); flint_abort(); } } fmpz_clear(p); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; } arb-2.22.1/partitions/test/t-partitions_fmpz_ui_using_doubles.c000066400000000000000000000070511417376376500250170ustar00rootroot00000000000000/* Copyright (C) 2011 Fredrik Johansson This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "flint/arith.h" #include "partitions.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}, }; #define NUM 5000 int main(void) { flint_rand_t state; slong i; flint_printf("partitions_fmpz_ui_using_doubles...."); fflush(stdout); flint_randinit(state); { fmpz_t p; fmpz * v; fmpz_init(p); v = _fmpz_vec_init(NUM); arith_number_of_partitions_vec(v, NUM); for (i = 0; i < NUM; i++) { partitions_fmpz_ui_using_doubles(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"); flint_abort(); } } _fmpz_vec_clear(v, NUM); for (i = 0; testdata[i][0] != 0; i++) { partitions_fmpz_ui_using_doubles(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]); flint_abort(); } } fmpz_clear(p); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return 0; }